gisviewer-vue3-arcgis 1.0.115 → 1.0.116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/src/gis-map/gis-map.vue.d.ts +5 -3
- package/es/src/gis-map/gis-map.vue.mjs +93 -92
- package/es/src/gis-map/index.d.ts +4 -2
- package/es/src/gis-map/stores/appData.d.ts +3 -0
- package/es/src/gis-map/stores/appData.mjs +7 -4
- package/es/src/gis-map/utils/common-utils.d.ts +12 -0
- package/es/src/gis-map/utils/common-utils.mjs +81 -43
- package/es/src/gis-map/utils/holo-flow/trace-renderer-external.mjs +3 -3
- package/es/src/gis-map/utils/holo-flow/trace-renderer-layer.mjs +0 -1
- package/es/src/gis-map/utils/open-drive-renderer/draw-bezier.d.ts +17 -0
- package/es/src/gis-map/utils/open-drive-renderer/draw-bezier.mjs +49 -0
- package/es/src/gis-map/utils/open-drive-renderer/index.d.ts +31 -3
- package/es/src/gis-map/utils/open-drive-renderer/index.mjs +274 -44
- package/es/src/gis-map/utils/open-drive-renderer/junction.d.ts +50 -0
- package/es/src/gis-map/utils/open-drive-renderer/junction.mjs +151 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane-section.d.ts +48 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane-section.mjs +82 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane-utils.d.ts +29 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane-utils.mjs +265 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane.d.ts +70 -0
- package/es/src/gis-map/utils/open-drive-renderer/lane.mjs +93 -0
- package/es/src/gis-map/utils/open-drive-renderer/road.d.ts +60 -0
- package/es/src/gis-map/utils/open-drive-renderer/road.mjs +113 -0
- package/es/src/gis-map/utils/open-drive-renderer/wasm-loader.d.ts +88 -0
- package/es/src/gis-map/utils/open-drive-renderer/wasm-loader.mjs +366 -0
- package/es/src/types/index.d.ts +48 -0
- package/lib/src/gis-map/gis-map.vue.d.ts +5 -3
- package/lib/src/gis-map/gis-map.vue.js +1 -1
- package/lib/src/gis-map/index.d.ts +4 -2
- package/lib/src/gis-map/stores/appData.d.ts +3 -0
- package/lib/src/gis-map/stores/appData.js +1 -1
- package/lib/src/gis-map/utils/common-utils.d.ts +12 -0
- package/lib/src/gis-map/utils/common-utils.js +1 -1
- package/lib/src/gis-map/utils/holo-flow/trace-renderer-external.js +1 -1
- package/lib/src/gis-map/utils/holo-flow/trace-renderer-layer.js +1 -1
- package/lib/src/gis-map/utils/open-drive-renderer/draw-bezier.d.ts +17 -0
- package/lib/src/gis-map/utils/open-drive-renderer/draw-bezier.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/index.d.ts +31 -3
- package/lib/src/gis-map/utils/open-drive-renderer/index.js +1 -1
- package/lib/src/gis-map/utils/open-drive-renderer/junction.d.ts +50 -0
- package/lib/src/gis-map/utils/open-drive-renderer/junction.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane-section.d.ts +48 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane-section.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane-utils.d.ts +29 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane-utils.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane.d.ts +70 -0
- package/lib/src/gis-map/utils/open-drive-renderer/lane.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/road.d.ts +60 -0
- package/lib/src/gis-map/utils/open-drive-renderer/road.js +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/wasm-loader.d.ts +88 -0
- package/lib/src/gis-map/utils/open-drive-renderer/wasm-loader.js +1 -0
- package/lib/src/types/index.d.ts +48 -0
- package/package.json +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("pinia"),t=e.defineStore("appData",{state:()=>({mapConfig:{},saveTrackLog:!1})});exports.useAppDataStore=t;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("pinia"),t=e.defineStore("appData",{state:()=>({mapConfig:{},saveTrackLog:!1,geoReference:"",xOffset:0,yOffset:0})});exports.useAppDataStore=t;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Point, Polygon, Polyline } from '@arcgis/core/geometry';
|
|
2
|
+
import * as turf from '@turf/helpers';
|
|
2
3
|
export default class CommonUtils {
|
|
3
4
|
/**
|
|
4
5
|
* 得到某个点在一定方向、距离之外的另一个点
|
|
@@ -62,4 +63,15 @@ export default class CommonUtils {
|
|
|
62
63
|
* @returns
|
|
63
64
|
*/
|
|
64
65
|
static unzip(key: string): string | undefined;
|
|
66
|
+
static getStdVecEntries(std_vec: any, delete_vec?: boolean): any[];
|
|
67
|
+
static getStdMapEntries(std_map: any): any[];
|
|
68
|
+
static getStdMapKeys(std_map: any, delete_map?: boolean): any[];
|
|
69
|
+
/**
|
|
70
|
+
* OpenDrive坐标转换为WGS84坐标
|
|
71
|
+
* @param line
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
static transformLineProjection(line: number[][]): number[][];
|
|
75
|
+
static pointsEqual(point1: number[], point2: number[]): boolean;
|
|
76
|
+
static getExtensionLine(pt1: number[], pt2: number[], distance: number): turf.Position;
|
|
65
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("@arcgis/core/geometry"),O=require("@arcgis/core/geometry/geometryEngineAsync"),L=require("@arcgis/core/geometry/support/webMercatorUtils"),l=require("@turf/bearing"),g=require("@turf/destination"),w=require("@turf/helpers"),b=require("pako"),m=require("proj4"),A=require("../stores/appData.js");function y(c){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(c){for(const e in c)if(e!=="default"){const n=Object.getOwnPropertyDescriptor(c,e);Object.defineProperty(t,e,n.get?n:{enumerable:!0,get:()=>c[e]})}}return t.default=c,Object.freeze(t)}const p=y(O),P=y(L),a=y(w);class i{static destinationWithPoint(t,e,n){const r=a.point([t.x,t.y]),s=g(r,n,e,{units:"meters"});return new u.Point({x:s.geometry.coordinates[0],y:s.geometry.coordinates[1]})}static angleOfLine(t){const e=t.paths[0],n=a.point(e[0]),r=a.point(e[e.length-1]);return l(n,r)}static extendLineInTowDir(t,e){const n=t.paths[0],r=a.point(n[0]),s=a.point(n[1]),o=l(s,r),f=g(r,e,o,{units:"meters"}),h=o>0?o-180:o+180,d=g(s,e,h,{units:"meters"});return new u.Polyline({paths:[[f.geometry.coordinates,d.geometry.coordinates]]})}static async getIntersectPointOfTwoLines(t,e){const n=await p.intersectLinesToPoints(t,e);if(n.length)return n[0]}static async getIntersectPointsOfStopLineAndLane(t,e,n){let r=await i.getIntersectPointOfLineAndPolygon(t,e);if(await i.pointDistance(r)<3&&n){for(const s of n)if(r=await i.getIntersectPointOfLineAndPolygon(t,e,s),await i.pointDistance(r)>2.5){const o=new u.Polyline({paths:[r]});return(await i.getOffsetLine(o,-s)).paths[0]}}else return r;return[]}static async pointDistance(t){if(t.length<2)return 0;const e=new u.Polyline({paths:[t]});return await p.geodesicLength(e,"meters")}static async getIntersectPointOfLineAndPolygon(t,e,n=0){n!==0&&(t=await i.getOffsetLine(t,n));const r=await p.intersect(t,e);if(r instanceof u.Polyline){const s=r.paths[0],o=s[0],f=s[s.length-1];return[o,f]}return[]}static async getOffsetLine(t,e){const n=P.geographicToWebMercator(t),r=await p.offset(n,e,"meters");return P.webMercatorToGeographic(r,!1)}static unzip(t){try{const e=[],n=t.split("");for(let s=0;s<n.length;s++){const o=n[s];e.push(o.charCodeAt(0))}const r=new Uint8Array(e);return b.inflate(r,{to:"string"})}catch{console.log(`非压缩内容: ${t}`)}}static getStdVecEntries(t,e=!1){const n=new Array(t.size());for(let r=0;r<t.size();r++)n[r]=t.get(r);return e&&t.delete(),n}static getStdMapEntries(t){const e=[];for(const n of i.getStdMapKeys(t))e.push([n,t.get(n)]);return e}static getStdMapKeys(t,e=!1){const n=[],r=t.keys();for(let s=0;s<r.size();s++)n.push(r.get(s));return r.delete(),e&&t.delete(),n}static transformLineProjection(t){const e=A.useAppDataStore(),n=e.geoReference,r=e.xOffset,s=e.yOffset;return t.map(o=>m(n).inverse([o[0]-r,o[1]-s]))}static pointsEqual(t,e){return Math.abs(t[0]-e[0])<Number.EPSILON&&Math.abs(t[1]-e[1])<Number.EPSILON}static getExtensionLine(t,e,n){const r=a.point(t),s=a.point(e),o=l(r,s);return g(s,n,o,{units:"meters"}).geometry.coordinates}}exports.default=i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const v=require("@arcgis/core/core/promiseUtils.js"),y=require("@arcgis/core/core/reactiveUtils.js"),T=require("@arcgis/core/geometry/SpatialReference"),S=require("@arcgis/core/views/3d/externalRenderers"),C=require("three"),G=require("three/examples/jsm/loaders/GLTFLoader"),m=require("../../../types/index.js"),B=require("../../stores/index.js");function f(u){const i=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(u){for(const e in u)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(u,e);Object.defineProperty(i,e,t.get?t:{enumerable:!0,get:()=>u[e]})}}return i.default=u,Object.freeze(i)}const R=f(v),I=f(y),M=f(S),l=f(C);class V{constructor(i){this.cameraHeightThreshold=1e3,this.roughness=.2,this.metalness=.8,this.defaultMaterial=new l.MeshPhongMaterial({color:16777215}),this.materialMap=new Map([[1,this.createCarMaterial(16777215)],[2,this.createCarMaterial(7833753)],[3,this.createCarMaterial(16766720)],[4,this.createCarMaterial(16758465)],[5,this.createCarMaterial(14423100)],[6,this.createCarMaterial(3329330)],[7,this.createCarMaterial(2003183)],[8,this.createCarMaterial(16032864)],[9,this.createCarMaterial(2105376)],[10,this.createCarMaterial(9662683)],[99,this.createCarMaterial(6908265)]]),this.isInitialized=!1,this.showGroundVehicle=!0,this.showElevatedVehicle=!0,this.isPaused=!1,this.currentSpriteContent=m.EVehiclePlateState.None,this.historyPositionMap=new Map,this.vehicleObjectMap=new Map,this.needInterpolate=!0,this.updateModel=!1,this.appDataStore=B.default.useAppDataStore,this.logTable=[["ptcId","plateno","timestamp","localTimestamp","speed","longitude","latitude","ptcType","vehicleType","vehicleColor","plateColor","heading","fixAngle","roadLayer","step","receiveTimestamp","queueLength","status"]],this.assetsRoot=JSON.parse(JSON.stringify(this.appDataStore.mapConfig)).assetsRoot,this.view=i,I.watch(()=>this.view.camera.position.z,(e,t)=>{(t<=this.cameraHeightThreshold&&e>this.cameraHeightThreshold||t>this.cameraHeightThreshold&&e<=this.cameraHeightThreshold)&&(this.updateModel=!0)})}createCarMaterial(i){return new l.MeshPhongMaterial({color:i})}getLog(){return this.logTable}async init(){const i=new G.GLTFLoader;await R.eachAlways([new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/car.glb`,t=>{this.carModel=t.scene,this.carModel.rotation.x=l.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/van.glb`,t=>{this.vanModel=t.scene,this.vanModel.rotation.x=l.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/truck.glb`,t=>{this.truckModel=t.scene,this.truckModel.scale.set(1.2,1,1.5),this.truckModel.rotation.x=l.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/bus.glb`,t=>{this.busModel=t.scene,this.busModel.rotation.x=l.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/bicycle.glb`,t=>{this.bicycleModel=t.scene,this.bicycleModel.rotation.x=l.MathUtils.degToRad(90),this.bicycleModel.rotation.y=l.MathUtils.degToRad(180),e()})}),new Promise(e=>{this.bluePlateBG=new Image,this.bluePlateBG.src=`${this.assetsRoot}/Images/PlateBG/blue.png`,this.bluePlateBG.onload=()=>{e()}}),new Promise(e=>{this.yellowPlateBG=new Image,this.yellowPlateBG.src=`${this.assetsRoot}/Images/PlateBG/yellow.png`,this.yellowPlateBG.onload=()=>{e()}}),new Promise(e=>{this.whitePlateBG=new Image,this.whitePlateBG.src=`${this.assetsRoot}/Images/PlateBG/white.png`,this.whitePlateBG.onload=()=>{e()}}),new Promise(e=>{this.blackPlateBG=new Image,this.blackPlateBG.src=`${this.assetsRoot}/Images/PlateBG/black.png`,this.blackPlateBG.onload=()=>{e()}}),new Promise(e=>{this.neoYellowPlateBG=new Image,this.neoYellowPlateBG.src=`${this.assetsRoot}/Images/PlateBG/neo_yellow.png`,this.neoYellowPlateBG.onload=()=>{e()}}),new Promise(e=>{this.neoGreenPlateBG=new Image,this.neoGreenPlateBG.src=`${this.assetsRoot}/Images/PlateBG/neo_green.png`,this.neoGreenPlateBG.onload=()=>{e()}}),new Promise(e=>{this.greyPlateBG=new Image,this.greyPlateBG.src=`${this.assetsRoot}/Images/PlateBG/grey.png`,this.greyPlateBG.onload=()=>{e()}})]),this.isInitialized=!0}setInterpolate(i){this.clearVehicles(),this.needInterpolate=i}async setup(i){this.context=i,this.renderer=new l.WebGLRenderer({context:i.gl,premultipliedAlpha:!0,logarithmicDepthBuffer:!0,antialias:!0,powerPreference:"high-performance"}),this.renderer.shadowMap.enabled=!0,this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setViewport(0,0,this.view.width,this.view.height),this.renderer.autoClearDepth=!1,this.renderer.autoClearStencil=!1,this.renderer.autoClearColor=!1;const e=this.renderer.setRenderTarget.bind(this.renderer);this.renderer.setRenderTarget=s=>{e(s),s==null&&i.bindRenderTarget()},this.scene=new l.Scene;const{camera:t}=i;this.camera=new l.PerspectiveCamera(t.fovY,t.aspect,.1,1e5),this.ambient=new l.AmbientLight(16777215,2),this.scene.add(this.ambient),this.sun=new l.DirectionalLight(16777215,2),this.scene.add(this.sun),i.resetWebGLState()}async render(i){var s;const e=i.camera;if(this.camera.position.set(e.eye[0],e.eye[1],e.eye[2]),this.camera.up.set(e.up[0],e.up[1],e.up[2]),this.camera.lookAt(new l.Vector3(e.center[0],e.center[1],e.center[2])),this.camera.projectionMatrix.fromArray(e.projectionMatrix),!this.isPaused&&this.needInterpolate)for(const a of this.vehicleObjectMap.keys()){const n=(s=this.vehicleObjectMap.get(a))==null?void 0:s.model;if(!n)continue;const o=this.computeVehiclePosition(a);if(o){const d=this.toRenderCoordinates(o);n.position.set(d[0],d[1],d[2]),n.rotation.y=l.MathUtils.degToRad(-o[3])}}const t=i.sunLight;this.sun.position.set(t.direction[0],t.direction[1],t.direction[2]),this.sun.intensity=t.diffuse.intensity,this.sun.color=new l.Color(t.diffuse.color[0],t.diffuse.color[1],t.diffuse.color[2]),this.ambient.intensity=t.ambient.intensity,this.ambient.color=new l.Color(t.ambient.color[0],t.ambient.color[1],t.ambient.color[2]),this.renderer.resetState(),i.bindRenderTarget(),this.renderer.render(this.scene,this.camera),M.requestRender(this.view),i.resetWebGLState()}async addVehicles(i){if(this.isPaused||!this.isInitialized)return;const e=Date.now();for(const t of i){this.appDataStore.saveTrackLog&&this.logTable.push([t.ptcId,t.plateNo,t.timestamp,t.localTimestamp,t.speed,t.x,t.y,t.ptcType,t.vehicleType,t.vehicleColor,t.plateColor,t.heading,t.fixAngle,t.roadLayer,t.step,e,0,0]);const{vehicleId:s,localTimestamp:a}=t,n=Number(t.x),o=Number(t.y),d=Number(t.heading);this.historyPositionMap.set(s,[{pos:[n,o,0],heading:d,time:a}]);const h=this.getVehicleModel(t);h.name=s,h.visible=!1;try{const r=await this.createPlateSprite(t);r&&(h.add(r),r.position.set(0,5,-4))}catch(r){console.log("createPlateSprite error:",r)}this.scene.add(h),this.vehicleObjectMap.set(s,{model:h,data:t,waitForDelete:!1,isMoving:!1})}}async updateVehicles(i){if(this.isPaused||!this.isInitialized)return;const e=[],t=Date.now();for(const s of i){const{vehicleId:a,timestamp:n}=s,o=Number(s.x),d=Number(s.y);let h=Number(s.heading);const r=this.vehicleObjectMap.get(a),p=this.historyPositionMap.get(a);if(!r||!p)e.push(s);else{if(this.appDataStore.saveTrackLog&&this.logTable.push([s.ptcId,s.plateNo,s.timestamp,s.localTimestamp,s.speed,s.x,s.y,s.ptcType,s.vehicleType,s.vehicleColor,s.plateColor,s.heading,s.fixAngle,s.roadLayer,s.step,t,p.length,1]),this.updateModel||r.data.vehicleColor!==s.vehicleColor||r.data.vehicleType!==s.vehicleType){this.scene.remove(r.model),this.disposeModel(r.model),r.model=this.getVehicleModel(s),r.model.visible=!0;const c=await this.createPlateSprite(s);c&&(r.model.add(c),c.position.set(0,5,-4)),this.scene.add(r.model)}if(r.data.showName!==s.showName||r.data.plateColor!==s.plateColor){const c=r.model.getObjectByName("VehiclePlate");c&&(r.model.remove(c),this.disposeModel(c));const g=await this.createPlateSprite(s);g&&(r.model.add(g),g.position.set(0,5,-4))}if(r.data=s,this.needInterpolate){const c=p[p.length-1];Math.abs(h-c.heading)>=180&&(h>c.heading?c.heading+=360:h+=360),p.push({pos:[o,d,0],heading:h,time:n})}else{this.historyPositionMap.set(a,[{pos:[o,d,0],heading:h,time:n}]);const c=this.toRenderCoordinates([o,d,0]);r.model.position.set(c[0],c[1],c[2]),r.model.rotation.y=l.MathUtils.degToRad(-h)}}}await this.addVehicles(e),this.updateModel=!1,this.needInterpolate||this.render(this.context)}toRenderCoordinates(i){const e=[0,0,0];return M.toRenderCoordinates(this.view,i,0,T.WGS84,e,0,1),e}deleteVehicles(i){if(this.isPaused)return;const e=Date.now();i.forEach(t=>{if(this.appDataStore.saveTrackLog){const a=this.historyPositionMap.get(t);this.logTable.push([t,"","","","","","","","","","","","","","",e,a?a.length:0,2])}const s=this.vehicleObjectMap.get(t);s&&(this.needInterpolate?s.isMoving?s.waitForDelete=!0:this.deleteVehicle(s):this.deleteVehicle(s))})}deleteVehicle(i){this.scene.remove(i.model),this.disposeModel(i.model);const e=i.data.vehicleId;this.vehicleObjectMap.delete(e),this.historyPositionMap.delete(e)}async toggleTrafficInfo(i){i.name==="vehiclePlate"&&(i.visible===!0&&this.currentSpriteContent===m.EVehiclePlateState.None?await this.updatePanelContent(m.EVehiclePlateState.PlateNumber):await this.updatePanelContent(i.visible?this.currentSpriteContent:m.EVehiclePlateState.None))}togglePause(i){this.isPaused=i}clearVehicles(){for(const i of this.vehicleObjectMap.keys()){const e=this.vehicleObjectMap.get(i);e&&(this.scene.remove(e.model),this.disposeModel(e.model))}this.vehicleObjectMap.clear(),this.historyPositionMap.clear()}async updatePanelContent(i){if(i!==this.currentSpriteContent){this.currentSpriteContent=i;for(const e of this.vehicleObjectMap.keys()){const t=this.vehicleObjectMap.get(e);if(t){const s=t.model.getObjectByName("VehiclePlate");if(s&&(t.model.remove(s),this.disposeModel(s)),i!==m.EVehiclePlateState.None){const a=await this.createPlateSprite(t.data);a&&(t.model.add(a),a.position.set(0,5,-4))}}}}}toggleGroundVehicle(i){console.log("toggleGroundVehicle",i),this.showGroundVehicle=i}toggleElevatedVehicle(i){this.showElevatedVehicle=i}disposeModel(i){i.traverse(e=>{e instanceof l.Mesh&&(e.geometry.dispose(),e.material.dispose())})}computeVehiclePosition(i){const e=this.historyPositionMap.get(i),t=this.vehicleObjectMap.get(i);if(!t||!e||!t.isMoving&&e.length<=2)return;const s=Date.now();t.isMoving=!0,t.data.roadLayer==="1"?t.model.visible=this.showGroundVehicle:t.model.visible=this.showElevatedVehicle,t.segmentStartTime||(t.segmentStartTime=s,t.segmentTotalTime=e[1].time-e[0].time);const a=s-t.segmentStartTime,n=Math.min(a/t.segmentTotalTime,1);if(n===1)if(e.shift(),e.length===1){t.waitForDelete===!0?this.deleteVehicle(t):(t.segmentStartTime=void 0,t.segmentTotalTime=void 0,t.model.visible=!1,t.isMoving=!1,console.log("hide vehicle",i));return}else{const o=a-t.segmentTotalTime;return t.segmentStartTime=Date.now(),t.segmentTotalTime=e[1].time-e[0].time-(o>0?o:0),(e[1].heading>=270&&e[0].heading<=90||e[1].heading<=90&&e[0].heading>=270)&&(e[1].heading>e[0].heading?e[0].heading+=360:e[1].heading+=360),e[0].pos.concat(e[0].heading)}else if(e.length>=2){const o=e[0].pos[0]+(e[1].pos[0]-e[0].pos[0])*n,d=e[0].pos[1]+(e[1].pos[1]-e[0].pos[1])*n,h=e[0].heading+(e[1].heading-e[0].heading)*n;return[o,d,0,h]}else return}getVehicleModel(i){if(this.view.camera.position.z>=this.cameraHeightThreshold){const e=new l.SphereGeometry(5,32,32),t=new l.MeshPhysicalMaterial({color:325253,emissive:0,roughness:this.roughness,metalness:this.metalness});return new l.Mesh(e,t)}else{let e;if(i.ptcType===2)e=this.bicycleModel.clone();else{switch(i.vehicleType){case 10:e=this.carModel.clone();break;case 20:e=this.vanModel.clone();break;case 25:e=this.truckModel.clone();break;case 50:e=this.busModel.clone();break;default:e=this.carModel.clone();break}const t=this.materialMap.get(i.vehicleColor)||this.defaultMaterial;let s=!1;e.traverse(a=>{!s&&a instanceof l.Mesh&&(a.material=t,s=!0)})}return e}}createCanvas(i,e,t){const s=document.createElement("canvas"),a=i.width,n=i.height;s.width=a,s.height=n;const o=s.getContext("2d");if(!o){console.log("canvas创建失败");return}return o.fillStyle="rgba(0,0,0,0.0)",o.fillRect(0,0,a,n),o.drawImage(i,0,0,a,n),o.beginPath(),o.translate(a/2,n/2),o.fillStyle=t,o.font="bold 32px 宋体",o.textBaseline="middle",o.textAlign="center",o.fillText(e,0,0),s}createPlateSprite(i){return new Promise((e,t)=>{var h,r;const s=!i.plateNo||i.plateNo==="0"||i.plateNo==="000000";if(this.currentSpriteContent===m.EVehiclePlateState.None||this.currentSpriteContent===m.EVehiclePlateState.PlateNumber&&s){e(void 0);return}let a=new Image,n="",o="";if(this.currentSpriteContent===m.EVehiclePlateState.PlateNumber||this.currentSpriteContent===m.EVehiclePlateState.Mix)if(s)a=this.greyPlateBG,n=i.ptcId,o="#ffffff";else switch(n=((h=i.showName)==null?void 0:h.substring(0,2))+"•"+((r=i.showName)==null?void 0:r.substring(2)),i.plateColor){case 1:a=this.bluePlateBG,o="#ffffff";break;case 2:a=this.yellowPlateBG,o="#000000";break;case 3:a=this.whitePlateBG,o="#000000";break;case 4:a=this.blackPlateBG,o="#ffffff";break;case 5:a=this.neoYellowPlateBG,o="#000000";break;case 6:a=this.neoGreenPlateBG,o="#000000";break;default:a=this.greyPlateBG,n=i.plateNo,o="#ffffff";break}else this.currentSpriteContent===m.EVehiclePlateState.Id&&(a=this.greyPlateBG,n=i.ptcId,o="#ffffff");const d=this.createCanvas(a,n,o);if(d){const p=new l.CanvasTexture(d),c=new l.SpriteMaterial({map:p,transparent:!1}),g=new l.Sprite(c),P=.05,w=d.width*P,b=d.height*P;g.scale.set(w,b,1),g.name="VehiclePlate",e(g)}else{t("canvas创建失败");return}a.onerror=p=>{console.log(`号牌背景加载失败: ${a.src}`,p),t(p)}})}}exports.default=V;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const v=require("@arcgis/core/core/promiseUtils.js"),y=require("@arcgis/core/core/reactiveUtils.js"),T=require("@arcgis/core/geometry/SpatialReference"),S=require("@arcgis/core/views/3d/externalRenderers"),C=require("three"),G=require("three/examples/jsm/loaders/GLTFLoader"),m=require("../../../types/index.js"),B=require("../../stores/index.js");function f(u){const i=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(u){for(const e in u)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(u,e);Object.defineProperty(i,e,t.get?t:{enumerable:!0,get:()=>u[e]})}}return i.default=u,Object.freeze(i)}const R=f(v),I=f(y),M=f(S),r=f(C);class V{constructor(i){this.cameraHeightThreshold=1e3,this.roughness=.2,this.metalness=.8,this.defaultMaterial=new r.MeshPhongMaterial({color:16777215}),this.materialMap=new Map([[1,this.createCarMaterial(16777215)],[2,this.createCarMaterial(7833753)],[3,this.createCarMaterial(16766720)],[4,this.createCarMaterial(16758465)],[5,this.createCarMaterial(14423100)],[6,this.createCarMaterial(3329330)],[7,this.createCarMaterial(2003183)],[8,this.createCarMaterial(16032864)],[9,this.createCarMaterial(2105376)],[10,this.createCarMaterial(9662683)],[99,this.createCarMaterial(6908265)]]),this.isInitialized=!1,this.showGroundVehicle=!0,this.showElevatedVehicle=!0,this.isPaused=!1,this.currentSpriteContent=m.EVehiclePlateState.None,this.historyPositionMap=new Map,this.vehicleObjectMap=new Map,this.needInterpolate=!0,this.updateModel=!1,this.appDataStore=B.default.useAppDataStore,this.logTable=[["ptcId","plateno","timestamp","localTimestamp","speed","longitude","latitude","ptcType","vehicleType","vehicleColor","plateColor","heading","fixAngle","roadLayer","step","receiveTimestamp","queueLength","status"]],this.assetsRoot=JSON.parse(JSON.stringify(this.appDataStore.mapConfig)).assetsRoot,this.view=i,I.watch(()=>this.view.camera.position.z,(e,t)=>{(t<=this.cameraHeightThreshold&&e>this.cameraHeightThreshold||t>this.cameraHeightThreshold&&e<=this.cameraHeightThreshold)&&(this.updateModel=!0)})}createCarMaterial(i){return new r.MeshPhongMaterial({color:i})}getLog(){return this.logTable}async init(){const i=new G.GLTFLoader;await R.eachAlways([new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/car.glb`,t=>{this.carModel=t.scene,this.carModel.rotation.x=r.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/van.glb`,t=>{this.vanModel=t.scene,this.vanModel.rotation.x=r.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/truck.glb`,t=>{this.truckModel=t.scene,this.truckModel.scale.set(1.2,1,1.5),this.truckModel.rotation.x=r.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/bus.glb`,t=>{this.busModel=t.scene,this.busModel.rotation.x=r.MathUtils.degToRad(90),e()})}),new Promise(e=>{i.load(`${this.assetsRoot}/3DModels/bicycle.glb`,t=>{this.bicycleModel=t.scene,this.bicycleModel.rotation.x=r.MathUtils.degToRad(90),this.bicycleModel.rotation.y=r.MathUtils.degToRad(180),e()})}),new Promise(e=>{this.bluePlateBG=new Image,this.bluePlateBG.src=`${this.assetsRoot}/Images/PlateBG/blue.png`,this.bluePlateBG.onload=()=>{e()}}),new Promise(e=>{this.yellowPlateBG=new Image,this.yellowPlateBG.src=`${this.assetsRoot}/Images/PlateBG/yellow.png`,this.yellowPlateBG.onload=()=>{e()}}),new Promise(e=>{this.whitePlateBG=new Image,this.whitePlateBG.src=`${this.assetsRoot}/Images/PlateBG/white.png`,this.whitePlateBG.onload=()=>{e()}}),new Promise(e=>{this.blackPlateBG=new Image,this.blackPlateBG.src=`${this.assetsRoot}/Images/PlateBG/black.png`,this.blackPlateBG.onload=()=>{e()}}),new Promise(e=>{this.neoYellowPlateBG=new Image,this.neoYellowPlateBG.src=`${this.assetsRoot}/Images/PlateBG/neo_yellow.png`,this.neoYellowPlateBG.onload=()=>{e()}}),new Promise(e=>{this.neoGreenPlateBG=new Image,this.neoGreenPlateBG.src=`${this.assetsRoot}/Images/PlateBG/neo_green.png`,this.neoGreenPlateBG.onload=()=>{e()}}),new Promise(e=>{this.greyPlateBG=new Image,this.greyPlateBG.src=`${this.assetsRoot}/Images/PlateBG/grey.png`,this.greyPlateBG.onload=()=>{e()}})]),this.isInitialized=!0}setInterpolate(i){this.clearVehicles(),this.needInterpolate=i}async setup(i){this.context=i,this.renderer=new r.WebGLRenderer({context:i.gl,premultipliedAlpha:!0,logarithmicDepthBuffer:!0,antialias:!0,powerPreference:"high-performance"}),this.renderer.shadowMap.enabled=!0,this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setViewport(0,0,this.view.width,this.view.height),this.renderer.autoClearDepth=!1,this.renderer.autoClearStencil=!1,this.renderer.autoClearColor=!1;const e=this.renderer.setRenderTarget.bind(this.renderer);this.renderer.setRenderTarget=s=>{e(s),s==null&&i.bindRenderTarget()},this.scene=new r.Scene;const{camera:t}=i;this.camera=new r.PerspectiveCamera(t.fovY,t.aspect,.1,1e5),this.ambient=new r.AmbientLight(16777215,2),this.scene.add(this.ambient),this.sun=new r.DirectionalLight(16777215,2),this.scene.add(this.sun),i.resetWebGLState()}async render(i){var s;const e=i.camera;if(this.camera.position.set(e.eye[0],e.eye[1],e.eye[2]),this.camera.up.set(e.up[0],e.up[1],e.up[2]),this.camera.lookAt(new r.Vector3(e.center[0],e.center[1],e.center[2])),this.camera.projectionMatrix.fromArray(e.projectionMatrix),!this.isPaused&&this.needInterpolate)for(const a of this.vehicleObjectMap.keys()){const n=(s=this.vehicleObjectMap.get(a))==null?void 0:s.model;if(!n)continue;const o=this.computeVehiclePosition(a);if(o){const d=this.toRenderCoordinates(o);n.position.set(d[0],d[1],d[2]),n.rotation.y=r.MathUtils.degToRad(-o[3])}}const t=i.sunLight;this.sun.position.set(t.direction[0],t.direction[1],t.direction[2]),this.sun.intensity=t.diffuse.intensity,this.sun.color=new r.Color(t.diffuse.color[0],t.diffuse.color[1],t.diffuse.color[2]),this.ambient.intensity=t.ambient.intensity,this.ambient.color=new r.Color(t.ambient.color[0],t.ambient.color[1],t.ambient.color[2]),this.renderer.resetState(),i.bindRenderTarget(),this.renderer.render(this.scene,this.camera),M.requestRender(this.view),i.resetWebGLState()}async addVehicles(i){if(this.isPaused||!this.isInitialized)return;const e=Date.now();for(const t of i){this.appDataStore.saveTrackLog&&this.logTable.push([t.ptcId,t.plateNo,t.timestamp,t.localTimestamp,t.speed,t.x,t.y,t.ptcType,t.vehicleType,t.vehicleColor,t.plateColor,t.heading,t.fixAngle,t.roadLayer,t.step,e,0,0]);const{vehicleId:s,localTimestamp:a}=t,n=Number(t.x),o=Number(t.y),d=Number(t.heading);this.historyPositionMap.set(s,[{pos:[n,o,0],heading:d,time:a}]);const h=this.getVehicleModel(t);h.name=s,h.visible=!1;try{const l=await this.createPlateSprite(t);l&&(h.add(l),l.position.set(0,5,-4))}catch(l){console.log("createPlateSprite error:",l)}this.scene.add(h),this.vehicleObjectMap.set(s,{model:h,data:t,waitForDelete:!1,isMoving:!1})}}async updateVehicles(i){if(this.isPaused||!this.isInitialized)return;const e=[],t=Date.now();for(const s of i){const{vehicleId:a,localTimestamp:n}=s,o=Number(s.x),d=Number(s.y);let h=Number(s.heading);const l=this.vehicleObjectMap.get(a),p=this.historyPositionMap.get(a);if(!l||!p)e.push(s);else{if(this.appDataStore.saveTrackLog&&this.logTable.push([s.ptcId,s.plateNo,s.timestamp,s.localTimestamp,s.speed,s.x,s.y,s.ptcType,s.vehicleType,s.vehicleColor,s.plateColor,s.heading,s.fixAngle,s.roadLayer,s.step,t,p.length,1]),this.updateModel||l.data.vehicleColor!==s.vehicleColor||l.data.vehicleType!==s.vehicleType){this.scene.remove(l.model),this.disposeModel(l.model),l.model=this.getVehicleModel(s),l.model.visible=!0;const c=await this.createPlateSprite(s);c&&(l.model.add(c),c.position.set(0,5,-4)),this.scene.add(l.model)}if(l.data.showName!==s.showName||l.data.plateColor!==s.plateColor){const c=l.model.getObjectByName("VehiclePlate");c&&(l.model.remove(c),this.disposeModel(c));const g=await this.createPlateSprite(s);g&&(l.model.add(g),g.position.set(0,5,-4))}if(l.data=s,this.needInterpolate){const c=p[p.length-1];Math.abs(h-c.heading)>=180&&(h>c.heading?c.heading+=360:h+=360),p.push({pos:[o,d,0],heading:h,time:n})}else{this.historyPositionMap.set(a,[{pos:[o,d,0],heading:h,time:n}]);const c=this.toRenderCoordinates([o,d,0]);l.model.position.set(c[0],c[1],c[2]),l.model.rotation.y=r.MathUtils.degToRad(-h)}}}await this.addVehicles(e),this.updateModel=!1,this.needInterpolate||this.render(this.context)}toRenderCoordinates(i){const e=[0,0,0];return M.toRenderCoordinates(this.view,i,0,T.WGS84,e,0,1),e}deleteVehicles(i){if(this.isPaused)return;const e=Date.now();i.forEach(t=>{if(this.appDataStore.saveTrackLog){const a=this.historyPositionMap.get(t);this.logTable.push([t,"","","","","","","","","","","","","","",e,a?a.length:0,2])}const s=this.vehicleObjectMap.get(t);s&&(this.needInterpolate?s.isMoving?s.waitForDelete=!0:this.deleteVehicle(s):this.deleteVehicle(s))})}deleteVehicle(i){this.scene.remove(i.model),this.disposeModel(i.model);const e=i.data.vehicleId;this.vehicleObjectMap.delete(e),this.historyPositionMap.delete(e)}async toggleTrafficInfo(i){i.name==="vehiclePlate"&&(i.visible===!0&&this.currentSpriteContent===m.EVehiclePlateState.None?await this.updatePanelContent(m.EVehiclePlateState.PlateNumber):await this.updatePanelContent(i.visible?this.currentSpriteContent:m.EVehiclePlateState.None))}togglePause(i){this.isPaused=i}clearVehicles(){for(const i of this.vehicleObjectMap.keys()){const e=this.vehicleObjectMap.get(i);e&&(this.scene.remove(e.model),this.disposeModel(e.model))}this.vehicleObjectMap.clear(),this.historyPositionMap.clear()}async updatePanelContent(i){if(i!==this.currentSpriteContent){this.currentSpriteContent=i;for(const e of this.vehicleObjectMap.keys()){const t=this.vehicleObjectMap.get(e);if(t){const s=t.model.getObjectByName("VehiclePlate");if(s&&(t.model.remove(s),this.disposeModel(s)),i!==m.EVehiclePlateState.None){const a=await this.createPlateSprite(t.data);a&&(t.model.add(a),a.position.set(0,5,-4))}}}}}toggleGroundVehicle(i){console.log("toggleGroundVehicle",i),this.showGroundVehicle=i}toggleElevatedVehicle(i){this.showElevatedVehicle=i}disposeModel(i){i.traverse(e=>{e instanceof r.Mesh&&(e.geometry.dispose(),e.material.dispose())})}computeVehiclePosition(i){const e=this.historyPositionMap.get(i),t=this.vehicleObjectMap.get(i);if(!t||!e||!t.isMoving&&e.length<=2)return;const s=Date.now();t.isMoving=!0,t.data.roadLayer==="1"?t.model.visible=this.showGroundVehicle:t.model.visible=this.showElevatedVehicle,t.segmentStartTime||(t.segmentStartTime=s,t.segmentTotalTime=e[1].time-e[0].time);const a=s-t.segmentStartTime,n=Math.min(a/t.segmentTotalTime,1);if(n===1)if(e.shift(),e.length===1){t.waitForDelete===!0?this.deleteVehicle(t):(t.segmentStartTime=void 0,t.segmentTotalTime=void 0,t.model.visible=!1,t.isMoving=!1,console.log("hide vehicle",i));return}else{t.segmentStartTime=Date.now();const o=a-t.segmentTotalTime;return t.segmentTotalTime=e[1].time-e[0].time-o,console.log(t.segmentStartTime,t.segmentTotalTime),(e[1].heading>=270&&e[0].heading<=90||e[1].heading<=90&&e[0].heading>=270)&&(e[1].heading>e[0].heading?e[0].heading+=360:e[1].heading+=360),e[0].pos.concat(e[0].heading)}else if(e.length>=2){const o=e[0].pos[0]+(e[1].pos[0]-e[0].pos[0])*n,d=e[0].pos[1]+(e[1].pos[1]-e[0].pos[1])*n,h=e[0].heading+(e[1].heading-e[0].heading)*n;return[o,d,0,h]}else return}getVehicleModel(i){if(this.view.camera.position.z>=this.cameraHeightThreshold){const e=new r.SphereGeometry(5,32,32),t=new r.MeshPhysicalMaterial({color:325253,emissive:0,roughness:this.roughness,metalness:this.metalness});return new r.Mesh(e,t)}else{let e;if(i.ptcType===2)e=this.bicycleModel.clone();else{switch(i.vehicleType){case 10:e=this.carModel.clone();break;case 20:e=this.vanModel.clone();break;case 25:e=this.truckModel.clone();break;case 50:e=this.busModel.clone();break;default:e=this.carModel.clone();break}const t=this.materialMap.get(i.vehicleColor)||this.defaultMaterial;let s=!1;e.traverse(a=>{!s&&a instanceof r.Mesh&&(a.material=t,s=!0)})}return e}}createCanvas(i,e,t){const s=document.createElement("canvas"),a=i.width,n=i.height;s.width=a,s.height=n;const o=s.getContext("2d");if(!o){console.log("canvas创建失败");return}return o.fillStyle="rgba(0,0,0,0.0)",o.fillRect(0,0,a,n),o.drawImage(i,0,0,a,n),o.beginPath(),o.translate(a/2,n/2),o.fillStyle=t,o.font="bold 32px 宋体",o.textBaseline="middle",o.textAlign="center",o.fillText(e,0,0),s}createPlateSprite(i){return new Promise((e,t)=>{var h,l;const s=!i.plateNo||i.plateNo==="0"||i.plateNo==="000000";if(this.currentSpriteContent===m.EVehiclePlateState.None||this.currentSpriteContent===m.EVehiclePlateState.PlateNumber&&s){e(void 0);return}let a=new Image,n="",o="";if(this.currentSpriteContent===m.EVehiclePlateState.PlateNumber||this.currentSpriteContent===m.EVehiclePlateState.Mix)if(s)a=this.greyPlateBG,n=i.ptcId,o="#ffffff";else switch(n=((h=i.showName)==null?void 0:h.substring(0,2))+"•"+((l=i.showName)==null?void 0:l.substring(2)),i.plateColor){case 1:a=this.bluePlateBG,o="#ffffff";break;case 2:a=this.yellowPlateBG,o="#000000";break;case 3:a=this.whitePlateBG,o="#000000";break;case 4:a=this.blackPlateBG,o="#ffffff";break;case 5:a=this.neoYellowPlateBG,o="#000000";break;case 6:a=this.neoGreenPlateBG,o="#000000";break;default:a=this.greyPlateBG,n=i.plateNo,o="#ffffff";break}else this.currentSpriteContent===m.EVehiclePlateState.Id&&(a=this.greyPlateBG,n=i.ptcId,o="#ffffff");const d=this.createCanvas(a,n,o);if(d){const p=new r.CanvasTexture(d),c=new r.SpriteMaterial({map:p,transparent:!1}),g=new r.Sprite(c),P=.05,w=d.width*P,b=d.height*P;g.scale.set(w,b,1),g.name="VehiclePlate",e(g)}else{t("canvas创建失败");return}a.onerror=p=>{console.log(`号牌背景加载失败: ${a.src}`,p),t(p)}})}}exports.default=V;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("@arcgis/core/Graphic"),p=require("@arcgis/core/layers/GraphicsLayer"),m=require("../../stores/index.js");class g{constructor(i){this.appDataStore=m.default.useAppDataStore,this.logTable=[["uuid","ptcId","plateno","timestamp","localTimestamp","timestamp_str","speed","laneNo","objHeight","objLength","latitude","longitude","ptcType","vehicleType","vehicleColor","plateColor","sbdm","heading","fixAngle","roadLayer","status","step","receiveTimestamp"]],this.needInterpolate=!0,this.isPaused=!1,this.showVehiclePlate=!1,this.showGroundVehicle=!0,this.showElevatedVehicle=!0,this.historyPositionMap=new Map,this.vehicleObjectMap=new Map,this.view=i,this.mapConfig=JSON.parse(JSON.stringify(this.appDataStore.mapConfig)),this.vehicleLayer=new p({id:"vehicleLayer"}),this.view.map.add(this.vehicleLayer),this.rafSignal=requestAnimationFrame(()=>this.render())}getLog(){return this.logTable}async init(){
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("@arcgis/core/Graphic"),p=require("@arcgis/core/layers/GraphicsLayer"),m=require("../../stores/index.js");class g{constructor(i){this.appDataStore=m.default.useAppDataStore,this.logTable=[["uuid","ptcId","plateno","timestamp","localTimestamp","timestamp_str","speed","laneNo","objHeight","objLength","latitude","longitude","ptcType","vehicleType","vehicleColor","plateColor","sbdm","heading","fixAngle","roadLayer","status","step","receiveTimestamp"]],this.needInterpolate=!0,this.isPaused=!1,this.showVehiclePlate=!1,this.showGroundVehicle=!0,this.showElevatedVehicle=!0,this.historyPositionMap=new Map,this.vehicleObjectMap=new Map,this.view=i,this.mapConfig=JSON.parse(JSON.stringify(this.appDataStore.mapConfig)),this.vehicleLayer=new p({id:"vehicleLayer"}),this.view.map.add(this.vehicleLayer),this.rafSignal=requestAnimationFrame(()=>this.render())}getLog(){return this.logTable}async init(){}addVehicles(i){return new Promise(e=>{if(this.isPaused){e();return}const t=i.map(s=>{const{vehicleId:o,heading:a,localTimestamp:h}=s,r=Number(s.x),l=Number(s.y);this.historyPositionMap.set(o,[{pos:[r,l,0],heading:a,time:h}]);const n=new c({geometry:{type:"point",x:r,y:l},attributes:{...s},symbol:this.createCIMSymbol(s)});return n.visible=!1,this.vehicleObjectMap.set(o,{graphic:n,data:s,waitForDelete:!1,isMoving:!1}),n});this.vehicleLayer.addMany(t),e()})}updateVehicles(i){return new Promise(e=>{if(this.isPaused){e();return}const t=[];i.forEach(s=>{const{vehicleId:o,heading:a,localTimestamp:h}=s,r=Number(s.x),l=Number(s.y),n=this.vehicleObjectMap.get(o);n?(n.data=s,this.historyPositionMap.get(o).push({pos:[r,l,0],heading:a,time:h})):t.push(s)}),this.addVehicles(t),e()})}deleteVehicles(i){this.isPaused||i.forEach(e=>{const t=this.vehicleObjectMap.get(e);t&&(t.waitForDelete=!0)})}clearVehicles(){this.vehicleLayer.removeAll(),this.vehicleObjectMap.clear(),this.historyPositionMap.clear()}toggleGroundVehicle(i){this.showGroundVehicle=i}toggleElevatedVehicle(i){this.showElevatedVehicle=i}toggleTrafficInfo(i){i.name==="vehiclePlate"&&(this.showVehiclePlate=i.visible)}togglePause(i){this.isPaused=i,this.isPaused?cancelAnimationFrame(this.rafSignal):this.rafSignal=requestAnimationFrame(()=>this.render())}updatePanelContent(i){console.log(i)}setInterpolate(i){this.needInterpolate=i}render(){this.isPaused||this.vehicleObjectMap.forEach((i,e)=>{this.updatePosition(e)}),this.rafSignal=requestAnimationFrame(()=>this.render())}updatePosition(i){const e=this.historyPositionMap.get(i),t=this.vehicleObjectMap.get(i);if(!e||!t||!t.isMoving&&e.length<=2)return;t.isMoving=!0,(t.graphic.getAttribute("roadLayer")||"1")==="1"?t.graphic.visible=this.showGroundVehicle:t.graphic.visible=this.showElevatedVehicle,t.segmentStartTime||(t.segmentStartTime=Date.now(),t.segmentTotalTime=e[1].time-e[0].time);const o=Date.now()-t.segmentStartTime,a=Math.min(1,o/t.segmentTotalTime);if(a===1)if(e.shift(),e.length===1){t.waitForDelete?(this.vehicleLayer.remove(t.graphic),this.vehicleObjectMap.delete(i),this.historyPositionMap.delete(i)):(t.segmentStartTime=void 0,t.segmentTotalTime=void 0,t.graphic.visible=!1,t.isMoving=!1);return}else t.segmentStartTime=Date.now(),t.segmentTotalTime=e[1].time-e[0].time,(e[1].heading>=270&&e[0].heading<=90||e[1].heading<=90&&e[0].heading>=270)&&(e[1].heading>e[0].heading?e[0].heading+=360:e[1].heading+=360),t.graphic.geometry={type:"point",x:e[0].pos[0],y:e[0].pos[1]};else{const h=e[0].pos[0]+(e[1].pos[0]-e[0].pos[0])*a,r=e[0].pos[1]+(e[1].pos[1]-e[0].pos[1])*a,l=e[0].heading+(e[1].heading-e[0].heading)*a;t.graphic.geometry={type:"point",x:h,y:r},t.data.heading=l,t.graphic.symbol=this.createCIMSymbol(t.data)}}createCIMSymbol(i){const e=this.getPlateFontColor(i.plateColor);return{type:"cim",data:{type:"CIMSymbolReference",primitiveOverrides:[{type:"CIMPrimitiveOverride",primitiveName:"textGraphic",propertyName:"TextString",valueExpressionInfo:{type:"CIMExpressionInfo",title:"Custom",expression:"$feature.showName",returnType:"Default"}}],symbol:{type:"CIMPointSymbol",symbolLayers:[{type:"CIMVectorMarker",enable:this.showVehiclePlate,size:32,colorLocked:!0,anchorPointUnits:"Relative",frame:{xmin:-8,ymin:-8,xmax:8,ymax:8},markerGraphics:[{type:"CIMMarkerGraphic",primitiveName:"textGraphic",geometry:{x:0,y:0},symbol:{type:"CIMTextSymbol",height:4,horizontalAlignment:"Center",offsetX:0,offsetY:8,haloSize:1,haloSymbol:{type:"CIMPolygonSymbol",symbolLayers:[{type:"CIMSolidFill",enable:!0,color:e.backgroundColor}]},symbol:{type:"CIMPolygonSymbol",symbolLayers:[{type:"CIMSolidFill",enable:!0,color:e.fillColor}]},verticalAlignment:"Center"},textString:""}],scaleSymbolsProportionally:!0,respectFrame:!0},{type:"CIMPictureMarker",enable:!0,anchorPoint:{x:0,y:0},anchorPointUnits:"Relative",size:30,rotation:i.heading,rotateClockwise:!0,textureFilter:"Picture",url:`${this.mapConfig.assetsRoot}Images/car/${this.getCarPic(i.vehicleColor)}`}]}}}}getCarPic(i){if(this.view.zoom<=15)return"point.png";let e="grey";switch(typeof i=="string"&&(i=i.toLowerCase()),i){case"a":case 1:e="white";break;case"b":case 2:e="grey";break;case"c":case 3:e="yellow";break;case"d":case 4:e="pink";break;case"e":case 5:e="red";break;case"f":case 10:e="purple";break;case"g":case 6:e="green";break;case"h":case 7:e="blue";break;case"i":case 8:e="brown";break;case"j":case 9:e="black";break}return e+".png"}getPlateFontColor(i){let e=[255,255,255,255],t=[169,169,169,255];switch(i){case 0:e=[0,0,0,255],t=[255,255,255,255];break;case 1:e=[0,0,0,255],t=[244,164,96,255];break;case 2:e=[255,255,255,255],t=[65,105,225,255];break;case 3:e=[255,255,255,255],t=[0,0,0,255];break;case 15:e=[244,164,96,255],t=[0,250,154,255];break;case 16:e=[0,0,0,255],t=[0,250,154,255];break}return{fillColor:e,backgroundColor:t}}}exports.default=g;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default class DrawBezier {
|
|
2
|
+
private static sampleCount;
|
|
3
|
+
static drawBezierBetweenLane(incoming: number[][], outgoing: number[][]): number[][];
|
|
4
|
+
/**
|
|
5
|
+
* 生成控制点
|
|
6
|
+
* 进口道的延长线和出口道的反向延长线的交点
|
|
7
|
+
*/
|
|
8
|
+
private static getControlPoint;
|
|
9
|
+
/**
|
|
10
|
+
* @desc 二阶贝塞尔
|
|
11
|
+
* @param {number} t 当前百分比
|
|
12
|
+
* @param {Array} p1 起点坐标
|
|
13
|
+
* @param {Array} p2 终点坐标
|
|
14
|
+
* @param {Array} cp 控制点
|
|
15
|
+
*/
|
|
16
|
+
private static twoBezier;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const P=require("@turf/helpers"),y=require("@turf/line-intersect"),p=require("../common-utils.js");function b(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const n in r)if(n!=="default"){const t=Object.getOwnPropertyDescriptor(r,n);Object.defineProperty(e,n,t.get?t:{enumerable:!0,get:()=>r[n]})}}return e.default=r,Object.freeze(e)}const m=b(P);class d{static drawBezierBetweenLane(e,n){const t=this.getControlPoint(e,n);if(t.length===3){const i=t[0],c=t[1],u=t[2],o=[];for(let s=0;s<=this.sampleCount;s++)o.push(this.twoBezier(s/this.sampleCount,i,c,u));return o}else return t}static getControlPoint(e,n){const t=e[0],i=e[1],c=p.default.getExtensionLine(t,i,100),u=m.lineString([t,c]),o=n[0],s=n[1],a=p.default.getExtensionLine(s,o,100),g=m.lineString([a,s]),l=y(u,g);if(l.features.length===0)return[i,o];const f=l.features[0].geometry.coordinates;return[i,o,f]}static twoBezier(e,n,t,i){const[c,u]=n,[o,s]=i,[a,g]=t,l=(1-e)*(1-e)*c+2*e*(1-e)*o+e*e*a,f=(1-e)*(1-e)*u+2*e*(1-e)*s+e*e*g;return[l,f]}}d.sampleCount=50;exports.default=d;
|
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
import View from '@arcgis/core/views/View';
|
|
2
|
+
import { IFindSumoParams, IResult, IShowOpenDriveFromFileParams } from '../../../types';
|
|
2
3
|
export default class OpenDriveRenderer {
|
|
4
|
+
private static instance;
|
|
5
|
+
static getInstance(view: View): OpenDriveRenderer;
|
|
3
6
|
private readonly view;
|
|
4
7
|
private laneLayer;
|
|
8
|
+
private roadNameLayer;
|
|
9
|
+
private junctionLayer;
|
|
10
|
+
private highlightLayer;
|
|
11
|
+
private allLaneGraphics;
|
|
12
|
+
private allRefLineGraphics;
|
|
13
|
+
private wasmLoader;
|
|
5
14
|
constructor(view: View);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
15
|
+
showOpenDriveFromFile(params: IShowOpenDriveFromFileParams): Promise<IResult>;
|
|
16
|
+
/**
|
|
17
|
+
* 从服务器载入OpenDrive文件解析结果并显示
|
|
18
|
+
* @param server
|
|
19
|
+
* @param projectName
|
|
20
|
+
*/
|
|
21
|
+
showOpenDriveFromServer(server: string, projectName: string): Promise<IResult>;
|
|
22
|
+
private showAllLanes;
|
|
23
|
+
private showJunction;
|
|
24
|
+
clearOpenDrive(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* 用sumo的id定位车道、基本段、路段
|
|
27
|
+
* @param params
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
findSumo(params: IFindSumoParams): Promise<IResult>;
|
|
31
|
+
/**
|
|
32
|
+
* 用sumo的id定位车道、基本段、路段
|
|
33
|
+
* @param params
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
private findLane;
|
|
9
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const m=require("@arcgis/core/Graphic"),b=require("@arcgis/core/geometry"),F=require("@arcgis/core/geometry/geometryEngineAsync.js"),I=require("@arcgis/core/layers/FeatureLayer"),D=require("@arcgis/core/layers/GraphicsLayer"),N=require("axios"),G=require("pako"),P=require("./wasm-loader.js");function q(y){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(y){for(const t in y)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(y,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>y[t]})}}return e.default=y,Object.freeze(e)}const R=q(F);class v{constructor(e){this.wasmLoader=P.default.getInstance(),this.view=e,this.laneLayer=new I({id:"OpenDriveLane",fields:[{name:"ObjectID",alias:"ObjectID",type:"oid"},{name:"id",alias:"编号",type:"string"},{name:"roadId",alias:"道路号",type:"string"},{name:"roadName",alias:"道路名称",type:"string"},{name:"sectionId",alias:"路段号",type:"string"},{name:"laneId",alias:"车道号",type:"string"},{name:"type",alias:"类型",type:"string"}],objectIdField:"ObjectID",geometryType:"polygon",spatialReference:{wkid:4326},source:[],outFields:["*"],renderer:{type:"unique-value",field:"type",defaultSymbol:{type:"simple-fill",color:[100,100,100],style:"solid",outline:{color:"white",width:1}},uniqueValueInfos:[{value:"shoulder",label:"路肩",symbol:{type:"simple-fill",color:"#008000",style:"solid",outline:{color:"white",width:1}}},{value:"border",label:"路沿",symbol:{type:"simple-fill",color:"#DCDCDC",style:"solid",outline:{color:"white",width:1}}},{value:"driving",label:"机动车道",symbol:{type:"simple-fill",color:[47,79,79,.8],style:"solid",outline:{color:"white",width:1}}},{value:"none",label:"无",symbol:{type:"simple-fill",color:[111,120,135],style:"none",outline:{color:"white",width:1}}},{value:"restricted",label:"禁行区",symbol:{type:"simple-fill",color:"yellow",style:"solid",outline:{color:"yellow",width:2}}},{value:"parking",label:"停车区",symbol:{type:"simple-fill",color:[115,115,115],style:"solid",outline:{color:"white",width:1}}},{value:"median",label:"中央隔离带",symbol:{type:"simple-fill",color:"#008000",style:"solid",outline:{color:"white",width:1}}},{value:"biking",label:"非机动车道",symbol:{type:"simple-fill",color:"#D3D3D3",style:"solid",outline:{color:"white",width:1}}},{value:"sidewalk",label:"人行道",symbol:{type:"simple-fill",color:"#C0C0C0",style:"solid",outline:{color:"white",width:1}}},{value:"junction",label:"路口区域",symbol:{type:"simple-fill",color:"#2F4F4F",style:"solid",outline:{color:"white",width:1}}},{value:"selected",label:"选中车道",symbol:{type:"simple-fill",color:[141,168,211],style:"solid",outline:{color:"white",width:1}}}]}}),this.roadNameLayer=new I({id:"OpenDriveRoadName",fields:[{name:"ObjectID",alias:"ObjectID",type:"oid"},{name:"roadId",alias:"道路号",type:"string"},{name:"roadName",alias:"道路名称",type:"string"}],objectIdField:"ObjectID",geometryType:"polyline",spatialReference:{wkid:4326},source:[],renderer:{type:"simple",symbol:{type:"simple-line",style:"solid",color:[0,0,0,0],width:1}},labelingInfo:[{symbol:{type:"text",color:"black",haloColor:"white",haloSize:1,font:{size:12,family:"sans-serif"}},labelPlacement:"center-along",labelExpressionInfo:{expression:"$feature.roadName"}}]}),this.junctionLayer=new D({id:"OpenDriveJunction"}),this.highlightLayer=new D({id:"OpenDriveHighlight"}),this.view.map.addMany([this.laneLayer,this.junctionLayer,this.highlightLayer,this.roadNameLayer])}static getInstance(e){return this.instance||(this.instance=new v(e)),this.instance}async showOpenDriveFromFile(e){var l,d,a;const t=await this.wasmLoader.load(e.file);if(t.status!==0)return t;console.time("渲染用时");const{roads:i,junctions:s}=t.result;return await this.showAllLanes(i,((l=e.options)==null?void 0:l.showJunctionLane)||!1,((d=e.options)==null?void 0:d.showRoadName)||!0),(a=e.options)!=null&&a.showJunctionPolygon&&this.showJunction(s),console.timeEnd("渲染用时"),{status:0,message:"ok"}}async showOpenDriveFromServer(e,t){const i=`http://${e}/api/openDrive/analyzeXodr`,s=await N.get(i,{headers:{projectName:t},params:{analyze:!1,compressed:!0}});if(s.status!==200)throw new Error(`OpenDriveRenderer: ${s.statusText}`);let l=s.data.result.json;l.startsWith(window.location.protocol)||(l=`${window.location.protocol}//${e}${l}`);const a=await(await fetch(l)).arrayBuffer(),c=G.inflate(a,{to:"string"}),u=JSON.parse(c);return await this.showAllLanes(u,!1,!1),{status:0,message:"ok"}}async showAllLanes(e,t,i){const s=await this.laneLayer.queryFeatures();return s.features.length>0&&this.laneLayer.applyEdits({deleteFeatures:s.features}),this.roadNameLayer.visible=i,new Promise(l=>{let d=0;this.allLaneGraphics=[],this.allRefLineGraphics=[];for(const c of e){if(!t&&c.junction!=="-1")continue;const{id:u,refLine:p}=c;let h=c.name;h.includes("(")&&(h=h.slice(0,h.indexOf("(")));const w=new m({geometry:new b.Polyline({paths:[p]}),attributes:{ObjectID:d++,roadId:u,roadName:h}});this.allRefLineGraphics.push(w);for(const o of c.laneSections){const r=Number(o.id);for(const n of o.lanePaths){const f=Number(n.id);if(f===0)continue;const O=n.type,g=n.innerPath.concat(n.outerPath.reverse());if(g.length<=3){console.warn(`lane ${f} has less than 3 points`);continue}g.push(n.innerPath[0]);const L=new b.Polygon({rings:[g]});if(L){const j=new m({geometry:L,attributes:{ObjectID:d++,id:`${u}+${r}+${f}`,roadId:u,roadName:c.name,sectionId:r,laneId:f,type:O}});this.allLaneGraphics.push(j)}}}}const a=setInterval(()=>{if(this.allLaneGraphics.length>0||this.allRefLineGraphics.length>0){if(this.allLaneGraphics.length>0){const c=this.allLaneGraphics.splice(0,100);this.laneLayer.applyEdits({addFeatures:c})}if(this.allRefLineGraphics.length>0){const c=this.allRefLineGraphics.splice(0,10);this.roadNameLayer.applyEdits({addFeatures:c})}}else clearInterval(a),l()},10)})}async showJunction(e){for(const t of e){const i=new b.Polygon({rings:[t.outline]}),s=new m({geometry:i,attributes:{id:t.id,name:t.name},symbol:{type:"simple-fill",color:[47,79,79,.8],style:"solid",outline:{color:"white",width:1}}});this.junctionLayer.add(s)}}async clearOpenDrive(){const e=await this.laneLayer.queryFeatures();e.features.length>0&&this.laneLayer.applyEdits({deleteFeatures:e.features}),this.wasmLoader.clear()}async findSumo(e){const{id:t}=e,i=t.split("+");if(i.length>2)return{status:-1,message:"id格式错误"};const s=i.length===2?Number(i[1]):void 0,l=i[0].split("#");if(l.length>2)return{status:-1,message:"id格式错误"};const d=l[0],a=l.length===2?Number(l[1]):void 0;return await this.findLane({roadsectId:d,segmentId:a,laneId:s})}async findLane(e){let{roadsectId:t,segmentId:i,laneId:s}=e;t.startsWith("-")&&(t=t.slice(1)),console.log(t,i,s);const l=this.laneLayer.createQuery();l.returnGeometry=!0,l.outFields=["*"],l.where=`roadId = '${t}'`;const d=await this.laneLayer.queryFeatures(l);if(d.features.length===0)return{status:-1,message:"未找到。请检查路段编号"};let a=d.features;if(i!==void 0){const o=[];if(a.forEach(r=>{const n=Number(r.attributes.sectionId);o.indexOf(n)===-1&&o.push(n)}),o.sort((r,n)=>r-n),i>o.length-1)return{status:-1,message:"未找到。请检查基本段编号"};i=o[i],a=a.filter(r=>Number(r.attributes.sectionId)===i)}if(s!==void 0){const o=[];if(a.forEach(r=>{const n=Number(r.attributes.laneId);o.indexOf(n)===-1&&o.push(n)}),o.sort((r,n)=>r-n),s>o.length-1)return{status:-1,message:"未找到。请检查车道编号"};s=o[s],a=a.filter(r=>Number(r.attributes.laneId)===s)}const c=a.map(o=>o.geometry),u=await R.union(c);this.highlightLayer.removeAll(),this.highlightLayer.add(new m({geometry:u,symbol:{type:"simple-fill",style:"none",outline:{color:"red",width:2}}}));const p=new m({geometry:u,symbol:{type:"simple-fill",color:[255,0,0,.5],style:"solid",outline:{width:0}}});this.highlightLayer.add(p);let h=0;const w=setInterval(()=>{h%2===0?p.visible=!0:p.visible=!1,h++,h>10&&(this.highlightLayer.removeAll(),clearInterval(w))},500);return this.view.type==="2d"?await this.view.goTo(u,{duration:1e3}):await this.view.goTo(u,{duration:1e3}),{status:0,message:"ok"}}}exports.default=v;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ILaneInfo } from '../../../types';
|
|
2
|
+
interface ILink {
|
|
3
|
+
incoming: ILaneInfo;
|
|
4
|
+
connecting: ILaneInfo;
|
|
5
|
+
outgoing: ILaneInfo;
|
|
6
|
+
}
|
|
7
|
+
export default class Junction {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
/** 路口内的行车通道,包含进口道->转接道->出口道三个车道 */
|
|
11
|
+
laneLinks: Array<ILink>;
|
|
12
|
+
/** 进口车道按roadId归类, */
|
|
13
|
+
private incomingLanes;
|
|
14
|
+
private outline;
|
|
15
|
+
private wasmLoader;
|
|
16
|
+
private roadList;
|
|
17
|
+
constructor(odrJunction: any);
|
|
18
|
+
/**
|
|
19
|
+
* 在路口中,找到进口道的后继转接车道
|
|
20
|
+
* @param {string} roadId 进口道道路id
|
|
21
|
+
* @param {number} laneId 进口道车道id
|
|
22
|
+
* @returns {ILaneInfo[]}
|
|
23
|
+
*/
|
|
24
|
+
getSuccessorForIncoming(roadId: string, laneId: number): ILaneInfo[];
|
|
25
|
+
/**
|
|
26
|
+
* 在路口中,找到出口道的前驱转接车道
|
|
27
|
+
* @param {string} roadId 出口道道路id
|
|
28
|
+
* @param {number} laneId 出口道车道id
|
|
29
|
+
* @returns {ILaneInfo[]}
|
|
30
|
+
*/
|
|
31
|
+
getPredecessorForOutgoing(roadId: string, laneId: number): ILaneInfo[];
|
|
32
|
+
/**
|
|
33
|
+
* 获取路口轮廓线
|
|
34
|
+
* 要等所有路口对象生成之后才能调用,所以不放在初始化中
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
getJunctionOutline(): number[][];
|
|
38
|
+
/**
|
|
39
|
+
* 获取此路口各个进口道的停止线
|
|
40
|
+
*/
|
|
41
|
+
getRoadStopLine(): {
|
|
42
|
+
roadId: string;
|
|
43
|
+
line: number[][];
|
|
44
|
+
}[];
|
|
45
|
+
/**
|
|
46
|
+
* 获取此路口的所有进口车道
|
|
47
|
+
*/
|
|
48
|
+
getAllIncomingLanes(): ILaneInfo[];
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const m=require("../common-utils.js"),E=require("./draw-bezier.js"),$=require("./wasm-loader.js");class j{constructor(t){this.laneLinks=[],this.incomingLanes=new Map,this.wasmLoader=$.default.getInstance(),this.id=t.id,this.name=t.name,this.roadList=$.default.getInstance().roadList;const i=m.default.getStdVecEntries(t.odr_connections);for(const o of i){const n=o.connecting_road,e=this.roadList.get(n);if(!e){console.log(`转接道路不存在: ${n}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}if(!e.predecessor.elementId){console.log(`转接道路不存在predecessor: ${n}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}if(!e.successor.elementId){console.log(`转接道路不存在successor: ${n}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const{elementId:s,contactPoint:c}=e.predecessor,d=this.roadList.get(s);if(!d){console.log(`进口道路不存在: ${s}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const{elementId:a,contactPoint:h}=e.successor,l=this.roadList.get(a);if(!l){console.log(`出口道路不存在: ${a}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const L=m.default.getStdVecEntries(o.odr_lane_links);for(const r of L){const I=c==="start"?0:d.getLastLaneSection().s0,f=r.from;if(f===0){console.log("进口车道id为0"),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const p=0,u=r.to;if(u===0){console.log("转接车道id为0"),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const g=e.getFirstLaneSection().getLane(u);if(!g||(g==null?void 0:g.successor)===0){console.log(`转接车道不存在successor: ${n}_0_${u}`),console.log(`junction: ${this.id}, connection: ${o.id}`);continue}const S=h==="start"?0:l.getLastLaneSection().s0,v=g.successor;this.laneLinks.push({incoming:{roadId:s,sectionId:I,laneId:f},connecting:{roadId:n,sectionId:p,laneId:u},outgoing:{roadId:a,sectionId:S,laneId:v}})}}this.laneLinks.forEach(o=>{const n=o.incoming,{roadId:e,laneId:s}=n,c=this.incomingLanes.get(e);c?c.find(d=>d.laneId===s)||c.push(n):this.incomingLanes.set(e,[n])});for(const o of this.incomingLanes.values())o.sort((n,e)=>+(Math.abs(n.laneId)>Math.abs(e.laneId))||+(n.laneId===e.laneId)-1)}getSuccessorForIncoming(t,i){const o=[];return this.laneLinks.forEach(n=>{n.incoming.roadId===t&&n.incoming.laneId===i&&o.push(n.connecting)}),o}getPredecessorForOutgoing(t,i){const o=[];return this.laneLinks.forEach(n=>{n.outgoing.roadId===t&&n.outgoing.laneId===i&&o.push(n.connecting)}),o}getJunctionOutline(){if(this.outline)return this.outline;const t=[],i=[];this.incomingLanes.forEach(o=>{const n=this.wasmLoader.getLane(o[0]);n&&i.push(n)}),i.sort((o,n)=>{const e=o.drivingAngle<0?o.drivingAngle+360:o.drivingAngle,s=n.drivingAngle<0?n.drivingAngle+360:n.drivingAngle;return e-s}),i.push(i[0]);for(let o=0;o<i.length-1;o++){const n=i[o],e=i[o+1],s=n.laneSection.allLaneIds,c=n.id>0?s[0]:s[s.length-1],d=n.laneSection.getLane(c),a=e.laneSection.allLaneIds,h=e.id>0?a[a.length-1]:a[0],l=e.laneSection.getLane(h),L=d.getLaneEndPoints("outer").reverse(),r=l.getLaneEndPoints("outer").reverse(),I=E.default.drawBezierBetweenLane(L,r);t.push(...I)}return t.push(t[0]),this.outline=t,t}getRoadStopLine(){const t=[];for(const i of this.incomingLanes){const o=i[0],n=i[1],e=this.wasmLoader.getLane(n[0]);if(!e||e.isDirEqual===void 0)continue;const s=e.isDirEqual?e.laneSection.borders.top:e.laneSection.borders.bottom;t.push({roadId:o,line:s})}return t}getAllIncomingLanes(){return[...this.incomingLanes.values()].flat()}}exports.default=j;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ISampledLaneSection } from '../../../types';
|
|
2
|
+
import Lane from './lane';
|
|
3
|
+
import Road from './road';
|
|
4
|
+
export default class LaneSection {
|
|
5
|
+
/** 路段id:
|
|
6
|
+
* 在道路参考线上,路段起始点与道路起始点的距离
|
|
7
|
+
*/
|
|
8
|
+
s0: number;
|
|
9
|
+
road: Road;
|
|
10
|
+
/** 路段上下左右的边框 */
|
|
11
|
+
borders: {
|
|
12
|
+
left: number[][];
|
|
13
|
+
right: number[][];
|
|
14
|
+
top: number[][];
|
|
15
|
+
bottom: number[][];
|
|
16
|
+
};
|
|
17
|
+
/** 上下左右边框围成的多边形 */
|
|
18
|
+
polygon: number[][];
|
|
19
|
+
/** 路段内的车道 */
|
|
20
|
+
private idToLane;
|
|
21
|
+
constructor(odrLanesection: any, road: Road);
|
|
22
|
+
/**
|
|
23
|
+
* 获取一个车道
|
|
24
|
+
* @param id
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
getLane(id: number): Lane | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* 获取所有车道
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
get allLanes(): Lane[];
|
|
33
|
+
get laneNumber(): number;
|
|
34
|
+
/**
|
|
35
|
+
* 获取所有车道id,id升序排列
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
38
|
+
get allLaneIds(): number[];
|
|
39
|
+
/**
|
|
40
|
+
* 路段采样后的数据
|
|
41
|
+
*/
|
|
42
|
+
get sampledLaneSection(): ISampledLaneSection;
|
|
43
|
+
/**
|
|
44
|
+
* 计算路段上下左右边框
|
|
45
|
+
* @returns
|
|
46
|
+
*/
|
|
47
|
+
private getBorderLine;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("../common-utils.js"),c=require("./lane.js");class g{constructor(s,r){this.s0=s.s0,this.road=r,this.idToLane=new Map,u.default.getStdVecEntries(s.odr_lanes,!0).forEach(a=>{const n=new c.default(a,r,this);this.idToLane.set(n.id,n)}),this.borders=this.getBorderLine();const e=[];e.push(...this.borders.right),e.push(...this.borders.top),e.push(...[...this.borders.left].reverse()),e.push(...[...this.borders.bottom].reverse()),e.push(e[0]),this.polygon=e}getLane(s){return this.idToLane.get(s)}get allLanes(){return[...this.idToLane.values()]}get laneNumber(){return this.idToLane.size}get allLaneIds(){return[...this.idToLane.keys()].sort((s,r)=>s-r)}get sampledLaneSection(){const s=this.allLanes.filter(r=>r.id!==0);return{id:this.s0,lanePaths:s.map(r=>r.sampledLane)}}getBorderLine(){let s=[],r=[];const t=[],e=[],a=this.allLaneIds;return a.filter(n=>n!==0).forEach((n,p)=>{const o=this.getLane(n),i=o.innerBorder[o.innerBorder.length-1],h=o.outerBorder[o.outerBorder.length-1],l=o.innerBorder[0],d=o.outerBorder[0];p===0?(r=o.outerBorder,t.push(i),e.push(l)):p===a.length-2?(s=o.outerBorder,t.push(i),e.push(l)):o.id<0?(u.default.pointsEqual(h,t[t.length-1])||t.push(h),t.push(i),u.default.pointsEqual(d,e[e.length-1])||e.push(d),e.push(l)):(u.default.pointsEqual(i,t[t.length-1])||t.push(i),t.push(h),u.default.pointsEqual(l,e[e.length-1])||e.push(l),e.push(d))}),{left:s,right:r,top:t,bottom:e}}}exports.default=g;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ILaneInfo } from '../../../types';
|
|
2
|
+
import Lane from './lane';
|
|
3
|
+
export default class LaneUtils {
|
|
4
|
+
private static shpLanePolygonMap;
|
|
5
|
+
private static shpArrowPositionMap;
|
|
6
|
+
/**
|
|
7
|
+
* 判断车道航向角是否和参考线方向一致,
|
|
8
|
+
* 道路两端都连接到道路时无法计算,默认为true
|
|
9
|
+
* @param lane
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
static isLaneDirEqualDriveDir(lane: Lane): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 计算车道航向角
|
|
15
|
+
* @param lane
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
static getDriveAngle(lane: Lane): number;
|
|
19
|
+
/**
|
|
20
|
+
* 获取车道首尾端点,包括内侧、中间、外侧
|
|
21
|
+
* @param type
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
static getLaneEndPoints(lane: Lane, type?: string): number[][];
|
|
25
|
+
static getPrevAndNext(lane: Lane): {
|
|
26
|
+
predecessorLanes: ILaneInfo[];
|
|
27
|
+
successorLanes: ILaneInfo[];
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const m=require("@turf/bearing"),j=require("@turf/helpers"),a=require("./wasm-loader.js");function h(e){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(o,t,n.get?n:{enumerable:!0,get:()=>e[t]})}}return o.default=e,Object.freeze(o)}const I=h(j),L=class{static isLaneDirEqualDriveDir(e){var t,n;let o=0;if(((t=e.road.predecessor)==null?void 0:t.elementType)==="junction"){const c=e.road.predecessor.elementId,i=a.default.getInstance().junctionList.get(c);if(i){for(const d of i.laneLinks)if(d.outgoing.roadId===e.road.id){o=d.outgoing.laneId;break}}}else if(((n=e.road.successor)==null?void 0:n.elementType)==="junction"){const c=e.road.successor.elementId,i=a.default.getInstance().junctionList.get(c);if(i){for(const d of i.laneLinks)if(d.incoming.roadId===e.road.id){o=d.incoming.laneId;break}}}return o===0?!0:o*e.id>0}static getDriveAngle(e){const o=L.getLaneEndPoints(e),t=I.point(o[0]),n=I.point(o[1]);return m(t,n)}static getLaneEndPoints(e,o="middle"){let t,n,c,i;switch(e.isDirEqual?(t=e.innerBorder[0],n=e.innerBorder[e.innerBorder.length-1],c=e.outerBorder[0],i=e.outerBorder[e.outerBorder.length-1]):(t=e.innerBorder[e.innerBorder.length-1],n=e.innerBorder[0],c=e.outerBorder[e.outerBorder.length-1],i=e.outerBorder[0]),o){case"inner":return[t,n];case"outer":return[c,i];default:{const d=[(t[0]+c[0])/2,(t[1]+c[1])/2],g=[(n[0]+i[0])/2,(n[1]+i[1])/2];return[d,g]}}}static getPrevAndNext(e){var i,d,g,l;const o=[],t=[],n=e.laneSection.s0===0,c=e.road.isLastLaneSection(e.laneSection.s0);if(n){if(((i=e.road.predecessor)==null?void 0:i.elementType)==="junction"){const s=a.default.getInstance().junctionList.get(e.road.predecessor.elementId);if(s){const r=s.getSuccessorForIncoming(e.road.id,e.id);if(r.length>0)t.push(...r);else{const u=s.getPredecessorForOutgoing(e.road.id,e.id);o.push(...u)}}}else if(((d=e.road.predecessor)==null?void 0:d.elementType)==="road"&&e.predecessor!==0){const s=e.road.predecessor.elementId;let r=0;if(e.road.predecessor.contactPoint==="end"){const f=a.default.getInstance().roadList.get(s);f&&(r=f.getLastLaneSection().s0)}const u={roadId:s,sectionId:r,laneId:e.predecessor};e.isDirEqual?o.push(u):t.push(u)}}else if(e.predecessor!==0){const s=e.road.getPrevLaneSection(e.laneSection.s0);if(s){const r={roadId:e.road.id,sectionId:s.s0,laneId:e.predecessor};e.isDirEqual?o.push(r):t.push(r)}}if(c){if(((g=e.road.successor)==null?void 0:g.elementType)==="junction"){const s=a.default.getInstance().junctionList.get(e.road.successor.elementId);if(s){const r=s.getSuccessorForIncoming(e.road.id,e.id);if(r.length>0)t.push(...r);else{const u=s.getPredecessorForOutgoing(e.road.id,e.id);o.push(...u)}}}else if(((l=e.road.successor)==null?void 0:l.elementType)==="road"&&e.successor!==0){const s=e.road.successor.elementId;let r=0;if(e.road.successor.contactPoint==="end"){const f=a.default.getInstance().roadList.get(s);f&&(r=f.getLastLaneSection().s0)}const u={roadId:s,sectionId:r,laneId:e.successor};e.isDirEqual?t.push(u):o.push(u)}}else if(e.successor!==0){const s=e.road.getNextLaneSection(e.laneSection.s0);if(s){const r={roadId:e.road.id,sectionId:s.s0,laneId:e.successor};e.isDirEqual?t.push(r):o.push(r)}}return{predecessorLanes:o,successorLanes:t}}};let p=L;p.shpLanePolygonMap=new Map;p.shpArrowPositionMap=new Map;exports.default=p;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ISampledLane } from '../../../types';
|
|
2
|
+
import LaneSection from './lane-section';
|
|
3
|
+
import Road from './road';
|
|
4
|
+
export default class Lane {
|
|
5
|
+
/** 车道id:
|
|
6
|
+
* 车道在路段中的序号,-2,-1,0,1,2,...
|
|
7
|
+
*/
|
|
8
|
+
id: number;
|
|
9
|
+
/** 车道类型, driving/walk/bike... */
|
|
10
|
+
type: string;
|
|
11
|
+
/** 内侧边线采样点坐标 */
|
|
12
|
+
innerBorder: number[][];
|
|
13
|
+
/** 外侧边线采样点坐标 */
|
|
14
|
+
outerBorder: number[][];
|
|
15
|
+
road: Road;
|
|
16
|
+
laneSection: LaneSection;
|
|
17
|
+
predecessor: number;
|
|
18
|
+
successor: number;
|
|
19
|
+
/** 车道行车方向与正北夹角 */
|
|
20
|
+
private angle;
|
|
21
|
+
/** 车道行车方向是否与参考线方向一致 */
|
|
22
|
+
private _isDirEqual;
|
|
23
|
+
/**
|
|
24
|
+
* 行车方向是否已计算
|
|
25
|
+
* 存在无法计算行车方向, isDirEqual = undefined的情况,额外加一个标志
|
|
26
|
+
* */
|
|
27
|
+
private isDirEqualReady;
|
|
28
|
+
/**
|
|
29
|
+
* 车道面
|
|
30
|
+
*/
|
|
31
|
+
ring: number[][];
|
|
32
|
+
constructor(odrLane: any, road: Road, lanesection: LaneSection);
|
|
33
|
+
get isDirEqual(): boolean | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* 车道代码:道路id_路段id_车道id
|
|
36
|
+
*/
|
|
37
|
+
get laneCode(): string;
|
|
38
|
+
/**
|
|
39
|
+
* 车道边线采样后的数据
|
|
40
|
+
*/
|
|
41
|
+
get sampledLane(): ISampledLane;
|
|
42
|
+
/**
|
|
43
|
+
* 获取路段内同方向最外侧车道
|
|
44
|
+
*/
|
|
45
|
+
get outerMostLaneInTheSameDir(): Lane;
|
|
46
|
+
/**
|
|
47
|
+
* 车道航向角
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
get drivingAngle(): number;
|
|
51
|
+
/**
|
|
52
|
+
* 获取车道按行车方向的起点、终点,可选择内侧、中间、外侧
|
|
53
|
+
* @param type
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
getLaneEndPoints(type?: string): number[][];
|
|
57
|
+
/**
|
|
58
|
+
* 获取车道的前驱车道和后继车道
|
|
59
|
+
* @returns
|
|
60
|
+
*/
|
|
61
|
+
getLink(): {
|
|
62
|
+
predecessorLanes: import("../../../types").ILaneInfo[];
|
|
63
|
+
successorLanes: import("../../../types").ILaneInfo[];
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* 获取车道停止线
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
getStopLine(): number[][];
|
|
70
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const i=require("../common-utils.js"),r=require("./lane-utils.js");class d{constructor(e,t,n){this.isDirEqualReady=!1,this.road=t,this.laneSection=n,this.id=e.id,this.type=e.type,this.predecessor=e.predecessor,this.successor=e.successor;const o=i.default.getStdVecEntries(e.inner_border,!0);this.innerBorder=i.default.transformLineProjection(o);const a=i.default.getStdVecEntries(e.outer_border,!0);this.outerBorder=i.default.transformLineProjection(a);const s=this.innerBorder.concat([...this.outerBorder].reverse());s.push(s[0]),this.ring=s}get isDirEqual(){return this.isDirEqualReady||(this._isDirEqual=r.default.isLaneDirEqualDriveDir(this),this.isDirEqualReady=!0),this._isDirEqual}get laneCode(){return`${this.road.id}_${this.laneSection.s0}_${this.id}`}get sampledLane(){return{id:this.id,type:this.type,innerPath:this.innerBorder,outerPath:this.outerBorder}}get outerMostLaneInTheSameDir(){const e=this.laneSection.allLaneIds,t=this.id>0?e[e.length-1]:e[0];return this.laneSection.getLane(t)}get drivingAngle(){if(!this.angle){const e=r.default.getDriveAngle(this);this.angle=e}return this.angle}getLaneEndPoints(e="middle"){return r.default.getLaneEndPoints(this,e)}getLink(){return r.default.getPrevAndNext(this)}getStopLine(){const e=this.getLaneEndPoints("inner"),t=this.getLaneEndPoints("outer");return[e[1],t[1]]}}exports.default=d;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { IRoadLink, ISampledRoad } from '../../../types';
|
|
2
|
+
import LaneSection from './lane-section';
|
|
3
|
+
export default class Road {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
length: number;
|
|
7
|
+
junction: string;
|
|
8
|
+
successor: IRoadLink;
|
|
9
|
+
predecessor: IRoadLink;
|
|
10
|
+
/** 道路上下左右的边框 */
|
|
11
|
+
borders: {
|
|
12
|
+
left: number[][];
|
|
13
|
+
right: number[][];
|
|
14
|
+
top: number[][];
|
|
15
|
+
bottom: number[][];
|
|
16
|
+
};
|
|
17
|
+
/** 上下左右边框围成的多边形 */
|
|
18
|
+
polygon: number[][];
|
|
19
|
+
refLine: number[][];
|
|
20
|
+
private sToLaneSection;
|
|
21
|
+
constructor(odrRoad: any);
|
|
22
|
+
/**
|
|
23
|
+
* 获取一个路段
|
|
24
|
+
* @param s0
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
getLaneSection(s0: number): LaneSection | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* 获取第一个路段
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
getFirstLaneSection(): LaneSection;
|
|
33
|
+
/**
|
|
34
|
+
* 获取最后一个路段
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
getLastLaneSection(): LaneSection;
|
|
38
|
+
/**
|
|
39
|
+
* 是否是最后一个路段的里程值
|
|
40
|
+
* @param s
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
isLastLaneSection(s: number): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* 获取下一个路段
|
|
46
|
+
* @param s
|
|
47
|
+
*/
|
|
48
|
+
getNextLaneSection(s: number): LaneSection | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* 获取上一个路段
|
|
51
|
+
* @param s
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
getPrevLaneSection(s: number): LaneSection | undefined;
|
|
55
|
+
/** 获取所有路段 */
|
|
56
|
+
get allLaneSections(): LaneSection[];
|
|
57
|
+
get laneSectionNumber(): number;
|
|
58
|
+
get sampledRoad(): ISampledRoad;
|
|
59
|
+
private getBorderLine;
|
|
60
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("../common-utils.js"),h=require("./lane-section.js");class l{constructor(e){this.id=e.id,this.name=e.name,this.length=e.length,this.junction=e.junction,this.sToLaneSection=new Map;const t=a.default.getStdVecEntries(e.ref_line,!0);this.refLine=a.default.transformLineProjection(t);for(const i of[!0,!1]){const o=i?e.predecessor:e.successor,r={elementId:o.id,elementType:o.type,contactPoint:o.contact_point};i?this.predecessor=r:this.successor=r}a.default.getStdVecEntries(e.odr_lanesections,!0).forEach(i=>{const o=new h.default(i,this);this.sToLaneSection.set(o.s0,o)}),this.borders=this.getBorderLine();const n=[];n.push(...this.borders.right),n.push(...this.borders.top),n.push(...[...this.borders.left].reverse()),n.push(...[...this.borders.bottom].reverse()),n.push(n[0]),this.polygon=n}getLaneSection(e){return this.sToLaneSection.get(e)}getFirstLaneSection(){const e=[...this.sToLaneSection.keys()];return e.sort((t,s)=>t-s),this.sToLaneSection.get(e[0])}getLastLaneSection(){const e=[...this.sToLaneSection.keys()];return e.sort((t,s)=>t-s),this.sToLaneSection.get(e[e.length-1])}isLastLaneSection(e){const t=[...this.sToLaneSection.keys()];return t.sort((s,n)=>s-n),e===t[t.length-1]}getNextLaneSection(e){const t=[...this.sToLaneSection.keys()],s=t.indexOf(e);if(s>=0&&s<t.length-1)return this.sToLaneSection.get(t[s+1])}getPrevLaneSection(e){const t=[...this.sToLaneSection.keys()],s=t.indexOf(e);if(s>0)return this.sToLaneSection.get(t[s-1])}get allLaneSections(){return[...this.sToLaneSection.values()]}get laneSectionNumber(){return this.sToLaneSection.size}get sampledRoad(){return{id:this.id,name:this.name,junction:this.junction,refLine:this.refLine,laneSections:this.allLaneSections.map(e=>e.sampledLaneSection)}}getBorderLine(){const e=[],t=[];let s=[],n=[];const i=[...this.sToLaneSection.keys()];return i.forEach((o,r)=>{const c=this.getLaneSection(o);r===0?n=c.borders.bottom:r===i.length-1&&(s=c.borders.top),e.push(...c.borders.left),t.push(...c.borders.right)}),{left:e,right:t,top:s,bottom:n}}}exports.default=l;
|