1+ import ll from '@conveyal/lonlat'
2+ import uniqueId from 'lodash.uniqueid'
13import shp from 'shpjs'
4+ import lineDistance from 'turf-line-distance'
25import lineSlice from 'turf-line-slice'
36import point from 'turf-point'
4- import lineDistance from 'turf-line-distance'
5- import ll from '@conveyal/lonlat'
67
78import { updateActiveGtfsEntity , saveActiveGtfsEntity } from '../active'
8- import { getControlPointSnap , recalculatePatternCoordinates , newControlPoint } from '../../util/map '
9+ import { setErrorMessage } from '../../../manager/actions/status '
910import { polyline as getPolyline } from '../../../scenario-editor/utils/valhalla'
10-
11- export function updateMapSetting ( props ) {
12- return {
13- type : 'UPDATE_MAP_SETTING' ,
14- props
15- }
16- }
11+ import { recalculateShape , newControlPoint } from '../../util/map'
1712
1813export function addControlPoint ( controlPoint , index ) {
1914 return {
@@ -23,48 +18,6 @@ export function addControlPoint (controlPoint, index) {
2318 }
2419}
2520
26- export function handleControlPointDragEnd ( index , controlPoint , evt , pattern ) {
27- return function ( dispatch , getState ) {
28- const coordinates = getState ( ) . editor . editSettings . patternCoordinates
29- const controlPointGeoJson = evt . target . toGeoJSON ( )
30- const { snap, distTraveled } = getControlPointSnap ( controlPointGeoJson , coordinates )
31- dispatch ( updateActiveGtfsEntity ( pattern , 'trippattern' , { shape : { type : 'LineString' , coordinates} } ) )
32- dispatch ( updateControlPoint ( index , snap , distTraveled ) )
33- }
34- }
35-
36- export function handleControlPointDrag ( controlPoints , index , latlng , patternShape ) {
37- return function ( dispatch , getState ) {
38- const { followStreets} = getState ( ) . editor . editSettings
39- recalculatePatternCoordinates (
40- controlPoints ,
41- 'update' ,
42- index ,
43- followStreets ,
44- latlng ,
45- patternShape ,
46- false
47- )
48- . then ( coords => {
49- if ( coords ) {
50- dispatch ( updatePatternCoordinates ( coords ) )
51- // const coord = ll.toCoordinates(latlng)
52- // const cpPoint = point(coord)
53- // const { snap, distTraveled } = getControlPointSnap(cpPoint, coords)
54- // dispatch(updateControlPoint(index, snap, distTraveled, false))
55- }
56- } )
57- }
58- }
59-
60- export function removingControlPoint ( pattern , index ) {
61- return {
62- type : 'REMOVE_CONTROL_POINT' ,
63- pattern,
64- index
65- }
66- }
67-
6821export function constructControlPoint ( pattern , latlng , controlPoints ) {
6922 return function ( dispatch , getState ) {
7023 // slice line
@@ -91,50 +44,10 @@ export function constructControlPoint (pattern, latlng, controlPoints) {
9144 }
9245}
9346
94- export function updatePatternCoordinates ( coordinates ) {
95- return {
96- type : 'UPDATE_PATTERN_COORDINATES' ,
97- coordinates
98- }
99- }
100-
101- export function removeControlPoint ( controlPoints , index , pattern ) {
102- return async function ( dispatch , getState ) {
103- const { followStreets} = getState ( ) . editor . editSettings
104- const coordinates = await recalculatePatternCoordinates (
105- controlPoints ,
106- 'delete' ,
107- index ,
108- followStreets ,
109- null ,
110- pattern . shape
111- )
112- // update pattern
113- dispatch (
114- updateActiveGtfsEntity ( pattern , 'trippattern' , {
115- shape : { type : 'LineString' , coordinates}
116- } )
117- )
118- // remove controlPoint
119- dispatch ( removingControlPoint ( pattern , index ) )
120- }
121- }
122-
123- export function updateControlPoint ( index , point , distance , hardUpdate = true ) {
124- return {
125- type : 'UPDATE_CONTROL_POINT' ,
126- index,
127- point,
128- distance,
129- hardUpdate
130- }
131- }
132-
133- function receivedRoutesShapefile ( feedSource , geojson ) {
47+ function controlPointDragOrEnd ( dragId ) {
13448 return {
135- type : 'RECEIVED_ROUTES_SHAPEFILE' ,
136- feedSource,
137- geojson
49+ type : 'CONTROL_POINT_DRAG_START_OR_END' ,
50+ dragId
13851 }
13952}
14053
@@ -171,3 +84,137 @@ export function extendPatternToPoint (pattern, endPoint, newEndPoint) {
17184 return shape
17285 }
17386}
87+
88+ /**
89+ * Calculate a new shape according to newly dragged position of control point
90+ *
91+ * @param {ControlPoint[] } controlPoints
92+ * @param {Number } index Index of the control point being dragged
93+ * @param {Position } latlng Position of drag point
94+ * @param {Object } patternShape
95+ */
96+ export function handleControlPointDrag (
97+ controlPoints ,
98+ index ,
99+ latlng ,
100+ patternShape
101+ ) {
102+ return function ( dispatch , getState ) {
103+ const { currentDragId, followStreets} = getState ( ) . editor . editSettings
104+ recalculateShape ( {
105+ controlPoints,
106+ defaultToStraightLine : false ,
107+ dragId : currentDragId ,
108+ editType : 'update' ,
109+ followStreets,
110+ index,
111+ newPoint : latlng ,
112+ patternShape
113+ } ) . then ( result => {
114+ // make sure dragging hasn't already stopped and that coordinates are returned
115+ if (
116+ result . dragId === getState ( ) . editor . editSettings . currentDragId &&
117+ result . coordinates
118+ ) {
119+ dispatch ( updatePatternCoordinates ( result . coordinates ) )
120+ }
121+ } )
122+ }
123+ }
124+
125+ export function handleControlPointDragEnd ( controlPoints , index , latlng , pattern ) {
126+ return function ( dispatch , getState ) {
127+ // proclaim end of dragging
128+ dispatch ( controlPointDragOrEnd ( ) )
129+
130+ // recalculate shape for final position
131+ const { followStreets} = getState ( ) . editor . editSettings
132+ recalculateShape ( {
133+ controlPoints,
134+ defaultToStraightLine : false ,
135+ editType : 'update' ,
136+ index,
137+ followStreets,
138+ newPoint : latlng ,
139+ patternShape : pattern . shape ,
140+ snapControlPointToNewSegment : true
141+ } ) . then ( result => {
142+ if ( ! result . coordinates ) {
143+ dispatch ( setErrorMessage (
144+ 'An error occurred while trying to recalculate the shape. Please try again.'
145+ ) )
146+ } else {
147+ dispatch (
148+ updateActiveGtfsEntity ( pattern , 'trippattern' , {
149+ shape : { type : 'LineString' , coordinates : result . coordinates }
150+ } )
151+ )
152+ dispatch ( updateControlPoints ( result . updatedControlPoints ) )
153+ }
154+ } )
155+ }
156+ }
157+
158+ /**
159+ * Save data to store that dragging is in progress
160+ *
161+ * @param {ControlPoint } controlPoint
162+ * @return {Action }
163+ */
164+ export function handleControlPointDragStart ( controlPoint ) {
165+ return controlPointDragOrEnd ( uniqueId ( controlPoint . id ) )
166+ }
167+
168+ function receivedRoutesShapefile ( feedSource , geojson ) {
169+ return {
170+ type : 'RECEIVED_ROUTES_SHAPEFILE' ,
171+ feedSource,
172+ geojson
173+ }
174+ }
175+
176+ export function removeControlPoint ( controlPoints , index , pattern ) {
177+ return async function ( dispatch , getState ) {
178+ const { followStreets} = getState ( ) . editor . editSettings
179+ const {
180+ coordinates,
181+ updatedControlPoints
182+ } = await recalculateShape ( {
183+ controlPoints,
184+ editType : 'delete' ,
185+ index,
186+ followStreets,
187+ patternShape : pattern . shape
188+ } )
189+ // TODO-CONTROL-POINT-FIX: update distance of other control points
190+ // update pattern
191+ dispatch (
192+ updateActiveGtfsEntity ( pattern , 'trippattern' , {
193+ shape : { type : 'LineString' , coordinates}
194+ } )
195+ )
196+ // update controlPoints
197+ dispatch ( updateControlPoints ( updatedControlPoints ) )
198+ }
199+ }
200+
201+ export function updateControlPoints ( newControlPoints ) {
202+ return {
203+ type : 'UPDATE_CONTROL_POINTS' ,
204+ newControlPoints
205+ }
206+ }
207+
208+ export function updateMapSetting ( props ) {
209+ return {
210+ type : 'UPDATE_MAP_SETTING' ,
211+ props
212+ }
213+ }
214+
215+ export function updatePatternCoordinates ( coordinates ) {
216+ return {
217+ type : 'UPDATE_PATTERN_COORDINATES' ,
218+ coordinates
219+ }
220+ }
0 commit comments