AddRoad.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import { listenLayer } from "../ListenLayer";
  2. import Constant from "../Constant";
  3. import { mathUtil } from "../Util/MathUtil";
  4. import { dataService } from "../Service/DataService";
  5. import { pointService } from "../Service/PointService";
  6. import { elementService } from "../Service/ElementService";
  7. import { stateService } from "../Service/StateService";
  8. import VectorType from "../enum/VectorType";
  9. import { roadService } from "../Service/RoadService";
  10. export default class AddRoad {
  11. constructor() {
  12. this.startInfo = {};
  13. this.endInfo = {};
  14. this.canAdd = false;
  15. }
  16. setPointInfo(dir, pointInfo) {
  17. if (dir == "start") {
  18. this.startInfo = {
  19. position: {
  20. x: pointInfo.x,
  21. y: pointInfo.y,
  22. },
  23. linkedPointId: pointInfo.linkedPointId,
  24. linkedRoadId: pointInfo.linkedRoadId,
  25. };
  26. } else if (dir == "end") {
  27. this.endInfo = {
  28. position: {
  29. x: pointInfo.x,
  30. y: pointInfo.y,
  31. },
  32. linkedPointId: pointInfo.linkedPointId,
  33. linkedRoadId: pointInfo.linkedRoadId,
  34. };
  35. }
  36. }
  37. buildRoad() {
  38. console.log("添加路段!");
  39. let joinInfos = this.getJoinsForRoads();
  40. let splitPointIds = this.splitAllJoins(joinInfos);
  41. this.creatNewRoads(splitPointIds);
  42. this.canAdd = false;
  43. this.updateStart(
  44. this.endInfo.position,
  45. splitPointIds[splitPointIds.length - 1]
  46. );
  47. listenLayer.clear();
  48. }
  49. //开始新建公路,可能是多个
  50. creatNewRoads(splitPointIds) {
  51. for (let i = 0; i < splitPointIds.length - 1; ++i) {
  52. let pointId1 = splitPointIds[i];
  53. let pointId2 = splitPointIds[i + 1];
  54. let roadId = roadService.getRoadId(pointId1, pointId2);
  55. if (!roadId) {
  56. let road = roadService.create(pointId1, pointId2);
  57. }
  58. }
  59. }
  60. canAddRoadForEnd(endPt) {
  61. if (listenLayer.modifyPoint) {
  62. if (
  63. mathUtil.getDistance(this.startInfo.position, listenLayer.modifyPoint) <
  64. Constant.minAdsorbPix
  65. ) {
  66. return false;
  67. }
  68. } else {
  69. if (
  70. mathUtil.getDistance(this.startInfo.position, endPt) <
  71. Constant.minAdsorbPix
  72. ) {
  73. return false;
  74. }
  75. }
  76. return true;
  77. }
  78. getJoinsForRoads() {
  79. let result = [];
  80. const roads = dataService.getRoads();
  81. let hasComputerPointIds = [];
  82. let hasExitPointIds = [];
  83. if (this.startInfo.linkedPointId) {
  84. hasComputerPointIds.push(this.startInfo.linkedPointId);
  85. hasExitPointIds.push(this.startInfo.linkedPointId);
  86. result.push({
  87. join: { x: this.startInfo.position.x, y: this.startInfo.position.y },
  88. pointId: this.startInfo.linkedPointId,
  89. });
  90. } else if (this.startInfo.linkedRoadId) {
  91. result.push({
  92. join: { x: this.startInfo.position.x, y: this.startInfo.position.y },
  93. roadId: this.startInfo.linkedRoadId,
  94. });
  95. } else {
  96. result.push({
  97. join: { x: this.startInfo.position.x, y: this.startInfo.position.y },
  98. });
  99. }
  100. if (this.endInfo.linkedPointId) {
  101. hasComputerPointIds.push(this.endInfo.linkedPointId);
  102. hasExitPointIds.push(this.endInfo.linkedPointId);
  103. result.push({
  104. join: { x: this.endInfo.position.x, y: this.endInfo.position.y },
  105. pointId: this.endInfo.linkedPointId,
  106. });
  107. } else if (this.endInfo.linkedRoadId) {
  108. result.push({
  109. join: { x: this.endInfo.position.x, y: this.endInfo.position.y },
  110. roadId: this.endInfo.linkedRoadId,
  111. });
  112. } else {
  113. result.push({
  114. join: { x: this.endInfo.position.x, y: this.endInfo.position.y },
  115. });
  116. }
  117. const line = mathUtil.createLine1(
  118. this.startInfo.position,
  119. this.endInfo.position
  120. );
  121. for (let key in roads) {
  122. if (this.startInfo.linkedRoadId && this.startInfo.linkedRoadId == key) {
  123. continue;
  124. } else if (
  125. this.endInfo.linkedRoadId &&
  126. this.endInfo.linkedRoadId == key
  127. ) {
  128. continue;
  129. }
  130. let road = roads[key];
  131. if (
  132. hasExitPointIds.indexOf(road.startId) > -1 ||
  133. hasExitPointIds.indexOf(road.endId) > -1
  134. ) {
  135. continue;
  136. }
  137. let startPoint = dataService.getPoint(road.startId);
  138. let endPoint = dataService.getPoint(road.endId);
  139. let flag = false;
  140. if (hasComputerPointIds.indexOf(road.startId) < 0) {
  141. hasComputerPointIds.push(road.startId);
  142. const startJoin = mathUtil.getJoinLinePoint(startPoint, line);
  143. if (
  144. mathUtil.PointInSegment(
  145. startJoin,
  146. this.startInfo.position,
  147. this.endInfo.position,
  148. Constant.minAdsorbPix
  149. ) &&
  150. mathUtil.getDistance(startPoint, startJoin) < Constant.minAdsorbPix
  151. ) {
  152. result.push({
  153. join: { x: startJoin.x, y: startJoin.y },
  154. pointId: road.startId,
  155. });
  156. flag = true;
  157. hasExitPointIds.push(road.startId);
  158. }
  159. }
  160. if (hasComputerPointIds.indexOf(road.endId) < 0) {
  161. hasComputerPointIds.push(road.endId);
  162. const endJoin = mathUtil.getJoinLinePoint(endPoint, line);
  163. if (
  164. mathUtil.PointInSegment(
  165. endJoin,
  166. this.startInfo.position,
  167. this.endInfo.position,
  168. Constant.minAdsorbPix
  169. ) &&
  170. mathUtil.getDistance(endPoint, endJoin) < Constant.minAdsorbPix
  171. ) {
  172. result.push({
  173. join: { x: endJoin.x, y: endJoin.y },
  174. pointId: road.endId,
  175. });
  176. flag = true;
  177. hasExitPointIds.push(road.endId);
  178. }
  179. }
  180. if (!flag) {
  181. //不与墙key的端点相交
  182. if (
  183. hasExitPointIds.indexOf(road.startId) < 0 &&
  184. hasExitPointIds.indexOf(road.endId) < 0
  185. ) {
  186. let join = mathUtil.getIntersectionPoint3(
  187. startPoint,
  188. endPoint,
  189. this.startInfo.position,
  190. this.endInfo.position
  191. );
  192. if (join) {
  193. result.push({ join: { x: join.x, y: join.y }, roadId: key });
  194. }
  195. }
  196. }
  197. }
  198. return result;
  199. }
  200. splitAllJoins(joinInfos) {
  201. // 对joinInfos要进行排序
  202. joinInfos = joinInfos.sort(sortNumber.bind(this));
  203. function sortNumber(a, b) {
  204. return (
  205. mathUtil.getDistance(this.startInfo.position, a.join) -
  206. mathUtil.getDistance(this.startInfo.position, b.join)
  207. );
  208. }
  209. const splitPointIds = [];
  210. for (let i = 0; i < joinInfos.length; ++i) {
  211. const info = joinInfos[i];
  212. const join = info.join;
  213. const roadId = info.roadId;
  214. const pointId = info.pointId;
  215. if (pointId) {
  216. splitPointIds.push(pointId);
  217. } else if (roadId) {
  218. // 拆分roadId
  219. const splitPoint = pointService.create(join);
  220. const splitPointId = splitPoint.vectorId;
  221. //可能joinInfos的两个点都在roadId上
  222. let newRoadId = null;
  223. if (
  224. joinInfos[i + 1] &&
  225. joinInfos[i].roadId == joinInfos[i + 1].roadId
  226. ) {
  227. let road = dataService.getRoad(roadId);
  228. let startPoint = dataService.getPoint(road.startId);
  229. if (
  230. mathUtil.getDistance(startPoint, joinInfos[i].join) <
  231. mathUtil.getDistance(startPoint, joinInfos[i + 1].join)
  232. ) {
  233. newRoadId = roadService.splitRoad(roadId, splitPointId, "end");
  234. } else {
  235. newRoadId = roadService.splitRoad(roadId, splitPointId, "start");
  236. }
  237. } else {
  238. newRoadId = roadService.splitRoad(roadId, splitPointId, "start");
  239. }
  240. if (newRoadId == null) {
  241. dataService.deletePoint(splitPointId);
  242. continue;
  243. }
  244. splitPointIds.push(splitPointId);
  245. }
  246. //首尾没有吸附的情况
  247. else {
  248. const splitPoint = pointService.create(join);
  249. splitPointIds.push(splitPoint.vectorId);
  250. }
  251. }
  252. return splitPointIds;
  253. }
  254. updateStart(position, linkedPointId) {
  255. mathUtil.clonePoint(this.startInfo.position, position);
  256. this.startInfo.linkedPointId = linkedPointId;
  257. elementService.setNewRoadStartPosition(this.startInfo.position);
  258. }
  259. setNewRoadPoint(dir, position) {
  260. if (dir == "start") {
  261. if (listenLayer.modifyPoint) {
  262. this.setPointInfo(dir, listenLayer.modifyPoint);
  263. } else {
  264. this.setPointInfo(dir, position);
  265. }
  266. return true;
  267. } else if (dir == "end") {
  268. if (listenLayer.modifyPoint) {
  269. this.setPointInfo(dir, listenLayer.modifyPoint);
  270. } else {
  271. this.setPointInfo(dir, position);
  272. }
  273. return true;
  274. }
  275. return false;
  276. }
  277. clear() {
  278. this.startInfo = {};
  279. this.endInfo = {};
  280. this.canAdd = false;
  281. elementService.hideNewRoad();
  282. elementService.hideStartAddRoad();
  283. }
  284. }
  285. const addRoad = new AddRoad();
  286. export { addRoad };