Skip to content

Instantly share code, notes, and snippets.

@MustansirZia
Last active May 17, 2020 10:20
Show Gist options
  • Save MustansirZia/c729d042be222725840033d475520d5e to your computer and use it in GitHub Desktop.
Save MustansirZia/c729d042be222725840033d475520d5e to your computer and use it in GitHub Desktop.
Reverse Geocode JS [ES7] Gist - Latitude/Longitude to local address.
/**
* Created by M on 15/04/17. With ❤
*/
/*
* Reverse Geocode JS [ES7] Gist. Converts latitude/longitude to a human readable address.
* Firstly, tries to judge whether the lat/long is over a road. If so, returns the local street address
* with state and country stripped out.
* If not, returns the local address for the nearest point of interest. (or place). The second condition works even if
* the lat/long belongs to a disputed territory such as Kashmir, India.
* It uses Google's Geocode Web API and Places Web API.
* Calls are done over REST using axios.
* Transpile to ES5 by -
* $ babel index.js --out-file=output.js --presets=env --plugins=transform-runtime
*/
import axios from 'axios';
// Get your API key from here - https://developers.google.com/maps/documentation/javascript/get-api-key
const API_KEY = 'YOUR_MAPS_API_KEY_HERE';
export async function reverseGeoCodeAddress(latitude, longitude) {
try {
// Google's Geocode API to get address components for a place filtered by location type and result type.
// For more info - https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding
const response = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${API_KEY}&result_type=premise|natural_feature|park|route|intersection|street_number|street_address|airport|sublocality_level_5|sublocality_level_4|sublocality_level_3|sublocality_level_2|sublocality_level_1&location_type=GEOMETRIC_CENTER|RANGE_INTERPOLATED`);
const serialized = response.data;
// If the lat/long is indeed over a street or a road. This would say 'OK'.
if (serialized.status === 'OK') {
const results = serialized.results[0].address_components;
const addressString = results.reduce((acc, address) => {
const addressType = address.types.join('|');
if (addressType.includes('natural_feature')
|| addressType.includes('park')
|| addressType.includes('route')
|| addressType.includes('neighborhood')
|| addressType.includes('intersection')
|| addressType.includes('street_address')
|| addressType.includes('street_number')
|| addressType.includes('airport')
|| addressType.includes('sublocality')) {
return acc ? `${acc}, ${address.long_name}` : `${address.long_name}`;
}
return acc;
}, '');
return addressString;
} else if (serialized.status === 'ZERO_RESULTS') {
// If otherwise, fetch the nearest place and its details using Google's Places API.
// For more info - https://developers.google.com/places/web-service/search
const addressString = await resolveAddressFromPlacesAPI(latitude, longitude);
return addressString || 'Address Not Available';
} else {
throw new Error(serialized.status);
}
} catch (ex) {
throw new Error(ex);
}
}
async function resolveAddressFromPlacesAPI(latitude, longitude) {
try {
const response = await axios.get(`https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${API_KEY}&location=${latitude},${longitude}&rankby=distance`);
const serialized = response.data;
if (serialized.status === 'OK') {
if (serialized.results.length > 1) {
const { name, vicinity } = serialized.results[0];
return `${name} ${vicinity}`;
} else {
return null;
}
} else {
throw new Error(serialized.status);
}
} catch (ex) {
throw new Error(ex);
}
}
// Street Address.
// reverseGeoCodeAddress(14.608614226179533,120.99334727972746)
// => 814-817, Earnshaw Street, Sampaloc
// Place Address.
// reverseGeoCodeAddress(14.619009268584021, 120.98432499915361)
// => Cecilio Apostol Elementary School F Yuseco St, Santa Cruz, Manila
reverseGeoCodeAddress(14.619009268584021, 120.98432499915361)
.then(address => {
console.log(address);
})
.catch(err => {
console.log(err);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment