如何将 React 与 Google Places API 结合使用,在 Google 地图上显示地点标记?

2024-02-29

我正在尝试构建一个类似的地图,您可以在拖动地图时查看地点标记。我想在地图上显示来自 Google Places API 的“酒店”标记。

使用以下 JavaScript 代码谷歌地图 https://developers.google.com/maps/documentation/javascript/examples/place-search,我可以在 Google 地图上显示酒店,但我想用 React 来做到这一点,使用反应谷歌地图 https://github.com/tomchentw/react-google-maps.

<!DOCTYPE html>
<html>
  <head>
    <title>Place searches</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
    <script>
      // This example requires the Places library. Include the libraries=places
      // parameter when you first load the API. For example:
      // <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">

      var map;
      var infowindow;

      function initMap() {
        var pyrmont = {lat: -33.867, lng: 151.195};

        map = new google.maps.Map(document.getElementById('map'), {
          center: pyrmont,
          zoom: 15
        });

        infowindow = new google.maps.InfoWindow();
        var service = new google.maps.places.PlacesService(map);
        service.nearbySearch({
          location: pyrmont,
          radius: 500,
          type: ['hotel']
        }, callback);
      }

      function callback(results, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
          }
        }
      }

      function createMarker(place) {
        var placeLoc = place.geometry.location;
        var marker = new google.maps.Marker({
          map: map,
          position: place.geometry.location
        });

        google.maps.event.addListener(marker, 'click', function() {
          infowindow.setContent(place.name);
          infowindow.open(map, this);
        });
      }
    </script>
  </head>
  <body>
    <div id="map"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async defer></script>
  </body>
</html>

反应谷歌地图 https://tomchentw.github.io/react-google-maps/#searchbox有一个显示搜索输入字段的示例。这样我就可以通过搜索来搜索并显示标记,例如“伦敦的酒店”。但我不想搜索地点,而是想立即显示酒店的标记。 (下例中的API密钥来自react-google-maps示例。)

const _ = require("lodash");
const { compose, withProps, lifecycle } = require("recompose");
const {
  withScriptjs,
  withGoogleMap,
  GoogleMap,
  Marker,
} = require("react-google-maps");
const { SearchBox } = require("react-google-maps/lib/components/places/SearchBox");

const MapWithASearchBox = compose(
  withProps({
    googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyC4R6AN7SmujjPUIGKdyao2Kqitzr1kiRg&v=3.exp&libraries=geometry,drawing,places",
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `400px` }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  lifecycle({
    componentWillMount() {
      const refs = {}

      this.setState({
        bounds: null,
        center: {
          lat: 41.9, lng: -87.624
        },
        markers: [],
        onMapMounted: ref => {
          refs.map = ref;
        },
        onBoundsChanged: () => {
          this.setState({
            bounds: refs.map.getBounds(),
            center: refs.map.getCenter(),
          })
        },
        onSearchBoxMounted: ref => {
          refs.searchBox = ref;
        },
        onPlacesChanged: () => {
          const places = refs.searchBox.getPlaces();
          const bounds = new google.maps.LatLngBounds();

          places.forEach(place => {
            if (place.geometry.viewport) {
              bounds.union(place.geometry.viewport)
            } else {
              bounds.extend(place.geometry.location)
            }
          });
          const nextMarkers = places.map(place => ({
            position: place.geometry.location,
          }));
          const nextCenter = _.get(nextMarkers, '0.position', this.state.center);

          this.setState({
            center: nextCenter,
            markers: nextMarkers,
          });
          // refs.map.fitBounds(bounds);
        },
      })
    },
  }),
  withScriptjs,
  withGoogleMap
)(props =>
  <GoogleMap
    ref={props.onMapMounted}
    defaultZoom={15}
    center={props.center}
    onBoundsChanged={props.onBoundsChanged}
  >
    <SearchBox
      ref={props.onSearchBoxMounted}
      bounds={props.bounds}
      controlPosition={google.maps.ControlPosition.TOP_LEFT}
      onPlacesChanged={props.onPlacesChanged}
    >
      <input
        type="text"
        placeholder="Customized your placeholder"
        style={{
          boxSizing: `border-box`,
          border: `1px solid transparent`,
          width: `240px`,
          height: `32px`,
          marginTop: `27px`,
          padding: `0 12px`,
          borderRadius: `3px`,
          boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
          fontSize: `14px`,
          outline: `none`,
          textOverflow: `ellipses`,
        }}
      />
    </SearchBox>
    {props.markers.map((marker, index) =>
      <Marker key={index} position={marker.position} />
    )}
  </GoogleMap>
);

<MapWithASearchBox />

我已经尝试解决这个问题很多天了,并且一直在寻找教程,但我找不到解决方案。我明白我应该使用:

new google.maps.places.PlacesService()

并添加选项:

 const center = new google.maps.LatLng(37.422, -122.084068);
 const options = {
   location: center
   radius: '500',
   types: ['hotel']
 };

当使用react-google-maps时,我需要使用与Scriptjs。但我如何将所有这些整合在一起呢?

我如何使用react-google-maps谷歌地方信息API https://developers.google.com/maps/documentation/javascript/examples/place-search,在地图上显示 Google 的“酒店”标记?


你可以通过传递你的裁判来做到这一点GoogleMap to new google.maps.places.PlacesService()创建一个服务,然后您可以使用该服务nearbySearch()搜索酒店、餐馆等。Google 附近地点搜索 API 文档 https://developers.google.com/maps/documentation/javascript/places#place_search_requests says:

附近搜索可让您按关键字或类型搜索指定区域内的地点。

开火fetchPlaces()方法你可以同时使用onTilesLoaded支撑来自谷歌地图 https://tomchentw.github.io/react-google-maps/#googlemap组件或componentDidMount()。在下面的例子中我也通过了fetchPlaces to onBoundChanged因为我的搜索基于bounds这样每次移动地图时它都可以给我新的位置,请注意:

const bounds = refs.map.getBounds();
const service = new google.maps.places.PlacesService(refs.map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED);
const request = {
  bounds: bounds,
  type: ['hotel']
};

这是我使用的示例recompose:

/*global google*/
import React from "react"
import { compose, withProps, withHandlers, withState } from "recompose"
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps"

const MyMapComponent = compose(
    withProps({
        googleMapURL: "https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places",
        loadingElement: <div style={{ height: `100%` }} />,
        containerElement: <div style={{ height: `400px` }} />,
        mapElement: <div style={{ height: `100%` }} />,
    }),
    withScriptjs,
    withGoogleMap,
    withState('places', 'updatePlaces', ''),
    withHandlers(() => {
        const refs = {
            map: undefined,
        }

        return {
            onMapMounted: () => ref => {
                refs.map = ref
            },
            fetchPlaces: ({ updatePlaces }) => {
                let places;
                const bounds = refs.map.getBounds();
                const service = new google.maps.places.PlacesService(refs.map.context.__SECRET_MAP_DO_NOT_USE_OR_YOU_WILL_BE_FIRED);
                const request = {
                    bounds: bounds,
                    type: ['hotel']
                };
                service.nearbySearch(request, (results, status) => {
                    if (status == google.maps.places.PlacesServiceStatus.OK) {
                        console.log(results);
                        updatePlaces(results);
                    }
                })
            }
        }
    }),
)((props) => {
    return (
        <GoogleMap
            onTilesLoaded={props.fetchPlaces}
            ref={props.onMapMounted}
            onBoundsChanged={props.fetchPlaces}
            defaultZoom={8}
            defaultCenter={{ lat: 51.508530, lng: -0.076132 }}
        >
            {props.places && props.places.map((place, i) =>
                <Marker key={i} position={{ lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }} />
            )}
        </GoogleMap>
    )
})

export default class MyFancyComponent extends React.PureComponent {
    render() {
        return (
            <MyMapComponent />
        )
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 React 与 Google Places API 结合使用,在 Google 地图上显示地点标记? 的相关文章

随机推荐

  • Laravel 3 - 如何验证复选框数组,至少选中 1 个?

    我开始学习 Laravel 并且仍在学习曲线上 现在我从 Laravel 3 开始 但一旦我开始工作 很可能会将我的项目切换到 Laravel 4 现在的问题是 如何验证复选框数组 我想验证组内至少有 1 个复选框已启用 选中 我在 Lar
  • Bulma 导航栏和 VueJS 路由器活动链接

    我已经开始使用布尔玛0 7 1 and VueJs 2 5 17 现在 我正在使用 Vue 路由器组件 并且我希望每当我位于链接表示的 页面 上时 将导航栏中的按钮设置为活动状态 我的代码如下
  • 由于冲突,无法删除一些未标记的 docker 镜像

    我无法显式删除一些未标记的 docker 映像 具体来说 那些带有标签的
  • C#/.NET:在 C# 中创建动态视觉效果

    注意 我不太确定如何标题或标记这个问题 所以如果您有任何想法 请帮忙 我目前正在设想一些可能的项目 涉及动态渲染某些东西 作为假设的例子 无论是点 线 文本还是五线谱上的音符 但是 如果我要承担这些项目 我 我不太确定如何实现这个设计 我很
  • 在 C# 中验证 FQDN

    有人有正则表达式来验证合法的 FQDN 吗 现在 我使用这个正则表达式 1 254 d a zA Z0 9 1 63 a zA Z 2 但是 此正则表达式会导致 aa a 无效 而 aa aa 有效 有谁知道为什么 这是一个较短的模式 1
  • 如何查询所有子文档

    我从 MongoDb 和 nodejs 使用 mongoose 开始 我有一个收藏Stories 每个都可以有一个或多个Tags 是这样的 title The red fox content The red fox jumps away t
  • 使用 bootstrap 的 Angular 6 库

    我正在使用 Angular 6 库功能在 Angular 项目中创建 Angular 库https github com angular angular cli wiki stories create library https githu
  • 如何在图片下方写标题?

    我有两个图像需要保持内联 我想在每张图片下写一个标题
  • Ionic 3 - 每个页面都需要自己的模块吗?

    我是 Ionic 新手 试图了解如何组织中型应用程序 每个页面应该有自己的模块吗 或者将相似的页面分组到同一个模块中是否更好 有可能这样做吗 看来 IonicPageModule forChild 方法只接受一页 IonicPageModu
  • 将环境类与管道运行结合使用

    我正在使用环境类对管道使用估计器步骤 以便拥有自定义 Docker 映像 因为我需要一些apt get软件包能够安装特定的 pip 软件包 从日志中可以看出 与估计器的非管道版本不同 它完全忽略了环境变量的 docker 部分 很简单 这似
  • Microsoft AlwaysOn 故障转移解决方案和 Delphi

    我正在尝试制作一个 Delphi 应用程序来与 AlwaysOn 解决方案一起使用 我在谷歌上发现我必须使用MultiSubnetFailover True在连接字符串中 应用程序在Delphi XE3中编译并使用TADOConnectio
  • 什么是直接引用?

    严格模式规则之一 Annex C http ecma international org ecma 262 5 1 sec C 状态 When a delete运算符出现在严格模式代码中 语法错误被抛出 如果它一元表达式是对变量 函数参数或
  • 如何跟踪量角器正在等待哪些异步任务?

    我有一个中型 Angular 应用程序 由于某些原因 我的一些量角器测试在我的实时生产环境中运行时超时 我相当确定超时是由于量角器等待某些异步任务而发生的 我了解区域 并且我尝试将所有长时间运行的异步任务保留在 ngZone 之外 根据th
  • 如何让定时器准确? (Flash/ActionScript 3.0)

    我使用以下方法以 X 次 分钟发送声音 X 通过 bpm 确定 它是一个 NumericStepper 对象 var mainTimer Timer new Timer 60 bpm value 1000 0 mainTimer addEv
  • 使用 Visual Studio 2008 编辑 RDL 文件

    我已在两个工作站上安装了 SQL Server 2008 Express 在一台工作站上 它更新了 VS2008 安装 以便我可以创建包含 rdl 文件格式的报告的报告项目 在其他工作站上 VS2008只能创建 编辑 rdlc文件 报告编辑
  • string.Format() 给出“输入字符串的格式不正确”

    我在这里做错了什么 string tmp if UseImageFiles vCalHeader td img src 0 cal fastreverse gif width 13px height 9 style border 1px s
  • Pandas Fillna 多列与每列众数

    使用人口普查数据时 我想将两列 workclass 和 native country 中的 NaN 替换为这两列各自的模式 我可以轻松获得模式 mode df filter workclass native country mode 它返回
  • 使用 Javascript 将禁用属性添加到输入元素

    我有一个输入框 我希望禁用它并同时隐藏它以避免移植表单时出现问题 到目前为止 我有以下代码来隐藏我的输入 shownextrow click function this closest tr next show find longboxsm
  • 为什么通常的访问控制检查适用于通过模板参数访问时用于指定显式实例化的名称?

    C 11 14 标准在注释 14 7 2 12 temp explicit 中声明了以下内容 通常的访问检查规则不适用于用于指定的名称 显式实例化 注意 特别是模板参数 以及函数声明符中使用的名称 包括参数类型 返回类型和异常规范 可以是私
  • 如何将 React 与 Google Places API 结合使用,在 Google 地图上显示地点标记?

    我正在尝试构建一个类似的地图 您可以在拖动地图时查看地点标记 我想在地图上显示来自 Google Places API 的 酒店 标记 使用以下 JavaScript 代码谷歌地图 https developers google com m