Gmap.module and Geocoding

Events happening in the community are now at Drupal community events on www.drupal.org.
webgeer's picture

Google Maps API has added the ability to Geocode (translate addresses into lat/long's). I am trying to figure out how I should incorporate it into the GMap.module.

I am thinking that maybe I will add a php function gmap_geocode($address) and also add a javascript function to gmap.js gmapGeocode(address) so that geocoding can be done either server side or client side depending on the application.

Initially at least these functions will just be API functions. Hopefully, I can find some time to to some changes to the macrocreator and I will incoroprate the add point at address into that.

What do others think, and how do you forsee using this, or alternatively, do you think I should leave this alone, and let geocoding stay the territory of the location.module?

Comments

Best case..

zacker's picture

location module should have a hook that allows external geo-coders to geo-code addresses. Then GMap module could implement the first geo-coder (google).

location module has geocoder

dado's picture

but it is disabled by default. user can enable by uncommenting 1 line of code. for US, ankur is using geocoder.us i think. Licensing concerns prevented him from releasing if I understand correctly. See here
http://drupal.org/node/53782

Geocoding and location.module

webgeer's picture

I am aware of the geocoding in location module. To be honest, I never got it to work for me. I looked into trying to get it working, but decided that it wasn't worth my effort (for what I wanted anyways). I'm thinking that initially anyways I am going to concentrate on doing the geocoding on the javascript side -- how this will work is that below the lat/long fields there will be a field for address, when you fill it in it will then update the lat/long from the geocoded value, the address will not be saved with the node it is just used to get a lat/long. This combined with the recently submitted patch for gmap.module (that I still have to look over and test see http://drupal.org/node/69243 ) will make location.module entirely unnecessary for doing lat/longs for both nodes and users.

I think for most users, this will be a more satisfactory method. It will not have all of the capabilities of location.module (which will still be an option if you want to use it), but it will be much lighter and will provide the functionality most will want.

geocoding using location module

dado's picture

i got it working. the problem seems to be that while the geocoding functions are there, they are (1) commented out and (2) not hooked up. I had to invoke the proper function in my own custom module as follows

function mymodule_nodeapi($node, $op, $teaser) {
  //if we are inserting or updating a location enabled node, and lat/lon not defined, attempt to geocode it
  if (($op == 'insert' || $op == 'update') && $node->location) {
    //if this node is location enabled, and lat/lon not defined, attempt to geocode it
    if (function_exists('location_latlon_exact_us') && (!$node->location['latitude'] || !$node->location['longitude'])) {
      $latlon = location_latlon_exact_us($node->location);
      if ($latlon['lat'] && $latlon['lon']) {
        watchdog('content', 'mymodule: added latitude &amp; longitude for <b>' . $node->title . '</b>');
        $node->location['latitude'] = $latlon['lat'];
        $node->location['longitude'] = $latlon['lon'];
        $node->location['source'] = LOCATION_LATLON_USER_SUBMITTED;
      }
    }
  }

i will say that some ajax-based geocoding capability would be cool. but it would be best if it were integrated into the location module's fields rather than requiring filling out of some gmap specific locative fields that are otherwise not used.

Sort of my plan...

webgeer's picture

That is sort of what I figured I would have to do. Didn't seem worth it to me, as very few of locations for any of my sites would be in the US.

Currently the AJAX-based geocoding does not work with location.module, it only works, if you use the gmap_location.module's built in location functionality. I think this is quite appropriate. After all location module is designed to have its own geocoding, and that should probably be expanded rather than using the custom function.

I did set-up the functions in mind so that if there was a desire to setup ajax geocoding for the location module it wouldn't be too difficult to do. The way it would be set up is there would be a button added above the map and below the location fields and when you click the button, it would update the lat/long based on the information in the location fields. I have started working on this, but I hit some snags and it isn't a very high priority for me, so I didn't go any further.

the geocoding in javascript is in cvs

webgeer's picture

The cvs version of gmap_location.module now includes geocoding using the Google Maps API. The module has also been redesigned to work without location.module (thank you ahoeben).

In order to use the Google API geocoding, you will have to disable the location.module and enable setting a location using gmap.

[edit add comment below]
If you use location.module with this version of the module you will need to apply the patch at: http://drupal.org/node/69449

Just reporting another reliable comment about this:

marcoBauli's picture

Geodan wrote on drupal.org/node/60049:

I think that's a good idea to make geocoding optional. I'd actually be in favour of moving the geocoding capabilities to a geocoder.module or something and use location.module as an API only. The same should then apply for mapping capabilities, map links etc.

User registers, and voila -- they're on the map!

DaveNotik's picture

I'd like to let new users register, enter their location (amongst other information), and then display on a map.

Seems like a straight-forward scenario, yet I can't get it to work.

With this new geocoding stuff, the user is required to go to edit their account and can enter their address which is then geocoded to a certain lat/long, save, and they're on the map. Cool, but most users won't edit their account after the fact, what if I want to make it required, and seems unintuitive.

How can we make it so that they can enter their address on the registration form, and they're now on the map.

I tried gmaps + gmaps_location + location + views and many combinations thereof, to no avail.

I also looked at posts like http://drupal.org/node/63557#comment-140446 and http://drupal.org/node/75749, to no avail.

I looked at Zack's mashup (http://www.zacker.org/screencast-drupal-mashup-machine), to no avail.

Again: user enters their address, they're now on the map. Isn't that the scenario many of us are shooting for?

--D

geocode module

Barleyman's picture

Hello All,

I started this thread a few days ago http://drupal.org/node/75749#comment-141273 (before Boris referred me here) about geocoding address data (see summary below). Basically I am looking to have address details collected and stored via the profile module and have those addresses automatically geocoded.

I realize the gmap module can do geocoding as well, but I really don't need all of the other functionality that it currently offers.

(summary of previous thread with Boris) - As stated above already, it seems to make sense to have a separate geocoding module that can be used by any application, including possibly gmap, location, and our profileaddress, etc. It would also give you the ability to map all ip addresses of people currently online.

I think it would be pretty useful to have a geocode module where you could pass all the variables necessary to help geocode an address...

myfunction_geocodeapi (Address, ipaddress, city, region, country)

first the function checks which variables it has been given, then trys to geocode via

  1. google maps api
  2. maxmind city to lat/lon database if present
  3. ip to lat/lon database if present
  4. etc, etc we could add additional sources, which allows us not to be tied to a single data source.

and then returns the following ("success", "lat=40", "lon=96", "source=googleapi", "accuracy=address level")
or ("success", "lat=40", "lon=96", "source=citydatabase", "accuracy=city level")
or ("success", "lat=40", "lon=96", "source=current ip address", "accuracy=ip level")
etc, etc.

The user could also specify to use "google", "maxmind", etc exclusively if he or she wanted to.

I currently have a proof of concept working:

http://seattle911.com/forums/profileaddress.png

All data is stored in the profile including lat/lon and the address is automatically geocoded when a user is updated or created. With an option to set Lat/lon manually. This is done via a profileaddress module and a geocoder api module (only integrated with google maps api currently) and it allows for multiple address types in the profile, like, Home, Business etc. It basically accomplishes what davenotik@drupal.org was asking for, users register and they are geocoded. Now it is just a matter of using that lat/lon data on gmap, etc.

My question is, would anyone be interested in working on or using a geocoder module, that could be called by other modules? And how best would we integrate that with the gmap project.

geocode.module - why

Anonymous's picture

geocode.module +1

The work that has been done in the gmap.module and location.module rocks. I'm now just stumbling down the multimodule mashup route and feel a case could be made for integrating the geocoding code in gmap and location and some of the work by barleyman (above) into a very useful new geocode.module (api). [barleyman - have you posted a link to your code yet or placed it in cvs?]

Background
After having tried both the location.module and gmap.module geocoding, I'm warming to the idea of a stand-alone geocode.module. After several attempts, including creating mymodule described later in this tread, I was not able to get geocoding for google to function in the location module. [In my opinion geocode.us should be avoided due to licensing issues. If you wish a deeper eduction on creative commons licenses, specifically the issues surrounding non-commercial use, see http://lists.ibiblio.org/pipermail/cc-licenses/]. I had much better luck in the gmap module set, with successful geocoding for users, but geocoding for nodes requires me to turn off the location.module, which I cannot until I replace the location_views.module. [I did test this feature with location.module off and it does work - thanks webgear.]

Reasons for a standalone geocode.module (api):
(1) geocoding is a discrete action that can be reused by several modules. Location and gmap modules are one set of examples, but profile, event, cck and many other modules can be geo enabled with a lighter geocoding footprint..

(2) Address information gathered in a standard xml format may also be redistributed in that format with less verification overhead. This means we can distribute both the lat/lon xml/rss in standard formats and the address in standard formats. (vcard, xml, rss). [Thanks barleyman for the examples]

(3) geocoding from several services allows for greater flexibility. For some time google's geocode seemed not to handle zip codes. Now it does. Yahoo is building strength in its API offerings. Countries not covered by one service may be covered by another service.

(4) geocode_views.module - The proximity search tools linked to the location_views module are great. A geocode_views.module could take these ideas further by enabling proximity searches by zipcode, city/state/country, and address inside a single service verified line.

(5) Single line input of address information is more user friendly. This allows for smaller real estate on a new user/node. We then could populate a more comprehensive Location/coordinates address/map/latlon page that could be hidden behind a tab.

(6) A standalone module may simply focus our minds. Gmap and Yahoo mapping APIs are accelerating. For example I have just deployed marker drag and bounce on my site (example:http://fatatlas.com - create content - wiki page). Very nice. Getting the user interaction scenario right is very tough on a map. Gmap.module and location.module could both the improved faster by taking the geocoding interaction off the table into a stand alone module.

Just some thoughts.

Some code for get geocoder, hope help you.

seide's picture

I just wrote some codes to get the latitude and longitude from google geocoder at localhost,
it is not well tested but worked by me. I hope it is helpful for you.

<?php
/* The follow is the code for getting latitude and longitudegeocoder */

function location_geocode_gmap($location, $country){
 
$location_geocode_gmap_url="http://maps.google.com/maps/geo?q="
                            
.implode("%20", explode(" ", $location['street'])).'+'
                            
.implode("%20", explode(" ", $location['city'])).='+'
                            
.$country
                            
."&output=csv&key=".variable_get('googlemap_api_key', '');
 
$content=explode(",", file_get_contents("$location_geocode_gmap_url"));

 
//maps.google.com return a content with csv form, which is seperated with ",",
  //the 2-th parameter is the latitude, the 3-th parament is longitude.
 
return array("lat"=>$content[2], "lon"=>$content[3]);
}
?>

The introduce:
1.parameter:
a. $location:
It is a array variable from location module,
you can also use your own array variable,
item for street and city must exist in the variable.
For example:

$location=array("city"=>"Dortmund", "street"=>"Kamp str 10");

b. $country:
It is the name of country, for example

$country="germany";

2.return:
function return a array with lotitude and longtitude.
For example, using code:

$myPoint=location_geocode_gmap($location, $country);

then, $myPoint[0] is lotitude and $myPoint[1] is longtitude.

3.
It works automatic by your google map api key,
which is registed in the gmap module.

where do I call this

nyumbani_yangu's picture

Ok, your geocode snippet looks as if it translates a given address (through location module) to lat/long.

Now, whats the trick , can you tell me exactly what needs to be done to make the marker come out?

ie:

1) I place the function you provide in location module
2) Where is the function called?
3) Where do I set the google map?

Can this only be done for user profiles or will it apply to all nodes ?

WOW! I used module like this

alex12's picture

WOW! I used module like this from phpclasses.org for ip location service development. Google Maps is one of the greatest services that I've ever seen.

drupal.org/project/gcg

****Me and Drupal :)****
Clickbank IPN - Sell online or create a membership site with the largest affiliate network!
Review Critical - One of my sites

drupal.org/project/gcg

giorgio79's picture

sorry, double post

****Me and Drupal :)****
Clickbank IPN - Sell online or create a membership site with the largest affiliate network!
Review Critical - One of my sites

Help with Gmap

cwittusen's picture

I'm trying to something seemingly easy but it appears to be an uphill battle for me.

  1. I have created a content type called Map
  2. I made sure I could use the location feature in the content type and I enabled it to input the regular address part
  3. When I try it out, I put in the values of an address and then submit it but I don't see a google map, instead I see a link to google map
  4. I created a view, with gmap:view and added the required fields of long and lat (not sure why you have to add this because I don't want it to be displayed)
  5. I review the view but to my dismay, it only displays a map of USA as set in the gmap configuration with no markers what so ever.
  6. I continue to pull my hair out, bit by bit but that doesn't help.

I posted this here because you guys seem to have this whole thing pegged and seem to understand it in detail. Hoping for some assistance.

Regards,
Chris W

Regards,
Chris W

3: Yeah, that's a really old

bdragon's picture

#3: Yeah, that's a really old part of location that hasn't been updated yet. I really need to add an option to display an actual *map* instead. Posted feature request @ http://drupal.org/node/305561

#4: This is because I originally didn't understand how to add additional fields to the query programatically. I need to revisit this. The original idea was to allow it to be flexible enough to use with any sort of storage, but there are probabaly ways to simplify this.

#5: Is there a url I could look at?

???

bdragon's picture

Err, what happened THERE?

markdown nuttiness

greggles's picture

The # is an h1 tag, so "#3" becomes an h1 tag around 3...

You can use a different input format or put a \ in front of the items that markdown is based on.

It's a bit sad but this

danielb's picture

It's a bit sad but this module still doesn't geocode when it's meant to. I have looked through all the code. I see a relevent bit in hook_user commented out - but I do not see any other geocoding stuff in the entire module that would relate to content/nodes.

So I have written this hook_nodeapi implementation to do it

function bfx_nodeapi(&$node, $op, $teaser, $page) {
  switch ($op) {
    case 'insert':
    case 'update':

      foreach ($node->locations as $key => $location) {
        if (!$location['locpick']['user_latitude'] && !$location['locpick']['user_longitude'] && !$location['delete_location']) {
          $geocode = gmap_geocode($location['name'].", ".$location['street'].", ".$location['additional'].", ".$location['city'].", ".$location['province'].", ".$location['postal_code'].", ".$location['country']);
          if (is_array($geocode) && $geocode['status'] == 200) {
            $node->locations[$key]['locpick']['user_latitude'] = $geocode['latitude'];
            $node->locations[$key]['locpick']['user_longitude'] = $geocode['longitude'];
          }
          else {
            drupal_set_message("Unable to contact google map service.", 'error');
          }
        }
      }

      break;



  }
}

Please consider adding this to to the gmap/location modules - as the GUI clearly states that behaviour like this will happen - and yet it doesn't.

Sure it does

michelle's picture

I have location/gmap installed and it geocodes just fine. I couldn't tell you which module is doing it as they are so intertwined but one of them does. I think it might be location, but I'm not sure.

Michelle


See my Drupal articles and tutorials or come check out the Coulee Region

Wow guys, this is just the

mike123106's picture

Wow guys, this is just the thread I was looking for!

I imported (manually) thousands of nodes from sql database and they all have location. I want to GEO code their lat/long from the addresses. When I use the website and simply add a new node, the geocoding works fine. However, since all these were imported to the database somehow the "encoding" process got skipped.

So here I am. I have tried this solution as stated in the above thread:

function mymodule_nodeapi($node, $op, $teaser) {
  //if we are inserting or updating a location enabled node, and lat/lon not defined, attempt to geocode it
  if (($op == 'insert' || $op == 'update') && $node->location) {
    //if this node is location enabled, and lat/lon not defined, attempt to geocode it
    if (function_exists('location_latlon_exact_us') && (!$node->location['latitude'] || !$node->location['longitude'])) {
      $latlon = location_latlon_exact_us($node->location);
      if ($latlon['lat'] && $latlon['lon']) {
        watchdog('content', 'mymodule: added latitude &amp; longitude for <b>' . $node->title . '</b>');
        $node->location['latitude'] = $latlon['lat'];
        $node->location['longitude'] = $latlon['lon'];
        $node->location['source'] = LOCATION_LATLON_USER_SUBMITTED;
      }
    }
  }

I put this in my own module but this seems to not do anything.

I have also tried this:

function bfx_nodeapi(&$node, $op, $teaser, $page) {
  switch ($op) {
    case 'insert':
    case 'update':

      foreach ($node->locations as $key => $location) {
        if (!$location['locpick']['user_latitude'] && !$location['locpick']['user_longitude'] && !$location['delete_location']) {
          $geocode = gmap_geocode($location['name'].", ".$location['street'].", ".$location['additional'].", ".$location['city'].", ".$location['province'].", ".$location['postal_code'].", ".$location['country']);
          if (is_array($geocode) && $geocode['status'] == 200) {
            $node->locations[$key]['locpick']['user_latitude'] = $geocode['latitude'];
            $node->locations[$key]['locpick']['user_longitude'] = $geocode['longitude'];
          }
          else {
            drupal_set_message("Unable to contact google map service.", 'error');
          }
        }
      }

      break;



  }
}

But I am constantly getting an "Unable to contact google map service" error. I know it can contact them just fine. I am guessing it has something to do with $location['locpick']['user_latitude'] I do not know what locpick is. Also I am not using user locations im using node locations. I have a CCK type called "wifi".

I AM fairly new to drupal... so any help would be greatly apreciated! I am hoping I can just Administer>content and check all and "publish" and make all the locations encoded with lat/long. I have tried some things with load module and save, but that didn't work.

Thanks a bunch!

A note to add - without any

mike123106's picture

A note to add - without any of these special modules, if I just go into each node and change the address by one number, and save it geocodes. Then I edit, and change it back to the original address and it geocodes the correct address. I wish I could just call whatever process is happening, for all of my nodes. Unfortunately just "publishing" your nodes does not re geocode anything. Something has to change.

Location and Mapping

Group organizers

Group categories

Wiki type

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: