jtwang7 / Project-Note

开发小记 - 项目里的一些新奇玩意儿
1 stars 0 forks source link

mapbox 地图方法 #17

Open jtwang7 opened 1 year ago

jtwang7 commented 1 year ago

mapbox 地图方法

mapbox 地图自适应缩放比例

function mapboxFitBounds(
  coordinates: [number, number][],
  mapInstance: mapboxgl.Map,
  options: mapboxgl.FitBoundsOptions = {
    padding: 50,
  }
) {
  // Create a 'LngLatBounds' with both corners at the first coordinate.
  const bounds = new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]);
  // Extend the 'LngLatBounds' to include every coordinate in the bounds result.
  for (const coord of coordinates) {
    bounds.extend(coord);
  }
  mapInstance.fitBounds(bounds, options);
}

mapbox 多余 label 标签移除

function removeExtraLabel(instance: mapboxgl.Map) {
  const layers = instance.getStyle().layers;
  if (layers) {
    for (let i = 0; i < layers.length; i++) {
      if (/-label$/.test(layers[i].id)) {
        instance.removeLayer(layers[i].id);
      }
    }
  }
}

deck.gl based on mapbox (react) 地图视野自适应

react component logic

const INITIAL_VIEW_STATE = {
    longitude: -122.41669,
    latitude: 37.7853,
    zoom: 13,
    pitch: 50,
    bearing: 0,
  };
const [viewState, setViewState] = useState(INITIAL_VIEW_STATE);

// 自适应视野
const viewport = new WebMercatorViewport({ width: 200, height: 200 });
const coordinates: [number, number][] = ods.reduce((res, odPair) => {
  res.push(odPair.from.coordinates);
  res.push(odPair.to.coordinates);
  return res;
}, []);
const lngs = coordinates.map((p) => p[0]);
const lats = coordinates.map((p: any) => p[1]);
const [minLng, minLat, maxLng, maxLat] = [
  _.min(lngs)!,
  _.min(lats)!,
  _.max(lngs)!,
  _.max(lats)!,
];
const { longitude, latitude, zoom } = viewport.fitBounds(
  [
    [minLng, minLat],
    [maxLng, maxLat],
  ],
  { padding: 20 }
);
setViewState((state) => ({
  ...state,
  longitude,
  latitude,
  zoom,
}));

JSX

<DeckGL
  initialViewState={INITIAL_VIEW_STATE}
  viewState={viewState}
  layers={[arclayer]}
  width={200}
  height={200}
  style={{ position: "relative" }}
  controller={true}
>
  <StaticMap
    ref={mapboxRef}
    mapboxAccessToken={mapboxAccessToken}
    mapStyle="mapbox://styles/mapbox/light-v11"
    onLoad={onMapboxLoad}
  />
</DeckGL>

WebMercatorViewport 的内置宽度需和 <DeckGL /> 内置宽度一致