The more I use Drupal, the more I am impressed. But I need a little help with this. I am trying to set up a map of all users using the google map api v2. I download and installed location.module and the gmap module and got them working fine. I did not like the logic of storing address data. Since I use the profile module extensively, I was hoping the gmap module would work with that. Once I realized the location module installed a custom table for addresses and this was used by gmaps I thought there must be a better way to have this functionality but store the information in the profile module.
This is my idea...........
1. Add a single text box address field as a new field type in the profile module. (nobody likes to enter address in a several fields)
2. User inputs address like in google maps, eg "123 main st seattle wa"
3. use the google geocode api via php to geocode the address and return the address details in xml file in formatted to xAL address standard (internation standard for addresses used by google maps api, supports all countries) (I have this piece done already)
4. If address cannot be geocoded, give validation error "unable to find address lat/lon..." else store xml file in profile field "xAL address"
5. also store the pretty address and lat/lon in separate profile fields to be used easily elsewhere.
Once this data is in the profile fields, it would be simple to use the information elsewhere throughout the site, including dropping in a Google map for the users. This seems like a much more logical approach, but maybe I am missing something.
My questions....
1. Does this make sense and is it worth pursuing?
2. What is the best way to implement this?
Your thoughts good are bad are appreciated.....
John
p.s. I have never written my own modules, but I am willing to try this.
Comments
geocode module
After posting I did some further iterations to find a possible solution for me. -> http://drupal.org/node/71999
This "hook" system made me realize how amazing drupal is. I have been using Mambo/Joomla and Drupal blows them out of the water!
I am building my first module to take an address as a profile field and geocode it and store the returned xAL address in a profile field, and also store city, state, postalcode, and "pretty" address with all fields.
I also am using these....
http://api.drupal.org/api/4.7/function/hook_user
and the module handbook
I can't believe it, my first post not so long ago was "how to enable search" and now I am talking about hooks and stuff... I've been drupalized.
Look at the Gmap module
Have you looked at the Gmap module? Or the location module? Both enable these functions in part. Check out the mapping group, too: http://groups.drupal.org/mapping
That being said, I've been looking at the idea of creating a new userlocation.module that would enable multiple locations per user (home, work, current location, etc.). Part of this would also be mapping of location fields to profile fields -- so the actual data is still stored in the profile fields, is searchable, etc. Check the vcard module for an idea of what a mapping interface for profile fields looks like.
I already did install gmap and location module...
Hi Boris, thanks for the comments, but if you look at my first post (albeit not worded very well) I did install the gmap and location module. I didn't like the fact it did not work with profile fields, which is where I would think the address details should go. My plan is too create a module where the user has one text field to enter an address like 123 main st seattle wa (similar to google maps) and the google api would return the formatted address xAL and lat/lot. eg.
{
"name": "1600 Amphitheatre Parkway, Mountain View, CA, USA",
"Status": {
"code": 200,
"request": "geocode"
},
"Placemark": [
{
"address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
"AddressDetails": {
"Country": {
"CountryNameCode": "US",
"AdministrativeArea": {
"AdministrativeAreaName": "CA",
"SubAdministrativeArea": {
"SubAdministrativeAreaName": "Santa Clara",
"Locality": {
"LocalityName": "Mountain View",
"Thoroughfare": {
"ThoroughfareName": "1600 Amphitheatre Pkwy"
},
"PostalCode": {
"PostalCodeNumber": "94043"
}
}
}
}
},
"Accuracy": 8
},
Point: {
coordinates: [-122.083739, 37.423021, 0]
}
}
]
}
I feel it would be a better user experience not having to enter data in multiple fields and a better way to store data because I get a nicely formatted address back that I can store, use, search, etc. Am I missing something?
Let's make user location?
OK...understand where you're coming from.
I see what you're saying about a single address entry field (like Google). I don't know if I agree with the UX -- I know that depending on where I put (for instance) my apartment number, this might be something that Google would choke on.
Also, regardless of input, once you get the info back from Google, it should ideally be mapped to individual fields in the profile / database. This makes it much easier to, e.g., filter by country, state, city, etc.
As I said, check out the vcard module for an example of linking data to profile fields.
good advice
Very good comments. After considering what you said, I agree that it will be better to have a "normal" input for addresses to avoid the google issues. Plus, this doesn't make us completely dependent on google for address information, ie. user in Bolivia that google knows nothing about will not be able to store an address under my original idea. Also, I see what you mean about storing data as individual fields, I was going to do that for city, state, country, but I should do that for all the relevant information. As far as I understand (very little) the xAL address information that comes back from google, the fields can vary (greatly sometimes) country to country because address info is so different, so what would be the best way to store all of that information?
Based on your comments here are my thoughts now.
My goal:
1. Store a user address(s) information using the profile (with field mappings like vcard)
2. As an option for each address, geocode via google map api to get lat/lon and xAL formatted address.
3. Store addresses in a very internationally friendly way (if possible) using standards, even though my particular use is just for North America right now.
As I am writing this, I wonder if it makes more sense to just create specific profile fields in the profile table rather than mapping existing fields. The reason I say this... we could set up the required fields needing for geocoding and ensuring we have all the necessary fields for a proper international address. I would assume this would be easier for someone with a fresh install but not helpful for someone with an existing app with address data in the profile or location module. If so we would need a kind of import function using mappings.
I might be in way over my head on this one. I am sorry if I have stupid ideas, I am just now starting to understand how drupal works and I am more of "copy&paste&editer" than a true programmer.
by the way, is there a way on these forums to "watch" a topic so I get email updates? I searched around but didn't find anything.
other discussion on this topic
http://groups.drupal.org/node/512
More notes on address / user location
Internationalizing address fields: this is a big task...we should start by something as simple as:
* Address1
* Address2
* City
* State/Region
* Country
There are databases of both cities and countries, so we could even do something interesting like ship with DB info for that, including lat/long for the middle of cities. You could do a type-ahead / autocomplete for that.
Past that, we need to capture address formats per country...check out Mac OS X AddressBook, where this is built in.
Generating profile fields from user location: sure...on install we could have the option to generate the appropriate fields in profile. Essentially, just skip the mapping interface for starters, and have that as an advanced option. Hmmm. Need to think on this.
Lastly, there is talk in the Mapping group about separating out geocoding into a separate module. We should do the same...rely on gmap module to handle the Google API, and we just pass the address info and get back geolocation. Different countries or solutions could be then plugged in.
Don't apologize...there are no stupid ideas, only learning.
email updates: nope....you can use your tracker, but it means coming back and refreshing that page at this point.
Cart before the horse
Thanks for your help to a newbie Boris. I came down off the mountain last night and realized that data I get back from Google is really nothing more than I collect from the user. So I decided to start coding something. I know this is a little ahead of the game, but before I start to help on a project I felt I need to code something on my own from scratch. This is what I have so far.
*Street
*Additional (these could be easily changed to a desc that is internationally more friendly, perhaps address1&2)
*City
*State/Province (maybe I should change to region)
*Postal Code
*Country
*Set Lat/Lon Coordinates
- Auto (default)
- Manual
*Lat
*Lon
I currently have a basic module for this working!! (it is not much, but for me I am happy)
This is what it currently does.
When a user registers it prompts for address, checks google and sets lat/lon. If unable to set lat/lon presents message based on google maps api, but stills saves address without lat/lon.
If a user upates his address it performs the geocoding again, unless they have "Manual" set for lat/lon
I am going to implement a variable $addresstype or something, so if you want a Home, Business, School address in your profile, just copy module 3 times and change $addresstype to Home, Business, etc. We could of course code something to "make new address type", but that will be later, I just considered multiple types when posting. I will post the code I have in just a minute once I finalize some things so you can look at it. It is a first for me, so I am sure there is a lot of mistakes. We could add additional options in the future to set lat/lon Auto, manual, by city (using maxmind data), etc, etc.
o.k here it is but I am having a problem
My first crack at this profileaddress module is here including a screenshot.... (because I like screenshots)
link temporarily removed while sort out some issues.
I am having a problem right now. It works fine on my test install, but on my other install the hook_user function is not recognizing any of the &$edit array variables. If I do a print_r on the array $edit, it shows all the proper fields, but they are empty, hence it can't geocode the address in the users input form. I am sure I am doing something stupid, but I am not sure what yet....
the one thing I am sure is a little hacky is embedding the the country and province/state list in the profile_fields table instead of its own table, but I wanted to avoid having to modify the existing profile module, and this was the only way I knew how.
Boris, I hope this is what you had in mind for the "user location module"? If not, don't worry, we can start from scratch, but it already has been a good learning experience.
John
---UPDATE---
The above module now works for me, but... I had to change to the name of the module back to the original name I gave it which was geocode.module, not profileaddress.module, which is what I wanted. I don't know why that works. It would not work when it was named profileaddress.module and the hook_user function was also name profileaddress_user. I changed both the module name and function name back to geocode... and it works. I am not sure why yet.
I just re-read your previous post about geocoding and using gmaps api. It makes sense to have separate modules, but the gmap api requires you to install the gmap.module which is more than I want for just geocoding. I would just like to geocode an address, nothing else. Once the lat/lon data is in the profile, people can do whatever they want with it. The module I created, does geocoding via google, but could be expanded to do geocoding by other methods if google fails, city/country data, click on a map, ip address location, etc.
There should probably be a separate module/webservice just for geocoding. Send address, ip and get back lat/lon, accuracy, and source of lat/lon. eg.
send 123 main st, vancouver, bc, ca returns 47.0000, 96.0000 accuracy=8, source=google
or london, england returns lat 0.0 lon 1.0 accuracy=4, source ip_address
p.s. again i am sure I am making comments that make an experienced drupal user cringe, but am trying to learn/understand.
geocode module
Boris, could you point me to link where they are discussing a separate geocode module? I can't seem to find it.
I want to comply with this http://drupal.org/node/23789.
So I wonder if it still makes sense to create a geocode and a profile address module?
I know it might seem like I don't want to use the existing gmap module, but I just don't need all of its functions, especially being tied to the location module. I always would like to use or help to update an existing module if available.
If someone is working on a pure geocoding api module (which makes total sense to me now to have this), I would interested in using or helping to develop it.
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
google maps api
maxmind city to lat/lon database if present
ip to lat/lon database if present
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.
This could be very useful for a lot of applications, I think. Maybe someone is already working on it, but I can't find it yet.
Or perhaps we could work together and I could work on the geocoding piece and whatever other help is needed.
Away from computer for weekend
So don't have time to look through your massive postings in detail :P -- good stuff! Will look into when I get back to work tomorrow.
Probably best to move this discussion over to http://groups.drupal.org/mapping -- they're discussing further advancement, geocoding, etc.
moved conversation over here...
http://groups.drupal.org/node/781
Screenshot
Thanks Boris, I will move this discussion over the google maps group.
Here is a screenshot of what I have working currently
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.
International Address Format
Here's what we used to do at a large enterprise company I worked at for 9 years:
1. We had a scrollbox for country.
2. Based on the country selected, the address format would change.
What is needed?
We need one person from each country to provide an address format -- or we need to create a module where people can add address formats. I can't code but would be happy to work with a coder.