@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 3.96 kB
JavaScript
import{jsx as F}from"react/jsx-runtime";import"maplibre-gl/dist/maplibre-gl.css";import{prepareDebug as q,Renderer as H}from"@expofp/renderer";import{addProtocol as J,Map as V}from"maplibre-gl";import{Protocol as X}from"pmtiles";import{useEffect as T,useRef as l,useState as K}from"react";import{uiState as B}from"../../store";import{CollapsedAttributionControl as Q}from"./CollapsedAttributionControl.js";import{ExpofpLogoControl as $}from"./ExpofpLogoControl.js";import{registerPmtilesArchive as v}from"./utils/pmtiles-range-fallback";import{createStyleTransform as ee}from"./utils/resolve-map-style";const te='<a href="https://maplibre.org/" target="_blank">MapLibre</a>';export const MAP_DIM_LAYER_ID="expofp-map-dim";const p="expofp-map-dim-source",oe="3d-expofp";let y=null;const re=["coalesce",["get","name:en"],["get","name_en"],["get","name:latin"],["get","name"]],ne={type:"Feature",geometry:{type:"Polygon",coordinates:[[[-180,-85],[180,-85],[180,85],[-180,85],[-180,-85]]]},properties:{}};function z(e){if(!e||typeof e!="object")return!1;const o=e.length;if(typeof o!="number"||o<16)return!1;const r=e[0];return typeof r=="number"&&Number.isFinite(r)}function ie(e){if(z(e))return Array.from(e);const r=e?.defaultProjectionData?.mainMatrix;return z(r)?Array.from(r):(console.warn("Maplibre custom layer received an unsupported projection matrix payload.",e),null)}function g(e){return typeof e=="string"?e.includes("name"):Array.isArray(e)?e.some(o=>g(o)):!e||typeof e!="object"?!1:Object.values(e).some(o=>g(o))}function ae(e){return e.type!=="symbol"||!e.id||!e.layout?!1:g(e.layout["text-field"])}function se(e){const o=e.getStyle();for(const r of o.layers??[])ae(r)&&e.setLayoutProperty(r.id,"text-field",re)}function le(){if(y)return y;const e=new X;y=e;try{J("pmtiles",e.tile)}catch(o){console.warn("Maplibre PMTiles protocol registration failed.",o)}return e}export default function ce({sceneDef:e,geoConfig:o,tileSource:r,mapOptions:N,debug:b,onMapReady:h,onMapDimLayerReady:x,onMapLoadError:M,onPointerMissed:Z,children:U}){const P=l(null),[A,L]=K(),_=l(h),S=l(x),E=l(M),G=l({geoConfig:o,tileSource:r,mapOptions:N,debug:b});return T(()=>{_.current=h,S.current=x,E.current=M}),T(()=>{const j=P.current;if(!j)return;const{geoConfig:n,tileSource:c,mapOptions:f,debug:I}=G.current;let u=!1,R;const C=()=>{const W=le(),Y=n.bounds?{bounds:n.bounds,fitBoundsOptions:{padding:n.fitPadding,bearing:n.bearing}}:{center:n.center,zoom:n.zoom},w=ee(c.style,c.offline?i=>v(W,i):void 0,c.restyle),t=new V({container:j,...Y,bearing:n.bearing,maxPitch:f?.maxPitch,minZoom:f?.minZoom,maxZoom:f?.maxZoom,maxBounds:f?.maxBounds,attributionControl:!1,bearingSnap:0,aroundCenter:!1,pitchWithRotate:B.pitchEnabled,touchPitch:B.pitchEnabled,canvasContextAttributes:{antialias:!0}});t.addControl(new $),t.addControl(new Q(te)),n.zoomAdjustment&&t.jumpTo({zoom:t.getZoom()+n.zoomAdjustment}),t.once("error",i=>{t.isStyleLoaded()||E.current?.(i?.error??i)});const O=i=>{const a=i?.id;!a||t.hasImage(a)||t.addImage(a,{width:1,height:1,data:new Uint8Array(4)})};t.on("styleimagemissing",O);let d;const m=()=>t.triggerRepaint(),k={id:oe,type:"custom",renderingMode:"3d",onAdd(i,a){u||(L({gl:a,requestFrame:m,onFrame:s=>(d=s,m(),()=>{d===s&&(d=void 0)})}),_.current?.(t,m))},render(i,a){const s=ie(a??i);s&&d?.(s),I&&m()}},D=()=>{se(t),t.getSource(p)||t.addSource(p,{type:"geojson",data:ne}),t.getLayer(MAP_DIM_LAYER_ID)||t.addLayer({id:MAP_DIM_LAYER_ID,type:"fill",source:p,paint:{"fill-color":"#000000","fill-opacity":0,"fill-opacity-transition":{duration:0,delay:0}}}),S.current?.(t),t.addLayer(k)};t.on("style.load",D),t.setStyle(c.style,w?{transformStyle:w}:void 0),R=()=>{t.off("style.load",D),t.off("styleimagemissing",O),t.remove()}};return I?q().then(()=>{u||C()}):C(),()=>{u=!0,R?.(),L(void 0)}},[]),F("div",{ref:P,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%"},children:A&&F(H,{...A,scene:e,debug:b,onPointerMissed:Z,children:U})})}