Files
iD/modules/validations/unsquare_way.js
T
2019-04-26 14:56:39 -07:00

95 lines
3.3 KiB
JavaScript

import { t } from '../util/locale';
import { actionOrthogonalize } from '../actions/orthogonalize';
import { geoOrthoCanOrthogonalize } from '../geo';
import { utilDisplayLabel } from '../util';
import { validationIssue, validationIssueFix } from '../core/validation';
export function validationUnsquareWay() {
var type = 'unsquare_way';
// use looser constraints for detection than those for completing the action
var epsilon = 0.01;
var degreeThreshold = 6;
function isBuilding(entity, graph) {
if (entity.type !== 'way' || entity.geometry(graph) !== 'area') return false;
return entity.tags.building && entity.tags.building !== 'no';
}
var validation = function checkMissingRole(entity, context) {
var graph = context.graph();
if (!isBuilding(entity, graph)) return [];
var isClosed = entity.isClosed();
var nodes = context.childNodes(entity).slice(); // shallow copy
if (isClosed) nodes.pop();
// don't flag ways with lots of nodes since they are likely detail-mapped
if (nodes.length > 6) return [];
var osm = context.connection();
var connectedToUnloadedTile = nodes.some(function(node) {
return !osm.isDataLoaded(node.loc);
});
// ignore if not all conncted tiles are downloaded
if (connectedToUnloadedTile) return [];
var hasConnectedSquarableWays = nodes.some(function(node) {
return graph.parentWays(node).some(function(way) {
if (way.id === entity.id) return false;
return isBuilding(way, graph);
});
});
// don't flag connected ways to avoid unresolvable unsquare loops
if (hasConnectedSquarableWays) return [];
var projectedLocs = nodes.map(function(node) {
return context.projection(node.loc);
});
if (!geoOrthoCanOrthogonalize(projectedLocs, isClosed, epsilon, degreeThreshold, true)) return [];
var action = actionOrthogonalize(entity.id, context.projection, undefined, epsilon, degreeThreshold);
action.onCompletion = function() {
context.validator().validate();
};
return new validationIssue({
type: type,
severity: 'warning',
message: t('issues.unsquare_way.message', {
feature: utilDisplayLabel(entity, context)
}),
reference: showReference,
entities: [entity],
fixes: [
new validationIssueFix({
icon: 'iD-operation-orthogonalize',
title: t('issues.fix.square_feature.title'),
autoArgs: [action, t('operations.orthogonalize.annotation.area')],
onClick: function() {
context.perform(action, t('operations.orthogonalize.annotation.area'));
}
})
]
});
function showReference(selection) {
selection.selectAll('.issue-reference')
.data([0])
.enter()
.append('div')
.attr('class', 'issue-reference')
.text(t('issues.unsquare_way.buildings.reference'));
}
};
validation.type = type;
return validation;
}