Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

Determine geographical/administrative info by address data (Google Maps)

  • Hulotte
  • Hulotte's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 3 weeks ago #180975 by Hulotte
Hi!


For our current survey we want to determine geocoordinates, (German) district and federal state names from address data we already have from our participants.

So what we have right now is a survey with a closed participant list. Every participant has additionally address data (street address and number, ZIP, city) in custom attribute fields.

To get the geocoordinates we used this solution here which works great:
www.limesurvey.org/de/community/forum/ca...d-on-previous-answer (we placed short-text question directly before a map question and then place the script in the source of the map question):




But how can we also add district and federal state names (it can filles in into the same field with the geocoordinates, separated by a semicolon)?

The Google Maps API is able to deliver all of the necessary information (e.g. maps.googleapis.com/maps/api/geocode/jso...13.3779&key=XXXXXXXX <- this only works with a API key; I attached the JSON (geo.zip) you get when opening this URL). This part is relevant:
Code:
"results" : [
      {
         "address_components" : [
            {
               "long_name" : "1",
               "short_name" : "1",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Pariser Platz",
               "short_name" : "Pariser Platz",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Mitte",
               "short_name" : "Mitte",
               "types" : [ "political", "sublocality", "sublocality_level_1" ]
            },
            {
               "long_name" : "Berlin",
               "short_name" : "Berlin",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Berlin",
               "short_name" : "Berlin",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Deutschland",
               "short_name" : "DE",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "10117",
               "short_name" : "10117",
               "types" : [ "postal_code" ]
            }


It would be great to extract the sublocality_level_1, locality and administrative_area_level_1 info and write it into the fields right after the geocoordinates.

Any ideas how to do that?


Last but not least: We are running LimeSurvey Version 2.05+ Build 140320 (sadly the update processes at the institution I am working are a little bit complicated, so there is no chance to update to a current version).

Any help is very much appreciated!

Thanks a lot!
Hulotte
Attachments:
The topic has been locked.
  • Hulotte
  • Hulotte's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 3 weeks ago #180994 by Hulotte
We could solve it. I'll post the solution here tomorrow...
The topic has been locked.
  • Hulotte
  • Hulotte's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 6 days ago #181594 by Hulotte
Nearly forgot to post the solution:

Code:
<script charset="utf-8" type="text/javascript">
 
$(document).ready(function() {  
  var mapQ = $('#question{QID}');
  var mapInput = $('input.text.location', mapQ);
  var mapSGQA = mapInput.attr('id').replace(/answer/, '').replace(/_c/, '');
  var map = gmaps[mapSGQA+'_c'];
  var marker = gmaps['marker__'+mapSGQA+'_c'];
  var addressQ = mapQ.prevAll('.text-short:eq(0)');
  var addressInput = $('input.text', addressQ);
 
  // Add a "Search" button
  addressInput.after('<br><button class="geocode" type="button">Get geocoordinates</button>');
 
  // Wait for the maps to load
  google.maps.event.addListenerOnce(map, 'idle', function(){
 
    // Initialize geocoder
    var geocoder = new google.maps.Geocoder();
 
    // Geocode look-up function
    function codeAddress() {
      var address = addressInput.val();
      geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
      // Just confirming the address found by geocoding is appropriate
      // if(window.confirm("Address found: " + results[0].formatted_address+". Is it correct?"))
      {
        // Record the formatted address into the address field
        // addressInput.val(results[0].formatted_address);
        // capture geolocation
        var geoCoord = results[0].geometry.location;
        // capture admin boundaries
        var level_1 = "", level_2 = "";
        results[0].address_components.forEach(function(component){
          if(component.types.includes("administrative_area_level_1")){
            level_1 = component.long_name;
          }
          if(component.types.includes("administrative_area_level_2")){
            level_2 = component.long_name;
          }
          if(component.types.includes("sublocality_level_1")){
            level_3 = component.long_name;
          }
        });
        var lat = Math.round(geoCoord.lat()*10000)/10000;
        var long = Math.round(geoCoord.lng()*10000)/10000;
        // Move the map and marker
        map.setCenter(geoCoord);
        marker.setPosition(geoCoord);
        // Record the new position &amp; administrative boundaries
        mapInput.val(lat+ ";" + long + ";" + level_1 + ";" + level_2 + ";" + level_3);
        // $('#answer{SGQ}').val(lat + ';' + long + ";" + level_1 + ";" + level_2);
      }
    } 
    else {
      alert("An error occurred. Error status: " + status);
    }
  });
}
 
$('button.geocode').click(function(e) {
  codeAddress();
});
});});
</script>

Hope this helps!
The following user(s) said Thank You: Joffm, cdorin
The topic has been locked.
More
4 years 11 months ago #182109 by cdorin
Your solution is really beautiful. I will put it into my to-do tasks (adding it into the manual). Thank you for also helping other LimeSurvey community members!

Manual: manual.limesurvey.org/LimeSurvey_Manual
Bugs tracker: bugs.limesurvey.org/my_view_page.php
If you self-host and need help, contact one of our partners: limesurvey.com
Please do not contact me via PM - thank you.
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 11 months ago #182592 by DenisChenu
But included feature didn't work with a valid google map API key ?
If it don't work : bug must be reported and fixed (not by me since i don't have a google map api key (and don't want to use google map …)).

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose