Mapbox 标记在缩放/平移时移动到错误的位置

问题描述

目前,我正在显示地图的单个副本。在图形边缘平移或从改变位置的制造商进一步缩小时。即使完成了这些操作,我也想让标记保持在它们的位置,我该如何实现。

codesanBox - https://codesandbox.io/s/mapbox-marker-issue-03cdc

index.js

import "mapBox-gl/dist/mapBox-gl.css";
import "react-map-gl-geocoder/dist/mapBox-gl-geocoder.css";
import React,{ useState,useRef,useCallback } from "react";
import { render } from "react-dom";
import MapGL from "react-map-gl";
import Pins from "./pins";

import CITIES from "./cities.json";
const MAPBox_TOKEN =
  "pk.eyJ1Ijoic21peWFrYXdhIiwiYSI6ImNqcGM0d3U4bTB6dWwzcW04ZHRsbHl0ZWoifQ.X9cvdajtPbs9JDMG-CmdsA";

const App = () => {
  const [viewport,setViewport] = useState({
    latitude: 37.7577,longitude: -122.4376,zoom: 8
  });
  const mapRef = useRef();
  const handleViewportChange = useCallback(
    (newViewport) => setViewport(newViewport),[]
  );

  return (
    <div style={{ height: "100vh" }}>
      <MapGL
        ref={mapRef}
        {...viewport}
        width="90vw"
        height="90vh"
        onViewportChange={handleViewportChange}
        mapBoxApiAccesstoken={MAPBox_TOKEN}
        mapOptions={{
          renderWorldcopies: false,maxBounds: [
            [-180,-90],// Southwest coordinates
            [180,90] // northeast coordinates
          ]
        }}
      >
        <Pins data={CITIES} onClick={() => {}} />
      </MapGL>
    </div>
  );
};

render(<App />,document.getElementById("root"));

pins.js

import * as React from "react";
import { Marker } from "react-map-gl";

const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,0.6,3.9,1.6,5.4c0,0.1,0.2,0.3
  c0,0.2c0.2,0.3,0.4,0.7,0.9c2.6,3.1,7.4,7.6,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9
  C20.1,15.8,20.2,15.7z`;

const SIZE = 20;

// Important for perf: the markers never change,avoid rerender when the map viewport changes
function Pins(props) {
  const { data,onClick } = props;

  return data.map((city,index) => (
    <Marker
      key={`marker-${index}`}
      longitude={city.longitude}
      latitude={city.latitude}
    >
      <svg
        height={SIZE}
        viewBox="0 0 24 24"
        style={{
          cursor: "pointer",fill: "#d00",stroke: "none",transform: `translate(${-SIZE / 2}px,${-SIZE}px)`
        }}
      >
        <path d={ICON} />
      </svg>
    </Marker>
  ));
}

export default React.memo(Pins);

数据 - https://github.com/visgl/react-map-gl/raw/master/examples/.data/cities.json

解决方法

您遇到了 react-map-gl 的限制:https://github.com/visgl/react-map-gl/issues/786

您不能使用 maxBounds,因为 react-map-gl 没有使用 mapbox-gl-js 的内置交互处理逻辑。要限制地图边界,您应该执行类似

_onViewportChange = (viewport) => {
  const oldViewport = this.state.viewport;
  if (Math.abs(oldViewport.longitude - viewport.longitude) > 180) {
    // wrapped around the 180th meridian
    return;
  }
  this.setState({viewport});
}

作为一种解决方法,您可以删除设置 maxBoundsrenderWorldCopies。或者按照该线程中的建议进行操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...