Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
fallback to google api in case of error
Browse files Browse the repository at this point in the history
  • Loading branch information
devfd committed May 19, 2016
1 parent 28b46be commit 205beeb
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 21 deletions.
23 changes: 2 additions & 21 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
import { NativeModules } from 'react-native';
import Geocoder from './js/geocoder.js';

const { RNGeocoder } = NativeModules;

export default {

geocodePosition(position) {
if (!position || !position.lat || !position.lng) {
return Promise.reject(new Error("invalid position: {lat, lng} required"));
}

return RNGeocoder.geocodePosition(position);
},

geocodeAddress(address) {
if (!address) {
return Promise.reject(new Error("address is null"));
}

return RNGeocoder.geocodeAddress(address);
},
}
export default Geocoder;
34 changes: 34 additions & 0 deletions js/geocoder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { NativeModules } from 'react-native';
import GoogleApi from './googleApi.js';

const { RNGeocoder } = NativeModules;

export default {
apiKey: null,

fallbackToGoogle(key) {
this.apiKey = key;
},

geocodePosition(position) {
if (!position || !position.lat || !position.lng) {
return Promise.reject(new Error("invalid position: {lat, lng} required"));
}

return RNGeocoder.geocodePosition(position).catch(err => {
if (!this.apiKey) { throw err; }
return GoogleApi.geocodePosition(this.apiKey, position);
});
},

geocodeAddress(address) {
if (!address) {
return Promise.reject(new Error("address is null"));
}

return RNGeocoder.geocodeAddress(address).catch(err => {
if (!this.apiKey) { throw err; }
return GoogleApi.geocodeAddress(this.apiKey, address);
});
},
}
87 changes: 87 additions & 0 deletions js/googleApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const googleUrl = 'https://maps.google.com/maps/api/geocode/json';

function format(raw) {
const address = {
position: {},
formattedAddress: raw.formatted_address || '',
feature: null,
streetNumber: null,
streetName: null,
postalCode: null,
locality: null,
country: null,
countryCode: null,
adminArea: null,
subAdminArea: null,
subLocality: null,
};

if (raw.geometry && raw.geometry.location) {
address.position = {
lat: raw.geometry.location.lat,
lng: raw.geometry.location.lng,
}
}

for (let component of raw.address_components) {
if (component.types.includes('route')) {
address.streetName = component.long_name;
}
else if (component.types.includes('street_number')) {
address.streetNumber = component.long_name;
}
else if (component.types.includes('country')) {
address.country = component.long_name;
address.countryCode = component.short_name;
}
else if (component.types.includes('locality')) {
address.locality = component.long_name;
}
else if (component.types.includes('postal_code')) {
address.postalCode = component.long_name;
}
else if (component.types.includes('administrative_area_level_1')) {
address.adminArea = component.long_name;
}
else if (component.types.includes('administrative_area_level_2')) {
address.subAdminArea = component.long_name;
}
else if (component.types.includes('sublocality') || component.types.includes('sublocality_level_1')) {
address.subLocality = component.long_name;
}
else if (component.types.includes('point_of_interest') || component.types.includes('colloquial_area')) {
address.feature = component.long_name;
}
}

return address;
}

export default {
geocodePosition(apiKey, position) {
if (!apiKey || !position || !position.lat || !position.lng) {
return Promise.reject(new Error("invalid apiKey / position"));
}

return this.googleRequest(`${googleUrl}?key=${apiKey}&latlng=${position.lat},${position.lng}`);
},

geocodeAddress(apiKey, address) {
if (!apiKey || !address) {
return Promise.reject(new Error("invalid apiKey / address"));
}

return this.googleRequest(`${googleUrl}?key=${apiKey}&address=${encodeURI(address)}`);
},

async googleRequest(url) {
const res = await fetch(url);
const json = await res.json();

if (!json.results || json.status !== 'OK') {
return Promise.reject(new Error(`geocoding error ${json.status}, ${json.error_message}`));
}

return json.results.map(format);
}
}

0 comments on commit 205beeb

Please sign in to comment.