react-geoidentify-country-selector
Version:
Identifier geocoder for country selector on react
196 lines (137 loc) • 5.29 kB
JavaScript
/**
* Request module
* @type {request|exports|module.exports}
*/
const request = require('request');
class YaGeocoder {
constructor(options) {}
resolve(query, options, callback) {
if (!query) {
return callback(new Error('No address specified'));
}
if (typeof options == 'function') {
callback = options;
options = {};
}
let geoRequest = this.buildRequest(query, options);
this.resolveQuery(geoRequest, options, callback);
}
buildRequest(query, options) {
let results = options.results || 10;
var q = 'geocode=' + encodeURIComponent(query) + '&results=' + results +
'&format=json&lang=en-US';
if (options.kind) {
q += '&kind=' + options.kind;
}
return q;
}
resolveQuery(geoRequest, options, callback) {
request.get({
url: 'https://geocode-maps.yandex.ru/1.x/?' + geoRequest,
json: true,
timeout: options.timeout || 60000
}, (err, response, body) => {
var collection = [];
if (err) {
return callback(err);
}
if (!body) {
return callback(null, collection);
}
if (body.error) {
return callback(new Error(body.error.message));
}
if (!body.response) {
return callback(new Error(`Empty response, address not resolved`));
}
body.response.GeoObjectCollection.featureMember.forEach(item => {
let geoObject = item.GeoObject;
var refinedGeoObject = this.refineGeoObject(geoObject);
if (refinedGeoObject != null) {
collection.push(refinedGeoObject);
}
});
callback(null, collection);
});
}
refineGeoObject(geoObject) {
var administrativeArea = geoObject.metaDataProperty.GeocoderMetaData.AddressDetails.Country.AdministrativeArea;
var countryCode = geoObject.metaDataProperty.GeocoderMetaData.Address.country_code;
if (!administrativeArea) {
return null;
}
let geoCoordinates = geoObject.Point.pos.split(' ');
let locality;
let Thoroughfare;
let Premise;
let geo = {
longitude: geoCoordinates[0],
latitude: geoCoordinates[1],
obl: administrativeArea.AdministrativeAreaName,
country_code: countryCode
};
if (administrativeArea.hasOwnProperty('SubAdministrativeArea')) {
locality = administrativeArea.SubAdministrativeArea.Locality;
geo.raion = administrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
if (locality) {
geo.place = locality.LocalityName;
} else {
return null;
}
} else {
locality = administrativeArea.Locality;
if (locality) {
geo.geoRaion = locality.LocalityName;
} else {
return null;
}
}
if (locality.hasOwnProperty('DependentLocality')) {
if (locality.DependentLocality.hasOwnProperty('Premise')) {
geo.place = locality.DependentLocality.DependentLocalityName;
Premise = locality.DependentLocality.Premise;
geo.house = Premise.PremiseNumber;
} else if (locality.DependentLocality.hasOwnProperty('Thoroughfare')) {
Thoroughfare = locality.DependentLocality.Thoroughfare;
geo.street = Thoroughfare.ThoroughfareName;
if (Thoroughfare.hasOwnProperty('Premise')) {
if (Thoroughfare.Premise.hasOwnProperty('PremiseNumber')) {
geo.house = Thoroughfare.Premise.PremiseNumber;
}
}
} else if (locality.DependentLocality.hasOwnProperty('DependentLocality')) {
var DependentLocality2 = locality.DependentLocality.DependentLocality;
geo.place = DependentLocality2.DependentLocalityName;
} else {
geo.place = locality.DependentLocality.DependentLocalityName;
}
} else {
if (locality.hasOwnProperty('Thoroughfare')) {
Thoroughfare = locality.Thoroughfare;
geo.street = Thoroughfare.ThoroughfareName;
if (Thoroughfare.hasOwnProperty('Premise')) {
geo.house = Thoroughfare.Premise.PremiseNumber;
}
}
}
var addressArr = [geo.obl];
if (geo.raion) {
addressArr.push(geo.raion);
}
if (geo.place) {
addressArr.push(geo.place);
}
if (geo.street) {
addressArr.push(geo.street);
}
if (geo.house) {
addressArr.push(geo.house);
}
if (geo.country_code) {
addressArr.push(geo.country_code);
}
geo.address = addressArr.join(', ');
return geo;
}
}
module.exports = YaGeocoder;