如何使用Google Places API的React在Google地图上显示地点标记? [英] How to use React with Google Places API, to display place markers on a Google map?

查看:470
本文介绍了如何使用Google Places API的React在Google地图上显示地点标记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作类似于

解决方案

您可以通过将您的 GoogleMap 的ref传递给 new google.maps.places.PlacesService()来创建一个服务,然后使用该服务,您可以使用 nearbySearch()来搜索酒店,餐厅等。 Google地方信息附近的搜索API文档说:


A近通过搜索,您可以按关键字或类型搜索指定区域内的地点。


触发 fetchPlaces( )方法,您可以同时使用 onTilesLoaded 来自 GoogleMap 组件或 componentDidMount()。在下面的例子中,我还将 fetchPlaces 传递给 onBoundChanged ,因为我将搜索放在边界因此,每当我移动地图时它都会给我新的地方,请注意这里:

  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 = {
界限:界限,
类型:['hotel']
};

以下是我使用 recompose 的示例:

  / *全局谷歌* / 
导入从react反应
导入{compose,withProps,withHandlers ,withState} fromrecompose
从react-google-maps导入{withScriptjs,withGoogleMap,GoogleMap,Marker}
$ b $常量MyMapComponent =合成(
withProps({ b $ b 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 {
onMapMou nted:()=> ref => {
refs.map = ref
},
fetchPlaces:({updatePlaces})=> {
让位;
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 = {
界限:界限,
类型:['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& amp;& props.places.map((place, i)=>
< Marker key = {i} position = {{lat:place.geometry.location.lat(),lng:place.geometry.location.lng()}} />
)}
< / GoogleMap>

})

导出默认class MyFancyComponent extends React.PureComponent {
render(){
return(
< MyMapComponent />

}
}


I'm trying to build a similar map as on Airbnb, where you can view place markers as you drag the map around. I would like to display "hotel" markers from the Google Places API on a map.

Using the following JS code from Google Maps I can display hotels on the google map, but I would like to do this with React, using 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>

react-google-maps has an example of showing the search input field. So with that I'm able to search and show markers by searching e.g. "hotels in London". But instead of searching for places, I would like to immediately show the markers for hotels. (The API key in the example below is from the react-google-maps example).

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 />

I have been trying to figure this out for many days now, and have been looking for tutorials, but couldn't find a solution. I understand that I should use:

new google.maps.places.PlacesService()

and add options:

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

And when using the react-google-maps, I need to use the withScriptjs. But I still don't understand how to put all of this together?

How to use react-google-maps with Google Places API, to display "hotel" markers from Google on the map?

解决方案

You can do that by passing a ref of your GoogleMap to new google.maps.places.PlacesService() to create a service and then with that service you can use nearbySearch() to search for hotels, restaurants, etc. As the Google Places Nearby Search API docs says:

A Nearby Search lets you search for places within a specified area by keyword or type.

To fire the fetchPlaces() method you can use both onTilesLoaded prop from GoogleMap component or componentDidMount(). In the example below I also passed fetchPlaces to onBoundChanged since I am basing my search on bounds so it can give me new places every time I move the map, note here:

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']
};

Here is my example using 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 />
        )
    }
}

这篇关于如何使用Google Places API的React在Google地图上显示地点标记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆