mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
km marks initial
This commit is contained in:
parent
c853d656b8
commit
d4c839a422
5 changed files with 186 additions and 34 deletions
|
@ -57,7 +57,7 @@ class Component extends React.PureComponent<Props, State> {
|
||||||
<span className="desktop-only">
|
<span className="desktop-only">
|
||||||
<Icon icon="icon-cycle" size={32} />
|
<Icon icon="icon-cycle" size={32} />
|
||||||
</span>
|
</span>
|
||||||
<span className="desktop-only">{toHours(estimated)}</span>
|
<div className="desktop-only">{toHours(estimated)}</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
dialogOpened &&
|
dialogOpened &&
|
||||||
|
|
|
@ -33,8 +33,8 @@ export class Component extends Polyline {
|
||||||
|
|
||||||
this.constraintsStyle = { ...this.constraintsStyle, ...options.constraintsStyle };
|
this.constraintsStyle = { ...this.constraintsStyle, ...options.constraintsStyle };
|
||||||
this.maxMarkers = options.maxMarkers || this.maxMarkers;
|
this.maxMarkers = options.maxMarkers || this.maxMarkers;
|
||||||
this.kmMarksEnabled = options.kmMarksEnabled || this.kmMarksEnabled;
|
// this.kmMarksEnabled = options.kmMarksEnabled || this.kmMarksEnabled;
|
||||||
this.kmMarksStep = options.kmMarksStep || this.kmMarksStep;
|
// this.kmMarksStep = options.kmMarksStep || this.kmMarksStep;
|
||||||
|
|
||||||
this.constrLine = new Polyline([], this.constraintsStyle);
|
this.constrLine = new Polyline([], this.constraintsStyle);
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ export class Component extends Polyline {
|
||||||
this.setLatLngs(latlngs);
|
this.setLatLngs(latlngs);
|
||||||
this.recreateMarkers();
|
this.recreateMarkers();
|
||||||
this.recalcDistance();
|
this.recalcDistance();
|
||||||
this.recalcKmMarks();
|
// this.recalcKmMarks();
|
||||||
this.touchHinter.setLatLngs(latlngs);
|
this.touchHinter.setLatLngs(latlngs);
|
||||||
this.fire('latlngschange', { latlngs });
|
this.fire('latlngschange', { latlngs });
|
||||||
};
|
};
|
||||||
|
@ -483,35 +483,35 @@ export class Component extends Polyline {
|
||||||
|
|
||||||
this.fire('distancechange', { distance: this.distance });
|
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 = () => {
|
// kmMarksEnabled?: InteractivePolylineOptions['kmMarksEnabled'] = true;
|
||||||
if (!this.kmMarksEnabled) return;
|
// kmMarksStep?: InteractivePolylineOptions['kmMarksStep'] = 5;
|
||||||
|
// kmMarks?: { [x: number]: LatLngLiteral };
|
||||||
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 };
|
|
||||||
// kmMarksLayer?: LayerGroup = new LayerGroup();
|
// kmMarksLayer?: LayerGroup = new LayerGroup();
|
||||||
|
|
||||||
markers: Marker[] = [];
|
markers: Marker[] = [];
|
||||||
|
|
127
src/modules/KmMarks.ts
Normal file
127
src/modules/KmMarks.ts
Normal 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;
|
|
@ -5,6 +5,7 @@ import { editor, Editor } from "$modules/Editor";
|
||||||
import { ILatLng } from "$modules/Stickers";
|
import { ILatLng } from "$modules/Stickers";
|
||||||
import { InteractivePoly } from "$modules/InteractivePoly";
|
import { InteractivePoly } from "$modules/InteractivePoly";
|
||||||
import { Arrows } from "$modules/Arrows";
|
import { Arrows } from "$modules/Arrows";
|
||||||
|
import { KmMarks } from "$modules/KmMarks";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
map: Map;
|
map: Map;
|
||||||
|
@ -28,7 +29,7 @@ export class Poly {
|
||||||
.on('distancechange', this.onDistanceUpdate)
|
.on('distancechange', this.onDistanceUpdate)
|
||||||
.on('allvertexhide', this.onVertexHide)
|
.on('allvertexhide', this.onVertexHide)
|
||||||
.on('allvertexshow', this.onVertexShow)
|
.on('allvertexshow', this.onVertexShow)
|
||||||
.on('latlngschange', this.updateArrows);
|
.on('latlngschange', this.updateMarks)
|
||||||
|
|
||||||
this.poly.addTo(map);
|
this.poly.addTo(map);
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
@ -41,6 +42,7 @@ export class Poly {
|
||||||
this.lockMapClicks = lockMapClicks;
|
this.lockMapClicks = lockMapClicks;
|
||||||
|
|
||||||
this.arrows = new Arrows({}).addTo(map);
|
this.arrows = new Arrows({}).addTo(map);
|
||||||
|
this.kmMarks = new KmMarks().addTo(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDistanceUpdate = (event) => {
|
onDistanceUpdate = (event) => {
|
||||||
|
@ -51,11 +53,12 @@ export class Poly {
|
||||||
onVertexHide = (): void => this.editor.setMarkersShown(false);
|
onVertexHide = (): void => this.editor.setMarkersShown(false);
|
||||||
onVertexShow = (): void => this.editor.setMarkersShown(true);
|
onVertexShow = (): void => this.editor.setMarkersShown(true);
|
||||||
|
|
||||||
updateArrows = event => {
|
updateMarks = event => {
|
||||||
this.editor.setChanged(true);
|
this.editor.setChanged(true);
|
||||||
|
|
||||||
const { latlngs } = event;
|
const { latlngs } = event;
|
||||||
this.arrows.setLatLngs(latlngs);
|
this.arrows.setLatLngs(latlngs);
|
||||||
|
this.kmMarks.setLatLngs(latlngs);
|
||||||
};
|
};
|
||||||
|
|
||||||
continue = (): void => {
|
continue = (): void => {
|
||||||
|
@ -104,6 +107,7 @@ export class Poly {
|
||||||
|
|
||||||
arrows;
|
arrows;
|
||||||
poly;
|
poly;
|
||||||
|
kmMarks;
|
||||||
|
|
||||||
editor: Props['editor'];
|
editor: Props['editor'];
|
||||||
map: Props['map'];
|
map: Props['map'];
|
||||||
|
|
|
@ -99,6 +99,27 @@
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.leaflet-km-marker {
|
||||||
|
position: relative;
|
||||||
|
background: green;
|
||||||
|
|
||||||
|
.leaflet-km-dist {
|
||||||
|
background: blue;
|
||||||
|
color: white;
|
||||||
|
border-radius: 11px;
|
||||||
|
font-size: 9px;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 20px;
|
||||||
|
height: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
top: -5px;
|
||||||
|
left: -5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.touch-hinter-poly {
|
.touch-hinter-poly {
|
||||||
stroke: rgba(255, 50, 0, 0.1);
|
stroke: rgba(255, 50, 0, 0.1);
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue