woodykiddy
woodykiddy

Reputation: 6455

How to limit search results with Google Maps Autocomplete API

I am currently restricting the suburb lookup within Australia using ComponentRestrictions but wondering if I can further refine the returned results.

For example,

enter image description here

if I enter Coogee in the search, I can see multiple results coming out. But if I only want Coogee in NSW instead WA, how should I do that?

There's a mention of Place Types with this documentation. But I am not too sure which might be the right type(s) to use in my case

Code snippet

const input = document.getElementById('inputSuburb');
const options = {
    fields: ["address_components", "geometry", "types", "name"],
    componentRestrictions: { country: 'au' },
    types: ['locality', 'postal_code']
};

autocomplete = new google.maps.places.Autocomplete(input, options);

autocomplete.addListener('place_changed', function () {
   const place = autocomplete.getPlace();
   console.log(place);
}

Upvotes: 0

Views: 1605

Answers (1)

geocodezip
geocodezip

Reputation: 161404

The ComponentRestrictions for AutoComplete only allows country level restrictions (at present).

ComponentRestrictions interface
Properties
country optional

Type: string|Array optional
Restricts predictions to the specified country (ISO 3166-1 Alpha-2 country code, case insensitive). For example, 'us', 'br', or 'au'. You can provide a single one, or an array of up to five country code strings.

One option for attaining your desired result would be to use the strictBounds option of AutoComplete, setting the bounds to those of NSW.

  const input = document.getElementById('inputSuburb');
  const options = {
    fields: ["address_components", "geometry", "types", "name"],
    strictBounds: true,
    bounds : { // bounds of NSW
      "south": -37.5052801,
      "west": 140.9992793,
      "north": -28.15702,
      "east": 159.1054441
    },
    componentRestrictions: {
      country: 'au'
    },
    types: ['locality', 'postal_code']
  };

  autocomplete = new google.maps.places.Autocomplete(input, options);

  autocomplete.addListener('place_changed', function() {
    const place = autocomplete.getPlace();
    console.log(place);
  });

proof of concept fiddle

screenshot of autocomplete with strictBounds

code snippet:

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 40.749933,
      lng: -73.98633
    },
    zoom: 13,
    mapTypeControl: false,
  });
  map.fitBounds({ // bounds of NSW
      "south": -37.5052801,
      "west": 140.9992793,
      "north": -28.15702,
      "east": 159.1054441
    });
  const input = document.getElementById('inputSuburb');
  const options = {
    fields: ["address_components", "geometry", "types", "name"],
    strictBounds: true,
    bounds : { // bounds of NSW
      "south": -37.5052801,
      "west": 140.9992793,
      "north": -28.15702,
      "east": 159.1054441
    },
    componentRestrictions: {
      country: 'au'
    },
    types: ['locality', 'postal_code']
  };

  autocomplete = new google.maps.places.Autocomplete(input, options);

  autocomplete.addListener('place_changed', function() {
    const place = autocomplete.getPlace();
    console.log(place);
  });

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);
    }

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

window.initMap = initMap;
#map {
  height: 100%;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Place Autocomplete</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
        <input id="inputSuburb" type="text" placeholder="Enter a location" value="cooge"/>
    <div id="map"></div>
    <div id="infowindow-content">
      <span id="place-name" class="title"></span><br />
      <span id="place-address"></span>
    </div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Upvotes: 1

Related Questions