UNPKG

@expofp/floorplan

Version:

Interactive floor plan library for expos and events

2 lines (1 loc) • 4.1 kB
import{LngLatBounds as A,MercatorCoordinate as S}from"maplibre-gl";import{getFpGeo as C}from"../../../data/fpGeo.js";import{getSvgArea as D}from"../../../data/svg.js";import{uiState as v}from"../../../store";import{convertLocalToGps as x}from"../../../utils/gps";import{planBearing as N}from"../../../utils/planBearing";import{framingRect as R}from"../../Map/framing-rect.js";export const MAP_BOUNDS_PADDING_FACTOR=3,MAP_BOUNDS_MIN_PADDING_DEGREES=.02,INITIAL_FIT_ZOOM_ADJUSTMENT=.15;const b=1.42,O=.35,d=.9,B=.85,w=8,U=.05;export function deriveVenueMapBounds(t){const n=D(),o=[[n.min.x,n.min.y],[n.max.x,n.min.y],[n.max.x,n.max.y],[n.min.x,n.max.y]].map(([c,l])=>x(c,l,t));if(!o.every(([c,l])=>Number.isFinite(c)&&Number.isFinite(l)))return;const i=o.map(([c])=>c),e=o.map(([,c])=>c),s=Math.min(...i),r=Math.max(...i),a=Math.min(...e),m=Math.max(...e),h=Math.max((r-s)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES),u=Math.max((m-a)*MAP_BOUNDS_PADDING_FACTOR,MAP_BOUNDS_MIN_PADDING_DEGREES);return[[s-h,a-u],[r+h,m+u]]}function E(t,n,o,i){const e=Math.min(t.getZoom(),n),s=(o-e)*Math.min(1,i/b);return e+s>=t.getMinZoom()-U}function V(t,n,o){if(E(t,n,o,b))return b;if(!E(t,n,o,O))return null;let i=O,e=b;for(let s=0;s<w;s++){const r=(i+e)/2;E(t,n,o,r)?i=r:e=r}return i}export function getLocalRectGeoBounds(t,n){const o=[x(t.min.x,t.min.y,n),x(t.max.x,t.min.y,n),x(t.max.x,t.max.y,n),x(t.min.x,t.max.y,n)],i=o.map(([s])=>s),e=o.map(([,s])=>s);return[[Math.min(...i),Math.min(...e)],[Math.max(...i),Math.max(...e)]]}const I=512;export function cameraForLocalRect(t,n,o,i,e){const s=[x(t.min.x,t.min.y,n),x(t.max.x,t.min.y,n),x(t.max.x,t.max.y,n),x(t.min.x,t.max.y,n)].map(([g,p])=>S.fromLngLat({lng:g,lat:p}));if(!s.every(({x:g,y:p})=>Number.isFinite(g)&&Number.isFinite(p)))return null;const r=-o*Math.PI/180,a=Math.cos(r),m=Math.sin(r),h=s.map(({x:g,y:p})=>g*a-p*m),u=s.map(({x:g,y:p})=>g*m+p*a),c=Math.max(...h)-Math.min(...h),l=Math.max(...u)-Math.min(...u);if(c<=0||l<=0)return null;const y=i.width-e.left-e.right,f=i.height-e.top-e.bottom;if(y<=0||f<=0)return null;const L=Math.min(y/(c*I),f/(l*I));if(!(L>0))return null;const M=I*L,_=(Math.min(...h)+Math.max(...h))/2-(e.left-e.right)/2/M,T=(Math.min(...u)+Math.max(...u))/2-(e.top-e.bottom)/2/M,{lng:F,lat:z}=new S(_*a+T*m,-_*m+T*a).toLngLat();return{center:[F,z],zoom:Math.log2(L)}}export function getVisibleRectFitPadding(t=0,n=v.canvasVisibleRectPx){const o=v.screenSize;return n?{top:Math.max(0,n.min.y)+t,bottom:Math.max(0,o.height-n.max.y)+t,left:Math.max(0,n.min.x)+t,right:Math.max(0,o.width-n.max.x)+t}:{top:t,bottom:t,left:t,right:t}}export function isLngLatInVisibleViewport(t,n,o){const i=t.project(n),e=t.getCanvas();return i.x>=o.left&&i.x<=e.clientWidth-o.right&&i.y>=o.top&&i.y<=e.clientHeight-o.bottom}export function deriveGeoConfig(){const t=C()?.properties?.config;if(!t)return null;const n=(t.p0.lng+t.p2.lng)/2,o=(t.p0.lat+t.p2.lat)/2,i=N(t.p0,t.p2),e=Number.isFinite(i)?i:t.bearing??0;return{center:[n,o],bearing:e,zoom:16,gpsConfig:t}}export function fitMapToLocalRect(t,n,o,i={}){if(!t||!n||!o||n.size.height===1/0||n.size.width===1/0||n.size.height<=0||n.size.width<=0)return;const e=getLocalRectGeoBounds(n,o.gpsConfig),s=t.getCanvas(),r=getVisibleRectFitPadding(i.padding??50,R()),a=cameraForLocalRect(n,o.gpsConfig,o.bearing,{width:s.clientWidth,height:s.clientHeight},r);if(!a){t.fitBounds(e,{padding:r,bearing:o.bearing,essential:!0});return}const m=t.project(t.getCenter()),h=t.project(a.center),u=Math.max(t.getCanvas().clientWidth,t.getCanvas().clientHeight,1),c=Math.hypot(h.x-m.x,h.y-m.y)/u,l=Math.abs(t.getZoom()-a.zoom),y=i.duration??Math.min(2800,500+c*450+l*150),f={center:a.center,zoom:a.zoom,bearing:o.bearing,duration:y,essential:!0};if(c<=1.2&&l<=1.5){t.easeTo(f);return}const L=t.getBounds().extend(A.convert(e)),M=t.cameraForBounds(L,{padding:r,bearing:o.bearing});if(!M?.center||typeof M.zoom!="number"||M.zoom>=t.getZoom()-.2){t.easeTo(f);return}const _=V(t,a.zoom,M.zoom);if(_!==null){const T=Math.max(O,_*d),F=Math.round(y*B);t.flyTo({...f,curve:T,duration:F});return}t.easeTo(f)}