terra-draw-route-snap-mode 0.2.0 → 0.2.1
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/dist/routing.d.ts +3 -0
- package/dist/terra-draw-route-snap-mode.cjs +1 -1
- package/dist/terra-draw-route-snap-mode.cjs.map +1 -1
- package/dist/terra-draw-route-snap-mode.d.ts +3 -3
- package/dist/terra-draw-route-snap-mode.modern.js +1 -1
- package/dist/terra-draw-route-snap-mode.modern.js.map +1 -1
- package/dist/terra-draw-route-snap-mode.module.js +1 -1
- package/dist/terra-draw-route-snap-mode.module.js.map +1 -1
- package/dist/terra-draw-route-snap-mode.umd.js +1 -1
- package/dist/terra-draw-route-snap-mode.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/terra-draw-route-snap-mode.ts +9 -8
package/dist/routing.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { FeatureCollection, LineString, Position, Feature, Point } from "geojson
|
|
|
2
2
|
export type RouteFinder = {
|
|
3
3
|
getRoute: (positionA: Feature<Point>, positionB: Feature<Point>) => Feature<LineString> | null;
|
|
4
4
|
setNetwork: (network: FeatureCollection<LineString>) => void;
|
|
5
|
+
expandNetwork: (additionalNetwork: FeatureCollection<LineString>) => void;
|
|
5
6
|
};
|
|
6
7
|
export interface RoutingInterface {
|
|
7
8
|
getRoute: (startCoord: Position, endCoord: Position) => Feature<LineString> | null;
|
|
@@ -43,6 +44,7 @@ export declare class Routing implements RoutingInterface {
|
|
|
43
44
|
* @param network The network to use
|
|
44
45
|
*/
|
|
45
46
|
setNetwork(network: FeatureCollection<LineString>): void;
|
|
47
|
+
expandRouteNetwork(additionalNetwork: FeatureCollection<LineString>): void;
|
|
46
48
|
/**
|
|
47
49
|
* Get the route between two coordinates returned as a GeoJSON LineString
|
|
48
50
|
* @param startCoord start coordinate
|
|
@@ -50,4 +52,5 @@ export declare class Routing implements RoutingInterface {
|
|
|
50
52
|
* @returns The route as a GeoJSON LineString
|
|
51
53
|
*/
|
|
52
54
|
getRoute(startCoord: Position, endCoord: Position): Feature<LineString> | null;
|
|
55
|
+
private clone;
|
|
53
56
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var t=require("terra-draw");function e(){return e=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)({}).hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},e.apply(null,arguments)}function i(t,e){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},i(t,e)}var r=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],s=/*#__PURE__*/function(){function t(t,e,i,s){if(void 0===e&&(e=64),void 0===i&&(i=Float64Array),this.data=void 0,this.ids=void 0,this.coords=void 0,this._pos=void 0,this._finished=void 0,this.numItems=void 0,this.nodeSize=void 0,this.ArrayType=void 0,this.IndexArrayType=void 0,isNaN(t)||t<0)throw new Error("Unexpected numItems value: "+t+".");this.numItems=t,this.nodeSize=Math.min(Math.max(e,2),65535),this.ArrayType=i,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;var n=r.indexOf(this.ArrayType),o=2*t*this.ArrayType.BYTES_PER_ELEMENT,a=t*this.IndexArrayType.BYTES_PER_ELEMENT,h=(8-a%8)%8;if(n<0)throw new Error("Unexpected typed array class: "+i+".");s?(this.data=s,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+h,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+o+a+h),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+h,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+n]),new Uint16Array(this.data,2,1)[0]=this.nodeSize,new Uint32Array(this.data,4,1)[0]=this.numItems)}var e=t.prototype;return e.add=function(t,e){var i=this._pos>>1;return this.ids[i]=i,this.coords[this._pos++]=t,this.coords[this._pos++]=e,i},e.finish=function(){var t=this._pos>>1;if(t!==this.numItems)throw new Error("Added "+t+" items when expected "+this.numItems+".");return n(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this},t}();function n(t,e,i,r,s,a){if(!(s-r<=i)){var h=r+s>>1;o(t,e,h,r,s,a),n(t,e,i,r,h-1,1-a),n(t,e,i,h+1,s,1-a)}}function o(t,e,i,r,s,n){for(;s>r;){if(s-r>600){var h=s-r+1,d=i-r+1,u=Math.log(h),c=.5*Math.exp(2*u/3),p=.5*Math.sqrt(u*c*(h-c)/h)*(d-h/2<0?-1:1);o(t,e,i,Math.max(r,Math.floor(i-d*c/h+p)),Math.min(s,Math.floor(i+(h-d)*c/h+p)),n)}var l=e[2*i+n],f=r,v=s;for(a(t,e,r,i),e[2*s+n]>l&&a(t,e,r,s);f<v;){for(a(t,e,f,v),f++,v--;e[2*f+n]<l;)f++;for(;e[2*v+n]>l;)v--}e[2*r+n]===l?a(t,e,r,v):a(t,e,++v,s),v<=i&&(r=v+1),i<=v&&(s=v-1)}}function a(t,e,i,r){h(t,i,r),h(e,2*i,2*r),h(e,2*i+1,2*r+1)}function h(t,e,i){var r=t[e];t[e]=t[i],t[i]=r}var d=/*#__PURE__*/function(){function t(t,e){if(void 0===t&&(t=[]),void 0===e&&(e=function(t,e){return t<e?-1:t>e?1:0}),this.data=void 0,this.length=void 0,this.compare=void 0,this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(var i=(this.length>>1)-1;i>=0;i--)this._down(i)}var e=t.prototype;return e.push=function(t){this.data.push(t),this._up(this.length++)},e.pop=function(){if(0!==this.length){var t=this.data[0],e=this.data.pop();return this.length--,this.length>0&&(this.data[0]=e,this._down(0)),t}},e.peek=function(){return this.data[0]},e._up=function(t){for(var e=this.data,i=this.compare,r=e[t];t>0;){var s=t-1>>1,n=e[s];if(i(r,n)>=0)break;e[t]=n,t=s}e[t]=r},e._down=function(t){for(var e=this.data,i=this.compare,r=this.length>>1,s=e[t];t<r;){var n=1+(t<<1),o=n+1;if(o<this.length&&i(e[o],e[n])<0&&(n=o),i(e[n],s)>=0)break;e[t]=e[n],t=n}e[t]=s},t}(),u=Math.PI/180;function c(t,e,i,r){var s=r.minLng,n=r.maxLng,o=r.minLat,a=r.maxLat;if(t>=s&&t<=n)return e<o?l((e-o)*u):e>a?l((e-a)*u):0;var h=Math.min(l((t-s)*u),l((t-n)*u)),d=function(t,e){var i=1-2*e;return i<=0?t>0?90:-90:Math.atan(Math.tan(t*u)/i)/u}(e,h);return d>o&&d<a?f(h,i,e,d):Math.min(f(h,i,e,o),f(h,i,e,a))}function p(t,e){return t.dist-e.dist}function l(t){var e=Math.sin(t/2);return e*e}function f(t,e,i,r){return e*Math.cos(r*u)*t+l((i-r)*u)}function v(t,e,i,r,s){return f(l((t-i)*u),s,e,r)}var y=/*#__PURE__*/function(){function t(t){this.useCache=!0,this.indexedNetworkPoints=void 0,this.points=[],this.routeFinder=void 0,this.network=void 0,this.routeCache={},this.useCache=t.useCache||!0,this.network=t.network,this.routeFinder=t.routeFinder,this.initialise()}var e=t.prototype;return e.initialise=function(){var t=this;this.network.features.forEach(function(e){e.geometry.coordinates.forEach(function(e){t.points.push(e)})}),this.indexedNetworkPoints=new s(this.points.length),this.points.forEach(function(e){t.indexedNetworkPoints.add(e[0],e[1])}),this.indexedNetworkPoints.finish(),this.routeCache={}},e.getClosestNetworkCoordinate=function(t){var e=function(t,e,i,r,s){void 0===r&&(r=Infinity),void 0===s&&(s=Infinity);var n=1,o=[];void 0===r&&(r=Infinity),void 0!==s&&(n=l(s/6371));for(var a=new d([],p),h={left:0,right:t.ids.length-1,axis:0,dist:0,minLng:-180,minLat:-90,maxLng:180,maxLat:90},f=Math.cos(i*u);h;){var y=h.right,m=h.left;if(y-m<=t.nodeSize)for(var g=m;g<=y;g++){var I=t.ids[g],x=v(e,i,t.coords[2*g],t.coords[2*g+1],f);a.push({id:I,dist:x})}else{var w=m+y>>1,C=t.coords[2*w],L=t.coords[2*w+1],P=t.ids[w],E=v(e,i,C,L,f);a.push({id:P,dist:E});var A=(h.axis+1)%2,k={left:m,right:w-1,axis:A,minLng:h.minLng,minLat:h.minLat,maxLng:0===h.axis?C:h.maxLng,maxLat:1===h.axis?L:h.maxLat,dist:0},M={left:w+1,right:y,axis:A,minLng:0===h.axis?C:h.minLng,minLat:1===h.axis?L:h.minLat,maxLng:h.maxLng,maxLat:h.maxLat,dist:0};k.dist=c(e,i,f,k),M.dist=c(e,i,f,M),a.push(k),a.push(M)}for(;a.length&&null!=a.peek().id;){var S=a.pop();if(S.dist>n)return o;if(o.push(S.id),o.length===r)return o}h=a.pop()}return o}(this.indexedNetworkPoints,t[0],t[1],1);return this.points[e[0]]||null},e.setRouteFinder=function(t){this.routeFinder=t},e.setNetwork=function(t){this.network=t,this.routeFinder.setNetwork(t),this.initialise()},e.getRoute=function(t,e){if(this.useCache){var i=t+"-"+e;if(this.routeCache[i])return this.routeCache[i]}var r=this.routeFinder.getRoute({type:"Feature",geometry:{type:"Point",coordinates:t},properties:{}},{type:"Feature",geometry:{type:"Point",coordinates:e},properties:{}});return this.useCache?(this.routeCache[t+"-"+e]=r,r):r},t}(),m={cancel:"Escape",finish:"Enter"},g={draw:"crosshair",close:"pointer"},I=/*#__PURE__*/function(r){function s(t){var e;return(e=r.call(this,t,!0)||this).mode="routesnap",e.currentCoordinate=0,e.currentId=void 0,e.keyEvents=m,e.cursors=g,e.maxPoints=1,e.moveLineId=void 0,e.routing=void 0,e.currentPointIds=[],e.routeId=0,e.pixelDistance=function(t,e){var i=e.x-t.x,r=e.y-t.y;return Math.sqrt(r*r+i*i)},e.latestEvent=null,e.updateOptions(t),e}var n,o;o=r,(n=s).prototype=Object.create(o.prototype),n.prototype.constructor=n,i(n,o);var a=s.prototype;return a.updateOptions=function(t){r.prototype.updateOptions.call(this,t),null!=t&&t.routing&&t.routing!==this.routing&&(this.cleanUp(),this.routing=t.routing),void 0!==(null==t?void 0:t.maxPoints)&&t.maxPoints!==this.maxPoints&&t.maxPoints>0&&(this.maxPoints=t.maxPoints),null!=t&&t.cursors&&(this.cursors=e({},this.cursors,t.cursors)),null===(null==t?void 0:t.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=t&&t.keyEvents&&(this.keyEvents=e({},this.keyEvents,t.keyEvents))},a.measure=function(t,e){var i=this.project(e[0],e[1]);return this.pixelDistance({x:i.x,y:i.y},{x:t.containerX,y:t.containerY})},a.close=function(){this.currentId&&(this.currentCoordinate=0,this.currentId=void 0,this.currentPointIds=[],"drawing"===this.state&&this.setStarted())},a.registerBehaviors=function(t){},a.start=function(){this.setStarted(),this.setCursor(this.cursors.draw)},a.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},a.onMouseMove=function(t){var e=this;this.latestEvent=t,requestAnimationFrame(function(){var t=e.latestEvent;t&&(e.processMouseMove(t),e.latestEvent=null)})},a.processMouseMove=function(t){if(this.setCursor(this.cursors.draw),this.moveLineId&&!this.store.has(this.moveLineId)&&(this.moveLineId=void 0),this.currentId&&0!==this.currentCoordinate){var e=this.store.getGeometryCopy(this.currentId);if(e){if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance){if(this.setCursor(this.cursors.close),!this.moveLineId)return;return this.store.has(this.moveLineId)&&this.store.delete([this.moveLineId]),void(this.moveLineId=void 0)}var i=this.store.getGeometryCopy(this.currentId);if(i){var r=this.routing.getClosestNetworkCoordinate([t.lng,t.lat]);if(r){var s=this.routing.getRoute(i.coordinates[i.coordinates.length-1],r);if(s)if(this.moveLineId)this.store.updateGeometry([{id:this.moveLineId,geometry:s.geometry}]);else{var n=this.store.create([{geometry:s.geometry,properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.moveLineId=n[0]}}}}}},a.onClick=function(t){if("right"!==t.button){var i=[t.lng,t.lat];if(this.currentId&&!this.store.has(this.currentId)&&(this.currentId=void 0,this.currentCoordinate=0,this.currentPointIds=[]),this.currentId){var r=this.store.getGeometryCopy(this.currentId);if(this.measure(t,r.coordinates[r.coordinates.length-1])<this.pointerDistance)return 1===this.currentCoordinate&&this.store.delete(this.currentPointIds),void this.close()}else this.routeId++;var s=this.routing.getClosestNetworkCoordinate(i);if(0===this.currentCoordinate){if(s){var n=this.store.create([{geometry:{type:"LineString",coordinates:[s]},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}},{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]),o=n[1];this.currentId=n[0],this.currentPointIds.push(o),this.currentCoordinate++,"started"===this.state&&this.setDrawing()}}else if(1===this.currentCoordinate&&this.currentId&&s){var a=this.store.getGeometryCopy(this.currentId),h=this.routing.getRoute(a.coordinates[0],s);if(h){this.store.updateGeometry([{id:this.currentId,geometry:null==h?void 0:h.geometry}]);var d=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}])[0];this.currentCoordinate=2,this.currentPointIds.push(d)}if(1===this.maxPoints)return void this.close()}else if(this.currentCoordinate>1&&this.currentId&&s&&this.currentCoordinate<=this.maxPoints){var u=this.store.getGeometryCopy(this.currentId),c=this.routing.getRoute(u.coordinates[u.coordinates.length-1],s);if(c){var p=e({},u,{coordinates:[].concat(u.coordinates,c.geometry.coordinates)});this.store.updateGeometry([{id:this.currentId,geometry:p}]);var l=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}])[0];this.maxPoints===this.currentCoordinate?this.close():(this.currentCoordinate++,this.currentPointIds.push(l))}}}},a.onKeyDown=function(){},a.onKeyUp=function(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()},a.onDragStart=function(){},a.onDrag=function(){},a.onDragEnd=function(){},a.cleanUp=function(){try{this.currentId&&this.store.delete([this.currentId].concat(this.currentPointIds))}catch(t){}this.currentId=void 0,this.moveLineId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted()},a.styleFeature=function(e){var i=t.TerraDrawExtend.getDefaultStyling();return"Feature"===e.type&&"LineString"===e.geometry.type&&e.properties.mode===this.mode?(i.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,"#B90E0A",e),i.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,4,e),i.zIndex=10,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.routePointOutlineWidth,1,e),i):i},a.validateFeature=function(t){return r.prototype.validateFeature.call(this,t)},a.afterFeatureAdded=function(t){},s}(t.TerraDrawExtend.TerraDrawBaseDrawMode);exports.Routing=y,exports.TerraDrawRouteSnapMode=I;
|
|
1
|
+
var t=require("terra-draw");function e(){return e=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)({}).hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},e.apply(null,arguments)}function i(t,e){return i=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},i(t,e)}var r=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],s=/*#__PURE__*/function(){function t(t,e,i,s){if(void 0===e&&(e=64),void 0===i&&(i=Float64Array),this.data=void 0,this.ids=void 0,this.coords=void 0,this._pos=void 0,this._finished=void 0,this.numItems=void 0,this.nodeSize=void 0,this.ArrayType=void 0,this.IndexArrayType=void 0,isNaN(t)||t<0)throw new Error("Unexpected numItems value: "+t+".");this.numItems=t,this.nodeSize=Math.min(Math.max(e,2),65535),this.ArrayType=i,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;var n=r.indexOf(this.ArrayType),o=2*t*this.ArrayType.BYTES_PER_ELEMENT,a=t*this.IndexArrayType.BYTES_PER_ELEMENT,h=(8-a%8)%8;if(n<0)throw new Error("Unexpected typed array class: "+i+".");s?(this.data=s,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+h,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+o+a+h),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+h,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+n]),new Uint16Array(this.data,2,1)[0]=this.nodeSize,new Uint32Array(this.data,4,1)[0]=this.numItems)}var e=t.prototype;return e.add=function(t,e){var i=this._pos>>1;return this.ids[i]=i,this.coords[this._pos++]=t,this.coords[this._pos++]=e,i},e.finish=function(){var t=this._pos>>1;if(t!==this.numItems)throw new Error("Added "+t+" items when expected "+this.numItems+".");return n(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this},t}();function n(t,e,i,r,s,a){if(!(s-r<=i)){var h=r+s>>1;o(t,e,h,r,s,a),n(t,e,i,r,h-1,1-a),n(t,e,i,h+1,s,1-a)}}function o(t,e,i,r,s,n){for(;s>r;){if(s-r>600){var h=s-r+1,u=i-r+1,d=Math.log(h),c=.5*Math.exp(2*d/3),l=.5*Math.sqrt(d*c*(h-c)/h)*(u-h/2<0?-1:1);o(t,e,i,Math.max(r,Math.floor(i-u*c/h+l)),Math.min(s,Math.floor(i+(h-u)*c/h+l)),n)}var p=e[2*i+n],f=r,v=s;for(a(t,e,r,i),e[2*s+n]>p&&a(t,e,r,s);f<v;){for(a(t,e,f,v),f++,v--;e[2*f+n]<p;)f++;for(;e[2*v+n]>p;)v--}e[2*r+n]===p?a(t,e,r,v):a(t,e,++v,s),v<=i&&(r=v+1),i<=v&&(s=v-1)}}function a(t,e,i,r){h(t,i,r),h(e,2*i,2*r),h(e,2*i+1,2*r+1)}function h(t,e,i){var r=t[e];t[e]=t[i],t[i]=r}var u=/*#__PURE__*/function(){function t(t,e){if(void 0===t&&(t=[]),void 0===e&&(e=function(t,e){return t<e?-1:t>e?1:0}),this.data=void 0,this.length=void 0,this.compare=void 0,this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(var i=(this.length>>1)-1;i>=0;i--)this._down(i)}var e=t.prototype;return e.push=function(t){this.data.push(t),this._up(this.length++)},e.pop=function(){if(0!==this.length){var t=this.data[0],e=this.data.pop();return this.length--,this.length>0&&(this.data[0]=e,this._down(0)),t}},e.peek=function(){return this.data[0]},e._up=function(t){for(var e=this.data,i=this.compare,r=e[t];t>0;){var s=t-1>>1,n=e[s];if(i(r,n)>=0)break;e[t]=n,t=s}e[t]=r},e._down=function(t){for(var e=this.data,i=this.compare,r=this.length>>1,s=e[t];t<r;){var n=1+(t<<1),o=n+1;if(o<this.length&&i(e[o],e[n])<0&&(n=o),i(e[n],s)>=0)break;e[t]=e[n],t=n}e[t]=s},t}(),d=Math.PI/180;function c(t,e,i,r){var s=r.minLng,n=r.maxLng,o=r.minLat,a=r.maxLat;if(t>=s&&t<=n)return e<o?p((e-o)*d):e>a?p((e-a)*d):0;var h=Math.min(p((t-s)*d),p((t-n)*d)),u=function(t,e){var i=1-2*e;return i<=0?t>0?90:-90:Math.atan(Math.tan(t*d)/i)/d}(e,h);return u>o&&u<a?f(h,i,e,u):Math.min(f(h,i,e,o),f(h,i,e,a))}function l(t,e){return t.dist-e.dist}function p(t){var e=Math.sin(t/2);return e*e}function f(t,e,i,r){return e*Math.cos(r*d)*t+p((i-r)*d)}function v(t,e,i,r,s){return f(p((t-i)*d),s,e,r)}var y=/*#__PURE__*/function(){function t(t){this.useCache=!0,this.indexedNetworkPoints=void 0,this.points=[],this.routeFinder=void 0,this.network=void 0,this.routeCache={},this.useCache=void 0===t.useCache||t.useCache,this.network=this.clone(t.network),this.routeFinder=t.routeFinder,this.initialise()}var e=t.prototype;return e.initialise=function(){var t=this;this.network.features.forEach(function(e){e.geometry.coordinates.forEach(function(e){t.points.push(e)})}),this.indexedNetworkPoints=new s(this.points.length),this.points.forEach(function(e){t.indexedNetworkPoints.add(e[0],e[1])}),this.indexedNetworkPoints.finish(),this.routeCache={}},e.getClosestNetworkCoordinate=function(t){var e=function(t,e,i,r,s){void 0===r&&(r=Infinity),void 0===s&&(s=Infinity);var n=1,o=[];void 0===r&&(r=Infinity),void 0!==s&&(n=p(s/6371));for(var a=new u([],l),h={left:0,right:t.ids.length-1,axis:0,dist:0,minLng:-180,minLat:-90,maxLng:180,maxLat:90},f=Math.cos(i*d);h;){var y=h.right,m=h.left;if(y-m<=t.nodeSize)for(var g=m;g<=y;g++){var I=t.ids[g],x=v(e,i,t.coords[2*g],t.coords[2*g+1],f);a.push({id:I,dist:x})}else{var w=m+y>>1,C=t.coords[2*w],L=t.coords[2*w+1],P=t.ids[w],E=v(e,i,C,L,f);a.push({id:P,dist:E});var k=(h.axis+1)%2,A={left:m,right:w-1,axis:k,minLng:h.minLng,minLat:h.minLat,maxLng:0===h.axis?C:h.maxLng,maxLat:1===h.axis?L:h.maxLat,dist:0},M={left:w+1,right:y,axis:k,minLng:0===h.axis?C:h.minLng,minLat:1===h.axis?L:h.minLat,maxLng:h.maxLng,maxLat:h.maxLat,dist:0};A.dist=c(e,i,f,A),M.dist=c(e,i,f,M),a.push(A),a.push(M)}for(;a.length&&null!=a.peek().id;){var S=a.pop();if(S.dist>n)return o;if(o.push(S.id),o.length===r)return o}h=a.pop()}return o}(this.indexedNetworkPoints,t[0],t[1],1);return this.points[e[0]]||null},e.setRouteFinder=function(t){this.routeFinder=t},e.setNetwork=function(t){this.network=this.clone(t),this.routeFinder.setNetwork(t),this.initialise()},e.expandRouteNetwork=function(t){var e=this.clone(t);this.routeFinder.expandNetwork(e);var i={type:"FeatureCollection",features:[].concat(e.features,this.network.features)};this.network=i,this.initialise()},e.getRoute=function(t,e){if(this.useCache){var i=t+"-"+e;if(this.routeCache[i])return this.routeCache[i]}var r=this.routeFinder.getRoute({type:"Feature",geometry:{type:"Point",coordinates:t},properties:{}},{type:"Feature",geometry:{type:"Point",coordinates:e},properties:{}});return this.useCache?(this.routeCache[t+"-"+e]=r,r):r},e.clone=function(t){return JSON.parse(JSON.stringify(t))},t}(),m={cancel:"Escape",finish:"Enter"},g={draw:"crosshair",close:"pointer"},I=/*#__PURE__*/function(r){function s(t){var e;return(e=r.call(this,t,!0)||this).mode="routesnap",e.currentCoordinate=0,e.currentId=void 0,e.keyEvents=m,e.cursors=g,e.maxPoints=1,e.moveLineId=void 0,e.routing=void 0,e.currentPointIds=[],e.routeId=0,e.pixelDistance=function(t,e){var i=e.x-t.x,r=e.y-t.y;return Math.sqrt(r*r+i*i)},e.latestEvent=null,e.updateOptions(t),e}var n,o;o=r,(n=s).prototype=Object.create(o.prototype),n.prototype.constructor=n,i(n,o);var a=s.prototype;return a.updateOptions=function(t){r.prototype.updateOptions.call(this,t),null!=t&&t.routing&&t.routing!==this.routing&&(this.cleanUp(),this.routing=t.routing),void 0!==(null==t?void 0:t.maxPoints)&&t.maxPoints!==this.maxPoints&&t.maxPoints>0&&(this.maxPoints=t.maxPoints),null!=t&&t.cursors&&(this.cursors=e({},this.cursors,t.cursors)),null===(null==t?void 0:t.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=t&&t.keyEvents&&(this.keyEvents=e({},this.keyEvents,t.keyEvents))},a.measure=function(t,e){var i=this.project(e[0],e[1]);return this.pixelDistance({x:i.x,y:i.y},{x:t.containerX,y:t.containerY})},a.close=function(){this.currentId&&(this.currentCoordinate=0,this.currentId=void 0,this.currentPointIds=[],"drawing"===this.state&&this.setStarted())},a.registerBehaviors=function(t){},a.start=function(){this.setStarted(),this.setCursor(this.cursors.draw)},a.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},a.onMouseMove=function(t){var e=this;this.latestEvent=t,requestAnimationFrame(function(){var t=e.latestEvent;t&&(e.processMouseMove(t),e.latestEvent=null)})},a.processMouseMove=function(t){if(this.setCursor(this.cursors.draw),this.moveLineId&&!this.store.has(this.moveLineId)&&(this.moveLineId=void 0),this.currentId&&0!==this.currentCoordinate){var e=this.store.getGeometryCopy(this.currentId);if(e){if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance){if(this.setCursor(this.cursors.close),!this.moveLineId)return;return this.store.has(this.moveLineId)&&this.store.delete([this.moveLineId]),void(this.moveLineId=void 0)}var i=this.store.getGeometryCopy(this.currentId);if(i){var r=this.routing.getClosestNetworkCoordinate([t.lng,t.lat]);if(r){var s=this.routing.getRoute(i.coordinates[i.coordinates.length-1],r);if(s)if(this.moveLineId)this.store.updateGeometry([{id:this.moveLineId,geometry:s.geometry}]);else{var n=this.store.create([{geometry:s.geometry,properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.moveLineId=n[0]}}}}}},a.onClick=function(t){if("right"!==t.button){var i=[t.lng,t.lat];if(this.currentId&&!this.store.has(this.currentId)&&(this.currentId=void 0,this.currentCoordinate=0,this.currentPointIds=[]),this.currentId){var r=this.store.getGeometryCopy(this.currentId);if(this.measure(t,r.coordinates[r.coordinates.length-1])<this.pointerDistance)return 1===this.currentCoordinate&&this.store.delete(this.currentPointIds),void this.close()}else this.routeId++;var s=this.routing.getClosestNetworkCoordinate(i);if(0===this.currentCoordinate){if(s){var n=this.store.create([{geometry:{type:"LineString",coordinates:[s]},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}},{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]),o=n[1];this.currentId=n[0],this.currentPointIds.push(o),this.currentCoordinate++,"started"===this.state&&this.setDrawing()}}else if(1===this.currentCoordinate&&this.currentId&&s){var a=this.store.getGeometryCopy(this.currentId),h=this.routing.getRoute(a.coordinates[0],s);if(h){this.store.updateGeometry([{id:this.currentId,geometry:null==h?void 0:h.geometry}]);var u=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}])[0];this.currentCoordinate=2,this.currentPointIds.push(u)}if(1===this.maxPoints)return void this.close()}else if(this.currentCoordinate>1&&this.currentId&&s&&this.currentCoordinate<=this.maxPoints){var d=this.store.getGeometryCopy(this.currentId),c=this.routing.getRoute(d.coordinates[d.coordinates.length-1],s);if(c){var l=e({},d,{coordinates:[].concat(d.coordinates,c.geometry.coordinates)});this.store.updateGeometry([{id:this.currentId,geometry:l}]);var p=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}])[0];this.maxPoints===this.currentCoordinate?this.close():(this.currentCoordinate++,this.currentPointIds.push(p))}}}},a.onKeyDown=function(){},a.onKeyUp=function(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()},a.onDragStart=function(){},a.onDrag=function(){},a.onDragEnd=function(){},a.cleanUp=function(){var t=this;if(this.store){var e=[this.currentId,this.moveLineId].concat(this.currentPointIds).filter(function(e){return e&&t.store.has(e)});this.store.delete(e),this.currentId=void 0,this.moveLineId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted()}},a.styleFeature=function(e){var i=t.TerraDrawExtend.getDefaultStyling();return"Feature"===e.type&&"LineString"===e.geometry.type&&e.properties.mode===this.mode?(i.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,"#B90E0A",e),i.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,4,e),i.zIndex=10,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.routePointOutlineWidth,1,e),i):i},a.validateFeature=function(t){return r.prototype.validateFeature.call(this,t)},a.afterFeatureAdded=function(t){},s}(t.TerraDrawExtend.TerraDrawBaseDrawMode);exports.Routing=y,exports.TerraDrawRouteSnapMode=I;
|
|
2
2
|
//# sourceMappingURL=terra-draw-route-snap-mode.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terra-draw-route-snap-mode.cjs","sources":["../src/kdbush/kdbush.ts","../src/kdbush/tinyqueue.ts","../src/kdbush/geokdbush.ts","../src/routing.ts","../src/terra-draw-route-snap-mode.ts"],"sourcesContent":["// Adapted from https://github.com/mourner/kdbush\n\n// ISC License\n\n// Copyright (c) 2018, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nconst ARRAY_TYPES = [\n Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,\n Int32Array, Uint32Array, Float32Array, Float64Array\n];\n\nconst VERSION = 1;\nconst HEADER_SIZE = 8;\n\nexport class KDBush {\n private data: ArrayBuffer;\n public ids: Uint16Array | Uint32Array;\n public coords: InstanceType<TypedArrayConstructor>;\n private _pos: number;\n private _finished: boolean;\n private numItems: number;\n public nodeSize: number;\n private ArrayType: TypedArrayConstructor;\n private IndexArrayType: typeof Uint16Array | typeof Uint32Array;\n\n constructor(\n numItems: number,\n nodeSize: number = 64,\n ArrayType: TypedArrayConstructor = Float64Array,\n data?: ArrayBuffer\n ) {\n if (isNaN(numItems) || numItems < 0) {\n throw new Error(`Unexpected numItems value: ${numItems}.`);\n }\n\n this.numItems = numItems;\n this.nodeSize = Math.min(Math.max(nodeSize, 2), 65535);\n this.ArrayType = ArrayType;\n this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);\n const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT;\n const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT;\n const padCoords = (8 - idsByteSize % 8) % 8;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n if (data) {\n this.data = data;\n this.ids = new (this.IndexArrayType as any)(this.data, HEADER_SIZE, numItems);\n this.coords = new (this.ArrayType as any)(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = numItems * 2;\n this._finished = true;\n } else {\n this.data = new ArrayBuffer(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords);\n this.ids = new (this.IndexArrayType as any)(this.data, HEADER_SIZE, numItems);\n this.coords = new (this.ArrayType as any)(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = 0;\n this._finished = false;\n\n new Uint8Array(this.data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(this.data, 2, 1)[0] = this.nodeSize;\n new Uint32Array(this.data, 4, 1)[0] = this.numItems;\n }\n }\n\n add(x: number, y: number): number {\n const index = this._pos >> 1;\n this.ids[index] = index;\n this.coords[this._pos++] = x;\n this.coords[this._pos++] = y;\n return index;\n }\n\n finish(): this {\n const numAdded = this._pos >> 1;\n if (numAdded !== this.numItems) {\n throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`);\n }\n sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0);\n this._finished = true;\n return this;\n }\n}\n\ntype TypedArrayConstructor =\n Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor |\n Int16ArrayConstructor | Uint16ArrayConstructor |\n Int32ArrayConstructor | Uint32ArrayConstructor |\n Float32ArrayConstructor | Float64ArrayConstructor;\n\nfunction sort(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n nodeSize: number,\n left: number,\n right: number,\n axis: number\n): void {\n if (right - left <= nodeSize) return;\n const m = (left + right) >> 1;\n select(ids, coords, m, left, right, axis);\n sort(ids, coords, nodeSize, left, m - 1, 1 - axis);\n sort(ids, coords, nodeSize, m + 1, right, 1 - axis);\n}\n\nfunction select(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n k: number,\n left: number,\n right: number,\n axis: number\n): void {\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp(2 * z / 3);\n const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n select(ids, coords, k, newLeft, newRight, axis);\n }\n\n const t = coords[2 * k + axis];\n let i = left;\n let j = right;\n\n swapItem(ids, coords, left, k);\n if (coords[2 * right + axis] > t) {\n swapItem(ids, coords, left, right);\n }\n\n while (i < j) {\n swapItem(ids, coords, i, j);\n i++;\n j--;\n while (coords[2 * i + axis] < t) i++;\n while (coords[2 * j + axis] > t) j--;\n }\n\n if (coords[2 * left + axis] === t) {\n swapItem(ids, coords, left, j);\n } else {\n j++;\n swapItem(ids, coords, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swapItem(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n i: number,\n j: number\n): void {\n swap(ids, i, j);\n swap(coords, 2 * i, 2 * j);\n swap(coords, 2 * i + 1, 2 * j + 1);\n}\n\nfunction swap<T extends Uint16Array | Uint32Array | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint8Array | Uint8ClampedArray>(\n arr: T,\n i: number,\n j: number\n): void {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n","// Adapted from https://github.com/mourner/kdbush\n\n// ISC License\n\n// Copyright (c) 2017, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nexport default class TinyQueue<T> {\n\n private data: T[];\n public length: number;\n private compare: (a: T, b: T) => number;\n\n constructor(\n data: T[] = [],\n compare: (a: T, b: T) => number = (a, b) =>\n a < b ? -1 : a > b ? 1 : 0\n ) {\n this.data = data;\n this.length = this.data.length;\n this.compare = compare;\n\n if (this.length > 0) {\n for (let i = (this.length >> 1) - 1; i >= 0; i--) {\n this._down(i);\n }\n }\n }\n\n push(item: T): void {\n this.data.push(item);\n this._up(this.length++);\n }\n\n pop(): T | undefined {\n if (this.length === 0) {\n return undefined;\n }\n\n const top = this.data[0];\n const bottom = this.data.pop() as T;\n\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = bottom;\n this._down(0);\n }\n\n return top;\n }\n\n peek(): T | undefined {\n return this.data[0];\n }\n\n private _up(pos: number): void {\n const { data, compare } = this;\n const item = data[pos];\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const current = data[parent];\n if (compare(item, current) >= 0) {\n break;\n }\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n }\n\n private _down(pos: number): void {\n const { data, compare } = this;\n const halfLength = this.length >> 1;\n const item = data[pos];\n\n while (pos < halfLength) {\n let bestChild = (pos << 1) + 1;\n const right = bestChild + 1;\n\n if (right < this.length && compare(data[right], data[bestChild]) < 0) {\n bestChild = right;\n }\n\n if (compare(data[bestChild], item) >= 0) {\n break;\n }\n\n data[pos] = data[bestChild];\n pos = bestChild;\n }\n\n data[pos] = item;\n }\n}\n","// Adapted from https://github.com/mourner/geokdbush\n\n// ISC License\n\n// Copyright (c) 2017, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nimport { KDBush } from './kdbush';\nimport TinyQueue from './tinyqueue';\n\nconst earthRadius = 6371;\nconst rad = Math.PI / 180;\n\n\nexport function around(index: KDBush, lng: number, lat: number, maxResults = Infinity, maxDistance = Infinity) {\n let maxHaverSinDist = 1;\n const result = [];\n\n if (maxResults === undefined) maxResults = Infinity;\n if (maxDistance !== undefined) maxHaverSinDist = haverSin(maxDistance / earthRadius);\n\n // a distance-sorted priority queue that will contain both points and kd-tree nodes\n const q = new TinyQueue([], compareDist);\n\n // an object that represents the top kd-tree node (the whole Earth)\n let node = {\n left: 0, // left index in the kd-tree array\n right: index.ids.length - 1, // right index\n axis: 0, // 0 for longitude axis and 1 for latitude axis\n dist: 0, // will hold the lower bound of children's distances to the query point\n minLng: -180, // bounding box of the node\n minLat: -90,\n maxLng: 180,\n maxLat: 90\n };\n\n const cosLat = Math.cos(lat * rad);\n\n while (node) {\n const right = node.right;\n const left = node.left;\n\n if (right - left <= index.nodeSize) { // leaf node\n\n // add all points of the leaf node to the queue\n for (let i = left; i <= right; i++) {\n const id = index.ids[i];\n\n const dist = haverSinDist(lng, lat, index.coords[2 * i], index.coords[2 * i + 1], cosLat);\n q.push({ id, dist });\n }\n\n } else { // not a leaf node (has child nodes)\n\n const m = (left + right) >> 1; // middle index\n const midLng = index.coords[2 * m];\n const midLat = index.coords[2 * m + 1];\n\n // add middle point to the queue\n const id = index.ids[m];\n const dist = haverSinDist(lng, lat, midLng, midLat, cosLat);\n q.push({ id, dist });\n\n\n const nextAxis = (node.axis + 1) % 2;\n\n // first half of the node\n const leftNode = {\n left,\n right: m - 1,\n axis: nextAxis,\n minLng: node.minLng,\n minLat: node.minLat,\n maxLng: node.axis === 0 ? midLng : node.maxLng,\n maxLat: node.axis === 1 ? midLat : node.maxLat,\n dist: 0\n };\n // second half of the node\n const rightNode = {\n left: m + 1,\n right,\n axis: nextAxis,\n minLng: node.axis === 0 ? midLng : node.minLng,\n minLat: node.axis === 1 ? midLat : node.minLat,\n maxLng: node.maxLng,\n maxLat: node.maxLat,\n dist: 0\n };\n\n leftNode.dist = boxDist(lng, lat, cosLat, leftNode);\n rightNode.dist = boxDist(lng, lat, cosLat, rightNode);\n\n // add child nodes to the queue\n q.push(leftNode);\n q.push(rightNode);\n }\n\n // fetch closest points from the queue; they're guaranteed to be closer\n // than all remaining points (both individual and those in kd-tree nodes),\n // since each node's distance is a lower bound of distances to its children\n while (q.length && q.peek().id != null) {\n const candidate = q.pop()!;\n if (candidate.dist > maxHaverSinDist) return result;\n result.push(candidate.id);\n if (result.length === maxResults) return result;\n }\n\n // the next closest kd-tree node\n node = q.pop();\n }\n\n return result;\n}\n\n// lower bound for distance from a location to points inside a bounding box\nfunction boxDist(lng: number, lat: number, cosLat: number, node: any) {\n const minLng = node.minLng;\n const maxLng = node.maxLng;\n const minLat = node.minLat;\n const maxLat = node.maxLat;\n\n // query point is between minimum and maximum longitudes\n if (lng >= minLng && lng <= maxLng) {\n if (lat < minLat) return haverSin((lat - minLat) * rad);\n if (lat > maxLat) return haverSin((lat - maxLat) * rad);\n return 0;\n }\n\n // query point is west or east of the bounding box;\n // calculate the extremum for great circle distance from query point to the closest longitude;\n const haverSinDLng = Math.min(haverSin((lng - minLng) * rad), haverSin((lng - maxLng) * rad));\n const extremumLat = vertexLat(lat, haverSinDLng);\n\n // if extremum is inside the box, return the distance to it\n if (extremumLat > minLat && extremumLat < maxLat) {\n return haverSinDistPartial(haverSinDLng, cosLat, lat, extremumLat);\n }\n // otherwise return the distan e to one of the bbox corners (whichever is closest)\n return Math.min(\n haverSinDistPartial(haverSinDLng, cosLat, lat, minLat),\n haverSinDistPartial(haverSinDLng, cosLat, lat, maxLat)\n );\n}\n\nfunction compareDist(a: any, b: any) {\n return a.dist - b.dist;\n}\n\nfunction haverSin(theta: number) {\n const s = Math.sin(theta / 2);\n return s * s;\n}\n\nfunction haverSinDistPartial(haverSinDLng: number, cosLat1: number, lat1: number, lat2: number) {\n return cosLat1 * Math.cos(lat2 * rad) * haverSinDLng + haverSin((lat1 - lat2) * rad);\n}\n\nfunction haverSinDist(lng1: number, lat1: number, lng2: number, lat2: number, cosLat1: number) {\n const haverSinDLng = haverSin((lng1 - lng2) * rad);\n return haverSinDistPartial(haverSinDLng, cosLat1, lat1, lat2);\n}\n\nexport function distance(lng1: number, lat1: number, lng2: number, lat2: number) {\n const h = haverSinDist(lng1, lat1, lng2, lat2, Math.cos(lat1 * rad));\n return 2 * earthRadius * Math.asin(Math.sqrt(h));\n}\n\nfunction vertexLat(lat: number, haverSinDLng: number) {\n const cosDLng = 1 - 2 * haverSinDLng;\n if (cosDLng <= 0) return lat > 0 ? 90 : -90;\n return Math.atan(Math.tan(lat * rad) / cosDLng) / rad;\n}","import { KDBush } from \"./kdbush/kdbush\";\nimport { around } from \"./kdbush/geokdbush\";\nimport {\n FeatureCollection,\n LineString,\n Position,\n Feature,\n Point,\n} from \"geojson\";\n\nexport type RouteFinder = {\n getRoute: (positionA: Feature<Point>, positionB: Feature<Point>) => Feature<LineString> | null\n setNetwork: (network: FeatureCollection<LineString>) => void\n}\n\nexport interface RoutingInterface {\n getRoute: (\n startCoord: Position,\n endCoord: Position\n ) => Feature<LineString> | null;\n getClosestNetworkCoordinate: (coordinate: Position) => Position | null;\n setRouteFinder: (routeFinder: RouteFinder) => void;\n setNetwork: (network: FeatureCollection<LineString>) => void\n}\n\n/**\n * Routing class for finding routes on a network of LineStrings.\n * The LineString network must have coordinates that are shared between\n * the LineStrings in order to find a route.\n */\nexport class Routing implements RoutingInterface {\n constructor(options: {\n network: FeatureCollection<LineString>, useCache?: boolean,\n routeFinder: RouteFinder\n }) {\n this.useCache = options.useCache || true;\n this.network = options.network;\n this.routeFinder = options.routeFinder;\n\n this.initialise();\n }\n\n private useCache: boolean = true;\n private indexedNetworkPoints!: KDBush;\n private points: Position[] = []\n private routeFinder: RouteFinder;\n private network: FeatureCollection<LineString>;\n private routeCache: Record<string, Feature<LineString> | null> = {};\n\n // Initialise the routing instance setting internal data structures\n private initialise() {\n this.network.features.forEach((feature) => {\n feature.geometry.coordinates.forEach((coordinate) => {\n this.points.push(coordinate);\n });\n });\n\n this.indexedNetworkPoints = new KDBush(this.points.length);\n\n this.points.forEach(coordinate => {\n this.indexedNetworkPoints.add(coordinate[0], coordinate[1]);\n })\n\n this.indexedNetworkPoints.finish();\n\n this.routeCache = {};\n }\n\n /**\n * Return the closest network coordinate to the input coordinate\n * @param inputCoordinate The coordinate to find the closest network coordinate to\n * @returns a coordinate on the network or null if no coordinate is found\n */\n public getClosestNetworkCoordinate(inputCoordinate: Position) {\n const aroundInput: number[] = around(\n this.indexedNetworkPoints,\n inputCoordinate[0],\n inputCoordinate[1],\n 1\n );\n\n const nearest = this.points[aroundInput[0]]\n return nearest ? nearest : null;\n }\n\n /**\n * Set the route finder for the routing instance\n * @param routeFinder The route finder to use\n */\n public setRouteFinder(routeFinder: RouteFinder) {\n this.routeFinder = routeFinder;\n }\n\n /**\n * Set the network for the routing instance\n * @param network The network to use\n */\n public setNetwork(network: FeatureCollection<LineString>) {\n this.network = network;\n\n // Ensure the network is updated correctly for the router finder\n this.routeFinder.setNetwork(network);\n\n // Re-initialize all internal data structures for this class\n this.initialise();\n }\n\n /**\n * Get the route between two coordinates returned as a GeoJSON LineString\n * @param startCoord start coordinate\n * @param endCoord end coordinate\n * @returns The route as a GeoJSON LineString\n */\n public getRoute(startCoord: Position, endCoord: Position): Feature<LineString> | null {\n\n // Check if caching is enabled, and if the coordinates are already in the cache \n if (this.useCache) {\n const routeKey = `${startCoord}-${endCoord}`;\n\n if (this.routeCache[routeKey]) {\n return this.routeCache[routeKey];\n }\n }\n\n const start = {\n type: \"Feature\",\n geometry: {\n type: \"Point\",\n coordinates: startCoord,\n },\n properties: {},\n } as Feature<Point>;\n\n const end = {\n type: \"Feature\",\n geometry: {\n type: \"Point\",\n coordinates: endCoord,\n },\n properties: {},\n } as Feature<Point>;\n\n const route = this.routeFinder.getRoute(start, end);\n\n // If caching is enabled, store the route in the cache\n if (this.useCache) {\n const routeKey = `${startCoord}-${endCoord}`\n this.routeCache[routeKey] = route;\n return route;\n }\n\n return route;\n\n }\n}\n","import {\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n TerraDrawMouseEvent,\n BehaviorConfig,\n GeoJSONStoreFeatures,\n TerraDrawExtend\n} from \"terra-draw\";\nimport { LineString, Position } from \"geojson\";\nimport { Validation } from \"terra-draw/dist/common\";\nimport { RoutingInterface } from \"./routing\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"] | null;\n finish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ninterface Cursors {\n draw?: TerraDrawExtend.Cursor;\n close?: TerraDrawExtend.Cursor;\n}\n\nconst defaultCursors = {\n draw: \"crosshair\",\n close: \"pointer\"\n} as Required<Cursors>;\n\ntype RouteStyling = {\n lineStringWidth: TerraDrawExtend.NumericStyling;\n lineStringColor: TerraDrawExtend.HexColorStyling\n routePointColor: TerraDrawExtend.HexColorStyling;\n routePointWidth: TerraDrawExtend.NumericStyling;\n routePointOutlineColor: TerraDrawExtend.HexColorStyling;\n routePointOutlineWidth: TerraDrawExtend.NumericStyling;\n};\n\ninterface TerraDrawPolygonModeOptions<T extends TerraDrawExtend.CustomStyling>\n extends TerraDrawExtend.BaseModeOptions<T> {\n routing: RoutingInterface;\n pointerDistance?: number;\n keyEvents?: TerraDrawLineStringModeKeyEvents | null;\n maxPoints?: number;\n cursors?: Partial<Cursors>;\n}\n\nconst { TerraDrawBaseDrawMode } = TerraDrawExtend;\n\nexport class TerraDrawRouteSnapMode extends TerraDrawBaseDrawMode<RouteStyling> {\n mode = \"routesnap\" as const;\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private keyEvents: TerraDrawLineStringModeKeyEvents = defaultKeyEvents;\n private cursors: Required<Cursors> = defaultCursors;\n\n private maxPoints: number = 1\n private moveLineId: string | undefined;\n private routing!: RoutingInterface;\n private currentPointIds: string[] = [];\n private routeId = 0;\n\n constructor(options?: TerraDrawPolygonModeOptions<RouteStyling>) {\n super(options, true);\n this.updateOptions(options);\n }\n\n override updateOptions(options?: Partial<TerraDrawPolygonModeOptions<RouteStyling>>) {\n super.updateOptions(options);\n\n if (options?.routing && options.routing !== this.routing) {\n // We can't guarantee the rout created so far is valid with the new routing \n // So we need to clean up the current state\n this.cleanUp();\n this.routing = options.routing;\n }\n\n if (options?.maxPoints !== undefined && options.maxPoints !== this.maxPoints && options.maxPoints > 0) {\n this.maxPoints = options.maxPoints;\n }\n\n if (options?.cursors) {\n this.cursors = { ...this.cursors, ...options.cursors };\n }\n\n // null is the case where we want to explicitly turn key bindings off\n if (options?.keyEvents === null) {\n this.keyEvents = { cancel: null, finish: null };\n } else if (options?.keyEvents) {\n this.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n }\n }\n\n private pixelDistance = (\n pointOne: { x: number; y: number },\n pointTwo: { x: number; y: number }\n ) => {\n const { x: x1, y: y1 } = pointOne;\n const { x: x2, y: y2 } = pointTwo;\n const y = x2 - x1;\n const x = y2 - y1;\n return Math.sqrt(x * x + y * y);\n };\n\n private measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n const { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n const distance = this.pixelDistance(\n { x, y },\n { x: clickEvent.containerX, y: clickEvent.containerY }\n );\n\n return distance;\n }\n\n private close() {\n if (!this.currentId) {\n return;\n }\n\n // Reset the state back to starting state\n this.currentCoordinate = 0;\n this.currentId = undefined;\n this.currentPointIds = [];\n\n // Go back to started state\n if (this.state === \"drawing\") {\n this.setStarted();\n }\n }\n\n /** @internal */\n registerBehaviors(config: BehaviorConfig) { }\n\n /** @internal */\n start() {\n this.setStarted();\n this.setCursor(this.cursors.draw);\n }\n\n /** @internal */\n stop() {\n this.cleanUp();\n this.setStopped();\n this.setCursor(\"unset\");\n }\n\n\n private latestEvent: TerraDrawMouseEvent | null = null;\n\n /** @internal */\n onMouseMove(event: TerraDrawMouseEvent) {\n this.latestEvent = event;\n\n requestAnimationFrame(() => {\n const latestEvent = this.latestEvent;\n if (latestEvent) {\n this.processMouseMove(latestEvent);\n this.latestEvent = null;\n }\n });\n }\n\n private processMouseMove(event: TerraDrawMouseEvent) {\n this.setCursor(this.cursors.draw);\n\n if (this.moveLineId && !this.store.has(this.moveLineId)) {\n this.moveLineId = undefined;\n }\n\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n\n const currentLineGeometryForCloseCheck = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (!currentLineGeometryForCloseCheck) {\n return;\n }\n\n // If the cursor is close the last line\n // delete the current moving line and set the cursor to pointer\n if (\n this.measure(\n event,\n currentLineGeometryForCloseCheck.coordinates[\n currentLineGeometryForCloseCheck.coordinates.length - 1\n ]\n ) < this.pointerDistance\n ) {\n this.setCursor(this.cursors.close);\n\n if (!this.moveLineId) {\n return;\n }\n if (this.store.has(this.moveLineId)) {\n this.store.delete([this.moveLineId]);\n }\n this.moveLineId = undefined;\n return;\n }\n\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (!currentLineGeometry) {\n return;\n }\n\n const eventCoord = [event.lng, event.lat] as Position;\n\n const closestPoint = this.routing.getClosestNetworkCoordinate(eventCoord);\n\n if (!closestPoint) {\n return;\n }\n\n const length = currentLineGeometry.coordinates.length - 1;\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[length],\n closestPoint\n );\n\n if (!geojsonRoute) {\n return;\n }\n\n if (!this.moveLineId) {\n const [createdId] = this.store.create([\n {\n geometry: geojsonRoute.geometry,\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.moveLineId = createdId as string;\n } else {\n this.store.updateGeometry([\n {\n id: this.moveLineId,\n geometry: geojsonRoute.geometry,\n },\n ]);\n }\n }\n\n /** @internal */\n onClick(event: TerraDrawMouseEvent) {\n if (event.button === \"right\") {\n return;\n }\n\n const eventCoord = [event.lng, event.lat] as Position;\n\n if (this.currentId && !this.store.has(this.currentId)) {\n this.currentId = undefined;\n this.currentCoordinate = 0;\n this.currentPointIds = [];\n }\n\n if (this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (\n this.measure(\n event,\n currentLineGeometry.coordinates[\n currentLineGeometry.coordinates.length - 1\n ]\n ) < this.pointerDistance\n ) {\n if (this.currentCoordinate === 1) {\n this.store.delete(this.currentPointIds);\n }\n\n this.close();\n\n return;\n }\n } else {\n this.routeId++;\n }\n\n let closestPoint = this.routing.getClosestNetworkCoordinate(eventCoord);\n\n if (this.currentCoordinate === 0) {\n if (closestPoint) {\n const [createdId, pointId] = this.store.create([\n {\n geometry: {\n type: \"LineString\",\n coordinates: [closestPoint],\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.currentId = createdId as string;\n this.currentPointIds.push(pointId as string);\n this.currentCoordinate++;\n\n if (this.state === \"started\") {\n this.setDrawing();\n }\n }\n } else if (this.currentCoordinate === 1 && this.currentId && closestPoint) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[0],\n closestPoint\n );\n if (geojsonRoute) {\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: geojsonRoute?.geometry,\n },\n ]);\n\n const [pointId] = this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.currentCoordinate = 2;\n this.currentPointIds.push(pointId as string);\n }\n\n if (this.maxPoints === 1) {\n this.close();\n\n return;\n }\n } else if (\n this.currentCoordinate > 1 &&\n this.currentId &&\n closestPoint &&\n this.currentCoordinate <= this.maxPoints\n ) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const length = currentLineGeometry.coordinates.length - 1;\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[length],\n closestPoint\n );\n\n if (geojsonRoute) {\n const newGeometry = {\n ...currentLineGeometry,\n coordinates: [\n ...currentLineGeometry.coordinates,\n ...geojsonRoute.geometry.coordinates,\n ],\n };\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: newGeometry,\n },\n ]);\n\n const [pointId] = this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n if (this.maxPoints === this.currentCoordinate) {\n this.close();\n } else {\n this.currentCoordinate++;\n this.currentPointIds.push(pointId as string);\n }\n }\n }\n }\n\n /** @internal */\n onKeyDown() { }\n\n /** @internal */\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n\n if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n\n /** @internal */\n onDragStart() { }\n\n /** @internal */\n onDrag() { }\n\n /** @internal */\n onDragEnd() { }\n\n /** @internal */\n cleanUp() {\n try {\n if (this.currentId) {\n this.store.delete([this.currentId, ...this.currentPointIds]);\n }\n } catch (error) { }\n\n this.currentId = undefined;\n this.moveLineId = undefined;\n this.currentCoordinate = 0;\n if (this.state === \"drawing\") {\n this.setStarted();\n }\n }\n\n /** @internal */\n styleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n const styles = TerraDrawExtend.getDefaultStyling();\n\n if (\n feature.type === \"Feature\" &&\n feature.geometry.type === \"LineString\" &&\n feature.properties.mode === this.mode\n ) {\n styles.lineStringColor = this.getHexColorStylingValue(this.styles.lineStringColor, \"#B90E0A\", feature);\n styles.lineStringWidth = this.getNumericStylingValue(this.styles.lineStringWidth, 4, feature);\n styles.zIndex = 10;\n\n return styles;\n } else if (\n feature.type === \"Feature\" &&\n feature.geometry.type === \"Point\" &&\n feature.properties.mode === this.mode\n ) {\n styles.pointColor = this.getHexColorStylingValue(this.styles.routePointColor, \"#B90E0A\", feature);\n styles.pointOutlineColor = this.getHexColorStylingValue(this.styles.routePointColor, \"#B90E0A\", feature);\n styles.pointOutlineWidth = this.getNumericStylingValue(this.styles.routePointOutlineWidth, 1, feature);\n\n return styles;\n }\n\n return styles;\n }\n\n validateFeature(feature: unknown): ReturnType<Validation> {\n return super.validateFeature(feature)\n }\n\n afterFeatureAdded(feature: GeoJSONStoreFeatures) { }\n\n}\n\nexport { Routing, type RouteFinder, type RoutingInterface } from \"./routing\";"],"names":["ARRAY_TYPES","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","KDBush","numItems","nodeSize","ArrayType","data","ids","this","coords","_pos","_finished","IndexArrayType","isNaN","Error","Math","min","max","arrayTypeIndex","indexOf","coordsByteSize","BYTES_PER_ELEMENT","idsByteSize","padCoords","ArrayBuffer","set","_proto","prototype","add","x","y","index","finish","numAdded","sort","left","right","axis","m","select","k","n","z","log","s","exp","sd","sqrt","floor","t","i","j","swapItem","swap","arr","tmp","TinyQueue","compare","a","b","length","_down","push","item","_up","pop","top","bottom","peek","pos","parent","current","halfLength","bestChild","rad","PI","boxDist","lng","lat","cosLat","node","minLng","maxLng","minLat","maxLat","haverSin","haverSinDLng","extremumLat","cosDLng","atan","tan","vertexLat","haverSinDistPartial","compareDist","dist","theta","sin","cosLat1","lat1","lat2","cos","haverSinDist","lng1","lng2","Routing","options","useCache","indexedNetworkPoints","points","routeFinder","network","routeCache","initialise","_this","features","forEach","feature","geometry","coordinates","coordinate","getClosestNetworkCoordinate","inputCoordinate","aroundInput","maxResults","maxDistance","Infinity","maxHaverSinDist","result","undefined","q","id","midLng","midLat","nextAxis","leftNode","rightNode","candidate","around","setRouteFinder","setNetwork","getRoute","startCoord","endCoord","routeKey","route","type","properties","defaultKeyEvents","cancel","defaultCursors","draw","close","TerraDrawRouteSnapMode","_TerraDrawBaseDrawMod","call","mode","currentCoordinate","currentId","keyEvents","cursors","maxPoints","moveLineId","routing","currentPointIds","routeId","pixelDistance","pointOne","pointTwo","latestEvent","updateOptions","cleanUp","_extends","measure","clickEvent","secondCoordinate","_this$project","project","containerX","containerY","state","setStarted","registerBehaviors","config","start","setCursor","stop","setStopped","onMouseMove","event","_this2","requestAnimationFrame","processMouseMove","store","has","currentLineGeometryForCloseCheck","getGeometryCopy","pointerDistance","currentLineGeometry","closestPoint","geojsonRoute","updateGeometry","_this$store$create","create","isDrawnRoute","onClick","button","eventCoord","_this$store$create2","pointId","setDrawing","newGeometry","concat","onKeyDown","onKeyUp","key","onDragStart","onDrag","onDragEnd","error","styleFeature","styles","TerraDrawExtend","getDefaultStyling","lineStringColor","getHexColorStylingValue","lineStringWidth","getNumericStylingValue","zIndex","pointColor","routePointColor","pointOutlineColor","pointOutlineWidth","routePointOutlineWidth","validateFeature","afterFeatureAdded","TerraDrawBaseDrawMode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terra-draw-route-snap-mode.cjs","sources":["../src/kdbush/kdbush.ts","../src/kdbush/tinyqueue.ts","../src/kdbush/geokdbush.ts","../src/routing.ts","../src/terra-draw-route-snap-mode.ts"],"sourcesContent":["// Adapted from https://github.com/mourner/kdbush\n\n// ISC License\n\n// Copyright (c) 2018, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nconst ARRAY_TYPES = [\n Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,\n Int32Array, Uint32Array, Float32Array, Float64Array\n];\n\nconst VERSION = 1;\nconst HEADER_SIZE = 8;\n\nexport class KDBush {\n private data: ArrayBuffer;\n public ids: Uint16Array | Uint32Array;\n public coords: InstanceType<TypedArrayConstructor>;\n private _pos: number;\n private _finished: boolean;\n private numItems: number;\n public nodeSize: number;\n private ArrayType: TypedArrayConstructor;\n private IndexArrayType: typeof Uint16Array | typeof Uint32Array;\n\n constructor(\n numItems: number,\n nodeSize: number = 64,\n ArrayType: TypedArrayConstructor = Float64Array,\n data?: ArrayBuffer\n ) {\n if (isNaN(numItems) || numItems < 0) {\n throw new Error(`Unexpected numItems value: ${numItems}.`);\n }\n\n this.numItems = numItems;\n this.nodeSize = Math.min(Math.max(nodeSize, 2), 65535);\n this.ArrayType = ArrayType;\n this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);\n const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT;\n const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT;\n const padCoords = (8 - idsByteSize % 8) % 8;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n if (data) {\n this.data = data;\n this.ids = new (this.IndexArrayType as any)(this.data, HEADER_SIZE, numItems);\n this.coords = new (this.ArrayType as any)(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = numItems * 2;\n this._finished = true;\n } else {\n this.data = new ArrayBuffer(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords);\n this.ids = new (this.IndexArrayType as any)(this.data, HEADER_SIZE, numItems);\n this.coords = new (this.ArrayType as any)(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = 0;\n this._finished = false;\n\n new Uint8Array(this.data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(this.data, 2, 1)[0] = this.nodeSize;\n new Uint32Array(this.data, 4, 1)[0] = this.numItems;\n }\n }\n\n add(x: number, y: number): number {\n const index = this._pos >> 1;\n this.ids[index] = index;\n this.coords[this._pos++] = x;\n this.coords[this._pos++] = y;\n return index;\n }\n\n finish(): this {\n const numAdded = this._pos >> 1;\n if (numAdded !== this.numItems) {\n throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`);\n }\n sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0);\n this._finished = true;\n return this;\n }\n}\n\ntype TypedArrayConstructor =\n Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor |\n Int16ArrayConstructor | Uint16ArrayConstructor |\n Int32ArrayConstructor | Uint32ArrayConstructor |\n Float32ArrayConstructor | Float64ArrayConstructor;\n\nfunction sort(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n nodeSize: number,\n left: number,\n right: number,\n axis: number\n): void {\n if (right - left <= nodeSize) return;\n const m = (left + right) >> 1;\n select(ids, coords, m, left, right, axis);\n sort(ids, coords, nodeSize, left, m - 1, 1 - axis);\n sort(ids, coords, nodeSize, m + 1, right, 1 - axis);\n}\n\nfunction select(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n k: number,\n left: number,\n right: number,\n axis: number\n): void {\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp(2 * z / 3);\n const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n select(ids, coords, k, newLeft, newRight, axis);\n }\n\n const t = coords[2 * k + axis];\n let i = left;\n let j = right;\n\n swapItem(ids, coords, left, k);\n if (coords[2 * right + axis] > t) {\n swapItem(ids, coords, left, right);\n }\n\n while (i < j) {\n swapItem(ids, coords, i, j);\n i++;\n j--;\n while (coords[2 * i + axis] < t) i++;\n while (coords[2 * j + axis] > t) j--;\n }\n\n if (coords[2 * left + axis] === t) {\n swapItem(ids, coords, left, j);\n } else {\n j++;\n swapItem(ids, coords, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swapItem(\n ids: Uint16Array | Uint32Array,\n coords: InstanceType<TypedArrayConstructor>,\n i: number,\n j: number\n): void {\n swap(ids, i, j);\n swap(coords, 2 * i, 2 * j);\n swap(coords, 2 * i + 1, 2 * j + 1);\n}\n\nfunction swap<T extends Uint16Array | Uint32Array | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint8Array | Uint8ClampedArray>(\n arr: T,\n i: number,\n j: number\n): void {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n","// Adapted from https://github.com/mourner/kdbush\n\n// ISC License\n\n// Copyright (c) 2017, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nexport default class TinyQueue<T> {\n\n private data: T[];\n public length: number;\n private compare: (a: T, b: T) => number;\n\n constructor(\n data: T[] = [],\n compare: (a: T, b: T) => number = (a, b) =>\n a < b ? -1 : a > b ? 1 : 0\n ) {\n this.data = data;\n this.length = this.data.length;\n this.compare = compare;\n\n if (this.length > 0) {\n for (let i = (this.length >> 1) - 1; i >= 0; i--) {\n this._down(i);\n }\n }\n }\n\n push(item: T): void {\n this.data.push(item);\n this._up(this.length++);\n }\n\n pop(): T | undefined {\n if (this.length === 0) {\n return undefined;\n }\n\n const top = this.data[0];\n const bottom = this.data.pop() as T;\n\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = bottom;\n this._down(0);\n }\n\n return top;\n }\n\n peek(): T | undefined {\n return this.data[0];\n }\n\n private _up(pos: number): void {\n const { data, compare } = this;\n const item = data[pos];\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const current = data[parent];\n if (compare(item, current) >= 0) {\n break;\n }\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n }\n\n private _down(pos: number): void {\n const { data, compare } = this;\n const halfLength = this.length >> 1;\n const item = data[pos];\n\n while (pos < halfLength) {\n let bestChild = (pos << 1) + 1;\n const right = bestChild + 1;\n\n if (right < this.length && compare(data[right], data[bestChild]) < 0) {\n bestChild = right;\n }\n\n if (compare(data[bestChild], item) >= 0) {\n break;\n }\n\n data[pos] = data[bestChild];\n pos = bestChild;\n }\n\n data[pos] = item;\n }\n}\n","// Adapted from https://github.com/mourner/geokdbush\n\n// ISC License\n\n// Copyright (c) 2017, Vladimir Agafonkin\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose\n// with or without fee is hereby granted, provided that the above copyright notice\n// and this permission notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\n// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS\n// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n// THIS SOFTWARE.\n\nimport { KDBush } from './kdbush';\nimport TinyQueue from './tinyqueue';\n\nconst earthRadius = 6371;\nconst rad = Math.PI / 180;\n\n\nexport function around(index: KDBush, lng: number, lat: number, maxResults = Infinity, maxDistance = Infinity) {\n let maxHaverSinDist = 1;\n const result = [];\n\n if (maxResults === undefined) maxResults = Infinity;\n if (maxDistance !== undefined) maxHaverSinDist = haverSin(maxDistance / earthRadius);\n\n // a distance-sorted priority queue that will contain both points and kd-tree nodes\n const q = new TinyQueue([], compareDist);\n\n // an object that represents the top kd-tree node (the whole Earth)\n let node = {\n left: 0, // left index in the kd-tree array\n right: index.ids.length - 1, // right index\n axis: 0, // 0 for longitude axis and 1 for latitude axis\n dist: 0, // will hold the lower bound of children's distances to the query point\n minLng: -180, // bounding box of the node\n minLat: -90,\n maxLng: 180,\n maxLat: 90\n };\n\n const cosLat = Math.cos(lat * rad);\n\n while (node) {\n const right = node.right;\n const left = node.left;\n\n if (right - left <= index.nodeSize) { // leaf node\n\n // add all points of the leaf node to the queue\n for (let i = left; i <= right; i++) {\n const id = index.ids[i];\n\n const dist = haverSinDist(lng, lat, index.coords[2 * i], index.coords[2 * i + 1], cosLat);\n q.push({ id, dist });\n }\n\n } else { // not a leaf node (has child nodes)\n\n const m = (left + right) >> 1; // middle index\n const midLng = index.coords[2 * m];\n const midLat = index.coords[2 * m + 1];\n\n // add middle point to the queue\n const id = index.ids[m];\n const dist = haverSinDist(lng, lat, midLng, midLat, cosLat);\n q.push({ id, dist });\n\n\n const nextAxis = (node.axis + 1) % 2;\n\n // first half of the node\n const leftNode = {\n left,\n right: m - 1,\n axis: nextAxis,\n minLng: node.minLng,\n minLat: node.minLat,\n maxLng: node.axis === 0 ? midLng : node.maxLng,\n maxLat: node.axis === 1 ? midLat : node.maxLat,\n dist: 0\n };\n // second half of the node\n const rightNode = {\n left: m + 1,\n right,\n axis: nextAxis,\n minLng: node.axis === 0 ? midLng : node.minLng,\n minLat: node.axis === 1 ? midLat : node.minLat,\n maxLng: node.maxLng,\n maxLat: node.maxLat,\n dist: 0\n };\n\n leftNode.dist = boxDist(lng, lat, cosLat, leftNode);\n rightNode.dist = boxDist(lng, lat, cosLat, rightNode);\n\n // add child nodes to the queue\n q.push(leftNode);\n q.push(rightNode);\n }\n\n // fetch closest points from the queue; they're guaranteed to be closer\n // than all remaining points (both individual and those in kd-tree nodes),\n // since each node's distance is a lower bound of distances to its children\n while (q.length && q.peek().id != null) {\n const candidate = q.pop()!;\n if (candidate.dist > maxHaverSinDist) return result;\n result.push(candidate.id);\n if (result.length === maxResults) return result;\n }\n\n // the next closest kd-tree node\n node = q.pop();\n }\n\n return result;\n}\n\n// lower bound for distance from a location to points inside a bounding box\nfunction boxDist(lng: number, lat: number, cosLat: number, node: any) {\n const minLng = node.minLng;\n const maxLng = node.maxLng;\n const minLat = node.minLat;\n const maxLat = node.maxLat;\n\n // query point is between minimum and maximum longitudes\n if (lng >= minLng && lng <= maxLng) {\n if (lat < minLat) return haverSin((lat - minLat) * rad);\n if (lat > maxLat) return haverSin((lat - maxLat) * rad);\n return 0;\n }\n\n // query point is west or east of the bounding box;\n // calculate the extremum for great circle distance from query point to the closest longitude;\n const haverSinDLng = Math.min(haverSin((lng - minLng) * rad), haverSin((lng - maxLng) * rad));\n const extremumLat = vertexLat(lat, haverSinDLng);\n\n // if extremum is inside the box, return the distance to it\n if (extremumLat > minLat && extremumLat < maxLat) {\n return haverSinDistPartial(haverSinDLng, cosLat, lat, extremumLat);\n }\n // otherwise return the distan e to one of the bbox corners (whichever is closest)\n return Math.min(\n haverSinDistPartial(haverSinDLng, cosLat, lat, minLat),\n haverSinDistPartial(haverSinDLng, cosLat, lat, maxLat)\n );\n}\n\nfunction compareDist(a: any, b: any) {\n return a.dist - b.dist;\n}\n\nfunction haverSin(theta: number) {\n const s = Math.sin(theta / 2);\n return s * s;\n}\n\nfunction haverSinDistPartial(haverSinDLng: number, cosLat1: number, lat1: number, lat2: number) {\n return cosLat1 * Math.cos(lat2 * rad) * haverSinDLng + haverSin((lat1 - lat2) * rad);\n}\n\nfunction haverSinDist(lng1: number, lat1: number, lng2: number, lat2: number, cosLat1: number) {\n const haverSinDLng = haverSin((lng1 - lng2) * rad);\n return haverSinDistPartial(haverSinDLng, cosLat1, lat1, lat2);\n}\n\nexport function distance(lng1: number, lat1: number, lng2: number, lat2: number) {\n const h = haverSinDist(lng1, lat1, lng2, lat2, Math.cos(lat1 * rad));\n return 2 * earthRadius * Math.asin(Math.sqrt(h));\n}\n\nfunction vertexLat(lat: number, haverSinDLng: number) {\n const cosDLng = 1 - 2 * haverSinDLng;\n if (cosDLng <= 0) return lat > 0 ? 90 : -90;\n return Math.atan(Math.tan(lat * rad) / cosDLng) / rad;\n}","import { KDBush } from \"./kdbush/kdbush\";\nimport { around } from \"./kdbush/geokdbush\";\nimport {\n FeatureCollection,\n LineString,\n Position,\n Feature,\n Point,\n} from \"geojson\";\n\nexport type RouteFinder = {\n getRoute: (positionA: Feature<Point>, positionB: Feature<Point>) => Feature<LineString> | null\n setNetwork: (network: FeatureCollection<LineString>) => void\n expandNetwork: (additionalNetwork: FeatureCollection<LineString>) => void\n}\n\nexport interface RoutingInterface {\n getRoute: (\n startCoord: Position,\n endCoord: Position\n ) => Feature<LineString> | null;\n getClosestNetworkCoordinate: (coordinate: Position) => Position | null;\n setRouteFinder: (routeFinder: RouteFinder) => void;\n setNetwork: (network: FeatureCollection<LineString>) => void\n}\n\n/**\n * Routing class for finding routes on a network of LineStrings.\n * The LineString network must have coordinates that are shared between\n * the LineStrings in order to find a route.\n */\nexport class Routing implements RoutingInterface {\n constructor(options: {\n network: FeatureCollection<LineString>, useCache?: boolean,\n routeFinder: RouteFinder\n }) {\n this.useCache = options.useCache !== undefined ? options.useCache : true;\n this.network = this.clone(options.network);\n this.routeFinder = options.routeFinder;\n\n this.initialise();\n }\n\n private useCache: boolean = true;\n private indexedNetworkPoints!: KDBush;\n private points: Position[] = []\n private routeFinder: RouteFinder;\n private network: FeatureCollection<LineString>;\n private routeCache: Record<string, Feature<LineString> | null> = {};\n\n // Initialise the routing instance setting internal data structures\n private initialise() {\n this.network.features.forEach((feature) => {\n feature.geometry.coordinates.forEach((coordinate) => {\n this.points.push(coordinate);\n });\n });\n\n this.indexedNetworkPoints = new KDBush(this.points.length);\n\n this.points.forEach(coordinate => {\n this.indexedNetworkPoints.add(coordinate[0], coordinate[1]);\n })\n\n this.indexedNetworkPoints.finish();\n\n this.routeCache = {};\n }\n\n /**\n * Return the closest network coordinate to the input coordinate\n * @param inputCoordinate The coordinate to find the closest network coordinate to\n * @returns a coordinate on the network or null if no coordinate is found\n */\n public getClosestNetworkCoordinate(inputCoordinate: Position) {\n const aroundInput: number[] = around(\n this.indexedNetworkPoints,\n inputCoordinate[0],\n inputCoordinate[1],\n 1\n );\n\n const nearest = this.points[aroundInput[0]]\n return nearest ? nearest : null;\n }\n\n /**\n * Set the route finder for the routing instance\n * @param routeFinder The route finder to use\n */\n public setRouteFinder(routeFinder: RouteFinder) {\n this.routeFinder = routeFinder;\n }\n\n /**\n * Set the network for the routing instance\n * @param network The network to use\n */\n public setNetwork(network: FeatureCollection<LineString>) {\n this.network = this.clone(network);\n\n // Ensure the network is updated correctly for the router finder\n this.routeFinder.setNetwork(network);\n\n // Re-initialize all internal data structures for this class\n this.initialise();\n }\n\n public expandRouteNetwork(additionalNetwork: FeatureCollection<LineString>) {\n const clonedNetwork = this.clone(additionalNetwork);\n\n // Ensure the network is updated correctly for the router finder\n this.routeFinder.expandNetwork(clonedNetwork);\n\n const mergedNetwork = {\n type: \"FeatureCollection\",\n features: [...clonedNetwork.features, ...this.network.features]\n } as FeatureCollection<LineString>;\n\n this.network = mergedNetwork;\n\n // Re-initialize all internal data structures for this class\n // TODO: Is there a way to avoid re-initialising here?\n this.initialise();\n }\n\n /**\n * Get the route between two coordinates returned as a GeoJSON LineString\n * @param startCoord start coordinate\n * @param endCoord end coordinate\n * @returns The route as a GeoJSON LineString\n */\n public getRoute(startCoord: Position, endCoord: Position): Feature<LineString> | null {\n\n // Check if caching is enabled, and if the coordinates are already in the cache \n if (this.useCache) {\n const routeKey = `${startCoord}-${endCoord}`;\n\n if (this.routeCache[routeKey]) {\n return this.routeCache[routeKey];\n }\n }\n\n const start = {\n type: \"Feature\",\n geometry: {\n type: \"Point\",\n coordinates: startCoord,\n },\n properties: {},\n } as Feature<Point>;\n\n const end = {\n type: \"Feature\",\n geometry: {\n type: \"Point\",\n coordinates: endCoord,\n },\n properties: {},\n } as Feature<Point>;\n\n const route = this.routeFinder.getRoute(start, end);\n\n // If caching is enabled, store the route in the cache\n if (this.useCache) {\n const routeKey = `${startCoord}-${endCoord}`\n this.routeCache[routeKey] = route;\n return route;\n }\n\n return route;\n\n }\n\n private clone(network: FeatureCollection<LineString>) {\n return JSON.parse(JSON.stringify(network)) as FeatureCollection<LineString>;\n }\n}\n","import {\n TerraDrawAdapterStyling,\n TerraDrawKeyboardEvent,\n TerraDrawMouseEvent,\n BehaviorConfig,\n GeoJSONStoreFeatures,\n TerraDrawExtend\n} from \"terra-draw\";\nimport { LineString, Position } from \"geojson\";\nimport { Validation } from \"terra-draw/dist/common\";\nimport { RoutingInterface } from \"./routing\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n cancel: KeyboardEvent[\"key\"] | null;\n finish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ninterface Cursors {\n draw?: TerraDrawExtend.Cursor;\n close?: TerraDrawExtend.Cursor;\n}\n\nconst defaultCursors = {\n draw: \"crosshair\",\n close: \"pointer\"\n} as Required<Cursors>;\n\ntype RouteStyling = {\n lineStringWidth: TerraDrawExtend.NumericStyling;\n lineStringColor: TerraDrawExtend.HexColorStyling\n routePointColor: TerraDrawExtend.HexColorStyling;\n routePointWidth: TerraDrawExtend.NumericStyling;\n routePointOutlineColor: TerraDrawExtend.HexColorStyling;\n routePointOutlineWidth: TerraDrawExtend.NumericStyling;\n};\n\ninterface TerraDrawRouteSnapModeOptions<T extends TerraDrawExtend.CustomStyling>\n extends TerraDrawExtend.BaseModeOptions<T> {\n routing: RoutingInterface;\n pointerDistance?: number;\n keyEvents?: TerraDrawLineStringModeKeyEvents | null;\n maxPoints?: number;\n cursors?: Partial<Cursors>;\n}\n\nconst { TerraDrawBaseDrawMode } = TerraDrawExtend;\n\nexport class TerraDrawRouteSnapMode extends TerraDrawBaseDrawMode<RouteStyling> {\n mode = \"routesnap\" as const;\n\n private currentCoordinate = 0;\n private currentId: string | undefined;\n private keyEvents: TerraDrawLineStringModeKeyEvents = defaultKeyEvents;\n private cursors: Required<Cursors> = defaultCursors;\n\n private maxPoints: number = 1\n private moveLineId: string | undefined;\n private routing!: RoutingInterface;\n private currentPointIds: string[] = [];\n private routeId = 0;\n\n constructor(options?: TerraDrawRouteSnapModeOptions<RouteStyling>) {\n super(options, true);\n this.updateOptions(options);\n }\n\n override updateOptions(options?: Partial<TerraDrawRouteSnapModeOptions<RouteStyling>>) {\n super.updateOptions(options);\n\n if (options?.routing && options.routing !== this.routing) {\n // We can't guarantee the rout created so far is valid with the new routing \n // So we need to clean up the current state\n this.cleanUp();\n this.routing = options.routing;\n }\n\n if (options?.maxPoints !== undefined && options.maxPoints !== this.maxPoints && options.maxPoints > 0) {\n this.maxPoints = options.maxPoints;\n }\n\n if (options?.cursors) {\n this.cursors = { ...this.cursors, ...options.cursors };\n }\n\n // null is the case where we want to explicitly turn key bindings off\n if (options?.keyEvents === null) {\n this.keyEvents = { cancel: null, finish: null };\n } else if (options?.keyEvents) {\n this.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n }\n }\n\n private pixelDistance = (\n pointOne: { x: number; y: number },\n pointTwo: { x: number; y: number }\n ) => {\n const { x: x1, y: y1 } = pointOne;\n const { x: x2, y: y2 } = pointTwo;\n const y = x2 - x1;\n const x = y2 - y1;\n return Math.sqrt(x * x + y * y);\n };\n\n private measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n const { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n const distance = this.pixelDistance(\n { x, y },\n { x: clickEvent.containerX, y: clickEvent.containerY }\n );\n\n return distance;\n }\n\n private close() {\n if (!this.currentId) {\n return;\n }\n\n // Reset the state back to starting state\n this.currentCoordinate = 0;\n this.currentId = undefined;\n this.currentPointIds = [];\n\n // Go back to started state\n if (this.state === \"drawing\") {\n this.setStarted();\n }\n }\n\n /** @internal */\n registerBehaviors(config: BehaviorConfig) { }\n\n /** @internal */\n start() {\n this.setStarted();\n this.setCursor(this.cursors.draw);\n }\n\n /** @internal */\n stop() {\n this.cleanUp();\n this.setStopped();\n this.setCursor(\"unset\");\n }\n\n\n private latestEvent: TerraDrawMouseEvent | null = null;\n\n /** @internal */\n onMouseMove(event: TerraDrawMouseEvent) {\n this.latestEvent = event;\n\n requestAnimationFrame(() => {\n const latestEvent = this.latestEvent;\n if (latestEvent) {\n this.processMouseMove(latestEvent);\n this.latestEvent = null;\n }\n });\n }\n\n private processMouseMove(event: TerraDrawMouseEvent) {\n this.setCursor(this.cursors.draw);\n\n if (this.moveLineId && !this.store.has(this.moveLineId)) {\n this.moveLineId = undefined;\n }\n\n if (!this.currentId || this.currentCoordinate === 0) {\n return;\n }\n\n const currentLineGeometryForCloseCheck = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (!currentLineGeometryForCloseCheck) {\n return;\n }\n\n // If the cursor is close the last line\n // delete the current moving line and set the cursor to pointer\n if (\n this.measure(\n event,\n currentLineGeometryForCloseCheck.coordinates[\n currentLineGeometryForCloseCheck.coordinates.length - 1\n ]\n ) < this.pointerDistance\n ) {\n this.setCursor(this.cursors.close);\n\n if (!this.moveLineId) {\n return;\n }\n if (this.store.has(this.moveLineId)) {\n this.store.delete([this.moveLineId]);\n }\n this.moveLineId = undefined;\n return;\n }\n\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (!currentLineGeometry) {\n return;\n }\n\n const eventCoord = [event.lng, event.lat] as Position;\n\n const closestPoint = this.routing.getClosestNetworkCoordinate(eventCoord);\n\n if (!closestPoint) {\n return;\n }\n\n const length = currentLineGeometry.coordinates.length - 1;\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[length],\n closestPoint\n );\n\n if (!geojsonRoute) {\n return;\n }\n\n if (!this.moveLineId) {\n const [createdId] = this.store.create([\n {\n geometry: geojsonRoute.geometry,\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.moveLineId = createdId as string;\n } else {\n this.store.updateGeometry([\n {\n id: this.moveLineId,\n geometry: geojsonRoute.geometry,\n },\n ]);\n }\n }\n\n /** @internal */\n onClick(event: TerraDrawMouseEvent) {\n if (event.button === \"right\") {\n return;\n }\n\n const eventCoord = [event.lng, event.lat] as Position;\n\n if (this.currentId && !this.store.has(this.currentId)) {\n this.currentId = undefined;\n this.currentCoordinate = 0;\n this.currentPointIds = [];\n }\n\n if (this.currentId) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n if (\n this.measure(\n event,\n currentLineGeometry.coordinates[\n currentLineGeometry.coordinates.length - 1\n ]\n ) < this.pointerDistance\n ) {\n if (this.currentCoordinate === 1) {\n this.store.delete(this.currentPointIds);\n }\n\n this.close();\n\n return;\n }\n } else {\n this.routeId++;\n }\n\n let closestPoint = this.routing.getClosestNetworkCoordinate(eventCoord);\n\n if (this.currentCoordinate === 0) {\n if (closestPoint) {\n const [createdId, pointId] = this.store.create([\n {\n geometry: {\n type: \"LineString\",\n coordinates: [closestPoint],\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.currentId = createdId as string;\n this.currentPointIds.push(pointId as string);\n this.currentCoordinate++;\n\n if (this.state === \"started\") {\n this.setDrawing();\n }\n }\n } else if (this.currentCoordinate === 1 && this.currentId && closestPoint) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[0],\n closestPoint\n );\n if (geojsonRoute) {\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: geojsonRoute?.geometry,\n },\n ]);\n\n const [pointId] = this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n this.currentCoordinate = 2;\n this.currentPointIds.push(pointId as string);\n }\n\n if (this.maxPoints === 1) {\n this.close();\n\n return;\n }\n } else if (\n this.currentCoordinate > 1 &&\n this.currentId &&\n closestPoint &&\n this.currentCoordinate <= this.maxPoints\n ) {\n const currentLineGeometry = this.store.getGeometryCopy<LineString>(\n this.currentId\n );\n\n const length = currentLineGeometry.coordinates.length - 1;\n\n const geojsonRoute = this.routing.getRoute(\n currentLineGeometry.coordinates[length],\n closestPoint\n );\n\n if (geojsonRoute) {\n const newGeometry = {\n ...currentLineGeometry,\n coordinates: [\n ...currentLineGeometry.coordinates,\n ...geojsonRoute.geometry.coordinates,\n ],\n };\n\n this.store.updateGeometry([\n {\n id: this.currentId,\n geometry: newGeometry,\n },\n ]);\n\n const [pointId] = this.store.create([\n {\n geometry: {\n type: \"Point\",\n coordinates: closestPoint,\n },\n properties: { mode: this.mode, isDrawnRoute: true, routeId: this.routeId },\n },\n ]);\n\n if (this.maxPoints === this.currentCoordinate) {\n this.close();\n } else {\n this.currentCoordinate++;\n this.currentPointIds.push(pointId as string);\n }\n }\n }\n }\n\n /** @internal */\n onKeyDown() { }\n\n /** @internal */\n onKeyUp(event: TerraDrawKeyboardEvent) {\n if (event.key === this.keyEvents.cancel) {\n this.cleanUp();\n }\n\n if (event.key === this.keyEvents.finish) {\n this.close();\n }\n }\n\n /** @internal */\n onDragStart() { }\n\n /** @internal */\n onDrag() { }\n\n /** @internal */\n onDragEnd() { }\n\n /** @internal */\n cleanUp() {\n if (!this.store) {\n return;\n }\n const present = [this.currentId, this.moveLineId, ...this.currentPointIds].filter(id => id && this.store.has(id)) as string[];\n\n this.store.delete(present);\n\n this.currentId = undefined;\n this.moveLineId = undefined;\n this.currentCoordinate = 0;\n if (this.state === \"drawing\") {\n this.setStarted();\n }\n }\n\n /** @internal */\n styleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n const styles = TerraDrawExtend.getDefaultStyling();\n\n if (\n feature.type === \"Feature\" &&\n feature.geometry.type === \"LineString\" &&\n feature.properties.mode === this.mode\n ) {\n styles.lineStringColor = this.getHexColorStylingValue(this.styles.lineStringColor, \"#B90E0A\", feature);\n styles.lineStringWidth = this.getNumericStylingValue(this.styles.lineStringWidth, 4, feature);\n styles.zIndex = 10;\n\n return styles;\n } else if (\n feature.type === \"Feature\" &&\n feature.geometry.type === \"Point\" &&\n feature.properties.mode === this.mode\n ) {\n styles.pointColor = this.getHexColorStylingValue(this.styles.routePointColor, \"#B90E0A\", feature);\n styles.pointOutlineColor = this.getHexColorStylingValue(this.styles.routePointColor, \"#B90E0A\", feature);\n styles.pointOutlineWidth = this.getNumericStylingValue(this.styles.routePointOutlineWidth, 1, feature);\n\n return styles;\n }\n\n return styles;\n }\n\n validateFeature(feature: unknown): ReturnType<Validation> {\n return super.validateFeature(feature)\n }\n\n afterFeatureAdded(feature: GeoJSONStoreFeatures) { }\n\n}\n\nexport { Routing, type RouteFinder, type RoutingInterface } from \"./routing\";"],"names":["ARRAY_TYPES","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","KDBush","numItems","nodeSize","ArrayType","data","ids","this","coords","_pos","_finished","IndexArrayType","isNaN","Error","Math","min","max","arrayTypeIndex","indexOf","coordsByteSize","BYTES_PER_ELEMENT","idsByteSize","padCoords","ArrayBuffer","set","_proto","prototype","add","x","y","index","finish","numAdded","sort","left","right","axis","m","select","k","n","z","log","s","exp","sd","sqrt","floor","t","i","j","swapItem","swap","arr","tmp","TinyQueue","compare","a","b","length","_down","push","item","_up","pop","top","bottom","peek","pos","parent","current","halfLength","bestChild","rad","PI","boxDist","lng","lat","cosLat","node","minLng","maxLng","minLat","maxLat","haverSin","haverSinDLng","extremumLat","cosDLng","atan","tan","vertexLat","haverSinDistPartial","compareDist","dist","theta","sin","cosLat1","lat1","lat2","cos","haverSinDist","lng1","lng2","Routing","options","useCache","indexedNetworkPoints","points","routeFinder","network","routeCache","undefined","clone","initialise","_this","features","forEach","feature","geometry","coordinates","coordinate","getClosestNetworkCoordinate","inputCoordinate","aroundInput","maxResults","maxDistance","Infinity","maxHaverSinDist","result","q","id","midLng","midLat","nextAxis","leftNode","rightNode","candidate","around","setRouteFinder","setNetwork","expandRouteNetwork","additionalNetwork","clonedNetwork","expandNetwork","mergedNetwork","type","concat","getRoute","startCoord","endCoord","routeKey","route","properties","JSON","parse","stringify","defaultKeyEvents","cancel","defaultCursors","draw","close","TerraDrawRouteSnapMode","_TerraDrawBaseDrawMod","call","mode","currentCoordinate","currentId","keyEvents","cursors","maxPoints","moveLineId","routing","currentPointIds","routeId","pixelDistance","pointOne","pointTwo","latestEvent","updateOptions","cleanUp","_extends","measure","clickEvent","secondCoordinate","_this$project","project","containerX","containerY","state","setStarted","registerBehaviors","config","start","setCursor","stop","setStopped","onMouseMove","event","_this2","requestAnimationFrame","processMouseMove","store","has","currentLineGeometryForCloseCheck","getGeometryCopy","pointerDistance","currentLineGeometry","closestPoint","geojsonRoute","updateGeometry","_this$store$create","create","isDrawnRoute","onClick","button","eventCoord","_this$store$create2","pointId","setDrawing","newGeometry","onKeyDown","onKeyUp","key","onDragStart","onDrag","onDragEnd","_this3","present","filter","styleFeature","styles","TerraDrawExtend","getDefaultStyling","lineStringColor","getHexColorStylingValue","lineStringWidth","getNumericStylingValue","zIndex","pointColor","routePointColor","pointOutlineColor","pointOutlineWidth","routePointOutlineWidth","validateFeature","afterFeatureAdded","TerraDrawBaseDrawMode"],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ type RouteStyling = {
|
|
|
17
17
|
routePointOutlineColor: TerraDrawExtend.HexColorStyling;
|
|
18
18
|
routePointOutlineWidth: TerraDrawExtend.NumericStyling;
|
|
19
19
|
};
|
|
20
|
-
interface
|
|
20
|
+
interface TerraDrawRouteSnapModeOptions<T extends TerraDrawExtend.CustomStyling> extends TerraDrawExtend.BaseModeOptions<T> {
|
|
21
21
|
routing: RoutingInterface;
|
|
22
22
|
pointerDistance?: number;
|
|
23
23
|
keyEvents?: TerraDrawLineStringModeKeyEvents | null;
|
|
@@ -36,8 +36,8 @@ export declare class TerraDrawRouteSnapMode extends TerraDrawBaseDrawMode<RouteS
|
|
|
36
36
|
private routing;
|
|
37
37
|
private currentPointIds;
|
|
38
38
|
private routeId;
|
|
39
|
-
constructor(options?:
|
|
40
|
-
updateOptions(options?: Partial<
|
|
39
|
+
constructor(options?: TerraDrawRouteSnapModeOptions<RouteStyling>);
|
|
40
|
+
updateOptions(options?: Partial<TerraDrawRouteSnapModeOptions<RouteStyling>>): void;
|
|
41
41
|
private pixelDistance;
|
|
42
42
|
private measure;
|
|
43
43
|
private close;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{TerraDrawExtend as t}from"terra-draw";function e(){return e=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var s in i)({}).hasOwnProperty.call(i,s)&&(t[s]=i[s])}return t},e.apply(null,arguments)}const i=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class s{constructor(t,e=64,s=Float64Array,r){if(this.data=void 0,this.ids=void 0,this.coords=void 0,this._pos=void 0,this._finished=void 0,this.numItems=void 0,this.nodeSize=void 0,this.ArrayType=void 0,this.IndexArrayType=void 0,isNaN(t)||t<0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=t,this.nodeSize=Math.min(Math.max(e,2),65535),this.ArrayType=s,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const o=i.indexOf(this.ArrayType),n=2*t*this.ArrayType.BYTES_PER_ELEMENT,h=t*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-h%8)%8;if(o<0)throw new Error(`Unexpected typed array class: ${s}.`);r?(this.data=r,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+h+a,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+n+h+a),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+h+a,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+o]),new Uint16Array(this.data,2,1)[0]=this.nodeSize,new Uint32Array(this.data,4,1)[0]=this.numItems)}add(t,e){const i=this._pos>>1;return this.ids[i]=i,this.coords[this._pos++]=t,this.coords[this._pos++]=e,i}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return r(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}}function r(t,e,i,s,n,h){if(n-s<=i)return;const a=s+n>>1;o(t,e,a,s,n,h),r(t,e,i,s,a-1,1-h),r(t,e,i,a+1,n,1-h)}function o(t,e,i,s,r,h){for(;r>s;){if(r-s>600){const n=r-s+1,a=i-s+1,d=Math.log(n),u=.5*Math.exp(2*d/3),c=.5*Math.sqrt(d*u*(n-u)/n)*(a-n/2<0?-1:1);o(t,e,i,Math.max(s,Math.floor(i-a*u/n+c)),Math.min(r,Math.floor(i+(n-a)*u/n+c)),h)}const a=e[2*i+h];let d=s,u=r;for(n(t,e,s,i),e[2*r+h]>a&&n(t,e,s,r);d<u;){for(n(t,e,d,u),d++,u--;e[2*d+h]<a;)d++;for(;e[2*u+h]>a;)u--}e[2*s+h]===a?n(t,e,s,u):(u++,n(t,e,u,r)),u<=i&&(s=u+1),i<=u&&(r=u-1)}}function n(t,e,i,s){h(t,i,s),h(e,2*i,2*s),h(e,2*i+1,2*s+1)}function h(t,e,i){const s=t[e];t[e]=t[i],t[i]=s}class a{constructor(t=[],e=(t,e)=>t<e?-1:t>e?1:0){if(this.data=void 0,this.length=void 0,this.compare=void 0,this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(t){this.data.push(t),this._up(this.length++)}pop(){if(0===this.length)return;const t=this.data[0],e=this.data.pop();return this.length--,this.length>0&&(this.data[0]=e,this._down(0)),t}peek(){return this.data[0]}_up(t){const{data:e,compare:i}=this,s=e[t];for(;t>0;){const r=t-1>>1,o=e[r];if(i(s,o)>=0)break;e[t]=o,t=r}e[t]=s}_down(t){const{data:e,compare:i}=this,s=this.length>>1,r=e[t];for(;t<s;){let s=1+(t<<1);const o=s+1;if(o<this.length&&i(e[o],e[s])<0&&(s=o),i(e[s],r)>=0)break;e[t]=e[s],t=s}e[t]=r}}const d=Math.PI/180;function u(t,e,i,s){const r=s.minLng,o=s.maxLng,n=s.minLat,h=s.maxLat;if(t>=r&&t<=o)return e<n?l((e-n)*d):e>h?l((e-h)*d):0;const a=Math.min(l((t-r)*d),l((t-o)*d)),u=function(t,e){const i=1-2*e;return i<=0?t>0?90:-90:Math.atan(Math.tan(t*d)/i)/d}(e,a);return u>n&&u<h?p(a,i,e,u):Math.min(p(a,i,e,n),p(a,i,e,h))}function c(t,e){return t.dist-e.dist}function l(t){const e=Math.sin(t/2);return e*e}function p(t,e,i,s){return e*Math.cos(s*d)*t+l((i-s)*d)}function m(t,e,i,s,r){return p(l((t-i)*d),r,e,s)}class y{constructor(t){this.useCache=!0,this.indexedNetworkPoints=void 0,this.points=[],this.routeFinder=void 0,this.network=void 0,this.routeCache={},this.useCache=t.useCache||!0,this.network=t.network,this.routeFinder=t.routeFinder,this.initialise()}initialise(){this.network.features.forEach(t=>{t.geometry.coordinates.forEach(t=>{this.points.push(t)})}),this.indexedNetworkPoints=new s(this.points.length),this.points.forEach(t=>{this.indexedNetworkPoints.add(t[0],t[1])}),this.indexedNetworkPoints.finish(),this.routeCache={}}getClosestNetworkCoordinate(t){const e=function(t,e,i,s=Infinity,r=Infinity){let o=1;const n=[];void 0===s&&(s=Infinity),void 0!==r&&(o=l(r/6371));const h=new a([],c);let p={left:0,right:t.ids.length-1,axis:0,dist:0,minLng:-180,minLat:-90,maxLng:180,maxLat:90};const y=Math.cos(i*d);for(;p;){const r=p.right,a=p.left;if(r-a<=t.nodeSize)for(let s=a;s<=r;s++){const r=t.ids[s],o=m(e,i,t.coords[2*s],t.coords[2*s+1],y);h.push({id:r,dist:o})}else{const s=a+r>>1,o=t.coords[2*s],n=t.coords[2*s+1],d=t.ids[s],c=m(e,i,o,n,y);h.push({id:d,dist:c});const l=(p.axis+1)%2,g={left:a,right:s-1,axis:l,minLng:p.minLng,minLat:p.minLat,maxLng:0===p.axis?o:p.maxLng,maxLat:1===p.axis?n:p.maxLat,dist:0},f={left:s+1,right:r,axis:l,minLng:0===p.axis?o:p.minLng,minLat:1===p.axis?n:p.minLat,maxLng:p.maxLng,maxLat:p.maxLat,dist:0};g.dist=u(e,i,y,g),f.dist=u(e,i,y,f),h.push(g),h.push(f)}for(;h.length&&null!=h.peek().id;){const t=h.pop();if(t.dist>o)return n;if(n.push(t.id),n.length===s)return n}p=h.pop()}return n}(this.indexedNetworkPoints,t[0],t[1],1);return this.points[e[0]]||null}setRouteFinder(t){this.routeFinder=t}setNetwork(t){this.network=t,this.routeFinder.setNetwork(t),this.initialise()}getRoute(t,e){if(this.useCache){const i=`${t}-${e}`;if(this.routeCache[i])return this.routeCache[i]}const i=this.routeFinder.getRoute({type:"Feature",geometry:{type:"Point",coordinates:t},properties:{}},{type:"Feature",geometry:{type:"Point",coordinates:e},properties:{}});return this.useCache?(this.routeCache[`${t}-${e}`]=i,i):i}}const g={cancel:"Escape",finish:"Enter"},f={draw:"crosshair",close:"pointer"},{TerraDrawBaseDrawMode:I}=t;class v extends I{constructor(t){super(t,!0),this.mode="routesnap",this.currentCoordinate=0,this.currentId=void 0,this.keyEvents=g,this.cursors=f,this.maxPoints=1,this.moveLineId=void 0,this.routing=void 0,this.currentPointIds=[],this.routeId=0,this.pixelDistance=(t,e)=>{const{x:i,y:s}=t,{x:r,y:o}=e,n=r-i,h=o-s;return Math.sqrt(h*h+n*n)},this.latestEvent=null,this.updateOptions(t)}updateOptions(t){super.updateOptions(t),null!=t&&t.routing&&t.routing!==this.routing&&(this.cleanUp(),this.routing=t.routing),void 0!==(null==t?void 0:t.maxPoints)&&t.maxPoints!==this.maxPoints&&t.maxPoints>0&&(this.maxPoints=t.maxPoints),null!=t&&t.cursors&&(this.cursors=e({},this.cursors,t.cursors)),null===(null==t?void 0:t.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=t&&t.keyEvents&&(this.keyEvents=e({},this.keyEvents,t.keyEvents))}measure(t,e){const{x:i,y:s}=this.project(e[0],e[1]);return this.pixelDistance({x:i,y:s},{x:t.containerX,y:t.containerY})}close(){this.currentId&&(this.currentCoordinate=0,this.currentId=void 0,this.currentPointIds=[],"drawing"===this.state&&this.setStarted())}registerBehaviors(t){}start(){this.setStarted(),this.setCursor(this.cursors.draw)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){this.latestEvent=t,requestAnimationFrame(()=>{const t=this.latestEvent;t&&(this.processMouseMove(t),this.latestEvent=null)})}processMouseMove(t){if(this.setCursor(this.cursors.draw),this.moveLineId&&!this.store.has(this.moveLineId)&&(this.moveLineId=void 0),!this.currentId||0===this.currentCoordinate)return;const e=this.store.getGeometryCopy(this.currentId);if(!e)return;if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance){if(this.setCursor(this.cursors.close),!this.moveLineId)return;return this.store.has(this.moveLineId)&&this.store.delete([this.moveLineId]),void(this.moveLineId=void 0)}const i=this.store.getGeometryCopy(this.currentId);if(!i)return;const s=this.routing.getClosestNetworkCoordinate([t.lng,t.lat]);if(!s)return;const r=this.routing.getRoute(i.coordinates[i.coordinates.length-1],s);if(r)if(this.moveLineId)this.store.updateGeometry([{id:this.moveLineId,geometry:r.geometry}]);else{const[t]=this.store.create([{geometry:r.geometry,properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.moveLineId=t}}onClick(t){if("right"===t.button)return;const i=[t.lng,t.lat];if(this.currentId&&!this.store.has(this.currentId)&&(this.currentId=void 0,this.currentCoordinate=0,this.currentPointIds=[]),this.currentId){const e=this.store.getGeometryCopy(this.currentId);if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance)return 1===this.currentCoordinate&&this.store.delete(this.currentPointIds),void this.close()}else this.routeId++;let s=this.routing.getClosestNetworkCoordinate(i);if(0===this.currentCoordinate){if(s){const[t,e]=this.store.create([{geometry:{type:"LineString",coordinates:[s]},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}},{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.currentId=t,this.currentPointIds.push(e),this.currentCoordinate++,"started"===this.state&&this.setDrawing()}}else if(1===this.currentCoordinate&&this.currentId&&s){const t=this.store.getGeometryCopy(this.currentId),e=this.routing.getRoute(t.coordinates[0],s);if(e){this.store.updateGeometry([{id:this.currentId,geometry:null==e?void 0:e.geometry}]);const[t]=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.currentCoordinate=2,this.currentPointIds.push(t)}if(1===this.maxPoints)return void this.close()}else if(this.currentCoordinate>1&&this.currentId&&s&&this.currentCoordinate<=this.maxPoints){const t=this.store.getGeometryCopy(this.currentId),i=this.routing.getRoute(t.coordinates[t.coordinates.length-1],s);if(i){const r=e({},t,{coordinates:[...t.coordinates,...i.geometry.coordinates]});this.store.updateGeometry([{id:this.currentId,geometry:r}]);const[o]=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.maxPoints===this.currentCoordinate?this.close():(this.currentCoordinate++,this.currentPointIds.push(o))}}}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()}onDragStart(){}onDrag(){}onDragEnd(){}cleanUp(){try{this.currentId&&this.store.delete([this.currentId,...this.currentPointIds])}catch(t){}this.currentId=void 0,this.moveLineId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted()}styleFeature(e){const i=t.getDefaultStyling();return"Feature"===e.type&&"LineString"===e.geometry.type&&e.properties.mode===this.mode?(i.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,"#B90E0A",e),i.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,4,e),i.zIndex=10,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.routePointOutlineWidth,1,e),i):i}validateFeature(t){return super.validateFeature(t)}afterFeatureAdded(t){}}export{y as Routing,v as TerraDrawRouteSnapMode};
|
|
1
|
+
import{TerraDrawExtend as t}from"terra-draw";function e(){return e=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var s in i)({}).hasOwnProperty.call(i,s)&&(t[s]=i[s])}return t},e.apply(null,arguments)}const i=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class s{constructor(t,e=64,s=Float64Array,r){if(this.data=void 0,this.ids=void 0,this.coords=void 0,this._pos=void 0,this._finished=void 0,this.numItems=void 0,this.nodeSize=void 0,this.ArrayType=void 0,this.IndexArrayType=void 0,isNaN(t)||t<0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=t,this.nodeSize=Math.min(Math.max(e,2),65535),this.ArrayType=s,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const o=i.indexOf(this.ArrayType),n=2*t*this.ArrayType.BYTES_PER_ELEMENT,h=t*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-h%8)%8;if(o<0)throw new Error(`Unexpected typed array class: ${s}.`);r?(this.data=r,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+h+a,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+n+h+a),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+h+a,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+o]),new Uint16Array(this.data,2,1)[0]=this.nodeSize,new Uint32Array(this.data,4,1)[0]=this.numItems)}add(t,e){const i=this._pos>>1;return this.ids[i]=i,this.coords[this._pos++]=t,this.coords[this._pos++]=e,i}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return r(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}}function r(t,e,i,s,n,h){if(n-s<=i)return;const a=s+n>>1;o(t,e,a,s,n,h),r(t,e,i,s,a-1,1-h),r(t,e,i,a+1,n,1-h)}function o(t,e,i,s,r,h){for(;r>s;){if(r-s>600){const n=r-s+1,a=i-s+1,d=Math.log(n),u=.5*Math.exp(2*d/3),c=.5*Math.sqrt(d*u*(n-u)/n)*(a-n/2<0?-1:1);o(t,e,i,Math.max(s,Math.floor(i-a*u/n+c)),Math.min(r,Math.floor(i+(n-a)*u/n+c)),h)}const a=e[2*i+h];let d=s,u=r;for(n(t,e,s,i),e[2*r+h]>a&&n(t,e,s,r);d<u;){for(n(t,e,d,u),d++,u--;e[2*d+h]<a;)d++;for(;e[2*u+h]>a;)u--}e[2*s+h]===a?n(t,e,s,u):(u++,n(t,e,u,r)),u<=i&&(s=u+1),i<=u&&(r=u-1)}}function n(t,e,i,s){h(t,i,s),h(e,2*i,2*s),h(e,2*i+1,2*s+1)}function h(t,e,i){const s=t[e];t[e]=t[i],t[i]=s}class a{constructor(t=[],e=(t,e)=>t<e?-1:t>e?1:0){if(this.data=void 0,this.length=void 0,this.compare=void 0,this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(t){this.data.push(t),this._up(this.length++)}pop(){if(0===this.length)return;const t=this.data[0],e=this.data.pop();return this.length--,this.length>0&&(this.data[0]=e,this._down(0)),t}peek(){return this.data[0]}_up(t){const{data:e,compare:i}=this,s=e[t];for(;t>0;){const r=t-1>>1,o=e[r];if(i(s,o)>=0)break;e[t]=o,t=r}e[t]=s}_down(t){const{data:e,compare:i}=this,s=this.length>>1,r=e[t];for(;t<s;){let s=1+(t<<1);const o=s+1;if(o<this.length&&i(e[o],e[s])<0&&(s=o),i(e[s],r)>=0)break;e[t]=e[s],t=s}e[t]=r}}const d=Math.PI/180;function u(t,e,i,s){const r=s.minLng,o=s.maxLng,n=s.minLat,h=s.maxLat;if(t>=r&&t<=o)return e<n?l((e-n)*d):e>h?l((e-h)*d):0;const a=Math.min(l((t-r)*d),l((t-o)*d)),u=function(t,e){const i=1-2*e;return i<=0?t>0?90:-90:Math.atan(Math.tan(t*d)/i)/d}(e,a);return u>n&&u<h?p(a,i,e,u):Math.min(p(a,i,e,n),p(a,i,e,h))}function c(t,e){return t.dist-e.dist}function l(t){const e=Math.sin(t/2);return e*e}function p(t,e,i,s){return e*Math.cos(s*d)*t+l((i-s)*d)}function m(t,e,i,s,r){return p(l((t-i)*d),r,e,s)}class y{constructor(t){this.useCache=!0,this.indexedNetworkPoints=void 0,this.points=[],this.routeFinder=void 0,this.network=void 0,this.routeCache={},this.useCache=void 0===t.useCache||t.useCache,this.network=this.clone(t.network),this.routeFinder=t.routeFinder,this.initialise()}initialise(){this.network.features.forEach(t=>{t.geometry.coordinates.forEach(t=>{this.points.push(t)})}),this.indexedNetworkPoints=new s(this.points.length),this.points.forEach(t=>{this.indexedNetworkPoints.add(t[0],t[1])}),this.indexedNetworkPoints.finish(),this.routeCache={}}getClosestNetworkCoordinate(t){const e=function(t,e,i,s=Infinity,r=Infinity){let o=1;const n=[];void 0===s&&(s=Infinity),void 0!==r&&(o=l(r/6371));const h=new a([],c);let p={left:0,right:t.ids.length-1,axis:0,dist:0,minLng:-180,minLat:-90,maxLng:180,maxLat:90};const y=Math.cos(i*d);for(;p;){const r=p.right,a=p.left;if(r-a<=t.nodeSize)for(let s=a;s<=r;s++){const r=t.ids[s],o=m(e,i,t.coords[2*s],t.coords[2*s+1],y);h.push({id:r,dist:o})}else{const s=a+r>>1,o=t.coords[2*s],n=t.coords[2*s+1],d=t.ids[s],c=m(e,i,o,n,y);h.push({id:d,dist:c});const l=(p.axis+1)%2,g={left:a,right:s-1,axis:l,minLng:p.minLng,minLat:p.minLat,maxLng:0===p.axis?o:p.maxLng,maxLat:1===p.axis?n:p.maxLat,dist:0},f={left:s+1,right:r,axis:l,minLng:0===p.axis?o:p.minLng,minLat:1===p.axis?n:p.minLat,maxLng:p.maxLng,maxLat:p.maxLat,dist:0};g.dist=u(e,i,y,g),f.dist=u(e,i,y,f),h.push(g),h.push(f)}for(;h.length&&null!=h.peek().id;){const t=h.pop();if(t.dist>o)return n;if(n.push(t.id),n.length===s)return n}p=h.pop()}return n}(this.indexedNetworkPoints,t[0],t[1],1);return this.points[e[0]]||null}setRouteFinder(t){this.routeFinder=t}setNetwork(t){this.network=this.clone(t),this.routeFinder.setNetwork(t),this.initialise()}expandRouteNetwork(t){const e=this.clone(t);this.routeFinder.expandNetwork(e);const i={type:"FeatureCollection",features:[...e.features,...this.network.features]};this.network=i,this.initialise()}getRoute(t,e){if(this.useCache){const i=`${t}-${e}`;if(this.routeCache[i])return this.routeCache[i]}const i=this.routeFinder.getRoute({type:"Feature",geometry:{type:"Point",coordinates:t},properties:{}},{type:"Feature",geometry:{type:"Point",coordinates:e},properties:{}});return this.useCache?(this.routeCache[`${t}-${e}`]=i,i):i}clone(t){return JSON.parse(JSON.stringify(t))}}const g={cancel:"Escape",finish:"Enter"},f={draw:"crosshair",close:"pointer"},{TerraDrawBaseDrawMode:I}=t;class v extends I{constructor(t){super(t,!0),this.mode="routesnap",this.currentCoordinate=0,this.currentId=void 0,this.keyEvents=g,this.cursors=f,this.maxPoints=1,this.moveLineId=void 0,this.routing=void 0,this.currentPointIds=[],this.routeId=0,this.pixelDistance=(t,e)=>{const{x:i,y:s}=t,{x:r,y:o}=e,n=r-i,h=o-s;return Math.sqrt(h*h+n*n)},this.latestEvent=null,this.updateOptions(t)}updateOptions(t){super.updateOptions(t),null!=t&&t.routing&&t.routing!==this.routing&&(this.cleanUp(),this.routing=t.routing),void 0!==(null==t?void 0:t.maxPoints)&&t.maxPoints!==this.maxPoints&&t.maxPoints>0&&(this.maxPoints=t.maxPoints),null!=t&&t.cursors&&(this.cursors=e({},this.cursors,t.cursors)),null===(null==t?void 0:t.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=t&&t.keyEvents&&(this.keyEvents=e({},this.keyEvents,t.keyEvents))}measure(t,e){const{x:i,y:s}=this.project(e[0],e[1]);return this.pixelDistance({x:i,y:s},{x:t.containerX,y:t.containerY})}close(){this.currentId&&(this.currentCoordinate=0,this.currentId=void 0,this.currentPointIds=[],"drawing"===this.state&&this.setStarted())}registerBehaviors(t){}start(){this.setStarted(),this.setCursor(this.cursors.draw)}stop(){this.cleanUp(),this.setStopped(),this.setCursor("unset")}onMouseMove(t){this.latestEvent=t,requestAnimationFrame(()=>{const t=this.latestEvent;t&&(this.processMouseMove(t),this.latestEvent=null)})}processMouseMove(t){if(this.setCursor(this.cursors.draw),this.moveLineId&&!this.store.has(this.moveLineId)&&(this.moveLineId=void 0),!this.currentId||0===this.currentCoordinate)return;const e=this.store.getGeometryCopy(this.currentId);if(!e)return;if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance){if(this.setCursor(this.cursors.close),!this.moveLineId)return;return this.store.has(this.moveLineId)&&this.store.delete([this.moveLineId]),void(this.moveLineId=void 0)}const i=this.store.getGeometryCopy(this.currentId);if(!i)return;const s=this.routing.getClosestNetworkCoordinate([t.lng,t.lat]);if(!s)return;const r=this.routing.getRoute(i.coordinates[i.coordinates.length-1],s);if(r)if(this.moveLineId)this.store.updateGeometry([{id:this.moveLineId,geometry:r.geometry}]);else{const[t]=this.store.create([{geometry:r.geometry,properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.moveLineId=t}}onClick(t){if("right"===t.button)return;const i=[t.lng,t.lat];if(this.currentId&&!this.store.has(this.currentId)&&(this.currentId=void 0,this.currentCoordinate=0,this.currentPointIds=[]),this.currentId){const e=this.store.getGeometryCopy(this.currentId);if(this.measure(t,e.coordinates[e.coordinates.length-1])<this.pointerDistance)return 1===this.currentCoordinate&&this.store.delete(this.currentPointIds),void this.close()}else this.routeId++;let s=this.routing.getClosestNetworkCoordinate(i);if(0===this.currentCoordinate){if(s){const[t,e]=this.store.create([{geometry:{type:"LineString",coordinates:[s]},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}},{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.currentId=t,this.currentPointIds.push(e),this.currentCoordinate++,"started"===this.state&&this.setDrawing()}}else if(1===this.currentCoordinate&&this.currentId&&s){const t=this.store.getGeometryCopy(this.currentId),e=this.routing.getRoute(t.coordinates[0],s);if(e){this.store.updateGeometry([{id:this.currentId,geometry:null==e?void 0:e.geometry}]);const[t]=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.currentCoordinate=2,this.currentPointIds.push(t)}if(1===this.maxPoints)return void this.close()}else if(this.currentCoordinate>1&&this.currentId&&s&&this.currentCoordinate<=this.maxPoints){const t=this.store.getGeometryCopy(this.currentId),i=this.routing.getRoute(t.coordinates[t.coordinates.length-1],s);if(i){const r=e({},t,{coordinates:[...t.coordinates,...i.geometry.coordinates]});this.store.updateGeometry([{id:this.currentId,geometry:r}]);const[o]=this.store.create([{geometry:{type:"Point",coordinates:s},properties:{mode:this.mode,isDrawnRoute:!0,routeId:this.routeId}}]);this.maxPoints===this.currentCoordinate?this.close():(this.currentCoordinate++,this.currentPointIds.push(o))}}}onKeyDown(){}onKeyUp(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()}onDragStart(){}onDrag(){}onDragEnd(){}cleanUp(){if(!this.store)return;const t=[this.currentId,this.moveLineId,...this.currentPointIds].filter(t=>t&&this.store.has(t));this.store.delete(t),this.currentId=void 0,this.moveLineId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted()}styleFeature(e){const i=t.getDefaultStyling();return"Feature"===e.type&&"LineString"===e.geometry.type&&e.properties.mode===this.mode?(i.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,"#B90E0A",e),i.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,4,e),i.zIndex=10,i):"Feature"===e.type&&"Point"===e.geometry.type&&e.properties.mode===this.mode?(i.pointColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineColor=this.getHexColorStylingValue(this.styles.routePointColor,"#B90E0A",e),i.pointOutlineWidth=this.getNumericStylingValue(this.styles.routePointOutlineWidth,1,e),i):i}validateFeature(t){return super.validateFeature(t)}afterFeatureAdded(t){}}export{y as Routing,v as TerraDrawRouteSnapMode};
|
|
2
2
|
//# sourceMappingURL=terra-draw-route-snap-mode.modern.js.map
|