mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
displaying end marker
This commit is contained in:
parent
72c6b99f58
commit
5db6d85e35
3 changed files with 128 additions and 20 deletions
|
@ -2,18 +2,19 @@ import React, { FC, useEffect, memo, useState, useCallback } from 'react';
|
||||||
import { InteractivePoly } from '~/utils/map/InteractivePoly';
|
import { InteractivePoly } from '~/utils/map/InteractivePoly';
|
||||||
import { isMobile } from '~/utils/window';
|
import { isMobile } from '~/utils/window';
|
||||||
import { LatLng } from 'leaflet';
|
import { LatLng } from 'leaflet';
|
||||||
import { selectEditor } from '~/redux/editor/selectors';
|
import { selectEditor, selectEditorMode, selectEditorEditing } from '~/redux/editor/selectors';
|
||||||
import pick from 'ramda/es/pick';
|
import pick from 'ramda/es/pick';
|
||||||
import * as MAP_ACTIONS from '~/redux/map/actions';
|
import * as MAP_ACTIONS from '~/redux/map/actions';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectMap } from '~/redux/map/selectors';
|
import { selectMap, selectMapRoute } from '~/redux/map/selectors';
|
||||||
import { MainMap } from '~/constants/map';
|
import { MainMap } from '~/constants/map';
|
||||||
import { MODES } from '~/constants/modes';
|
import { MODES } from '~/constants/modes';
|
||||||
import * as EDITOR_ACTIONS from '~/redux/editor/actions';
|
import * as EDITOR_ACTIONS from '~/redux/editor/actions';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
editor: pick(['mode', 'editing'], selectEditor(state)),
|
mode: selectEditorMode(state),
|
||||||
map: pick(['route'], selectMap(state)),
|
editing: selectEditorEditing(state),
|
||||||
|
route: selectMapRoute(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
|
@ -25,13 +26,7 @@ const mapDispatchToProps = {
|
||||||
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||||
|
|
||||||
const RouteUnconnected: FC<Props> = memo(
|
const RouteUnconnected: FC<Props> = memo(
|
||||||
({
|
({ route, editing, mode, mapSetRoute, editorSetDistance, editorSetMarkersShown }) => {
|
||||||
map: { route },
|
|
||||||
editor: { editing, mode },
|
|
||||||
mapSetRoute,
|
|
||||||
editorSetDistance,
|
|
||||||
editorSetMarkersShown,
|
|
||||||
}) => {
|
|
||||||
const [layer, setLayer] = useState<InteractivePoly>(null);
|
const [layer, setLayer] = useState<InteractivePoly>(null);
|
||||||
|
|
||||||
const onDistanceChange = useCallback(({ distance }) => editorSetDistance(distance), [
|
const onDistanceChange = useCallback(({ distance }) => editorSetDistance(distance), [
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { FC, useEffect, useCallback, memo } from 'react';
|
import { FC, useEffect, useCallback, memo, useState } from 'react';
|
||||||
import pick from 'ramda/es/pick';
|
|
||||||
import { OsrmRouter } from '~/utils/map/OsrmRouter';
|
import { OsrmRouter } from '~/utils/map/OsrmRouter';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectMap } from '~/redux/map/selectors';
|
import { selectMapRoute } from '~/redux/map/selectors';
|
||||||
import { selectEditorRouter, selectEditorMode } from '~/redux/editor/selectors';
|
import { selectEditorRouter, selectEditorMode } from '~/redux/editor/selectors';
|
||||||
import { MainMap } from '~/constants/map';
|
import { MainMap } from '~/constants/map';
|
||||||
import * as EDITOR_ACTIONS from '~/redux/editor/actions';
|
import * as EDITOR_ACTIONS from '~/redux/editor/actions';
|
||||||
import { MODES } from '~/constants/modes';
|
import { MODES } from '~/constants/modes';
|
||||||
|
import { LatLngLiteral, marker, divIcon } from 'leaflet';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { angleBetweenPoints } from '~/utils/geom';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
map: pick(['route'], selectMap(state)),
|
route: selectMapRoute(state),
|
||||||
router: pick(['waypoints', 'points'], selectEditorRouter(state)),
|
router: selectEditorRouter(state),
|
||||||
mode: selectEditorMode(state),
|
mode: selectEditorMode(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,20 +23,94 @@ const mapDispatchToProps = {
|
||||||
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||||
|
|
||||||
const RouterUnconnected: FC<Props> = memo(
|
const RouterUnconnected: FC<Props> = memo(
|
||||||
({ map: { route }, mode, router: { waypoints }, editorSetRouter }) => {
|
({ route, mode, router: { waypoints }, editorSetRouter }) => {
|
||||||
|
const [distance, setDistance] = useState(0);
|
||||||
|
const [end, setEnd] = useState<LatLngLiteral>(null);
|
||||||
|
const [direction, setDirection] = useState<boolean>(false);
|
||||||
|
|
||||||
const updateWaypoints = useCallback(
|
const updateWaypoints = useCallback(
|
||||||
({ waypoints }) => editorSetRouter({ waypoints: waypoints.filter(wp => !!wp.latLng) }),
|
({ waypoints }) => {
|
||||||
[editorSetRouter]
|
const filtered = waypoints.filter(wp => !!wp.latLng);
|
||||||
|
|
||||||
|
if (filtered.length < 2) {
|
||||||
|
setDistance(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
editorSetRouter({ waypoints: filtered });
|
||||||
|
},
|
||||||
|
[editorSetRouter, setDistance]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateDistance = useCallback(
|
||||||
|
({ routes, waypoints }) => {
|
||||||
|
console.log(routes.length, waypoints.length);
|
||||||
|
if (!routes || !routes.length || waypoints.length < 2) {
|
||||||
|
console.log('hm 1');
|
||||||
|
setDistance(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { summary, coordinates } = routes[0];
|
||||||
|
|
||||||
|
if (coordinates.length <= 1) {
|
||||||
|
console.log('hm 2');
|
||||||
|
setDistance(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalDistance = parseFloat((summary.totalDistance / 1000).toFixed(1)) || 0;
|
||||||
|
const latlng = (coordinates.length && coordinates[coordinates.length - 1]) || null;
|
||||||
|
|
||||||
|
const angle = angleBetweenPoints(
|
||||||
|
MainMap.latLngToContainerPoint(coordinates[coordinates.length - 2]),
|
||||||
|
MainMap.latLngToContainerPoint(coordinates[coordinates.length - 3])
|
||||||
|
);
|
||||||
|
|
||||||
|
setDistance(totalDistance);
|
||||||
|
setEnd(latlng);
|
||||||
|
setDirection(angle > -90 && angle < 90);
|
||||||
|
},
|
||||||
|
[setDistance, setEnd]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
OsrmRouter.on('waypointschanged', updateWaypoints).addTo(MainMap);
|
OsrmRouter.on('waypointschanged', updateWaypoints)
|
||||||
|
.on('routesfound', updateDistance)
|
||||||
|
.addTo(MainMap);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
OsrmRouter.off('waypointschanged', updateWaypoints).setWaypoints([]);
|
OsrmRouter.off('waypointschanged', updateWaypoints).setWaypoints([]);
|
||||||
};
|
};
|
||||||
}, [MainMap, updateWaypoints, mode]);
|
}, [MainMap, updateWaypoints, mode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!distance || !end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = marker(end, {
|
||||||
|
draggable: false,
|
||||||
|
interactive: false,
|
||||||
|
icon: divIcon({
|
||||||
|
html: `
|
||||||
|
<div class="leaflet-km-dist">
|
||||||
|
${parseFloat(distance.toFixed(1))}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
className: classNames('leaflet-km-marker router-end-marker', { right: !direction }),
|
||||||
|
iconSize: [11, 11],
|
||||||
|
iconAnchor: [6, 6],
|
||||||
|
}),
|
||||||
|
zIndexOffset: -100,
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addTo(MainMap);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
item.removeFrom(MainMap);
|
||||||
|
};
|
||||||
|
}, [distance, end, direction]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mode !== MODES.ROUTER) return;
|
if (mode !== MODES.ROUTER) return;
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,43 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.router-end-marker {
|
||||||
|
.leaflet-km-dist {
|
||||||
|
background: @router_line;
|
||||||
|
left: auto;
|
||||||
|
right: -3px;
|
||||||
|
top: -3px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -10;
|
||||||
|
padding: 2px 16px 2px 4px;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: white;
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
.leaflet-km-dist {
|
||||||
|
padding: 2px 4px 2px 16px;
|
||||||
|
left: -3px;
|
||||||
|
right: auto;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
left: 5px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.leaflet-km-marker-2 {
|
.leaflet-km-marker-2 {
|
||||||
.leaflet-km-dist {
|
.leaflet-km-dist {
|
||||||
background: green;
|
background: green;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue