Java tutorial
/* * Copyright 2012 University of South Florida * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.usf.cutr.opentripplanner.android.tasks; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.res.Resources.NotFoundException; import android.location.Address; import android.location.Geocoder; import android.os.AsyncTask; import android.preference.PreferenceManager; import android.util.Log; import android.widget.Toast; import com.google.android.gms.maps.model.LatLng; import edu.usf.cutr.opentripplanner.android.OTPApp; import edu.usf.cutr.opentripplanner.android.R; import edu.usf.cutr.opentripplanner.android.listeners.OTPGeocodingListener; import edu.usf.cutr.opentripplanner.android.model.Server; import edu.usf.cutr.opentripplanner.android.pois.GooglePlaces; //import edu.usf.cutr.opentripplanner.android.pois.Itract; import edu.usf.cutr.opentripplanner.android.pois.Nominatim; import edu.usf.cutr.opentripplanner.android.pois.POI; import edu.usf.cutr.opentripplanner.android.pois.Places; import edu.usf.cutr.opentripplanner.android.util.LocationUtil; /** * @author Khoa Tran * */ public class OTPGeocoding extends AsyncTask<String, Integer, Long> { private static final String TAG = "OTP"; private WeakReference<Activity> activity; private Context context; private boolean isStartTextbox; private OTPGeocodingListener callback; private String placesService; private boolean geocodingForMarker; private ArrayList<Address> addressesReturn = new ArrayList<Address>(); private Server selectedServer; public OTPGeocoding(WeakReference<Activity> activity, Context context, boolean isStartTextbox, boolean geocodingForMarker, Server selectedServer, String placesService, OTPGeocodingListener callback) { this.context = context; this.activity = activity; this.isStartTextbox = isStartTextbox; this.callback = callback; this.selectedServer = selectedServer; this.placesService = placesService; this.geocodingForMarker = geocodingForMarker; } public OTPGeocoding() { } public JSONObject reverseGeocoding(double latitude, double longitude) { HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng=" + latitude + "," + longitude + "&sensor=true"); HttpClient client = new DefaultHttpClient(); HttpResponse response; StringBuilder stringBuilder = new StringBuilder(); try { response = client.execute(httpGet); HttpEntity entity = response.getEntity(); InputStream stream = entity.getContent(); int b; while ((b = stream.read()) != -1) { stringBuilder.append((char) b); } } catch (ClientProtocolException e) { } catch (IOException e) { } JSONObject jsonObject = new JSONObject(); try { jsonObject = new JSONObject(stringBuilder.toString()); } catch (JSONException e) { e.printStackTrace(); } return jsonObject; } protected void onPreExecute() { // Do nothing } protected Long doInBackground(String... reqs) { long count = reqs.length; String address = reqs[0]; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (address == null || address.equalsIgnoreCase("")) { return count; } if (address.equalsIgnoreCase(context.getString(R.string.my_location))) { String currentLat = reqs[1]; String currentLng = reqs[2]; LatLng latLng = new LatLng(Double.parseDouble(currentLat), Double.parseDouble(currentLng)); Address addressReturn = new Address(context.getResources().getConfiguration().locale); addressReturn.setLatitude(latLng.latitude); addressReturn.setLongitude(latLng.longitude); addressReturn.setAddressLine(addressReturn.getMaxAddressLineIndex() + 1, context.getString(R.string.my_location)); addressesReturn.add(addressReturn); return count; } ArrayList<Address> addresses = null; if (prefs.getBoolean(OTPApp.PREFERENCE_KEY_USE_ANDROID_GEOCODER, true)) { Log.d("test", "create a geocoder"); Geocoder gc = new Geocoder(context); try { if (selectedServer != null) { addresses = (ArrayList<Address>) gc.getFromLocationName(address, context.getResources().getInteger(R.integer.geocoder_max_results), selectedServer.getLowerLeftLatitude(), selectedServer.getLowerLeftLongitude(), selectedServer.getUpperRightLatitude(), selectedServer.getUpperRightLongitude()); } else { addresses = (ArrayList<Address>) gc.getFromLocationName(address, context.getResources().getInteger(R.integer.geocoder_max_results)); } } catch (IOException e) { e.printStackTrace(); } } addresses = filterAddressesBBox(addresses); if ((addresses == null) || addresses.isEmpty()) { addresses = searchPlaces(address); for (int i = 0; i < addresses.size(); i++) { Address addr = addresses.get(i); String str = addr.getAddressLine(0); List<String> addrLines = Arrays.asList(str.split(", ")); for (int j = 0; j < addrLines.size(); j++) { addr.setAddressLine(j, addrLines.get(j)); } } } addresses = filterAddressesBBox(addresses); addressesReturn.addAll(addresses); return count; } /** * Filters the addresses obtained in geocoding process, removing the * results outside server limits. * * @param the list of addresses to filter * @return a new list filtered */ private ArrayList<Address> filterAddressesBBox(ArrayList<Address> addresses) { if (!(addresses == null || addresses.isEmpty())) { ArrayList<Address> addressesFiltered = new ArrayList<Address>(addresses); for (Address address : addressesFiltered) { if (!LocationUtil.checkPointInBoundingBox(new LatLng(address.getLatitude(), address.getLongitude()), selectedServer, OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) { addressesFiltered.remove(address); } } return addressesFiltered; } return addresses; } /** * Try to grab the developer key from an unversioned resource file, if it exists * @return the developer key from an unversioned resource file, or empty string if it doesn't exist */ private String getKeyFromResource() { String strKey = new String(""); try { InputStream in = context.getResources().openRawResource(R.raw.googleplaceskey); BufferedReader r = new BufferedReader(new InputStreamReader(in)); StringBuilder total = new StringBuilder(); while ((strKey = r.readLine()) != null) { total.append(strKey); } strKey = total.toString(); strKey.trim(); //Remove any whitespace } catch (NotFoundException e) { Log.w(TAG, "Warning - didn't find the google places key file:" + e); } catch (IOException e) { Log.w(TAG, "Error reading the developer key file:" + e); } return strKey; } private ArrayList<Address> searchPlaces(String name) { HashMap<String, String> params = new HashMap<String, String>(); Places p; /*params.put(Itract.PARAM_NAME, name); if (selectedServer != null) { params.put(Itract.PARAM_LAT, Double.toString(selectedServer.getGeometricalCenterLatitude())); params.put(Itract.PARAM_LON, Double.toString(selectedServer.getGeometricalCenterLongitude())); } p = new Itract();*/ if (placesService.equals(context.getResources().getString(R.string.geocoder_google_places))) { params.put(GooglePlaces.PARAM_NAME, name); if (selectedServer != null) { params.put(GooglePlaces.PARAM_LOCATION, Double.toString(selectedServer.getGeometricalCenterLatitude()) + "," + Double.toString(selectedServer.getGeometricalCenterLongitude())); params.put(GooglePlaces.PARAM_RADIUS, Double.toString(selectedServer.getRadius())); } p = new GooglePlaces(getKeyFromResource()); Log.v(TAG, "Using Google Places!"); } else { params.put(Nominatim.PARAM_NAME, name); if (selectedServer != null) { params.put(Nominatim.PARAM_LEFT, Double.toString(selectedServer.getLowerLeftLongitude())); params.put(Nominatim.PARAM_TOP, Double.toString(selectedServer.getLowerLeftLatitude())); params.put(Nominatim.PARAM_RIGHT, Double.toString(selectedServer.getUpperRightLongitude())); params.put(Nominatim.PARAM_BOTTOM, Double.toString(selectedServer.getUpperRightLatitude())); } p = new Nominatim(); Log.v(TAG, "Using Nominatim!"); } ArrayList<POI> pois = new ArrayList<POI>(); pois.addAll(p.getPlaces(params)); ArrayList<Address> addresses = new ArrayList<Address>(); for (int i = 0; i < pois.size(); i++) { POI poi = pois.get(i); Log.v(TAG, poi.getName() + " " + poi.getLatitude() + "," + poi.getLongitude()); Address addr = new Address(context.getResources().getConfiguration().locale); addr.setLatitude(poi.getLatitude()); addr.setLongitude(poi.getLongitude()); String addressLine; if (poi.getAddress() != null) { if (!poi.getAddress().contains(poi.getName())) { addressLine = (poi.getName() + ", " + poi.getAddress()); } else { addressLine = poi.getAddress(); } } else { addressLine = poi.getName(); } addr.setAddressLine(addr.getMaxAddressLineIndex() + 1, addressLine); addresses.add(addr); } return addresses; } protected void onCancelled(Long result) { if (activity.get() != null) { AlertDialog.Builder geocoderAlert = new AlertDialog.Builder(activity.get()); geocoderAlert.setTitle(R.string.geocoder_results_title).setMessage(R.string.geocoder_no_results_message) .setCancelable(false).setPositiveButton(context.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); AlertDialog alert = geocoderAlert.create(); alert.show(); } Log.e(TAG, "No geocoding processed!"); } protected void onPostExecute(Long result) { callback.onOTPGeocodingComplete(isStartTextbox, addressesReturn, geocodingForMarker); } }