Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
We had an issue geocoding a country with address field.
Only the country was given, in this case it was Indonesia (countrycode: ID).
When geocoding through Google, we get Idoha as result.
In the patch below, it supports for integrating the countries module OR add the country: [country code] to the query.
In both cases we get more accurate results.
Comments
Comment #1
michaelmol CreditAttribution: michaelmol commentedpatch attached
Comment #2
michaelmol CreditAttribution: michaelmol commentedComment #3
michaelmol CreditAttribution: michaelmol commentedThe patch includes a lot of code styling fixes (spaces, tabs etc).
The functional part starts from:
Comment #4
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedunfortunately this no longer applies
Comment #5
ptmkenny CreditAttribution: ptmkenny commentedComment #6
troybthompson CreditAttribution: troybthompson commentedI manually applied the country part of the patch and it solved my problem with El Salvador showing up in Switzerland. =^)
Comment #7
nagy.balint CreditAttribution: nagy.balint commentedRerolled the patch, works like a charm.
Comment #8
ptmkenny CreditAttribution: ptmkenny commentedI can confirm that this patch successfully uses the countries module to distinguish between countries.
Comment #9
Simon Georges CreditAttribution: Simon Georges commentedIf I understand correctly, with this patch, the country is added two times to the query (one using the current code, one at the end coming from the patch). Am I right?
Comment #10
Simon Georges CreditAttribution: Simon Georges commentedComment #11
joelpittet@Simon Georges I believe you are right regarding #9.
Maybe it should replace it? @ptmkenny or @nagy.balint
Comment #12
eelkeblokI stumbled upon this issue because it looks like I am working on the same project that led @michaelmol to open this issue. The patch applied in that project has evolved beyond the version in this ticket to solve a few more problems we ran into, basically to solve the problem noted by Simon Georges. I'm attaching that version here.
Also, I am planning to improve integration between Countries module and Geocoder in another way; it is currently not possible to have a location field on a country representing the location of that country (at least, while using Geocoder to automatically fill that field). Since that really also constitutes "Integration with Countries module" (the title of this issue), but really is in a completely different area, I guess I'll rename this issue to "Use Countries module to improve goecoding results" and open a new "Allow geocoded field on Countries entity" issue. Edit: Done, see #2376447: Allow geocoded field on Countries entity.
Comment #13
eelkeblokComment #14
eelkeblokComment #15
Simon Georges CreditAttribution: Simon Georges commentedI like the solution of this last patch, less intrusive. I'm just waiting for some people to confirm it works before committing. Thanks!
Comment #16
basvredelingI've taken another look at this... the patch works. But, the functionality overlaps with #2245189: Make address field country unambiguous. Difference being that this needs countries module to be installed. 2245189 just uses the country list which is also used in the installer and is part of Drupal core. We could include both because the countries module is bound to be more up to date than core /includes/iso.inc.
I've included a patch which implements both.
Comment #17
basvredelingI added another patch because using the official country name confuses the Google geocoder.
The new patch uses the name instead of the official name.
===
"Luxembourg" was passed as "Grand Duchy de Luxembourg" (and leads to a result in downtown Los Angeles)
"France" was passed as "French Republic" (and leads to the french embassy in Budapest, Hungary)
"Netherlands" was passed as "Kingdom of the Netherlands" (and leads to a place near Almaty, Kazakhstan)
Comment #18
joelpittetThis looks good:
#17 looks great!
Isn't this 'official_name' property not 'official'?
Comment #19
basvredelingBork, my bad. It should be
$country->name
, not$country->official_name
nor$country->official
. Good catch.Comment #20
PolHi all,
Instead of using '
if (function_exists('country_load')) {
', shouldn't we use entity_load('country', ... ) and remove the if condition ?We could try to find the results in cascade... first using entity_load('country', ... ) then using the default Drupal system ?
What do you think ?
Comment #21
PolLet me know what you think of this patch.
Comment #22
joelpittetThe patch looks great though I'd really advise against using a private function(denoted by the
_
), thought it's likely not going to change it's not part of the API. Can you switch it back tocountry_get_list()
?Comment #23
joelpittetTo be more clear: the fallback should be
locale.inc + country_get_list().
It gets the countries alter hook and is the proper API to be calling instead of the private function in iso
Comment #24
PolYou're absolutely right.
Can you let me know when you've tested this patch (especially with the entity_load() stuff) so I can commit it ?
Thanks!
Comment #25
joelpittetThanks @Pol for changing that up.
Well one thing that get's lost in translation with the removal of country_load() is that it uppercase the ISO code for comparison to normalize it using
drupal_strtoupper()
which is a UTF safe string uppercase(which is a bit overkill if we expect a 2 character iso code.Even though I like the idea, if
countries
is not installed it will be much slower to do a SQL/cache query with no results than it would to do afunction_exists()
so I'm back peddling on that idea. The string to array clean up is still good in my books though. Does that logic seem correct to you @Pol?Comment #26
PolI don't know I would prefer cleaner code even if it's a bit slower... So, what do you think we should do ?
Comment #27
joelpittetI really think we should use the function_exists() or module_exists() code. I'm bias as I'm big on performance but also I think it's cleaner because it's clear what the dependency is on that call being made. Sorry should have looked harder in #22
Comment #28
PolOk let's do this then.
Comment #30
PolOk it's done, I just replace
function_exists()
withmodule_exists()
.Comment #31
joelpittetAwesome, thanks @Pol