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 ava2 s  .com*/
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.osmdroid.bonuspack.utils.BonusPackHelper;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
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 android.content.Context;
import android.location.Address;
import android.os.Bundle;
import android.util.Log;

/**
 * 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>
   * 
   * 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.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.Smartgeo.java
com.ilm.sandwich.StartChooser.java
com.ilm.sandwich.TouchableWrapper.java
com.ilm.sandwich.helferklassen.HttpRequests.java
com.ilm.sandwich.helferklassen.Locationer.java
com.ilm.sandwich.helferklassen.MapDownload.java
com.ilm.sandwich.helferklassen.MyItemizedOverlay.java
com.ilm.sandwich.helferklassen.PlacesAutoComplete.java
com.ilm.sandwich.helferklassen.PlacesTextSearch.java
com.ilm.sandwich.helferklassen.Rechnung.java
com.ilm.sandwich.helferklassen.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