UNPKG

@egodigital/egoose

Version:

Helper classes and functions for Node.js 10 or later.

139 lines 5.11 kB
"use strict"; /** * This file is part of the @egodigital/egoose distribution. * Copyright (c) e.GO Digital GmbH, Aachen, Germany (https://www.e-go-digital.com/) * * @egodigital/egoose is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, version 3. * * @egodigital/egoose is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); const http_1 = require("../http"); const index_1 = require("../index"); const _ = require("lodash"); const geocoder = require("node-geocoder"); const geodist = require('geodist'); const polyline = require('@mapbox/polyline'); /** * Tries to detect geo coordinates from address data. * * @param {string|AddressToGeoCoordinatesOptions} queryOrOpts The query string or the options. * @param {boolean} [throwOnError] Throw an exception on error or return (false). Default: (false) * * @return {GeoCoordinates|false} The location or (false) if not found. */ async function addressToGeoCoordinates(queryOrOpts, throwOnError) { let query; if (_.isObjectLike(queryOrOpts)) { const OPTS = queryOrOpts; query = `${index_1.toStringSafe(OPTS.street)} ${index_1.toStringSafe(OPTS.zipCode)} ${index_1.toStringSafe(OPTS.city)}`; } else { query = index_1.toStringSafe(queryOrOpts); } const ADDR_STR = index_1.normalizeString(query) .split(' ') .map(x => x.trim()) .filter(x => '' !== x) .join(' '); if ('' !== ADDR_STR) { try { const CLIENT_OPTS = { provider: 'google', httpAdapter: 'https', apiKey: index_1.toStringSafe(process.env.GOOGLE_API_KEY).trim(), formatter: null, }; const CLIENT = geocoder(CLIENT_OPTS); const RESULT = await CLIENT.geocode(ADDR_STR); if (RESULT && RESULT.length) { const ENTRY = RESULT[0]; if (ENTRY) { const COORDINATES = { lat: parseFloat(index_1.toStringSafe(ENTRY.latitude).trim()), lng: parseFloat(index_1.toStringSafe(ENTRY.longitude).trim()), }; if (!isNaN(COORDINATES.lat) && !isNaN(COORDINATES.lng)) { return COORDINATES; } } } } catch (e) { if (index_1.toBooleanSafe(throwOnError)) { throw e; /// re-throw } } } return false; } exports.addressToGeoCoordinates = addressToGeoCoordinates; /** * Calculates the distance between 2 geo points. * * @param {number} lat1 The latitude of the first point. * @param {number} lon1 The longitude of the first point. * @param {number} lat2 The latitude of the second point. * @param {number} lon2 The longitude of the second point. * @param {string} [unit] The custom unit to use. * * @return {number} The distance in meters. */ function calcDistance(lat1, lon1, lat2, lon2, unit = 'meters') { return geodist({ lat: lat1, lon: lon1 }, { lat: lat2, lon: lon2 }, { exact: true, unit: unit, }); } exports.calcDistance = calcDistance; /** * Calculates a route via a service, like MapBox. * * @param {GeoCoordinates} from The start location. * @param {GeoCoordinates} to The end location. * * @return {Promise<contracts.GeoCoordinates[]>} The promise with the route. */ async function calcRoute(from, to) { const RESPONSE = await http_1.POST('https://api.mapbox.com/directions/v5/mapbox/driving?access_token=' + encodeURIComponent(process.env.MAPBOX_API_TOKEN), { body: Buffer.from(`coordinates=${from.lng},${from.lat};${to.lng},${from.lat}&steps=true&waypoints=0;1&waypoint_names=Home;Work&banner_instructions=true`, 'utf8'), headers: { 'Content-type': 'application/x-www-form-urlencoded', } }); if (200 !== RESPONSE.code) { throw new Error(`Unexpected response: [${RESPONSE.code}] '${RESPONSE.status}'`); } const RESULT = JSON.parse((await RESPONSE.readBody()) .toString('utf8')); if ('ok' !== index_1.normalizeString(RESULT.code)) { throw new Error(`Routing failed!`); } const ROUTE = []; const WAYPOINTS = polyline.decode(RESULT.routes[0].geometry); for (const WP of WAYPOINTS) { ROUTE.push({ lat: WP[0], lng: WP[1], }); } // prepend 'from' ROUTE.unshift(from); // append 'to' ROUTE.push(to); return ROUTE; } exports.calcRoute = calcRoute; //# sourceMappingURL=index.js.map