@maptalks/traffic 0.98.0 → 0.98.2
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @maptalks/traffic v0.98.
|
|
2
|
+
* @maptalks/traffic v0.98.2
|
|
3
3
|
* LICENSE : UNLICENSED
|
|
4
4
|
* (c) 2016-2024 maptalks.org
|
|
5
5
|
*/
|
|
@@ -915,5 +915,5 @@ class L {
|
|
|
915
915
|
|
|
916
916
|
export { L as TrafficScene };
|
|
917
917
|
|
|
918
|
-
"undefined" != typeof console && console.log("@maptalks/traffic v0.98.
|
|
918
|
+
"undefined" != typeof console && console.log("@maptalks/traffic v0.98.2");
|
|
919
919
|
//# sourceMappingURL=maptalks.traffic.es.js.map
|
package/dist/maptalks.traffic.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @maptalks/traffic v0.98.
|
|
2
|
+
* @maptalks/traffic v0.98.2
|
|
3
3
|
* LICENSE : UNLICENSED
|
|
4
4
|
* (c) 2016-2024 maptalks.org
|
|
5
5
|
*/
|
|
6
|
-
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("maptalks"),require("@turf/turf"),require("@maptalks/gltf-layer")):"function"==typeof define&&define.amd?define(["exports","maptalks","@turf/turf","@maptalks/gltf-layer"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).maptalks=t.maptalks||{},t.maptalks,t.turf,t.maptalks)}(this,(function(t,i,s,e){"use strict";function h(t){var i=Object.create(null);return t&&Object.keys(t).forEach((function(s){if("default"!==s){var e=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(i,s,e.get?e:{enumerable:!0,get:function(){return t[s]}})}})),i.default=t,Object.freeze(i)}var n=h(i),r=h(s);let o=0;function u(t,i,s){return t.length!==+t.length&&(t=Object.values(t)),t[c(t.length-1)]}function l(t){const i=++o+"";return t?t+i:i}function c(t,i){return i||(i=t,t=0),t+Math.floor(Math.random()*(i-t+1))}class a{constructor(t,i){this.source=t,this.target=i}get vector(){return this.target.subtract(this.source)}get length(){return this.vector.length}get direction(){return this.vector.direction}get center(){return this.getPoint(.5)}split(t,i){let s,e,h,n,r,o;const u=i?function(){r=[];for(let i=n=t-1;n<=0?i<=0:i>=0;n<=0?i++:i--)r.push(i);return r}.apply(this):function(){o=[];for(let i=0,s=t-1;0<=s?i<=s:i>=s;0<=s?i++:i--)o.push(i);return o}.apply(this),l=[];for(e=0,h=u.length;e<h;e++)s=u[e],l.push(this.subsegment(s/t,(s+1)/t));return l}getPoint(t){return this.source.add(this.vector.mult(t))}subsegment(t,i){const s=this.vector,e=this.source.add(s.mult(t)),h=this.source.add(s.mult(i));return new a(e,h)}}class f{constructor(t,i,s,e){this.A=t,this.B=i,this.O=s,this.Q=e,this.AO=new a(this.A,this.O),this.OQ=new a(this.O,this.Q),this.QB=new a(this.Q,this.B),this.len=null}get length(){let t,i,s,e,h;if(null==this.len)for(s=10,e=null,this.len=0,t=h=0;h<=10;t=++h)i=this.getPoint(t/10),e&&(this.len+=i.subtract(e).length),e=i;return this.len}getPoint(t){const i=this.AO.getPoint(t),s=this.OQ.getPoint(t),e=this.QB.getPoint(t),h=new a(i,s).getPoint(t),n=new a(s,e).getPoint(t);return new a(h,n).getPoint(t)}getDirection(t){const i=this.AO.getPoint(t),s=this.OQ.getPoint(t),e=this.QB.getPoint(t),h=new a(i,s).getPoint(t),n=new a(s,e).getPoint(t);return new a(h,n).direction}}class d{constructor(t,i,s){this.id=l("laneposition"),this.free=!0,this.car=t,this.position=s,this.tmpLane=i}get lane(){return this.tmpLane}set lane(t){this.release(),this.tmpLane=t}get relativePosition(){return this.position/this.lane.length}get nextCarDistance(){let t,i;const s=this.getNext();return s?(i=s.position-s.car.length/2,t=this.position+this.car.length/2,{car:s.car,distance:i-t}):{car:null,distance:1/0}}acquire(){let t;return null!=(null!=(t=this.lane)?t.addCarPosition:void 0)?(this.free=!1,this.lane.addCarPosition(this)):null}release(){let t;return!this.free&&(null!=(t=this.lane)?t.removeCar:void 0)?(this.free=!0,this.lane.removeCar(this)):null}getNext(){return this.lane&&!this.free?this.lane.getNext(this):null}}class g{constructor(t,i,s){this.isChangingLanes=!1,this.car=t,this.current=new d(t,i,s||0),this.current.acquire(),this.next=new d(t),this.temp=new d(t)}get lane(){return this.temp.lane||this.current.lane}get absolutePosition(){return null!==this.temp.lane&&void 0!==this.temp.lane?this.temp.position:this.current.position}get relativePosition(){return this.absolutePosition/this.lane.length}get direction(){return this.lane.getDirection()}get coords(){return this.lane.getPoint(this.relativePosition)}get nextCarDistance(){const t=this.current.nextCarDistance,i=this.next.nextCarDistance;return t.distance<i.distance?t:i}get distanceToStopLine(){return this.canEnterIntersection()?1/0:this.getDistanceToIntersection()}get nextIntersection(){return this.current.lane.road.target}get previousIntersection(){return this.current.lane.road.source}isValidTurn(){const t=this.car.nextLane,i=this.current.lane,s=i.getTurnDirection(t);if(3===s)throw Error("no U-turns are allowed");if(0===s&&!i.isLeftmost)throw Error("no left turns from this lane");if(2===s&&!i.isRightmost)throw Error("no right turns from this lane");return!0}canEnterIntersection(){const t=this.car.nextLane,i=this.current.lane;if(!t)return!0;const s=this.nextIntersection,e=i.getTurnDirection(t),h=i.road.targetSideId;return s.controlSignals.state[h][e]}getDistanceToIntersection(){const t=this.current.lane.length-this.car.length/2-this.current.position;return this.isChangingLanes?1/0:Math.max(t,0)}timeToMakeTurn(t){return void 0===t&&(t=0),this.getDistanceToIntersection()<=t}moveForward(t){let i,s;t=Math.max(t,0),this.current.position+=t,this.next.position+=t,this.temp.position+=t,this.timeToMakeTurn()&&this.canEnterIntersection()&&this.isValidTurn()&&this.t(this.car.popNextLane(),0);const e=this.temp.position/(null!=(i=this.temp.lane)?i.length:void 0),h=2*this.car.length;return this.isChangingLanes&&this.temp.position>h&&!this.current.free&&this.current.release(),this.isChangingLanes&&this.next.free&&this.temp.position+h>(null!=(s=this.temp.lane)?s.length:void 0)&&this.next.acquire(),this.isChangingLanes&&e>=1&&this.i(),!this.current.lane||this.isChangingLanes||this.car.nextLane?null:this.car.pickNextLane()}changeLane(t){if(this.isChangingLanes)throw Error("already changing lane");if(null==t)throw Error("no next lane");if(t===this.lane)throw Error("next lane == current lane");if(this.lane.road!==t.road)throw Error("not neighbouring lanes");const i=this.current.position+3*this.car.length;return this.t(t,i)}h(){const t=this.current.lane.getPoint(this.current.relativePosition),i=this.next.lane.getPoint(this.next.relativePosition),s=i.subtract(t).length,e=this.current.lane.middleLine.vector.normalized.mult(.3*s),h=t.add(e),n=this.next.lane.middleLine.vector.normalized.mult(.3*s),r=i.subtract(n);return new f(t,i,h,r)}o(){return this.h()}t(t,i){if(this.isChangingLanes)throw Error("already changing lane");if(null==t)return 0;this.isChangingLanes=!0,this.next.lane=t,this.next.position=i;const s=this.o();return this.temp.lane=s,this.temp.position=0,this.next.position-=this.temp.lane.length}i(){if(!this.isChangingLanes)throw Error("no lane changing is going on");return this.isChangingLanes=!1,this.current.lane=this.next.lane,this.current.position=this.next.position||0,this.current.acquire(),this.next.lane=null,this.next.position=NaN,this.temp.lane=null,this.temp.position=NaN,this.current.lane}release(){let t,i,s;return null!=(t=this.current)&&t.release(),null!=(i=this.next)&&i.release(),null!=(s=this.temp)?s.release():void 0}}const w=[];class p{constructor(t,i){this.type=c(w.length-1),this.id=l("car"),this.color=(300+240*Math.random()|0)%360,this.preferedLane=null,this.width=2,this.length=2,this.tmpSpeed=0,this.maxSpeed=30,this.s0=2,this.timeHeadway=1.5,this.maxAcceleration=1,this.maxDeceleration=3,this.alive=!0,this.trajectory=new g(this,t,i)}get coords(){return this.trajectory.coords}get speed(){return this.tmpSpeed}set speed(t){t<0&&(t=0),t>this.maxSpeed&&(t=this.maxSpeed),this.tmpSpeed=t}get direction(){return this.trajectory.direction}release(){return this.trajectory.release()}getAcceleration(){let t;const i=this.trajectory.nextCarDistance,s=Math.max(i.distance,0),e=this.maxAcceleration,h=this.maxDeceleration,n=this.speed-(null!=(t=i.car)?t.speed:void 0)||0,r=Math.pow(this.speed/this.maxSpeed,4),o=this.s0,u=this.speed*this.timeHeadway,l=o+u+this.speed*n/(2*Math.sqrt(e*h)),c=Math.pow(l/s,2),a=1+u+Math.pow(this.speed,2)/(2*h),f=1-r-c-Math.pow(a/this.trajectory.distanceToStopLine,2);return this.maxAcceleration*f}move(t){const i=this.getAcceleration();if(this.speed+=i*t,!this.trajectory.isChangingLanes&&this.nextLane){const t=this.trajectory.current.lane,i=t.getTurnDirection(this.nextLane),s=function(){switch(i){case 0:return t.leftmostAdjacent;case 2:return t.rightmostAdjacent;default:return t}}();s!==t&&this.trajectory.changeLane(s)}const s=this.speed*t+.5*i*Math.pow(t,2);return this.trajectory.nextCarDistance.distance<s&&console.log("bad IDM"),this.trajectory.timeToMakeTurn(s)&&null==this.nextLane?(this.alive=!1,this.alive):this.trajectory.moveForward(s)}pickNextRoad(){const t=this.trajectory.nextIntersection,i=this.trajectory.current.lane,s=t.roads.filter((function(t){return t.target!==i.road.source}));if(0===s.length)return null;return u(s)}pickNextLane(){if(this.nextLane)throw Error("next lane is already chosen");this.nextLane=null;const t=this.pickNextRoad();if(!t)return null;const i=this.trajectory.current.lane.road.getTurnDirection(t),s=function(){switch(i){case 0:return t.lanesNumber-1;case 1:return c(0,t.lanesNumber-1);case 2:return 0}return null}();return this.nextLane=t.lanes[s],this.nextLane}popNextLane(){const t=this.nextLane;return this.nextLane=null,this.preferedLane=null,t}}class m{constructor(t){this.flipMultiplier=.4*Math.random()-.2+1,this.time=0,this.stateNum=0,this.lightsFlipInterval=20,this.states=[["L","","L",""],["FR","","FR",""],["","L","","L"],["","FR","","FR"]],this.intersection=t}get flipInterval(){return this.flipMultiplier*this.lightsFlipInterval}get state(){let t=this.states[this.stateNum%this.states.length];this.intersection.roads.length<=2&&(t=["LFR","LFR","LFR","LFR"]);const i=[];for(let s=0,e=t.length;s<e;s++){const e=t[s];i.push(this.decode(e))}return i}decode(t){const i=[0,0,0],s=[].indexOf||function(t){for(let i=0,s=this.length;i<s;i++)if(i in this&&this[i]===t)return i;return-1};return s.call(t,"L")>=0&&(i[0]=1),s.call(t,"F")>=0&&(i[1]=1),s.call(t,"R")>=0&&(i[2]=1),i}flip(){return this.stateNum+=1}onTick(t){return this.time+=t,this.time>this.flipInterval?(this.flip(),this.time-=this.flipInterval):null}}class v{constructor(t,i){this.x=0,this.y=0,t&&(this.x=t),i&&(this.y=i)}get length(){return Math.sqrt(this.x*this.x+this.y*this.y)}get direction(){return Math.atan2(this.y,this.x)}get normalized(){return new v(this.x/this.length,this.y/this.length)}add(t){return new v(this.x+t.x,this.y+t.y)}subtract(t){return new v(this.x-t.x,this.y-t.y)}mult(t){return new v(this.x*t,this.y*t)}divide(t){return new v(this.x/t,this.y/t)}}class b{constructor(t,i,s,e){this.x=0,this.y=0,this.width=0,this.height=0,this.x=t||0,this.y=i||0,this.width=s||0,this.height=e||0}static copy(t){return new b(t.x,t.y,t.width,t.height)}toJSON(){return Object.assign({},this)}area(){return this.width*this.height}left(t){return void 0!==t&&(this.x=t),this.x}right(t){return void 0!==t&&(this.x=t-this.width),this.x+this.width}top(t){return void 0!==t&&(this.y=t),this.y}bottom(t){return void 0!==t&&(this.y=t-this.height),this.y+this.height}center(t){return void 0!==t&&(this.x=t.x-this.width/2,this.y=t.y-this.height/2),new v(this.x+this.width/2,this.y+this.height/2)}containsPoint(t){let i,s;return this.left()<=(i=t.x)&&i<=this.right()&&this.top()<=(s=t.y)&&s<=this.bottom()}containsRect(t){return this.left()<=t.left()&&t.right()<=this.right()&&this.top()<=t.top()&&t.bottom()<=this.bottom()}getVertices(){return[new v(this.left(),this.top()),new v(this.right(),this.top()),new v(this.right(),this.bottom()),new v(this.left(),this.bottom())]}getSide(t){const i=this.getVertices();return new a(i[t],i[(t+1)%4])}getSectorId(t){const i=t.subtract(this.center());if(i.y<=0&&Math.abs(i.x)<=Math.abs(i.y))return 0;if(i.x>=0&&Math.abs(i.x)>=Math.abs(i.y))return 1;if(i.y>=0&&Math.abs(i.x)<=Math.abs(i.y))return 2;if(i.x<=0&&Math.abs(i.x)>=Math.abs(i.y))return 3;throw new Error("algorithm error")}getSector(t){return this.getSide(this.getSectorId(t))}}class M{constructor(t){this.id=l("intersection"),this.rect=t,this.roads=[],this.inRoads=[],this.controlSignals=new m(this)}static copy(t){t.rect=b.copy(t.rect);const i=Object.create(M.prototype);return Object.assign(i,t),i.roads=[],i.inRoads=[],i.controlSignals=new m(i),i}toJSON(){return{id:this.id,rect:this.rect}}update(){let t,i,s,e,h;const n=this.roads;for(i=0,e=n.length;i<e;i++)t=n[i],t.update();const r=this.inRoads,o=[];for(s=0,h=r.length;s<h;s++)t=r[s],o.push(t.update());return o}}class y{constructor(t,i){let s,e,h;if(this.objects={},this.factory=t,i&&i.objects)for(s in h=i.objects,h)e=h[s],this.factory instanceof p||(this.objects[s]=this.factory.copy(e))}get length(){return Object.keys(this.objects).length}toJSON(){return this.objects}get(t){return this.objects[t]}put(t){return this.objects[t.id]=t}pop(t){let i;const s=null!==(i=t.id)?i:t,e=this.objects[s];return e instanceof p&&e.release(),delete this.objects[s],e}all(){return this.objects}clear(){return this.objects={}}}class O{constructor(t,i,s){this.leftmostAdjacent=null,this.rightmostAdjacent=null,this.carsPositions={},this.sourceSegment=t,this.targetSegment=i,this.road=s,this.update()}get sourceSideId(){return this.road.sourceSideId}get targetSideId(){return this.road.targetSideId}get isRightmost(){return this===this.rightmostAdjacent}get isLeftmost(){return this===this.leftmostAdjacent}get leftBorder(){return new a(this.sourceSegment.source,this.targetSegment.target)}get rightBorder(){return new a(this.sourceSegment.target,this.targetSegment.source)}toJSON(){const t=Object.assign({},this);return delete t.carsPositions,t}update(){return this.middleLine=new a(this.sourceSegment.center,this.targetSegment.center),this.length=this.middleLine.length,this.direction=this.middleLine.direction}getTurnDirection(t){return t?this.road.getTurnDirection(t.road):1}getDirection(){return this.direction}getPoint(t){return this.middleLine.getPoint(t)}addCarPosition(t){if(t.id in this.carsPositions)throw Error("car is already here");return this.carsPositions[t.id]=t}removeCar(t){if(!(t.id in this.carsPositions))throw Error("removing unknown car");return delete this.carsPositions[t.id]}getNext(t){if(t.lane!==this)throw Error("car is on other lane");let i=null,s=1/0;const e=this.carsPositions;for(const h in e){const n=e[h],r=n.position-t.position;!n.free&&0<r&&r<s&&(s=r,i=n)}return i}}class L{constructor(t,i,s){this.id=l("road"),this.lanes=[],this.lanesNumber=null,this.source=t,this.target=i,this.gridSize=s||32,this.update()}get length(){return this.targetSide.target.subtract(this.sourceSide.source).length}get leftmostLane(){return this.lanes[this.lanesNumber-1]}get rightmostLane(){return this.lanes[0]}copy(t){const i=Object.create(L.prototype);return Object.assign(i,t),null==i.lanes&&(i.lanes=[]),i}toJSON(){return{id:this.id,source:this.source.id,target:this.target.id}}getTurnDirection(t){if(this.target!==t.source)throw Error("invalid roads");const i=this.targetSideId;return(t.sourceSideId-i-1+8)%4}update(){let t,i,s,e,h,n;if(!this.source||!this.target)throw Error("incomplete road");this.sourceSideId=this.source.rect.getSectorId(this.target.rect.center()),this.sourceSide=this.source.rect.getSide(this.sourceSideId).subsegment(.5,1),this.targetSideId=this.target.rect.getSectorId(this.source.rect.center()),this.targetSide=this.target.rect.getSide(this.targetSideId).subsegment(0,.5),this.lanesNumber=0|Math.min(this.sourceSide.length,this.targetSide.length),this.lanesNumber=Math.max(2,this.lanesNumber/this.gridSize|0);const r=this.sourceSide.split(this.lanesNumber,!0),o=this.targetSide.split(this.lanesNumber);if(null==this.lanes||this.lanes.length<this.lanesNumber)for(null==this.lanes&&(this.lanes=[]),t=s=0,h=this.lanesNumber-1;0<=h?s<=h:s>=h;t=0<=h?++s:--s)null==(i=this.lanes)[t]&&(i[t]=new O(r[t],o[t],this));const u=[];for(t=e=0,n=this.lanesNumber-1;0<=n?e<=n:e>=n;t=0<=n?++e:--e)this.lanes[t].sourceSegment=r[t],this.lanes[t].targetSegment=o[t],this.lanes[t].leftAdjacent=this.lanes[t+1],this.lanes[t].rightAdjacent=this.lanes[t-1],this.lanes[t].leftmostAdjacent=this.lanes[this.lanesNumber-1],this.lanes[t].rightmostAdjacent=this.lanes[0],u.push(this.lanes[t].update());return u}}class x{constructor(t){this.toRemove=[],this.carsList={},this.u=0,this.l=0,this.p=new e.GLTFLayer("traffic"),this.m=5,this.v="stop",this.M=[],this.L={},this.options=t||{},this.carsNumber=this.options.carsNumber||10,this.gridSize=this.options.gridSize||32,this.set()}run(){this.v="running",this.C()}stop(){this.v="stop"}remove(){this.N&&cancelAnimationFrame(this.N),this.p.remove(),delete this.map}setSymbols(t){this.M=t;for(let t=0;t<this.M.length;t++){const i=this.M[t];this.L[i.url]=new e.MultiGLTFMarker([],{symbol:i}).addTo(this.p)}}C(){if("running"!==this.v)return;const t=Date.now();this.u=t;const i=Date.now();let s,e=i-this.l||0;e>100&&(e=100),this.l=i,this.onTick(this.m*e/1e3);let h=this.toRemove.length;for(;h--;)this.j(this.toRemove[h]);this.clearTmpRemove();const n=this.cars.all();for(s in n)this.I(n[s]);this.N=window.requestAnimationFrame(this.C.bind(this))}R(){for(const t in this.L)this.L[t].removeData();for(const t in this.carsList){const i=this.carsList[t],s=i.url;this.L[s].addData(i)}}I(t){const i=t.id.substring(3);if(this.carsList[i]){if(!t)return;const s=t.coords,e=t.direction,h=this.map,r=h.pointAtResToCoordinate(new n.Point(s.x/this.gridSize,s.y/this.gridSize),h.getGLRes()),o=e/Math.PI*180+90;this.carsList[i].coordinates=r,this.carsList[i].rotation=[0,0,o];const u=this.S(i),l=this.carsList[i].url;u>-1?this.L[l].updateData(u,this.carsList[i]):this.L[l].addData(this.carsList[i])}else{const t=this.M[Math.floor(Math.random()*this.M.length)];this.carsList[i]={coordinates:null,direction:null,url:t.url},this.showHideCar(this.carsList[i],"show")}}showHideCar(t,i,s){const e=this;n.animation.Animation.animate({symbol:{transparent:1}},{duration:1e3,easing:"out"},(function(h){if("running"===h.state.playState){let n=0;"show"===i?(n=h.styles.symbol.transparent,t.color=[1,1,1,n]):"hide"===i&&(n=1-h.styles.symbol.transparent,t.color=[1,1,1,n],n<.01&&setTimeout((function(){const t=e.S(s);if(!e.carsList[s])return;const i=e.carsList[s].url;t>-1&&e.L[i].removeData(t),delete e.carsList[s]}),100))}})).play()}S(t){const i=this.carsList[t];if(!i)return-1;const s=i.url;return this.L[s].getAllData().indexOf(this.carsList[t])}j(t){const i=t.substring(3);null!=this.carsList[i]&&this.showHideCar(this.carsList[i],"hide",i)}get instantSpeed(){const t=Object.values(this.cars.all()).map((t=>t.speed));return 0===t.length?0:t.reduce((function(t,i){return t+i}))/t.length}get map(){const t=this.T;return t?t.getMap():null}addTo(t){this.T=t,this.p.addTo(t)}set(t){return null==t&&(t={}),this.intersections=new y(M,t.intersections),this.roads=new y(L,t.roads),this.cars=new y(p,t.cars),this.carsNumber=0}save(){const t=Object.assign({},this);return delete t.cars,window.localStorage.world=JSON.stringify(t)}setCarNumber(t){this.carsNumber=t}getCarNumber(){return this.carsNumber}load(){let t,i,s,e;if(t=window.localStorage.world,t=t&&JSON.parse(t),null==t)return null;this.clear(),this.carsNumber=t.carsNumber||0;const h=t.intersections;for(i in h)s=h[i],this.addIntersection(M.copy(s));const n=t.roads,r=[];for(i in n)e=n[i],e=(new L).copy(e),e.source=this.getIntersection(e.source),e.target=this.getIntersection(e.target),r.push(this.addRoad(e));return r}intersectSegment(t,i){for(let s=0;s<i.length-1;s++){const e=[i[s],i[s+1]],h=r.lineString(e),n=r.lineIntersect(t,h);if(n.features.length)return{intersectIndex:s,coord:n.features[0].geometry.coordinates}}return null}intersection(t,i,s,e,h,n){const o=r.lineString(t);for(let t=i+1;t<e.length;t++){const r=e[t],u=this.intersectSegment(o,r);if(!u)continue;const l={};l[i]={pre:s},l[t]={pre:u.intersectIndex+n[t]};const c={inLines:l,coordinate:this.map.coordinateToPointAtRes({x:u.coord[0],y:u.coord[1]},this.map.getGLRes())};h.push(c)}}generateTraffic(t){if(!this.map)return;const i={};let s=0;for(let e=0;e<t.length;e++)i[e]=s,s+=t[e].length;const e=[];let h=0;for(let s=0;s<t.length;s++){const n=t[s];for(let r=0;r<n.length-1;r++){const o=[n[r],n[r+1]];this.intersection(o,s,h+r,t,e,i)}h+=n.length}const n=[];let r=0;const o=this.map;for(let i=0;i<t.length;i++){const s=t[i];for(let t=0;t<s.length;t++){const e=o.coordinateToPointAtRes({x:s[t][0],y:s[t][1]},o.getGLRes()),h={};0===t?h[i]={pre:null}:(s.length,h[i]={pre:t-1+r});const u={inLines:h,coordinate:e};n.push(u)}r+=s.length}for(let t=0;t<n.length;t++){const i=n[t];this.comparePrePoint(i,t,e)}const u=this.gridSize,l=[];for(let t=0;t<n.length;t++){const i=n[t],s=i.coordinate.x,e=i.coordinate.y,h=new b(s*u-.5,e*u-.5,1,1),r=new M(h);r.connectRoads=i.roads,l.push(r),this.addIntersection(r)}const c=[];for(let t=0;t<e.length;t++){const i=e[t],s=i.coordinate.x,h=i.coordinate.y,n=new b(s*u-.5,h*u-.5,1,1),r=new M(n);r.connectRoads=i.roads,c.push(r),this.addIntersection(r)}for(let t=0;t<l.length;t++){const i=l[t],s=i.connectRoads;if(s)for(let t=0;t<s.length;t++){const e=s[t];if(null!=e.pre){let t=null;const s=e.type;"line"===s?t=l[e.pre]:"line-interact"===s&&(t=c[e.pre]),this.addRoad(new L(i,t)),this.addRoad(new L(t,i))}}}for(let t=0;t<c.length;t++){const i=c[t],s=i.connectRoads;if(s)for(let t=0;t<s.length;t++){const e=s[t];if(null!=e.pre){let t=null;const s=e.type;"line"===s?t=l[e.pre]:"line-interact"===s&&(t=c[e.pre]),this.addRoad(new L(i,t)),this.addRoad(new L(t,i))}}}}comparePrePoint(t,i,s){const e=this.getPre(t);if(e){const{pre:h,lineIndex:n}=e;for(let e=0;e<s.length;e++){const r=s[e];r.inLines[n]&&r.inLines[n].pre===h&&(t.roads=[{pre:e,type:"line-interact"}],r.roads?r.roads.push({pre:i-1,type:"line"}):r.roads=[{pre:i-1,type:"line"}])}t.roads||(t.roads=[{pre:i-1,type:"line"}])}}getPre(t){for(const i in t.inLines)if(null!==t.inLines[i].pre)return{pre:t.inLines[i].pre,lineIndex:i};return null}clear(){return this.set({})}onTick(t){let i,s,e;if(t>1)throw Error("delta > 1");this.refreshCars();const h=this.intersections.all();for(s in h)e=h[s],e.controlSignals.onTick(t);const n=this.cars.all(),r=[];for(s in n)i=n[s],i.move(t),i.alive?r.push(void 0):r.push(this.removeCar(i));return r}refreshCars(){return this.cars.length<this.carsNumber&&this.addRandomCar(),this.cars.length>this.carsNumber?this.removeRandomCar():null}addRoad(t){return this.roads.put(t),t.source.roads.push(t),t.target.inRoads.push(t),t.update()}getRoad(t){return this.roads.get(t)}addCar(t){return this.cars.put(t)}getCar(t){return this.cars.get(t)}removeCar(t){return this.toRemove.push(t.id),this.cars.pop(t)}clearTmpRemove(){this.toRemove=[]}addIntersection(t){return this.intersections.put(t)}getIntersection(t){return this.intersections.get(t)}addRandomCar(){let t;const i=u(this.roads.all());return null!=i&&(t=u(i.lanes),null!=t)?this.addCar(new p(t)):null}removeRandomCar(){const t=u(this.cars.all());return null!=t?this.removeCar(t):null}}"undefined"!=typeof window&&window.maptalks&&(window.maptalks.TrafficScene=x),t.TrafficScene=x,"undefined"!=typeof console&&console.log("@maptalks/traffic v0.98.0")}));
|
|
6
|
+
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("maptalks"),require("@turf/turf"),require("@maptalks/gltf-layer")):"function"==typeof define&&define.amd?define(["exports","maptalks","@turf/turf","@maptalks/gltf-layer"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).maptalks=t.maptalks||{},t.maptalks,t.turf,t.maptalks)}(this,(function(t,i,s,e){"use strict";function h(t){var i=Object.create(null);return t&&Object.keys(t).forEach((function(s){if("default"!==s){var e=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(i,s,e.get?e:{enumerable:!0,get:function(){return t[s]}})}})),i.default=t,Object.freeze(i)}var n=h(i),r=h(s);let o=0;function u(t,i,s){return t.length!==+t.length&&(t=Object.values(t)),t[c(t.length-1)]}function l(t){const i=++o+"";return t?t+i:i}function c(t,i){return i||(i=t,t=0),t+Math.floor(Math.random()*(i-t+1))}class a{constructor(t,i){this.source=t,this.target=i}get vector(){return this.target.subtract(this.source)}get length(){return this.vector.length}get direction(){return this.vector.direction}get center(){return this.getPoint(.5)}split(t,i){let s,e,h,n,r,o;const u=i?function(){r=[];for(let i=n=t-1;n<=0?i<=0:i>=0;n<=0?i++:i--)r.push(i);return r}.apply(this):function(){o=[];for(let i=0,s=t-1;0<=s?i<=s:i>=s;0<=s?i++:i--)o.push(i);return o}.apply(this),l=[];for(e=0,h=u.length;e<h;e++)s=u[e],l.push(this.subsegment(s/t,(s+1)/t));return l}getPoint(t){return this.source.add(this.vector.mult(t))}subsegment(t,i){const s=this.vector,e=this.source.add(s.mult(t)),h=this.source.add(s.mult(i));return new a(e,h)}}class f{constructor(t,i,s,e){this.A=t,this.B=i,this.O=s,this.Q=e,this.AO=new a(this.A,this.O),this.OQ=new a(this.O,this.Q),this.QB=new a(this.Q,this.B),this.len=null}get length(){let t,i,s,e,h;if(null==this.len)for(s=10,e=null,this.len=0,t=h=0;h<=10;t=++h)i=this.getPoint(t/10),e&&(this.len+=i.subtract(e).length),e=i;return this.len}getPoint(t){const i=this.AO.getPoint(t),s=this.OQ.getPoint(t),e=this.QB.getPoint(t),h=new a(i,s).getPoint(t),n=new a(s,e).getPoint(t);return new a(h,n).getPoint(t)}getDirection(t){const i=this.AO.getPoint(t),s=this.OQ.getPoint(t),e=this.QB.getPoint(t),h=new a(i,s).getPoint(t),n=new a(s,e).getPoint(t);return new a(h,n).direction}}class d{constructor(t,i,s){this.id=l("laneposition"),this.free=!0,this.car=t,this.position=s,this.tmpLane=i}get lane(){return this.tmpLane}set lane(t){this.release(),this.tmpLane=t}get relativePosition(){return this.position/this.lane.length}get nextCarDistance(){let t,i;const s=this.getNext();return s?(i=s.position-s.car.length/2,t=this.position+this.car.length/2,{car:s.car,distance:i-t}):{car:null,distance:1/0}}acquire(){let t;return null!=(null!=(t=this.lane)?t.addCarPosition:void 0)?(this.free=!1,this.lane.addCarPosition(this)):null}release(){let t;return!this.free&&(null!=(t=this.lane)?t.removeCar:void 0)?(this.free=!0,this.lane.removeCar(this)):null}getNext(){return this.lane&&!this.free?this.lane.getNext(this):null}}class g{constructor(t,i,s){this.isChangingLanes=!1,this.car=t,this.current=new d(t,i,s||0),this.current.acquire(),this.next=new d(t),this.temp=new d(t)}get lane(){return this.temp.lane||this.current.lane}get absolutePosition(){return null!==this.temp.lane&&void 0!==this.temp.lane?this.temp.position:this.current.position}get relativePosition(){return this.absolutePosition/this.lane.length}get direction(){return this.lane.getDirection()}get coords(){return this.lane.getPoint(this.relativePosition)}get nextCarDistance(){const t=this.current.nextCarDistance,i=this.next.nextCarDistance;return t.distance<i.distance?t:i}get distanceToStopLine(){return this.canEnterIntersection()?1/0:this.getDistanceToIntersection()}get nextIntersection(){return this.current.lane.road.target}get previousIntersection(){return this.current.lane.road.source}isValidTurn(){const t=this.car.nextLane,i=this.current.lane,s=i.getTurnDirection(t);if(3===s)throw Error("no U-turns are allowed");if(0===s&&!i.isLeftmost)throw Error("no left turns from this lane");if(2===s&&!i.isRightmost)throw Error("no right turns from this lane");return!0}canEnterIntersection(){const t=this.car.nextLane,i=this.current.lane;if(!t)return!0;const s=this.nextIntersection,e=i.getTurnDirection(t),h=i.road.targetSideId;return s.controlSignals.state[h][e]}getDistanceToIntersection(){const t=this.current.lane.length-this.car.length/2-this.current.position;return this.isChangingLanes?1/0:Math.max(t,0)}timeToMakeTurn(t){return void 0===t&&(t=0),this.getDistanceToIntersection()<=t}moveForward(t){let i,s;t=Math.max(t,0),this.current.position+=t,this.next.position+=t,this.temp.position+=t,this.timeToMakeTurn()&&this.canEnterIntersection()&&this.isValidTurn()&&this.t(this.car.popNextLane(),0);const e=this.temp.position/(null!=(i=this.temp.lane)?i.length:void 0),h=2*this.car.length;return this.isChangingLanes&&this.temp.position>h&&!this.current.free&&this.current.release(),this.isChangingLanes&&this.next.free&&this.temp.position+h>(null!=(s=this.temp.lane)?s.length:void 0)&&this.next.acquire(),this.isChangingLanes&&e>=1&&this.i(),!this.current.lane||this.isChangingLanes||this.car.nextLane?null:this.car.pickNextLane()}changeLane(t){if(this.isChangingLanes)throw Error("already changing lane");if(null==t)throw Error("no next lane");if(t===this.lane)throw Error("next lane == current lane");if(this.lane.road!==t.road)throw Error("not neighbouring lanes");const i=this.current.position+3*this.car.length;return this.t(t,i)}h(){const t=this.current.lane.getPoint(this.current.relativePosition),i=this.next.lane.getPoint(this.next.relativePosition),s=i.subtract(t).length,e=this.current.lane.middleLine.vector.normalized.mult(.3*s),h=t.add(e),n=this.next.lane.middleLine.vector.normalized.mult(.3*s),r=i.subtract(n);return new f(t,i,h,r)}o(){return this.h()}t(t,i){if(this.isChangingLanes)throw Error("already changing lane");if(null==t)return 0;this.isChangingLanes=!0,this.next.lane=t,this.next.position=i;const s=this.o();return this.temp.lane=s,this.temp.position=0,this.next.position-=this.temp.lane.length}i(){if(!this.isChangingLanes)throw Error("no lane changing is going on");return this.isChangingLanes=!1,this.current.lane=this.next.lane,this.current.position=this.next.position||0,this.current.acquire(),this.next.lane=null,this.next.position=NaN,this.temp.lane=null,this.temp.position=NaN,this.current.lane}release(){let t,i,s;return null!=(t=this.current)&&t.release(),null!=(i=this.next)&&i.release(),null!=(s=this.temp)?s.release():void 0}}const w=[];class p{constructor(t,i){this.type=c(w.length-1),this.id=l("car"),this.color=(300+240*Math.random()|0)%360,this.preferedLane=null,this.width=2,this.length=2,this.tmpSpeed=0,this.maxSpeed=30,this.s0=2,this.timeHeadway=1.5,this.maxAcceleration=1,this.maxDeceleration=3,this.alive=!0,this.trajectory=new g(this,t,i)}get coords(){return this.trajectory.coords}get speed(){return this.tmpSpeed}set speed(t){t<0&&(t=0),t>this.maxSpeed&&(t=this.maxSpeed),this.tmpSpeed=t}get direction(){return this.trajectory.direction}release(){return this.trajectory.release()}getAcceleration(){let t;const i=this.trajectory.nextCarDistance,s=Math.max(i.distance,0),e=this.maxAcceleration,h=this.maxDeceleration,n=this.speed-(null!=(t=i.car)?t.speed:void 0)||0,r=Math.pow(this.speed/this.maxSpeed,4),o=this.s0,u=this.speed*this.timeHeadway,l=o+u+this.speed*n/(2*Math.sqrt(e*h)),c=Math.pow(l/s,2),a=1+u+Math.pow(this.speed,2)/(2*h),f=1-r-c-Math.pow(a/this.trajectory.distanceToStopLine,2);return this.maxAcceleration*f}move(t){const i=this.getAcceleration();if(this.speed+=i*t,!this.trajectory.isChangingLanes&&this.nextLane){const t=this.trajectory.current.lane,i=t.getTurnDirection(this.nextLane),s=function(){switch(i){case 0:return t.leftmostAdjacent;case 2:return t.rightmostAdjacent;default:return t}}();s!==t&&this.trajectory.changeLane(s)}const s=this.speed*t+.5*i*Math.pow(t,2);return this.trajectory.nextCarDistance.distance<s&&console.log("bad IDM"),this.trajectory.timeToMakeTurn(s)&&null==this.nextLane?(this.alive=!1,this.alive):this.trajectory.moveForward(s)}pickNextRoad(){const t=this.trajectory.nextIntersection,i=this.trajectory.current.lane,s=t.roads.filter((function(t){return t.target!==i.road.source}));if(0===s.length)return null;return u(s)}pickNextLane(){if(this.nextLane)throw Error("next lane is already chosen");this.nextLane=null;const t=this.pickNextRoad();if(!t)return null;const i=this.trajectory.current.lane.road.getTurnDirection(t),s=function(){switch(i){case 0:return t.lanesNumber-1;case 1:return c(0,t.lanesNumber-1);case 2:return 0}return null}();return this.nextLane=t.lanes[s],this.nextLane}popNextLane(){const t=this.nextLane;return this.nextLane=null,this.preferedLane=null,t}}class m{constructor(t){this.flipMultiplier=.4*Math.random()-.2+1,this.time=0,this.stateNum=0,this.lightsFlipInterval=20,this.states=[["L","","L",""],["FR","","FR",""],["","L","","L"],["","FR","","FR"]],this.intersection=t}get flipInterval(){return this.flipMultiplier*this.lightsFlipInterval}get state(){let t=this.states[this.stateNum%this.states.length];this.intersection.roads.length<=2&&(t=["LFR","LFR","LFR","LFR"]);const i=[];for(let s=0,e=t.length;s<e;s++){const e=t[s];i.push(this.decode(e))}return i}decode(t){const i=[0,0,0],s=[].indexOf||function(t){for(let i=0,s=this.length;i<s;i++)if(i in this&&this[i]===t)return i;return-1};return s.call(t,"L")>=0&&(i[0]=1),s.call(t,"F")>=0&&(i[1]=1),s.call(t,"R")>=0&&(i[2]=1),i}flip(){return this.stateNum+=1}onTick(t){return this.time+=t,this.time>this.flipInterval?(this.flip(),this.time-=this.flipInterval):null}}class v{constructor(t,i){this.x=0,this.y=0,t&&(this.x=t),i&&(this.y=i)}get length(){return Math.sqrt(this.x*this.x+this.y*this.y)}get direction(){return Math.atan2(this.y,this.x)}get normalized(){return new v(this.x/this.length,this.y/this.length)}add(t){return new v(this.x+t.x,this.y+t.y)}subtract(t){return new v(this.x-t.x,this.y-t.y)}mult(t){return new v(this.x*t,this.y*t)}divide(t){return new v(this.x/t,this.y/t)}}class b{constructor(t,i,s,e){this.x=0,this.y=0,this.width=0,this.height=0,this.x=t||0,this.y=i||0,this.width=s||0,this.height=e||0}static copy(t){return new b(t.x,t.y,t.width,t.height)}toJSON(){return Object.assign({},this)}area(){return this.width*this.height}left(t){return void 0!==t&&(this.x=t),this.x}right(t){return void 0!==t&&(this.x=t-this.width),this.x+this.width}top(t){return void 0!==t&&(this.y=t),this.y}bottom(t){return void 0!==t&&(this.y=t-this.height),this.y+this.height}center(t){return void 0!==t&&(this.x=t.x-this.width/2,this.y=t.y-this.height/2),new v(this.x+this.width/2,this.y+this.height/2)}containsPoint(t){let i,s;return this.left()<=(i=t.x)&&i<=this.right()&&this.top()<=(s=t.y)&&s<=this.bottom()}containsRect(t){return this.left()<=t.left()&&t.right()<=this.right()&&this.top()<=t.top()&&t.bottom()<=this.bottom()}getVertices(){return[new v(this.left(),this.top()),new v(this.right(),this.top()),new v(this.right(),this.bottom()),new v(this.left(),this.bottom())]}getSide(t){const i=this.getVertices();return new a(i[t],i[(t+1)%4])}getSectorId(t){const i=t.subtract(this.center());if(i.y<=0&&Math.abs(i.x)<=Math.abs(i.y))return 0;if(i.x>=0&&Math.abs(i.x)>=Math.abs(i.y))return 1;if(i.y>=0&&Math.abs(i.x)<=Math.abs(i.y))return 2;if(i.x<=0&&Math.abs(i.x)>=Math.abs(i.y))return 3;throw new Error("algorithm error")}getSector(t){return this.getSide(this.getSectorId(t))}}class M{constructor(t){this.id=l("intersection"),this.rect=t,this.roads=[],this.inRoads=[],this.controlSignals=new m(this)}static copy(t){t.rect=b.copy(t.rect);const i=Object.create(M.prototype);return Object.assign(i,t),i.roads=[],i.inRoads=[],i.controlSignals=new m(i),i}toJSON(){return{id:this.id,rect:this.rect}}update(){let t,i,s,e,h;const n=this.roads;for(i=0,e=n.length;i<e;i++)t=n[i],t.update();const r=this.inRoads,o=[];for(s=0,h=r.length;s<h;s++)t=r[s],o.push(t.update());return o}}class y{constructor(t,i){let s,e,h;if(this.objects={},this.factory=t,i&&i.objects)for(s in h=i.objects,h)e=h[s],this.factory instanceof p||(this.objects[s]=this.factory.copy(e))}get length(){return Object.keys(this.objects).length}toJSON(){return this.objects}get(t){return this.objects[t]}put(t){return this.objects[t.id]=t}pop(t){let i;const s=null!==(i=t.id)?i:t,e=this.objects[s];return e instanceof p&&e.release(),delete this.objects[s],e}all(){return this.objects}clear(){return this.objects={}}}class O{constructor(t,i,s){this.leftmostAdjacent=null,this.rightmostAdjacent=null,this.carsPositions={},this.sourceSegment=t,this.targetSegment=i,this.road=s,this.update()}get sourceSideId(){return this.road.sourceSideId}get targetSideId(){return this.road.targetSideId}get isRightmost(){return this===this.rightmostAdjacent}get isLeftmost(){return this===this.leftmostAdjacent}get leftBorder(){return new a(this.sourceSegment.source,this.targetSegment.target)}get rightBorder(){return new a(this.sourceSegment.target,this.targetSegment.source)}toJSON(){const t=Object.assign({},this);return delete t.carsPositions,t}update(){return this.middleLine=new a(this.sourceSegment.center,this.targetSegment.center),this.length=this.middleLine.length,this.direction=this.middleLine.direction}getTurnDirection(t){return t?this.road.getTurnDirection(t.road):1}getDirection(){return this.direction}getPoint(t){return this.middleLine.getPoint(t)}addCarPosition(t){if(t.id in this.carsPositions)throw Error("car is already here");return this.carsPositions[t.id]=t}removeCar(t){if(!(t.id in this.carsPositions))throw Error("removing unknown car");return delete this.carsPositions[t.id]}getNext(t){if(t.lane!==this)throw Error("car is on other lane");let i=null,s=1/0;const e=this.carsPositions;for(const h in e){const n=e[h],r=n.position-t.position;!n.free&&0<r&&r<s&&(s=r,i=n)}return i}}class L{constructor(t,i,s){this.id=l("road"),this.lanes=[],this.lanesNumber=null,this.source=t,this.target=i,this.gridSize=s||32,this.update()}get length(){return this.targetSide.target.subtract(this.sourceSide.source).length}get leftmostLane(){return this.lanes[this.lanesNumber-1]}get rightmostLane(){return this.lanes[0]}copy(t){const i=Object.create(L.prototype);return Object.assign(i,t),null==i.lanes&&(i.lanes=[]),i}toJSON(){return{id:this.id,source:this.source.id,target:this.target.id}}getTurnDirection(t){if(this.target!==t.source)throw Error("invalid roads");const i=this.targetSideId;return(t.sourceSideId-i-1+8)%4}update(){let t,i,s,e,h,n;if(!this.source||!this.target)throw Error("incomplete road");this.sourceSideId=this.source.rect.getSectorId(this.target.rect.center()),this.sourceSide=this.source.rect.getSide(this.sourceSideId).subsegment(.5,1),this.targetSideId=this.target.rect.getSectorId(this.source.rect.center()),this.targetSide=this.target.rect.getSide(this.targetSideId).subsegment(0,.5),this.lanesNumber=0|Math.min(this.sourceSide.length,this.targetSide.length),this.lanesNumber=Math.max(2,this.lanesNumber/this.gridSize|0);const r=this.sourceSide.split(this.lanesNumber,!0),o=this.targetSide.split(this.lanesNumber);if(null==this.lanes||this.lanes.length<this.lanesNumber)for(null==this.lanes&&(this.lanes=[]),t=s=0,h=this.lanesNumber-1;0<=h?s<=h:s>=h;t=0<=h?++s:--s)null==(i=this.lanes)[t]&&(i[t]=new O(r[t],o[t],this));const u=[];for(t=e=0,n=this.lanesNumber-1;0<=n?e<=n:e>=n;t=0<=n?++e:--e)this.lanes[t].sourceSegment=r[t],this.lanes[t].targetSegment=o[t],this.lanes[t].leftAdjacent=this.lanes[t+1],this.lanes[t].rightAdjacent=this.lanes[t-1],this.lanes[t].leftmostAdjacent=this.lanes[this.lanesNumber-1],this.lanes[t].rightmostAdjacent=this.lanes[0],u.push(this.lanes[t].update());return u}}class x{constructor(t){this.toRemove=[],this.carsList={},this.u=0,this.l=0,this.p=new e.GLTFLayer("traffic"),this.m=5,this.v="stop",this.M=[],this.L={},this.options=t||{},this.carsNumber=this.options.carsNumber||10,this.gridSize=this.options.gridSize||32,this.set()}run(){this.v="running",this.C()}stop(){this.v="stop"}remove(){this.N&&cancelAnimationFrame(this.N),this.p.remove(),delete this.map}setSymbols(t){this.M=t;for(let t=0;t<this.M.length;t++){const i=this.M[t];this.L[i.url]=new e.MultiGLTFMarker([],{symbol:i}).addTo(this.p)}}C(){if("running"!==this.v)return;const t=Date.now();this.u=t;const i=Date.now();let s,e=i-this.l||0;e>100&&(e=100),this.l=i,this.onTick(this.m*e/1e3);let h=this.toRemove.length;for(;h--;)this.j(this.toRemove[h]);this.clearTmpRemove();const n=this.cars.all();for(s in n)this.I(n[s]);this.N=window.requestAnimationFrame(this.C.bind(this))}R(){for(const t in this.L)this.L[t].removeData();for(const t in this.carsList){const i=this.carsList[t],s=i.url;this.L[s].addData(i)}}I(t){const i=t.id.substring(3);if(this.carsList[i]){if(!t)return;const s=t.coords,e=t.direction,h=this.map,r=h.pointAtResToCoordinate(new n.Point(s.x/this.gridSize,s.y/this.gridSize),h.getGLRes()),o=e/Math.PI*180+90;this.carsList[i].coordinates=r,this.carsList[i].rotation=[0,0,o];const u=this.S(i),l=this.carsList[i].url;u>-1?this.L[l].updateData(u,this.carsList[i]):this.L[l].addData(this.carsList[i])}else{const t=this.M[Math.floor(Math.random()*this.M.length)];this.carsList[i]={coordinates:null,direction:null,url:t.url},this.showHideCar(this.carsList[i],"show")}}showHideCar(t,i,s){const e=this;n.animation.Animation.animate({symbol:{transparent:1}},{duration:1e3,easing:"out"},(function(h){if("running"===h.state.playState){let n=0;"show"===i?(n=h.styles.symbol.transparent,t.color=[1,1,1,n]):"hide"===i&&(n=1-h.styles.symbol.transparent,t.color=[1,1,1,n],n<.01&&setTimeout((function(){const t=e.S(s);if(!e.carsList[s])return;const i=e.carsList[s].url;t>-1&&e.L[i].removeData(t),delete e.carsList[s]}),100))}})).play()}S(t){const i=this.carsList[t];if(!i)return-1;const s=i.url;return this.L[s].getAllData().indexOf(this.carsList[t])}j(t){const i=t.substring(3);null!=this.carsList[i]&&this.showHideCar(this.carsList[i],"hide",i)}get instantSpeed(){const t=Object.values(this.cars.all()).map((t=>t.speed));return 0===t.length?0:t.reduce((function(t,i){return t+i}))/t.length}get map(){const t=this.T;return t?t.getMap():null}addTo(t){this.T=t,this.p.addTo(t)}set(t){return null==t&&(t={}),this.intersections=new y(M,t.intersections),this.roads=new y(L,t.roads),this.cars=new y(p,t.cars),this.carsNumber=0}save(){const t=Object.assign({},this);return delete t.cars,window.localStorage.world=JSON.stringify(t)}setCarNumber(t){this.carsNumber=t}getCarNumber(){return this.carsNumber}load(){let t,i,s,e;if(t=window.localStorage.world,t=t&&JSON.parse(t),null==t)return null;this.clear(),this.carsNumber=t.carsNumber||0;const h=t.intersections;for(i in h)s=h[i],this.addIntersection(M.copy(s));const n=t.roads,r=[];for(i in n)e=n[i],e=(new L).copy(e),e.source=this.getIntersection(e.source),e.target=this.getIntersection(e.target),r.push(this.addRoad(e));return r}intersectSegment(t,i){for(let s=0;s<i.length-1;s++){const e=[i[s],i[s+1]],h=r.lineString(e),n=r.lineIntersect(t,h);if(n.features.length)return{intersectIndex:s,coord:n.features[0].geometry.coordinates}}return null}intersection(t,i,s,e,h,n){const o=r.lineString(t);for(let t=i+1;t<e.length;t++){const r=e[t],u=this.intersectSegment(o,r);if(!u)continue;const l={};l[i]={pre:s},l[t]={pre:u.intersectIndex+n[t]};const c={inLines:l,coordinate:this.map.coordinateToPointAtRes({x:u.coord[0],y:u.coord[1]},this.map.getGLRes())};h.push(c)}}generateTraffic(t){if(!this.map)return;const i={};let s=0;for(let e=0;e<t.length;e++)i[e]=s,s+=t[e].length;const e=[];let h=0;for(let s=0;s<t.length;s++){const n=t[s];for(let r=0;r<n.length-1;r++){const o=[n[r],n[r+1]];this.intersection(o,s,h+r,t,e,i)}h+=n.length}const n=[];let r=0;const o=this.map;for(let i=0;i<t.length;i++){const s=t[i];for(let t=0;t<s.length;t++){const e=o.coordinateToPointAtRes({x:s[t][0],y:s[t][1]},o.getGLRes()),h={};0===t?h[i]={pre:null}:(s.length,h[i]={pre:t-1+r});const u={inLines:h,coordinate:e};n.push(u)}r+=s.length}for(let t=0;t<n.length;t++){const i=n[t];this.comparePrePoint(i,t,e)}const u=this.gridSize,l=[];for(let t=0;t<n.length;t++){const i=n[t],s=i.coordinate.x,e=i.coordinate.y,h=new b(s*u-.5,e*u-.5,1,1),r=new M(h);r.connectRoads=i.roads,l.push(r),this.addIntersection(r)}const c=[];for(let t=0;t<e.length;t++){const i=e[t],s=i.coordinate.x,h=i.coordinate.y,n=new b(s*u-.5,h*u-.5,1,1),r=new M(n);r.connectRoads=i.roads,c.push(r),this.addIntersection(r)}for(let t=0;t<l.length;t++){const i=l[t],s=i.connectRoads;if(s)for(let t=0;t<s.length;t++){const e=s[t];if(null!=e.pre){let t=null;const s=e.type;"line"===s?t=l[e.pre]:"line-interact"===s&&(t=c[e.pre]),this.addRoad(new L(i,t)),this.addRoad(new L(t,i))}}}for(let t=0;t<c.length;t++){const i=c[t],s=i.connectRoads;if(s)for(let t=0;t<s.length;t++){const e=s[t];if(null!=e.pre){let t=null;const s=e.type;"line"===s?t=l[e.pre]:"line-interact"===s&&(t=c[e.pre]),this.addRoad(new L(i,t)),this.addRoad(new L(t,i))}}}}comparePrePoint(t,i,s){const e=this.getPre(t);if(e){const{pre:h,lineIndex:n}=e;for(let e=0;e<s.length;e++){const r=s[e];r.inLines[n]&&r.inLines[n].pre===h&&(t.roads=[{pre:e,type:"line-interact"}],r.roads?r.roads.push({pre:i-1,type:"line"}):r.roads=[{pre:i-1,type:"line"}])}t.roads||(t.roads=[{pre:i-1,type:"line"}])}}getPre(t){for(const i in t.inLines)if(null!==t.inLines[i].pre)return{pre:t.inLines[i].pre,lineIndex:i};return null}clear(){return this.set({})}onTick(t){let i,s,e;if(t>1)throw Error("delta > 1");this.refreshCars();const h=this.intersections.all();for(s in h)e=h[s],e.controlSignals.onTick(t);const n=this.cars.all(),r=[];for(s in n)i=n[s],i.move(t),i.alive?r.push(void 0):r.push(this.removeCar(i));return r}refreshCars(){return this.cars.length<this.carsNumber&&this.addRandomCar(),this.cars.length>this.carsNumber?this.removeRandomCar():null}addRoad(t){return this.roads.put(t),t.source.roads.push(t),t.target.inRoads.push(t),t.update()}getRoad(t){return this.roads.get(t)}addCar(t){return this.cars.put(t)}getCar(t){return this.cars.get(t)}removeCar(t){return this.toRemove.push(t.id),this.cars.pop(t)}clearTmpRemove(){this.toRemove=[]}addIntersection(t){return this.intersections.put(t)}getIntersection(t){return this.intersections.get(t)}addRandomCar(){let t;const i=u(this.roads.all());return null!=i&&(t=u(i.lanes),null!=t)?this.addCar(new p(t)):null}removeRandomCar(){const t=u(this.cars.all());return null!=t?this.removeCar(t):null}}"undefined"!=typeof window&&window.maptalks&&(window.maptalks.TrafficScene=x),t.TrafficScene=x,"undefined"!=typeof console&&console.log("@maptalks/traffic v0.98.2")}));
|
|
7
7
|
//# sourceMappingURL=maptalks.traffic.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maptalks/traffic",
|
|
3
|
-
"version": "0.98.
|
|
3
|
+
"version": "0.98.2",
|
|
4
4
|
"description": "a tool to render traffic effect",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"dist/maptalks.traffic.d.ts"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@maptalks/gltf-layer": "0.98.
|
|
23
|
+
"@maptalks/gltf-layer": "0.98.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"karma-expect": "^1.1.3",
|
|
38
38
|
"karma-mocha": "^2.0.1",
|
|
39
39
|
"karma-mocha-reporter": "^2.2.5",
|
|
40
|
-
"maptalks": "^1.0.0-rc.
|
|
40
|
+
"maptalks": "^1.0.0-rc.36",
|
|
41
41
|
"mocha": "^10.3.0",
|
|
42
42
|
"rollup": "^4.17.2",
|
|
43
43
|
"rollup-plugin-dts": "^6.1.0"
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"scripts": {
|
|
47
47
|
"clean": "rimraf dist",
|
|
48
48
|
"dev": "rollup -w -c rollup.config.js",
|
|
49
|
-
"build": "npm run clean && rollup --environment BUILD:production -c rollup.config.js",
|
|
49
|
+
"build": "npm run clean && npm run lint && rollup --environment BUILD:production -c rollup.config.js",
|
|
50
50
|
"build-dev": "rollup -c rollup.config.js",
|
|
51
|
-
"pretest": "npm run
|
|
51
|
+
"pretest": "npm run build",
|
|
52
52
|
"test": "karma start --single-run",
|
|
53
53
|
"tdd": "karma start --no-single-run",
|
|
54
54
|
"preversion": "npm run lint",
|
|
55
55
|
"version": "npm run build",
|
|
56
|
-
"lint": "eslint src/**/*.js"
|
|
56
|
+
"lint": "eslint \"src/**/*.{js,jsx,mjs,ts,tsx}\""
|
|
57
57
|
}
|
|
58
58
|
}
|