qwc2
Version:
QGIS Web Client
312 lines (310 loc) • 11.8 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* Copyright 2024 Sourcepole AG
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import ConfigUtils from './ConfigUtils';
import LocaleUtils from './LocaleUtils';
import VectorLayerUtils from './VectorLayerUtils';
var ValhallaSession = {
reqId: null,
pending: 0,
result: null,
clear: function clear() {
ValhallaSession.reqId = null;
ValhallaSession.pending = 0;
ValhallaSession.result = null;
}
};
function decodeShape(str) {
var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var index = 0;
var lat = 0;
var lng = 0;
var coordinates = [];
var shift = 0;
var result = 0;
var _byte = null;
var latitudeChange;
var longitudeChange;
var factor = Math.pow(10, precision || 6);
// Coordinates have variable length when encoded, so just keep
// track of whether we've hit the end of the string. In each
// loop iteration, a single coordinate is decoded.
while (index < str.length) {
// Reset shift, result, and byte
_byte = null;
shift = 0;
result = 0;
do {
_byte = str.charCodeAt(index++) - 63;
result |= (_byte & 0x1f) << shift;
shift += 5;
} while (_byte >= 0x20);
latitudeChange = result & 1 ? ~(result >> 1) : result >> 1;
shift = result = 0;
do {
_byte = str.charCodeAt(index++) - 63;
result |= (_byte & 0x1f) << shift;
shift += 5;
} while (_byte >= 0x20);
longitudeChange = result & 1 ? ~(result >> 1) : result >> 1;
lat += latitudeChange;
lng += longitudeChange;
coordinates.push([lng / factor, lat / factor]);
}
return coordinates;
}
function getValhallaParams(costing, locations, options, extraOptions) {
var costingOptions = {};
if (costing === 'auto') {
costingOptions.auto = {
top_speed: options.maxSpeed,
shortest: options.method === 'shortest',
use_ferry: options.useFerries ? 1 : 0,
use_tolls: options.useTollways ? 1 : 0,
use_highways: options.useHighways ? 1 : 0
};
} else if (costing === 'heavyvehicle') {
costing = 'truck';
costingOptions.truck = {
top_speed: options.maxSpeed,
shortest: options.method === 'shortest',
use_ferry: options.useFerries ? 1 : 0,
use_tolls: options.useTollways ? 1 : 0,
use_highways: options.useHighways ? 1 : 0
};
} else if (costing === 'transit') {
costing = 'multimodal';
var timepointMap = {
now: 0,
leaveat: 1,
arriveat: 2
};
extraOptions.date_time = {
value: options.time.slice(0, 16),
type: timepointMap[options.timepoint]
};
} else if (costing === 'bicycle') {
costingOptions.bicycle = {
cycling_speed: options.maxSpeed,
shortest: options.method === 'shortest',
use_ferry: options.useFerries ? 1 : 0
};
} else if (costing === 'pedestrian') {
costingOptions.pedestrian = {
walking_speed: options.maxSpeed,
shortest: options.method === 'shortest',
use_ferry: options.useFerries ? 1 : 0
};
}
var payload = _objectSpread({
costing: costing,
costing_options: costingOptions,
exclude_polygons: options.exclude_polygons || [],
locations: locations.map(function (loc) {
return {
lon: loc[0],
lat: loc[1]
};
}),
directions_options: {
units: "kilometers",
language: LocaleUtils.lang()
}
}, extraOptions);
return {
json: JSON.stringify(payload)
};
}
function computeRoute(costing, locations, options, callback) {
var extraOptions = {
id: "valhalla_directions"
};
var params = getValhallaParams(costing, locations, options, extraOptions);
var serviceUrl = ConfigUtils.getConfigProp("routingServiceUrl").replace(/\/$/, '');
var endpoint = options.optimized_route ? 'optimized_route' : 'route';
axios.get(serviceUrl + '/' + endpoint, {
params: params
}).then(function (response) {
if (!response.data || !response.data.trip) {
callback(false, {
errorMsgId: LocaleUtils.trmsg("routing.computefailed")
});
return;
}
var trip = response.data.trip;
if (trip.status !== 0) {
callback(false, response.data.trip.status_message);
}
// https://valhalla.github.io/valhalla/api/turn-by-turn/api-reference/
var travelTypeMap = {
car: {
icon: "routing-car",
color: [0, 0, 255, 1]
},
tractor_trailer: {
icon: "routing-truck",
color: [0, 0, 255, 1]
},
foot: {
icon: "routing-walking",
color: [127, 127, 255, 1]
},
road: {
icon: "routing-bicycle",
color: [0, 127, 0, 1]
},
tram: {
icon: "routing-tram",
color: [255, 0, 0, 1]
},
metro: {
icon: "routing-tram",
color: [255, 0, 0, 1]
},
rail: {
icon: "routing-train",
color: [255, 0, 0, 1]
},
bus: {
icon: "routing-bus",
color: [255, 0, 0, 1]
},
ferry: {
icon: "routing-ship",
color: [0, 0, 200, 1]
},
cable_car: {
icon: "routing-cablecar",
color: [255, 0, 0, 1]
},
gondola: {
icon: "routing-cablecar",
color: [255, 0, 0, 1]
},
funicular: {
icon: "routing-cablecar",
color: [255, 0, 0, 1]
}
};
var result = {
legs: trip.legs.map(function (leg) {
return {
coordinates: decodeShape(leg.shape),
time: leg.summary.time,
length: leg.summary.length * 1000,
maneuvers: leg.maneuvers.map(function (entry) {
return {
instruction: entry.instruction,
post_instruction: entry.verbal_post_transition_instruction,
geom_indices: [entry.begin_shape_index, entry.end_shape_index],
icon: (travelTypeMap[entry.travel_type] || {}).icon || "routing",
color: (travelTypeMap[entry.travel_type] || {}).color || "#0000FF",
time: entry.time,
length: entry.length * 1000
};
})
};
}),
locations: trip.locations.map(function (location) {
return {
lat: location.lat,
lon: location.lon,
orig_idx: location.original_index
};
}),
summary: {
bounds: [trip.summary.min_lon, trip.summary.min_lat, trip.summary.max_lon, trip.summary.max_lat],
time: trip.summary.time,
length: trip.summary.length * 1000
}
};
callback(true, result);
})["catch"](function (e) {
var error = ((e.response || {}).data || {}).error;
var data = {};
if (error) {
data.error = error;
} else {
data.errorMsgId = LocaleUtils.trmsg("routing.computefailed");
}
callback(false, data);
});
}
function computeIsochrone(costing, locations, contourOptions, options, callback) {
var extraOptions = {
contours: contourOptions.intervals.map(function (entry) {
return _defineProperty({}, contourOptions.mode, entry);
}),
id: "valhalla_isochrone"
};
var serviceUrl = ConfigUtils.getConfigProp("routingServiceUrl").replace(/\/$/, '');
var reqId = uuidv4();
ValhallaSession.reqId = reqId;
ValhallaSession.pending = locations.length;
locations.forEach(function (location) {
var params = getValhallaParams(costing, [location], options, extraOptions);
axios.get(serviceUrl + '/isochrone', {
params: params
}).then(function (response) {
if (reqId !== ValhallaSession.reqId) {
return;
}
if (!response.data || !response.data.features) {
ValhallaSession.clear();
callback(false, {
errorMsgId: LocaleUtils.trmsg("routing.computefailed")
});
return;
}
ValhallaSession.pending -= 1;
if (!ValhallaSession.result) {
ValhallaSession.result = response.data;
} else {
var _ValhallaSession$resu;
(_ValhallaSession$resu = ValhallaSession.result.features).push.apply(_ValhallaSession$resu, _toConsumableArray(response.data.features));
}
if (ValhallaSession.pending === 0) {
var areas = ValhallaSession.result.features.map(function (feature) {
return feature.geometry.coordinates;
});
callback(true, {
areas: areas,
bounds: VectorLayerUtils.computeFeatureBBox(ValhallaSession.result)
});
ValhallaSession.clear();
}
})["catch"](function (e) {
ValhallaSession.clear();
var error = ((e.response || {}).data || {}).error;
var data = {};
if (error) {
data.error = error;
} else {
data.errorMsgId = LocaleUtils.trmsg("routing.computefailed");
}
callback(false, data);
});
});
}
export default {
computeRoute: computeRoute,
computeIsochrone: computeIsochrone
};