Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gisgraphy Geocoder #34

Merged
merged 10 commits into from
Feb 22, 2018
Merged

Add Gisgraphy Geocoder #34

merged 10 commits into from
Feb 22, 2018

Conversation

gisgraphy
Copy link
Contributor

Add Gisgraphy Geocoder as a new provider (for geocoding forward and reverse and autocomplete)
Documentation need to be updated.
Some technical choice can be discussed as

  • the CountryInfo class
  • what to do if the queryType is not correct (we then consider that it is geocoding), maybe throw an exception can be better
  • put the DTO in a specific package can improve lisibility.

A try in real environement can also be necessary

Every comments are welcomed

@karussell
Copy link
Member

Thanks a lot! Will have a look, especially in the choices you mean.

}

@JsonProperty
public void setGisgraphyGeocodingUrl(String gisgraphyGeocodingUrl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here URL is Url, but in the converter.yml it is URL. Also the reverseGeocodingURL is all in upper case as well. Since the other services use Url, it might be the best to have everything as "Url"? We could also rename everything "URL", since URL is the common acronym.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's interesting that this wasn't picked up the tests. Maybe we need better integration tests? When I tried to start the server locally it wouldn't start due to that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I rename all to Upper.

@QueryParam("limit") @DefaultValue("5") Integer limit,
@QueryParam("querytype") @DefaultValue("geocoding") String queryType) {
limit = fixLimit(limit);

Copy link
Member

@boldtrn boldtrn Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here it might be worthwhile to check if the parameter input is valid to sort out completely wrong input, like we do in AbstractConverterResource#checkInvalidParameter.

For example if you pass an empty q to a regular geocoding search, it will send a request to https://services.gisgraphy.com/geocoding/?address=&format=json&apikey=..., which will return in a 500 -> which returns "The geocoding provider responded with an unexpected error." to the user.

Copy link
Member

@boldtrn boldtrn Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: In this case I would have expected the server to return a 400 error code "Bad Request" and not a 500 "Internal Server Error". WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi

It make sense for the 400 status code. I need to update this on server side (later). Feel free to provide an issue with a tag 'enhancement' on Gisgraphy github repo

+ target.getUri() + " the provider returned: "
+ status.code + " - " + status.message);
throw new BadRequestException(
"error deserializing geocoding feed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid the code duplication here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I can :)

@boldtrn
Copy link
Member

boldtrn commented Feb 15, 2018

what to do if the queryType is not correct (we then consider that it is geocoding), maybe throw an exception can be better

I think it might be better to have it similar to the GraphHopper api with reverse=true|false and maybe add another parameter with autocomplete=true|false. That way users don't necessarily rewrite the request when using provider=gisgraphy.

@Timed
public Response handle(@QueryParam("q") @DefaultValue("") String query,
@QueryParam("lat") @DefaultValue("") String lat,
@QueryParam("lng") @DefaultValue("") String lng,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GraphHopper API uses point instead of lat,lng, do you think it makes sense to point instead? I think it would make it easier to integrate this for our users?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not, but I propose to put default value to "" instead of false as in ConverterResourceNominatim#handle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If autocomplete is true and so does reverse , do we
1/ force reverse to false
2/ ignore autocomplete and consider it is a reverse query
3 / throws an exception
4 / other

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Maybe if autocomplete==true and reverse==true then we could do an autocomplete with location bias :) ?

throw new BadRequestException(
"error deserializing geocoding feed");
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you mentioned, I think here should be indeed another else that throws and exception

public class ConverterResourceGisgraphy extends AbstractConverterResource {

// all webservices
public static final String ADDRESS_PARAMETER = "address";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be public?


@JsonProperty("label")
public String getLabel() {
StringBuffer addressFormated = new StringBuffer();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense to use formatedFull instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no formatedFull won't have the house number. Gisgraphy search for street and a street with house number is return. we don't store address in SolR but streets (it allow address interpolation and more)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain this a bit more? I tried to get a real live example and couldn't find any house numbers via gisgraphy?

I tried for example Universitätsbibliothek, Standort Stadtmitte, in OSM it contains a housenumber. When I looked it up via Gisgraphy fulltext, there is no house number. That doesn't trouble me, but I would like to avoid business logic in the geocoding-converter, if it's avoidable. The simpler the better :). This also means we don't have to update the geocoding-converter if any geocoding provider changes details about their implementation.

That's why I was asking about using formattedFull or for fulltext it seems to be fully_qualified_name.

this.formatedPostal = formatedPostal;
}

public String getDisplayName() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be better to use formattedFull?

Copy link
Member

@boldtrn boldtrn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for this PR! I added a couple of comments.

@gisgraphy
Copy link
Contributor Author

gisgraphy commented Feb 15, 2018 via email

@karussell
Copy link
Member

karussell commented Feb 15, 2018

ok, true.

Remove duplicate code
change Gisgraphy Ressource API (reverse and autocomplete instead of
query type, point instead of lat/long)
update tests
@gisgraphy
Copy link
Contributor Author

modifications done ! let me know if it is ok to be merged

@devemux86
Copy link

Also could use StringBuilder instead of StringBuffer where possible?

use string builder where possible
@gisgraphy
Copy link
Contributor Author

I have done changes to use string builder. Some changes has also been done to display zipcode in the label.

I remove WIP from the name of the PR ;-)

@gisgraphy gisgraphy changed the title [WIP] Add Gisgraphy Geocoder Add Gisgraphy Geocoder Feb 15, 2018
@gisgraphy
Copy link
Contributor Author

There is still some docs and README to update

@gisgraphy
Copy link
Contributor Author

README updated for Gisgraphy.

Everything ok to be merged ?

}

private void checkParameters(String query, boolean reverse, boolean autocomplete, String lat,String lng) {
if (query!=null && query.trim().isEmpty() && !reverse){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, the trim is a nice idea, haven't used that in AbstractConverterResource#checkInvalidParameter. Do you think it would make sense to reuse AbstractConverterResource#checkInvalidParameter and just add the autocomplete part to the check? I would like to avoid code duplication.

private checkInvalidParameter(boolean reverse, String query, String point, boolean autocomplete) {
   super.checkInvalidParameter(reverse, query, point);
  if (reverse && autocomplete){
    throw new BadRequestException("autocomplete is not available in reverse geocoding request, set reverse or autocomplete to false but not both");
}   

We could then move this code after the check, as this could create a index out of bounds exception for non empty points that don't contain a ' ,'?:

		String lat = null;
		String lng = null;
		if (!point.isEmpty()){
			String[] cords = point.split(",");
			 lat = cords[0];
			 lng = cords[1];
		}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok but the AbstractConverterResource#checkInvalidParameter has not the same parameters as ConverterResourceGisgraphy##checkInvalidParameter. Do you want me to modify the signature of AbstractConverterResource ?I don't think add the boolean autocomplete make sense since it means nothing for the AbstractConverterResource. but tell me (we are not force to use the autocomplete parameter)

has been done on server side to calculate the lable instead of client
side)
improve checkparameters (remove code de-duplication)
@boldtrn
Copy link
Member

boldtrn commented Feb 20, 2018

BTW: I have just seen that you used tabs instead of spaces. The whole codebase uses spaces, which will lead to ugly changelogs with the next autoformat. Most editors nowadays use spaces by default and also most language specs recommend using spaces. If it's easy for to changes this, it would be nice if you could do this, otherwise I can do this in another commit before merging.

new ConverterApplication().run(args);
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind to check the formatting? Sometimes there are 2 or 3 lines between methods. Is there a reason for this or can we just use one empty line?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also there is a change for this whole file, probably because of tabs vs spaces. It would be great if we could keep the changeset as small as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do it separately. I use Eclipse and appreciate if you can do it in another commit. thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I done it but not sure it is correct

if (point!=null && !point.isEmpty() && point.indexOf(",")>0){
String[] cords = point.split(",");
lat = cords[0];
lng = cords[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind to check the format here? These two lines use white spaces, all other lines use tabs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do the formatting separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have modified settings in eclipse to use space and reformat, hope it will be better.

target = target.queryParam(SEARCH_LIMIT_PARAMETER, limit);
}
return target;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to reduce the code duplicateion for the 3 buildTarget methods?

All 3 use these lines:

if (!apiKey.isEmpty()) {
			target = target.queryParam(APIKEY_PARAMETER, apiKey);
		}
		if (lat!=null && !lat.isEmpty()) {
			target = target.queryParam(LAT_PARAMETER, lat);
		}
		if (lng!=null && !lng.isEmpty()) {
			target = target.queryParam(LONG_PARAMETER, lng);
		}

2 use these lines:

		if (!radius.isEmpty()) {
			target = target.queryParam(RADIUS_PARAMETER, radius);
		}
		if (!country.isEmpty()) {
			target = target.queryParam(COUNTRY_PARAMETER, country);
		}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@QueryParam("country") @DefaultValue("") String country,
@QueryParam("limit") @DefaultValue("5") Integer limit,
@QueryParam("reverse") @DefaultValue("false") boolean reverse,
@QueryParam("autocomplete") @DefaultValue("false") boolean autocomplete) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add the locale parameter as well? The other 2 converters have a locale parameter.

AFAIK gisgraphy allows locale input only for autocomplete searches. So adding it might not make sense? WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no 'locale' is not managed for autocomplete (it is for the full-text web service, but not in suggest). There is a lang parameter but it has an impact on returned fields (and those fields are not returned by the suggest web service). This is not managed at all for geocoding and reverse web services. It might be an improvement but needs some code modifications on the server side that are not planned yet. We have to go without this first ;-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok no problem :), that's why I was asking.

* @author <a href="mailto:[email protected]">David Masclet</a>
*
*/
public class CountryInfo {
Copy link
Member

@boldtrn boldtrn Feb 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding this class, AFAIK you want to add the country to Gisgraphy? Should we then even add this class, wait until the country is available in Gisgraphy, or use the country code for now and switch to the country name, once it's available in the Gisgraphy API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping this code because other geocoder returns the country name and not the iso-3166-2 one. The code can be done but needs time. The goal is to have a first PR that match as best as possible to ease the migration of users that want to use Gisgraphy. Then we will improve it step by step (as for locale parameter). Gisgraphy is not to be a perfect equivalent to other providers, even if I think the proposed changes make sens. Gisgraphy has some fields that are not present in Nominatim (formatedpostal, azimuthStart, azimuthEnd, length,...) and I am not sure they modify their feed to match Gisgraphy. :-). hopefully, there are some improvements in Gisgraphy that can be done ;-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT @karussell, should we just use the country code or should we convert the country code into the actual country name?

Copy link
Member

@karussell karussell Feb 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with what @gisgraphy said 👍 (offering country name via this converter or did I misunderstood sth :)?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offering country name via this converter or did I misunderstood sth :)?

No that's correct :). Ok, let's keep it as it is.





Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lines added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed





Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lines added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed (bad habits to add few lines before adding code)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do that as well ;). I try to always check before committing that I remove them again.

@boldtrn
Copy link
Member

boldtrn commented Feb 20, 2018

Is there something missing to merge ?

Sorry for the multiple review rounds, I know it's tedious :). I added a couple more comments.

@gisgraphy
Copy link
Contributor Author

no problem, I appreciate review since it makes sense :) hope it will be ok.

clean code (remove empty lines)
refactor code to avoid duplicate code
}


@JsonProperty("house_number")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double empty lines above and below the getCountry :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

public class GisgraphySearchResponse {


private Integer numFound = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double Empty line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed





Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

@JsonIgnoreProperties(ignoreUnknown = true)
public class GisgraphySearchResult {


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

*******************************************************************************/
package com.graphhopper.converter.data;

import java.io.File;
Copy link
Member

@boldtrn boldtrn Feb 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove the unused import?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

private static final String SEARCH_LIMIT_PARAMETER = "to";
private static final String SEARCH_QUERY_PARAMETER = "q";


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

}



Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

private WebTarget buildAutocompleteTarget(String query, String lat,
String lng, String radius, String country, int limit) {
WebTarget target = buildBaseTarget(lat, lng, searchURL);
target.queryParam(SEARCH_QUERY_PARAMETER, query)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here a target = is missing or we have to remove the ; in the line above, also see the failing test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected

@boldtrn
Copy link
Member

boldtrn commented Feb 20, 2018

Thanks, the formatting looks correct now, you can always check in the files tab. Before there were huge changes in files where you only changed one or two lines.

I think once we fix the failing test, this PR should be pretty much ready to merge. We just need to decide how we handle the country code :).

tests are now ok.
@gisgraphy
Copy link
Contributor Author

modifications are done. For the country field, I plan to do server modifications soon and will propose a new PR when done

do we merge? :)

@Override
public String getName() {
return "graphhopper-nominatim-converter";
return "graphhopper-geocoder-converter";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch, thanks :)

Copy link
Member

@boldtrn boldtrn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for this nice PR. Will merge this now.

@boldtrn boldtrn merged commit c43c773 into graphhopper:master Feb 22, 2018
@karussell
Copy link
Member

Thank you all will now bring this into production - exciting :) !

@karussell
Copy link
Member

@gisgraphy is it already possible to search for parking places through this converter?

@gisgraphy
Copy link
Contributor Author

to search by name, the URL is something like http://services.gisgraphy.com/fulltext/?q=sebastopol&style=long&placetype=parking

or name / GPS : http://services.gisgraphy.com/fulltext/?q=sebastopol&style=long&placetype=parking&lat=48.8566101&lng=2.3514992

fulltext webservice is possible but the placetype parameter is not mapped in the converter

or by GPS position :
http://services.gisgraphy.com/geoloc/search?format=json&lat=48.856610100000005&lng=2.3514992&placetype=Parking

geoloc webservice is not available yet in the converter.

so it need some developpement

@gisgraphy
Copy link
Contributor Author

there is a lot of possibilities in Gisgraphy that are possible but this PR was a first one. maybe add an enhancement/issues to track this. I am currently busy and have no time to do that soon :(

@karussell
Copy link
Member

karussell commented Mar 26, 2018

Really no problem and no hurry. Will create an issue and maybe @boldtrn or I will create time for this

#46

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants