Timothy
Timothy

Reputation: 139

GoogleMaps, Reverse geocode, return street_address

I have a form that allows the user to create a new marker on the Google Map, with an infoWindow containing info the user provides. One field allows the user to enter a description of the location (i.e. "Buds Burgers on Sonoma in Vallejo") and a marker will be created with the exact same info in what I have labeled as "Location.address". My goal is to reverse geocode the given coordinates and output the street address for any location provided. I am able to console.log the lat and lng so I know that I can access them, I just haven't been able to figure out how do I use them.

location.rb

create_table "locations", force: :cascade do |t|
    t.string   "location_name"
    t.string   "location_address"
    t.string   "location_description"
    t.float    "lat"
    t.float    "lng"
    t.datetime "created_at",           null: false
    t.datetime "updated_at",           null: false
  end

The script running on my map page:

<script>
    map = new google.maps.Map(document.getElementById('map'), {
                zoom: 10,
                center: new google.maps.LatLng(37.725685, -122.156830),
                mapTypeId: google.maps.MapTypeId.ROADMAP
                });

      var places = <%= @locations.to_json.html_safe %>
      var infowindow = new google.maps.InfoWindow();
      var marker, i;
      for (i = 0; i < places.length; i++) {
        marker = new google.maps.Marker({
        position: new google.maps.LatLng(places[i].lat, places[i].lng),
        map: map
        });
        var lat = (places[i].lat);
        var lng = (places[i].lng);

        console.log(" lat: " +  places[i].lat + " " + "lng: " + places[i].lng);
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
          return function() {
            infowindow.setContent(places[i].location_name + "   <br />  " + places[i].location_description  + "    <br />     " + places[i].location_address);
            infowindow.open(map, marker);
          }
        })(marker, i));
      }
</script>

Form:

 <%= form_for @location, :html => { :class => "form-inline" } do |f| %>
  <%= f.label :name %>:
  <%= f.text_field :location_name %><br />

  <%= f.label "Description or Discount Offered" %>:
  <%= f.text_field :location_description %><br />

  <%= f.label :address %>:
  <%= f.text_field :location_address %><br />

  <%= f.submit "Create New Location"%>
 <% end %>

I am at my wits end. Help please.

Thank you.

Upvotes: 1

Views: 1584

Answers (1)

rafon
rafon

Reputation: 1542

I am not familiar with Ruby-on-Rails but I can definitely help you in Google Maps API. Let's just use coordinates places[i].lat and places[i].lng since you said in your post that you can log their values.

You wanted to Reverse Geocode the coordinates you acquired.

Reverse geocoding is the process of converting geographic coordinates into a human-readable address.

Let's start by creating a new Geocoder instance.

var geocoder = new google.maps.Geocoder();

This means that a new instance of Geocoder Object has been created using variable "geocoder". You can now use Geocoder's geocode method.

In Reverse Geocoding, geocode method accepts 2 arguments - location, and callback. You need to use "location" parameter and supply a comma-separated latitude/longitude or you can simply use new google.maps.LatLng(lat, lng) object. The value of this should be the coordinates you acquired.

geocoder.geocode( { 'location' : new google.maps.LatLng(places[i].lat, places[i].lng) }, callback );

On the other hand, the callback arguments need two arguments as well. The first is for the result, and the other is for the status. You can name the arguments, whatever you want. This is where most of our logic will be implemented.

function(results, status) {
   if ( status === 'OK' ) {
   } 
}

In the callback function, there's should be a condition that checks if the returned status is 'OK'. If so, the results arguments will return an array of results. There's a note in Reverse Geocoding documentation:

The reverse geocoder often returns more than one result. Geocoded addresses are not just postal addresses, but any way to geographically name a location.

You can get the formatted address under results[0].formatted_address. You can also get address_components such as "street_number", "route", "locality", and "country" and append it to the DOM. I recommend using an external library using JQuery to make DOM manipulation easier. You can do something like this:

function(results, status) {
   if ( status === 'OK' ) {
   $('div#street_name').html('<p>'+results[0].formatted_address.+'</p>');
   } 
}

The whole code looks something like this:

var geocoder = new google.maps.Geocoder();

geocoder.geocode( { 'location' : new google.maps.LatLng(places[i].lat, places[i].lng) }, function(results, status) {
   if ( status === 'OK' ) {
   $('div#street_name').html('<p>'+results[0].formatted_address.+'</p>');
   } 
});

Hope this helps and happy coding!

Upvotes: 2

Related Questions