UNPKG

universal-geocoder

Version:

Universal geocoding abstraction server-side and client-side with multiple built-in providers

134 lines (122 loc) 3.52 kB
import { GeocodeQuery, GeocodeQueryObject } from "query"; import { MapQuestLocation, MapQuestLocationObject } from "provider"; import Geocoded, { GeocodedObject } from "Geocoded"; import { ADMIN_LEVEL_CODES } from "AdminLevel"; export interface MapQuestGeocodeQueryObject extends GeocodeQueryObject { readonly location?: | MapQuestLocationObject | MapQuestLocation | GeocodedObject | Geocoded; } export default class MapQuestGeocodeQuery extends GeocodeQuery { private readonly location?: MapQuestLocationObject; protected constructor({ location, ...geocodeQueryObject }: MapQuestGeocodeQueryObject) { super({ ...geocodeQueryObject, text: location ? "from_location" : geocodeQueryObject.text, }); if (!location) { return; } if ("getLatLng" in location) { this.location = (<MapQuestLocation>location).toObject(); return; } if ("getLocality" in location) { this.location = MapQuestGeocodeQuery.convertGeocodedToLocationObject( <Geocoded>location ); return; } let geocodedPropsNumber = 0; let mapQuestLocationPropsNumber = 0; const geocodedObject = Geocoded.create({}).toObject(); Object.keys(geocodedObject).forEach((prop) => { if (prop in location) { geocodedPropsNumber += 1; } }); [ "street", "adminArea5", "city", "adminArea4", "county", "adminArea3", "state", "adminArea1", "country", "postalCode", "type", ].forEach((prop) => { if (prop in location) { mapQuestLocationPropsNumber += 1; } }); if (geocodedPropsNumber > mapQuestLocationPropsNumber) { this.location = MapQuestGeocodeQuery.convertGeocodedToLocationObject( Geocoded.create(<GeocodedObject>location) ); return; } this.location = location; } public static create( object: MapQuestGeocodeQueryObject ): MapQuestGeocodeQuery { return new this(object); } public toObject(): MapQuestGeocodeQueryObject { return { ...super.toObject(), location: this.location, }; } public withLocation( location: | MapQuestLocationObject | MapQuestLocation | GeocodedObject | Geocoded ): MapQuestGeocodeQuery { return new MapQuestGeocodeQuery({ ...this.toObject(), location }); } public getLocation(): undefined | MapQuestLocationObject { return this.location; } private static convertGeocodedToLocationObject( geocoded: Geocoded ): MapQuestLocationObject { const location: MapQuestLocationObject = {}; const streetParts = [ geocoded.getStreetNumber() || "", geocoded.getStreetName() || "", ]; const street = streetParts.join(" "); if (street) { location.street = street; } if (geocoded.getLocality()) { location.city = geocoded.getLocality(); } if (geocoded.getCountry()) { location.country = geocoded.getCountry(); } if (geocoded.getPostalCode()) { location.postalCode = geocoded.getPostalCode(); } geocoded.getAdminLevels().forEach((adminLevel) => { if (adminLevel.getLevel() === ADMIN_LEVEL_CODES.STATE_CODE) { location.state = adminLevel.getCode() || adminLevel.getName(); } if (adminLevel.getLevel() === ADMIN_LEVEL_CODES.COUNTY_CODE) { location.county = adminLevel.getCode() || adminLevel.getName(); } }); return location; } }