diff --git a/package.json b/package.json
index 5f9de60..bdd70eb 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"select2": "^4.0.13",
"select2-bootstrap-5-theme": "^1.1.1",
"autonumeric": "^4.6.0",
+ "@here/flexpolyline": "^0.1.0",
"flatpickr": "^4.6.3",
"script-loader": "^0.7.2",
"timepicker": "^1.13.4",
diff --git a/src/Map/index.js b/src/Map/index.js
index 3973c89..9153edd 100644
--- a/src/Map/index.js
+++ b/src/Map/index.js
@@ -3,10 +3,12 @@ import 'leaflet/dist/leaflet.css';
import "leaflet.markercluster";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
+import { decode as decodeFlexPolyline } from '@here/flexpolyline';
import {RouteSetting, defaultRouteSettings} from './route.types.js';
let siteKey;
let markerImg;
+let mapProvider;
const svgCache = new Map();
const mapInstances = new WeakMap();
const selectedMarkers = new WeakMap();
@@ -25,9 +27,15 @@ const DEPOT_TYPE = {
END: 'depot-end'
};
+const MAP_PROVIDER = {
+ MAPY_CZ: 'mapy.cz',
+ HERE: 'here',
+};
+
async function run(options) {
siteKey = options.siteKey;
markerImg = options.markerImg;
+ mapProvider = options.mapProvider ?? MAP_PROVIDER.MAPY_CZ;
function applyEventHandlers(el) {
const {
@@ -51,7 +59,8 @@ async function run(options) {
const routeSettings = {
...defaultRouteSettings,
...route,
- customMarkers: customMarkers,
+ customMarkers,
+ mapProvider,
};
if (mapInstances.has(el)) {
@@ -71,28 +80,39 @@ async function run(options) {
onBeforeRouteCalculationMap.set(map, onBeforeRouteCalculation);
onAfterRouteCalculationMap.set(map, onAfterRouteCalculation);
- L.tileLayer("https://api.mapy.cz/v1/maptiles/basic/256/{z}/{x}/{y}?apikey=" + siteKey, {
- minZoom: 0,
- maxZoom: 19,
- attribution: '© Seznam.cz a.s. a další',
- }).addTo(map);
-
- const LogoControl = L.Control.extend({
- options: {
- position: 'bottomleft',
- },
- onAdd: function (map) {
- const container = L.DomUtil.create('div');
- const link = L.DomUtil.create('a', '', container);
- link.setAttribute('href', 'http://mapy.cz/');
- link.setAttribute('target', '_blank');
- link.innerHTML = '
';
- L.DomEvent.disableClickPropagation(link);
-
- return container;
- },
- });
- new LogoControl().addTo(map);
+ if (mapProvider === MAP_PROVIDER.HERE) {
+ L.tileLayer(
+ `https://maps.hereapi.com/v3/base/mc/{z}/{x}/{y}/png8?style=explore.day&apiKey=${siteKey}`,
+ {
+ minZoom: 0,
+ maxZoom: 20,
+ attribution: '© HERE',
+ }
+ ).addTo(map);
+ } else {
+ L.tileLayer(
+ `https://api.mapy.cz/v1/maptiles/basic/256/{z}/{x}/{y}?apikey=${siteKey}`,
+ {
+ minZoom: 0,
+ maxZoom: 19,
+ attribution: '© Seznam.cz a.s. a další',
+ }
+ ).addTo(map);
+
+ const LogoControl = L.Control.extend({
+ options: { position: 'bottomleft' },
+ onAdd: function () {
+ const container = L.DomUtil.create('div');
+ const link = L.DomUtil.create('a', '', container);
+ link.setAttribute('href', 'http://mapy.cz/');
+ link.setAttribute('target', '_blank');
+ link.innerHTML = '
';
+ L.DomEvent.disableClickPropagation(link);
+ return container;
+ },
+ });
+ new LogoControl().addTo(map);
+ }
if (position.length) {
if (zoom) {
@@ -100,6 +120,13 @@ async function run(options) {
} else {
map.fitBounds([position]);
}
+ } else if (!markers.length) {
+ const depot = routeSettings.startPoint ?? routeSettings.endPoint;
+ if (depot) {
+ map.setView([depot.lat, depot.lon], zoom ?? 12);
+ } else {
+ map.setView([50.0755, 14.4378], 7);
+ }
}
map.scrollWheelZoom.disable();
@@ -109,7 +136,6 @@ async function run(options) {
map.dragging.disable();
}
-
if (selectable) {
enableRectangleSelection(map, onSelectionChange, showSelectionOrder);
}
@@ -142,10 +168,7 @@ async function run(options) {
if (markers.length) {
addMarkers(map, markers, markerOptions, customMarkerOptions, position, selectable, onSelectionChange, showSelectionOrder, markerInfoCallback);
} else if (showDefaultMarker) {
- createMarker({
- id: 0,
- position: position
- }, markerOptions, customMarkerOptions, null, selectable, onSelectionChange, map, showSelectionOrder, markerInfoCallback).addTo(map);
+ createMarker({ id: 0, position }, markerOptions, customMarkerOptions, null, selectable, onSelectionChange, map, showSelectionOrder, markerInfoCallback).addTo(map);
}
};
} else {
@@ -154,10 +177,7 @@ async function run(options) {
if (markers.length) {
addMarkers(map, markers, markerOptions, customMarkerOptions, position, selectable, onSelectionChange, showSelectionOrder, markerInfoCallback);
} else if (showDefaultMarker) {
- createMarker({
- id: 0,
- position: position
- }, markerOptions, customMarkerOptions, null, selectable, onSelectionChange, map, showSelectionOrder, markerInfoCallback).addTo(map);
+ createMarker({ id: 0, position }, markerOptions, customMarkerOptions, null, selectable, onSelectionChange, map, showSelectionOrder, markerInfoCallback).addTo(map);
}
}
};
@@ -183,14 +203,10 @@ async function run(options) {
if (node.hasAttribute("data-adt-map")) {
applyEventHandlers(node);
}
-
- node.querySelectorAll?.('[data-adt-map]').forEach(el => {
- applyEventHandlers(el);
- });
+ node.querySelectorAll?.('[data-adt-map]').forEach(el => applyEventHandlers(el));
}
});
}
-
if (mutation.type === "attributes" && mutation.attributeName === "data-adt-map") {
applyEventHandlers(mutation.target);
}
@@ -204,9 +220,7 @@ async function run(options) {
attributeFilter: ["data-adt-map"]
});
- document.querySelectorAll('[data-adt-map]').forEach(function (el) {
- applyEventHandlers(el);
- });
+ document.querySelectorAll('[data-adt-map]').forEach(el => applyEventHandlers(el));
}
function enableRectangleSelection(map, onSelectionChange, showSelectionOrder) {
@@ -218,13 +232,7 @@ function enableRectangleSelection(map, onSelectionChange, showSelectionOrder) {
if (e.originalEvent.ctrlKey && e.originalEvent.shiftKey) {
isDrawing = true;
startPoint = e.latlng;
-
- rectangle = L.rectangle([startPoint, startPoint], {
- color: '#3388ff',
- weight: 2,
- fillOpacity: 0.1
- }).addTo(map);
-
+ rectangle = L.rectangle([startPoint, startPoint], { color: '#3388ff', weight: 2, fillOpacity: 0.1 }).addTo(map);
map.dragging.disable();
e.originalEvent.preventDefault();
}
@@ -246,10 +254,8 @@ function enableRectangleSelection(map, onSelectionChange, showSelectionOrder) {
const markerMap = markerInstances.get(map);
const selectedInArea = [];
- markerMap.forEach((markerInstance, markerId) => {
- const latLng = markerInstance.getLatLng();
-
- if (bounds.contains(latLng)) {
+ markerMap.forEach((markerInstance) => {
+ if (bounds.contains(markerInstance.getLatLng())) {
selectedInArea.push(markerInstance);
}
});
@@ -268,9 +274,7 @@ function enableRectangleSelection(map, onSelectionChange, showSelectionOrder) {
if (onSelectionChange && window[onSelectionChange]) {
const order = selectionOrder.get(map);
- const orderedIds = Array.from(order.entries())
- .sort((a, b) => a[1] - b[1])
- .map(entry => entry[0]);
+ const orderedIds = Array.from(order.entries()).sort((a, b) => a[1] - b[1]).map(e => e[0]);
window[onSelectionChange](orderedIds);
}
@@ -290,21 +294,12 @@ function addMarkers(map, markers, options, selectedOptions, position, selectable
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
-
iconCreateFunction: function (cluster) {
const childCount = cluster.getChildCount();
- let c = ' marker-cluster-';
- if (childCount < 10) {
- c += 'small';
- } else if (childCount < 100) {
- c += 'medium';
- } else {
- c += 'large';
- }
-
+ const c = childCount < 10 ? 'small' : childCount < 100 ? 'medium' : 'large';
return new L.DivIcon({
html: '
' + childCount + '
',
- className: 'marker-cluster' + c,
+ className: 'marker-cluster marker-cluster-' + c,
iconSize: new L.Point(40, 40)
});
}
@@ -326,7 +321,6 @@ function addMarkers(map, markers, options, selectedOptions, position, selectable
iconAnchor: [markerImage.width / 2, markerImage.height]
});
createMarker(marker, markerOptions, selectedOptions, cluster, selectable, onSelectionChange, map, showSelectionOrder, markerInfoCallback);
-
loadedCount++;
if (loadedCount === totalMarkers) {
checkAndApplyPreselection(map, markers, showSelectionOrder, onSelectionChange, selectable);
@@ -364,11 +358,6 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
mapMarker._selectedIcon = selectedOptions.icon;
mapMarker._markerData = marker;
- const markerElement = mapMarker.getElement();
- if (markerElement && markerElement.parentElement) {
- markerElement.parentElement.style.pointerEvents = 'visible';
- }
-
if (map) {
const markers = markerInstances.get(map);
markers.set(marker.id, mapMarker);
@@ -377,7 +366,6 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
const el = mapMarker.getElement();
if (el) {
el.style.cursor = 'pointer';
-
const parent = el.parentElement;
if (parent) {
parent.style.pointerEvents = 'all';
@@ -390,14 +378,14 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
if (selectable && map) {
mapMarker.on('click', function (e) {
- if (e.originalEvent.shiftKey && markerInfoCallback && window[markerInfoCallback]) {
+ if (e.originalEvent.shiftKey && !e.originalEvent.ctrlKey && markerInfoCallback && window[markerInfoCallback]) {
window[markerInfoCallback](marker);
L.DomEvent.stopPropagation(e);
+ L.DomEvent.preventDefault(e);
return;
}
const selected = selectedMarkers.get(map);
-
if (selected.has(marker.id)) {
deselectMarker(mapMarker, map, showSelectionOrder);
} else {
@@ -406,9 +394,7 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
if (onSelectionChange && window[onSelectionChange]) {
const order = selectionOrder.get(map);
- const orderedIds = Array.from(order.entries())
- .sort((a, b) => a[1] - b[1])
- .map(entry => entry[0]);
+ const orderedIds = Array.from(order.entries()).sort((a, b) => a[1] - b[1]).map(e => e[0]);
window[onSelectionChange](orderedIds);
}
@@ -416,11 +402,9 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
if (settings && settings.enabled) {
calculateRoute(map);
}
-
if (originalCallback && window[originalCallback]) {
window[originalCallback](e);
}
-
L.DomEvent.stopPropagation(e);
});
} else if (originalCallback) {
@@ -443,9 +427,7 @@ function createMarker(marker, options, selectedOptions, cluster = null, selectab
async function selectMarker(marker, map, showSelectionOrder) {
const selected = selectedMarkers.get(map);
const order = selectionOrder.get(map);
-
selected.add(marker.options.id);
-
const maxOrder = order.size > 0 ? Math.max(...order.values()) : 0;
const newOrder = maxOrder + 1;
order.set(marker.options.id, newOrder);
@@ -453,14 +435,13 @@ async function selectMarker(marker, map, showSelectionOrder) {
if (marker._selectedIcon) {
marker.setIcon(marker._selectedIcon);
}
-
const icon = marker.getElement();
if (icon) {
icon.classList.add('marker-selected');
}
if (showSelectionOrder) {
- const newIcon = await createMarkerIcon(map, marker.options.icon.options.iconUrl, newOrder)
+ const newIcon = await createMarkerIcon(map, marker.options.icon.options.iconUrl, newOrder);
marker.setIcon(newIcon);
}
}
@@ -472,11 +453,7 @@ function deselectMarker(marker, map, showSelectionOrder) {
selected.delete(marker.options.id);
order.delete(marker.options.id);
- order.forEach((value, key) => {
- if (value > removedOrder) {
- order.set(key, value - 1);
- }
- });
+ order.forEach((value, key) => { if (value > removedOrder) order.set(key, value - 1); });
if (showSelectionOrder) {
updateMarkerOrderDisplay(map, marker, null, false);
@@ -500,22 +477,16 @@ function deselectMarker(marker, map, showSelectionOrder) {
}
}
-
async function updateMarkerOrderDisplay(map, marker, orderNumber, isSelected, color = null) {
if (!marker._normalIcon || !marker._normalIcon.options) return;
-
- const iconUrl = isSelected && marker._selectedIcon ?
- marker._selectedIcon.options.iconUrl :
- marker._normalIcon.options.iconUrl;
+ const iconUrl = isSelected && marker._selectedIcon ? marker._selectedIcon.options.iconUrl : marker._normalIcon.options.iconUrl;
const newIcon = await createMarkerIcon(map, iconUrl, orderNumber, color);
-
marker.setIcon(newIcon);
}
async function createMarkerIcon(map, iconUrl, orderNumber, color = null) {
let inlineStyle = null;
const settings = routeSettingsMap.get(map);
-
if ((settings && settings.enabled) || color) {
inlineStyle = `--marker-fill: ${color ?? settings.color};`;
}
@@ -546,12 +517,10 @@ function applyPreselectedMarkers(map, markersData, showSelectionOrder, onSelecti
const markerMap = markerInstances.get(map);
const order = selectionOrder.get(map);
const preselected = markersData
- .filter(m => {
- return m.selected === true;
- })
+ .filter(m => m.selected === true)
.sort((a, b) => (a.selectionOrder || 0) - (b.selectionOrder || 0));
- preselected.forEach((markerData, index) => {
+ preselected.forEach((markerData) => {
const markerInstance = markerMap.get(markerData.id);
if (markerInstance) {
selectMarker(markerInstance, map, showSelectionOrder);
@@ -561,10 +530,7 @@ function applyPreselectedMarkers(map, markersData, showSelectionOrder, onSelecti
});
if (onSelectionChange && window[onSelectionChange] && order.size > 0) {
- const orderedIds = Array.from(order.entries())
- .sort((a, b) => a[1] - b[1])
- .map(entry => entry[0]);
-
+ const orderedIds = Array.from(order.entries()).sort((a, b) => a[1] - b[1]).map(e => e[0]);
window[onSelectionChange](orderedIds);
}
@@ -586,24 +552,22 @@ async function calculateRoute(map) {
routePolylines.set(map, null);
}
- if (!routeSettings || !routeSettings.enabled) {
- return;
- }
+ if (!routeSettings || !routeSettings.enabled) return;
const hasCustomStart = routeSettings.startPoint !== null && routeSettings.startPoint !== undefined;
const hasCustomEnd = routeSettings.endPoint !== null && routeSettings.endPoint !== undefined;
- if (hasCustomStart) addDepotMarker(map, routeSettings.startPoint, DEPOT_TYPE.START);
- if (hasCustomEnd) addDepotMarker(map, routeSettings.endPoint, DEPOT_TYPE.END);
+ if (hasCustomStart) {
+ addDepotMarker(map, routeSettings.startPoint, DEPOT_TYPE.START);
+ }
+ if (hasCustomEnd) {
+ addDepotMarker(map, routeSettings.endPoint, DEPOT_TYPE.END);
+ }
if (!selectedSet || selectedSet.size === 0) return;
- const orderedIds = Array.from(order.entries())
- .sort((a, b) => a[1] - b[1])
- .map(entry => entry[0]);
- const routeMarkers = orderedIds
- .map(id => markers.find(m => m.id === id))
- .filter(m => m !== undefined);
+ const orderedIds = Array.from(order.entries()).sort((a, b) => a[1] - b[1]).map(e => e[0]);
+ const routeMarkers = orderedIds.map(id => markers.find(m => m.id === id)).filter(m => m !== undefined);
if (routeMarkers.length < 2) return;
@@ -612,86 +576,25 @@ async function calculateRoute(map) {
window[beforeCallback]();
}
- let startPoint = hasCustomStart ? routeSettings.startPoint : routeMarkers[0].position;
- let endPoint = hasCustomEnd ? routeSettings.endPoint : routeMarkers[routeMarkers.length - 1].position;
+ const isHere = routeSettings.mapProvider === MAP_PROVIDER.HERE;
+ const startPoint = hasCustomStart ? routeSettings.startPoint : routeMarkers[0].position;
+ const endPoint = hasCustomEnd ? routeSettings.endPoint : routeMarkers[routeMarkers.length - 1].position;
- const WAYPOINTS_LIMIT = 15;
const allCoords = [];
const allParts = [];
- let totalDuration = 0;
- let totalLength = 0;
try {
- if (routeMarkers.length <= WAYPOINTS_LIMIT) {
- const params = new URLSearchParams({
- start: `${startPoint.lon},${startPoint.lat}`,
- end: `${endPoint.lon},${endPoint.lat}`,
- routeType: routeSettings.routeType,
- apikey: siteKey
- });
- routeMarkers.forEach(m => params.append('waypoints', `${m.position.lon},${m.position.lat}`));
-
- const response = await fetch(`https://api.mapy.cz/v1/routing/route?${params.toString()}`);
- const data = await response.json();
-
- if (data.geometry?.geometry?.coordinates) {
- allCoords.push(...data.geometry.geometry.coordinates.map(c => [c[1], c[0]]));
- }
- if (data.parts) {
- allParts.push(...data.parts);
- }
- if (data.duration) {
- totalDuration += data.duration;
- }
- if (data.length) {
- totalLength += data.length;
- }
+ if (isHere) {
+ await calculateRouteHere({ routeMarkers, startPoint, endPoint, routeSettings, allCoords, allParts });
} else {
- const chunks = [];
- for (let i = 0; i < routeMarkers.length; i += WAYPOINTS_LIMIT) {
- chunks.push(routeMarkers.slice(i, i + WAYPOINTS_LIMIT));
- }
-
- for (let i = 0; i < chunks.length; i++) {
- const chunk = chunks[i];
- const isFirstChunk = i === 0;
- const isLastChunk = i === chunks.length - 1;
-
- const chunkStart = isFirstChunk ? startPoint : chunks[i - 1][chunks[i - 1].length - 1].position;
- const chunkEnd = isLastChunk ? endPoint : chunk[chunk.length - 1].position;
-
- const params = new URLSearchParams({
- start: `${chunkStart.lon},${chunkStart.lat}`,
- end: `${chunkEnd.lon},${chunkEnd.lat}`,
- routeType: routeSettings.routeType,
- apikey: siteKey
- });
-
- const markersToAdd = isFirstChunk ? chunk : chunk.slice(1);
- markersToAdd.forEach(m => params.append('waypoints', `${m.position.lon},${m.position.lat}`));
-
- const response = await fetch(`https://api.mapy.cz/v1/routing/route?${params.toString()}`);
- const data = await response.json();
-
- if (data.geometry?.geometry?.coordinates) {
- allCoords.push(...data.geometry.geometry.coordinates.map(c => [c[1], c[0]]));
- }
- if (data.parts) {
- allParts.push(...data.parts);
- }
- if (data.duration) {
- totalDuration += data.duration;
- }
- if (data.length) {
- totalLength += data.length;
- }
- }
+ await calculateRouteMapyCz({ routeMarkers, startPoint, endPoint, routeSettings, allCoords, allParts });
}
} catch (error) {
console.error('Error calculating route:', error);
const afterCallback = onAfterRouteCalculationMap.get(map);
- if (afterCallback && window[afterCallback]) window[afterCallback]({}, 0, 0);
-
+ if (afterCallback && window[afterCallback]) {
+ window[afterCallback]({}, 0, 0);
+ }
return;
}
@@ -704,20 +607,103 @@ async function calculateRoute(map) {
routePolylines.set(map, polyline);
}
- // @type {TRouteParts}
+ const totalDuration = allParts.reduce((s, p) => s + (p.duration || 0), 0);
+ const totalLength = allParts.reduce((s, p) => s + (p.length || 0), 0);
+
const routeParts = {};
allParts.forEach((part, index) => {
if (index < orderedIds.length) {
- const markerId = orderedIds[index];
- routeParts[markerId] = {
- duration: part.duration,
- length: part.length,
- };
+ routeParts[orderedIds[index]] = { duration: part.duration, length: part.length };
}
});
const afterCallback = onAfterRouteCalculationMap.get(map);
- if (afterCallback && window[afterCallback]) window[afterCallback](routeParts, totalLength, totalDuration);
+ if (afterCallback && window[afterCallback]) {
+ window[afterCallback](routeParts, totalLength, totalDuration);
+ }
+}
+
+async function calculateRouteMapyCz({ routeMarkers, startPoint, endPoint, routeSettings, allCoords, allParts }) {
+ const WAYPOINTS_LIMIT = 15;
+
+ const chunks = [];
+ for (let i = 0; i < routeMarkers.length; i += WAYPOINTS_LIMIT) chunks.push(routeMarkers.slice(i, i + WAYPOINTS_LIMIT));
+
+ for (let i = 0; i < chunks.length; i++) {
+ const chunk = chunks[i];
+ const isFirstChunk = i === 0;
+ const isLastChunk = i === chunks.length - 1;
+ const chunkStart = isFirstChunk ? startPoint : chunks[i - 1][chunks[i - 1].length - 1].position;
+ const chunkEnd = isLastChunk ? endPoint : chunk[chunk.length - 1].position;
+
+ const params = new URLSearchParams({
+ start: `${chunkStart.lon},${chunkStart.lat}`,
+ end: `${chunkEnd.lon},${chunkEnd.lat}`,
+ routeType: routeSettings.routeType,
+ apikey: siteKey
+ });
+
+ const markersToAdd = isFirstChunk ? chunk : chunk.slice(1);
+ markersToAdd.forEach(m => params.append('waypoints', `${m.position.lon},${m.position.lat}`));
+
+ const response = await fetch(`https://api.mapy.cz/v1/routing/route?${params.toString()}`);
+ const data = await response.json();
+
+ if (data.geometry?.geometry?.coordinates) {
+ allCoords.push(...data.geometry.geometry.coordinates.map(c => [c[1], c[0]]));
+ }
+ if (data.parts) {
+ allParts.push(...data.parts);
+ }
+ }
+}
+
+async function calculateRouteHere({ routeMarkers, startPoint, endPoint, routeSettings, allCoords, allParts }) {
+ const WAYPOINTS_LIMIT = 98;
+
+ const chunks = [];
+ for (let i = 0; i < routeMarkers.length; i += WAYPOINTS_LIMIT) chunks.push(routeMarkers.slice(i, i + WAYPOINTS_LIMIT));
+
+ for (let i = 0; i < chunks.length; i++) {
+ const chunk = chunks[i];
+ const isFirstChunk = i === 0;
+ const isLastChunk = i === chunks.length - 1;
+ const chunkStart = isFirstChunk ? startPoint : chunks[i - 1][chunks[i - 1].length - 1].position;
+ const chunkEnd = isLastChunk ? endPoint : chunk[chunk.length - 1].position;
+
+ const params = new URLSearchParams({
+ origin: `${chunkStart.lat},${chunkStart.lon}`,
+ destination: `${chunkEnd.lat},${chunkEnd.lon}`,
+ transportMode: routeSettings.routeType,
+ return: 'polyline,summary',
+ apiKey: siteKey,
+ });
+
+ if (routeSettings.departureTime) {
+ params.set('departureTime', routeSettings.departureTime);
+ }
+
+ const viaMarkers = isFirstChunk ? chunk : chunk.slice(1);
+ viaMarkers.forEach(m => params.append('via', `${m.position.lat},${m.position.lon}`));
+
+ const response = await fetch(`https://router.hereapi.com/v8/routes?${params.toString()}`);
+ const data = await response.json();
+
+ if (!data.routes || data.routes.length === 0) {
+ console.warn('HERE routing: žádná trasa nenalezena', data);
+ continue;
+ }
+
+ for (const section of data.routes[0].sections) {
+ if (section.polyline) {
+ const decoded = decodeFlexPolyline(section.polyline);
+ allCoords.push(...decoded.polyline);
+ }
+ if (section.summary) {
+ allParts.push({ duration: section.summary.duration, length: section.summary.length });
+ }
+ }
+ }
}
function addDepotMarker(map, position, depotType) {
@@ -728,53 +714,35 @@ function addDepotMarker(map, position, depotType) {
const img = new Image();
img.src = iconUrl;
img.onload = function () {
- const icon = L.icon({
- iconUrl: iconUrl,
- iconSize: [img.width, img.height],
- iconAnchor: [img.width / 2, img.height]
- });
-
- L.marker(position, {icon: icon}).addTo(map);
+ const icon = L.icon({ iconUrl, iconSize: [img.width, img.height], iconAnchor: [img.width / 2, img.height] });
+ L.marker(position, { icon }).addTo(map);
};
}
function getSelectedMarkers(mapElement) {
const map = mapInstances.get(mapElement);
if (!map) return [];
-
const order = selectionOrder.get(map);
- return Array.from(order.entries())
- .sort((a, b) => a[1] - b[1])
- .map(entry => entry[0]);
+ return Array.from(order.entries()).sort((a, b) => a[1] - b[1]).map(e => e[0]);
}
function clearSelection(mapElement) {
const map = mapInstances.get(mapElement);
if (!map) return;
-
const selected = selectedMarkers.get(map);
const order = selectionOrder.get(map);
const markers = markerInstances.get(map);
-
- markers.forEach((markerInstance) => {
- if (selected.has(markerInstance.options.id)) {
- deselectMarker(markerInstance, map, true);
- }
- });
-
+ markers.forEach((markerInstance) => { if (selected.has(markerInstance.options.id)) {
+ deselectMarker(markerInstance, map, true);
+ } });
selected.clear();
order.clear();
}
-function getOnSelectionChange(map) {
- return onSelectionChangeMap.get(map);
-}
-
function toggleMarker(mapElement, markerId, selected) {
const map = mapInstances.get(mapElement);
const markers = markerInstances.get(map);
const marker = markers?.get(markerId);
-
if (!marker) return;
const selectedSet = selectedMarkers.get(map);
@@ -799,6 +767,19 @@ function toggleMarker(mapElement, markerId, selected) {
}
}
+function setOrder(mapElement, markerId, orderNumber) {
+ let color = null;
+ const map = mapInstances.get(mapElement);
+ const settings = $(mapElement).data('adt-map');
+ const markers = markerInstances.get(map);
+ const marker = markers?.get(markerId);
+ if (settings && settings.route && settings.route.enabled) {
+ color = settings.route.color;
+ }
+ if (!marker) return;
+ updateMarkerOrderDisplay(mapElement, marker, orderNumber, true, color);
+}
+
function addMarkerAndSelect(mapElement, markerData) {
const map = mapInstances.get(mapElement);
if (!map) return;
@@ -814,65 +795,61 @@ function addMarkerAndSelect(mapElement, markerData) {
return;
}
- const iconUrl = routeSettings?.customMarkers?.normal || markerImg;
- const img = new Image();
- img.src = iconUrl;
- img.onload = function () {
- const icon = L.icon({
- iconUrl,
- iconSize: [img.width, img.height],
- iconAnchor: [img.width / 2, img.height]
+ const normalIconUrl = routeSettings?.customMarkers?.normal || markerImg;
+ const selectedIconUrl = routeSettings?.customMarkers?.selected || normalIconUrl;
+
+ const normalImg = new Image();
+ normalImg.src = normalIconUrl;
+ normalImg.onload = function () {
+ const normalIcon = L.icon({
+ iconUrl: normalIconUrl,
+ iconSize: [normalImg.width, normalImg.height],
+ iconAnchor: [normalImg.width / 2, normalImg.height],
});
- const options = { icon };
- const selectedOptions = { icon: L.icon({
- iconUrl: routeSettings?.customMarkers?.selected || iconUrl,
- iconSize: [img.width, img.height],
- iconAnchor: [img.width / 2, img.height]
- })};
-
- const newMarker = createMarker(
- markerData,
- options,
- selectedOptions,
- cluster || null,
- true,
- onSelectionChangeMap.get(map),
- map,
- true,
- null
- );
-
- if (!cluster) {
- newMarker.addTo(map);
- }
+ const loadSelectedIcon = (callback) => {
+ if (selectedIconUrl === normalIconUrl) {
+ callback(normalIcon);
+ return;
+ }
+ const selectedImgEl = new Image();
+ selectedImgEl.src = selectedIconUrl;
+ selectedImgEl.onload = function () {
+ callback(L.icon({
+ iconUrl: selectedIconUrl,
+ iconSize: [selectedImgEl.width, selectedImgEl.height],
+ iconAnchor: [selectedImgEl.width / 2, selectedImgEl.height],
+ }));
+ };
+ };
- markersData.push(markerData);
+ loadSelectedIcon((selectedIcon) => {
+ const newMarker = createMarker(
+ markerData,
+ { icon: normalIcon },
+ { icon: selectedIcon },
+ cluster || null,
+ true,
+ onSelectionChangeMap.get(map),
+ map,
+ true,
+ null
+ );
+
+ if (!cluster) {
+ newMarker.addTo(map);
+ }
- selectMarker(newMarker, map, true);
+ markersData.push(markerData);
+ selectMarker(newMarker, map, true);
- if (routeSettings?.enabled) {
- calculateRoute(map);
- }
+ if (routeSettings?.enabled) {
+ calculateRoute(map);
+ }
+ });
};
}
-function setOrder(mapElement, markerId, orderNumber) {
- let color = null;
- const map = mapInstances.get(mapElement);
- const settings = $(mapElement).data('adt-map')
- const markers = markerInstances.get(map);
- const marker = markers?.get(markerId);
-
- if (settings && settings.route && settings.route.enabled) {
- color = settings.route.color;
- }
-
- if (!marker) return;
-
- updateMarkerOrderDisplay(mapElement, marker, orderNumber, true, color);
-}
-
function onBeforeRouteCalculation(mapElement, callbackName) {
const map = mapInstances.get(mapElement);
if (!map) return;
@@ -901,4 +878,4 @@ export default {
onAfterRouteCalculation,
recalculateRoute,
addMarkerAndSelect,
-}
+}
\ No newline at end of file