geocoder-php / Geocoder

The most featured Geocoder library written in PHP.
https://geocoder-php.org
MIT License
3.95k stars 516 forks source link

Could not execute query #857

Closed BillyFigueroa closed 5 years ago

BillyFigueroa commented 6 years ago

I am no longer able to query geocoder with the OpenStreetMap provider

Here is a snipper of how I am importing, declaring and using it all

use Geocoder\Provider\OpenStreetMap;
use Ivory\HttpAdapter\CurlHttpAdapter;

...

$this->geocoder = new OpenStreetMap(new CurlHttpAdapter);

...

// Build full address to grab the coordinates
$fullAddress = $currUser->address1 . ', ' . $currUser->city . ', ' . $currUser->state . ', ' . $currUser->zipcode;

try {
    $geoCoords = $this->geocoder->geocode($fullAddress);
   ...
}

The code breaks in this try logic. Did something change recently with OpenStreetMap and if so, did you guys go back and change older versions of geoccoder? I am having these issues on the version below

"name": "willdurand/geocoder",
"version": "v3.3.0",
"source": {
    "type": "git",
    "url": "https://github.com/geocoder-php/Geocoder.git",
    "reference": "ccc178e2984c0af24881faa0ffe515f20e5e8c23"
}

The error I see is the following...

Could not execute query "http://nominatim.openstreetmap.org/search?q=228+Nagle+Ave%2C+New+York%2C+NY%2C+10034&format=xml&addressdetails=1&limit=5"

but when I enter that into the browser it actually works but it is redirected to https. Could this have anything to do with the fact that https is not supported?

jbelien commented 6 years ago

Hello @BillyFigueroa ,

The Nominatim provider works just fine. I have no idea what's the OpenStreetMap provider but I suspect it's probably a really old one.

I suggest you to switch to Nominatim provider. It's the provider that queries OpenStreetMap database.

I also suggest you to switch to the last version of the Geocoder v4.0.0.

BillyFigueroa commented 6 years ago

@jbelien a simple "just upgrade and use the new providers" is not really an answer. I am not trying to be an a** but OpenStreetMap worked before with out needing to have some "Nominatim server" to use. Those are changes I seem to be forced into making with out upgrading. The issue I am having is, I can understand not supporting an old Provider, but with out me upgrading my version of this library, why did it stop working?

jbelien commented 6 years ago

I agree that "just upgrade and use the new providers" is not an suitable answer but I'm a recent contributor to Geocoder PHP and I have absolutely no knowledge about an OpenStreetMap provider (the one you seem to use) and so I can not fix that provider or even try to see what's not working.

The issue is probably the fact that OpenStreetMap decided to force the use of HTTPS ; including https://nominatim.openstreetmap.org/ and the "old" OpenStreetMap provider is probably not following the redirection from HTTP to HTTPS. We obviously have no control about what's happen on Nominatim side either.

BillyFigueroa commented 6 years ago

@jbelie I appreciate that. I did make a temporary fix to just simple add https to the url but I had to modify their code. I will look into Nominatin however setting up a server seems like a lot of work based on what I have read. Seems like you have to modify the server (Apache or Nginx etc). Do you have any Providers who do not need an API key? I will go read over the docs and see what the options are but just thought I d ask. If Version 4 has more options for that

jbelien commented 6 years ago

As long as you respect Nominatim Usage Policy, you can use Nominatim provider by directly send your request to https://nominatim.openstreetmap.org/ (this service does not require an API key) :

Requirements

  • No heavy uses (an absolute maximum of 1 request per second).
  • Provide a valid HTTP Referer or User-Agent identifying the application (stock User-Agents as set by http libraries will not do).
  • Clearly display attribution as suitable for your medium.
  • Data is provided under the ODbL license which requires to share alike (although small extractions are likely to be covered by fair usage / fair dealing).

To use https://nominatim.openstreetmap.org/ with the Nominatim provider, here is what you need to do :

use Geocoder\Query\GeocodeQuery;

$httpClient = new \Http\Adapter\Guzzle6\Client();
$provider = \Geocoder\Provider\Nominatim\Nominatim::withOpenStreetMapServer($httpClient);
$geocoder = new \Geocoder\StatefulGeocoder($provider, 'en');

$result = $geocoder->geocodeQuery(GeocodeQuery::create('Buckingham Palace, London'));

About the HTTP Referer and User-Agent, there is an open issue (#853) we are working on it.

Nyholm commented 6 years ago

As @jbelien suggests, this is not a change in the client/provider. I see that you are using version 3, it has not been updated in a year. I think there is an issue on the server side. If changing to HTTPS works then that is fine.

Also note that version 3 has gone end of life which means all the cool new stuff will only be added in version 4.

BillyFigueroa commented 6 years ago

@jbelien thanks. I will look at changing my code when I have time to try this. @Nyholm thanks. I will see if updating to version 4 using his example works for me. My fix temporarily fixes the problem. I just need the time to make the change and test in dev

romaricdrigon commented 6 years ago

I just had the same issue. It looks like Nomatim moved to https only, and Geocoder is not able to handle the "redirect" response he got, hence the "no results" issue.

To make the issue worse, the OpenStreetMap provider has an hard-coded URL you can't change. And if you are using some "old" Symfony version, you can't upgrade the bundle past 4.2.0.

The solution is then to add a custom provider which will use Nomatim (for 4.2.0 bundle):

services:
    app.geocoder.nomatim:
        class: Geocoder\Provider\Nominatim
        arguments:
            - '@bazinga_geocoder.geocoder.adapter'
            - "https://nominatim.openstreetmap.org"
            - "fr"
        tags:
            - { name: bazinga_geocoder.provider }

And then the bazinga_geocoder.geocoder service will work again. No need to register again the provider in the bundle configuration.

jbelien commented 6 years ago

Hello @romaricdrigon ,

I just had the same issue. It looks like Nomatim moved to https only, and Geocoder is not able to handle the "redirect" response he got, hence the "no results" issue.

Indeed, OpenStreetMap (and so Nominatim) decided to allow HTTPS only since a few months. But there shouldn't be any issue with the "redirect" ; if I'm not mistaken, that's not handled by Geocoder but by the "HTTP Client" you specify in the constructor !

To make the issue worse, the OpenStreetMap provider has an hard-coded URL you can't change.

As you can see in Nominatim.php#L68, you can provide whatever URL you want in the constructor.

romaricdrigon commented 6 years ago

Hello @jbelien,

Technically you are true, and you can do that with the latest versions, but with Geocoder bundle 3.xx or 4.xx you can't. Hence my workaround.

More specifically, your point is true regarding Nomatim provider, but that provider is not available on Geocoder bundle 3.xx or 4.xx. It has only openstreetmap: https://github.com/geocoder-php/BazingaGeocoderBundle/blob/4.2.0/DependencyInjection/Configuration.php With the hard-coded URL: https://github.com/geocoder-php/Geocoder/blob/v3.3.0/src/Geocoder/Provider/OpenStreetMap.php#L23

The default cache adapter in Geocoder bundle 3.xx or 4.xx does not follow redirect, I did not took a screenshot of the dump but that was clear. Hence the issue @BillyFigueroa and I had.

Again, the issue here is about being stuck on some old Geocoder (bundle) version, because we are using some Symfony LTS, previous Symfony 3.

jbelien commented 6 years ago

Oh okay, I get it now ! Sorry for the noise then and thanks a lot for your workaround 👍