Custom Interactive Maps With Geocoding In Google Maps

Introduction

Geocoding is a process in Google Maps to convert the address into coordinates(like latitude and longitude) and using these coordinates we can place markers on the Google Map. In Google Maps, we have a geocoding service in Javascript Map API which needs to be enabled and accessed for performing geocoding. There is another term associated with this called Reverse geocoding. Reverse geocoding is the process in which geographical coordinates are converted into addresses. This address will be in the human-readable format. 

Calling Geocoding Service

Geocoding service is asynchronous in nature. So we have to pass the callback functions to handle responses and errors. In the callback method, we will handle the results. The geocoder can return many results based on the address or location passed. If the address passed has more than one match, then we will get more than one result. 
We can access the Google Map API geocoding service using google.maps.Geocoder constructor object. We will use the geocode() method of the service to initialize a request to the geocoding service. We have to pass additional parameters from the following literal.
We have to pass only one parameter out of the following:

  • Address -  The address to geocode.
  • Location - The LatLng for which we want to obtain an address. In this case, reverse geocoding will take place.
  • PlaceId - The place if is the unique identifier that we can use with Maps API.
Now we have some optional parameters as well to pass in the request. You can read here.
Let us see one example to understand better:

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <title>Marker On Map</title>
  <style>
    #Gmap {
      height: 1000px;
      width: 100%;
    }

    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <div id="Gmap"></div>
  <script>
    function initMap() {
      var mapOptions = {
        streetViewControl: false,
        center: { lat: -45.67677, lng: -90.253456 },
        zoom: 4,

      };
      var map = new google.maps.Map(document.getElementById('Gmap'), mapOptions);
      var marker = new google.maps.Marker({
        position: { lat: -45.67677, lng: -90.253456 },
        map: map,
        gestureHandling: 'cooperative'
      });
      fetchLocation();
    }

    function fetchLocation() {
      var geocoder = new google.maps.Geocoder;
      geocoder.geocode({ address: "LA" }, (results, status) => {
        console.log(results);

      });
    }
    
  </script> 
  <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
</body>
</html>


Geocoding Responses

The response will be a single geocoding output. Now we will see what we got in the above example for address: "LA". 

results[]: {
 types[]: string,
 formatted_address: string,
 address_components[]: {
   short_name: string,
   long_name: string,
   postcode_localities[]: string,
   types[]: string
 },
 partial_match: boolean,
 place_id: string,
 postcode_localities[]: string,
 geometry: {
   location: LatLng,
   location_type: GeocoderLocationType
   viewport: LatLngBounds,
   bounds: LatLngBounds
 }
}

We will see what we will get for LA. Read geocoding results to understand all the results fields. Some we will discuss here:

  • formatted_address - It is the string address in a human-readable format. It consists of various address components as well. 
  • address_components - This is an array that consists of various individual components related to this address. 
  • geometry - It contains the location which contains a LatLng object.

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Los Angeles",
               "short_name" : "Los Angeles",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Los Angeles County",
               "short_name" : "Los Angeles County",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "California",
               "short_name" : "CA",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Los Angeles, CA, USA",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 34.3373061,
                  "lng" : -118.1552891
               },
               "southwest" : {
                  "lat" : 33.7036519,
                  "lng" : -118.6681759
               }
            },
            "location" : {
               "lat" : 34.0522342,
               "lng" : -118.2436849
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 34.3373061,
                  "lng" : -118.1552891
               },
               "southwest" : {
                  "lat" : 33.7036519,
                  "lng" : -118.6681759
               }
            }
         },
         "place_id" : "ChIJE9on3F3HwoAR9AhGJW_fL-I",
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

Getting Address For Different Marker Locations

Now we will be working with the Google geocoding API to get the address in the human-readable format for a marker. We will be placing a marker at different locations by dragging it. We will be attaching an event called "dragend" with the marker. At the end of dragging the marker, function fetchAddress() will be called. We will be passing the ev.LatLng object as shown below:  

 marker.addListener("dragend", (ev) => {
        console.log(ev);
        fetchAddress(ev.latLng);
      });

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <title>Marker On Map</title>
  <style>
    #Gmap {
      height: 1000px;
      width: 100%;
    }

    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <div id="Gmap"></div>
  <script>
    function initMap() {
      var marker;
      var map;
      var mapOptions = {
        streetViewControl: false,
        center: { lat: 45.67677, lng: 110.253456 },
        zoom: 4,
      };
      map = new google.maps.Map(document.getElementById('Gmap'), mapOptions);
      marker = new google.maps.Marker({
        position: { lat: 45.67677, lng: 110.253456 },
        map: map,
        draggable: true,
      });

      marker.addListener("dragend", (ev) => {
        console.log(ev);
        fetchAddress(ev.latLng);
      });

    }


    function fetchAddress(latLng) {
      var geocoder = new google.maps.Geocoder;
      geocoder.geocode({ 'location': latLng }, (results, status) => {
        console.log(results);
        var address = results[0].formatted_address;
        var addressInDetail = results[0].address_components;
        for (var i = 0; i < addressInDetail.length; i++) {
          var addressOutput = addressInDetail[i].long_name;
          console.log(addressOutput);
        }
      });
    }


  </script>

  <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
</body>
</html>

In this case, reverse geocoding will be done using geocoder.geocode() method. We will pass the location and get the address in different result responses.

Comments