Skip to content

Commit

Permalink
v3.0.0: change return type to array and add options param
Browse files Browse the repository at this point in the history
# 3.0.0 (2018-02-06)

For making the API more robust for future changes and new features I changed the return type of both methods to an array and added an 'options' param.

## ** BREAKING CHANGES **
- The result Object of __nativegeocoder.reverseGeocode__ is an Array.
- The result Object of __nativegeocoder.forwardGeocode__ is an Array.

## CHANGELOG
- Add options param for both __nativegeocoder.reverseGeocode__ and __nativegeocoder.forwardGeocode__ for setting locale & max result objects (closes #17, #25)
  • Loading branch information
Sebastian Baar committed Feb 6, 2018
1 parent 08d92e3 commit b354b45
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 190 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 3.0.0 (2018-02-06)

For making the API more robust for future changes and new features I changed the return type of both methods to an array and added an 'options' param.

## ** BREAKING CHANGES **
- The result Object of __nativegeocoder.reverseGeocode__ is an Array.
- The result Object of __nativegeocoder.forwardGeocode__ is an Array.

## CHANGELOG
- Add options param for both __nativegeocoder.reverseGeocode__ and __nativegeocoder.forwardGeocode__ for setting locale & max result objects (closes #17, #25)

# 2.0.5 (2017-10-13)

update dependency 'cordova-plugin-add-swift-support' to 1.7.1 (closes #24)
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ You can also configure the following variable to customize the iOS location plis
## nativegeocoder.reverseGeocode
Reverse geocode a given latitude and longitude to find location address.

nativegeocoder.reverseGeocode(successCallback, errorCallback, latitude, longitude);
nativegeocoder.reverseGeocode(successCallback, errorCallback, latitude, longitude, options);

### Parameters
- __latitude__: The latitude. (Double)
- __longitude__: The longtitude. (Double)
- __options__: The Options. ( { useLocale: boolean, maxResults: number } )

### Result Object
### Result Object (Array)
https://developer.apple.com/documentation/corelocation/clplacemark
https://developer.android.com/reference/android/location/Address.html

Expand All @@ -50,7 +51,7 @@ https://developer.android.com/reference/android/location/Address.html
```js
nativegeocoder.reverseGeocode(success, failure, 52.5072095, 13.1452818);
function success(result) {
alert("The address is: \n\n" + JSON.stringify(result));
alert("The address is: \n\n" + JSON.stringify(result[0]));
}
function failure(err) {
alert(JSON.stringify(err));
Expand All @@ -60,20 +61,21 @@ function failure(err) {
## nativegeocoder.forwardGeocode
Forward geocode a given address to find coordinates.

nativegeocoder.forwardGeocode(successCallback, errorCallback, addressString);
nativegeocoder.forwardGeocode(successCallback, errorCallback, addressString, options);

### Parameters
- __addressString__: The address to be geocoded. (String)
- __options__: The Options. ( { useLocale: boolean, maxResults: number } )

### Result Object
### Result Object (Array)
- latitude
- longitude

### Example
```js
nativegeocoder.forwardGeocode(success, failure, "Berlin");
function success(coordinates) {
alert("The coordinates are latitude = " + coordinates.latitude + " and longitude = " + coordinates.longitude);
alert("The coordinates are latitude = " + coordinates[0].latitude + " and longitude = " + coordinates[0].longitude);
}
function failure(err) {
alert(JSON.stringify(err));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-nativegeocoder",
"version": "2.0.5",
"version": "3.0.0",
"description": "Cordova plugin for native forward and reverse geocoding",
"cordova": {
"id": "cordova-plugin-nativegeocoder",
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<plugin id="cordova-plugin-nativegeocoder" version="2.0.5" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="cordova-plugin-nativegeocoder" version="3.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>NativeGeocoder</name>
<description>Cordova plugin for native forward and reverse geocoding</description>
<license>MIT</license>
Expand Down
186 changes: 134 additions & 52 deletions src/android/NativeGeocoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@

import android.location.Address;
import android.location.Geocoder;
import android.text.TextUtils;

import org.apache.cordova.*;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

class NativeGeocoderOptions {
boolean useLocale = true;
int maxResults = 1;
}

public class NativeGeocoder extends CordovaPlugin {

private static int MAX_RESULTS_COUNT = 5;
private Geocoder geocoder;

@Override
Expand All @@ -29,21 +36,40 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
if (action.equals("reverseGeocode")) {
double latitude = args.getDouble(0);
double longitude = args.getDouble(1);
this.reverseGeocode(latitude, longitude, callbackContext);
JSONObject options = null;
try {
options = args.getJSONObject(2);
} catch (JSONException e) {
e.printStackTrace();
}

this.reverseGeocode(latitude, longitude, options, callbackContext);
return true;
}

if (action.equals("forwardGeocode")) {
String addressString = args.getString(0);
this.forwardGeocode(addressString, callbackContext);
JSONObject options = null;
try {
options = args.getJSONObject(2);
} catch (JSONException e) {
e.printStackTrace();
}
this.forwardGeocode(addressString, options, callbackContext);
return true;
}

return false;

}

private void reverseGeocode(double latitude, double longitude, CallbackContext callbackContext) {
/**
* Reverse geocode a given latitude and longitude to find location address
* @param latitude
* @param longitude
* @param options
* @param callbackContext
*/
private void reverseGeocode(double latitude, double longitude, JSONObject options, CallbackContext callbackContext) throws JSONException{

if (latitude == 0 || longitude == 0) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Expected two non-empty double arguments.");
Expand All @@ -57,24 +83,54 @@ private void reverseGeocode(double latitude, double longitude, CallbackContext c
return;
}

geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.getDefault());
NativeGeocoderOptions geocoderOptions = new NativeGeocoderOptions();

if (options != null && options.has("useLocale")) {
geocoderOptions.useLocale = options.getBoolean("useLocale");
} else {
geocoderOptions.useLocale = true;
}
if (options != null && options.has("maxResults")) {
geocoderOptions.maxResults = options.getInt("maxResults");
} else {
geocoderOptions.maxResults = 1;
}

if (geocoderOptions.useLocale) {
geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.getDefault());
} else {
geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.ENGLISH);
}

if (geocoderOptions.maxResults > 0) {
geocoderOptions.maxResults = geocoderOptions.maxResults > MAX_RESULTS_COUNT ? MAX_RESULTS_COUNT : geocoderOptions.maxResults;
} else {
geocoderOptions.maxResults = 1;
}

try {
List<Address> geoResults = geocoder.getFromLocation(latitude, longitude, 1);
List<Address> geoResults = geocoder.getFromLocation(latitude, longitude, geocoderOptions.maxResults);
if (geoResults.size() > 0) {
Address address = geoResults.get(0);

// https://developer.android.com/reference/android/location/Address.html
JSONObject resultObj = new JSONObject();
resultObj.put("countryCode", address.getCountryCode());
resultObj.put("countryName", address.getCountryName());
resultObj.put("postalCode", address.getPostalCode());
resultObj.put("administrativeArea", address.getAdminArea());
resultObj.put("subAdministrativeArea", address.getSubAdminArea());
resultObj.put("locality", address.getLocality());
resultObj.put("subLocality", address.getSubLocality());
resultObj.put("thoroughfare", address.getThoroughfare());
resultObj.put("subThoroughfare", address.getSubThoroughfare());
int maxResultObjects = geoResults.size() >= geocoderOptions.maxResults ? geoResults.size() : geoResults.size();
JSONArray resultObj = new JSONArray();

for (int i = 0; i < maxResultObjects; i++) {
Address address = geoResults.get(i);

// https://developer.android.com/reference/android/location/Address.html
JSONObject placemark = new JSONObject();
placemark.put("countryCode", address.getCountryCode());
placemark.put("countryName", address.getCountryName());
placemark.put("postalCode", address.getPostalCode());
placemark.put("administrativeArea", address.getAdminArea());
placemark.put("subAdministrativeArea", address.getSubAdminArea());
placemark.put("locality", address.getLocality());
placemark.put("subLocality", address.getSubLocality());
placemark.put("thoroughfare", address.getThoroughfare());
placemark.put("subThoroughfare", address.getSubThoroughfare());

resultObj.put(placemark);
}

callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, resultObj));
} else {
Expand All @@ -88,60 +144,86 @@ private void reverseGeocode(double latitude, double longitude, CallbackContext c
}
}

private void forwardGeocode(String addressString, CallbackContext callbackContext) {
/**
* Forward geocode a given address to find coordinates
* @param addressString
* @param options
* @param callbackContext
*/
private void forwardGeocode(String addressString, JSONObject options, CallbackContext callbackContext) throws JSONException {

if (addressString == null || addressString.length() == 0) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Expected a non-empty string argument.");
callbackContext.sendPluginResult(r);
return;
}

if (!Geocoder.isPresent()) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Geocoder is not present on this device/emulator.");
callbackContext.sendPluginResult(r);
return;
}

NativeGeocoderOptions geocoderOptions = new NativeGeocoderOptions();
geocoderOptions.useLocale = true;

if (options != null && options.has("maxResults")) {
geocoderOptions.maxResults = options.getInt("maxResults");
} else {
geocoderOptions.maxResults = 1;
}

geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.getDefault());

if (addressString != null && addressString.length() > 0) {
if (geocoderOptions.maxResults > 0) {
geocoderOptions.maxResults = geocoderOptions.maxResults > MAX_RESULTS_COUNT ? MAX_RESULTS_COUNT : geocoderOptions.maxResults;
} else {
geocoderOptions.maxResults = 1;
}

try {
List<Address> geoResults = geocoder.getFromLocationName(addressString, 1);
if (geoResults.size() > 0) {
Address address = geoResults.get(0);
try {
List<Address> geoResults = geocoder.getFromLocationName(addressString, geocoderOptions.maxResults);

if (geoResults.size() > 0) {
int maxResultObjects = geoResults.size() >= geocoderOptions.maxResults ? geoResults.size() : geoResults.size();
JSONArray resultObj = new JSONArray();

for (int i = 0; i < maxResultObjects; i++) {
Address address = geoResults.get(i);

try {
String latitude = String.valueOf(address.getLatitude());
String longitude = String.valueOf(address.getLongitude());

if (latitude.isEmpty() || longitude.isEmpty()) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot get latitude and/or longitude.");
callbackContext.sendPluginResult(r);
return;
}

JSONObject coordinates = new JSONObject();
coordinates.put("latitude", latitude);
coordinates.put("longitude", longitude);

callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, coordinates));
if (!latitude.isEmpty() && !longitude.isEmpty()) {
JSONObject coordinates = new JSONObject();
coordinates.put("latitude", latitude);
coordinates.put("longitude", longitude);

resultObj.put(coordinates);
}
}
catch (RuntimeException e) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot get latitude and/or longitude.");
callbackContext.sendPluginResult(r);
e.printStackTrace();
}
}
else {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot find a location.");

if (resultObj.length() == 0) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot get latitude and/or longitude.");
callbackContext.sendPluginResult(r);
} else {
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, resultObj));
}

}
catch (Exception e) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Geocoder:getFromLocationName Error: " +e.getMessage());

} else {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot find a location.");
callbackContext.sendPluginResult(r);
}

}
else {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Expected a non-empty string argument.");
catch (Exception e) {
PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Geocoder:getFromLocationName Error: " +e.getMessage());
callbackContext.sendPluginResult(r);
}
}
}

}
Loading

0 comments on commit b354b45

Please sign in to comment.