123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
- import { readFileSync } from 'fs';
- import { join } from 'path';
- import { CacheService } from 'src/cache/cache.service';
- @Injectable()
- export class GetRouterService implements OnModuleInit {
- constructor(private cacheService: CacheService) {}
- private breakPointInfo: any;
- private logger: Logger = new Logger('GetRouterService');
- async onModuleInit() {
- try {
- const path = join(__dirname, '../ws/points-BreakPointId.json');
- // const path = join(__dirname, '../ws/demo1.json');
- const data = await readFileSync(path);
- const BreakPointInfo = JSON.parse(Buffer.from(data).toString('utf-8'));
- this.breakPointInfo = BreakPointInfo;
- // console.log('BreakPointInfo', BreakPointInfo);
- } catch (error) {
- this.logger.error('load-json-error', error);
- }
- }
- searchRoad(appId, startPointId, clicking_point) {
- try {
- console.log('进入2 - searchRoad');
- //表示终点
- let endPoint;
- //const keys = this.cacheService.keys(`breakpoints:app_id:${appId}*`);
- let minDis = null;
- //for (let i = 0; i < keys.length; ++i) {
- for (const key in this.breakPointInfo) {
- //const breakPointRes = await this.cacheService.get(keys[i]);
- //const breakPoint = JSON.parse(breakPointRes);
- if (Number(key) == startPointId) {
- continue;
- }
- //const position = breakPoint.position;
- const breakPoint = this.breakPointInfo[key];
- if (minDis == null) {
- minDis = this.getDistance(clicking_point, breakPoint.position);
- endPoint = breakPoint;
- endPoint.breakPointId = Number(key);
- } else if (
- minDis > this.getDistance(clicking_point, breakPoint.position)
- ) {
- endPoint = breakPoint;
- minDis = this.getDistance(clicking_point, breakPoint.position);
- endPoint.breakPointId = Number(key);
- }
- }
- if (minDis > 100) {
- return null;
- }
- // const startPointRes = await this.cacheService.get(
- // 'breakpoints:app_id:' + appId + ':break_point_id:' + startPointId,
- // );
- // const startPoint = JSON.parse(startPointRes);
- const startPoint = this.breakPointInfo[startPointId];
- if (startPoint.contact.indexOf(endPoint.breakPointId) > -1) {
- // debugger;
- return [startPointId, endPoint.breakPointId];
- }
- // const endPointRes = await this.cacheService.get(
- // 'breakpoints:app_id:' + appId + ':break_point_id:' + endPointId,
- // );
- // const endPoint = JSON.parse(endPointRes);
- const openList = [], //开启列表
- closeList = []; //关闭列表
- let result = []; //结果数组
- let result_index: number; //结果数组在开启列表中的序号
- //openList.push({x:startPoint.x,y:startPoint.y,G:0});//把当前点加入到开启列表中,并且G是0
- openList.push({
- breakPointId: startPointId,
- G: 0,
- position: startPoint.position,
- contact: startPoint.contact,
- }); //把当前点加入到开启列表中,并且G是0
- do {
- const currentPoint = openList.pop();
- // const currentPointId = currentPointInfo.breakPointId;
- // const currentPoint = {
- // breakPointId: currentPointInfo.breakPointId,
- // position: this.breakPointInfo[currentPointId].position,
- // contact:this.breakPointInfo[currentPointId].contact,
- // G: currentPointInfo.G,
- // };
- closeList.push(currentPoint);
- if (closeList.length > 10000) {
- console.log('错误过渡路径:', closeList.length);
- return null;
- }
- //读redis里的数据
- // const breakPointRes = await this.cacheService.get(
- // 'breakpoints:app_id:' +
- // appId +
- // ':break_point_id:' +
- // currentPointInfo.breakPointId,
- // );
- let surroundPoint = [];
- //const _breakPoint = JSON.parse(breakPointRes);
- const _breakPoint = this.breakPointInfo[currentPoint.breakPointId];
- surroundPoint = _breakPoint.contact;
- for (let i = 0; i < surroundPoint.length; ++i) {
- const neighPointId = surroundPoint[i];
- // const itemRes = await this.cacheService.get(
- // 'breakpoints:app_id:' + appId + ':break_point_id:' + neighPointId,
- // );
- // const item = JSON.parse(itemRes);
- const item = this.breakPointInfo[neighPointId];
- if (this.existList(item, closeList) != -1) {
- continue;
- }
- item.breakPointId = neighPointId;
- //g 到父节点的位置
- const g =
- currentPoint.G +
- this.getDistance(currentPoint.position, item.position);
- if (this.existList(item, openList) == -1) {
- //如果不在开启列表中
- item['H'] = this.getDistance(endPoint.position, item.position);
- item['G'] = g;
- item['F'] = item.H + item.G;
- item['parent'] = currentPoint;
- openList.push(item);
- } else {
- //存在在开启列表中,比较目前的g值和之前的g的大小
- const index = this.existList(item, openList);
- //如果当前点的g更小
- if (g < openList[index].G) {
- openList[index].parent = currentPoint;
- openList[index].G = g;
- openList[index].F = g + openList[index].H;
- }
- }
- }
- //如果开启列表空了,没有通路,结果为空
- if (openList.length == 0) {
- break;
- }
- openList.sort(this.sortF); //这一步是为了循环回去的时候,找出 F 值最小的, 将它从 "开启列表" 中移掉
- } while ((result_index = this.existList(endPoint, openList)) == -1);
- //判断结果列表是否为空
- let currentObj;
- if (result_index == -1) {
- result = [];
- } else {
- currentObj = openList[result_index];
- do {
- //把路劲节点添加到result当中
- result.unshift(currentObj.breakPointId);
- currentObj = currentObj.parent;
- if (!currentObj) {
- break;
- }
- } while (
- //currentObj.position.x != startPoint.position.x ||
- //currentObj.position.y != startPoint.position.y
- result.length < 50 &&
- currentObj.contact.indexOf(startPointId) < 0
- );
- }
- if (result.length > 30) {
- console.log('错误过渡路径:' + result);
- // debugger;
- return null;
- }
- result.unshift(currentObj.breakPointId);
- result.unshift(startPointId);
- console.log('path-end' + result);
- // debugger;
- return result;
- } catch (error) {
- console.error('searchRoad', error);
- return [];
- }
- }
- //用F值对数组排序
- sortF(a, b) {
- return b.F - a.F;
- }
- //获取周围点
- async SurroundPoint(appId, curPointId, endPoint) {
- //读redis里的数据
- const breakPointRes = await this.cacheService.get(
- 'breakpoints:app_id:' + appId + ':break_point_id:' + curPointId,
- );
- const breakPoint = JSON.parse(breakPointRes);
- if (this.getDistance(breakPoint.position, endPoint.position) < 1) {
- breakPoint.contact.push(endPoint.breakPointId);
- }
- return breakPoint.contact;
- }
- //判断点是否存在在列表中,是的话返回的是序列号
- existList(point, list) {
- for (let i = 0; i < list.length; ++i) {
- if (point.breakPointId == list[i].breakPointId) {
- return i;
- }
- }
- return -1;
- }
- getDistance(position1, position2) {
- return Math.sqrt(
- (position1.x - position2.x) * (position1.x - position2.x) +
- (position1.y - position2.y) * (position1.y - position2.y),
- );
- }
- }
|