Skip to content

Commit b2507b0

Browse files
evansirokylandonreed
authored andcommitted
refactor(editor): fixes for deleting the last stop...
…when the last stop is in a pattern with only 2 stops
1 parent 3692864 commit b2507b0

File tree

7 files changed

+234
-86
lines changed

7 files changed

+234
-86
lines changed

lib/editor/actions/map/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function handleControlPointDragEnd (controlPoints, index, latlng, pattern
141141
}).then(result => {
142142
if (!result.coordinates) {
143143
dispatch(setErrorMessage(
144-
'An error occurred while trying to recalculate the shape. Please try again.'
144+
'An error occurred while trying to recalculate the shape after dragging. Please try again.'
145145
))
146146
} else {
147147
dispatch(

lib/editor/actions/map/stopStrategies.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,10 @@ export function removeStopFromPattern (pattern, stop, index, controlPoints) {
249249
return
250250
}
251251
if (!coordinates) {
252-
dispatch(setErrorMessage(
253-
'An error occurred while trying to recalculate the shape. Please try again.'
254-
))
255-
return
252+
shape = null
253+
} else {
254+
shape = {type: 'LineString', coordinates}
256255
}
257-
shape = {type: 'LineString', coordinates}
258256
}
259257
const patternStops = [...pattern.patternStops]
260258
patternStops.splice(index, 1)

lib/editor/reducers/data.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ const data = (state = defaultState, action) => {
167167
case 'UPDATE_ACTIVE_GTFS_ENTITY':
168168
switch (component) {
169169
case 'trippattern':
170-
patternIndex = state.active.entity.tripPatterns.findIndex(p => p.id === action.entity.id)
171170
entity = Object.assign({}, state.active.subEntity)
172171
for (key in action.props) {
173172
entity[key] = action.props[key]

lib/editor/util/__tests__/__snapshots__/map.js.snap

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,59 @@ Object {
394394
"type": "Feature",
395395
},
396396
},
397+
Object {
398+
"defaultDwellTime": 0,
399+
"defaultTravelTime": 120,
400+
"distance": 691.729078104771,
401+
"hidden": true,
402+
"id": "fyz2",
403+
"permanent": true,
404+
"point": Object {
405+
"geometry": Object {
406+
"coordinates": Array [
407+
-77.92252574804179,
408+
42.09235127309673,
409+
],
410+
"type": "Point",
411+
},
412+
"properties": Object {},
413+
"type": "Feature",
414+
},
415+
"shapeDistTraveled": 691.729078104771,
416+
"stopId": "a9c9cd55-ca3f-4ce7-9a93-96f2f4eaf089",
417+
"timepoint": null,
418+
},
419+
],
420+
}
421+
`;
422+
423+
exports[`editor > util > map > recalculateShape > deleting > should delete the last stop when there are control points after the last stop 1`] = `
424+
Object {
425+
"coordinates": null,
426+
"dragId": null,
427+
"updatedControlPoints": Array [
428+
Object {
429+
"defaultDwellTime": 0,
430+
"defaultTravelTime": 0,
431+
"distance": 0,
432+
"hidden": true,
433+
"id": "2zu5",
434+
"permanent": true,
435+
"point": Object {
436+
"geometry": Object {
437+
"coordinates": Array [
438+
-122.00743318,
439+
37.06121322,
440+
],
441+
"type": "Point",
442+
},
443+
"properties": Object {},
444+
"type": "Feature",
445+
},
446+
"shapeDistTraveled": 0,
447+
"stopId": "aad0f374-0f29-4300-ae05-6affbe0f1562",
448+
"timepoint": null,
449+
},
397450
],
398451
}
399452
`;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[{
2+
"distance": 0,
3+
"id": "2zu5",
4+
"permanent": true,
5+
"point": {
6+
"type": "Feature",
7+
"properties": {},
8+
"geometry": {
9+
"type": "Point",
10+
"coordinates": [-122.00743318, 37.06121322]
11+
}
12+
},
13+
"stopId": "aad0f374-0f29-4300-ae05-6affbe0f1562",
14+
"defaultTravelTime": 0,
15+
"defaultDwellTime": 0,
16+
"timepoint": null,
17+
"shapeDistTraveled": 0,
18+
"hidden": true
19+
},
20+
{
21+
"distance": 170.7245980700509,
22+
"id": "25p4",
23+
"permanent": true,
24+
"point": {
25+
"type": "Feature",
26+
"properties": {},
27+
"geometry": {
28+
"type": "Point",
29+
"coordinates": [-122.00872656844231, 37.060454715231224]
30+
}
31+
}
32+
},
33+
{
34+
"distance": 341.4491961401018,
35+
"id": "cy46",
36+
"permanent": true,
37+
"point": {
38+
"type": "Feature",
39+
"properties": {},
40+
"geometry": {
41+
"type": "Point",
42+
"coordinates": [-122.00981702504365, 37.059191439360475]
43+
}
44+
},
45+
"stopId": "ec6a3479-9795-4480-9884-1c25851a163e",
46+
"defaultTravelTime": 0,
47+
"defaultDwellTime": 0,
48+
"timepoint": null,
49+
"shapeDistTraveled": 341.4491961401018,
50+
"hidden": true
51+
},
52+
{
53+
"distance": 358.0806866950734,
54+
"id": "4s05",
55+
"permanent": true,
56+
"point": {
57+
"type": "Feature",
58+
"properties": {},
59+
"geometry": {
60+
"type": "Point",
61+
"coordinates": [-122.009919, 37.059066]
62+
}
63+
}
64+
}
65+
]

lib/editor/util/__tests__/map.js

Lines changed: 84 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,98 +4,107 @@ import nock from 'nock'
44

55
import {recalculateShape} from '../map'
66

7-
const controlPoints = require('./fixtures/test-control-points.json')
7+
const fixtureControlPoints = require('./fixtures/test-control-points.json')
88
const followStreets = true
99
const patternShape = require('./fixtures/test-pattern-shape.json')
1010

1111
describe('editor > util > map >', () => {
1212
describe('recalculateShape >', () => {
13-
function makeTestCase ({editType, index, mapzenResponeFile, newPoint}) {
14-
return async () => {
15-
// setup nock
16-
if (mapzenResponeFile) {
17-
nock('https://valhalla.mapzen.com')
18-
.get(/^\/route\?json.*/)
19-
.reply(200, require(mapzenResponeFile))
20-
}
13+
function makeTestCase ({
14+
controlPoints = fixtureControlPoints,
15+
editType,
16+
index,
17+
mapzenResponeFile,
18+
newPoint,
19+
resultCoordsCanBeNull = false,
20+
title
21+
}) {
22+
return it(
23+
title,
24+
async () => {
25+
// setup nock
26+
if (mapzenResponeFile) {
27+
nock('https://valhalla.mapzen.com')
28+
.get(/^\/route\?json.*/)
29+
.reply(200, require(mapzenResponeFile))
30+
}
2131

22-
const result = await recalculateShape({
23-
controlPoints,
24-
editType,
25-
index,
26-
followStreets,
27-
newPoint,
28-
patternShape
29-
})
32+
const result = await recalculateShape({
33+
controlPoints,
34+
editType,
35+
index,
36+
followStreets,
37+
newPoint,
38+
patternShape
39+
})
3040

31-
expect(result).toMatchSnapshot()
32-
const {coordinates} = result
33-
expect(coordinates.length).toBeGreaterThan(0)
34-
coordinates.forEach(coord => {
35-
expect(coord.length).toBe(2)
36-
expect(Math.abs(coord[0])).toBeLessThanOrEqual(180)
37-
expect(Math.abs(coord[1])).toBeLessThanOrEqual(90)
38-
})
39-
}
41+
expect(result).toMatchSnapshot()
42+
const {coordinates} = result
43+
if (!resultCoordsCanBeNull) {
44+
expect(coordinates.length).toBeGreaterThan(0)
45+
coordinates.forEach(coord => {
46+
expect(coord.length).toBe(2)
47+
expect(Math.abs(coord[0])).toBeLessThanOrEqual(180)
48+
expect(Math.abs(coord[1])).toBeLessThanOrEqual(90)
49+
})
50+
}
51+
}
52+
)
4053
}
4154

4255
describe('updating >', () => {
43-
it(
44-
'should update the first stop',
45-
makeTestCase({
46-
editType: 'update',
47-
index: 0,
48-
mapzenResponeFile: './fixtures/mapzen-response-update-first-stop.json',
49-
newPoint: [-77.92553, 42.08666]
50-
})
51-
)
56+
makeTestCase({
57+
editType: 'update',
58+
index: 0,
59+
mapzenResponeFile: './fixtures/mapzen-response-update-first-stop.json',
60+
newPoint: [-77.92553, 42.08666],
61+
title: 'should update the first stop'
62+
})
5263

53-
it(
54-
'should update the last stop',
55-
makeTestCase({
56-
editType: 'update',
57-
index: 4,
58-
mapzenResponeFile: './fixtures/mapzen-response-update-last-stop.json',
59-
newPoint: [-77.92262, 42.09828]
60-
})
61-
)
64+
makeTestCase({
65+
editType: 'update',
66+
index: 4,
67+
mapzenResponeFile: './fixtures/mapzen-response-update-last-stop.json',
68+
newPoint: [-77.92262, 42.09828],
69+
title: 'should update the last stop'
70+
})
6271

63-
it(
64-
'should update a point in the middle of the control points',
65-
makeTestCase({
66-
editType: 'update',
67-
index: 3,
68-
mapzenResponeFile: './fixtures/mapzen-response-update-middle-control-point.json',
69-
newPoint: [-77.92382, 42.09182]
70-
})
71-
)
72+
makeTestCase({
73+
editType: 'update',
74+
index: 3,
75+
mapzenResponeFile: './fixtures/mapzen-response-update-middle-control-point.json',
76+
newPoint: [-77.92382, 42.09182],
77+
title: 'should update a point in the middle of the control points'
78+
})
7279
})
7380

7481
describe('deleting >', () => {
75-
it(
76-
'should delete the first stop',
77-
makeTestCase({
78-
editType: 'delete',
79-
index: 0
80-
})
81-
)
82+
makeTestCase({
83+
editType: 'delete',
84+
index: 0,
85+
title: 'should delete the first stop'
86+
})
8287

83-
it(
84-
'should delete the last stop',
85-
makeTestCase({
86-
editType: 'delete',
87-
index: 4
88-
})
89-
)
88+
makeTestCase({
89+
editType: 'delete',
90+
index: 4,
91+
title: 'should delete the last stop'
92+
})
9093

91-
it(
92-
'should delete a point in the middle of the control points',
93-
makeTestCase({
94-
editType: 'delete',
95-
index: 3,
96-
mapzenResponeFile: './fixtures/mapzen-response-delete-middle-control-point.json'
97-
})
98-
)
94+
makeTestCase({
95+
controlPoints: require('./fixtures/test-control-points-with-extra-point-at-end.json'),
96+
editType: 'delete',
97+
index: 2,
98+
resultCoordsCanBeNull: true,
99+
title: 'should delete the last stop when there are control points after the last stop'
100+
})
101+
102+
makeTestCase({
103+
editType: 'delete',
104+
index: 3,
105+
mapzenResponeFile: './fixtures/mapzen-response-delete-middle-control-point.json',
106+
title: 'should delete a point in the middle of the control points'
107+
})
99108
})
100109
})
101110
})

lib/editor/util/map.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ export async function recalculateShape ({
193193
* @return {Coordinate[]}
194194
*/
195195
function lineSliceAlongToCoords (startDistance, endDistance) {
196+
if (startDistance === 0 && endDistance === 0) {
197+
return []
198+
}
196199
return lineSliceAlong(
197200
lineString(patternShape.coordinates),
198201
startDistance,
@@ -268,22 +271,43 @@ export async function recalculateShape ({
268271
mToKm(controlPoints[nextToLastIndex].distance)
269272
)),
270273
dragId,
271-
updatedControlPoints: controlPoints.slice(0, nextToLastIndex)
274+
updatedControlPoints: controlPoints.slice(0, nextToLastIndex + 1)
272275
}
273276
} else {
274277
// deleting an in-between control point or stop
275278
if (currentControlPoint.stopId) {
276-
// deleting a stop. Recalculate shape between last 2 stops
279+
// deleting a stop. Recalculate shape between the previous and following stops
277280
let previousStopIdx = index - 1
278281
while (!controlPoints[previousStopIdx].stopId && previousStopIdx > 0) {
279282
previousStopIdx--
280283
}
281284
previousControlPoint = controlPoints[previousStopIdx]
282285

283286
let followingStopIdx = index + 1
284-
while (!controlPoints[followingStopIdx].stopId && followingStopIdx < controlPoints.length - 1) {
285-
followingStopIdx++
287+
let nextStopFound = false
288+
for (; followingStopIdx < controlPoints.length; followingStopIdx++) {
289+
if (controlPoints[followingStopIdx].stopId) {
290+
nextStopFound = true
291+
break
292+
}
293+
}
294+
295+
if (!nextStopFound) {
296+
// there are no more stops after this control point!
297+
// return the coordinates as far as the new last stop
298+
299+
// set coords to null if last stop was deleted
300+
const newCoords = lineSliceAlongToCoords(
301+
0,
302+
mToKm(controlPoints[previousStopIdx].distance)
303+
)
304+
return {
305+
coordinates: newCoords.length > 0 ? ensureValidCoords(newCoords) : null,
306+
dragId,
307+
updatedControlPoints: controlPoints.slice(0, previousStopIdx + 1)
308+
}
286309
}
310+
287311
followingControlPoint = controlPoints[followingStopIdx]
288312
}
289313

0 commit comments

Comments
 (0)