-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Snap To Rail #1027
base: mtc-deploy
Are you sure you want to change the base?
Snap To Rail #1027
Changes from all commits
23f5fa3
b809f44
356c46e
d69c421
ddb4352
69187fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// @flow | ||
|
||
import toLower from 'lodash/toLower' | ||
import upperFirst from 'lodash/upperFirst' | ||
|
||
export default function toSentenceCase (s: string): string { | ||
return upperFirst(toLower(s)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -220,9 +220,10 @@ export function addStopAtInterval (latlng: LatLng, activePattern: Pattern, contr | |
} | ||
|
||
export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?number) { | ||
// eslint-disable-next-line complexity | ||
return async function (dispatch: dispatchFn, getState: getStateFn) { | ||
const {data, editSettings} = getState().editor | ||
const {avoidMotorways, followStreets} = editSettings.present | ||
const {avoidMotorways, snapToOption} = editSettings.present | ||
const {patternStops: currentPatternStops, shapePoints} = pattern | ||
const patternStops = clone(currentPatternStops) | ||
const {controlPoints, patternSegments} = getControlPoints(getState()) | ||
|
@@ -260,7 +261,7 @@ export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?num | |
} else { | ||
dispatch(updatePatternStops(pattern, patternStops)) | ||
// Otherwise, check if a shape ought to be created. Then, save. | ||
if (patternStops.length === 2 && followStreets) { | ||
if (patternStops.length === 2 && snapToOption) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is anticipating |
||
// Create shape between stops the added stop is the second one and | ||
// followStreets is enabled. Otherwise, there is no need to create a | ||
// new shape because it would just be a straight line segment anyways. | ||
|
@@ -272,7 +273,7 @@ export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?num | |
} | ||
const points = [previousStop, stop] | ||
.map((stop, index) => ({lng: stop.stop_lon, lat: stop.stop_lat})) | ||
const patternSegments = await getPolyline(points, true, avoidMotorways) | ||
const patternSegments = await getPolyline(points, true, avoidMotorways, snapToOption) | ||
// Update pattern stops and geometry. | ||
const controlPoints = controlPointsFromSegments(patternStops, patternSegments) | ||
dispatch(updatePatternGeometry({controlPoints, patternSegments})) | ||
|
@@ -335,11 +336,11 @@ export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?num | |
controlPoints: clonedControlPoints, | ||
defaultToStraightLine: false, | ||
editType: 'update', | ||
followStreets, | ||
index: spliceIndex, | ||
newPoint: {lng: stop.stop_lon, lat: stop.stop_lat}, | ||
snapControlPointToNewSegment: true, | ||
patternCoordinates: clonedPatternSegments | ||
patternCoordinates: clonedPatternSegments, | ||
snapToOption | ||
}) | ||
} catch (err) { | ||
console.log(err) | ||
|
@@ -376,11 +377,11 @@ export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?num | |
controlPoints: clonedControlPoints, | ||
defaultToStraightLine: false, | ||
editType: 'update', | ||
followStreets, | ||
index, | ||
newPoint: {lng: stop.stop_lon, lat: stop.stop_lat}, | ||
snapControlPointToNewSegment: true, | ||
patternCoordinates: clonedPatternSegments | ||
patternCoordinates: clonedPatternSegments, | ||
snapToOption | ||
}) | ||
} catch (err) { | ||
console.log(err) | ||
|
@@ -406,12 +407,12 @@ export function addStopToPattern (pattern: Pattern, stop: GtfsStop, index?: ?num | |
*/ | ||
function extendPatternToPoint (pattern, endPoint, newEndPoint, stop = null, splitInterval = 0) { | ||
return async function (dispatch: dispatchFn, getState: getStateFn) { | ||
const {avoidMotorways, followStreets} = getState().editor.editSettings.present | ||
const {avoidMotorways, snapToOption} = getState().editor.editSettings.present | ||
const {controlPoints, patternSegments} = getControlPoints(getState()) | ||
const clonedControlPoints = clone(controlPoints) | ||
let newShape | ||
if (followStreets) { | ||
newShape = await getPolyline([endPoint, newEndPoint], false, avoidMotorways) | ||
if (snapToOption) { | ||
newShape = await getPolyline([endPoint, newEndPoint], false, avoidMotorways, snapToOption) | ||
} | ||
if (!newShape) { | ||
// Get single coordinate for straight line if polyline fails or if not | ||
|
@@ -503,16 +504,16 @@ export function removeStopFromPattern (pattern: Pattern, stop: GtfsStop, index: | |
// If pattern has no shape points, don't attempt to refactor pattern shape | ||
console.log('pattern coordinates do not exist') | ||
} else { | ||
const {avoidMotorways, followStreets} = getState().editor.editSettings.present | ||
const {avoidMotorways, snapToOption} = getState().editor.editSettings.present | ||
let result | ||
try { | ||
result = await recalculateShape({ | ||
avoidMotorways, | ||
controlPoints: clonedControlPoints, | ||
editType: 'delete', | ||
index: cpIndex, | ||
followStreets, | ||
patternCoordinates: clonedPatternSegments | ||
patternCoordinates: clonedPatternSegments, | ||
snapToOption | ||
}) | ||
} catch (err) { | ||
console.log(err) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,8 @@ import {Alert, Checkbox, Form, FormControl, ControlLabel} from 'react-bootstrap' | |
import Rcslider from 'rc-slider' | ||
|
||
import {updateEditSetting} from '../../actions/active' | ||
import {CLICK_OPTIONS} from '../../util' | ||
import toSentenceCase from '../../../common/util/to-sentence-case' | ||
import {CLICK_OPTIONS, SNAP_TO_OPTIONS} from '../../util' | ||
import toSentenceCase from '../../../common/util/text' | ||
import type {EditSettingsState} from '../../../types/reducers' | ||
|
||
type Props = { | ||
|
@@ -59,12 +59,11 @@ export default class EditSettings extends Component<Props, State> { | |
const {editSettings, patternSegment, updateEditSetting} = this.props | ||
const { | ||
editGeometry, | ||
followStreets, | ||
onMapClick, | ||
stopInterval | ||
stopInterval, | ||
snapToOption | ||
} = editSettings | ||
const SETTINGS = [ | ||
{type: 'followStreets', label: 'Snap to streets'}, | ||
{type: 'avoidMotorways', label: 'Avoid highways in routing'}, | ||
{type: 'hideStopHandles', label: 'Hide stop handles'}, | ||
{type: 'hideInactiveSegments', label: 'Hide inactive segments'}, | ||
|
@@ -75,6 +74,21 @@ export default class EditSettings extends Component<Props, State> { | |
const noSegmentIsActive = !patternSegment && patternSegment !== 0 | ||
return ( | ||
<div> | ||
<ControlLabel><small>Snap to options</small></ControlLabel> | ||
<FormControl | ||
componentClass='select' | ||
value={snapToOption} | ||
name={'snapToOption'} | ||
onChange={this._onSelectChange}> | ||
{SNAP_TO_OPTIONS.map(v => { | ||
return ( | ||
<option | ||
key={v} | ||
value={v}>{toSentenceCase(v.replace(/_/g, ' '))} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could avoid this by using an enum and then having a map from enum to string There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. with JS you could even have one large object that has both enum value and string! |
||
</option> | ||
) | ||
})} | ||
</FormControl> | ||
{SETTINGS.map((s, i) => ( | ||
<Checkbox | ||
checked={editSettings[s.type]} | ||
|
@@ -83,7 +97,7 @@ export default class EditSettings extends Component<Props, State> { | |
// this state would cause the entire shape to disappear). | ||
disabled={ | ||
(s.type === 'hideInactiveSegments' && noSegmentIsActive) || | ||
(s.type === 'avoidMotorways' && !followStreets) | ||
(s.type === 'avoidMotorways' && snapToOption !== 'STREET') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No magic strings! Let's use enums instead if we stick with |
||
} | ||
name={s.type} | ||
style={{margin: '3px 0'}} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,11 +48,11 @@ export default class EditShapePanel extends Component<Props> { | |
/** | ||
* Construct new pattern geometry from the pattern stop locations. | ||
*/ | ||
async drawPatternFromStops (pattern: Pattern, stopsCoordinates: Array<LatLng>, followStreets: boolean): Promise<any> { | ||
async drawPatternFromStops (pattern: Pattern, stopsCoordinates: Array<LatLng>): Promise<any> { | ||
const {editSettings, saveActiveGtfsEntity, setErrorMessage, updatePatternGeometry} = this.props | ||
let patternSegments = [] | ||
if (followStreets) { | ||
patternSegments = await getPolyline(stopsCoordinates, true, editSettings.present.avoidMotorways) | ||
if (editSettings.present.snapToOption !== 'NONE') { | ||
patternSegments = await getPolyline(stopsCoordinates, true, editSettings.present.avoidMotorways, editSettings.present.snapToOption) | ||
} else { | ||
// Construct straight-line segments using stop coordinates | ||
stopsCoordinates | ||
|
@@ -92,7 +92,7 @@ export default class EditShapePanel extends Component<Props> { | |
} | ||
|
||
_generateShapeFromStops = () => { | ||
const {activePattern, editSettings, stops} = this.props | ||
const {activePattern, stops} = this.props | ||
const stopLocations = stops && activePattern.patternStops && activePattern.patternStops.length | ||
? activePattern.patternStops | ||
.map((s, index) => { | ||
|
@@ -104,7 +104,7 @@ export default class EditShapePanel extends Component<Props> { | |
return {lng: stop.stop_lon, lat: stop.stop_lat} | ||
}) | ||
: [] | ||
this.drawPatternFromStops(activePattern, stopLocations, editSettings.present.followStreets) | ||
this.drawPatternFromStops(activePattern, stopLocations) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uh oh! I'm not sure |
||
} | ||
|
||
_confirmCreateFromStops = () => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,6 @@ export const defaultState = { | |
currentDragId: null, | ||
distanceFromIntersection: 5, | ||
editGeometry: false, | ||
followStreets: true, | ||
hideInactiveSegments: false, | ||
intersectionStep: 2, | ||
onMapClick: CLICK_OPTIONS[0], | ||
|
@@ -29,6 +28,7 @@ export const defaultState = { | |
showStops: true, | ||
showTooltips: true, | ||
hideStopHandles: true, | ||
snapToOption: 'NONE', | ||
stopInterval: 400 | ||
} | ||
|
||
|
@@ -49,7 +49,7 @@ export const reducers = { | |
...defaultState, | ||
// Do not reset follow streets if exiting pattern editing. | ||
// TODO: Are there other edit settings that should not be overridden? | ||
followStreets: state.followStreets | ||
snapToOption: state.snapToOption | ||
} | ||
}, | ||
'SETTING_ACTIVE_GTFS_ENTITY' ( | ||
|
@@ -96,6 +96,11 @@ export const reducers = { | |
action: ActionType<typeof updateEditSetting> | ||
): EditSettingsState { | ||
const {setting, value} = action.payload | ||
return update(state, { [setting]: {$set: value} }) | ||
// RAIL-TODO: make sure followStreet is properly set. | ||
// RAIL-TODO: use in a lot of places, make sure nothing breaks???? | ||
return update(state, { | ||
[setting]: {$set: value}, | ||
followStreets: {$set: value === 'STREET'} | ||
}) | ||
Comment on lines
+99
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes let's definitely leave |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,11 @@ export const CLICK_OPTIONS: Array<string> = [ | |
'ADD_STOPS_AT_INTERVAL', | ||
'ADD_STOPS_AT_INTERSECTIONS' | ||
] | ||
export const SNAP_TO_OPTIONS: Array<string> = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this an array instead of an enum? |
||
'NONE', | ||
'STREET', | ||
'RAIL' | ||
] | ||
export const YEAR_FORMAT: string = 'YYYY-MM-DD' | ||
export const EXCEPTION_EXEMPLARS = { | ||
MONDAY: 0, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we call this
followOption
instead ofsnapToOption
?