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

Osm channel reverse geocoding #1049

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fi.nls.oskari.search;

import fi.mml.portti.service.search.ChannelSearchResult;
import fi.mml.portti.service.search.IllegalSearchCriteriaException;
import fi.mml.portti.service.search.SearchCriteria;
import fi.mml.portti.service.search.SearchResultItem;
import fi.nls.oskari.annotation.Oskari;
Expand Down Expand Up @@ -29,17 +30,25 @@ public class OpenStreetMapSearchChannel extends SearchChannel {
/** logger */
private Logger log = LogFactory.getLogger(this.getClass());
private String serviceURL = null;
private String reverseGeocodeURL = null;
public static final String ID = "OPENSTREETMAP_CHANNEL";
public final static String SERVICE_SRS = "EPSG:4326";

private static final String PROPERTY_SERVICE_URL = "search.channel.OPENSTREETMAP_CHANNEL.service.url";
private static final String PROPERTY_SERVICE_REVERSE_GEOCODE_URL = "search.channel.OPENSTREETMAP_CHANNEL.reversegeocode.url";
private static final String PROPERTY_BBOX = "search.channel.OPENSTREETMAP_CHANNEL.search.bbox";

@Override
public void init() {
super.init();
serviceURL = PropertyUtil.get(PROPERTY_SERVICE_URL, "https://nominatim.openstreetmap.org/search");
log.debug("ServiceURL set to " + serviceURL);
reverseGeocodeURL = PropertyUtil.get(PROPERTY_SERVICE_REVERSE_GEOCODE_URL, "https://nominatim.openstreetmap.org/reverse");
log.debug("ServiceURL set to " + serviceURL + ", Reverse Geocode URL set to " + reverseGeocodeURL);
}

@Override
public Capabilities getCapabilities() {
return Capabilities.BOTH;
}

private String getUrl(SearchCriteria searchCriteria) throws UnsupportedEncodingException {
Expand All @@ -64,6 +73,15 @@ private String getUrl(SearchCriteria searchCriteria) throws UnsupportedEncodingE
return IOHelper.constructUrl(serviceURL, params);
}

private String getReverseGeocodeURL(SearchCriteria searchCriteria, Point point) throws UnsupportedEncodingException {
Map<String, String> params = new HashMap<>();
params.put("format", "json");
params.put("addressdetails", "1");
params.put("accept-language", searchCriteria.getLocale());
params.put("lat", String.valueOf(point.getLat()));
params.put("lon", String.valueOf(point.getLon()));
return IOHelper.constructUrl(reverseGeocodeURL, params);
}
/**
* Returns the search raw results.
* @param searchCriteria Search criteria.
Expand All @@ -90,7 +108,7 @@ private JSONArray getData(SearchCriteria searchCriteria) throws Exception {
* @return Search results.
*/
public ChannelSearchResult doSearch(SearchCriteria searchCriteria) {
ChannelSearchResult searchResultList = new ChannelSearchResult();
ChannelSearchResult searchResultList = null;

String srs = searchCriteria.getSRS();
if( srs == null ) {
Expand All @@ -102,6 +120,16 @@ public ChannelSearchResult doSearch(SearchCriteria searchCriteria) {
CoordinateReferenceSystem sourceCrs = CRS.decode(SERVICE_SRS, true);
CoordinateReferenceSystem targetCrs = CRS.decode(srs, true);
final JSONArray data = getData(searchCriteria);
searchResultList = createChannelSearchResult(data, sourceCrs, targetCrs);
} catch (Exception e) {
log.error(e, "Failed to search locations from register of OpenStreetMap");
}
return searchResultList;
}

private ChannelSearchResult createChannelSearchResult(JSONArray data, CoordinateReferenceSystem sourceCrs, CoordinateReferenceSystem targetCrs) {
ChannelSearchResult searchResultList = new ChannelSearchResult();
try {
for (int i = 0; i < data.length(); i++) {
JSONObject dataItem = data.getJSONObject(i);
JSONObject address = dataItem.getJSONObject("address");
Expand Down Expand Up @@ -130,9 +158,41 @@ public ChannelSearchResult doSearch(SearchCriteria searchCriteria) {
}
searchResultList.addItem(item);
}
} catch (Exception e) {
log.error(e, "Failed to search locations from register of OpenStreetMap");
} catch(Exception e) {
log.error(e, "Failed to convert JSONArray to ChannelSearchResult");
}

return searchResultList;
}
@Override
public ChannelSearchResult reverseGeocode(SearchCriteria searchCriteria) throws IllegalSearchCriteriaException {
try {
String srs = searchCriteria.getSRS();
if( srs == null ) {
srs = "EPSG:3067";
ZakarFin marked this conversation as resolved.
Show resolved Hide resolved
}

// Lon,lat (east coordinate is always first in transformation input and output
CoordinateReferenceSystem sourceCrs = CRS.decode(srs, true);
CoordinateReferenceSystem targetCrs = CRS.decode(SERVICE_SRS, true);

// from source to wgs84
final Point point = ProjectionHelper.transformPoint(searchCriteria.getLon(), searchCriteria.getLat(), sourceCrs, targetCrs);

String url = getReverseGeocodeURL(searchCriteria, point);
HttpURLConnection connection = getConnection(url);
IOHelper.addIdentifierHeaders(connection);
String data = IOHelper.readString(connection);
log.debug("DATA: " + data);
JSONArray jsonData = new JSONArray();
jsonData.put(JSONHelper.createJSONObject(data));

// convert back from wgs84 to map projection
return createChannelSearchResult(jsonData, targetCrs, sourceCrs);

} catch (Exception e) {
log.error(e, "Failed to reverse geocode locations from register of OpenStreetMap");
return null;
}
}
}
Loading