Skip to content

Commit

Permalink
update uploader to use place autocomplete and geocoding services inst…
Browse files Browse the repository at this point in the history
…ead of searchbox
  • Loading branch information
pleary committed Nov 30, 2023
1 parent e724ab4 commit 9c45ff5
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 90 deletions.
2 changes: 1 addition & 1 deletion app/assets/stylesheets/observations/uploader.scss
Expand Up @@ -1131,7 +1131,7 @@ $tickmark: 6px;
margin-top: 15px;
}

.GooglePlacesSearchBox {
.GooglePlacesAutocomplete {
position: absolute;
top: 16px;
left: 181px;
Expand Down
@@ -0,0 +1,92 @@
import React from "react";
import PropTypes from "prop-types";
import { objectToComparable } from "../../../shared/util";

class GooglePlacesAutocomplete extends React.Component {
constructor( props ) {
super( props );
this.input = React.createRef( );
}

componentDidMount( ) {
this.placesAutocomplete = new google.maps.places.Autocomplete(
this.input.current,
{
types: ["geocode"],
fields: ["place_id"]
}
);
this.placesAutocompleteService = new google.maps.places.AutocompleteService( );
this.googleGeocoder = new google.maps.Geocoder( );
}

componentDidUpdate( prevProps ) {
if ( !this.placesAutocomplete ) return;
// Change the bias bounds of the placesAutocomplete
const { bounds } = this.props;
if ( bounds && objectToComparable( bounds ) !== objectToComparable( prevProps.bounds ) ) {
this.placesAutocomplete.setBounds( bounds );
}
// Remove any existing event listener for places_changes
if ( this.placesChangedListener ) {
google.maps.event.removeListener( this.placesChangedListener );
}
// Add a listener for places_changed
this.placesChangedListener = this.placesAutocomplete.addListener( "place_changed", ( ) => {
const place = this.placesAutocomplete.getPlace( );
if ( place && place.place_id ) {
this.geocodePlaceID( place.place_id );
return;
}
this.processAutocompletePrediction( );
} );
}

processAutocompletePrediction( ) {
// the user hit enter in the place autocomplete input field without picking a result. Run
// the text in the input field through the placesAutocompleteService and process the top
// result as if it were selected by the user
const q = $( this.input.current ).val( );
this.placesAutocompleteService.getQueryPredictions(
{ input: q },
( predictions, status ) => {
if ( status !== google.maps.places.PlacesServiceStatus.OK
|| predictions.length === 0 || !predictions[0].place_id ) {
return;
}
this.geocodePlaceID( predictions[0].place_id );
}
);
}

geocodePlaceID( placeID ) {
const { onPlacesChanged } = this.props;
// fetch additional information for the placeID from the geocoder service to get details
// such as address_components, viewport, center lat/lng, etc.
this.googleGeocoder.geocode( { placeId: placeID }, ( results, status ) => {
if ( status !== google.maps.GeocoderStatus.OK ) {
return;
}
onPlacesChanged( this.input.curent, results[0] );
} );
}

render( ) {
return (
<div className="GooglePlacesAutocomplete">
<input
ref={this.input}
type="text"
placeholder={I18n.t( "search_for_a_location" )}
/>
</div>
);
}
}

GooglePlacesAutocomplete.propTypes = {
bounds: PropTypes.object,
onPlacesChanged: PropTypes.func.isRequired
};

export default GooglePlacesAutocomplete;

This file was deleted.

Expand Up @@ -5,7 +5,7 @@ import _ from "lodash";
import util from "../models/util";
import { objectToComparable } from "../../../shared/util";
import PhotoMarkerOverlayView from "./photo_marker_overlay_view";
import GooglePlacesSearchBox from "./google_places_search_box";
import GooglePlacesAutocomplete from "./google_places_autocomplete";

let lastCenterChange = new Date().getTime();

Expand Down Expand Up @@ -134,8 +134,11 @@ class LocationChooserMap extends React.Component {
this.moveCircle( latLng, radius, { geocode: true } );
}

handlePlacesChanged( input, places ) {
handlePlacesChanged( input, place ) {
const { updateState } = this.props;
if ( _.isEmpty( place ) ) {
return;
}
let searchQuery;
let lat;
let lng;
Expand All @@ -158,35 +161,12 @@ class LocationChooserMap extends React.Component {
}
let notes;
let radius;
let viewport;
if ( places.length > 0 ) {
const { geometry } = places[0];
( { viewport } = geometry );
lat = lat || geometry.location.lat( );
lng = lng || geometry.location.lng( );
// Set the locality notes using political entity names and omitting
// street-level information
const storeStreetAddress = false; // disabling until we figure out what we really want
if (
storeStreetAddress
&& places[0].address_components
&& places[0].address_components.length > 0
) {
const goodTypes = ["political", "neighborhood"];
const goodComponents = _.filter(
places[0].address_components,
p => _.intersection( p.types, goodTypes ).length > 0
);
notes = goodComponents
.map( p => ( p.short_name || p.long_name ) )
.join( ", " );
if ( places[0].name && !places[0].name.match( /^\d+/ ) ) {
notes = `${places[0].name}, ${notes}`;
}
} else {
notes = places[0].formatted_address;
}
}

const { geometry } = place;
const { viewport } = geometry;
lat = lat || geometry.location.lat( );
lng = lng || geometry.location.lng( );
notes = place.formatted_address;
if ( typeof ( google ) !== "undefined" ) {
if ( viewport && !searchedForCoord ) {
// radius is the largest distance from geom center to one of the bounds corners
Expand Down Expand Up @@ -243,10 +223,7 @@ class LocationChooserMap extends React.Component {
lng,
obsCard: currentCard,
obsCards,
radius,
show,
center,
fitCurrentCircle
radius
} = this.props;

// Determine if we should re-render the overlays
Expand Down Expand Up @@ -446,7 +423,7 @@ class LocationChooserMap extends React.Component {
return (
<div className="LocationChooserMap map">
<div className="map-inner" />
<GooglePlacesSearchBox
<GooglePlacesAutocomplete
bounds={bounds}
onPlacesChanged={this.handlePlacesChanged}
/>
Expand Down

0 comments on commit 9c45ff5

Please sign in to comment.