mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
optimized marks calculation speed
This commit is contained in:
parent
0ea9710497
commit
d8b51e0b1a
1 changed files with 50 additions and 45 deletions
|
@ -1,29 +1,30 @@
|
|||
import { divIcon, LatLngLiteral, Layer, LayerGroup, Map, marker, Marker } from "leaflet";
|
||||
import { arrowClusterIcon, createArrow } from "~/utils/arrow";
|
||||
import { divIcon, LatLngLiteral, Layer, LayerGroup, Map, marker, Marker } from 'leaflet';
|
||||
import { arrowClusterIcon, createArrow } from '~/utils/arrow';
|
||||
import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
|
||||
import { allwaysPositiveAngleDeg, angleBetweenPoints, distKmHaversine } from "~/utils/geom";
|
||||
import { allwaysPositiveAngleDeg, angleBetweenPoints, distKmHaversine } from '~/utils/geom';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface KmMarksOptions {
|
||||
showMiddleMarkers: boolean,
|
||||
showEndMarker: boolean,
|
||||
kmMarksStep: number,
|
||||
showMiddleMarkers: boolean;
|
||||
showEndMarker: boolean;
|
||||
kmMarksStep: number;
|
||||
}
|
||||
|
||||
class KmMarksLayer extends LayerGroup {
|
||||
constructor(latlngs?: LatLngLiteral[], options?: KmMarksOptions){
|
||||
constructor(latlngs?: LatLngLiteral[], options?: KmMarksOptions) {
|
||||
super();
|
||||
|
||||
this.options = {
|
||||
showMiddleMarkers: true,
|
||||
showEndMarker: true,
|
||||
kmMarksStep: 10,
|
||||
kmMarksStep: 20,
|
||||
...(options || {}),
|
||||
} as KmMarksOptions;
|
||||
}
|
||||
|
||||
setLatLngs = (latlngs: LatLngLiteral[]): void => {
|
||||
if (!this.map) return;
|
||||
|
||||
this.marksLayer.clearLayers();
|
||||
this.endMarker.clearLayers();
|
||||
|
||||
|
@ -36,7 +37,7 @@ class KmMarksLayer extends LayerGroup {
|
|||
};
|
||||
|
||||
drawMiddleMarkers = (latlngs: LatLngLiteral[]) => {
|
||||
const kmMarks = {};
|
||||
const marks = [];
|
||||
let last_km_mark = 0;
|
||||
|
||||
this.distance = latlngs.reduce((dist, current, index) => {
|
||||
|
@ -51,20 +52,20 @@ class KmMarksLayer extends LayerGroup {
|
|||
if (rounded > last_km_mark) {
|
||||
const angle = angleBetweenPoints(
|
||||
this.map.latLngToContainerPoint(current),
|
||||
this.map.latLngToContainerPoint(next),
|
||||
this.map.latLngToContainerPoint(next)
|
||||
);
|
||||
|
||||
// if segment is too long, we'll add multiple markers on it
|
||||
for (let i = 1; i <= count; i += 1) {
|
||||
const step = last_km_mark + (i * this.options.kmMarksStep);
|
||||
const step = last_km_mark + i * this.options.kmMarksStep;
|
||||
const shift = (step - dist) / diff;
|
||||
|
||||
const coords = {
|
||||
lat: current.lat - ((current.lat - next.lat) * shift),
|
||||
lng: current.lng - ((current.lng - next.lng) * shift),
|
||||
lat: current.lat - (current.lat - next.lat) * shift,
|
||||
lng: current.lng - (current.lng - next.lng) * shift,
|
||||
};
|
||||
|
||||
kmMarks[step] = { ...coords, angle };
|
||||
this.marksLayer.addLayer(this.createMiddleMarker(coords, angle, step));
|
||||
marks.push(this.createMiddleMarker(coords, angle, step));
|
||||
}
|
||||
|
||||
last_km_mark = rounded;
|
||||
|
@ -72,49 +73,54 @@ class KmMarksLayer extends LayerGroup {
|
|||
|
||||
return sum;
|
||||
}, 0);
|
||||
|
||||
this.marksLayer.addLayers(marks);
|
||||
};
|
||||
|
||||
createMiddleMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker => marker(latlng, {
|
||||
draggable: false,
|
||||
interactive: false,
|
||||
icon: divIcon({
|
||||
html: `
|
||||
<div class="leaflet-km-dist" style="transform: translate(-50%, -50%) rotate(${allwaysPositiveAngleDeg(angle)}deg);">
|
||||
createMiddleMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker =>
|
||||
marker(latlng, {
|
||||
draggable: false,
|
||||
interactive: false,
|
||||
icon: divIcon({
|
||||
html: `
|
||||
<div class="leaflet-km-dist" style="transform: translate(-50%, -50%) rotate(${allwaysPositiveAngleDeg(
|
||||
angle
|
||||
)}deg);">
|
||||
${distance}
|
||||
</div>
|
||||
`,
|
||||
className: 'leaflet-km-marker',
|
||||
iconSize: [11, 11],
|
||||
iconAnchor: [6, 6]
|
||||
})
|
||||
});
|
||||
className: 'leaflet-km-marker',
|
||||
iconSize: [11, 11],
|
||||
iconAnchor: [6, 6],
|
||||
}),
|
||||
});
|
||||
|
||||
createEndMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker => marker(latlng, {
|
||||
draggable: false,
|
||||
interactive: false,
|
||||
icon: divIcon({
|
||||
html: `
|
||||
createEndMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker =>
|
||||
marker(latlng, {
|
||||
draggable: false,
|
||||
interactive: false,
|
||||
icon: divIcon({
|
||||
html: `
|
||||
<div class="leaflet-km-dist">
|
||||
${parseFloat(distance.toFixed(1))}
|
||||
</div>
|
||||
`,
|
||||
className: classNames('leaflet-km-marker end-marker', { right: (angle > -90 && angle < 90) }),
|
||||
iconSize: [11, 11],
|
||||
iconAnchor: [6, 6]
|
||||
}),
|
||||
zIndexOffset: -100,
|
||||
});
|
||||
className: classNames('leaflet-km-marker end-marker', { right: angle > -90 && angle < 90 }),
|
||||
iconSize: [11, 11],
|
||||
iconAnchor: [6, 6],
|
||||
}),
|
||||
zIndexOffset: -100,
|
||||
});
|
||||
|
||||
drawEndMarker = (latlngs: LatLngLiteral[]): void => {
|
||||
this.endMarker.clearLayers();
|
||||
|
||||
const current = latlngs[latlngs.length - 2];
|
||||
const next = latlngs[latlngs.length - 1
|
||||
];
|
||||
const next = latlngs[latlngs.length - 1];
|
||||
|
||||
const angle = angleBetweenPoints(
|
||||
this.map.latLngToContainerPoint(current),
|
||||
this.map.latLngToContainerPoint(next),
|
||||
this.map.latLngToContainerPoint(next)
|
||||
);
|
||||
|
||||
this.endMarker.addLayer(this.createEndMarker(next, angle, this.distance));
|
||||
|
@ -134,9 +140,8 @@ class KmMarksLayer extends LayerGroup {
|
|||
distance: number = 0;
|
||||
}
|
||||
|
||||
|
||||
KmMarksLayer.addInitHook(function () {
|
||||
this.once('add', (event) => {
|
||||
KmMarksLayer.addInitHook(function() {
|
||||
this.once('add', event => {
|
||||
if (event.target instanceof KmMarksLayer) {
|
||||
this.map = event.target._map;
|
||||
this.marksLayer.addTo(this.map);
|
||||
|
@ -144,7 +149,7 @@ KmMarksLayer.addInitHook(function () {
|
|||
}
|
||||
});
|
||||
|
||||
this.once('remove', (event) => {
|
||||
this.once('remove', event => {
|
||||
if (event.target instanceof KmMarksLayer) {
|
||||
this.marksLayer.removeFrom(this.map);
|
||||
this.endMarker.removeFrom(this.map);
|
||||
|
@ -152,4 +157,4 @@ KmMarksLayer.addInitHook(function () {
|
|||
});
|
||||
});
|
||||
|
||||
export { KmMarksLayer };
|
||||
export { KmMarksLayer };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue