maparea 0.1.9 → 0.1.11
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/index.cjs +1 -1
- package/dist/index.d.ts +78 -15
- package/dist/index.mjs +1 -1
- package/index.ts +6 -4
- package/package.json +19 -19
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return typeof t==`function`?t(e):t??``}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i);else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o);t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e){let t=0,n=0;T(e.container,{onStart(){[t,n]=e.centerCoords},onMove(r,i){let a=t+r,o=n+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,t=a,n=o)},wheel:!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math,z=256;function B(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function V(e,t,n,{size:r=256,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=0,u=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s};return c.width=r,c.height=r,c.src=u(t,n),c.dataset.id=B(e,t,n),c.style=`position: absolute;`,c.onerror=()=>{l++;let{src:i}=c;if(!i||l>o){let t=S(e,s);t&&(c.onerror=()=>{},c.dataset.src=i,c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=I(f/r);if(t!==p)c.src=u(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),c.src=e.href}},c}function H(e){return e.querySelectorAll(`img[data-id]`)}function U(e,t){return e.querySelector(`img[data-id="${t}"]`)}function W(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l=256,margin:u=0}=t,d=Array.isArray(u)?u[0]:u,f=Array.isArray(u)?u[1]:u,p=L((n+2*d)/l),m=L((i+2*f)/l),h=I(s/l),g=I(c/l),_=null,v=new Set,y=``;for(let r=0;r<=p;r++){let o=h+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=m;r++){let u=g+(r%2==0?-1:1)*I(r/2);y=B(e,o,u),_=U(a,y),_||(_=V(e,o,u,t),a.append(_));let d=C(.5*n+o*l-s,2),f=C(.5*i+u*l-c,2);_.style.transform=`translate3d(${d}px, ${f}px, 0)`,v.add(y)}}for(let e of H(a)){let{id:t}=e.dataset;t&&!v.has(t)&&e.remove()}let b=S(e,r);o.toggleAttribute(`hidden`,!b),o.innerHTML!==b&&(o.innerHTML=b)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function G(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}function K(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function q(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=K(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function J(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}const Y=[.005,.018];function X(e){return Array.isArray(e)?J(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:K(e):e}function Z(e,[t,n]=Y){let{minLat:r=0,maxLat:i=0,minLon:a=0,maxLon:o=0}=X(e);return{minLat:r-t,maxLat:i+t,minLon:a-n,maxLon:o+n}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addClickListener=y,exports.addElement=w,exports.addNavigation=E,exports.addPersistence=D,exports.addResizeObserver=O,exports.addShape=P,exports.addShapeEditor=F,exports.addTiles=W,exports.addZoomControls=G,exports.eccentricityMap=r,exports.getCenter=q,exports.getGeoBounds=K,exports.getId=b,exports.getLayer=x,exports.getPointerPosition=_,exports.getVicinity=Z,exports.isGeoCoords=J,exports.resolveString=S,exports.toPrecision=C;
|
|
1
|
+
const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return t===void 0?t:t instanceof Function?t(e):t}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e,t){let n=0,r=0;T(e.container,{onStart(){[n,r]=e.centerCoords},onMove(t,i){let a=n+t,o=r+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,n=a,r=o)},wheel:t?.wheel??!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math,ee=256;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r,url:i,subdomains:a,error:o}){let s=new Image,c=S(e,r)??256;return s.width=c,s.height=c,s.src=((r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s})(t,n),s.dataset.id=z(e,t,n),s.style=`position: absolute;`,s.addEventListener(`error`,t=>{let n=t.target;if(n instanceof HTMLImageElement){let t=S(e,o);t&&(n.dataset.src=s.src,n.src=t)}}),s}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=S(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=L((n+2*f)/d),h=L((i+2*p)/d),g=I(s/d),_=I(c/d),v=null,y=new Set,b=``;for(let r=0;r<=m;r++){let o=g+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=h;r++){let l=_+(r%2==0?-1:1)*I(r/2);b=z(e,o,l),v=H(a,b),v||(v=B(e,o,l,t),a.append(v));let u=C(.5*n+o*d-s,2),f=C(.5*i+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,y.add(b)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!y.has(t)&&e.remove()}let x=S(e,r)??``;o.toggleAttribute(`hidden`,!x),o.innerHTML!==x&&(o.innerHTML=x)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}const{abs:G,log2:K,min:q,floor:J}=Math;function Y(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=G(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=K(n/t))}if(s!==void 0&&c!==void 0){let t=G(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=K(r/t))}let p=J(q(o+d,o+f));p!==o&&(e.zoom=p)}function X(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function Q(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function $(e){return Q(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?X(e):e}const te=[.005,.018];function ne(e,t=te){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=$(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addClickListener=y,exports.addElement=w,exports.addMovableViewport=E,exports.addPersistence=D,exports.addResizeObserver=O,exports.addShape=P,exports.addShapeEditor=F,exports.addTiles=U,exports.addZoomControls=W,exports.eccentricityMap=r,exports.fitGeoBounds=Y,exports.getCenter=Z,exports.getGeoBounds=X,exports.getId=b,exports.getLayer=x,exports.getPointerPosition=_,exports.getVicinity=ne,exports.isCoordsArray=Q,exports.resolveDynamic=S,exports.toGeoBounds=$,exports.toPrecision=C;
|
package/dist/index.d.ts
CHANGED
|
@@ -89,19 +89,19 @@ type MapAreaClickEvent = {
|
|
|
89
89
|
};
|
|
90
90
|
type MapAreaClickCallback = (event: MapAreaClickEvent) => void;
|
|
91
91
|
/**
|
|
92
|
-
* Adds a click listener to the map and returns a function
|
|
93
|
-
*
|
|
92
|
+
* Adds a click listener to the map and returns a function that removes
|
|
93
|
+
* the added listener.
|
|
94
94
|
*/
|
|
95
95
|
declare function addClickListener(map: MapArea, callback: MapAreaClickCallback, ignored?: IgnoredElement): () => void;
|
|
96
96
|
|
|
97
|
-
type
|
|
97
|
+
type Dynamic<T> = T | ((map: MapArea) => T);
|
|
98
98
|
|
|
99
99
|
type MapAreaElementOptions = {
|
|
100
100
|
className?: string; /** Geographical position (`[lat, lon]`) of the element's top left corner. */
|
|
101
101
|
coords?: GeoCoords; /** CSS `inset` (disregarding `coords`). */
|
|
102
|
-
inset?:
|
|
102
|
+
inset?: Dynamic<string>; /** Target layer. */
|
|
103
103
|
layer?: Element; /** HTML content of the element. */
|
|
104
|
-
content?:
|
|
104
|
+
content?: Dynamic<string>;
|
|
105
105
|
};
|
|
106
106
|
/**
|
|
107
107
|
* Adds an HTML or SVG element to the map.
|
|
@@ -118,12 +118,25 @@ declare function addElement(map: MapArea, element: HTMLElement | SVGSVGElement,
|
|
|
118
118
|
content
|
|
119
119
|
}: MapAreaElementOptions): void;
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
type MapAreaNavigationOptions = {
|
|
122
|
+
wheel?: boolean;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Enables navigation over the given map container with a mouse or touches
|
|
126
|
+
* or a scroll wheel (the latter can be disabled by setting `options.wheel`
|
|
127
|
+
* to `false`).
|
|
128
|
+
*/
|
|
129
|
+
declare function addMovableViewport(map: MapArea, options?: MapAreaNavigationOptions): void;
|
|
122
130
|
|
|
123
131
|
type PersistenceOptions = {
|
|
124
132
|
storageKey?: string;
|
|
125
133
|
session?: boolean;
|
|
126
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Enables persistence of the map's state across page reloads by saving it to
|
|
137
|
+
* the browser storage (`localStorage` by default, `sessionStorage` with
|
|
138
|
+
* `session` set to `true`).
|
|
139
|
+
*/
|
|
127
140
|
declare function addPersistence(map: MapArea, {
|
|
128
141
|
storageKey,
|
|
129
142
|
session
|
|
@@ -145,6 +158,9 @@ type MapAreaResizeEvent = {
|
|
|
145
158
|
height?: number;
|
|
146
159
|
};
|
|
147
160
|
type MapAreaResizeCallback = (event: MapAreaResizeEvent) => void;
|
|
161
|
+
/**
|
|
162
|
+
* Adds a resize observer to the map and returns a function turning it off.
|
|
163
|
+
*/
|
|
148
164
|
declare function addResizeObserver(map: MapArea, callback?: MapAreaResizeCallback): () => void;
|
|
149
165
|
|
|
150
166
|
type LayerOptions = {
|
|
@@ -153,6 +169,10 @@ type LayerOptions = {
|
|
|
153
169
|
inset?: string;
|
|
154
170
|
};
|
|
155
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Adds a shape based on the given array of geographic coordinates to
|
|
174
|
+
* the specified map layer.
|
|
175
|
+
*/
|
|
156
176
|
declare function addShape(map: MapArea, coords: GeoCoords[], layerOptions?: LayerOptions): void;
|
|
157
177
|
|
|
158
178
|
type Vertex<T> = {
|
|
@@ -166,6 +186,9 @@ type ShapeEditorOptions = {
|
|
|
166
186
|
onUpdate?: (shape: GeoVertex[]) => void;
|
|
167
187
|
ignoreClicks?: IgnoredElement;
|
|
168
188
|
};
|
|
189
|
+
/**
|
|
190
|
+
* Adds a shape editor to the given map container.
|
|
191
|
+
*/
|
|
169
192
|
declare function addShapeEditor(map: MapArea, options?: ShapeEditorOptions): void;
|
|
170
193
|
|
|
171
194
|
type MapAreaTileOptions = LayerOptions & {
|
|
@@ -175,18 +198,22 @@ type MapAreaTileOptions = LayerOptions & {
|
|
|
175
198
|
* or a function of `(map, x, y) => string` returning a fixed string URL.
|
|
176
199
|
*/
|
|
177
200
|
url?: string | ((map: MapArea, xIndex: number, yIndex: number) => string); /** Values of the `{s}` placeholder of the tile URLs. */
|
|
178
|
-
subdomains?: string[]; /**
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
size?: number;
|
|
201
|
+
subdomains?: string[]; /** URL to be used instead of a tile that failed to load. */
|
|
202
|
+
error?: Dynamic<string>; /** Tile size. */
|
|
203
|
+
size?: Dynamic<number>;
|
|
182
204
|
/**
|
|
183
205
|
* Margin in pixels, or a tuple of an x- and y-margin, to be tiled
|
|
184
206
|
* outside the viewport.
|
|
185
207
|
*/
|
|
186
208
|
margin?: number | [number, number]; /** Attribution HTML content. */
|
|
187
|
-
attribution?:
|
|
209
|
+
attribution?: Dynamic<string>; /** Attribution's CSS `inset`. */
|
|
188
210
|
attributionInset?: string;
|
|
189
211
|
};
|
|
212
|
+
/**
|
|
213
|
+
* Adds image tiles to the given map container based on `options.url`,
|
|
214
|
+
* which is a string URL with placeholders or a function of
|
|
215
|
+
* `(map, xIndex, yIndex) => string`.
|
|
216
|
+
*/
|
|
190
217
|
declare function addTiles(map: MapArea, options?: MapAreaTileOptions): HTMLElement;
|
|
191
218
|
|
|
192
219
|
type ZoomControlOptions = {
|
|
@@ -194,6 +221,9 @@ type ZoomControlOptions = {
|
|
|
194
221
|
minus?: string; /** CSS `inset` */
|
|
195
222
|
inset?: string;
|
|
196
223
|
};
|
|
224
|
+
/**
|
|
225
|
+
* Adds customizable zoom controls to the given map container.
|
|
226
|
+
*/
|
|
197
227
|
declare function addZoomControls(map: MapArea, options?: ZoomControlOptions): HTMLElement;
|
|
198
228
|
|
|
199
229
|
type PixelVertex = Vertex<PixelCoords>;
|
|
@@ -202,10 +232,26 @@ type ShapeLayerOptions = LayerOptions & {
|
|
|
202
232
|
markers?: boolean;
|
|
203
233
|
};
|
|
204
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Fits the map to the given geographic bounds.
|
|
237
|
+
*/
|
|
238
|
+
declare function fitGeoBounds(map: MapArea, bounds: GeoBounds): void;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Calculates the geographic coordinates of the center of an array
|
|
242
|
+
* of geographic coordinates.
|
|
243
|
+
*/
|
|
205
244
|
declare function getCenter(coords: GeoCoords[]): GeoCoords;
|
|
206
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Returns the minimal and maximal latitudes and longitudes of
|
|
248
|
+
* an array of geographic coordinates.
|
|
249
|
+
*/
|
|
207
250
|
declare function getGeoBounds(coords: GeoCoords[]): GeoBounds;
|
|
208
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Generates a string ID.
|
|
254
|
+
*/
|
|
209
255
|
declare function getId(): string;
|
|
210
256
|
|
|
211
257
|
/**
|
|
@@ -218,14 +264,31 @@ declare function getLayer(map: MapArea, {
|
|
|
218
264
|
inset
|
|
219
265
|
}?: LayerOptions): HTMLElement;
|
|
220
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Returns the pointer pixel position `[x, y]` of the given mouse or
|
|
269
|
+
* touch event.
|
|
270
|
+
*/
|
|
221
271
|
declare function getPointerPosition(event: MouseEvent | TouchEvent): [number, number] | null;
|
|
222
272
|
|
|
223
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Returns the minimal and maximal latitudes and longitudes of a region
|
|
275
|
+
* surrounding a geographic area, an array of geographic coordinates,
|
|
276
|
+
* or a single point.
|
|
277
|
+
*/
|
|
278
|
+
declare function getVicinity(x: GeoCoords | GeoCoords[] | GeoBounds, padding?: GeoCoords): GeoBounds;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Checks whether the given value is an array of coordinates.
|
|
282
|
+
*/
|
|
283
|
+
declare function isCoordsArray(x: unknown): x is [number, number];
|
|
224
284
|
|
|
225
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Resolves a dynamic value to a static value based on the context.
|
|
287
|
+
*/
|
|
288
|
+
declare function resolveDynamic<T>(map: MapArea, x: Dynamic<T> | undefined): T | undefined;
|
|
226
289
|
|
|
227
|
-
declare function
|
|
290
|
+
declare function toGeoBounds(x: GeoCoords | GeoCoords[] | GeoBounds): GeoBounds;
|
|
228
291
|
|
|
229
292
|
declare function toPrecision(x: number, n: number): string;
|
|
230
293
|
|
|
231
|
-
export { BoxDimensions, DEG,
|
|
294
|
+
export { BoxDimensions, DEG, Dynamic, GeoBounds, GeoCoords, GeoVertex, IgnoredElement, LayerOptions, MAX_LAT, MAX_LON, MIN_LAT, MIN_LON, MapArea, MapAreaClickCallback, MapAreaClickEvent, MapAreaElementOptions, MapAreaNavigationOptions, MapAreaOptions, MapAreaResizeCallback, MapAreaResizeEvent, MapAreaTileOptions, PersistenceOptions, PixelCoords, PixelVertex, Projection, RAD, RenderCallback, ShapeEditorOptions, ShapeLayerOptions, ZoomControlOptions, addClickListener, addElement, addMovableViewport, addPersistence, addResizeObserver, addShape, addShapeEditor, addTiles, addZoomControls, eccentricityMap, fitGeoBounds, getCenter, getGeoBounds, getId, getLayer, getPointerPosition, getVicinity, isCoordsArray, resolveDynamic, toGeoBounds, toPrecision };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return typeof t==`function`?t(e):t??``}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i);else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o);t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e){let t=0,n=0;T(e.container,{onStart(){[t,n]=e.centerCoords},onMove(r,i){let a=t+r,o=n+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,t=a,n=o)},wheel:!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r=256,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=0,u=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s};return c.width=r,c.height=r,c.src=u(t,n),c.dataset.id=z(e,t,n),c.style=`position: absolute;`,c.onerror=()=>{l++;let{src:i}=c;if(!i||l>o){let t=S(e,s);t&&(c.onerror=()=>{},c.dataset.src=i,c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=I(f/r);if(t!==p)c.src=u(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),c.src=e.href}},c}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l=256,margin:u=0}=t,d=Array.isArray(u)?u[0]:u,f=Array.isArray(u)?u[1]:u,p=L((n+2*d)/l),m=L((i+2*f)/l),h=I(s/l),g=I(c/l),_=null,v=new Set,y=``;for(let r=0;r<=p;r++){let o=h+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=m;r++){let u=g+(r%2==0?-1:1)*I(r/2);y=z(e,o,u),_=H(a,y),_||(_=B(e,o,u,t),a.append(_));let d=C(.5*n+o*l-s,2),f=C(.5*i+u*l-c,2);_.style.transform=`translate3d(${d}px, ${f}px, 0)`,v.add(y)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!v.has(t)&&e.remove()}let b=S(e,r);o.toggleAttribute(`hidden`,!b),o.innerHTML!==b&&(o.innerHTML=b)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}function G(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function K(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=G(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function q(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}const J=[.005,.018];function Y(e){return Array.isArray(e)?q(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:G(e):e}function X(e,[t,n]=J){let{minLat:r=0,maxLat:i=0,minLon:a=0,maxLon:o=0}=Y(e);return{minLat:r-t,maxLat:i+t,minLon:a-n,maxLon:o+n}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,y as addClickListener,w as addElement,E as addNavigation,D as addPersistence,O as addResizeObserver,P as addShape,F as addShapeEditor,U as addTiles,W as addZoomControls,r as eccentricityMap,K as getCenter,G as getGeoBounds,b as getId,x as getLayer,_ as getPointerPosition,X as getVicinity,q as isGeoCoords,S as resolveString,C as toPrecision};
|
|
1
|
+
const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return t===void 0?t:t instanceof Function?t(e):t}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e,t){let n=0,r=0;T(e.container,{onStart(){[n,r]=e.centerCoords},onMove(t,i){let a=n+t,o=r+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,n=a,r=o)},wheel:t?.wheel??!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r,url:i,subdomains:a,error:o}){let s=new Image,c=S(e,r)??256;return s.width=c,s.height=c,s.src=((r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s})(t,n),s.dataset.id=z(e,t,n),s.style=`position: absolute;`,s.addEventListener(`error`,t=>{let n=t.target;if(n instanceof HTMLImageElement){let t=S(e,o);t&&(n.dataset.src=s.src,n.src=t)}}),s}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=S(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=L((n+2*f)/d),h=L((i+2*p)/d),g=I(s/d),_=I(c/d),v=null,y=new Set,b=``;for(let r=0;r<=m;r++){let o=g+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=h;r++){let l=_+(r%2==0?-1:1)*I(r/2);b=z(e,o,l),v=H(a,b),v||(v=B(e,o,l,t),a.append(v));let u=C(.5*n+o*d-s,2),f=C(.5*i+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,y.add(b)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!y.has(t)&&e.remove()}let x=S(e,r)??``;o.toggleAttribute(`hidden`,!x),o.innerHTML!==x&&(o.innerHTML=x)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}const{abs:G,log2:K,min:q,floor:J}=Math;function Y(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=G(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=K(n/t))}if(s!==void 0&&c!==void 0){let t=G(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=K(r/t))}let p=J(q(o+d,o+f));p!==o&&(e.zoom=p)}function X(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function Q(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function $(e){return Q(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?X(e):e}const ee=[.005,.018];function te(e,t=ee){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=$(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,y as addClickListener,w as addElement,E as addMovableViewport,D as addPersistence,O as addResizeObserver,P as addShape,F as addShapeEditor,U as addTiles,W as addZoomControls,r as eccentricityMap,Y as fitGeoBounds,Z as getCenter,X as getGeoBounds,b as getId,x as getLayer,_ as getPointerPosition,te as getVicinity,Q as isCoordsArray,S as resolveDynamic,$ as toGeoBounds,C as toPrecision};
|
package/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from "./src/MapArea/const.ts";
|
|
|
2
2
|
export * from "./src/MapArea/index.ts";
|
|
3
3
|
export * from "./src/plugins/addClickListener.ts";
|
|
4
4
|
export * from "./src/plugins/addElement.ts";
|
|
5
|
-
export * from "./src/plugins/
|
|
5
|
+
export * from "./src/plugins/addMovableViewport.ts";
|
|
6
6
|
export * from "./src/plugins/addPersistence.ts";
|
|
7
7
|
export * from "./src/plugins/addResizeObserver.ts";
|
|
8
8
|
export * from "./src/plugins/addShape.ts";
|
|
@@ -10,7 +10,7 @@ export * from "./src/plugins/addShapeEditor.ts";
|
|
|
10
10
|
export * from "./src/plugins/addTiles.ts";
|
|
11
11
|
export * from "./src/plugins/addZoomControls.ts";
|
|
12
12
|
export * from "./src/types/BoxDimensions.ts";
|
|
13
|
-
export * from "./src/types/
|
|
13
|
+
export * from "./src/types/Dynamic.ts";
|
|
14
14
|
export * from "./src/types/GeoBounds.ts";
|
|
15
15
|
export * from "./src/types/GeoCoords.ts";
|
|
16
16
|
export * from "./src/types/GeoVertex.ts";
|
|
@@ -20,12 +20,14 @@ export * from "./src/types/PixelCoords.ts";
|
|
|
20
20
|
export * from "./src/types/PixelVertex.ts";
|
|
21
21
|
export * from "./src/types/Projection.ts";
|
|
22
22
|
export * from "./src/types/ShapeLayerOptions.ts";
|
|
23
|
+
export * from "./src/utils/fitGeoBounds.ts";
|
|
23
24
|
export * from "./src/utils/getCenter.ts";
|
|
24
25
|
export * from "./src/utils/getGeoBounds.ts";
|
|
25
26
|
export * from "./src/utils/getId.ts";
|
|
26
27
|
export * from "./src/utils/getLayer.ts";
|
|
27
28
|
export * from "./src/utils/getPointerPosition.ts";
|
|
28
29
|
export * from "./src/utils/getVicinity.ts";
|
|
29
|
-
export * from "./src/utils/
|
|
30
|
-
export * from "./src/utils/
|
|
30
|
+
export * from "./src/utils/isCoordsArray.ts";
|
|
31
|
+
export * from "./src/utils/resolveDynamic.ts";
|
|
32
|
+
export * from "./src/utils/toGeoBounds.ts";
|
|
31
33
|
export * from "./src/utils/toPrecision.ts";
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "maparea",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./dist/index.cjs",
|
|
6
|
-
"module": "./dist/index.mjs",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"preversion": "npm run shape",
|
|
10
|
-
"shape": "npx codeshape --minify",
|
|
11
|
-
"start": "npx @t8/serve test --spa -b --watch"
|
|
12
|
-
},
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git://github.com/axtk/maparea.git"
|
|
16
|
-
},
|
|
17
|
-
"author": "axtk",
|
|
18
|
-
"license": "MIT"
|
|
19
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "maparea",
|
|
3
|
+
"version": "0.1.11",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"preversion": "npm run shape",
|
|
10
|
+
"shape": "npx codeshape --minify",
|
|
11
|
+
"start": "npx @t8/serve test --spa -b --watch"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git://github.com/axtk/maparea.git"
|
|
16
|
+
},
|
|
17
|
+
"author": "axtk",
|
|
18
|
+
"license": "MIT"
|
|
19
|
+
}
|