UNPKG

react-map-gl

Version:

React components for MapLibre GL JS and Mapbox GL JS

111 lines (100 loc) 2.97 kB
import type {MapInstance} from '../types/lib'; import type {MapInstanceInternal} from '../types/internal'; import {LngLatLike, PointLike} from '../types/common'; import type Mapbox from './mapbox'; /** These methods may break the react binding if called directly */ const skipMethods = [ 'setMaxBounds', 'setMinZoom', 'setMaxZoom', 'setMinPitch', 'setMaxPitch', 'setRenderWorldCopies', 'setProjection', 'setStyle', 'addSource', 'removeSource', 'addLayer', 'removeLayer', 'setLayerZoomRange', 'setFilter', 'setPaintProperty', 'setLayoutProperty', 'setLight', 'setTerrain', 'setFog', 'remove' ] as const; export type MapRef = { getMap(): MapInstance; } & Omit<MapInstance, (typeof skipMethods)[number]>; export default function createRef(mapInstance: Mapbox): MapRef | null { if (!mapInstance) { return null; } const map = mapInstance.map as MapInstanceInternal; const ref: any = { getMap: () => mapInstance.map, // Overwrite getters to use our shadow transform getCenter: () => mapInstance.transform.center, getZoom: () => mapInstance.transform.zoom, getBearing: () => mapInstance.transform.bearing, getPitch: () => mapInstance.transform.pitch, getPadding: () => mapInstance.transform.padding, getBounds: () => mapInstance.transform.getBounds(), project: (lnglat: LngLatLike) => { const tr = map.transform; map.transform = mapInstance.transform; const result = map.project(lnglat); map.transform = tr; return result; }, unproject: (point: PointLike) => { const tr = map.transform; map.transform = mapInstance.transform; const result = map.unproject(point); map.transform = tr; return result; }, // options diverge between mapbox and maplibre queryTerrainElevation: (lnglat: LngLatLike, options?: any) => { const tr = map.transform; map.transform = mapInstance.transform; const result = map.queryTerrainElevation(lnglat, options); map.transform = tr; return result; }, queryRenderedFeatures: (geometry?: any, options?: any) => { const tr = map.transform; map.transform = mapInstance.transform; const result = map.queryRenderedFeatures(geometry, options); map.transform = tr; return result; } }; for (const key of getMethodNames(map)) { // @ts-expect-error if (!(key in ref) && !skipMethods.includes(key)) { ref[key] = map[key].bind(map); } } return ref; } function getMethodNames(obj: Object) { const result = new Set<string>(); let proto = obj; while (proto) { for (const key of Object.getOwnPropertyNames(proto)) { if ( key[0] !== '_' && typeof obj[key] === 'function' && key !== 'fire' && key !== 'setEventedParent' ) { result.add(key); } } proto = Object.getPrototypeOf(proto); } return Array.from(result); }