Teach realigning roads by moving nodes, adding midpoints

(closes #2381)
This commit is contained in:
Bryan Housel
2017-04-06 17:09:32 -04:00
parent ef1e7038eb
commit 8fe33d9430
4 changed files with 256 additions and 25 deletions
+240 -21
View File
@@ -1,6 +1,8 @@
import * as d3 from 'd3';
import _ from 'lodash';
import { t } from '../../util/locale';
import { geoSphericalDistance } from '../../geo/index';
import { modeSelect } from '../../modes/select';
import { utilRebind } from '../../util/rebind';
import { icon, pad } from './helper';
@@ -8,13 +10,18 @@ import { icon, pad } from './helper';
export function uiIntroLine(context, reveal) {
var dispatch = d3.dispatch('done'),
timeouts = [],
midpoint = [-85.62975395449628, 41.95787501510204],
start = [-85.6297754121684, 41.95805253325314],
intersection = [-85.62974496187628, 41.95742515554585],
tulipRoadId = null,
flowerRoadId = 'w646',
tulipRoadStart = [-85.6297754121684, 41.95805253325314],
tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204],
tulipRoadIntersection = [-85.62974496187628, 41.95742515554585],
woodRoadId = 'w525',
woodRoadEndId = 'n2862',
woodRoadAddNode = [-85.62390110349587, 41.95397111462291],
woodRoadDragEndpoint = [-85.62383958913921, 41.9546607846611],
woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872],
roadCategory = context.presets().item('category-road'),
residentialPreset = context.presets().item('highway/residential'),
targetId = 'w646',
lineId = null;
residentialPreset = context.presets().item('highway/residential');
var chapter = {
@@ -60,16 +67,16 @@ export function uiIntroLine(context, reveal) {
return chapter.restart();
}
lineId = null;
tulipRoadId = null;
var padding = 70 * Math.pow(2, context.map().zoom() - 18);
var box = pad(start, padding, context);
var box = pad(tulipRoadStart, padding, context);
box.height = box.height + 100;
reveal(box, t('intro.lines.start_line'));
context.map().on('move.intro drawn.intro', function() {
padding = 70 * Math.pow(2, context.map().zoom() - 18);
box = pad(start, padding, context);
box = pad(tulipRoadStart, padding, context);
box.height = box.height + 100;
reveal(box, t('intro.lines.start_line'), { duration: 0 });
});
@@ -92,12 +99,12 @@ export function uiIntroLine(context, reveal) {
return chapter.restart();
}
lineId = context.mode().selectedIDs()[0];
context.map().centerEase(midpoint);
tulipRoadId = context.mode().selectedIDs()[0];
context.map().centerEase(tulipRoadMidpoint);
timeout(function() {
var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
var box = pad(midpoint, padding, context);
var box = pad(tulipRoadMidpoint, padding, context);
box.height = box.height * 2;
reveal(box,
t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') })
@@ -105,7 +112,7 @@ export function uiIntroLine(context, reveal) {
context.map().on('move.intro drawn.intro', function() {
padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
box = pad(midpoint, padding, context);
box = pad(tulipRoadMidpoint, padding, context);
box.height = box.height * 2;
reveal(box,
t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }),
@@ -115,7 +122,7 @@ export function uiIntroLine(context, reveal) {
}, 260); // after easing..
context.history().on('change.intro', function() {
var entity = lineId && context.hasEntity(lineId);
var entity = tulipRoadId && context.hasEntity(tulipRoadId);
if (!entity) return chapter.restart();
if (isLineConnected()) {
@@ -144,13 +151,13 @@ export function uiIntroLine(context, reveal) {
function isLineConnected() {
var entity = lineId && context.hasEntity(lineId);
var entity = tulipRoadId && context.hasEntity(tulipRoadId);
if (!entity) return false;
var drawNodes = context.graph().childNodes(entity);
return _.some(drawNodes, function(node) {
return _.some(context.graph().parentWays(node), function(parent) {
return parent.id === targetId;
return parent.id === flowerRoadId;
});
});
}
@@ -159,7 +166,7 @@ export function uiIntroLine(context, reveal) {
function retryIntersect() {
d3.select(window).on('mousedown.intro', eventCancel, true);
var box = pad(intersection, 80, context);
var box = pad(tulipRoadIntersection, 80, context);
reveal(box,
t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') })
);
@@ -170,10 +177,10 @@ export function uiIntroLine(context, reveal) {
function continueLine() {
if (context.mode().id !== 'draw-line') return chapter.restart();
var entity = lineId && context.hasEntity(lineId);
var entity = tulipRoadId && context.hasEntity(tulipRoadId);
if (!entity) return chapter.restart();
context.map().centerEase(intersection);
context.map().centerEase(tulipRoadIntersection);
reveal('#surface', t('intro.lines.continue_line'));
@@ -287,7 +294,8 @@ export function uiIntroLine(context, reveal) {
function nameRoad() {
context.on('exit.intro', function() {
continueTo(play);
context.history().checkpoint('doneAddRoad');
continueTo(updateLine);
});
timeout(function() {
@@ -303,6 +311,217 @@ export function uiIntroLine(context, reveal) {
}
function updateLine() {
context.history().reset('doneAddRoad');
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return chapter.restart();
}
context.map().zoom(19).centerEase(woodRoadDragMidpoint, 500);
timeout(function() {
var padding = 250 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadDragMidpoint, padding, context);
var advance = function() { continueTo(addNode); };
reveal(box, t('intro.lines.update_line'),
{ buttonText: t('intro.ok'), buttonCallback: advance }
);
context.map().on('move.intro drawn.intro', function() {
var box = pad(woodRoadDragMidpoint, padding, context);
reveal(box, t('intro.lines.update_line'),
{ duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
);
});
}, 550);
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
nextStep();
}
}
function addNode() {
context.history().reset('doneAddRoad');
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return chapter.restart();
}
var padding = 40 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadAddNode, padding, context);
reveal(box, t('intro.lines.add_node'));
context.map().on('move.intro drawn.intro', function() {
var box = pad(woodRoadAddNode, padding, context);
reveal(box, t('intro.lines.add_node'), { duration: 0 });
});
context.history().on('change.intro', function(changed) {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
if (changed.created().length === 1) {
timeout(function() { continueTo(startDragEndpoint); }, 500);
}
});
context.on('enter.intro', function(mode) {
if (mode.id !== 'select') {
continueTo(updateLine);
}
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
context.history().on('change.intro', null);
context.on('enter.intro', null);
nextStep();
}
}
function startDragEndpoint() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var padding = 100 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadDragEndpoint, padding, context);
reveal(box, t('intro.lines.start_drag_endpoint'));
context.map().on('move.intro drawn.intro', function() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var box = pad(woodRoadDragEndpoint, padding, context);
reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 });
var entity = context.entity(woodRoadEndId);
if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 2) {
continueTo(finishDragEndpoint);
}
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
nextStep();
}
}
function finishDragEndpoint() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var padding = 100 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadDragEndpoint, padding, context);
reveal(box, t('intro.lines.finish_drag_endpoint'));
context.map().on('move.intro drawn.intro', function() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var box = pad(woodRoadDragEndpoint, padding, context);
reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 });
var entity = context.entity(woodRoadEndId);
if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 2.5) {
continueTo(startDragEndpoint);
}
});
context.on('enter.intro', function() {
continueTo(startDragMidpoint);
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
context.on('enter.intro', null);
nextStep();
}
}
function startDragMidpoint() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var padding = 80 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadDragMidpoint, padding, context);
reveal(box, t('intro.lines.start_drag_midpoint'));
context.map().on('move.intro drawn.intro', function() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var box = pad(woodRoadDragMidpoint, padding, context);
reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 });
});
context.history().on('change.intro', function(changed) {
if (changed.created().length === 1) {
continueTo(continueDragMidpoint);
}
});
context.on('enter.intro', function(mode) {
if (mode.id !== 'select') {
// keep Wood Road selected so midpoint triangles are drawn..
context.enter(modeSelect(context, [woodRoadId]));
}
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
context.history().on('change.intro', null);
context.on('enter.intro', null);
nextStep();
}
}
function continueDragMidpoint() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var padding = 100 * Math.pow(2, context.map().zoom() - 19);
var box = pad(woodRoadDragEndpoint, padding, context);
box.height += 400;
var advance = function() { continueTo(play); };
reveal(box, t('intro.lines.continue_drag_midpoint'),
{ buttonText: t('intro.ok'), buttonCallback: advance }
);
context.map().on('move.intro drawn.intro', function() {
if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
return continueTo(updateLine);
}
var box = pad(woodRoadDragEndpoint, padding, context);
box.height += 400;
reveal(box, t('intro.lines.continue_drag_midpoint'),
{ duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
);
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
nextStep();
}
}
function play() {
dispatch.call('done');
reveal('.intro-nav-wrap .chapter-building',
@@ -316,7 +535,7 @@ export function uiIntroLine(context, reveal) {
chapter.enter = function() {
context.history().reset('initial');
context.map().zoom(18.5).centerEase(start);
context.map().zoom(18.5).centerEase(tulipRoadStart);
addLine();
};
+2 -2
View File
@@ -6,8 +6,9 @@ import { icon, pointBox } from './helper';
export function uiIntroNavigation(context, reveal) {
var dispatch = d3.dispatch('done'),
timeouts = [],
hallId = 'n2061',
timeouts = [];
springSt = [-85.63585099140167, 41.942506848938926];
var chapter = {
@@ -174,7 +175,6 @@ export function uiIntroNavigation(context, reveal) {
function selectedStreet() {
var springSt = [-85.63585099140167, 41.942506848938926];
context.map().centerEase(springSt);
timeout(function() {