mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
typescripted all the modules
This commit is contained in:
parent
098b2ce281
commit
5699a7abb7
9 changed files with 224 additions and 298 deletions
|
@ -1,9 +1,9 @@
|
||||||
import { Map } from '$modules/Map';
|
import { Map } from '$modules/Map';
|
||||||
import { NewPoly } from '$modules/NewPoly';
|
import { Poly } from '$modules/Poly';
|
||||||
import { MODES } from '$constants/modes';
|
import { MODES } from '$constants/modes';
|
||||||
import { Stickers } from '$modules/Stickers';
|
import { Stickers } from '$modules/Stickers';
|
||||||
import { Router } from '$modules/Router';
|
import { Router } from '$modules/Router';
|
||||||
import { DEFAULT_LOGO, LOGOS } from '$constants/logos';
|
import { DEFAULT_LOGO, ILogos, LOGOS } from '$constants/logos';
|
||||||
|
|
||||||
import { getUrlData } from '$utils/history';
|
import { getUrlData } from '$utils/history';
|
||||||
import { store } from '$redux/store';
|
import { store } from '$redux/store';
|
||||||
|
@ -23,9 +23,42 @@ import {
|
||||||
import { DEFAULT_PROVIDER, IProvider, PROVIDERS } from '$constants/providers';
|
import { DEFAULT_PROVIDER, IProvider, PROVIDERS } from '$constants/providers';
|
||||||
import { STICKERS } from '$constants/stickers';
|
import { STICKERS } from '$constants/stickers';
|
||||||
import { IRootState } from "$redux/user/reducer";
|
import { IRootState } from "$redux/user/reducer";
|
||||||
import { DEFAULT_USER } from "$constants/auth";
|
import { DEFAULT_USER, IUser } from "$constants/auth";
|
||||||
|
|
||||||
export class Editor {
|
interface IEditor {
|
||||||
|
map: Map;
|
||||||
|
poly: Poly;
|
||||||
|
stickers: Stickers;
|
||||||
|
router: Router;
|
||||||
|
|
||||||
|
logo: keyof ILogos;
|
||||||
|
owner: string;
|
||||||
|
initialData: {
|
||||||
|
version: number,
|
||||||
|
title: string,
|
||||||
|
owner: string,
|
||||||
|
address: string,
|
||||||
|
path: any,
|
||||||
|
route: any,
|
||||||
|
stickers: any,
|
||||||
|
provider: string,
|
||||||
|
is_public: boolean,
|
||||||
|
};
|
||||||
|
activeSticker: IRootState['activeSticker'];
|
||||||
|
mode: IRootState['mode'];
|
||||||
|
provider: IProvider;
|
||||||
|
switches: {
|
||||||
|
[x: string]: {
|
||||||
|
start?: () => any,
|
||||||
|
stop?: () => any,
|
||||||
|
toggle?: () => any,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
clickHandlers;
|
||||||
|
user: IUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Editor implements IEditor {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.logo = DEFAULT_LOGO;
|
this.logo = DEFAULT_LOGO;
|
||||||
this.owner = null;
|
this.owner = null;
|
||||||
|
@ -40,13 +73,13 @@ export class Editor {
|
||||||
map: { map }
|
map: { map }
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
this.poly = new NewPoly({
|
this.poly = new Poly({
|
||||||
map, routerMoveStart, lockMapClicks, setTotalDist: this.setDistance, triggerOnChange, editor: this,
|
map, routerMoveStart, lockMapClicks, setTotalDist: this.setDistance, triggerOnChange, editor: this,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.stickers = new Stickers({ map, lockMapClicks, triggerOnChange, editor: this });
|
this.stickers = new Stickers({ map, lockMapClicks, triggerOnChange, editor: this });
|
||||||
this.router = new Router({
|
this.router = new Router({
|
||||||
map, lockMapClicks, setRouterPoints: this.setRouterPoints, changeMode, pushPolyPoints
|
map, lockMapClicks, setRouterPoints: this.setRouterPoints, pushPolyPoints
|
||||||
});
|
});
|
||||||
|
|
||||||
this.switches = {
|
this.switches = {
|
||||||
|
@ -93,17 +126,17 @@ export class Editor {
|
||||||
map.addEventListener('dragstop', () => lockMapClicks(false));
|
map.addEventListener('dragstop', () => lockMapClicks(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
map; // todo typecheck
|
map;
|
||||||
poly; // todo typecheck
|
poly;
|
||||||
stickers;
|
stickers;
|
||||||
router;
|
router;
|
||||||
|
|
||||||
logo: string | number = DEFAULT_LOGO;
|
logo = DEFAULT_LOGO;
|
||||||
owner = null;
|
owner = null;
|
||||||
initialData;
|
initialData;
|
||||||
activeSticker: IRootState['activeSticker'];
|
activeSticker;
|
||||||
mode: IRootState['mode'];
|
mode;
|
||||||
provider: IProvider;
|
provider;
|
||||||
switches;
|
switches;
|
||||||
clickHandlers;
|
clickHandlers;
|
||||||
user = DEFAULT_USER;
|
user = DEFAULT_USER;
|
||||||
|
@ -359,6 +392,6 @@ export class Editor {
|
||||||
|
|
||||||
export const editor = new Editor();
|
export const editor = new Editor();
|
||||||
|
|
||||||
declare let window:any;
|
declare let window: any;
|
||||||
|
|
||||||
window.editor = editor;
|
window.editor = editor;
|
||||||
|
|
|
@ -9,7 +9,13 @@ import 'leaflet/dist/leaflet.css';
|
||||||
import { PROVIDER } from '$config/frontend';
|
import { PROVIDER } from '$config/frontend';
|
||||||
import { DEFAULT_PROVIDER, PROVIDERS } from '$constants/providers';
|
import { DEFAULT_PROVIDER, PROVIDERS } from '$constants/providers';
|
||||||
|
|
||||||
export class Map {
|
interface IMap {
|
||||||
|
map: MapInterface;
|
||||||
|
tileLayer: TileLayer;
|
||||||
|
setProvider: (provider: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Map implements IMap {
|
||||||
constructor({ container }) {
|
constructor({ container }) {
|
||||||
this.map = map(container).setView([55.0153275, 82.9071235], 13);
|
this.map = map(container).setView([55.0153275, 82.9071235], 13);
|
||||||
// todo: change coords?
|
// todo: change coords?
|
||||||
|
@ -23,10 +29,10 @@ export class Map {
|
||||||
this.tileLayer.addTo(this.map);
|
this.tileLayer.addTo(this.map);
|
||||||
}
|
}
|
||||||
|
|
||||||
map: MapInterface;
|
map;
|
||||||
tileLayer: TileLayer;
|
tileLayer;
|
||||||
|
|
||||||
setProvider = (provider: string): void => {
|
setProvider = (provider) => {
|
||||||
const { url } = (provider && PROVIDERS[provider] && PROVIDERS[provider]) || PROVIDERS[DEFAULT_PROVIDER];
|
const { url } = (provider && PROVIDERS[provider] && PROVIDERS[provider]) || PROVIDERS[DEFAULT_PROVIDER];
|
||||||
|
|
||||||
this.tileLayer.setUrl(url);
|
this.tileLayer.setUrl(url);
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
import L from 'leaflet';
|
|
||||||
import 'leaflet-geometryutil';
|
|
||||||
import { simplify } from '$utils/simplify';
|
|
||||||
import { findDistance, middleCoord } from '$utils/geom';
|
|
||||||
import { CLIENT } from '$config/frontend';
|
|
||||||
import { MODES } from '$constants/modes';
|
|
||||||
|
|
||||||
const polyStyle = {
|
|
||||||
color: 'url(#activePathGradient)',
|
|
||||||
weight: '6',
|
|
||||||
markerMid: 'url(#arrow)'
|
|
||||||
};
|
|
||||||
// const polyStyle = { color: '#ff3344', weight: '5' };
|
|
||||||
|
|
||||||
export class Poly {
|
|
||||||
constructor({
|
|
||||||
map, routerMoveStart, lockMapClicks, setTotalDist, triggerOnChange, editor,
|
|
||||||
}) {
|
|
||||||
this.poly = L.polyline([], polyStyle);
|
|
||||||
|
|
||||||
this.latlngs = [];
|
|
||||||
this.poly.addTo(map);
|
|
||||||
this.editor = editor;
|
|
||||||
|
|
||||||
this.map = map;
|
|
||||||
|
|
||||||
this.routerMoveStart = routerMoveStart;
|
|
||||||
this.setTotalDist = setTotalDist;
|
|
||||||
this.triggerOnChange = triggerOnChange;
|
|
||||||
this.lockMapClicks = lockMapClicks;
|
|
||||||
this.bindEvents();
|
|
||||||
|
|
||||||
this.arrows = new L.LayerGroup().addTo(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawArrows = () => {
|
|
||||||
this.arrows.clearLayers();
|
|
||||||
const { latlngs } = this;
|
|
||||||
|
|
||||||
if (!latlngs || latlngs.length <= 1) return;
|
|
||||||
|
|
||||||
latlngs.map((latlng, i) => {
|
|
||||||
if (i === 0) return;
|
|
||||||
|
|
||||||
const mid = middleCoord(latlngs[i], latlngs[i - 1]);
|
|
||||||
const dist = findDistance(latlngs[i - 1].lat, latlngs[i - 1].lng, latlngs[i].lat, latlngs[i].lng);
|
|
||||||
|
|
||||||
if (dist <= 1) return;
|
|
||||||
|
|
||||||
const slide = new L.Polyline(
|
|
||||||
[
|
|
||||||
latlngs[i - 1],
|
|
||||||
[mid.lat, mid.lng]
|
|
||||||
],
|
|
||||||
{ color: 'none', weight: CLIENT.STROKE_WIDTH }
|
|
||||||
).addTo(this.arrows);
|
|
||||||
|
|
||||||
slide._path.setAttribute('marker-end', 'url(#long-arrow)');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
updateMarks = () => {
|
|
||||||
const coords = this.poly.toGeoJSON().geometry.coordinates;
|
|
||||||
this.latlngs = (coords && coords.length && coords.map(([lng, lat]) => ({ lng, lat }))) || [];
|
|
||||||
const meters = (this.poly && (L.GeometryUtil.length(this.poly) / 1000)) || 0;
|
|
||||||
const kilometers = (meters && meters.toFixed(1)) || 0;
|
|
||||||
|
|
||||||
this.setTotalDist(kilometers);
|
|
||||||
this.routerMoveStart();
|
|
||||||
|
|
||||||
this.drawArrows();
|
|
||||||
|
|
||||||
if (coords.length > 1) this.triggerOnChange();
|
|
||||||
};
|
|
||||||
|
|
||||||
preventMissClicks = e => {
|
|
||||||
const mode = this.editor.getMode();
|
|
||||||
|
|
||||||
if (mode === MODES.POLY) return;
|
|
||||||
|
|
||||||
e.cancel();
|
|
||||||
|
|
||||||
if (mode === MODES.NONE) this.editor.setMode(MODES.POLY);
|
|
||||||
};
|
|
||||||
|
|
||||||
bindEvents = () => {
|
|
||||||
// Если на карте что-то меняется, пересчитать километражи
|
|
||||||
this.map.editTools.addEventListener('editable:drawing:mouseup', this.updateMarks);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:dragend', this.updateMarks);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:mouseup', this.updateMarks);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:deleted', this.updateMarks);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:new', this.updateMarks);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:click', this.preventMissClicks);
|
|
||||||
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:dragstart', this.lockMap);
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:dragstart', this.clearArrows);
|
|
||||||
|
|
||||||
// После удаления точки - продолжить рисование
|
|
||||||
this.map.editTools.addEventListener('editable:vertex:deleted', this.continueForward);
|
|
||||||
//
|
|
||||||
// map.editTools.addEventListener('editable:vertex:dragend', e => writeReduxData({ e, updatePolyCoords }));
|
|
||||||
// map.editTools.addEventListener('editable:vertex:new', e => writeReduxData({ e, updatePolyCoords }));
|
|
||||||
// map.editTools.addEventListener('editable:vertex:deleted', e => writeReduxData({ e, updatePolyCoords }));
|
|
||||||
|
|
||||||
// Продолжить рисование после удаления точки
|
|
||||||
// map.editTools.addEventListener('editable:vertex:deleted', e => {
|
|
||||||
// poly.editor.continueForward();
|
|
||||||
// updateMarks();
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Добавлять точек в полилинию по щелчку
|
|
||||||
// map.editTools.addEventListener('editable:drawing:click', e => insertVertex({ e, updatePolyCoords }));
|
|
||||||
// map.editTools.addEventListener('editable:drawing:clicked', () => updateMarks({ updatePolyCoords }));
|
|
||||||
|
|
||||||
// Это для точек. При перетаскивании конца указателя тащим точку
|
|
||||||
// map.editTools.addEventListener('editable:vertex:drag', on_vertex_drag);
|
|
||||||
|
|
||||||
// при перетаскивании ручек убирать все отметки километров
|
|
||||||
// map.editTools.addEventListener('editable:vertex:dragstart', clearKmMarks);
|
|
||||||
};
|
|
||||||
|
|
||||||
continue = () => {
|
|
||||||
if (this.latlngs && this.latlngs.length) {
|
|
||||||
this.poly.enableEdit().continueForward();
|
|
||||||
this.poly.editor.reset();
|
|
||||||
} else {
|
|
||||||
this.poly = this.map.editTools.startPolyline();
|
|
||||||
this.poly.setStyle(polyStyle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
stop = () => {
|
|
||||||
if (this.map.editTools) this.map.editTools.stopDrawing();
|
|
||||||
};
|
|
||||||
|
|
||||||
continueForward = () => {
|
|
||||||
if (!this.poly.editor) return;
|
|
||||||
this.poly.editor.continueForward();
|
|
||||||
};
|
|
||||||
|
|
||||||
lockMap = () => {
|
|
||||||
this.lockMapClicks(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
setPoints = latlngs => {
|
|
||||||
if (!latlngs || latlngs.length <= 1) return;
|
|
||||||
this.poly.setLatLngs(latlngs);
|
|
||||||
|
|
||||||
this.updateMarks();
|
|
||||||
};
|
|
||||||
|
|
||||||
pushPoints = latlngs => {
|
|
||||||
const { map } = this;
|
|
||||||
const simplified = simplify({ map, latlngs });
|
|
||||||
const summary = [
|
|
||||||
...this.poly.getLatLngs(),
|
|
||||||
...simplified,
|
|
||||||
];
|
|
||||||
|
|
||||||
this.poly.setLatLngs(summary);
|
|
||||||
this.poly.enableEdit();
|
|
||||||
this.poly.editor.reset();
|
|
||||||
this.updateMarks();
|
|
||||||
};
|
|
||||||
|
|
||||||
clearAll = () => {
|
|
||||||
this.poly.setLatLngs([]);
|
|
||||||
// this.poly.disableEdit();
|
|
||||||
|
|
||||||
this.updateMarks();
|
|
||||||
};
|
|
||||||
|
|
||||||
clearArrows = () => this.arrows.clearLayers();
|
|
||||||
|
|
||||||
dumpData = () => this.latlngs;
|
|
||||||
|
|
||||||
get isEmpty() {
|
|
||||||
return (!this.latlngs || Object.values(this.latlngs).length <= 0);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
import L from 'leaflet';
|
import L, { Map, LayerGroup, Polyline } from 'leaflet';
|
||||||
import 'leaflet-geometryutil';
|
import 'leaflet-geometryutil';
|
||||||
import '$utils/EditablePolyline';
|
import { EditablePolyline } from '$utils/EditablePolyline';
|
||||||
import { simplify } from '$utils/simplify';
|
import { simplify } from '$utils/simplify';
|
||||||
import { findDistance, middleCoord } from '$utils/geom';
|
import { findDistance, middleCoord } from '$utils/geom';
|
||||||
import { CLIENT } from '$config/frontend';
|
import { CLIENT } from '$config/frontend';
|
||||||
import { MODES } from '$constants/modes';
|
import { MODES } from '$constants/modes';
|
||||||
|
import { Editor } from "$modules/Editor";
|
||||||
|
|
||||||
const polyStyle = {
|
const polyStyle = {
|
||||||
color: 'url(#activePathGradient)',
|
color: 'url(#activePathGradient)',
|
||||||
|
@ -12,13 +13,24 @@ const polyStyle = {
|
||||||
markerMid: 'url(#arrow)'
|
markerMid: 'url(#arrow)'
|
||||||
};
|
};
|
||||||
|
|
||||||
export class NewPoly {
|
interface IPoly {
|
||||||
|
poly: EditablePolyline;
|
||||||
|
editor: Editor;
|
||||||
|
map: Map;
|
||||||
|
routerMoveStart: () => void;
|
||||||
|
setTotalDist: (dist: number) => void;
|
||||||
|
triggerOnChange: () => void;
|
||||||
|
lockMapClicks: (status: boolean) => void;
|
||||||
|
arrows: LayerGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Poly implements IPoly {
|
||||||
constructor({
|
constructor({
|
||||||
map, routerMoveStart, lockMapClicks, setTotalDist, triggerOnChange, editor,
|
map, routerMoveStart, lockMapClicks, setTotalDist, triggerOnChange, editor,
|
||||||
}) {
|
}) {
|
||||||
const coordinates = [];
|
const coordinates = [];
|
||||||
|
|
||||||
this.poly = L.Polyline.PolylineEditor(coordinates, {
|
this.poly = new EditablePolyline(coordinates, {
|
||||||
...polyStyle,
|
...polyStyle,
|
||||||
maxMarkers: 100,
|
maxMarkers: 100,
|
||||||
|
|
||||||
|
@ -42,9 +54,8 @@ export class NewPoly {
|
||||||
this.setTotalDist = setTotalDist;
|
this.setTotalDist = setTotalDist;
|
||||||
this.triggerOnChange = triggerOnChange;
|
this.triggerOnChange = triggerOnChange;
|
||||||
this.lockMapClicks = lockMapClicks;
|
this.lockMapClicks = lockMapClicks;
|
||||||
// this.bindEvents();
|
|
||||||
|
|
||||||
this.arrows = new L.LayerGroup().addTo(map);
|
this.arrows.addTo(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
setModeOnDrawing = () => {
|
setModeOnDrawing = () => {
|
||||||
|
@ -52,45 +63,46 @@ export class NewPoly {
|
||||||
};
|
};
|
||||||
|
|
||||||
drawArrows = () => {
|
drawArrows = () => {
|
||||||
this.arrows.clearLayers();
|
// todo: fix this
|
||||||
const { latlngs } = this;
|
// this.arrows.clearLayers();
|
||||||
|
// const { latlngs } = this;
|
||||||
if (!latlngs || latlngs.length <= 1) return;
|
//
|
||||||
|
// if (!latlngs || latlngs.length <= 1) return;
|
||||||
latlngs.forEach((latlng, i) => {
|
//
|
||||||
if (i === 0) return;
|
// latlngs.forEach((latlng, i) => {
|
||||||
|
// if (i === 0) return;
|
||||||
const mid = middleCoord(latlngs[i], latlngs[i - 1]);
|
//
|
||||||
const dist = findDistance(latlngs[i - 1].lat, latlngs[i - 1].lng, latlngs[i].lat, latlngs[i].lng);
|
// const mid = middleCoord(latlngs[i], latlngs[i - 1]);
|
||||||
|
// const dist = findDistance(latlngs[i - 1].lat, latlngs[i - 1].lng, latlngs[i].lat, latlngs[i].lng);
|
||||||
if (dist <= 1) return;
|
//
|
||||||
|
// if (dist <= 1) return;
|
||||||
const slide = new L.Polyline(
|
//
|
||||||
[
|
// const slide = new Polyline(
|
||||||
latlngs[i - 1],
|
// [
|
||||||
[mid.lat, mid.lng]
|
// latlngs[i - 1],
|
||||||
],
|
// [mid.lat, mid.lng]
|
||||||
{ color: 'none', weight: CLIENT.STROKE_WIDTH }
|
// ],
|
||||||
).addTo(this.arrows);
|
// { color: 'none', weight: CLIENT.STROKE_WIDTH }
|
||||||
|
// ).addTo(this.arrows);
|
||||||
slide._path.setAttribute('marker-end', 'url(#long-arrow)');
|
//
|
||||||
});
|
// // todo: uncomment and fix this:
|
||||||
|
// // slide._path.setAttribute('marker-end', 'url(#long-arrow)');
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
updateMarks = () => {
|
updateMarks = () => {
|
||||||
// return;
|
// todo: fix this
|
||||||
const coords = this.poly.toGeoJSON().geometry.coordinates;
|
// const coords = this.poly.toGeoJSON().geometry.coordinates;
|
||||||
|
//
|
||||||
// this.latlngs = (coords && coords.length && coords.map(([lng, lat]) => ({ lng, lat }))) || [];
|
// const meters = (this.poly && (L.GeometryUtil.length(this.poly) / 1000)) || 0;
|
||||||
const meters = (this.poly && (L.GeometryUtil.length(this.poly) / 1000)) || 0;
|
// const kilometers = (meters && meters.toFixed(1)) || 0;
|
||||||
const kilometers = (meters && meters.toFixed(1)) || 0;
|
//
|
||||||
|
// this.setTotalDist(kilometers);
|
||||||
this.setTotalDist(kilometers);
|
// this.routerMoveStart();
|
||||||
this.routerMoveStart();
|
//
|
||||||
|
// this.drawArrows(); // <-- uncomment
|
||||||
this.drawArrows(); // <-- uncomment
|
//
|
||||||
|
// if (coords.length > 1) this.triggerOnChange();
|
||||||
if (coords.length > 1) this.triggerOnChange();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
preventMissClicks = e => {
|
preventMissClicks = e => {
|
||||||
|
@ -157,4 +169,13 @@ export class NewPoly {
|
||||||
get isEmpty() {
|
get isEmpty() {
|
||||||
return (!this.latlngs || Object.values(this.latlngs).length <= 0);
|
return (!this.latlngs || Object.values(this.latlngs).length <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
poly;
|
||||||
|
editor;
|
||||||
|
map;
|
||||||
|
routerMoveStart;
|
||||||
|
setTotalDist;
|
||||||
|
triggerOnChange;
|
||||||
|
lockMapClicks;
|
||||||
|
arrows = new LayerGroup();
|
||||||
}
|
}
|
|
@ -1,24 +1,38 @@
|
||||||
import L from 'leaflet';
|
import { Marker } from 'leaflet';
|
||||||
import Routing from 'leaflet-routing-machine/src/index';
|
import * as Routing from 'leaflet-routing-machine/src/index';
|
||||||
import { CLIENT } from '$config/frontend';
|
import { CLIENT } from '$config/frontend';
|
||||||
import { DomMarker } from '$utils/DomMarker';
|
import { DomMarker } from '$utils/DomMarker';
|
||||||
|
|
||||||
export class Router {
|
interface ILatLng {
|
||||||
|
lat: number, lng: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IWaypoint {
|
||||||
|
latLng: ILatLng
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRouter {
|
||||||
|
waypoints: Array<IWaypoint>;
|
||||||
|
lockMapClicks: (status: boolean) => void;
|
||||||
|
setRouterPoints: (count: void) => void;
|
||||||
|
pushPolyPoints: (coordinates: Array<{ lat: number, lng: number }>) => void;
|
||||||
|
router: Routing;
|
||||||
|
clearAll: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Router implements IRouter {
|
||||||
constructor({
|
constructor({
|
||||||
map, lockMapClicks, setRouterPoints, pushPolyPoints
|
map, lockMapClicks, setRouterPoints, pushPolyPoints
|
||||||
}) {
|
}) {
|
||||||
this.waypoints = [];
|
this.waypoints = [];
|
||||||
this.lockMapClicks = lockMapClicks;
|
this.lockMapClicks = lockMapClicks;
|
||||||
this.setRouterPoints = setRouterPoints;
|
this.setRouterPoints = setRouterPoints;
|
||||||
// this.changeMode = changeMode;
|
|
||||||
this.pushPolyPoints = pushPolyPoints;
|
this.pushPolyPoints = pushPolyPoints;
|
||||||
|
|
||||||
const routeLine = r => Routing.line(r, {
|
const routeLine = r => Routing.line(r, {
|
||||||
styles: [
|
styles: [
|
||||||
{ color: 'white', opacity: 0.8, weight: 6 },
|
{ color: 'white', opacity: 0.8, weight: 6 },
|
||||||
{
|
{ color: '#4597d0', opacity: 1, weight: 4, dashArray: '15,10' }
|
||||||
color: '#4597d0', opacity: 1, weight: 4, dashArray: '15,10'
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
addWaypoints: true,
|
addWaypoints: true,
|
||||||
}).on('linetouched', this.lockPropagations);
|
}).on('linetouched', this.lockPropagations);
|
||||||
|
@ -33,7 +47,7 @@ export class Router {
|
||||||
},
|
},
|
||||||
show: false,
|
show: false,
|
||||||
plan: Routing.plan([], {
|
plan: Routing.plan([], {
|
||||||
createMarker: (i, wp) => L.marker(wp.latLng, {
|
createMarker: (i, wp) => new Marker(wp.latLng, {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
icon: this.createWaypointMarker(),
|
icon: this.createWaypointMarker(),
|
||||||
}),
|
}),
|
||||||
|
@ -43,18 +57,14 @@ export class Router {
|
||||||
}).on('waypointschanged', this.updateWaypointsCount);
|
}).on('waypointschanged', this.updateWaypointsCount);
|
||||||
|
|
||||||
this.router.addTo(map);
|
this.router.addTo(map);
|
||||||
|
|
||||||
// this.router._line.on('mousedown', console.log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// changeMode = value => store.dispatch(setMode(value));
|
pushWaypointOnClick = ({ latlng: { lat, lng } }: { latlng: ILatLng }): void => {
|
||||||
//
|
|
||||||
pushWaypointOnClick = ({ latlng: { lat, lng } }) => {
|
|
||||||
const waypoints = this.router.getWaypoints().filter(({ latLng }) => !!latLng);
|
const waypoints = this.router.getWaypoints().filter(({ latLng }) => !!latLng);
|
||||||
this.router.setWaypoints([...waypoints, { lat, lng }]);
|
this.router.setWaypoints([...waypoints, { lat, lng }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
createWaypointMarker = () => {
|
createWaypointMarker = (): DomMarker => {
|
||||||
const element = document.createElement('div');
|
const element = document.createElement('div');
|
||||||
|
|
||||||
element.addEventListener('mousedown', this.lockPropagations);
|
element.addEventListener('mousedown', this.lockPropagations);
|
||||||
|
@ -65,13 +75,13 @@ export class Router {
|
||||||
className: 'router-waypoint',
|
className: 'router-waypoint',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
//
|
|
||||||
lockPropagations = () => {
|
lockPropagations = (): void => {
|
||||||
window.addEventListener('mouseup', this.unlockPropagations);
|
window.addEventListener('mouseup', this.unlockPropagations);
|
||||||
this.lockMapClicks(true);
|
this.lockMapClicks(true);
|
||||||
};
|
};
|
||||||
//
|
|
||||||
unlockPropagations = e => {
|
unlockPropagations = (e): void => {
|
||||||
if (e && e.preventPropagations) {
|
if (e && e.preventPropagations) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.preventPropagations();
|
e.preventPropagations();
|
||||||
|
@ -81,7 +91,7 @@ export class Router {
|
||||||
setTimeout(() => this.lockMapClicks(false), 300);
|
setTimeout(() => this.lockMapClicks(false), 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
startFrom = latlngs => {
|
startFrom = (latlngs: ILatLng): void => {
|
||||||
const waypoints = this.router.getWaypoints();
|
const waypoints = this.router.getWaypoints();
|
||||||
|
|
||||||
if (waypoints && waypoints.length) {
|
if (waypoints && waypoints.length) {
|
||||||
|
@ -93,9 +103,9 @@ export class Router {
|
||||||
this.router.setWaypoints([{ ...latlngs }]);
|
this.router.setWaypoints([{ ...latlngs }]);
|
||||||
};
|
};
|
||||||
|
|
||||||
moveStart = latlng => {
|
moveStart = (latlng: ILatLng): void => {
|
||||||
const waypoints = this.router.getWaypoints();
|
const waypoints = this.router.getWaypoints();
|
||||||
const { latLng } = (waypoints[0] || {});
|
const { latLng }: { latLng: ILatLng } = (waypoints[0] || {});
|
||||||
|
|
||||||
if (!latLng || !latlng) return;
|
if (!latLng || !latlng) return;
|
||||||
|
|
||||||
|
@ -111,18 +121,16 @@ export class Router {
|
||||||
this.router.setWaypoints(waypoints);
|
this.router.setWaypoints(waypoints);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateWaypointsCount = () => {
|
updateWaypointsCount = (): void => {
|
||||||
const waypoints = this.router.getWaypoints().filter(({ latLng }) => !!latLng);
|
const waypoints = this.router.getWaypoints().filter(({ latLng }) => !!latLng);
|
||||||
this.setRouterPoints(waypoints.length);
|
this.setRouterPoints(waypoints.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
cancelDrawing = () => {
|
cancelDrawing = (): void => {
|
||||||
this.router.setWaypoints([]);
|
this.router.setWaypoints([]);
|
||||||
// this.router.
|
|
||||||
// this.changeMode(MODES.NONE);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
submitDrawing = () => {
|
submitDrawing = (): void => {
|
||||||
const [route] = this.router._routes;
|
const [route] = this.router._routes;
|
||||||
if (!route) return;
|
if (!route) return;
|
||||||
|
|
||||||
|
@ -136,7 +144,13 @@ export class Router {
|
||||||
// this.router.setWaypoints(waypoints[waypoints.length - 1]);
|
// this.router.setWaypoints(waypoints[waypoints.length - 1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
clearAll = () => {
|
clearAll = (): void => {
|
||||||
this.router.setWaypoints([]);
|
this.router.setWaypoints([]);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
waypoints: Array<IWaypoint> = [];
|
||||||
|
lockMapClicks: (status: boolean) => void;
|
||||||
|
setRouterPoints: (count: void) => void;
|
||||||
|
pushPolyPoints: (coordinates: Array<{ lat: number, lng: number }>) => void;
|
||||||
|
router: Routing;
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
||||||
import { DomMarker } from '$utils/DomMarker';
|
import { DomMarker } from '$utils/DomMarker';
|
||||||
|
|
||||||
import { STICKERS } from '$constants/stickers';
|
import { STICKERS } from '$constants/stickers';
|
||||||
import ReactDOM from 'react-dom';
|
import * as ReactDOM from 'react-dom';
|
||||||
import { StickerDesc } from '$components/StickerDesc';
|
import { StickerDesc } from '$components/StickerDesc';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { getLabelDirection } from '$utils/geom';
|
import { getLabelDirection } from '$utils/geom';
|
||||||
|
@ -14,14 +14,31 @@ const getX = e => (
|
||||||
: { pageX: e.pageX, pageY: e.pageY }
|
: { pageX: e.pageX, pageY: e.pageY }
|
||||||
);
|
);
|
||||||
|
|
||||||
export class Sticker {
|
interface ISticker {
|
||||||
|
element: HTMLDivElement;
|
||||||
|
stickerImage: HTMLDivElement;
|
||||||
|
stickerArrow: HTMLDivElement;
|
||||||
|
marker: Marker;
|
||||||
|
text: string;
|
||||||
|
latlng: { lat: number, lng: number };
|
||||||
|
angle: number;
|
||||||
|
isDragging: boolean;
|
||||||
|
map: Map;
|
||||||
|
sticker: string;
|
||||||
|
set: string;
|
||||||
|
triggerOnChange: () => void;
|
||||||
|
direction: string;
|
||||||
|
deleteSticker: (sticker: this) => void;
|
||||||
|
lockMapClicks: (x: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Sticker implements ISticker {
|
||||||
constructor({
|
constructor({
|
||||||
latlng, deleteSticker, map, lockMapClicks, sticker, set, triggerOnChange, angle = 2.2, text = '',
|
latlng, deleteSticker, map, lockMapClicks, sticker, set, triggerOnChange, angle = 2.2, text = '',
|
||||||
}) {
|
}) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.latlng = latlng;
|
this.latlng = latlng;
|
||||||
this.angle = parseFloat(((angle && (angle % Math.PI)) || 2.2).toFixed(2));
|
this.angle = parseFloat(((angle && (angle % Math.PI)) || 2.2).toFixed(2));
|
||||||
this.isDragging = false;
|
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.sticker = sticker;
|
this.sticker = sticker;
|
||||||
this.set = set;
|
this.set = set;
|
||||||
|
@ -30,8 +47,6 @@ export class Sticker {
|
||||||
this.deleteSticker = deleteSticker;
|
this.deleteSticker = deleteSticker;
|
||||||
this.lockMapClicks = lockMapClicks;
|
this.lockMapClicks = lockMapClicks;
|
||||||
|
|
||||||
this.element = document.createElement('div');
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div
|
<div
|
||||||
|
@ -177,19 +192,19 @@ export class Sticker {
|
||||||
this.element.className = 'sticker-container';
|
this.element.className = 'sticker-container';
|
||||||
};
|
};
|
||||||
|
|
||||||
element: HTMLDivElement;
|
element = document.createElement('div');
|
||||||
stickerImage: HTMLDivElement;
|
stickerImage;
|
||||||
stickerArrow: HTMLDivElement;
|
stickerArrow;
|
||||||
marker: Marker;
|
marker;
|
||||||
text: string;
|
text;
|
||||||
latlng: { lat: number, lng: number };
|
latlng;
|
||||||
angle: number;
|
angle;
|
||||||
isDragging: boolean;
|
isDragging = false;
|
||||||
map: Map;
|
map;
|
||||||
sticker: string;
|
sticker;
|
||||||
set: string;
|
set;
|
||||||
triggerOnChange: () => void;
|
triggerOnChange;
|
||||||
direction: string;
|
direction;
|
||||||
deleteSticker: (sticker: this) => void;
|
deleteSticker;
|
||||||
lockMapClicks: (x: boolean) => void;
|
lockMapClicks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,26 @@
|
||||||
import L, { layerGroup } from 'leaflet';
|
import { LayerGroup, layerGroup, Map } from 'leaflet';
|
||||||
import { Sticker } from '$modules/Sticker';
|
import { Sticker } from '$modules/Sticker';
|
||||||
import 'leaflet.markercluster';
|
import { MarkerClusterGroup } from 'leaflet.markercluster/dist/leaflet.markercluster-src.js';
|
||||||
import { clusterIcon } from '$utils/clusterIcon';
|
import { clusterIcon } from '$utils/clusterIcon';
|
||||||
|
import { Editor } from "$modules/Editor";
|
||||||
|
|
||||||
export class Stickers {
|
interface IStickers {
|
||||||
|
clusterLayer: MarkerClusterGroup;
|
||||||
|
map: Map;
|
||||||
|
stickers: Array<Sticker>;
|
||||||
|
layer: LayerGroup;
|
||||||
|
triggerOnChange: () => void;
|
||||||
|
editor: Editor;
|
||||||
|
lockMapClicks: (x: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Stickers implements IStickers {
|
||||||
constructor({ map, lockMapClicks, triggerOnChange, editor }) {
|
constructor({ map, lockMapClicks, triggerOnChange, editor }) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.layer = layerGroup();
|
|
||||||
this.triggerOnChange = triggerOnChange;
|
this.triggerOnChange = triggerOnChange;
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
|
||||||
this.clusterLayer = L.markerClusterGroup({
|
this.clusterLayer = new MarkerClusterGroup({
|
||||||
spiderfyOnMaxZoom: false,
|
spiderfyOnMaxZoom: false,
|
||||||
showCoverageOnHover: false,
|
showCoverageOnHover: false,
|
||||||
zoomToBoundsOnClick: true,
|
zoomToBoundsOnClick: true,
|
||||||
|
@ -90,4 +100,11 @@ export class Stickers {
|
||||||
};
|
};
|
||||||
|
|
||||||
clusterLayer;
|
clusterLayer;
|
||||||
|
map;
|
||||||
|
stickers;
|
||||||
|
triggerOnChange;
|
||||||
|
editor;
|
||||||
|
lockMapClicks;
|
||||||
|
|
||||||
|
layer = layerGroup();
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import {
|
||||||
import {
|
import {
|
||||||
hideRenderer,
|
hideRenderer,
|
||||||
searchPutRoutes,
|
searchPutRoutes,
|
||||||
searchSetDistance,
|
|
||||||
searchSetLoading,
|
searchSetLoading,
|
||||||
setActiveSticker,
|
setActiveSticker,
|
||||||
setAddress,
|
setAddress,
|
||||||
|
@ -32,7 +31,6 @@ import {
|
||||||
setAddressOrigin,
|
setAddressOrigin,
|
||||||
setProvider,
|
setProvider,
|
||||||
changeProvider,
|
changeProvider,
|
||||||
openMapDialog,
|
|
||||||
setSaveLoading,
|
setSaveLoading,
|
||||||
mapsSetShift, searchChangeDistance,
|
mapsSetShift, searchChangeDistance,
|
||||||
} from '$redux/user/actions';
|
} from '$redux/user/actions';
|
||||||
|
@ -246,7 +244,7 @@ function* setActiveStickerSaga({ activeSticker }: { type: string, activeSticker:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function* setLogoSaga({ logo }: { type: string, logo: keyof ILogos }) {
|
function* setLogoSaga({ logo }: { type: string, logo: string }) {
|
||||||
const { mode } = yield select(getState);
|
const { mode } = yield select(getState);
|
||||||
editor.logo = logo;
|
editor.logo = logo;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import L from 'leaflet';
|
import L from 'leaflet';
|
||||||
|
|
||||||
L.Polyline.polylineEditor = L.Polyline.extend({
|
const EditablePolyline = L.Polyline.polylineEditor = L.Polyline.extend({
|
||||||
_prepareMapIfNeeded() {
|
_prepareMapIfNeeded() {
|
||||||
const that = this;
|
const that = this;
|
||||||
that._changed = false;
|
that._changed = false;
|
||||||
|
@ -14,7 +14,7 @@ L.Polyline.polylineEditor = L.Polyline.extend({
|
||||||
this._map._editablePolylinesEnabled = true;
|
this._map._editablePolylinesEnabled = true;
|
||||||
|
|
||||||
// Click anywhere on map to add a new point-polyline:
|
// Click anywhere on map to add a new point-polyline:
|
||||||
if (this._options.newPolylines) {
|
if (this._options && this._options.newPolylines) {
|
||||||
that._map.on('dblclick', (event) => {
|
that._map.on('dblclick', (event) => {
|
||||||
// console.log(`click, target=${event.target == that._map} type=${event.type}`);
|
// console.log(`click, target=${event.target == that._map} type=${event.type}`);
|
||||||
if (that._map.isEditablePolylinesBusy()) { return; }
|
if (that._map.isEditablePolylinesBusy()) { return; }
|
||||||
|
@ -778,3 +778,5 @@ L.Polyline.PolylineEditor = (latlngs, options, contexts, polylineNo) => {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export { EditablePolyline };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue