get-router.service.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
  2. import { readFileSync } from 'fs';
  3. import { join } from 'path';
  4. import { CacheService } from 'src/cache/cache.service';
  5. @Injectable()
  6. export class GetRouterService implements OnModuleInit {
  7. constructor(private cacheService: CacheService) {}
  8. private breakPointInfo: any;
  9. private logger: Logger = new Logger('GetRouterService');
  10. async onModuleInit() {
  11. try {
  12. const path = join(__dirname, '../ws/points-BreakPointId.json');
  13. // const path = join(__dirname, '../ws/demo1.json');
  14. const data = await readFileSync(path);
  15. const BreakPointInfo = JSON.parse(Buffer.from(data).toString('utf-8'));
  16. this.breakPointInfo = BreakPointInfo;
  17. // console.log('BreakPointInfo', BreakPointInfo);
  18. } catch (error) {
  19. this.logger.error('load-json-error', error);
  20. }
  21. }
  22. searchRoad(appId, startPointId, clicking_point) {
  23. try {
  24. console.log('进入2 - searchRoad');
  25. //表示终点
  26. let endPoint;
  27. //const keys = this.cacheService.keys(`breakpoints:app_id:${appId}*`);
  28. let minDis = null;
  29. //for (let i = 0; i < keys.length; ++i) {
  30. for (const key in this.breakPointInfo) {
  31. //const breakPointRes = await this.cacheService.get(keys[i]);
  32. //const breakPoint = JSON.parse(breakPointRes);
  33. if (Number(key) == startPointId) {
  34. continue;
  35. }
  36. //const position = breakPoint.position;
  37. const breakPoint = this.breakPointInfo[key];
  38. if (minDis == null) {
  39. minDis = this.getDistance(clicking_point, breakPoint.position);
  40. endPoint = breakPoint;
  41. endPoint.breakPointId = Number(key);
  42. } else if (
  43. minDis > this.getDistance(clicking_point, breakPoint.position)
  44. ) {
  45. endPoint = breakPoint;
  46. minDis = this.getDistance(clicking_point, breakPoint.position);
  47. endPoint.breakPointId = Number(key);
  48. }
  49. }
  50. if (minDis > 100) {
  51. return null;
  52. }
  53. // const startPointRes = await this.cacheService.get(
  54. // 'breakpoints:app_id:' + appId + ':break_point_id:' + startPointId,
  55. // );
  56. // const startPoint = JSON.parse(startPointRes);
  57. const startPoint = this.breakPointInfo[startPointId];
  58. if (startPoint.contact.indexOf(endPoint.breakPointId) > -1) {
  59. // debugger;
  60. return [startPointId, endPoint.breakPointId];
  61. }
  62. // const endPointRes = await this.cacheService.get(
  63. // 'breakpoints:app_id:' + appId + ':break_point_id:' + endPointId,
  64. // );
  65. // const endPoint = JSON.parse(endPointRes);
  66. const openList = [], //开启列表
  67. closeList = []; //关闭列表
  68. let result = []; //结果数组
  69. let result_index: number; //结果数组在开启列表中的序号
  70. //openList.push({x:startPoint.x,y:startPoint.y,G:0});//把当前点加入到开启列表中,并且G是0
  71. openList.push({
  72. breakPointId: startPointId,
  73. G: 0,
  74. position: startPoint.position,
  75. contact: startPoint.contact,
  76. }); //把当前点加入到开启列表中,并且G是0
  77. do {
  78. const currentPoint = openList.pop();
  79. // const currentPointId = currentPointInfo.breakPointId;
  80. // const currentPoint = {
  81. // breakPointId: currentPointInfo.breakPointId,
  82. // position: this.breakPointInfo[currentPointId].position,
  83. // contact:this.breakPointInfo[currentPointId].contact,
  84. // G: currentPointInfo.G,
  85. // };
  86. closeList.push(currentPoint);
  87. if (closeList.length > 10000) {
  88. console.log('错误过渡路径:', closeList.length);
  89. return null;
  90. }
  91. //读redis里的数据
  92. // const breakPointRes = await this.cacheService.get(
  93. // 'breakpoints:app_id:' +
  94. // appId +
  95. // ':break_point_id:' +
  96. // currentPointInfo.breakPointId,
  97. // );
  98. let surroundPoint = [];
  99. //const _breakPoint = JSON.parse(breakPointRes);
  100. const _breakPoint = this.breakPointInfo[currentPoint.breakPointId];
  101. surroundPoint = _breakPoint.contact;
  102. for (let i = 0; i < surroundPoint.length; ++i) {
  103. const neighPointId = surroundPoint[i];
  104. // const itemRes = await this.cacheService.get(
  105. // 'breakpoints:app_id:' + appId + ':break_point_id:' + neighPointId,
  106. // );
  107. // const item = JSON.parse(itemRes);
  108. const item = this.breakPointInfo[neighPointId];
  109. if (this.existList(item, closeList) != -1) {
  110. continue;
  111. }
  112. item.breakPointId = neighPointId;
  113. //g 到父节点的位置
  114. const g =
  115. currentPoint.G +
  116. this.getDistance(currentPoint.position, item.position);
  117. if (this.existList(item, openList) == -1) {
  118. //如果不在开启列表中
  119. item['H'] = this.getDistance(endPoint.position, item.position);
  120. item['G'] = g;
  121. item['F'] = item.H + item.G;
  122. item['parent'] = currentPoint;
  123. openList.push(item);
  124. } else {
  125. //存在在开启列表中,比较目前的g值和之前的g的大小
  126. const index = this.existList(item, openList);
  127. //如果当前点的g更小
  128. if (g < openList[index].G) {
  129. openList[index].parent = currentPoint;
  130. openList[index].G = g;
  131. openList[index].F = g + openList[index].H;
  132. }
  133. }
  134. }
  135. //如果开启列表空了,没有通路,结果为空
  136. if (openList.length == 0) {
  137. break;
  138. }
  139. openList.sort(this.sortF); //这一步是为了循环回去的时候,找出 F 值最小的, 将它从 "开启列表" 中移掉
  140. } while ((result_index = this.existList(endPoint, openList)) == -1);
  141. //判断结果列表是否为空
  142. let currentObj;
  143. if (result_index == -1) {
  144. result = [];
  145. } else {
  146. currentObj = openList[result_index];
  147. do {
  148. //把路劲节点添加到result当中
  149. result.unshift(currentObj.breakPointId);
  150. currentObj = currentObj.parent;
  151. if (!currentObj) {
  152. break;
  153. }
  154. } while (
  155. //currentObj.position.x != startPoint.position.x ||
  156. //currentObj.position.y != startPoint.position.y
  157. result.length < 50 &&
  158. currentObj.contact.indexOf(startPointId) < 0
  159. );
  160. }
  161. if (result.length > 30) {
  162. console.log('错误过渡路径:' + result);
  163. // debugger;
  164. return null;
  165. }
  166. result.unshift(currentObj.breakPointId);
  167. result.unshift(startPointId);
  168. console.log('path-end' + result);
  169. // debugger;
  170. return result;
  171. } catch (error) {
  172. console.error('searchRoad', error);
  173. return [];
  174. }
  175. }
  176. //用F值对数组排序
  177. sortF(a, b) {
  178. return b.F - a.F;
  179. }
  180. //获取周围点
  181. async SurroundPoint(appId, curPointId, endPoint) {
  182. //读redis里的数据
  183. const breakPointRes = await this.cacheService.get(
  184. 'breakpoints:app_id:' + appId + ':break_point_id:' + curPointId,
  185. );
  186. const breakPoint = JSON.parse(breakPointRes);
  187. if (this.getDistance(breakPoint.position, endPoint.position) < 1) {
  188. breakPoint.contact.push(endPoint.breakPointId);
  189. }
  190. return breakPoint.contact;
  191. }
  192. //判断点是否存在在列表中,是的话返回的是序列号
  193. existList(point, list) {
  194. for (let i = 0; i < list.length; ++i) {
  195. if (point.breakPointId == list[i].breakPointId) {
  196. return i;
  197. }
  198. }
  199. return -1;
  200. }
  201. getDistance(position1, position2) {
  202. return Math.sqrt(
  203. (position1.x - position2.x) * (position1.x - position2.x) +
  204. (position1.y - position2.y) * (position1.y - position2.y),
  205. );
  206. }
  207. }