Android Open Source - smartnavi Geocoder Nominatim






From Project

Back to project page smartnavi.

License

The source code is released under:

Apache License

If you think the Android project smartnavi listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.osmdroid.bonuspack.location;
//  w  w w  . j  av a2 s .c  o m
import android.content.Context;
import android.location.Address;
import android.os.Bundle;
import android.util.Log;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;

import org.osmdroid.bonuspack.utils.BonusPackHelper;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Implements an equivalent to Android Geocoder class, based on OpenStreetMap data and Nominatim API. <br>
 * See http://wiki.openstreetmap.org/wiki/Nominatim
 * or http://open.mapquestapi.com/nominatim/
 *
 * @author M.Kergall
 */
public class GeocoderNominatim {
    public static final String NOMINATIM_SERVICE_URL = "http://nominatim.openstreetmap.org/";
    public static final String MAPQUEST_SERVICE_URL = "http://open.mapquestapi.com/nominatim/v1/";

    protected Locale mLocale;
    protected String mServiceUrl;
    protected boolean mPolygon;

    public GeocoderNominatim(Context context, Locale locale) {
        mLocale = locale;
        setOptions(false);
        setService(NOMINATIM_SERVICE_URL); //default service
    }

    public GeocoderNominatim(Context context) {
        this(context, Locale.getDefault());
    }

    static public boolean isPresent() {
        return true;
    }

    /**
     * Specify the url of the Nominatim service provider to use.
     * Can be one of the predefined (NOMINATIM_SERVICE_URL or MAPQUEST_SERVICE_URL),
     * or another one, your local instance of Nominatim for instance.
     */
    public void setService(String serviceUrl) {
        mServiceUrl = serviceUrl;
    }

    /**
     * @param polygon true to get the polygon enclosing the location.
     */
    public void setOptions(boolean polygon) {
        mPolygon = polygon;
    }

    /**
     * Build an Android Address object from the Nominatim address in JSON format.
     * Current implementation is mainly targeting french addresses,
     * and will be quite basic on other countries.
     */
    protected Address buildAndroidAddress(JsonObject jResult) throws JsonSyntaxException {
        Address gAddress = new Address(mLocale);
        gAddress.setLatitude(jResult.get("lat").getAsDouble());
        gAddress.setLongitude(jResult.get("lon").getAsDouble());

        JsonObject jAddress = jResult.get("address").getAsJsonObject();

        int addressIndex = 0;
        if (jAddress.has("road")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("road").getAsString());
            gAddress.setThoroughfare(jAddress.get("road").getAsString());
        }
        if (jAddress.has("suburb")) {
            //gAddress.setAddressLine(addressIndex++, jAddress.getString("suburb"));
            //not kept => often introduce "noise" in the address.
            gAddress.setSubLocality(jAddress.get("suburb").getAsString());
        }
        if (jAddress.has("postcode")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("postcode").getAsString());
            gAddress.setPostalCode(jAddress.get("postcode").getAsString());
        }

        if (jAddress.has("city")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("city").getAsString());
            gAddress.setLocality(jAddress.get("city").getAsString());
        } else if (jAddress.has("town")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("town").getAsString());
            gAddress.setLocality(jAddress.get("town").getAsString());
        } else if (jAddress.has("village")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("village").getAsString());
            gAddress.setLocality(jAddress.get("village").getAsString());
        }

        if (jAddress.has("county")) { //France: departement
            gAddress.setSubAdminArea(jAddress.get("county").getAsString());
        }
        if (jAddress.has("state")) { //France: region
            gAddress.setAdminArea(jAddress.get("state").getAsString());
        }
        if (jAddress.has("country")) {
            gAddress.setAddressLine(addressIndex++, jAddress.get("country").getAsString());
            gAddress.setCountryName(jAddress.get("country").getAsString());
        }
        if (jAddress.has("country_code"))
            gAddress.setCountryCode(jAddress.get("country_code").getAsString());

    /* Other possible OSM tags in Nominatim results not handled yet: 
         * subway, golf_course, bus_stop, parking,...
     * house, house_number, building
     * city_district (13e Arrondissement)
     * road => or highway, ...
     * sub-city (like suburb) => locality, isolated_dwelling, hamlet ...
     * state_district
    */

        //Add non-standard (but very useful) information in Extras bundle:
        Bundle extras = new Bundle();
        if (jResult.has("polygonpoints")) {
            JsonArray jPolygonPoints = jResult.get("polygonpoints").getAsJsonArray();
            ArrayList<GeoPoint> polygonPoints = new ArrayList<GeoPoint>(jPolygonPoints.size());
            for (int i = 0; i < jPolygonPoints.size(); i++) {
                JsonArray jCoords = jPolygonPoints.get(i).getAsJsonArray();
                double lon = jCoords.get(0).getAsDouble();
                double lat = jCoords.get(1).getAsDouble();
                GeoPoint p = new GeoPoint(lat, lon);
                polygonPoints.add(p);
            }
            extras.putParcelableArrayList("polygonpoints", polygonPoints);
        }
        if (jResult.has("boundingbox")) {
            JsonArray jBoundingBox = jResult.get("boundingbox").getAsJsonArray();
            BoundingBoxE6 bb = new BoundingBoxE6(
                    jBoundingBox.get(1).getAsDouble(), jBoundingBox.get(2).getAsDouble(),
                    jBoundingBox.get(0).getAsDouble(), jBoundingBox.get(3).getAsDouble());
            extras.putParcelable("boundingbox", bb);
        }
        if (jResult.has("osm_id")) {
            long osm_id = jResult.get("osm_id").getAsLong();
            extras.putLong("osm_id", osm_id);
        }
        if (jResult.has("osm_type")) {
            String osm_type = jResult.get("osm_type").getAsString();
            extras.putString("osm_type", osm_type);
        }
        gAddress.setExtras(extras);

        return gAddress;
    }

    /**
     * Equivalent to Geocoder::getFromLocation(double latitude, double longitude, int maxResults).
     */
    public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
            throws IOException {
        String url = mServiceUrl
                + "reverse?"
                + "format=json"
                + "&accept-language=" + mLocale.getLanguage()
                //+ "&addressdetails=1"
                + "&lat=" + latitude
                + "&lon=" + longitude;
        Log.d(BonusPackHelper.LOG_TAG, "GeocoderNominatim::getFromLocation:" + url);
        String result = BonusPackHelper.requestStringFromUrl(url);
        if (result == null)
            throw new IOException();
        try {
            JsonParser parser = new JsonParser();
            JsonElement json = parser.parse(result);
            JsonObject jResult = json.getAsJsonObject();
            Address gAddress = buildAndroidAddress(jResult);
            List<Address> list = new ArrayList<Address>(1);
            list.add(gAddress);
            return list;
        } catch (JsonSyntaxException e) {
            throw new IOException();
        }
    }

    /**
     * Equivalent to Geocoder::getFromLocation(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude)
     * but adding bounded parameter.
     *
     * @param bounded true = return only results which are inside the view box; false = view box is used as a preferred area to find search results.
     */
    public List<Address> getFromLocationName(String locationName, int maxResults,
                                             double lowerLeftLatitude, double lowerLeftLongitude,
                                             double upperRightLatitude, double upperRightLongitude,
                                             boolean bounded)
            throws IOException {
        String url = mServiceUrl
                + "search?"
                + "format=json"
                + "&accept-language=" + mLocale.getLanguage()
                + "&addressdetails=1"
                + "&limit=" + maxResults
                + "&q=" + URLEncoder.encode(locationName);
        if (lowerLeftLatitude != 0.0 && upperRightLatitude != 0.0) {
            //viewbox = left, top, right, bottom:
            url += "&viewbox=" + lowerLeftLongitude
                    + "," + upperRightLatitude
                    + "," + upperRightLongitude
                    + "," + lowerLeftLatitude
                    + "&bounded=" + (bounded ? 1 : 0);
        }
        if (mPolygon) {
            //get polygon outlines for items found:
            url += "&polygon=1";
            //TODO: polygon param is obsolete. Should be replaced by polygon_geojson.
            //Upgrade is on hold, waiting for MapQuest service to become compatible.
        }
        Log.d(BonusPackHelper.LOG_TAG, "GeocoderNominatim::getFromLocationName:" + url);
        String result = BonusPackHelper.requestStringFromUrl(url);
        //Log.d(BonusPackHelper.LOG_TAG, result);
        if (result == null)
            throw new IOException();
        try {
            JsonParser parser = new JsonParser();
            JsonElement json = parser.parse(result);
            JsonArray jResults = json.getAsJsonArray();
            List<Address> list = new ArrayList<Address>(jResults.size());
            for (int i = 0; i < jResults.size(); i++) {
                JsonObject jResult = jResults.get(i).getAsJsonObject();
                Address gAddress = buildAndroidAddress(jResult);
                list.add(gAddress);
            }
            Log.d(BonusPackHelper.LOG_TAG, "done");
            return list;
        } catch (JsonSyntaxException e) {
            throw new IOException();
        }
    }

    /**
     * Equivalent to Geocoder::getFromLocation(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude)
     *
     * @see getFromLocationName(String locationName, int maxResults), about extra data added in Address results.
     */
    public List<Address> getFromLocationName(String locationName, int maxResults,
                                             double lowerLeftLatitude, double lowerLeftLongitude,
                                             double upperRightLatitude, double upperRightLongitude)
            throws IOException {
        return getFromLocationName(locationName, maxResults,
                lowerLeftLatitude, lowerLeftLongitude,
                upperRightLatitude, upperRightLongitude, true);
    }

    /**
     * Equivalent to Geocoder::getFromLocation(String locationName, int maxResults). <br>
     * <p/>
     * Some useful information, returned by Nominatim, that doesn't fit naturally within Android Address, are added in the bundle Address.getExtras():<br>
     * "boundingbox": the enclosing bounding box, as a BoundingBoxE6<br>
     * "osm_id": the OSM id, as a long<br>
     * "osm_type": one of the 3 OSM types, as a string (node, way, or relation). <br>
     * "polygonpoints": the enclosing polygon of the location (depending on setOptions usage), as an ArrayList of GeoPoint<br>
     * (others could be added if needed)
     */
    public List<Address> getFromLocationName(String locationName, int maxResults)
            throws IOException {
        return getFromLocationName(locationName, maxResults, 0.0, 0.0, 0.0, 0.0, false);
    }

}




Java Source Code List

com.ilm.sandwich.BackgroundService.java
com.ilm.sandwich.BuildConfig.java
com.ilm.sandwich.Config.java
com.ilm.sandwich.GoogleMapActivity.java
com.ilm.sandwich.Info.java
com.ilm.sandwich.MySupportMapFragment.java
com.ilm.sandwich.OsmMapActivity.java
com.ilm.sandwich.Settings.java
com.ilm.sandwich.StartChooser.java
com.ilm.sandwich.TouchableWrapper.java
com.ilm.sandwich.tools.Core.java
com.ilm.sandwich.tools.HttpRequests.java
com.ilm.sandwich.tools.Locationer.java
com.ilm.sandwich.tools.MapDownload.java
com.ilm.sandwich.tools.MyItemizedOverlay.java
com.ilm.sandwich.tools.PlacesAutoComplete.java
com.ilm.sandwich.tools.PlacesTextSearch.java
com.ilm.sandwich.tools.Statistics.java
com.ilm.sandwich.tools.SuggestionsAdapter.java
org.osmdroid.bonuspack.BuildConfig.java
org.osmdroid.bonuspack.BuildConfig.java
org.osmdroid.bonuspack.cachemanager.CacheManager.java
org.osmdroid.bonuspack.clustering.GridMarkerClusterer.java
org.osmdroid.bonuspack.clustering.MarkerClusterer.java
org.osmdroid.bonuspack.clustering.StaticCluster.java
org.osmdroid.bonuspack.kml.ColorStyle.java
org.osmdroid.bonuspack.kml.IconStyle.java
org.osmdroid.bonuspack.kml.KmlDocument.java
org.osmdroid.bonuspack.kml.KmlFeature.java
org.osmdroid.bonuspack.kml.KmlFolder.java
org.osmdroid.bonuspack.kml.KmlGeometry.java
org.osmdroid.bonuspack.kml.KmlGroundOverlay.java
org.osmdroid.bonuspack.kml.KmlLineString.java
org.osmdroid.bonuspack.kml.KmlMultiGeometry.java
org.osmdroid.bonuspack.kml.KmlPlacemark.java
org.osmdroid.bonuspack.kml.KmlPoint.java
org.osmdroid.bonuspack.kml.KmlPolygon.java
org.osmdroid.bonuspack.kml.LineStyle.java
org.osmdroid.bonuspack.kml.Style.java
org.osmdroid.bonuspack.location.FlickrPOIProvider.java
org.osmdroid.bonuspack.location.GeoNamesPOIProvider.java
org.osmdroid.bonuspack.location.GeocoderGisgraphy.java
org.osmdroid.bonuspack.location.GeocoderNominatimOld.java
org.osmdroid.bonuspack.location.GeocoderNominatim.java
org.osmdroid.bonuspack.location.NominatimPOIProvider.java
org.osmdroid.bonuspack.location.POI.java
org.osmdroid.bonuspack.location.PicasaPOIProvider.java
org.osmdroid.bonuspack.mapsforge.GenericMapView.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileModuleProvider.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileProvider.java
org.osmdroid.bonuspack.mapsforge.MapsForgeTileSource.java
org.osmdroid.bonuspack.overlays.DefaultInfoWindow.java
org.osmdroid.bonuspack.overlays.ExtendedOverlayItem.java
org.osmdroid.bonuspack.overlays.FolderOverlay.java
org.osmdroid.bonuspack.overlays.GroundOverlay.java
org.osmdroid.bonuspack.overlays.InfoWindow.java
org.osmdroid.bonuspack.overlays.ItemizedOverlayWithBubble.java
org.osmdroid.bonuspack.overlays.MapEventsOverlay.java
org.osmdroid.bonuspack.overlays.MapEventsReceiver.java
org.osmdroid.bonuspack.overlays.MarkerInfoWindow.java
org.osmdroid.bonuspack.overlays.Marker.java
org.osmdroid.bonuspack.overlays.Polygon.java
org.osmdroid.bonuspack.overlays.Polyline.java
org.osmdroid.bonuspack.routing.GoogleRoadManager.java
org.osmdroid.bonuspack.routing.MapQuestRoadManager.java
org.osmdroid.bonuspack.routing.OSRMRoadManager.java
org.osmdroid.bonuspack.routing.RoadLeg.java
org.osmdroid.bonuspack.routing.RoadManager.java
org.osmdroid.bonuspack.routing.RoadNode.java
org.osmdroid.bonuspack.routing.Road.java
org.osmdroid.bonuspack.utils.BonusPackHelper.java
org.osmdroid.bonuspack.utils.DouglasPeuckerReducer.java
org.osmdroid.bonuspack.utils.HttpConnection.java
org.osmdroid.bonuspack.utils.PolylineEncoder.java
org.osmdroid.bonuspack.utils.WebImageCache.java