mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
basic router
This commit is contained in:
parent
0d8a507620
commit
e477f50283
12 changed files with 215 additions and 15 deletions
25
package-lock.json
generated
25
package-lock.json
generated
|
@ -689,6 +689,16 @@
|
|||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@mapbox/corslite": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/corslite/-/corslite-0.0.7.tgz",
|
||||
"integrity": "sha1-KfW2oYi6lG5RS98LZAHtT74To54="
|
||||
},
|
||||
"@mapbox/polyline": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/polyline/-/polyline-0.2.0.tgz",
|
||||
"integrity": "sha1-biWYB0SqIjMflLZFpULALT/P7pc="
|
||||
},
|
||||
"@mrmlnc/readdir-enhanced": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||
|
@ -7418,6 +7428,16 @@
|
|||
"resolved": "https://registry.npmjs.org/leaflet-editable/-/leaflet-editable-1.1.0.tgz",
|
||||
"integrity": "sha1-93dZekCoGic/KHtIn9D+XM1gyNA="
|
||||
},
|
||||
"leaflet-routing-machine": {
|
||||
"version": "3.2.8",
|
||||
"resolved": "https://registry.npmjs.org/leaflet-routing-machine/-/leaflet-routing-machine-3.2.8.tgz",
|
||||
"integrity": "sha512-cJPN//kMu6J7L7M/apfjx3SEAt7TFSFGj285To4vLTnq4h9uPo5u6Rd8JdIipyBJXED/UvUVG7LlpguQ+G7gqA==",
|
||||
"requires": {
|
||||
"@mapbox/corslite": "0.0.7",
|
||||
"@mapbox/polyline": "^0.2.0",
|
||||
"osrm-text-instructions": "^0.11.5"
|
||||
}
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
|
||||
|
@ -8881,6 +8901,11 @@
|
|||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true
|
||||
},
|
||||
"osrm-text-instructions": {
|
||||
"version": "0.11.5",
|
||||
"resolved": "https://registry.npmjs.org/osrm-text-instructions/-/osrm-text-instructions-0.11.5.tgz",
|
||||
"integrity": "sha512-EKCfIXhJHsYQLcuctymvSVH7ulRXx5sGb2MdZL3NzD6XhRVZRkqwRicd9/QI27A5oXW4ojOEJ81RGay7bO6dbA=="
|
||||
},
|
||||
"output-file-sync": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz",
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"history": "^4.7.2",
|
||||
"leaflet": "^1.3.3",
|
||||
"leaflet-editable": "^1.1.0",
|
||||
"leaflet-routing-machine": "^3.2.8",
|
||||
"react": "^16.3.2",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-hot-loader": "^4.1.1",
|
||||
|
|
3
src/config.js
Normal file
3
src/config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const CONFIG = {
|
||||
OSRM_URL: 'http://vault48.org:5000/route/v1',
|
||||
};
|
|
@ -1,5 +1,6 @@
|
|||
export const MODES = {
|
||||
POLY: 'POLY',
|
||||
STICKERS: 'STICKERS',
|
||||
ROUTER: 'ROUTER',
|
||||
NONE: 'NONE',
|
||||
};
|
||||
|
|
|
@ -30,6 +30,8 @@ export class App extends React.Component {
|
|||
|
||||
startStickerMode = () => this.editor.changeMode(MODES.STICKERS);
|
||||
|
||||
startRouterMode = () => this.editor.changeMode(MODES.ROUTER);
|
||||
|
||||
render() {
|
||||
const { mode } = this.state;
|
||||
|
||||
|
@ -43,6 +45,9 @@ export class App extends React.Component {
|
|||
<button onClick={this.startStickerMode}>
|
||||
{mode === MODES.STICKERS && '-->'}{MODES.STICKERS}
|
||||
</button>
|
||||
<button onClick={this.startRouterMode}>
|
||||
{mode === MODES.ROUTER && '-->'}{MODES.ROUTER}
|
||||
</button>
|
||||
</ControlsScreen>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Map } from '$modules/Map';
|
||||
import { Poly } from "$modules/Poly";
|
||||
import { Poly } from '$modules/Poly';
|
||||
import { MODES } from '$constants/modes';
|
||||
import { Stickers } from '$modules/Stickers';
|
||||
import { Router } from '$modules/Router';
|
||||
|
||||
export class Editor {
|
||||
constructor({
|
||||
|
@ -10,8 +11,12 @@ export class Editor {
|
|||
setMode
|
||||
}) {
|
||||
this.map = new Map({ container });
|
||||
|
||||
const { lockMapClicks, map: { map } } = this;
|
||||
|
||||
this.poly = new Poly({ map: this.map.map });
|
||||
this.stickers = new Stickers({ map: this.map.map });
|
||||
this.stickers = new Stickers({ map, lockMapClicks });
|
||||
this.router = new Router({ map, lockMapClicks });
|
||||
|
||||
this.setMode = setMode;
|
||||
this.mode = mode;
|
||||
|
@ -20,14 +25,20 @@ export class Editor {
|
|||
[MODES.POLY]: {
|
||||
start: this.poly.continue,
|
||||
stop: this.poly.stop,
|
||||
},
|
||||
[MODES.ROUTER]: {
|
||||
start: this.routerSetStart,
|
||||
}
|
||||
};
|
||||
|
||||
this.clickHandlers = {
|
||||
[MODES.STICKERS]: this.stickers.createOnClick
|
||||
[MODES.STICKERS]: this.stickers.createOnClick,
|
||||
[MODES.ROUTER]: this.router.pushWaypointOnClick,
|
||||
};
|
||||
|
||||
this.map.map.addEventListener('mousedown', this.onClick);
|
||||
map.addEventListener('mouseup', this.onClick);
|
||||
map.addEventListener('dragstart', () => lockMapClicks(true));
|
||||
map.addEventListener('dragstop', () => lockMapClicks(false));
|
||||
}
|
||||
|
||||
changeMode = mode => {
|
||||
|
@ -52,6 +63,29 @@ export class Editor {
|
|||
};
|
||||
|
||||
onClick = e => {
|
||||
if (e.originalEvent.which === 3) return; // skip right click
|
||||
if (this.clickHandlers[this.mode]) this.clickHandlers[this.mode](e);
|
||||
};
|
||||
|
||||
lockMapClicks = lock => {
|
||||
if (lock) {
|
||||
this.map.map.removeEventListener('mouseup', this.onClick);
|
||||
this.map.map.addEventListener('mouseup', this.unlockMapClicks);
|
||||
} else {
|
||||
this.map.map.removeEventListener('mouseup', this.unlockMapClicks);
|
||||
this.map.map.addEventListener('mouseup', this.onClick);
|
||||
}
|
||||
};
|
||||
|
||||
unlockMapClicks = () => {
|
||||
this.lockMapClicks(false);
|
||||
};
|
||||
|
||||
routerSetStart = () => {
|
||||
const { latlngs } = this.poly;
|
||||
|
||||
if (!latlngs || !latlngs.length) return;
|
||||
|
||||
this.router.startFrom(latlngs.pop());
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ export class Map {
|
|||
constructor({ container }) {
|
||||
this.map = L.map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
this.tileLayer = L.tileLayer(providers.dgis, {
|
||||
this.tileLayer = L.tileLayer(providers.default, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
|
|
100
src/modules/Router.js
Normal file
100
src/modules/Router.js
Normal file
|
@ -0,0 +1,100 @@
|
|||
import L from 'leaflet';
|
||||
import 'leaflet-routing-machine';
|
||||
import { CONFIG } from '$config';
|
||||
import { DomMarker } from '$utils/DomMarker';
|
||||
|
||||
export class Router {
|
||||
constructor({ map, lockMapClicks }) {
|
||||
const routeLine = r => L.Routing.line(r, {
|
||||
styles: [
|
||||
{ color: 'white', opacity: 0.8, weight: 6 },
|
||||
{ color: '#4597d0', opacity: 1, weight: 4, dashArray: '15,10' }
|
||||
],
|
||||
addWaypoints: true,
|
||||
}).on('linetouched', this.lockPropagations);
|
||||
|
||||
this.router = L.Routing.control({
|
||||
serviceUrl: CONFIG.OSRM_URL,
|
||||
profile: 'bike',
|
||||
fitSelectedRoutes: false,
|
||||
routeLine,
|
||||
altLineOptions: {
|
||||
styles: [{ color: '#4597d0', opacity: 1, weight: 3 }]
|
||||
},
|
||||
show: false,
|
||||
plan: L.Routing.plan([], {
|
||||
createMarker: (i, wp) => L.marker(wp.latLng, {
|
||||
draggable: true,
|
||||
icon: this.createWaypointMarker(),
|
||||
}),
|
||||
routeWhileDragging: true,
|
||||
}),
|
||||
routeWhileDragging: true
|
||||
});
|
||||
// .on('waypointschanged', this.updateWaypointsByEvent);
|
||||
|
||||
this.router.addTo(map);
|
||||
|
||||
this.waypoints = [];
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
|
||||
console.log('router', this.router);
|
||||
// this.router._line.on('mousedown', console.log);
|
||||
console.log('map', map);
|
||||
}
|
||||
//
|
||||
pushWaypointOnClick = ({ latlng: { lat, lng } }) => {
|
||||
const waypoints = this.router.getWaypoints().filter(({ latLng }) => !!latLng);
|
||||
console.log('push', waypoints);
|
||||
this.router.setWaypoints([...waypoints, { lat, lng }]);
|
||||
};
|
||||
//
|
||||
// pushWaypoint = latlng => {
|
||||
// this.waypoints.push(latlng);
|
||||
// this.updateWaypoints();
|
||||
// };
|
||||
//
|
||||
// updateWaypointsByEvent = (e) => {
|
||||
// console.log('upd', e);
|
||||
// // this.waypoints = waypoints.map(({ latlng }) => latlng);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// updateWaypoints = () => {
|
||||
// this.router.setWaypoints(this.waypoints);
|
||||
// };
|
||||
//
|
||||
createWaypointMarker = () => {
|
||||
const element = document.createElement('div');
|
||||
|
||||
element.addEventListener('mousedown', this.lockPropagations);
|
||||
element.addEventListener('mouseup', this.unlockPropagations);
|
||||
|
||||
return new DomMarker({
|
||||
element,
|
||||
className: 'router-waypoint',
|
||||
});
|
||||
};
|
||||
//
|
||||
lockPropagations = () => {
|
||||
console.log('lock');
|
||||
window.addEventListener('mouseup', this.unlockPropagations);
|
||||
this.lockMapClicks(true);
|
||||
};
|
||||
//
|
||||
unlockPropagations = e => {
|
||||
console.log('unlock');
|
||||
if (e && e.preventPropagations) {
|
||||
console.log('stop');
|
||||
e.preventDefault();
|
||||
e.preventPropagations();
|
||||
}
|
||||
|
||||
window.removeEventListener('mouseup', this.unlockPropagations);
|
||||
setTimeout(() => this.lockMapClicks(false), 300);
|
||||
};
|
||||
|
||||
startFrom = latlngs => {
|
||||
this.router.setWaypoints([{ ...latlngs }]);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
import L from 'leaflet';
|
||||
import 'leaflet-editable';
|
||||
|
||||
import { DomMarker } from '$utils/leafletDomMarkers';
|
||||
import { DomMarker } from '$utils/DomMarker';
|
||||
|
||||
export class Sticker {
|
||||
constructor({
|
||||
latlng, deleteSticker, map
|
||||
latlng, deleteSticker, map, lockMapClicks
|
||||
}) {
|
||||
this.angle = 2.2;
|
||||
this.isDragging = false;
|
||||
this.map = map;
|
||||
|
||||
this.deleteSticker = deleteSticker;
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
|
||||
this.element = document.createElement('div');
|
||||
this.stickerImage = document.createElement('div');
|
||||
|
@ -34,14 +35,12 @@ export class Sticker {
|
|||
|
||||
this.sticker = L.marker(latlng, { icon: marker });
|
||||
|
||||
this.stickerImage.addEventListener('mousedown', this.onDragStart);
|
||||
this.stickerImage.addEventListener('mouseup', this.onDragStop);
|
||||
this.stickerImage.addEventListener('click', this.preventPropagations);
|
||||
|
||||
this.element.addEventListener('mousedown', this.preventPropagations);
|
||||
|
||||
this.setAngle(this.angle);
|
||||
|
||||
this.stickerImage.addEventListener('mousedown', this.onDragStart);
|
||||
this.stickerImage.addEventListener('mouseup', this.onDragStop);
|
||||
|
||||
this.element.addEventListener('mouseup', this.preventPropagations);
|
||||
this.stickerDelete.addEventListener('click', this.onDelete);
|
||||
}
|
||||
|
||||
|
@ -55,6 +54,8 @@ export class Sticker {
|
|||
this.isDragging = true;
|
||||
this.sticker.disableEdit();
|
||||
|
||||
this.lockMapClicks(true);
|
||||
|
||||
window.addEventListener('mousemove', this.onDrag);
|
||||
window.addEventListener('mouseup', this.onDragStop);
|
||||
};
|
||||
|
@ -74,6 +75,8 @@ export class Sticker {
|
|||
|
||||
window.removeEventListener('mousemove', this.onDrag);
|
||||
window.removeEventListener('mouseup', this.onDragStop);
|
||||
|
||||
this.lockMapClicks(false);
|
||||
};
|
||||
|
||||
onDrag = e => {
|
||||
|
@ -82,7 +85,6 @@ export class Sticker {
|
|||
};
|
||||
|
||||
estimateAngle = e => {
|
||||
console.log('est');
|
||||
const { x, y } = this.element.getBoundingClientRect();
|
||||
const { pageX, pageY } = e;
|
||||
this.angle = Math.atan2((y - pageY), (x - pageX));
|
||||
|
|
|
@ -2,10 +2,11 @@ import L from 'leaflet';
|
|||
import { Sticker } from '$modules/Sticker';
|
||||
|
||||
export class Stickers {
|
||||
constructor({ map }) {
|
||||
constructor({ map, lockMapClicks }) {
|
||||
this.map = map;
|
||||
this.layer = L.layerGroup();
|
||||
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
this.stickers = [];
|
||||
|
||||
this.layer.addTo(this.map);
|
||||
|
@ -23,6 +24,7 @@ export class Stickers {
|
|||
latlng,
|
||||
deleteSticker: this.deleteStickerByReference,
|
||||
map: this.map,
|
||||
lockMapClicks: this.lockMapClicks,
|
||||
});
|
||||
this.stickers.push(sticker);
|
||||
|
||||
|
|
|
@ -28,6 +28,32 @@ const vertexMixin = css`
|
|||
}
|
||||
`;
|
||||
|
||||
const routerMixin = css`
|
||||
.leaflet-control-container .leaflet-routing-container-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.router-waypoint {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-left: -20px;
|
||||
margin-top: -20px;
|
||||
outline: none;
|
||||
z-index: 10001;
|
||||
|
||||
::after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 0 2px #4597d0;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const stickers = css`
|
||||
.sticker-container {
|
||||
outline: none;
|
||||
|
@ -132,4 +158,5 @@ export const MapScreen = styled.div.attrs({ id: 'map' })`
|
|||
|
||||
${vertexMixin}
|
||||
${stickers}
|
||||
${routerMixin}
|
||||
`;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue