Ask user to redraw the building if the points really are not very square

This commit is contained in:
Bryan Housel
2017-04-14 11:28:52 -04:00
parent 633edf15b8
commit 0256252caf
4 changed files with 93 additions and 10 deletions
+3 -2
View File
@@ -973,7 +973,8 @@ en:
title: "Buildings"
add_building: "OpenStreetMap is the world's largest database of buildings. You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**"
start_building: "Let's add this house to the map by tracing its outline. Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**"
continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details. Finish the building shape by clicking on the starting node. **Continue tracing the building.**"
continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details. Finish the building by pressing return, or clicking again on either the first or last node. **Finish tracing the building.**"
retry_building: "It looks like you had some trouble placing the points at the building corners. Try again!"
choose_category_building: "**Choose {category} from the list**"
choose_preset_house: "There are many different types of buildings, but this one is clearly a house. If you're not sure of the type, it's OK to just pick the generic Building preset. **Choose the {preset} building type**"
close: "**Hit escape or click the {button} button to close the feature editor**"
@@ -983,7 +984,7 @@ en:
done_square: "See how the corners of the building moved into place? Let's learn another useful trick."
add_tank: "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**"
start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**"
continue_tank: "Add a few more points around the edge. The circle will be created outside the points that you draw. Finish the area by clicking on the starting node. **Continue tracing the tank.**"
continue_tank: "Add a few more points around the edge. The circle will be created outside the points that you draw. Finish the area by pressing return, or clicking again on either the first or last node. **Finish tracing the tank.**"
search_tank: "**Search for '{preset}'**"
choose_tank: "**Choose {preset} from the list.**"
rightclick_tank: "**Right-click to select the storage tank you created and show the edit menu.**"
+3 -2
View File
@@ -837,7 +837,8 @@
"title": "Buildings",
"add_building": "OpenStreetMap is the world's largest database of buildings. You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**",
"start_building": "Let's add this house to the map by tracing its outline. Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**",
"continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details. Finish the building shape by clicking on the starting node. **Continue tracing the building.**",
"continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details. Finish the building by pressing return, or clicking again on either the first or last node. **Finish tracing the building.**",
"retry_building": "It looks like you had some trouble placing the points at the building corners. Try again!",
"choose_category_building": "**Choose {category} from the list**",
"choose_preset_house": "There are many different types of buildings, but this one is clearly a house. If you're not sure of the type, it's OK to just pick the generic Building preset. **Choose the {preset} building type**",
"close": "**Hit escape or click the {button} button to close the feature editor**",
@@ -847,7 +848,7 @@
"done_square": "See how the corners of the building moved into place? Let's learn another useful trick.",
"add_tank": "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**",
"start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**",
"continue_tank": "Add a few more points around the edge. The circle will be created outside the points that you draw. Finish the area by clicking on the starting node. **Continue tracing the tank.**",
"continue_tank": "Add a few more points around the edge. The circle will be created outside the points that you draw. Finish the area by pressing return, or clicking again on either the first or last node. **Finish tracing the tank.**",
"search_tank": "**Search for '{preset}'**",
"choose_tank": "**Choose {preset} from the list.**",
"rightclick_tank": "**Right-click to select the storage tank you created and show the edit menu.**",
+38 -6
View File
@@ -1,8 +1,9 @@
import * as d3 from 'd3';
import _ from 'lodash';
import { t } from '../../util/locale';
import { modeBrowse } from '../../modes/browse';
import { utilRebind } from '../../util/rebind';
import { icon, pad, selectMenuItem, transitionTime } from './helper';
import { icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper';
export function uiIntroBuilding(context, reveal) {
@@ -125,12 +126,24 @@ export function uiIntroBuilding(context, reveal) {
});
context.on('enter.intro', function(mode) {
if (mode.id === 'draw-area')
if (mode.id === 'draw-area') {
return;
else if (mode.id === 'select')
return continueTo(chooseCategoryBuilding);
else
} else if (mode.id === 'select') {
var graph = context.graph(),
way = context.entity(context.selectedIDs()[0]),
nodes = graph.childNodes(way),
points = _.uniq(nodes).map(function(n) { return context.projection(n.loc); });
if (isMostlySquare(points)) {
houseId = way.id;
return continueTo(chooseCategoryBuilding);
} else {
return continueTo(retryHouse);
}
} else {
return chapter.restart();
}
});
function continueTo(nextStep) {
@@ -141,6 +154,26 @@ export function uiIntroBuilding(context, reveal) {
}
function retryHouse() {
var onClick = function() { continueTo(addHouse); };
revealHouse(house, t('intro.buildings.retry_building'),
{ buttonText: t('intro.ok'), buttonCallback: onClick }
);
context.map().on('move.intro drawn.intro', function() {
revealHouse(house, t('intro.buildings.retry_building'),
{ duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
);
});
function continueTo(nextStep) {
context.map().on('move.intro drawn.intro', null);
nextStep();
}
}
function chooseCategoryBuilding() {
if (context.mode().id !== 'select') {
return chapter.restart();
@@ -201,7 +234,6 @@ export function uiIntroBuilding(context, reveal) {
return chapter.restart();
}
houseId = context.mode().selectedIDs()[0];
context.history().checkpoint('hasHouse');
context.on('exit.intro', function() {
+49
View File
@@ -96,6 +96,55 @@ export function localize(obj) {
}
// Used to detect squareness.. some duplicataion of code from actionOrthogonalize.
export function isMostlySquare(points) {
// note: uses 15 here instead of the 12 from actionOrthogonalize because
// actionOrthogonalize can actually straighten some larger angles as it iterates
var threshold = 15, // degrees within right or straight
lowerBound = Math.cos((90 - threshold) * Math.PI / 180), // near right
upperBound = Math.cos(threshold * Math.PI / 180), // near straight
mag;
for (var i = 0; i < points.length; i++) {
mag = Math.abs(normalizedDotProduct(i, points));
if (mag > lowerBound && mag < upperBound) {
return false;
}
}
return true;
function normalizedDotProduct(i, points) {
var a = points[(i - 1 + points.length) % points.length],
b = points[i],
c = points[(i + 1) % points.length],
p = subtractPoints(a, b),
q = subtractPoints(c, b);
p = normalizePoint(p);
q = normalizePoint(q);
return p[0] * q[0] + p[1] * q[1];
function subtractPoints(a, b) {
return [a[0] - b[0], a[1] - b[1]];
}
function normalizePoint(point) {
var vector = [0, 0];
var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
if (length !== 0) {
vector[0] = point[0] / length;
vector[1] = point[1] / length;
}
return vector;
}
}
}
export function selectMenuItem(operation) {
var selector = '.edit-menu .edit-menu-item-' + operation +
', .radial-menu .radial-menu-item-' + operation;