maparea 0.1.2 → 0.1.4
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 +10 -7
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const{PI:e}=Math,t=e/180,n=180/e,r={sphM:0,WGS84:.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;_t=null;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??15}set zoom(e){this._p.zoom=e,this._t&&=(clearTimeout(this._t),null),this._t=setTimeout(()=>{this._t=null,delete this._cc,this.render()},150)}get projection(){return this._p.projection??`WGS84`}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(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 x(e){let t=0,n=0;b(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 S(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 C(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)}}function w(){return Math.random().toString(36).slice(2)}function T(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`#${t}`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.id=t??`layer-${w()}`,a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function E(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}const D=`http://www.w3.org/2000/svg`,O={className:`shape`};function k(e,t,n){let r=T(e,n??O);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(D,`svg`),i.setAttribute(`xmlns`,D),r.append(i));let a=j(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=E(n-t,3),d=E(o-r,3),f=E(.5*l.w+t-s,2),p=E(.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; left: ${f}px; top: ${p}px;`)}return r}function A(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function j(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(D,`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=E(s-i,3),f=E(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(D,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*A(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 M(e,t,n){let r={id:`shape-${w()}`,className:`shape`},i=t.map(e=>({id:w(),coords:e}));e.onRender(()=>{k(e,i,{...r,...n})})}function N(e,t){let n=[],r=null,i={id:`shape-editor-${w()}`,className:`shape-editor`,markers:!0},a=()=>{k(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:w(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}function P(e,t){return typeof t==`function`?t(e):t}const{floor:F,ceil:I}=Math,L=256;function R(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function z(e,t,n,{size:r=256,url:i,retries:a=0,error:o}){let s=new Image,c=0,l=(r,a)=>i?typeof i==`function`?i(e,t,n):i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(a)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang):``;return s.width=r,s.height=r,s.src=l(t,n),s.dataset.id=R(e,t,n),s.style=`position: absolute;`,s.onerror=()=>{c++;let{src:i}=s;if(!i||c>a){let t=P(e,o);t&&(s.onerror=()=>{},s.src=t);return}let u=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(u,d))[0],p=F(f/r);if(t!==p)s.src=l(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),s.src=e.href}},s}function B(e,t,{attribution:n,attributionInset:r=`auto 0 0 auto`}){let i=t.querySelector(`.attribution`),a=P(e,n);return a?(i||(i=document.createElement(`div`),i.className=`attribution`,i.style=`position: absolute; inset: ${r};`,t.append(i)),i.innerHTML!==a&&(i.innerHTML=a),i):(i&&i.remove(),null)}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=`tiles-${w()}`,className:r=`tiles`}=t,i=T(e,{id:n,className:r});return e.onRender(()=>{let n=B(e,i,t),{box:{w:r,h:a},centerCoords:[o,s]}=e,{size:c=256,margin:l=0}=t,u=Array.isArray(l)?l[0]:l,d=Array.isArray(l)?l[1]:l,f=I((r+2*u)/c),p=I((a+2*d)/c),m=F(o/c),h=F(s/c),g=null,_=new Set,v=``;for(let l=0;l<=f;l++){let u=m+(l%2==0?-1:1)*F(l/2);for(let l=0;l<=p;l++){let d=h+(l%2==0?-1:1)*F(l/2);v=R(e,u,d),g=H(i,v),g||(g=z(e,u,d,t),i.insertBefore(g,n));let f=.5*r+u*c-o,p=.5*a+d*c-s;g.style.left=`${E(f,2)}px`,g.style.top=`${E(p,2)}px`,_.add(v)}}for(let e of V(i)){let{id:t}=e.dataset;t&&!_.has(t)&&e.remove()}}),i}function W(e,t={}){let n=T(e,{className:`zoom-controls`,inset:`0 0 auto auto`}),{min:r,max:i,plus:a=`➕`,minus:o=`➖`}=t,s=document.createElement(`button`);s.dataset.id=`plus`,s.innerHTML=a;let c=document.createElement(`button`);c.dataset.id=`minus`,c.innerHTML=o;let l=()=>{i!==void 0&&s.toggleAttribute(`disabled`,e.zoom+1>i),r!==void 0&&c.toggleAttribute(`disabled`,e.zoom-1<r)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,l())}),e.onRender(l),n.append(s,c),n}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}}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.addNavigation=x,exports.addPersistence=S,exports.addResizeObserver=C,exports.addShape=M,exports.addShapeEditor=N,exports.addTiles=U,exports.addZoomControls=W,exports.eccentricityMap=r,exports.getBounds=G,exports.getCenter=K,exports.getId=w,exports.getLayer=T,exports.getVicinity=X,exports.isGeoCoords=q,exports.resolveString=P,exports.toPrecision=E;
|
|
1
|
+
const{PI:e}=Math,t=e/180,n=180/e,r={sphM:0,WGS84:.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??`WGS84`}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(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 x(e){let t=0,n=0;b(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 S(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 C(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)}}function w(){return Math.random().toString(36).slice(2)}function T(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`#${t}`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.id=t??`layer-${w()}`,a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function E(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}const D=`http://www.w3.org/2000/svg`,O={className:`shape`};function k(e,t,n){let r=T(e,n??O);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(D,`svg`),i.setAttribute(`xmlns`,D),r.append(i));let a=j(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=E(n-t,3),d=E(o-r,3),f=E(.5*l.w+t-s,2),p=E(.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 A(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function j(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(D,`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=E(s-i,3),f=E(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(D,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*A(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 M(e,t,n){let r={id:`shape-${w()}`,className:`shape`},i=t.map(e=>({id:w(),coords:e}));e.onRender(()=>{k(e,i,{...r,...n})})}function N(e,t){let n=[],r=null,i={id:`shape-editor-${w()}`,className:`shape-editor`,markers:!0},a=()=>{k(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:w(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}function P(e,t){return typeof t==`function`?t(e):t}const{floor:F,ceil:I,random:L}=Math,R=256;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=s.replaceAll(`{s}`,a[F(a.length*L())])),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=P(e,s);t&&(c.onerror=()=>{},c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=F(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,t,{attribution:n,attributionInset:r=`auto 0 0 auto`}){let i=t.querySelector(`.attribution`),a=P(e,n);return a?(i||(i=document.createElement(`div`),i.className=`attribution`,i.style=`position: absolute; inset: ${r};`,t.append(i)),i.innerHTML!==a&&(i.innerHTML=a),i):(i&&i.remove(),null)}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=`tiles-${w()}`,className:r=`tiles`}=t,i=T(e,{id:n,className:r}),a=()=>{let n=V(e,i,t),{box:{w:r,h:a},centerCoords:[o,s]}=e,{size:c=256,margin:l=0}=t,u=Array.isArray(l)?l[0]:l,d=Array.isArray(l)?l[1]:l,f=I((r+2*u)/c),p=I((a+2*d)/c),m=F(o/c),h=F(s/c),g=null,_=new Set,v=``;for(let l=0;l<=f;l++){let u=m+(l%2==0?-1:1)*F(l/2);for(let l=0;l<=p;l++){let d=h+(l%2==0?-1:1)*F(l/2);v=z(e,u,d),g=U(i,v),g||(g=B(e,u,d,t),i.insertBefore(g,n));let f=E(.5*r+u*c-o,2),p=E(.5*a+d*c-s,2);g.style.transform=`translate3d(${f}px, ${p}px, 0)`,_.add(v)}}for(let e of H(i)){let{id:t}=e.dataset;t&&!_.has(t)&&e.remove()}},o=e.zoom,s=null;return e.onRender(()=>{s!==null&&(clearTimeout(s),s=null),e.zoom===o?a():(i.style.opacity=`0`,s=setTimeout(()=>{s=null,i.style.opacity=``,a()},300)),o=e.zoom}),i}function G(e,t={}){let n=T(e,{className:`zoom-controls`,inset:`0 0 auto auto`}),{plus:r=`➕`,minus:i=`➖`}=t,a=document.createElement(`button`);a.dataset.id=`plus`,a.innerHTML=r;let o=document.createElement(`button`);o.dataset.id=`minus`,o.innerHTML=i;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.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,s())}),e.onRender(s),n.append(a,o),n}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.addNavigation=x,exports.addPersistence=S,exports.addResizeObserver=C,exports.addShape=M,exports.addShapeEditor=N,exports.addTiles=W,exports.addZoomControls=G,exports.eccentricityMap=r,exports.getBounds=K,exports.getCenter=q,exports.getId=w,exports.getLayer=T,exports.getVicinity=Z,exports.isGeoCoords=J,exports.resolveString=P,exports.toPrecision=E;
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,9 @@ type PixelCoords = [number, number];
|
|
|
29
29
|
type MapAreaOptions = {
|
|
30
30
|
container: string;
|
|
31
31
|
center?: GeoCoords;
|
|
32
|
-
zoom?: number;
|
|
32
|
+
zoom?: number;
|
|
33
|
+
minZoom?: number;
|
|
34
|
+
maxZoom?: number; /** Minimal and maximal latitudes and longitudes */
|
|
33
35
|
bounds?: GeoBounds;
|
|
34
36
|
projection?: Projection;
|
|
35
37
|
lang?: string;
|
|
@@ -44,8 +46,6 @@ declare class MapArea {
|
|
|
44
46
|
_cc: PixelCoords | undefined;
|
|
45
47
|
/** Render callbacks */
|
|
46
48
|
_r: Set<RenderCallback>;
|
|
47
|
-
/** Render timeout */
|
|
48
|
-
_t: ReturnType<typeof setTimeout> | null;
|
|
49
49
|
constructor(options: MapAreaOptions);
|
|
50
50
|
render(): void;
|
|
51
51
|
onRender(callback: RenderCallback, skipInitialCall?: boolean): () => void;
|
|
@@ -60,6 +60,10 @@ declare class MapArea {
|
|
|
60
60
|
get centerCoords(): PixelCoords;
|
|
61
61
|
get zoom(): number;
|
|
62
62
|
set zoom(value: number);
|
|
63
|
+
get minZoom(): number;
|
|
64
|
+
set minZoom(value: number);
|
|
65
|
+
get maxZoom(): number;
|
|
66
|
+
set maxZoom(value: number);
|
|
63
67
|
get projection(): Projection;
|
|
64
68
|
set projection(value: Projection);
|
|
65
69
|
get lang(): string;
|
|
@@ -147,7 +151,8 @@ type MapAreaTileOptions = LayerOptions & {
|
|
|
147
151
|
* tile indices, `{z}` for the zoom level, `{lang}` for the map language)
|
|
148
152
|
* or a function of `(map, x, y) => string` returning a fixed string URL.
|
|
149
153
|
*/
|
|
150
|
-
url?: string | ((map: MapArea, xIndex: number, yIndex: number) => string); /**
|
|
154
|
+
url?: string | ((map: MapArea, xIndex: number, yIndex: number) => string); /** Values of the `{s}` placeholder of the tile URLs. */
|
|
155
|
+
subdomains?: string[]; /** Maximum retry count per tile. */
|
|
151
156
|
retries?: number; /** URL to be used instead of a tile that failed to load. */
|
|
152
157
|
error?: DynamicString; /** Tile size. */
|
|
153
158
|
size?: number;
|
|
@@ -162,9 +167,7 @@ type MapAreaTileOptions = LayerOptions & {
|
|
|
162
167
|
declare function addTiles(map: MapArea, options?: MapAreaTileOptions): HTMLElement;
|
|
163
168
|
|
|
164
169
|
type ZoomControlOptions = {
|
|
165
|
-
/**
|
|
166
|
-
max?: number; /** HTML content of the zoom-in button */
|
|
167
|
-
plus?: string; /** HTML content of the zoom-out button */
|
|
170
|
+
/** HTML content of the zoom-in button */plus?: string; /** HTML content of the zoom-out button */
|
|
168
171
|
minus?: string;
|
|
169
172
|
};
|
|
170
173
|
declare function addZoomControls(map: MapArea, options?: ZoomControlOptions): HTMLElement;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const{PI:e}=Math,t=e/180,n=180/e,r={sphM:0,WGS84:.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;_t=null;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??15}set zoom(e){this._p.zoom=e,this._t&&=(clearTimeout(this._t),null),this._t=setTimeout(()=>{this._t=null,delete this._cc,this.render()},150)}get projection(){return this._p.projection??`WGS84`}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(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 x(e){let t=0,n=0;b(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 S(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 C(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)}}function w(){return Math.random().toString(36).slice(2)}function T(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`#${t}`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.id=t??`layer-${w()}`,a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function E(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}const D=`http://www.w3.org/2000/svg`,O={className:`shape`};function k(e,t,n){let r=T(e,n??O);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(D,`svg`),i.setAttribute(`xmlns`,D),r.append(i));let a=j(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=E(n-t,3),d=E(o-r,3),f=E(.5*l.w+t-s,2),p=E(.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; left: ${f}px; top: ${p}px;`)}return r}function A(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function j(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(D,`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=E(s-i,3),f=E(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(D,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*A(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 M(e,t,n){let r={id:`shape-${w()}`,className:`shape`},i=t.map(e=>({id:w(),coords:e}));e.onRender(()=>{k(e,i,{...r,...n})})}function N(e,t){let n=[],r=null,i={id:`shape-editor-${w()}`,className:`shape-editor`,markers:!0},a=()=>{k(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:w(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}function P(e,t){return typeof t==`function`?t(e):t}const{floor:F,ceil:I}=Math;function L(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function R(e,t,n,{size:r=256,url:i,retries:a=0,error:o}){let s=new Image,c=0,l=(r,a)=>i?typeof i==`function`?i(e,t,n):i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(a)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang):``;return s.width=r,s.height=r,s.src=l(t,n),s.dataset.id=L(e,t,n),s.style=`position: absolute;`,s.onerror=()=>{c++;let{src:i}=s;if(!i||c>a){let t=P(e,o);t&&(s.onerror=()=>{},s.src=t);return}let u=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(u,d))[0],p=F(f/r);if(t!==p)s.src=l(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),s.src=e.href}},s}function z(e,t,{attribution:n,attributionInset:r=`auto 0 0 auto`}){let i=t.querySelector(`.attribution`),a=P(e,n);return a?(i||(i=document.createElement(`div`),i.className=`attribution`,i.style=`position: absolute; inset: ${r};`,t.append(i)),i.innerHTML!==a&&(i.innerHTML=a),i):(i&&i.remove(),null)}function B(e){return e.querySelectorAll(`img[data-id]`)}function V(e,t){return e.querySelector(`img[data-id="${t}"]`)}function H(e,t={}){let{id:n=`tiles-${w()}`,className:r=`tiles`}=t,i=T(e,{id:n,className:r});return e.onRender(()=>{let n=z(e,i,t),{box:{w:r,h:a},centerCoords:[o,s]}=e,{size:c=256,margin:l=0}=t,u=Array.isArray(l)?l[0]:l,d=Array.isArray(l)?l[1]:l,f=I((r+2*u)/c),p=I((a+2*d)/c),m=F(o/c),h=F(s/c),g=null,_=new Set,v=``;for(let l=0;l<=f;l++){let u=m+(l%2==0?-1:1)*F(l/2);for(let l=0;l<=p;l++){let d=h+(l%2==0?-1:1)*F(l/2);v=L(e,u,d),g=V(i,v),g||(g=R(e,u,d,t),i.insertBefore(g,n));let f=.5*r+u*c-o,p=.5*a+d*c-s;g.style.left=`${E(f,2)}px`,g.style.top=`${E(p,2)}px`,_.add(v)}}for(let e of B(i)){let{id:t}=e.dataset;t&&!_.has(t)&&e.remove()}}),i}function U(e,t={}){let n=T(e,{className:`zoom-controls`,inset:`0 0 auto auto`}),{min:r,max:i,plus:a=`➕`,minus:o=`➖`}=t,s=document.createElement(`button`);s.dataset.id=`plus`,s.innerHTML=a;let c=document.createElement(`button`);c.dataset.id=`minus`,c.innerHTML=o;let l=()=>{i!==void 0&&s.toggleAttribute(`disabled`,e.zoom+1>i),r!==void 0&&c.toggleAttribute(`disabled`,e.zoom-1<r)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,l())}),e.onRender(l),n.append(s,c),n}function W(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 G(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=W(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function K(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}const q=[.005,.018];function J(e){return Array.isArray(e)?K(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:W(e):e}function Y(e,[t,n]=q){let{minLat:r=0,maxLat:i=0,minLon:a=0,maxLon:o=0}=J(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,x as addNavigation,S as addPersistence,C as addResizeObserver,M as addShape,N as addShapeEditor,H as addTiles,U as addZoomControls,r as eccentricityMap,W as getBounds,G as getCenter,w as getId,T as getLayer,Y as getVicinity,K as isGeoCoords,P as resolveString,E as toPrecision};
|
|
1
|
+
const{PI:e}=Math,t=e/180,n=180/e,r={sphM:0,WGS84:.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??`WGS84`}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(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 x(e){let t=0,n=0;b(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 S(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 C(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)}}function w(){return Math.random().toString(36).slice(2)}function T(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`#${t}`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.id=t??`layer-${w()}`,a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function E(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}const D=`http://www.w3.org/2000/svg`,O={className:`shape`};function k(e,t,n){let r=T(e,n??O);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(D,`svg`),i.setAttribute(`xmlns`,D),r.append(i));let a=j(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=E(n-t,3),d=E(o-r,3),f=E(.5*l.w+t-s,2),p=E(.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 A(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function j(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(D,`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=E(s-i,3),f=E(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(D,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*A(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 M(e,t,n){let r={id:`shape-${w()}`,className:`shape`},i=t.map(e=>({id:w(),coords:e}));e.onRender(()=>{k(e,i,{...r,...n})})}function N(e,t){let n=[],r=null,i={id:`shape-editor-${w()}`,className:`shape-editor`,markers:!0},a=()=>{k(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:w(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}function P(e,t){return typeof t==`function`?t(e):t}const{floor:F,ceil:I,random:L}=Math;function R(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function z(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=s.replaceAll(`{s}`,a[F(a.length*L())])),s};return c.width=r,c.height=r,c.src=u(t,n),c.dataset.id=R(e,t,n),c.style=`position: absolute;`,c.onerror=()=>{l++;let{src:i}=c;if(!i||l>o){let t=P(e,s);t&&(c.onerror=()=>{},c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=F(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 B(e,t,{attribution:n,attributionInset:r=`auto 0 0 auto`}){let i=t.querySelector(`.attribution`),a=P(e,n);return a?(i||(i=document.createElement(`div`),i.className=`attribution`,i.style=`position: absolute; inset: ${r};`,t.append(i)),i.innerHTML!==a&&(i.innerHTML=a),i):(i&&i.remove(),null)}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=`tiles-${w()}`,className:r=`tiles`}=t,i=T(e,{id:n,className:r}),a=()=>{let n=B(e,i,t),{box:{w:r,h:a},centerCoords:[o,s]}=e,{size:c=256,margin:l=0}=t,u=Array.isArray(l)?l[0]:l,d=Array.isArray(l)?l[1]:l,f=I((r+2*u)/c),p=I((a+2*d)/c),m=F(o/c),h=F(s/c),g=null,_=new Set,v=``;for(let l=0;l<=f;l++){let u=m+(l%2==0?-1:1)*F(l/2);for(let l=0;l<=p;l++){let d=h+(l%2==0?-1:1)*F(l/2);v=R(e,u,d),g=H(i,v),g||(g=z(e,u,d,t),i.insertBefore(g,n));let f=E(.5*r+u*c-o,2),p=E(.5*a+d*c-s,2);g.style.transform=`translate3d(${f}px, ${p}px, 0)`,_.add(v)}}for(let e of V(i)){let{id:t}=e.dataset;t&&!_.has(t)&&e.remove()}},o=e.zoom,s=null;return e.onRender(()=>{s!==null&&(clearTimeout(s),s=null),e.zoom===o?a():(i.style.opacity=`0`,s=setTimeout(()=>{s=null,i.style.opacity=``,a()},300)),o=e.zoom}),i}function W(e,t={}){let n=T(e,{className:`zoom-controls`,inset:`0 0 auto auto`}),{plus:r=`➕`,minus:i=`➖`}=t,a=document.createElement(`button`);a.dataset.id=`plus`,a.innerHTML=r;let o=document.createElement(`button`);o.dataset.id=`minus`,o.innerHTML=i;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.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,s())}),e.onRender(s),n.append(a,o),n}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,x as addNavigation,S as addPersistence,C as addResizeObserver,M as addShape,N as addShapeEditor,U as addTiles,W as addZoomControls,r as eccentricityMap,G as getBounds,K as getCenter,w as getId,T as getLayer,X as getVicinity,q as isGeoCoords,P as resolveString,E as toPrecision};
|