Reputation: 29
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 search for "treatment centers" and place markers using the Google Places API on a map.
I have been using the new, re-written @react-google-maps/api. So far, I was able to create both a search box and an autocomplete and get their latitude and longitude, but both offer only specific locations rather than the most similar searches (ex. if you search Taco Bell on Google Maps, it shows up with several options near you). The code below displays a map with the search box:
import { GoogleMap, LoadScript, Marker, StandaloneSearchBox, Autocomplete } from '@react-google-maps/api';
class HeaderMap extends Component {
constructor (props) {
super(props)
this.autocomplete = null
this.onLoad = this.onLoad.bind(this)
this.onPlaceChanged = this.onPlaceChanged.bind(this)
this.state = {
currentLocation: {lat: 0, lng: 0},
markers: [],
zoom: 8
}
}
componentDidMount() {
navigator?.geolocation.getCurrentPosition(({coords: {latitude: lat, longitude: lng}}) => {
const pos = {lat, lng}
this.setState({currentLocation: pos})
})
}
onLoad (autocomplete) {
console.log('autocomplete: ', autocomplete)
this.autocomplete = autocomplete
}
onPlaceChanged() {
if (this.autocomplete !== null) {
let lat = this.autocomplete.getPlace().geometry.location.lat()
let long = this.autocomplete.getPlace().geometry.location.lat()
} else {
console.log('Autocomplete is not loaded yet!')
}
}
render() {
return (
<LoadScript
googleMapsApiKey="API_KEY_HERE"
libraries={["places"]}
>
<GoogleMap
id='search-box-example'
mapContainerStyle={containerStyle}
center={this.state.currentLocation}
zoom={14}
// onDragEnd={search for centers in current location}
>
<Marker key={1} position={this.state.currentLocation} />
<Autocomplete
onLoad={this.onLoad}
onPlaceChanged={this.onPlaceChanged}
>
<input
type="text"
placeholder="Customized your placeholder"
style={inputStyles}
/>
</Autocomplete>
</GoogleMap>
</LoadScript>
);
}
}
How can I automatically search the bounds of the location and get the latitude and longitude of each result based on keywords? Thanks for your help!
Upvotes: 0
Views: 25428
Reputation: 2977
In your current code, it seems that you are using Autocomplete which was precoded by the library to have the functions of Places Autocomplete. You can use the StandaloneSearchBox to achieve your use case as it is implementing the Places Searchbox which returns a pick list that includes both places and predicted search terms.
Here is the code sample and code snippet below:
/*global google*/
import React from "react";
import { GoogleMap, StandaloneSearchBox, Marker } from "@react-google-maps/api";
let markerArray = [];
class Map extends React.Component {
state = {
currentLocation: { lat: 0, lng: 0 },
markers: [],
bounds: null
};
onMapLoad = map => {
navigator?.geolocation.getCurrentPosition(
({ coords: { latitude: lat, longitude: lng } }) => {
const pos = { lat, lng };
this.setState({ currentLocation: pos });
}
);
google.maps.event.addListener(map, "bounds_changed", () => {
console.log(map.getBounds());
this.setState({ bounds: map.getBounds() });
});
};
onSBLoad = ref => {
this.searchBox = ref;
};
onPlacesChanged = () => {
markerArray = [];
let results = this.searchBox.getPlaces();
for (let i = 0; i < results.length; i++) {
let place = results[i].geometry.location;
markerArray.push(place);
}
this.setState({ markers: markerArray });
console.log(markerArray);
};
render() {
return (
<div>
<div id="searchbox">
<StandaloneSearchBox
onLoad={this.onSBLoad}
onPlacesChanged={this.onPlacesChanged}
bounds={this.state.bounds}
>
<input
type="text"
placeholder="Customized your placeholder"
style={{
boxSizing: `border-box`,
border: `1px solid transparent`,
width: `240px`,
height: `32px`,
padding: `0 12px`,
borderRadius: `3px`,
boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
fontSize: `14px`,
outline: `none`,
textOverflow: `ellipses`,
position: "absolute",
left: "50%",
marginLeft: "-120px"
}}
/>
</StandaloneSearchBox>
</div>
<br />
<div>
<GoogleMap
center={this.state.currentLocation}
zoom={10}
onLoad={map => this.onMapLoad(map)}
mapContainerStyle={{ height: "400px", width: "800px" }}
>
{this.state.markers.map((mark, index) => (
<Marker key={index} position={mark} />
))}
</GoogleMap>
</div>
</div>
);
}
}
export default Map;
Upvotes: 3