get-router.service.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { Injectable } from '@nestjs/common';
  2. import { CacheService } from 'src/cache/cache.service';
  3. @Injectable()
  4. export class GetRouterService {
  5. constructor(private cacheService: CacheService) {}
  6. async searchRoad(appId, startPointId, clicking_point) {
  7. //表示终点
  8. let endPoint;
  9. const keys = await this.cacheService.keys(`breakpoints:app_id:${appId}*`);
  10. let minDis = null;
  11. for (let i = 0; i < keys.length; ++i) {
  12. const breakPointRes = await this.cacheService.get(keys[i]);
  13. const breakPoint = JSON.parse(breakPointRes);
  14. if (breakPoint.breakPointId == startPointId) {
  15. continue;
  16. }
  17. const position = breakPoint.position;
  18. if (minDis == null) {
  19. minDis = this.getDistance(clicking_point, position);
  20. endPoint = breakPoint;
  21. } else if (minDis > this.getDistance(clicking_point, position)) {
  22. endPoint = breakPoint;
  23. minDis = this.getDistance(clicking_point, position);
  24. }
  25. }
  26. if (minDis > 100) {
  27. return [];
  28. }
  29. const startPointRes = await this.cacheService.get(
  30. 'breakpoints:app_id:' + appId + ':break_point_id:' + startPointId,
  31. );
  32. const startPoint = JSON.parse(startPointRes);
  33. // const endPointRes = await this.cacheService.get(
  34. // 'breakpoints:app_id:' + appId + ':break_point_id:' + endPointId,
  35. // );
  36. // const endPoint = JSON.parse(endPointRes);
  37. const openList = [], //开启列表
  38. closeList = []; //关闭列表
  39. let result = []; //结果数组
  40. let result_index: number; //结果数组在开启列表中的序号
  41. //openList.push({x:startPoint.x,y:startPoint.y,G:0});//把当前点加入到开启列表中,并且G是0
  42. openList.push({ breakPointId: startPointId, G: 0 }); //把当前点加入到开启列表中,并且G是0
  43. do {
  44. const currentPointInfo = openList.pop();
  45. const currentPointRes = await this.cacheService.get(
  46. 'breakpoints:app_id:' +
  47. appId +
  48. ':break_point_id:' +
  49. currentPointInfo.breakPointId,
  50. );
  51. const currentPoint = JSON.parse(currentPointRes);
  52. closeList.push(currentPointInfo);
  53. //读redis里的数据
  54. const breakPointRes = await this.cacheService.get(
  55. 'breakpoints:app_id:' +
  56. appId +
  57. ':break_point_id:' +
  58. currentPointInfo.breakPointId,
  59. );
  60. let surroundPoint = [];
  61. const _breakPoint = JSON.parse(breakPointRes);
  62. surroundPoint = _breakPoint.contact;
  63. for (let i = 0; i < surroundPoint.length; ++i) {
  64. const neighPointId = surroundPoint[i];
  65. const itemRes = await this.cacheService.get(
  66. 'breakpoints:app_id:' + appId + ':break_point_id:' + neighPointId,
  67. );
  68. const item = JSON.parse(itemRes);
  69. //g 到父节点的位置
  70. const g =
  71. currentPointInfo.G +
  72. this.getDistance(currentPoint.position, item.position);
  73. if (this.existList(item, openList) == -1) {
  74. //如果不在开启列表中
  75. item['H'] = 0;
  76. item['G'] = g;
  77. item['F'] = item.H + item.G;
  78. item['parent'] = currentPoint;
  79. openList.push(item);
  80. } else {
  81. //存在在开启列表中,比较目前的g值和之前的g的大小
  82. const index = this.existList(item, openList);
  83. //如果当前点的g更小
  84. if (g < openList[index].G) {
  85. openList[index].parent = currentPoint;
  86. openList[index].G = g;
  87. openList[index].F = g + openList[index].H;
  88. }
  89. }
  90. }
  91. //如果开启列表空了,没有通路,结果为空
  92. if (openList.length == 0) {
  93. break;
  94. }
  95. openList.sort(this.sortF); //这一步是为了循环回去的时候,找出 F 值最小的, 将它从 "开启列表" 中移掉
  96. } while ((result_index = this.existList(endPoint, openList)) == -1);
  97. //判断结果列表是否为空
  98. if (result_index == -1) {
  99. result = [];
  100. } else {
  101. let currentObj = openList[result_index];
  102. do {
  103. //把路劲节点添加到result当中
  104. result.unshift(currentObj.breakPointId);
  105. currentObj = currentObj.parent;
  106. // debugger
  107. } while (
  108. currentObj.position.x != startPoint.position.x ||
  109. currentObj.position.y != startPoint.position.y
  110. );
  111. }
  112. result.unshift(startPointId);
  113. return result;
  114. }
  115. //用F值对数组排序
  116. sortF(a, b) {
  117. return b.F - a.F;
  118. }
  119. //获取周围点
  120. async SurroundPoint(appId, curPointId, endPoint) {
  121. //读redis里的数据
  122. const breakPointRes = await this.cacheService.get(
  123. 'breakpoints:app_id:' + appId + ':break_point_id:' + curPointId,
  124. );
  125. const breakPoint = JSON.parse(breakPointRes);
  126. if (this.getDistance(breakPoint.position, endPoint.position) < 1) {
  127. breakPoint.contact.push(endPoint.breakPointId);
  128. }
  129. return breakPoint.contact;
  130. }
  131. //判断点是否存在在列表中,是的话返回的是序列号
  132. existList(point, list) {
  133. for (let i = 0; i < list.length; ++i) {
  134. if (point.breakPointId == list[i].breakPointId) {
  135. return i;
  136. }
  137. }
  138. return -1;
  139. }
  140. getDistance(position1, position2) {
  141. return Math.sqrt(
  142. (position1.x - position2.x) * (position1.x - position2.x) +
  143. (position1.y - position2.y) * (position1.y - position2.y),
  144. );
  145. }
  146. }