【问题标题】:Centralize google map issue集中谷歌地图问题
【发布时间】:2021-10-13 00:44:06
【问题描述】:

import React, {
  useState
} from "react";

import GoogleMapReact from "google-map-react";

function GMap() {
  const [latLgn, setLatLgn] = useState([{
      lng: 24.7536,
      lat: 59.437
    },
    {
      lng: 24.7303,
      lat: 59.4393
    },
    {
      lng: 24.7387,
      lat: 59.4497
    },
  ]);
  const [tallinn] = useState({
    center: { // where i want to be centerd
      lng: 24.7536,
      lat: 59.437,
    },
    zoom: 10,
  });



  // Fit map to its bounds after the api is loaded
  const apiIsLoaded = (map, maps, latlgn) => {
    // Get bounds by our latlgn
    const bounds = getMapBounds(map, maps, latlgn);
    // Fit map to bounds
    map.fitBounds(bounds);
    // Bind the resize listener
    bindResizeListener(map, maps, bounds);
  };

  // Re-center map when resizing the window
  const bindResizeListener = (map, maps, bounds) => {
    maps.event.addDomListenerOnce(map, "idle", () => {
      maps.event.addDomListener(window, "resize", () => {
        map.fitBounds(bounds);
      });
    });
  };

  // Return map bounds based on list of places
  const getMapBounds = (map, maps, pins) => {
    const bounds = new maps.LatLngBounds();

    pins.forEach((pin) => {
      bounds.extend(new maps.LatLng(pin[1], pin[0]));
    });
    return bounds;
  };

  return ( <
    div >
    <
    div style = {
      {
        height: "100vh",
        width: "100%"
      }
    } >
    <
    GoogleMapReact bootstrapURLKeys = {
      {
        key: AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk
      }
    }
    defaultCenter = {
      tallinn.center
    }
    defaultZoom = {
      tallinn.zoom
    }
    onGoogleApiLoaded = {
      ({
        map,
        maps
      }) => apiIsLoaded(map, maps, latLgn)
    }
    yesIWantToUseGoogleMapApiInternals >
    {
      latLgn.map((item, index) => ( <
        div lat = {
          item[1]
        }
        lng = {
          item[0]
        }
        key = {
          index
        } > 
        </div>
      ))
    } </GoogleMapReact>
    </div> 
    </div>
  );
}
export default Gmap
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


我在集中正在渲染的地图时遇到问题。
尽管我仍然有docs 中所述的“lat”和“lng”状态,但当我使用 npm start 运行应用程序或刷新页面时,它会在海洋中的某个地方居中。\

PS。我将只粘贴我的“地图”组件。

import React, { useState } from "react";

import GoogleMapReact from "google-map-react";

export default function GMap() {
  const [latLgn, setLatLgn] = useState([{
      lng: 24.7536,
      lat: 59.437
    },
    {
      lng: 24.7303,
      lat: 59.4393
    },
    {
      lng: 24.7387,
      lat: 59.4497
    },
  ]);
  const [tallinn] = useState({
    center: { // where i want to be centerd
      lng: 24.7536,
      lat: 59.437,
    },
    zoom: 10,
  });

 

  // Fit map to its bounds after the api is loaded
  const apiIsLoaded = (map, maps, latlgn) => {
    // Get bounds by our latlgn
    const bounds = getMapBounds(map, maps, latlgn);
    // Fit map to bounds
    map.fitBounds(bounds);
    // Bind the resize listener
    bindResizeListener(map, maps, bounds);
  };

  // Re-center map when resizing the window
  const bindResizeListener = (map, maps, bounds) => {
    maps.event.addDomListenerOnce(map, "idle", () => {
      maps.event.addDomListener(window, "resize", () => {
        map.fitBounds(bounds);
      });
    });
  };

  // Return map bounds based on list of places
  const getMapBounds = (map, maps, pins) => {
    const bounds = new maps.LatLngBounds();

    pins.forEach((pin) => {
      bounds.extend(new maps.LatLng(pin[1], pin[0]));
    });
    return bounds;
  };

  return (
    <div>
      <div style={{ height: "100vh", width: "100%" }}>
        <GoogleMapReact
          bootstrapURLKeys={{key: AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk }}
          defaultCenter={tallinn.center}
          defaultZoom={tallinn.zoom}
          onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, latLgn)}
          yesIWantToUseGoogleMapApiInternals
        >
          {latLgn.map((item, index) => (
            <div lat={item[1]} lng={item[0]} key={index}< </div>
          ))}
        </GoogleMapReact>
      </div>
    </div>
  );
}

ps。如果我应该提供更多信息,请告诉我

更新

我创建了一个示例项目here

【问题讨论】:

  • 请提供一个minimal reproducible example 来证明您的问题,最好在问题本身中提供一个有效的StackSnippet
  • @geocodezip,感谢您的回复。如何在不公开分享我的 google API 密钥的情况下制作有效的 stackSnippet?
  • 将 API 密钥设为 .env 变量(如果您不确定,请关注 create-react-app.dev/docs/adding-custom-environment-variables)并进行复制,您可以像 @geocodezip 提到的那样共享为 StackSnippet,这样我们就可以看到运行时间/预览您正在尝试的内容
  • @harry9345 有一个可用的 Google 测试密钥,适用于 StackOverflow AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk(适用于 Google Maps Javascript API v3)
  • @geocodezip,我创建了 stackbiltz 项目。请看一下

标签: reactjs google-maps react-google-maps


【解决方案1】:

我检查了你的代码,发现了几件事。

首先,在您的getMapBounds 函数中,返回的边界为空。这是因为pin[1]pin[0] 的值是undefined。这可能是地图以this 为中心的原因,因为这是世界的中心,坐标为0,0。您必须改用pin.latpin.lng,这样它才能正确填充边界值。

其次,您似乎想在latLgn 的坐标上添加标记。要实现这一点,您可以按照 google-map-react 文档中提到的 AnyReactComponent 函数,而不是将 div 直接放在 latLgn.map 中。

最后,在您的latLgn.map 中,您不能使用item[1]item[0],因为它们也是undefined,而是使用item.latitem.lng

这是我的working code 的代码 sn-p:

import React, { useState } from "react";
import "./style.css"
import GoogleMapReact from "google-map-react";

const AnyReactComponent = ({ text }) => <div>{text}</div>;
export default function GMap() {
  const [latLgn, setLatLgn] = useState([{
      lng: 24.7536,
      lat: 59.437
    },
    {
      lng: 24.7303,
      lat: 59.4393
    },
    {
      lng: 24.7387,
      lat: 59.4497
    },
  ]);
  const [tallinn] = useState({
    center: { // where i want to be centerd
      lng: 24.7536,
      lat: 59.437,
    },
    zoom: 10,
  });

 

  // Fit map to its bounds after the api is loaded
  const apiIsLoaded = (map, maps, latlgn) => {
    // Get bounds by our latlgn
    const bounds = getMapBounds(map, maps, latlgn);
    // Fit map to bounds
    map.fitBounds(bounds);
    // Bind the resize listener
    bindResizeListener(map, maps, bounds);
  };

  // Re-center map when resizing the window
  const bindResizeListener = (map, maps, bounds) => {
    maps.event.addDomListenerOnce(map, "idle", () => {
      maps.event.addDomListener(window, "resize", () => {
        map.fitBounds(bounds);
      });
    });
  };

  // Return map bounds based on list of places
  const getMapBounds = (map, maps, pins) => {
    const bounds = new maps.LatLngBounds();

    pins.forEach((pin) => {
      bounds.extend(new maps.LatLng(pin.lat, pin.lng));
      console.log(pin[0])
    });
    return bounds;
  };

  return (
    <div>
      <div style={{ height: "100vh", width: "100%" }}>
        <GoogleMapReact
          bootstrapURLKeys={{key: "YOUR_API_KEY" }}
          defaultCenter={tallinn.center}
          defaultZoom={tallinn.zoom}
          onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps, latLgn)}
          yesIWantToUseGoogleMapApiInternals
        >
        {latLgn.map((item, index) => (
            <AnyReactComponent lat={item.lat} lng={item.lng} key={index} text={"(" +item.lat  + "," + item.lng +")"}> </AnyReactComponent>
          ))}
        </GoogleMapReact>
      </div>
    </div>
  );
}

我还在评论部分注意到了您的问题。您可以使用stackblitz 之类的在线 IDE 提供您的代码的 sscce,然后删除 API 密钥。您可以在问题中添加注释,说明您需要输入 API 密钥以查看代码的工作方式。你可以参考我上面的工作代码。

【讨论】:

  • 非常感谢。首先,我更新了问题,您可以查看 stackbiltz 项目以获取更多信息。关于你的观点:关于“pin.lat 和 pin.lng”,因为我没有将所有代码移到这里,所以我对状态进行硬编码,否则来自 API 的数据是一个对象数组,而 lat 和 lng 在该对象中的数组(请查看stackbilts)。我在这里使用的 div 只是为了显示。在现实生活中,它是一个组件。您对“item.lat 和 item.lng”的建议。也不行。请看一下我在 stackblitz 创建的项目
  • @harry9345,我似乎在您的代码中发现了问题。看来问题在于您的props 的人口时间。在代码的 App.js 中,您每 5 秒获取一次数据,它将填充道具,然后您在 apiIsLoaded 中设置边界(getMapBounds)。但是,问题在于latLgn 在触发 apiIsLoaded 函数时仍然为空。在 getMapBounds 中实例化边界后的初始值是 {south: 1, west: 180, north: -1, east: -180…} 并且由于引脚值是 [] 在 bounds.extend 之后它不会改变。
  • @harry9345 继续:回到 apiIsLoaded 函数,它将通过的边界将是 {south: 1, west: 180, north: -1, east: -180…},如果你在这个边界值上使用 map.fitBounds,它会将地图的中心设置为{lat: 0, lng: 180} 位于 ocean 的中间。当 latLgn 已经被道具填充时,您需要找到一种调用 getMapBounds 的方法,以便它将传递坐标而不是 []。
  • 非常感谢@Pagemag 的帮助,我明白了你在说什么,我会尝试修复它,否则我会再次寻求帮助。
  • 我接受你的答案是正确的,因为我想出了解决这个问题的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 2011-10-26
  • 2012-03-15
  • 2014-04-05
  • 1970-01-01
  • 2011-12-26
相关资源
最近更新 更多