【问题标题】:Want to Update the Center of MapContainer of React-Leaflet-js想要更新 React-Leaflet-js 的 MapContainer 的中心
【发布时间】:2020-12-19 02:09:58
【问题描述】:

我最近开始使用 React。但是当我开始 React-Leaflet Map 时,我遇到了问题。我有一个所有国家的 Json 文件,我只想放大我选择的那个国家。但我不知道我该怎么做?

function Map({ center, zoom }) {
    return (
        <div className="map">
            <MapContainer center={center} zoom={zoom} scrollWheelZoom={true}>
                <TileLayer attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
            </MapContainer>
        </div>
    )
}

这是我的 Map.js 文件,我已将其导入我的 App.js 文件并使用 useState 方法为其提供数据。

【问题讨论】:

  • 你能给我们看一个json的例子吗?它实际上包含地理信息吗?你是什​​么意思国家被“选中”?
  • [link](disease.sh/docs/#/COVID-19%3A%20Worldometers/… ) 您可以在此处查看 json 文件。实际上,我有一个下拉菜单,我在其中选择国家/地区的字符串名称作为输入,并在国家/地区的纬度和经度旁边获取整个列表。所以我想要一种方法让 mapcontaine 以该经纬度为中心。

标签: javascript reactjs react-leaflet


【解决方案1】:

因此传单定位(与大多数网络地图库一样)适用于纬度和经度。您在评论中引用的 API 将国家名称作为参数,并返回一些 COVID 数据。为了让您的地图做出适当响应,您需要对国家/地区名称进行地理编码。快速搜索找到了这个包含县名和国家中心latlng 的repo:https://github.com/eesur/country-codes-lat-long

那里引用的json文件有以下格式的数据:

{
  "country" : "Albania",
  "alpha2" : "AL",
  "alpha3" : "ALB",
  "numeric" : 8,
  "latitude" : 41,
  "longitude" : 20
}

为简单起见,假设我们下载该文件,将其重命名为 .js,然后导入内容。现在您拥有所有可用的数据。

您的代码未显示您在哪里进行 API 调用以获取您的 COVID 数据。但是假设有一个函数你称之为状态变量selectedCountry。您可以拥有一个响应该状态变量的useEffect

import countrycodes from './country-codes-lat-long-alpha3.js'

function App() {

  const [selected, setSelected] = useState("")
  const [center, setCenter] = useState([55, 122]) // some initial state

  // Call this effect whenever selected changes
  // (assuming the value of selected is an alpha3 3 character country code)
  useEffect(() => {
    if (selected){
      fetch(`/v3/covid-19/countries/${selected}`)
        .then(res => {
          // do something with your response data
          // set the map center to the lat lng defined by the reference json
          const countryData = countrycodes.ref_country_codes.filter(country => 
            country.alpha3 === selected
          )[0]
          const countryLatLng = {
            lat: countryData.latitude,
            lng: countryData.longitude,
          }
          setCenter(countryLatLng)
        })
    }
  }, [selected])
  

  return (
    <div>
      <Map center={center} />
      <select onChange={() => setSelected(e.target.value}>
        {a_bunch_of_country_options}
      </select>
    <div>
  )
}

总而言之,您的&lt;select&gt; 元素将设置selected 状态变量。当selected 发生变化时,它会触发useEffect,它会调用你的api 并对数据做任何你想做的事情。当数据返回时,效果会检查参考数据以获取所选国家/地区的latlng。 setCenter 然后将状态变量 center 设置为传递给地图的 latlng。地图应通过调整其中心来做出响应。

这只是您如何实现目标的基本概述。我所写的主要问题是它只设置了地图的 center。可能您正在寻找的效果是设置地图视图以显示国家/地区。为此,您不仅需要该国家/地区的中心latlng,还需要所选国家/地区的整个LatLngBounds。获取这种数据并不是那么简单。查看 GIS 堆栈交换中的 this thread 获取该数据。

假设您能够获得一个数据源,该数据源可以根据国家/地区名称或 2/3 字母代码为您提供国家/地区的边界。例如:

[
  {
    "country" : "Albania",
    "alpha2" : "AL",
    "alpha3" : "ALB",
    bounds: [ // made up
      {
        lat: 40.712, 
        lng: -74.227
      },
      {
        lat: 42.712, 
        lng: -72.227
      },  
  }
  ... // all the other countries
]

You can use the same method I described above, but instead of doing 

```javascript
const [center, setCenter] = useState(initialCenter)

你会的

const [bounds, setBounds] = useState()

然后你可以在你的useEffect中设置MapContainerbounds属性:


  const [bounds, setBounds] = useState()

  useEffect(() => {
    if (selected){
      fetch(`/v3/covid-19/countries/${selected}`)
        .then(res => {
          const countryData = countrycodes.ref_country_codes.filter(country => 
            country.alpha3 === selected
          )[0]
          setBounds(country.bounds)
        })
    }
  }, [selected])
  

  return (
    <div>
      <Map center={someInitialCenter} bounds={bounds} />
      ...
    <div>
  )

这将产生这样的效果:一旦用户选择下拉菜单,地图就会适合国家/地区的边界,并且国家/地区在框架中。当然,您需要正确的数据源,而发现这本身就是一项超出您问题范围的任务。

总之,leaflet 或 react-leaflet 没有任何内置功能可以仅根据国家名称在地图上找到正确的坐标。您需要一种根据国家名称对国家坐标进行地理编码的方法,然后在地图中加以利用。希望这能让你开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 2021-02-20
    • 2021-03-04
    • 2022-09-29
    相关资源
    最近更新 更多