Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.75 KB | None | 0 0
  1. import BaseParser from "../../BaseParser";
  2. import { getRegexPosition, fuzzyMatching } from "../../util";
  3. import { orderBy } from "lodash";
  4. import { DISTRICT_KEYWORDS } from "../../keywords/const-district";
  5. import { PROVINCE_KEYWORDS } from "../../keywords/const-province";
  6. import {
  7. SOURCE_KEYWORDS,
  8. DESTINATION_KEYWORDS
  9. } from "../../keywords/const-direction";
  10.  
  11. let DICT_PROVINCE_KEYWORDS = [];
  12.  
  13. export default class LocationRuleMultiTask extends BaseParser {
  14. constructor() {
  15. super();
  16. }
  17. PreProcess(train) {}
  18. Parse(message) {
  19. const { origin, dest } = LocationRuleMultiTask.getProvinceSourceDestination(message);
  20.  
  21. return {
  22. origin_province: !origin ? null : origin.province,
  23. dest_province: !dest ? null : dest.province,
  24. origin: !origin ? null : origin,
  25. dest: !dest ? null : dest
  26. };
  27. }
  28. // TODO:
  29. static getProvinceSourceDestination(msg) {
  30. // Search District Name in message
  31. if (!msg) {
  32. return { origin: null, dest: null };
  33. }
  34. let msg2 = msg.split(' ').join('#');
  35. let message = msg2.replace(/[-\(\)##\:]/g, "");//let message = msg.replace(/[-\(\)##\:]/g, "");
  36. // console.log("message", message);
  37. let result = []; //[Simple/Complex][workID][Direction][Location]
  38. let CSSKeyResult = [];
  39. let CSDKeyResult = [];
  40. let SKeyResult = [];
  41. let DKeyResult = [];
  42. let SnDKeyResult = [];
  43. //let sourceWord = [];
  44. //let destinationWord = [];
  45. let breakLineIndex = getRegexPosition(/\n/g, message);
  46. // console.log("breakLineIndex", breakLineIndex);
  47. let ii = 0;
  48. let foundCSSKey = false;
  49. let foundCSDKey = false;
  50. let foundCSSKeyNearDSKey = false;
  51. let foundCSDKeyNearDSKey = false;
  52. let workNum = 0;
  53. for (let keyword of COMPLEX_SENTENCE_SOURCE_KEYWORDS) {
  54. let index = [];
  55. index = getRegexPositionMultiTask(keyword, message,0);
  56. for (let re of index)
  57. {
  58. CSSKeyResult.push(re);
  59. }
  60. if (CSSKeyResult[0] && CSSKeyResult.length > 0) {
  61. foundCSSKey = true;
  62. }
  63. ii++;
  64. }
  65. ii=0;
  66. for (let keyword of COMPLEX_SENTENCE_DESTINATION_KEYWORDS) {
  67. let index = [];
  68. index = getRegexPositionMultiTask(keyword, message,1);
  69. for (let re of index)
  70. {
  71. CSDKeyResult.push(re);
  72. }
  73. if (CSDKeyResult[0] && CSDKeyResult.length > 0) {
  74. foundCSDKey = true;
  75. }
  76. ii++;
  77. }
  78. //console.log(foundCSSKey,foundCSDKey);
  79.  
  80. let sourceWord = [];
  81. let destinationWord = [];
  82. let result2 = [];
  83. for (let keyword of DISTRICT_KEYWORDS) {
  84. let index = [];
  85. ii++;
  86. if (keyword.district && keyword.district.length <= 3) {
  87. index = getRegexPosition(
  88. "(อ.|อำเภอ|ลูกศร|ขึ้น|ลง|up|down| )" + keyword.keyword + "( |\n)",
  89. message
  90. );
  91. } else {
  92. index = getRegexPosition(keyword.keyword, message);
  93. }
  94. if (index && index.length > 0) {
  95. result2.push(
  96. ...index.map(idx =>
  97. Object.assign({}, keyword, {
  98. index: idx
  99. })
  100. )
  101. );
  102. }
  103. }
  104. sourceWord = findPrefixWord(message, SOURCE_KEYWORDS);
  105. destinationWord = findPrefixWord(message, DESTINATION_KEYWORDS);
  106. sourceWord = removePrefixContainInResult(sourceWord, result2);
  107. destinationWord = removePrefixContainInResult(destinationWord, result2);
  108. for (let sw of sourceWord) {
  109. let inputSW = {Index:sw.index, Flag:2, Keyword:sw.keyword}
  110. SKeyResult.push(inputSW);
  111. }
  112. for (let dw of destinationWord) {
  113. let inputDW = {Index:dw.index, Flag:3, Keyword:dw.keyword}
  114. DKeyResult.push(inputDW);
  115. }
  116. SnDKeyResult = SKeyResult.concat(DKeyResult);
  117. SnDKeyResult.sort(function(a,b){return a.Index - b.Index});
  118.  
  119. let IsUndefined = false;
  120. let IsSimpleSingleTask = false; //ขึ้น-ลง
  121. let IsSimpleMultiTask = false; //n ขึ้น ,n ลง
  122. let IsSimpleMultiPairTask = false; //ขึ้น-ลง, ขึ้น-ลง, ...
  123. let IsSimpleMultiNotPairTask = false; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  124. let IsSimpleMulti_SingleNotPairMultiTask = false; //ขึ้น- ลง, ลง ...
  125. let IsSimpleMulti_MultiNotPairSingleTask = false; //ขึ้น, ขึ้น, ...- ลง
  126. let IsSimpleMulti_MultiNotPairMultiTask = false; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  127. let IsComplexSingleSingle_MultiTask = false; //ไป - กลับ
  128. let IsComplexSingleMulti_MultiTask = false; //ไป - กลับ
  129. let IsComplexMultiSingle_MultiTask = false; //ไป - กลับ
  130. let IsComplexMultiMulti_MultiTask = false; //ไป - กลับ
  131. let numFlag0 = SnDKeyResult.filter(item => item.Flag === 0).length;
  132. let numFlag1 = SnDKeyResult.filter(item => item.Flag === 1).length;
  133. let numFlag2 = SnDKeyResult.filter(item => item.Flag === 2).length;
  134. let numFlag3 = SnDKeyResult.filter(item => item.Flag === 3).length;
  135. let flagChangeIndex = [];
  136. ii=0;
  137. if(numFlag2 === 1 && numFlag3 ===1)
  138. {
  139. //ขึ้น-ลง
  140. IsSimpleSingleTask = true; //ขึ้น-ลง
  141. for(let res of SnDKeyResult)
  142. {
  143. let inputResult = {Index:res.Index, WorkIndex:0 ,Flag:res.Flag,Keyword:res.Keyword};
  144. result.push(inputResult);
  145. }
  146. }
  147. else if(numFlag2 === 0 && numFlag3 >=1)
  148. {
  149. IsUndefined = true;
  150. }
  151. else if(numFlag2 >= 1 && numFlag3 ===0)
  152. {
  153. IsUndefined = true;
  154. }
  155. else
  156. {
  157. //n ขึ้น ,n ลง
  158. //|-ขึ้น-ลง, ขึ้น-ลง, ...
  159. //'-ขึ้น, ขึ้น, ...- ลง, ลง ...
  160. // |-ขึ้น- ลง, ลง ...
  161. // |-ขึ้น, ขึ้น, ...- ลง
  162. // '-ขึ้น, ขึ้น, ...- ลง, ลง ...
  163. let tempFlag = -1;
  164. for(let res of SnDKeyResult)
  165. {
  166. if(res.Flag != tempFlag && tempFlag != -1)
  167. {
  168. flagChangeIndex.push(res);
  169. }
  170. tempFlag = res.Flag;
  171. }
  172. if(flagChangeIndex.length === 0)
  173. {
  174. IsUndefined = true;
  175. }
  176. else if(flagChangeIndex.length === 1)
  177. {
  178. //n ขึ้น ,n ลง
  179. //'-ขึ้น, ขึ้น, ...- ลง, ลง ...
  180. // |-ขึ้น- ลง, ลง ...
  181. // |-ขึ้น, ขึ้น, ...- ลง
  182. // '-ขึ้น, ขึ้น, ...- ลง, ลง ...
  183. if(numFlag2 === 1 && numFlag3 > 1)
  184. {
  185. let workIndex = 0;
  186. let tempFlag2Result = {Index:-1, WorkIndex:-1 ,Flag:-1,Keyword:""};
  187. for(let res of SnDKeyResult)
  188. {
  189. if(res.Flag === 2)
  190. {
  191. tempFlag2Result.Index= res.Index;
  192. tempFlag2Result.WorkIndex = workIndex;
  193. tempFlag2Result.Flag = res.Flag;
  194. tempFlag2Result.Keyword = res.Keyword;
  195. }
  196. }
  197. for(let res of SnDKeyResult)
  198. {
  199. if(res.Flag === 3)
  200. {
  201. let inputResultFlag2 = {Index:tempFlag2Result.Index, WorkIndex:workIndex ,Flag:tempFlag2Result.Flag,Keyword:tempFlag2Result.Keyword};
  202. result.push(inputResultFlag2);
  203. let inputResult = {Index:res.Index, WorkIndex:workIndex ,Flag:res.Flag,Keyword:res.Keyword};
  204. result.push(inputResult);
  205. workIndex++;
  206. }
  207. }
  208. IsSimpleMultiNotPairTask = true; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  209. IsSimpleMulti_SingleNotPairMultiTask = true; //ขึ้น- ลง, ลง ...
  210. }
  211. else if(numFlag2 > 1 && numFlag3 === 1)
  212. {
  213. let workIndex = 0;
  214. let tempFlag3Result = {Index:-1, WorkIndex:-1 ,Flag:-1,Keyword:""};
  215. for(let res of SnDKeyResult)
  216. {
  217. if(res.Flag === 3)
  218. {
  219. tempFlag3Result.Index= res.Index;
  220. tempFlag3Result.WorkIndex = workIndex;
  221. tempFlag3Result.Flag = res.Flag;
  222. tempFlag3Result.Keyword = res.Keyword;
  223. }
  224. }
  225. for(let res of SnDKeyResult)
  226. {
  227. if(res.Flag === 2)
  228. {
  229. let inputResult = {Index:res.Index, WorkIndex:workIndex ,Flag:res.Flag,Keyword:res.Keyword};
  230. result.push(inputResult);
  231. let inputResultFlag3 = {Index:tempFlag3Result.Index, WorkIndex:workIndex ,Flag:tempFlag3Result.Flag,Keyword:tempFlag3Result.Keyword};
  232. result.push(inputResultFlag3);
  233. workIndex++;
  234. }
  235. }
  236. IsSimpleMultiNotPairTask = true; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  237. IsSimpleMulti_MultiNotPairSingleTask = true; //ขึ้น, ขึ้น, ...- ลง
  238. }
  239. else if(numFlag2 > 1 && numFlag3 > 1)
  240. {
  241. let workIndex = 0;
  242. for(let res2 of SnDKeyResult)
  243. {
  244. if(res2.Flag === 2)
  245. {
  246. for(let res3 of SnDKeyResult)
  247. {
  248. if(res3.Flag === 3)
  249. {
  250. let inputResultFlag2 = {Index:res2.Index, WorkIndex:workIndex ,Flag:res2.Flag,Keyword:res2.Keyword};
  251. result.push(inputResultFlag2);
  252. let inputResultFlag3 = {Index:res3.Index, WorkIndex:workIndex ,Flag:res3.Flag,Keyword:res3.Keyword};
  253. result.push(inputResultFlag3);
  254. workIndex++;
  255. }
  256. }
  257. }
  258. }
  259. IsSimpleMultiNotPairTask = true; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  260. IsSimpleMulti_MultiNotPairMultiTask = true; //ขึ้น, ขึ้น, ...- ลง, ลง ...
  261. }
  262. }
  263. else if(flagChangeIndex.length > 1)
  264. {
  265. //n ขึ้น ,n ลง
  266. //'-ขึ้น-ลง, ขึ้น-ลง, ...
  267. //if(flagChangeIndex.length === (numFlag2 + numFlag3 - 1))
  268. {
  269. let tempFlag = -1;
  270. let flipFlopCount = 0; //let flipFlopFlag = true;
  271. let workIndex = 0;
  272. for(let res of SnDKeyResult)
  273. {
  274. if(tempFlag === -1)
  275. {
  276. let inputResult = {Index:res.Index, WorkIndex:workIndex ,Flag:res.Flag,Keyword:res.Keyword};
  277. result.push(inputResult);
  278. }
  279. else if(res.Flag === tempFlag)
  280. {
  281. let inputResult = {Index:res.Index, WorkIndex:workIndex ,Flag:res.Flag,Keyword:res.Keyword};
  282. result.push(inputResult);
  283. }
  284. else if(res.Flag != tempFlag && tempFlag != -1)
  285. {
  286. if(res.Flag != tempFlag)
  287. {
  288. flipFlopCount++;
  289. }
  290. if(flipFlopCount === 2)
  291. {
  292. workIndex++;
  293. flipFlopCount = 0;
  294. }
  295. let inputResult = {Index:res.Index, WorkIndex:workIndex ,Flag:res.Flag,Keyword:res.Keyword};
  296. result.push(inputResult);
  297. }
  298. tempFlag = res.Flag;
  299. }
  300. }
  301. IsSimpleMultiPairTask = true; //ขึ้น-ลง, ขึ้น-ลง, ...
  302. }
  303. }
  304.  
  305. if(foundCSSKey === true && foundCSDKey === true)
  306. {
  307. if(foundCSSKeyNearDSKey === true && foundCSDKeyNearDSKey === true)
  308. {
  309. //([simple = 0/complex = 1][num work]['up'/'down']['province'])
  310. //Result.push([simple/complex][work][up/down][province]);
  311. //workNum++;
  312. }
  313. }
  314.  
  315. if (result2.length === 0) return { source: null, destination: null };
  316. result2 = orderBy(result, ["index"], ["asc"]);
  317. //result2.sort(function(a,b){return a.index - b.index});
  318.  
  319. let source = getLocationMultiTask(result, result2,2);
  320. let destination = getLocationMultiTask(result, result2,3);
  321.  
  322. if (!destination) {
  323. return { source: null, destination: null };
  324. }
  325.  
  326.  
  327. const sourceProvinceDetail = getProvinceDetail(source.province);
  328. const destProvinceDetail = getProvinceDetail(destination.province);
  329. let origin = Object.assign({}, source, {
  330. region: sourceProvinceDetail ? sourceProvinceDetail.region : null,
  331. geographical_region: sourceProvinceDetail
  332. ? sourceProvinceDetail.geographical_region
  333. : null
  334. });
  335. let dest = Object.assign({}, destination, {
  336. region: destProvinceDetail ? destProvinceDetail.region : null,
  337. geographical_region: destProvinceDetail
  338. ? destProvinceDetail.geographical_region
  339. : null
  340. });
  341.  
  342.  
  343. }
  344. }
  345. export default class LocationRule extends BaseParser {
  346. constructor() {
  347. super();
  348. }
  349. PreProcess(train) {}
  350. Parse(message) {
  351. const { origin, dest } = LocationRule.getProvinceSourceDestination(message);
  352.  
  353. return {
  354. origin_province: !origin ? null : origin.province,
  355. dest_province: !dest ? null : dest.province,
  356. origin: !origin ? null : origin,
  357. dest: !dest ? null : dest
  358. };
  359. }
  360. // TODO:
  361. static getProvinceSourceDestination(msg) {
  362. // Search District Name in message
  363. if (!msg) {
  364. return { origin: null, dest: null };
  365. }
  366. let message = msg.replace(/[-\(\)#\:]/g, "");
  367. // console.log("message", message);
  368. let result = [];
  369. let sourceWord = [];
  370. let destinationWord = [];
  371. let breakLineIndex = getRegexPosition(/\n/g, message);
  372. // console.log("breakLineIndex", breakLineIndex);
  373. let ii = 0;
  374. for (let keyword of DISTRICT_KEYWORDS) {
  375. let index = [];
  376. ii++;
  377. if (keyword.district && keyword.district.length <= 3) {
  378. index = getRegexPosition(
  379. "(อ.|อำเภอ|ลูกศร|ขึ้น|ลง|up|down| )" + keyword.keyword + "( |\n)",
  380. message
  381. );
  382. } else {
  383. index = getRegexPosition(keyword.keyword, message);
  384. /*if (index && index.length === 0) {
  385. const newSearchWord = !keyword.district
  386. ? keyword.province
  387. : keyword.district;
  388. //console.log(msg, keyword);
  389. const { isMatch, index: messageIndex } = fuzzyMatching(
  390. message,
  391. newSearchWord
  392. );
  393. if (isMatch) {
  394. index = [messageIndex];
  395. }
  396. }*/
  397. }
  398. if (index && index.length > 0) {
  399. result.push(
  400. ...index.map(idx =>
  401. Object.assign({}, keyword, {
  402. index: idx
  403. })
  404. )
  405. );
  406. }
  407. }
  408. // console.log("result", result);
  409.  
  410. //console.log(result, message);
  411.  
  412. sourceWord = findPrefixWord(message, SOURCE_KEYWORDS);
  413. destinationWord = findPrefixWord(message, DESTINATION_KEYWORDS);
  414. // Remove prefix that contain in district keyword ex. ลง "อยู่ในคำว่า" แกลง
  415. sourceWord = removePrefixContainInResult(sourceWord, result);
  416. destinationWord = removePrefixContainInResult(destinationWord, result);
  417.  
  418. //console.log("sourceWord", sourceWord);
  419. //console.log("destinationWord", destinationWord);
  420. // Sort index of district name
  421. if (result.length === 0) return { source: null, destination: null };
  422. result = orderBy(result, ["index"], ["asc"]);
  423.  
  424. // console.log("eiei");
  425. //console.log("result", result);
  426. // First Index will be source province
  427. // Seconde Index (not same source province) will be destination
  428. let source = getSource(sourceWord, result);
  429. let destination = getDestination(
  430. destinationWord,
  431. result,
  432. source,
  433. breakLineIndex
  434. );
  435. //console.log("source", source);
  436. //console.log("destination", destination);
  437.  
  438. if (!destination) {
  439. return { source: null, destination: null };
  440. }
  441. // Get Region
  442. const sourceProvinceDetail = LocationRule.getProvinceDetail(
  443. source.province
  444. );
  445. const destProvinceDetail = LocationRule.getProvinceDetail(
  446. destination.province
  447. );
  448. let origin = Object.assign({}, source, {
  449. region: sourceProvinceDetail ? sourceProvinceDetail.region : null,
  450. geographical_region: sourceProvinceDetail
  451. ? sourceProvinceDetail.geographical_region
  452. : null
  453. });
  454. let dest = Object.assign({}, destination, {
  455. region: destProvinceDetail ? destProvinceDetail.region : null,
  456. geographical_region: destProvinceDetail
  457. ? destProvinceDetail.geographical_region
  458. : null
  459. });
  460.  
  461. return {
  462. origin,
  463. dest
  464. };
  465. }
  466.  
  467. static getProvinceDetail(province) {
  468. if (!province) return null;
  469. // DICT SEARCH
  470. if (Object.keys(DICT_PROVINCE_KEYWORDS).length === 0) {
  471. for (let proObj of PROVINCE_KEYWORDS) {
  472. DICT_PROVINCE_KEYWORDS[proObj.province] = proObj;
  473. }
  474. }
  475.  
  476. return DICT_PROVINCE_KEYWORDS[province];
  477. }
  478. }
  479.  
  480. const findPrefixWord = (message, keywords) => {
  481. let result = [];
  482. for (let keyword of keywords) {
  483. let index = [];
  484. index = getRegexPosition(keyword, message);
  485. if (index && index.length > 0) {
  486. result.push(
  487. ...index.map(idx =>
  488. Object.assign(
  489. {},
  490. { keyword },
  491. {
  492. index: idx
  493. }
  494. )
  495. )
  496. );
  497. }
  498. }
  499. return result;
  500. };
  501.  
  502. const getSource = (sourceWord, result) => {
  503. let source = null;
  504. let sourceCandidate = [];
  505. const offset = 4;
  506. for (let s of sourceWord) {
  507. for (let src of result) {
  508. if (
  509. s.index + s.keyword.length <= src.index &&
  510. src.index <= s.index + s.keyword.length + offset
  511. ) {
  512. sourceCandidate.push(src);
  513. break;
  514. }
  515. }
  516. }
  517.  
  518. if (sourceCandidate.length > 0) {
  519. source = orderBy(sourceCandidate, ["index"], ["asc"])[0];
  520. result = result.filter(res => res.index != source.index);
  521. } else {
  522. source = result[0];
  523. result = result.slice(1);
  524. }
  525. return source;
  526. };
  527.  
  528. const getDestination = (destinationWord, result, source, breakLineIndex) => {
  529. let destination = null;
  530. let destCandidate = [];
  531. for (let d of destinationWord) {
  532. for (let dest of result) {
  533. let nearestBreakLineIndex = getNearestBreakLine(d, breakLineIndex);
  534. //console.log("nearestBreakLine", nearestBreakLineIndex, d.index);
  535. let offset = 4;
  536. if (nearestBreakLineIndex) {
  537. offset = nearestBreakLineIndex - (d.index + d.keyword.length);
  538. }
  539.  
  540. if (
  541. d.index + d.keyword.length <= dest.index &&
  542. dest.index <= d.index + d.keyword.length + offset &&
  543. source.index + source.length < dest.index
  544. ) {
  545. destCandidate.push(dest);
  546. break;
  547. }
  548. }
  549. }
  550.  
  551. if (destCandidate.length > 0) {
  552. destination = orderBy(destCandidate, ["index"], ["asc"])[0];
  553. } else {
  554. for (let dest of result) {
  555. if (dest.province != source.province) {
  556. destination = dest;
  557. break;
  558. }
  559. }
  560. }
  561. return destination;
  562. };
  563.  
  564. const removePrefixContainInResult = (prefix, result) => {
  565. if (!result || !prefix) return prefix;
  566. let newPrefix = [];
  567. for (let pre of prefix) {
  568. let prefixDup = result.filter(r => {
  569. return (
  570. r.district &&
  571. r.index <= pre.index &&
  572. pre.index <= r.index + r.district.length
  573. );
  574. });
  575. if (prefixDup.length === 0) newPrefix.push(pre);
  576. }
  577. return newPrefix;
  578. };
  579.  
  580. const getNearestBreakLine = (prefix, breakLineIndex) => {
  581. if (!breakLineIndex || !prefix) return null;
  582. let nearestBreakLine = breakLineIndex.filter(bl => prefix.index < bl);
  583. //console.log("nearestBreakLine", nearestBreakLine);
  584. if (nearestBreakLine.length > 0) return nearestBreakLine[0];
  585. return null;
  586. };
  587.  
  588. const getLocationMultiTask = (sourceWord, result,flag) => {
  589. let source = null;
  590. let sourceCandidate = [];
  591. const offset = 4;
  592. for (let s of sourceWord) {
  593. if(s.Flag === flag)
  594. {
  595. for (let src of result) {
  596. if (
  597. s.Index + s.Keyword.length <= src.index &&
  598. src.index <= s.Index + s.Keyword.length + offset
  599. ) {
  600. let inputSrc = {keyword:src.keyword ,district:src.district ,province:src.province , lat:src.lat ,lon:src.lon ,index:src.index , workindex:s.WorkIndex};
  601. sourceCandidate.push(inputSrc);
  602. break;
  603. }
  604. }
  605. }
  606. }
  607.  
  608. if (sourceCandidate.length > 0) {
  609. source = orderBy(sourceCandidate, ["Index"], ["asc"])[0];
  610. //source = sourceCandidate.sort(function(a,b){return a.Index - b.Index});
  611. result = result.filter(res => res.Index != source.Index);
  612. } else {
  613. source = result[0];
  614. result = result.slice(1);
  615. }
  616. return source;
  617. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement