km marks initial

This commit is contained in:
muerwre 2019-03-01 12:28:37 +07:00
parent c853d656b8
commit d4c839a422
5 changed files with 186 additions and 34 deletions

View file

@ -33,8 +33,8 @@ export class Component extends Polyline {
this.constraintsStyle = { ...this.constraintsStyle, ...options.constraintsStyle };
this.maxMarkers = options.maxMarkers || this.maxMarkers;
this.kmMarksEnabled = options.kmMarksEnabled || this.kmMarksEnabled;
this.kmMarksStep = options.kmMarksStep || this.kmMarksStep;
// this.kmMarksEnabled = options.kmMarksEnabled || this.kmMarksEnabled;
// this.kmMarksStep = options.kmMarksStep || this.kmMarksStep;
this.constrLine = new Polyline([], this.constraintsStyle);
@ -49,7 +49,7 @@ export class Component extends Polyline {
this.setLatLngs(latlngs);
this.recreateMarkers();
this.recalcDistance();
this.recalcKmMarks();
// this.recalcKmMarks();
this.touchHinter.setLatLngs(latlngs);
this.fire('latlngschange', { latlngs });
};
@ -483,35 +483,35 @@ export class Component extends Polyline {
this.fire('distancechange', { distance: this.distance });
};
//
// recalcKmMarks = () => {
// if (!this.kmMarksEnabled) return;
//
// const latlngs = this.getLatLngs() as LatLngLiteral[];
//
// this.kmMarks = { };
//
// let last_km_mark = 0;
//
// latlngs.reduce((dist, latlng, index) => {
// if (index >= latlngs.length - 1) return;
//
// const next = latlngs[index + 1];
// const sum = dist + distKm(latlng, next);
// const rounded = Math.floor(dist / this.kmMarksStep) * this.kmMarksStep;
//
// if (rounded > last_km_mark) {
// last_km_mark = rounded;
// this.kmMarks[rounded] = latlng;
// }
//
// return sum;
// }, 0);
// };
recalcKmMarks = () => {
if (!this.kmMarksEnabled) return;
const latlngs = this.getLatLngs() as LatLngLiteral[];
this.kmMarks = { };
let last_km_mark = 0;
latlngs.reduce((dist, latlng, index) => {
if (index >= latlngs.length - 1) return;
const next = latlngs[index + 1];
const sum = dist + distKm(latlng, next);
const rounded = Math.floor(dist / this.kmMarksStep) * this.kmMarksStep;
if (rounded > last_km_mark) {
last_km_mark = rounded;
this.kmMarks[rounded] = latlng;
}
return sum;
}, 0);
};
kmMarksEnabled?: InteractivePolylineOptions['kmMarksEnabled'] = true;
kmMarksStep?: InteractivePolylineOptions['kmMarksStep'] = 5;
kmMarks?: { [x: number]: LatLngLiteral };
// kmMarksEnabled?: InteractivePolylineOptions['kmMarksEnabled'] = true;
// kmMarksStep?: InteractivePolylineOptions['kmMarksStep'] = 5;
// kmMarks?: { [x: number]: LatLngLiteral };
// kmMarksLayer?: LayerGroup = new LayerGroup();
markers: Marker[] = [];

127
src/modules/KmMarks.ts Normal file
View file

@ -0,0 +1,127 @@
import { divIcon, LatLngLiteral, LayerGroup, Map, marker, Marker } from "leaflet";
import { arrowClusterIcon, createArrow } from "$utils/arrow";
import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
import { angleBetweenPoints, dist2, distKm, middleCoord } from "$utils/geom";
interface KmMarksOptions {
showMiddleMarkers: boolean,
showEndMarker: boolean,
kmMarksStep: number,
}
class Component extends LayerGroup {
constructor(latlngs?: LatLngLiteral[], options?: KmMarksOptions){
super();
this.options = {
showMiddleMarkers: true,
showEndMarker: true,
kmMarksStep: 5,
...(options || {}),
} as KmMarksOptions;
}
setLatLngs = (latlngs: LatLngLiteral[]): void => {
if (!this.map) return;
this.marksLayer.clearLayers();
if (latlngs.length === 0) return;
if (this.options.showMiddleMarkers) this.drawMiddleMarkers(latlngs);
if (this.options.showEndMarker) this.drawEndMarker(latlngs);
};
drawMiddleMarkers = (latlngs: LatLngLiteral[]) => {
const kmMarks = {};
let last_km_mark = 0;
latlngs.reduce((dist, current, index) => {
if (index >= latlngs.length - 1) return;
const next = latlngs[index + 1];
const diff = distKm(current, next);
const sum = dist + diff;
const rounded = Math.floor(sum / this.options.kmMarksStep) * this.options.kmMarksStep;
const count = Math.floor((rounded - last_km_mark) / this.options.kmMarksStep);
if (rounded > last_km_mark) {
const angle = angleBetweenPoints(
this.map.latLngToContainerPoint(current),
this.map.latLngToContainerPoint(next),
);
console.log(`[${count}] found at ${index}`, dist, sum, rounded);
for (let i = 1; i <= count; i += 1) {
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),
};
kmMarks[step] = { ...coords, angle };
this.marksLayer.addLayer(this.createMiddleMarker(coords, angle, step));
console.log('-->', step, shift);
}
last_km_mark = rounded;
}
return sum;
}, 0);
console.log(kmMarks);
};
createMiddleMarker = (latlng: LatLngLiteral, angle: number, distance: number): Marker => marker(latlng, {
draggable: false,
interactive: false,
icon: divIcon({
html: `
<div class="leaflet-km-dist" style="transform: rotate(${angle}deg);">
${distance}
</div>
`,
className: 'leaflet-km-marker',
iconSize: [11, 11],
iconAnchor: [6, 6]
})
});
drawEndMarker = (latlngs: LatLngLiteral[]): void => {
};
options: KmMarksOptions;
map: Map;
marksLayer: MarkerClusterGroup = new MarkerClusterGroup({
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
zoomToBoundsOnClick: false,
animate: false,
maxClusterRadius: 10,
// iconCreateFunction: arrowClusterIcon,
});
}
Component.addInitHook(function () {
this.once('add', (event) => {
if (event.target instanceof KmMarks) {
this.map = event.target._map;
this.marksLayer.addTo(this.map);
}
});
this.once('remove', (event) => {
if (event.target instanceof KmMarks) {
this.marksLayer.removeFrom(this.map);
}
});
});
export const KmMarks = Component;

View file

@ -5,6 +5,7 @@ import { editor, Editor } from "$modules/Editor";
import { ILatLng } from "$modules/Stickers";
import { InteractivePoly } from "$modules/InteractivePoly";
import { Arrows } from "$modules/Arrows";
import { KmMarks } from "$modules/KmMarks";
interface Props {
map: Map;
@ -28,7 +29,7 @@ export class Poly {
.on('distancechange', this.onDistanceUpdate)
.on('allvertexhide', this.onVertexHide)
.on('allvertexshow', this.onVertexShow)
.on('latlngschange', this.updateArrows);
.on('latlngschange', this.updateMarks)
this.poly.addTo(map);
this.editor = editor;
@ -41,6 +42,7 @@ export class Poly {
this.lockMapClicks = lockMapClicks;
this.arrows = new Arrows({}).addTo(map);
this.kmMarks = new KmMarks().addTo(map);
}
onDistanceUpdate = (event) => {
@ -51,11 +53,12 @@ export class Poly {
onVertexHide = (): void => this.editor.setMarkersShown(false);
onVertexShow = (): void => this.editor.setMarkersShown(true);
updateArrows = event => {
updateMarks = event => {
this.editor.setChanged(true);
const { latlngs } = event;
this.arrows.setLatLngs(latlngs);
this.kmMarks.setLatLngs(latlngs);
};
continue = (): void => {
@ -104,6 +107,7 @@ export class Poly {
arrows;
poly;
kmMarks;
editor: Props['editor'];
map: Props['map'];