mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-16 22:03:37 +02:00
Merge branch 'master' into quick-translate
This commit is contained in:
+77
-13
@@ -1,51 +1,115 @@
|
||||
{
|
||||
"dataAddressFormats": [
|
||||
{
|
||||
"format": [["housenumber", "street"], ["city", "postcode"]]
|
||||
"format": [
|
||||
["housenumber", "street"],
|
||||
["city", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["gb"],
|
||||
"format": [["housename"], ["housenumber", "street"], ["city", "postcode"]]
|
||||
"format": [
|
||||
["housename"],
|
||||
["housenumber", "street"],
|
||||
["city", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["ie"],
|
||||
"format": [["housename"], ["housenumber", "street"], ["city"], ["postcode"]]
|
||||
"format": [
|
||||
["housename"],
|
||||
["housenumber", "street"],
|
||||
["city"],
|
||||
["postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["ad", "at", "ba", "be", "ch", "cz", "de", "dk", "es", "fi", "gr", "hr", "is", "it", "li", "nl", "no", "pl", "pt", "se", "si", "sk", "sm", "va"],
|
||||
"format": [["street", "housenumber"], ["postcode", "city"]]
|
||||
"countryCodes": [
|
||||
"ad", "at", "ba", "be", "ch", "cz",
|
||||
"de", "dk", "es", "fi", "gr", "hr",
|
||||
"is", "it", "li", "nl", "no", "pl",
|
||||
"pt", "se", "si", "sk", "sm", "va"
|
||||
],
|
||||
"format": [
|
||||
["street", "housenumber"],
|
||||
["postcode", "city"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["fr", "lu", "mo"],
|
||||
"format": [["housenumber", "street"], ["postcode", "city"]]
|
||||
"format": [
|
||||
["housenumber", "street"],
|
||||
["postcode", "city"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["br"],
|
||||
"format": [["street"], ["housenumber", "suburb"], ["city", "postcode"]]
|
||||
"format": [
|
||||
["street"],
|
||||
["housenumber", "suburb"],
|
||||
["city", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["vn"],
|
||||
"format": [["housenumber", "street"], ["subdistrict"], ["district"], ["city"], ["province", "postcode"]]
|
||||
"format": [
|
||||
["housenumber", "street"],
|
||||
["subdistrict"],
|
||||
["district"],
|
||||
["city"],
|
||||
["province", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["us"],
|
||||
"format": [["housenumber", "street"], ["city", "state", "postcode"]]
|
||||
"format": [
|
||||
["housenumber", "street"],
|
||||
["city", "state", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["ca"],
|
||||
"format": [["housenumber", "street"], ["city", "province", "postcode"]]
|
||||
"format": [
|
||||
["housenumber", "street"],
|
||||
["city", "province", "postcode"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["tw"],
|
||||
"format": [["postcode", "city", "district"], ["place", "street"], ["housenumber", "floor"]]
|
||||
"format": [
|
||||
["postcode", "city", "district"],
|
||||
["place", "street"],
|
||||
["housenumber", "floor"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["jp"],
|
||||
"format": [["postcode", "province", "county"], ["city", "suburb", "quarter"], ["neighbourhood", "block_number", "housenumber"]]
|
||||
"format": [
|
||||
["postcode", "province", "county"],
|
||||
["city", "suburb"],
|
||||
["quarter", "neighbourhood"],
|
||||
["block_number", "housenumber"]
|
||||
],
|
||||
"dropdowns": [
|
||||
"postcode", "province", "county",
|
||||
"city", "suburb",
|
||||
"quarter", "neighbourhood",
|
||||
"block_number"
|
||||
],
|
||||
"widths": {
|
||||
"postcode": 0.3, "province": 0.35, "county": 0.35,
|
||||
"city": 0.65, "suburb": 0.35,
|
||||
"quarter": 0.5, "neighbourhood": 0.5,
|
||||
"block_number": 0.5, "housenumber": 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"countryCodes": ["tr"],
|
||||
"format": [["neighbourhood"], ["street", "housenumber"], ["postcode", "district", "city"]]
|
||||
"format": [
|
||||
["neighbourhood"],
|
||||
["street", "housenumber"],
|
||||
["postcode", "district", "city"]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+13
-2
@@ -84,28 +84,39 @@ en:
|
||||
# access=*
|
||||
label: Access
|
||||
address:
|
||||
# 'addr:block_number=*, addr:city=*, addr:conscriptionnumber=*, addr:county=*, addr:country=*, addr:district=*, addr:floor=*, addr:hamlet=*, addr:housename=*, addr:housenumber=*, addr:neighbourhood=*, addr:place=*, addr:postcode=*, addr:province=*, addr:quarter=*, addr:state=*, addr:street=*, addr:subdistrict=*, addr:suburb=*'
|
||||
# 'addr:block_number=*, addr:city=*, addr:block_number=*, addr:conscriptionnumber=*, addr:county=*, addr:country=*, addr:county=*, addr:district=*, addr:floor=*, addr:hamlet=*, addr:housename=*, addr:housenumber=*, addr:neighbourhood=*, addr:place=*, addr:postcode=*, addr:province=*, addr:quarter=*, addr:state=*, addr:street=*, addr:subdistrict=*, addr:suburb=*'
|
||||
label: Address
|
||||
placeholders:
|
||||
block_number: Block number
|
||||
block_number: Block Number
|
||||
block_number!jp: Block No.
|
||||
city: City
|
||||
city!jp: City/Town/Village/Tokyo Special Ward
|
||||
city!vn: City/Town
|
||||
conscriptionnumber: '123'
|
||||
country: Country
|
||||
county: County
|
||||
county!jp: District
|
||||
district: District
|
||||
district!vn: Arrondissement/Town/District
|
||||
floor: Floor
|
||||
hamlet: Hamlet
|
||||
housename: Housename
|
||||
housenumber: '123'
|
||||
housenumber!jp: Building No./Lot No.
|
||||
neighbourhood: Neighbourhood
|
||||
neighbourhood!jp: Chōme/Aza/Koaza
|
||||
place: Place
|
||||
postcode: Postcode
|
||||
province: Province
|
||||
province!jp: Prefecture
|
||||
quarter: Quarter
|
||||
quarter!jp: Ōaza/Machi
|
||||
state: State
|
||||
street: Street
|
||||
subdistrict: Subdistrict
|
||||
subdistrict!vn: Ward/Commune/Townlet
|
||||
suburb: Suburb
|
||||
suburb!jp: Ward
|
||||
admin_level:
|
||||
# admin_level=*
|
||||
label: Admin Level
|
||||
|
||||
@@ -81,9 +81,11 @@
|
||||
"keys": [
|
||||
"addr:block_number",
|
||||
"addr:city",
|
||||
"addr:block_number",
|
||||
"addr:conscriptionnumber",
|
||||
"addr:county",
|
||||
"addr:country",
|
||||
"addr:county",
|
||||
"addr:district",
|
||||
"addr:floor",
|
||||
"addr:hamlet",
|
||||
@@ -107,25 +109,36 @@
|
||||
"label": "Address",
|
||||
"strings": {
|
||||
"placeholders": {
|
||||
"block_number": "Block number",
|
||||
"block_number": "Block Number",
|
||||
"block_number!jp": "Block No.",
|
||||
"city": "City",
|
||||
"city!jp": "City/Town/Village/Tokyo Special Ward",
|
||||
"city!vn": "City/Town",
|
||||
"conscriptionnumber": "123",
|
||||
"county": "County",
|
||||
"country": "Country",
|
||||
"county": "County",
|
||||
"county!jp": "District",
|
||||
"district": "District",
|
||||
"district!vn": "Arrondissement/Town/District",
|
||||
"floor": "Floor",
|
||||
"hamlet": "Hamlet",
|
||||
"housename": "Housename",
|
||||
"housenumber": "123",
|
||||
"housenumber!jp": "Building No./Lot No.",
|
||||
"neighbourhood": "Neighbourhood",
|
||||
"neighbourhood!jp": "Chōme/Aza/Koaza",
|
||||
"place": "Place",
|
||||
"postcode": "Postcode",
|
||||
"province": "Province",
|
||||
"province!jp": "Prefecture",
|
||||
"quarter": "Quarter",
|
||||
"quarter!jp": "Ōaza/Machi",
|
||||
"state": "State",
|
||||
"street": "Street",
|
||||
"subdistrict": "Subdistrict",
|
||||
"suburb": "Suburb"
|
||||
"subdistrict!vn": "Ward/Commune/Townlet",
|
||||
"suburb": "Suburb",
|
||||
"suburb!jp": "Ward"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
"keys": [
|
||||
"addr:block_number",
|
||||
"addr:city",
|
||||
"addr:block_number",
|
||||
"addr:conscriptionnumber",
|
||||
"addr:county",
|
||||
"addr:country",
|
||||
"addr:county",
|
||||
"addr:district",
|
||||
"addr:floor",
|
||||
"addr:hamlet",
|
||||
@@ -27,25 +29,36 @@
|
||||
"label": "Address",
|
||||
"strings": {
|
||||
"placeholders": {
|
||||
"block_number": "Block number",
|
||||
"block_number": "Block Number",
|
||||
"block_number!jp": "Block No.",
|
||||
"city": "City",
|
||||
"city!jp": "City/Town/Village/Tokyo Special Ward",
|
||||
"city!vn": "City/Town",
|
||||
"conscriptionnumber": "123",
|
||||
"county": "County",
|
||||
"country": "Country",
|
||||
"county": "County",
|
||||
"county!jp": "District",
|
||||
"district": "District",
|
||||
"district!vn": "Arrondissement/Town/District",
|
||||
"floor": "Floor",
|
||||
"hamlet": "Hamlet",
|
||||
"housename": "Housename",
|
||||
"housenumber": "123",
|
||||
"housenumber!jp": "Building No./Lot No.",
|
||||
"neighbourhood": "Neighbourhood",
|
||||
"neighbourhood!jp": "Chōme/Aza/Koaza",
|
||||
"place": "Place",
|
||||
"postcode": "Postcode",
|
||||
"province": "Province",
|
||||
"province!jp": "Prefecture",
|
||||
"quarter": "Quarter",
|
||||
"quarter!jp": "Ōaza/Machi",
|
||||
"state": "State",
|
||||
"street": "Street",
|
||||
"subdistrict": "Subdistrict",
|
||||
"suburb": "Suburb"
|
||||
"subdistrict!vn": "Ward/Commune/Townlet",
|
||||
"suburb": "Suburb",
|
||||
"suburb!jp": "Ward"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+14
-3
@@ -789,25 +789,36 @@
|
||||
"address": {
|
||||
"label": "Address",
|
||||
"placeholders": {
|
||||
"block_number": "Block number",
|
||||
"block_number": "Block Number",
|
||||
"block_number!jp": "Block No.",
|
||||
"city": "City",
|
||||
"city!jp": "City/Town/Village/Tokyo Special Ward",
|
||||
"city!vn": "City/Town",
|
||||
"conscriptionnumber": "123",
|
||||
"county": "County",
|
||||
"country": "Country",
|
||||
"county": "County",
|
||||
"county!jp": "District",
|
||||
"district": "District",
|
||||
"district!vn": "Arrondissement/Town/District",
|
||||
"floor": "Floor",
|
||||
"hamlet": "Hamlet",
|
||||
"housename": "Housename",
|
||||
"housenumber": "123",
|
||||
"housenumber!jp": "Building No./Lot No.",
|
||||
"neighbourhood": "Neighbourhood",
|
||||
"neighbourhood!jp": "Chōme/Aza/Koaza",
|
||||
"place": "Place",
|
||||
"postcode": "Postcode",
|
||||
"province": "Province",
|
||||
"province!jp": "Prefecture",
|
||||
"quarter": "Quarter",
|
||||
"quarter!jp": "Ōaza/Machi",
|
||||
"state": "State",
|
||||
"street": "Street",
|
||||
"subdistrict": "Subdistrict",
|
||||
"suburb": "Suburb"
|
||||
"subdistrict!vn": "Ward/Commune/Townlet",
|
||||
"suburb": "Suburb",
|
||||
"suburb!jp": "Ward"
|
||||
}
|
||||
},
|
||||
"admin_level": {
|
||||
|
||||
@@ -31,6 +31,9 @@ export function actionDisconnect(nodeId, newNodeId) {
|
||||
if (connection.index === 0 && way.isArea()) {
|
||||
// replace shared node with shared node..
|
||||
graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
|
||||
} else if (way.isClosed() && connection.index === way.nodes.length - 1) {
|
||||
// replace closing node with new new node..
|
||||
graph = graph.replace(way.unclose().addNode(newNode.id));
|
||||
} else {
|
||||
// replace shared node with multiple new nodes..
|
||||
graph = graph.replace(way.updateNode(newNode.id, connection.index));
|
||||
@@ -52,11 +55,11 @@ export function actionDisconnect(nodeId, newNodeId) {
|
||||
return;
|
||||
}
|
||||
if (way.isArea() && (way.nodes[0] === nodeId)) {
|
||||
candidates.push({wayID: way.id, index: 0});
|
||||
candidates.push({ wayID: way.id, index: 0 });
|
||||
} else {
|
||||
way.nodes.forEach(function(waynode, index) {
|
||||
if (waynode === nodeId) {
|
||||
candidates.push({wayID: way.id, index: index});
|
||||
candidates.push({ wayID: way.id, index: index });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,20 +41,27 @@ export function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
|
||||
annotation = t((way.isDegenerate() ?
|
||||
'operations.start.annotation.' :
|
||||
'operations.continue.annotation.') + context.geometry(wayId)),
|
||||
draw = behaviorDraw(context);
|
||||
draw = behaviorDraw(context),
|
||||
startIndex, start, end, segment;
|
||||
|
||||
var startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0,
|
||||
start = osmNode({loc: context.graph().entity(way.nodes[startIndex]).loc}),
|
||||
end = osmNode({loc: context.map().mouseCoordinates()}),
|
||||
segment = osmWay({
|
||||
|
||||
if (!isArea) {
|
||||
startIndex = typeof index === 'undefined' ? way.nodes.length - 1 : 0;
|
||||
start = osmNode({ id: 'nStart', loc: context.entity(way.nodes[startIndex]).loc });
|
||||
end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
|
||||
segment = osmWay({ id: 'wTemp',
|
||||
nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
|
||||
tags: _.clone(way.tags)
|
||||
});
|
||||
} else {
|
||||
end = osmNode({ loc: context.map().mouseCoordinates() });
|
||||
}
|
||||
|
||||
|
||||
var fn = context[way.isDegenerate() ? 'replace' : 'perform'];
|
||||
if (isArea) {
|
||||
fn(actionAddEntity(end),
|
||||
actionAddVertex(wayId, end.id, index)
|
||||
actionAddVertex(wayId, end.id)
|
||||
);
|
||||
} else {
|
||||
fn(actionAddEntity(start),
|
||||
@@ -70,7 +77,7 @@ export function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
|
||||
if (datum.type === 'node' && datum.id !== end.id) {
|
||||
loc = datum.loc;
|
||||
|
||||
} else if (datum.type === 'way' && datum.id !== segment.id) {
|
||||
} else if (datum.type === 'way') { // && (segment || datum.id !== segment.id)) {
|
||||
var dims = context.map().dimensions(),
|
||||
mouse = context.mouse(),
|
||||
pad = 5,
|
||||
@@ -145,9 +152,8 @@ export function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
|
||||
return function(graph) {
|
||||
if (isArea) {
|
||||
return graph
|
||||
.replace(way.addNode(newNode.id, index))
|
||||
.replace(way.addNode(newNode.id))
|
||||
.remove(end);
|
||||
|
||||
} else {
|
||||
return graph
|
||||
.replace(graph.entity(wayId).addNode(newNode.id, index))
|
||||
@@ -165,13 +171,19 @@ export function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
|
||||
var last = context.hasEntity(way.nodes[way.nodes.length - (isArea ? 2 : 1)]);
|
||||
if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
|
||||
|
||||
var newNode = osmNode({loc: loc});
|
||||
|
||||
context.replace(
|
||||
actionAddEntity(newNode),
|
||||
ReplaceTemporaryNode(newNode),
|
||||
annotation
|
||||
);
|
||||
if (isArea) {
|
||||
context.replace(
|
||||
actionMoveNode(end.id, loc),
|
||||
annotation
|
||||
);
|
||||
} else {
|
||||
var newNode = osmNode({loc: loc});
|
||||
context.replace(
|
||||
actionAddEntity(newNode),
|
||||
ReplaceTemporaryNode(newNode),
|
||||
annotation
|
||||
);
|
||||
}
|
||||
|
||||
finished = true;
|
||||
context.enter(mode);
|
||||
@@ -180,21 +192,28 @@ export function behaviorDrawWay(context, wayId, index, mode, baseGraph) {
|
||||
|
||||
// Connect the way to an existing way.
|
||||
drawWay.addWay = function(loc, edge) {
|
||||
var previousEdge = startIndex ?
|
||||
[way.nodes[startIndex], way.nodes[startIndex - 1]] :
|
||||
[way.nodes[0], way.nodes[1]];
|
||||
|
||||
// Avoid creating duplicate segments
|
||||
if (!isArea && geoEdgeEqual(edge, previousEdge))
|
||||
return;
|
||||
if (isArea) {
|
||||
context.perform(
|
||||
actionAddMidpoint({ loc: loc, edge: edge}, end),
|
||||
annotation
|
||||
);
|
||||
} else {
|
||||
var previousEdge = startIndex ?
|
||||
[way.nodes[startIndex], way.nodes[startIndex - 1]] :
|
||||
[way.nodes[0], way.nodes[1]];
|
||||
|
||||
var newNode = osmNode({ loc: loc });
|
||||
// Avoid creating duplicate segments
|
||||
if (geoEdgeEqual(edge, previousEdge))
|
||||
return;
|
||||
|
||||
context.perform(
|
||||
actionAddMidpoint({ loc: loc, edge: edge}, newNode),
|
||||
ReplaceTemporaryNode(newNode),
|
||||
annotation
|
||||
);
|
||||
var newNode = osmNode({ loc: loc });
|
||||
context.perform(
|
||||
actionAddMidpoint({ loc: loc, edge: edge}, newNode),
|
||||
ReplaceTemporaryNode(newNode),
|
||||
annotation
|
||||
);
|
||||
}
|
||||
|
||||
finished = true;
|
||||
context.enter(mode);
|
||||
|
||||
@@ -27,6 +27,13 @@ export function modeAddArea(context) {
|
||||
defaultTags = { area: 'yes' };
|
||||
|
||||
|
||||
function actionClose(wayId) {
|
||||
return function (graph) {
|
||||
return graph.replace(graph.entity(wayId).close());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function start(loc) {
|
||||
var graph = context.graph(),
|
||||
node = osmNode({ loc: loc }),
|
||||
@@ -36,7 +43,7 @@ export function modeAddArea(context) {
|
||||
actionAddEntity(node),
|
||||
actionAddEntity(way),
|
||||
actionAddVertex(way.id, node.id),
|
||||
actionAddVertex(way.id, node.id)
|
||||
actionClose(way.id)
|
||||
);
|
||||
|
||||
context.enter(modeDrawArea(context, way.id, graph));
|
||||
@@ -52,7 +59,7 @@ export function modeAddArea(context) {
|
||||
actionAddEntity(node),
|
||||
actionAddEntity(way),
|
||||
actionAddVertex(way.id, node.id),
|
||||
actionAddVertex(way.id, node.id),
|
||||
actionClose(way.id),
|
||||
actionAddMidpoint({ loc: loc, edge: edge }, node)
|
||||
);
|
||||
|
||||
@@ -67,7 +74,7 @@ export function modeAddArea(context) {
|
||||
context.perform(
|
||||
actionAddEntity(way),
|
||||
actionAddVertex(way.id, node.id),
|
||||
actionAddVertex(way.id, node.id)
|
||||
actionClose(way.id)
|
||||
);
|
||||
|
||||
context.enter(modeDrawArea(context, way.id, graph));
|
||||
|
||||
@@ -7,8 +7,6 @@ import {
|
||||
behaviorSelect
|
||||
} from '../behavior/index';
|
||||
|
||||
import { modeDragNode } from './index';
|
||||
|
||||
|
||||
export function modeBrowse(context) {
|
||||
var mode = {
|
||||
@@ -22,8 +20,7 @@ export function modeBrowse(context) {
|
||||
behaviorPaste(context),
|
||||
behaviorHover(context).on('hover', context.ui().sidebar.hover),
|
||||
behaviorSelect(context),
|
||||
behaviorLasso(context),
|
||||
modeDragNode(context).behavior
|
||||
behaviorLasso(context)
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -79,12 +79,16 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function start(entity) {
|
||||
activeIDs = _.map(context.graph().parentWays(entity), 'id');
|
||||
activeIDs.push(entity.id);
|
||||
wasMidpoint = entity.type === 'midpoint';
|
||||
|
||||
isCancelled = d3.event.sourceEvent.shiftKey ||
|
||||
!(wasMidpoint || _.some(activeIDs, function (activeID) { return selectedIDs.indexOf(activeID) !== -1; })) ||
|
||||
context.features().hasHiddenConnections(entity, context.graph());
|
||||
|
||||
if (isCancelled) return behavior.cancel();
|
||||
|
||||
wasMidpoint = entity.type === 'midpoint';
|
||||
if (wasMidpoint) {
|
||||
var midpoint = entity;
|
||||
entity = osmNode();
|
||||
@@ -93,12 +97,14 @@ export function modeDragNode(context) {
|
||||
var vertex = context.surface().selectAll('.' + entity.id);
|
||||
behavior.target(vertex.node(), entity);
|
||||
|
||||
activeIDs = _.map(context.graph().parentWays(entity), 'id');
|
||||
activeIDs.push(entity.id);
|
||||
|
||||
} else {
|
||||
context.perform(actionNoop());
|
||||
}
|
||||
|
||||
activeIDs = _.map(context.graph().parentWays(entity), 'id');
|
||||
activeIDs.push(entity.id);
|
||||
setActiveElements();
|
||||
context.enter(mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,18 @@ export function modeDrawArea(context, wayId, baseGraph) {
|
||||
|
||||
|
||||
mode.enter = function() {
|
||||
var way = context.entity(wayId),
|
||||
headId = way.nodes[way.nodes.length - 2],
|
||||
tailId = way.first();
|
||||
var way = context.entity(wayId);
|
||||
|
||||
behavior = behaviorDrawWay(context, wayId, -1, mode, baseGraph)
|
||||
behavior = behaviorDrawWay(context, wayId, undefined, mode, baseGraph)
|
||||
.tail(t('modes.draw_area.tail'));
|
||||
|
||||
var addNode = behavior.addNode;
|
||||
|
||||
behavior.addNode = function(node) {
|
||||
if (node.id === headId || node.id === tailId) {
|
||||
var length = way.nodes.length,
|
||||
penultimate = length > 2 ? way.nodes[length - 2] : null;
|
||||
|
||||
if (node.id === way.first() || node.id === penultimate) {
|
||||
behavior.finish();
|
||||
} else {
|
||||
addNode(node);
|
||||
|
||||
@@ -15,6 +15,7 @@ export function operationContinue(selectedIDs, context) {
|
||||
function candidateWays() {
|
||||
return graph.parentWays(vertex).filter(function(parent) {
|
||||
return parent.geometry(graph) === 'line' &&
|
||||
!parent.isClosed() &&
|
||||
parent.affix(vertex.id) &&
|
||||
(geometries.line.length === 0 || geometries.line[0] === parent);
|
||||
});
|
||||
|
||||
+149
-18
@@ -122,7 +122,7 @@ _.extend(osmWay.prototype, {
|
||||
|
||||
|
||||
isClosed: function() {
|
||||
return this.nodes.length > 0 && this.first() === this.last();
|
||||
return this.nodes.length > 1 && this.first() === this.last();
|
||||
},
|
||||
|
||||
|
||||
@@ -188,46 +188,169 @@ _.extend(osmWay.prototype, {
|
||||
},
|
||||
|
||||
|
||||
// If this way is not closed, append the beginning node to the end of the nodelist to close it.
|
||||
close: function() {
|
||||
if (this.isClosed() || !this.nodes.length) return this;
|
||||
|
||||
var nodes = this.nodes.slice();
|
||||
nodes = nodes.filter(noRepeatNodes);
|
||||
nodes.push(nodes[0]);
|
||||
return this.update({ nodes: nodes });
|
||||
},
|
||||
|
||||
|
||||
// If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
|
||||
unclose: function() {
|
||||
if (!this.isClosed()) return this;
|
||||
|
||||
var nodes = this.nodes.slice(),
|
||||
connector = this.first(),
|
||||
i = nodes.length - 1;
|
||||
|
||||
// remove trailing connectors..
|
||||
while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
|
||||
nodes.splice(i, 1);
|
||||
i = nodes.length - 1;
|
||||
}
|
||||
|
||||
nodes = nodes.filter(noRepeatNodes);
|
||||
return this.update({ nodes: nodes });
|
||||
},
|
||||
|
||||
|
||||
// Adds a node (id) in front of the node which is currently at position index.
|
||||
// If index is undefined, the node will be added to the end of the way for linear ways,
|
||||
// or just before the final connecting node for circular ways.
|
||||
// Consecutive duplicates are eliminated including existing ones.
|
||||
// Circularity is always preserved when adding a node.
|
||||
addNode: function(id, index) {
|
||||
var nodes = this.nodes.slice();
|
||||
nodes.splice(index === undefined ? nodes.length : index, 0, id);
|
||||
return this.update({nodes: nodes});
|
||||
var nodes = this.nodes.slice(),
|
||||
isClosed = this.isClosed(),
|
||||
max = isClosed ? nodes.length - 1 : nodes.length;
|
||||
|
||||
if (index === undefined) {
|
||||
index = max;
|
||||
}
|
||||
|
||||
if (index < 0 || index > max) {
|
||||
throw new RangeError('index ' + index + ' out of range 0..' + max);
|
||||
}
|
||||
|
||||
// If this is a closed way, remove all connector nodes except the first one
|
||||
// (there may be duplicates) and adjust index if necessary..
|
||||
if (isClosed) {
|
||||
var connector = this.first();
|
||||
|
||||
// leading connectors..
|
||||
var i = 1;
|
||||
while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
|
||||
nodes.splice(i, 1);
|
||||
if (index > i) index--;
|
||||
}
|
||||
|
||||
// trailing connectors..
|
||||
i = nodes.length - 1;
|
||||
while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
|
||||
nodes.splice(i, 1);
|
||||
if (index > i) index--;
|
||||
i = nodes.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.splice(index, 0, id);
|
||||
nodes = nodes.filter(noRepeatNodes);
|
||||
|
||||
// If the way was closed before, append a connector node to keep it closed..
|
||||
if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
|
||||
nodes.push(nodes[0]);
|
||||
}
|
||||
|
||||
return this.update({ nodes: nodes });
|
||||
},
|
||||
|
||||
|
||||
// Replaces the node which is currently at position index with the given node (id).
|
||||
// Consecutive duplicates are eliminated including existing ones.
|
||||
// Circularity is preserved when updating a node.
|
||||
updateNode: function(id, index) {
|
||||
var nodes = this.nodes.slice();
|
||||
var nodes = this.nodes.slice(),
|
||||
isClosed = this.isClosed(),
|
||||
max = nodes.length - 1;
|
||||
|
||||
if (index === undefined || index < 0 || index > max) {
|
||||
throw new RangeError('index ' + index + ' out of range 0..' + max);
|
||||
}
|
||||
|
||||
// If this is a closed way, remove all connector nodes except the first one
|
||||
// (there may be duplicates) and adjust index if necessary..
|
||||
if (isClosed) {
|
||||
var connector = this.first();
|
||||
|
||||
// leading connectors..
|
||||
var i = 1;
|
||||
while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
|
||||
nodes.splice(i, 1);
|
||||
if (index > i) index--;
|
||||
}
|
||||
|
||||
// trailing connectors..
|
||||
i = nodes.length - 1;
|
||||
while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
|
||||
nodes.splice(i, 1);
|
||||
if (index === i) index = 0; // update leading connector instead
|
||||
i = nodes.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.splice(index, 1, id);
|
||||
nodes = nodes.filter(noRepeatNodes);
|
||||
|
||||
// If the way was closed before, append a connector node to keep it closed..
|
||||
if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
|
||||
nodes.push(nodes[0]);
|
||||
}
|
||||
|
||||
return this.update({nodes: nodes});
|
||||
},
|
||||
|
||||
|
||||
// Replaces each occurrence of node id needle with replacement.
|
||||
// Consecutive duplicates are eliminated including existing ones.
|
||||
// Circularity is preserved.
|
||||
replaceNode: function(needle, replacement) {
|
||||
if (this.nodes.indexOf(needle) < 0)
|
||||
return this;
|
||||
var nodes = this.nodes.slice(),
|
||||
isClosed = this.isClosed();
|
||||
|
||||
var nodes = this.nodes.slice();
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
if (nodes[i] === needle) {
|
||||
nodes[i] = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
nodes = nodes.filter(noRepeatNodes);
|
||||
|
||||
// If the way was closed before, append a connector node to keep it closed..
|
||||
if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
|
||||
nodes.push(nodes[0]);
|
||||
}
|
||||
|
||||
return this.update({nodes: nodes});
|
||||
},
|
||||
|
||||
|
||||
// Removes each occurrence of node id needle with replacement.
|
||||
// Consecutive duplicates are eliminated including existing ones.
|
||||
// Circularity is preserved.
|
||||
removeNode: function(id) {
|
||||
var nodes = [];
|
||||
var nodes = this.nodes.slice(),
|
||||
isClosed = this.isClosed();
|
||||
|
||||
for (var i = 0; i < this.nodes.length; i++) {
|
||||
var node = this.nodes[i];
|
||||
if (node !== id && nodes[nodes.length - 1] !== node) {
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
nodes = nodes
|
||||
.filter(function(node) { return node !== id; })
|
||||
.filter(noRepeatNodes);
|
||||
|
||||
// Preserve circularity
|
||||
if (this.nodes.length > 1 && this.first() === id && this.last() === id && nodes[nodes.length - 1] !== nodes[0]) {
|
||||
// If the way was closed before, append a connector node to keep it closed..
|
||||
if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
|
||||
nodes.push(nodes[0]);
|
||||
}
|
||||
|
||||
@@ -248,7 +371,9 @@ _.extend(osmWay.prototype, {
|
||||
})
|
||||
}
|
||||
};
|
||||
if (changeset_id) r.way['@changeset'] = changeset_id;
|
||||
if (changeset_id) {
|
||||
r.way['@changeset'] = changeset_id;
|
||||
}
|
||||
return r;
|
||||
},
|
||||
|
||||
@@ -297,3 +422,9 @@ _.extend(osmWay.prototype, {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Filter function to eliminate consecutive duplicates.
|
||||
function noRepeatNodes(node, i, arr) {
|
||||
return i === 0 || node !== arr[i - 1];
|
||||
}
|
||||
|
||||
+10
-11
@@ -58,19 +58,18 @@ export function uiCommit(context) {
|
||||
context.connection().userChangesets(function (err, changesets) {
|
||||
if (err) return;
|
||||
|
||||
var comments = [];
|
||||
|
||||
for (var i = 0; i < changesets.length; i++) {
|
||||
if (changesets[i].tags.comment) {
|
||||
comments.push({
|
||||
title: changesets[i].tags.comment,
|
||||
value: changesets[i].tags.comment
|
||||
});
|
||||
}
|
||||
}
|
||||
var comments = changesets.map(function(changeset) {
|
||||
return {
|
||||
title: changeset.tags.comment,
|
||||
value: changeset.tags.comment
|
||||
};
|
||||
});
|
||||
|
||||
commentField
|
||||
.call(d3combobox().caseSensitive(true).data(comments));
|
||||
.call(d3combobox()
|
||||
.caseSensitive(true)
|
||||
.data(_.uniqBy(comments, 'title'))
|
||||
);
|
||||
});
|
||||
|
||||
var clippyArea = commentSection.append('div')
|
||||
|
||||
@@ -16,20 +16,11 @@ import { utilGetSetValue } from '../../util/get_set_value';
|
||||
|
||||
export function uiFieldAddress(field, context) {
|
||||
var dispatch = d3.dispatch('init', 'change'),
|
||||
nominatim = services.nominatim,
|
||||
nominatim = services.geocoder,
|
||||
wrap = d3.select(null),
|
||||
isInitialized = false,
|
||||
entity;
|
||||
|
||||
var widths = {
|
||||
housenumber: 1/3,
|
||||
street: 2/3,
|
||||
city: 2/3,
|
||||
state: 1/4,
|
||||
postcode: 1/3
|
||||
};
|
||||
|
||||
|
||||
function getNearStreets() {
|
||||
var extent = entity.extent(context.graph()),
|
||||
l = extent.center(),
|
||||
@@ -98,7 +89,6 @@ export function uiFieldAddress(field, context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getNearValues(key) {
|
||||
var extent = entity.extent(context.graph()),
|
||||
l = extent.center(),
|
||||
@@ -130,6 +120,11 @@ export function uiFieldAddress(field, context) {
|
||||
return a && a.countryCodes && _.includes(a.countryCodes, countryCode);
|
||||
}) || _.first(dataAddressFormats);
|
||||
|
||||
var widths = addressFormat.widths || {
|
||||
housenumber: 1/3, street: 2/3,
|
||||
city: 2/3, state: 1/4, postcode: 1/3
|
||||
};
|
||||
|
||||
function row(r) {
|
||||
// Normalize widths.
|
||||
var total = _.reduce(r, function(sum, field) {
|
||||
@@ -154,19 +149,25 @@ export function uiFieldAddress(field, context) {
|
||||
.enter()
|
||||
.append('input')
|
||||
.property('type', 'text')
|
||||
.attr('placeholder', function (d) { return field.t('placeholders.' + d.id); })
|
||||
.attr('placeholder', function (d) {
|
||||
var localkey = d.id + '!' + countryCode,
|
||||
tkey = field.strings.placeholders[localkey] ? localkey : d.id;
|
||||
return field.t('placeholders.' + tkey);
|
||||
})
|
||||
.attr('class', function (d) { return 'addr-' + d.id; })
|
||||
.style('width', function (d) { return d.width * 100 + '%'; });
|
||||
|
||||
// Update
|
||||
var addrTags = [
|
||||
|
||||
// setup dropdowns for common address tags
|
||||
var dropdowns = addressFormat.dropdowns || [
|
||||
'city', 'county', 'country', 'district', 'hamlet',
|
||||
'neighbourhood', 'place', 'postcode', 'province',
|
||||
'quarter', 'state', 'street', 'subdistrict', 'suburb'
|
||||
];
|
||||
|
||||
// If fields exist for any of these tags, create dropdowns to pick nearby values..
|
||||
addrTags.forEach(function(tag) {
|
||||
dropdowns.forEach(function(tag) {
|
||||
var nearValues = (tag === 'street') ? getNearStreets
|
||||
: (tag === 'city') ? getNearCities
|
||||
: getNearValues;
|
||||
@@ -202,7 +203,6 @@ export function uiFieldAddress(field, context) {
|
||||
.attr('class', 'preset-input-wrap')
|
||||
.merge(wrap);
|
||||
|
||||
|
||||
if (nominatim && entity) {
|
||||
var center = entity.extent(context.graph()).center();
|
||||
nominatim.countryCode(center, initCallback);
|
||||
|
||||
@@ -15,7 +15,7 @@ export {
|
||||
|
||||
export function uiFieldCombo(field, context) {
|
||||
var dispatch = d3.dispatch('change'),
|
||||
nominatim = services.nominatim,
|
||||
nominatim = services.geocoder,
|
||||
taginfo = services.taginfo,
|
||||
isMulti = (field.type === 'multiCombo'),
|
||||
isNetwork = (field.type === 'networkCombo'),
|
||||
|
||||
@@ -15,7 +15,7 @@ export {
|
||||
|
||||
export function uiFieldText(field, context) {
|
||||
var dispatch = d3.dispatch('change'),
|
||||
nominatim = services.nominatim,
|
||||
nominatim = services.geocoder,
|
||||
input,
|
||||
entity;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export { uiInit } from './init';
|
||||
export { uiFields } from './fields/index';
|
||||
export { uiAccount } from './account';
|
||||
export { uiAttribution } from './attribution';
|
||||
export { uiBackground } from './background';
|
||||
@@ -18,7 +17,6 @@ export { uiGeolocate } from './geolocate';
|
||||
export { uiHelp } from './help';
|
||||
export { uiInfo } from './info';
|
||||
export { uiInspector } from './inspector';
|
||||
export { uiIntro } from './intro';
|
||||
export { uiLasso } from './lasso';
|
||||
export { uiLoading } from './loading';
|
||||
export { uiMapData } from './map_data';
|
||||
|
||||
+2
-2
@@ -51,7 +51,7 @@
|
||||
"js-yaml": "~3.7.0",
|
||||
"jsonschema": "~1.1.0",
|
||||
"json-stable-stringify": "~1.0.1",
|
||||
"mapillary-js": "2.2.0",
|
||||
"mapillary-js": "2.3.0",
|
||||
"minimist": "~1.2.0",
|
||||
"mocha": "~3.2.0",
|
||||
"mocha-phantomjs-core": "~2.1.0",
|
||||
@@ -59,7 +59,7 @@
|
||||
"npm-run-all": "~4.0.0",
|
||||
"phantomjs-prebuilt": "~2.1.11",
|
||||
"request": "~2.79.0",
|
||||
"rollup": "0.41.1",
|
||||
"rollup": "0.41.4",
|
||||
"rollup-plugin-commonjs": "7.0.0",
|
||||
"rollup-plugin-json": "2.0.2",
|
||||
"rollup-plugin-node-resolve": "2.0.0",
|
||||
|
||||
+457
-29
@@ -127,16 +127,24 @@ describe('iD.osmWay', function() {
|
||||
});
|
||||
|
||||
describe('#isClosed', function() {
|
||||
it('returns false when the way has no nodes', function() {
|
||||
expect(iD.Way().isClosed()).to.equal(false);
|
||||
it('returns false when the way contains no nodes', function() {
|
||||
expect(iD.Way().isClosed()).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false when the way contains a single node', function() {
|
||||
expect(iD.Way({ nodes: 'a'.split('') }).isClosed()).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false when the way ends are not equal', function() {
|
||||
expect(iD.Way({nodes: ['n1', 'n2']}).isClosed()).to.equal(false);
|
||||
expect(iD.Way({ nodes: 'abc'.split('') }).isClosed()).to.be.false;
|
||||
});
|
||||
|
||||
it('returns true when the way ends are equal', function() {
|
||||
expect(iD.Way({nodes: ['n1', 'n2', 'n1']}).isClosed()).to.equal(true);
|
||||
expect(iD.Way({ nodes: 'aba'.split('') }).isClosed()).to.be.true;
|
||||
});
|
||||
|
||||
it('returns true when the way contains two of the same node', function() {
|
||||
expect(iD.Way({ nodes: 'aa'.split('') }).isClosed()).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -409,54 +417,474 @@ describe('iD.osmWay', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#close', function () {
|
||||
it('returns self for empty way', function () {
|
||||
var w = iD.Way();
|
||||
expect(w.close()).to.deep.equal(w);
|
||||
});
|
||||
|
||||
it('returns self for already closed way', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.close()).to.deep.equal(w1);
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.close()).to.deep.equal(w2);
|
||||
});
|
||||
|
||||
it('closes a way', function () {
|
||||
var w1 = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w1.close().nodes.join('')).to.eql('aba', 'multiple');
|
||||
var w2 = iD.Way({ nodes: 'a'.split('') });
|
||||
expect(w2.close().nodes.join('')).to.eql('aa', 'single');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when closing a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abb'.split('') });
|
||||
expect(w1.close().nodes.join('')).to.eql('aba', 'duplicate at end');
|
||||
var w2 = iD.Way({ nodes: 'abbc'.split('') });
|
||||
expect(w2.close().nodes.join('')).to.eql('abca', 'duplicate in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabc'.split('') });
|
||||
expect(w3.close().nodes.join('')).to.eql('abca', 'duplicate at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abbbcbb'.split('') });
|
||||
expect(w4.close().nodes.join('')).to.eql('abcba', 'duplicates multiple places');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unclose', function () {
|
||||
it('returns self for empty way', function () {
|
||||
var w = iD.Way();
|
||||
expect(w.unclose()).to.deep.equal(w);
|
||||
});
|
||||
|
||||
it('returns self for already unclosed way', function () {
|
||||
var w1 = iD.Way({ nodes: 'a'.split('') });
|
||||
expect(w1.unclose()).to.deep.equal(w1);
|
||||
var w2 = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w2.unclose()).to.deep.equal(w2);
|
||||
});
|
||||
|
||||
it('uncloses a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.unclose().nodes.join('')).to.eql('ab', 'multiple');
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.unclose().nodes.join('')).to.eql('a', 'single');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when unclosing a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.unclose().nodes.join('')).to.eql('abc', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.unclose().nodes.join('')).to.eql('abc', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.unclose().nodes.join('')).to.eql('abc', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.unclose().nodes.join('')).to.eql('abc', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.unclose().nodes.join('')).to.eql('abcb', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.unclose().nodes.join('')).to.eql('a', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.unclose().nodes.join('')).to.eql('a', 'single node circular with duplicates');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#addNode', function () {
|
||||
it('adds a node to the end of a way', function () {
|
||||
it('adds a node to an empty way', function () {
|
||||
var w = iD.Way();
|
||||
expect(w.addNode('a').nodes).to.eql(['a']);
|
||||
});
|
||||
|
||||
it('adds a node to a way at index 0', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b']});
|
||||
expect(w.addNode('c', 0).nodes).to.eql(['c', 'a', 'b']);
|
||||
it('adds a node to the end of a linear way when index is undefined', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.addNode('c').nodes.join('')).to.eql('abc');
|
||||
});
|
||||
|
||||
it('adds a node to a way at a positive index', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b']});
|
||||
expect(w.addNode('c', 1).nodes).to.eql(['a', 'c', 'b']);
|
||||
it('adds a node before the end connector of a circular way when index is undefined', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.addNode('c').nodes.join('')).to.eql('abca', 'circular');
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.addNode('c').nodes.join('')).to.eql('aca', 'single node circular');
|
||||
});
|
||||
|
||||
it('adds a node to a way at a negative index', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b']});
|
||||
expect(w.addNode('c', -1).nodes).to.eql(['a', 'c', 'b']);
|
||||
it('adds an internal node to a linear way at a positive index', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.addNode('c', 1).nodes.join('')).to.eql('acb');
|
||||
});
|
||||
|
||||
it('adds an internal node to a circular way at a positive index', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.addNode('c', 1).nodes.join('')).to.eql('acba', 'circular');
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.addNode('c', 1).nodes.join('')).to.eql('aca', 'single node circular');
|
||||
});
|
||||
|
||||
it('adds a leading node to a linear way at index 0', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.addNode('c', 0).nodes.join('')).to.eql('cab');
|
||||
});
|
||||
|
||||
it('adds a leading node to a circular way at index 0, preserving circularity', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.addNode('c', 0).nodes.join('')).to.eql('cabc', 'circular');
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.addNode('c', 0).nodes.join('')).to.eql('cac', 'single node circular');
|
||||
});
|
||||
|
||||
it('throws RangeError if index outside of array range for linear way', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.addNode.bind(w, 'c', 3)).to.throw(RangeError, /out of range 0\.\.2/, 'over range');
|
||||
expect(w.addNode.bind(w, 'c', -1)).to.throw(RangeError, /out of range 0\.\.2/, 'under range');
|
||||
});
|
||||
|
||||
it('throws RangeError if index outside of array range for circular way', function () {
|
||||
var w = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w.addNode.bind(w, 'c', 3)).to.throw(RangeError, /out of range 0\.\.2/, 'over range');
|
||||
expect(w.addNode.bind(w, 'c', -1)).to.throw(RangeError, /out of range 0\.\.2/, 'under range');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding to the end of a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abb'.split('') });
|
||||
expect(w1.addNode('b').nodes.join('')).to.eql('ab', 'duplicate at end');
|
||||
var w2 = iD.Way({ nodes: 'abbc'.split('') });
|
||||
expect(w2.addNode('c').nodes.join('')).to.eql('abc', 'duplicate in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabc'.split('') });
|
||||
expect(w3.addNode('c').nodes.join('')).to.eql('abc', 'duplicate at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abbbcbb'.split('') });
|
||||
expect(w4.addNode('b').nodes.join('')).to.eql('abcb', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding same node before the end connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.addNode('c').nodes.join('')).to.eql('abca', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.addNode('c').nodes.join('')).to.eql('abca', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.addNode('c').nodes.join('')).to.eql('abca', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.addNode('a').nodes.join('')).to.eql('abca', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.addNode('b').nodes.join('')).to.eql('abcba', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.addNode('a').nodes.join('')).to.eql('aa', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.addNode('a').nodes.join('')).to.eql('aa', 'single node circular with duplicates');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding different node before the end connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.addNode('d').nodes.join('')).to.eql('abcda', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.addNode('d').nodes.join('')).to.eql('abcda', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.addNode('d').nodes.join('')).to.eql('abcda', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.addNode('d').nodes.join('')).to.eql('abcda', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.addNode('d').nodes.join('')).to.eql('abcbda', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.addNode('d').nodes.join('')).to.eql('ada', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.addNode('d').nodes.join('')).to.eql('ada', 'single node circular with duplicates');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding to the beginning of a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abb'.split('') });
|
||||
expect(w1.addNode('a', 0).nodes.join('')).to.eql('ab', 'duplicate at end');
|
||||
var w2 = iD.Way({ nodes: 'abbc'.split('') });
|
||||
expect(w2.addNode('a', 0).nodes.join('')).to.eql('abc', 'duplicate in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabc'.split('') });
|
||||
expect(w3.addNode('a', 0).nodes.join('')).to.eql('abc', 'duplicate at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abbbcbb'.split('') });
|
||||
expect(w4.addNode('a', 0).nodes.join('')).to.eql('abcb', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding same node as beginning connector a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.addNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.addNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.addNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.addNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.addNode('a', 0).nodes.join('')).to.eql('abcba', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.addNode('a', 0).nodes.join('')).to.eql('aa', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.addNode('a', 0).nodes.join('')).to.eql('aa', 'single node circular with duplicates');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when adding different node as beginning connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.addNode('d', 0).nodes.join('')).to.eql('dabcd', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.addNode('d', 0).nodes.join('')).to.eql('dabcd', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.addNode('d', 0).nodes.join('')).to.eql('dabcd', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.addNode('d', 0).nodes.join('')).to.eql('dabcd', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.addNode('d', 0).nodes.join('')).to.eql('dabcbd', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.addNode('d', 0).nodes.join('')).to.eql('dad', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.addNode('d', 0).nodes.join('')).to.eql('dad', 'single node circular with duplicates');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateNode', function () {
|
||||
it('updates the node id at the specified index', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b', 'c']});
|
||||
expect(w.updateNode('d', 1).nodes).to.eql(['a', 'd', 'c']);
|
||||
it('throws RangeError if empty way', function () {
|
||||
var w = iD.Way();
|
||||
expect(w.updateNode.bind(w, 'd', 0)).to.throw(RangeError, /out of range 0\.\.-1/);
|
||||
});
|
||||
|
||||
it('updates an internal node on a linear way at a positive index', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.updateNode('d', 1).nodes.join('')).to.eql('ad');
|
||||
});
|
||||
|
||||
it('updates an internal node on a circular way at a positive index', function () {
|
||||
var w = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w.updateNode('d', 1).nodes.join('')).to.eql('ada', 'circular');
|
||||
});
|
||||
|
||||
it('updates a leading node on a linear way at index 0', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.updateNode('d', 0).nodes.join('')).to.eql('db');
|
||||
});
|
||||
|
||||
it('updates a leading node on a circular way at index 0, preserving circularity', function () {
|
||||
var w1 = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w1.updateNode('d', 0).nodes.join('')).to.eql('dbd', 'circular');
|
||||
var w2 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w2.updateNode('d', 0).nodes.join('')).to.eql('dd', 'single node circular');
|
||||
});
|
||||
|
||||
it('throws RangeError if index outside of array range for linear way', function () {
|
||||
var w = iD.Way({ nodes: 'ab'.split('') });
|
||||
expect(w.updateNode.bind(w, 'd', 2)).to.throw(RangeError, /out of range 0\.\.1/, 'over range');
|
||||
expect(w.updateNode.bind(w, 'd', -1)).to.throw(RangeError, /out of range 0\.\.1/, 'under range');
|
||||
});
|
||||
|
||||
it('throws RangeError if index outside of array range for circular way', function () {
|
||||
var w = iD.Way({ nodes: 'aba'.split('') });
|
||||
expect(w.updateNode.bind(w, 'd', 3)).to.throw(RangeError, /out of range 0\.\.2/, 'over range');
|
||||
expect(w.updateNode.bind(w, 'd', -1)).to.throw(RangeError, /out of range 0\.\.2/, 'under range');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating the end of a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcc'.split('') });
|
||||
expect(w1.updateNode('c', 3).nodes.join('')).to.eql('abc', 'duplicate at end');
|
||||
var w2 = iD.Way({ nodes: 'abbc'.split('') });
|
||||
expect(w2.updateNode('c', 3).nodes.join('')).to.eql('abc', 'duplicate in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabc'.split('') });
|
||||
expect(w3.updateNode('c', 3).nodes.join('')).to.eql('abc', 'duplicate at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abbbcbb'.split('') });
|
||||
expect(w4.updateNode('b', 6).nodes.join('')).to.eql('abcb', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating same node before the end connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.updateNode('c', 3).nodes.join('')).to.eql('abca', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.updateNode('c', 3).nodes.join('')).to.eql('abca', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.updateNode('c', 3).nodes.join('')).to.eql('abca', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.updateNode('a', 3).nodes.join('')).to.eql('abca', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.updateNode('b', 6).nodes.join('')).to.eql('abcba', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating different node before the end connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.updateNode('d', 3).nodes.join('')).to.eql('abcda', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.updateNode('d', 3).nodes.join('')).to.eql('abda', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.updateNode('d', 3).nodes.join('')).to.eql('abda', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.updateNode('d', 3).nodes.join('')).to.eql('dbcd', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.updateNode('d', 6).nodes.join('')).to.eql('abcbda', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating the beginning of a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abb'.split('') });
|
||||
expect(w1.updateNode('b', 0).nodes.join('')).to.eql('b', 'duplicate at end');
|
||||
var w2 = iD.Way({ nodes: 'abbc'.split('') });
|
||||
expect(w2.updateNode('b', 0).nodes.join('')).to.eql('bc', 'duplicate in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabc'.split('') });
|
||||
expect(w3.updateNode('a', 0).nodes.join('')).to.eql('abc', 'duplicate at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abbbcbb'.split('') });
|
||||
expect(w4.updateNode('a', 0).nodes.join('')).to.eql('abcb', 'duplicates multiple places');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating same node as beginning connector a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.updateNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.updateNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.updateNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.updateNode('a', 0).nodes.join('')).to.eql('abca', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.updateNode('a', 0).nodes.join('')).to.eql('abcba', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.updateNode('a', 0).nodes.join('')).to.eql('aa', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.updateNode('a', 0).nodes.join('')).to.eql('aa', 'single node circular with duplicates');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating different node as beginning connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.updateNode('d', 0).nodes.join('')).to.eql('dbcd', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.updateNode('d', 0).nodes.join('')).to.eql('dbcd', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.updateNode('d', 0).nodes.join('')).to.eql('dbcd', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.updateNode('d', 0).nodes.join('')).to.eql('dbcd', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.updateNode('d', 0).nodes.join('')).to.eql('dbcbd', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.updateNode('d', 0).nodes.join('')).to.eql('dd', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.updateNode('d', 0).nodes.join('')).to.eql('dd', 'single node circular with duplicates');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when updating different node as ending connector of a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcca'.split('') });
|
||||
expect(w1.updateNode('d', 4).nodes.join('')).to.eql('dbcd', 'duplicate internal node at end');
|
||||
var w2 = iD.Way({ nodes: 'abbca'.split('') });
|
||||
expect(w2.updateNode('d', 4).nodes.join('')).to.eql('dbcd', 'duplicate internal node in middle');
|
||||
var w3 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w3.updateNode('d', 4).nodes.join('')).to.eql('dbcd', 'duplicate connector node at beginning');
|
||||
var w4 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w4.updateNode('d', 4).nodes.join('')).to.eql('dbcd', 'duplicate connector node at end');
|
||||
var w5 = iD.Way({ nodes: 'abbbcbba'.split('') });
|
||||
expect(w5.updateNode('d', 7).nodes.join('')).to.eql('dbcbd', 'duplicates multiple places');
|
||||
var w6 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w6.updateNode('d', 1).nodes.join('')).to.eql('dd', 'single node circular');
|
||||
var w7 = iD.Way({ nodes: 'aaa'.split('') });
|
||||
expect(w7.updateNode('d', 2).nodes.join('')).to.eql('dd', 'single node circular with duplicates');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#replaceNode', function () {
|
||||
it('replaces a node', function () {
|
||||
var w1 = iD.Way({ nodes: 'a'.split('') });
|
||||
expect(w1.replaceNode('a','b').nodes.join('')).to.eql('b', 'single replace, single node');
|
||||
var w2 = iD.Way({ nodes: 'abc'.split('') });
|
||||
expect(w2.replaceNode('b','d').nodes.join('')).to.eql('adc', 'single replace, linear');
|
||||
var w4 = iD.Way({ nodes: 'abca'.split('') });
|
||||
expect(w4.replaceNode('b','d').nodes.join('')).to.eql('adca', 'single replace, circular');
|
||||
});
|
||||
|
||||
it('replaces multiply occurring nodes', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcb'.split('') });
|
||||
expect(w1.replaceNode('b','d').nodes.join('')).to.eql('adcd', 'multiple replace, linear');
|
||||
var w2 = iD.Way({ nodes: 'abca'.split('') });
|
||||
expect(w2.replaceNode('a','d').nodes.join('')).to.eql('dbcd', 'multiple replace, circular');
|
||||
var w3 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w3.replaceNode('a','d').nodes.join('')).to.eql('dd', 'multiple replace, single node circular');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when replacing along a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abbcd'.split('') });
|
||||
expect(w1.replaceNode('c','b').nodes.join('')).to.eql('abd', 'duplicate before');
|
||||
var w2 = iD.Way({ nodes: 'abcdd'.split('') });
|
||||
expect(w2.replaceNode('c','d').nodes.join('')).to.eql('abd', 'duplicate after');
|
||||
var w3 = iD.Way({ nodes: 'abbcbb'.split('')});
|
||||
expect(w3.replaceNode('c','b').nodes.join('')).to.eql('ab', 'duplicate before and after');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when replacing internal nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abbcda'.split('') });
|
||||
expect(w1.replaceNode('c','b').nodes.join('')).to.eql('abda', 'duplicate before');
|
||||
var w2 = iD.Way({ nodes: 'abcdda'.split('') });
|
||||
expect(w2.replaceNode('c','d').nodes.join('')).to.eql('abda', 'duplicate after');
|
||||
var w3 = iD.Way({ nodes: 'abbcbba'.split('')});
|
||||
expect(w3.replaceNode('c','b').nodes.join('')).to.eql('aba', 'duplicate before and after');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when replacing adjacent to connecting nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcda'.split('') });
|
||||
expect(w1.replaceNode('d','a').nodes.join('')).to.eql('abca', 'before single end connector');
|
||||
var w2 = iD.Way({ nodes: 'abcda'.split('') });
|
||||
expect(w2.replaceNode('b','a').nodes.join('')).to.eql('acda', 'after single beginning connector');
|
||||
var w3 = iD.Way({ nodes: 'abcdaa'.split('') });
|
||||
expect(w3.replaceNode('d','a').nodes.join('')).to.eql('abca', 'before duplicate end connector');
|
||||
var w4 = iD.Way({ nodes: 'aabcda'.split('') });
|
||||
expect(w4.replaceNode('b','a').nodes.join('')).to.eql('acda', 'after duplicate beginning connector');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when replacing connecting nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w1.replaceNode('a','d').nodes.join('')).to.eql('dbcd', 'duplicate end connector');
|
||||
var w2 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w2.replaceNode('a','d').nodes.join('')).to.eql('dbcd', 'duplicate beginning connector');
|
||||
var w3 = iD.Way({ nodes: 'aabcaa'.split('') });
|
||||
expect(w3.replaceNode('a','d').nodes.join('')).to.eql('dbcd', 'duplicate beginning and end connectors');
|
||||
var w4 = iD.Way({ nodes: 'aabaacaa'.split('') });
|
||||
expect(w4.replaceNode('a','d').nodes.join('')).to.eql('dbdcd', 'duplicates multiple places');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeNode', function () {
|
||||
it('removes the node', function () {
|
||||
var w = iD.Way({nodes: ['a']});
|
||||
expect(w.removeNode('a').nodes).to.eql([]);
|
||||
it('removes a node', function () {
|
||||
var w1 = iD.Way({ nodes: 'a'.split('') });
|
||||
expect(w1.removeNode('a').nodes.join('')).to.eql('', 'single remove, single node');
|
||||
var w2 = iD.Way({ nodes: 'abc'.split('') });
|
||||
expect(w2.removeNode('b').nodes.join('')).to.eql('ac', 'single remove, linear');
|
||||
var w3 = iD.Way({ nodes: 'abca'.split('') });
|
||||
expect(w3.removeNode('b').nodes.join('')).to.eql('aca', 'single remove, circular');
|
||||
var w4 = iD.Way({ nodes: 'aa'.split('') });
|
||||
expect(w4.removeNode('a').nodes.join('')).to.eql('', 'multiple remove, single node circular');
|
||||
});
|
||||
|
||||
it('prevents duplicate consecutive nodes', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b', 'c', 'b']});
|
||||
expect(w.removeNode('c').nodes).to.eql(['a', 'b']);
|
||||
it('removes multiply occurring nodes', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcb'.split('') });
|
||||
expect(w1.removeNode('b').nodes.join('')).to.eql('ac', 'multiple remove, linear');
|
||||
var w2 = iD.Way({ nodes: 'abcba'.split('') });
|
||||
expect(w2.removeNode('b').nodes.join('')).to.eql('aca', 'multiple remove, circular');
|
||||
});
|
||||
|
||||
it('preserves circularity', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b', 'c', 'd', 'a']});
|
||||
expect(w.removeNode('a').nodes).to.eql(['b', 'c', 'd', 'b']);
|
||||
it('eliminates duplicate consecutive nodes when removing along a linear way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abbcd'.split('') });
|
||||
expect(w1.removeNode('c').nodes.join('')).to.eql('abd', 'duplicate before');
|
||||
var w2 = iD.Way({ nodes: 'abcdd'.split('') });
|
||||
expect(w2.removeNode('c').nodes.join('')).to.eql('abd', 'duplicate after');
|
||||
var w3 = iD.Way({ nodes: 'abbcbb'.split('')});
|
||||
expect(w3.removeNode('c').nodes.join('')).to.eql('ab', 'duplicate before and after');
|
||||
});
|
||||
|
||||
it('prevents duplicate consecutive nodes when preserving circularity', function () {
|
||||
var w = iD.Way({nodes: ['a', 'b', 'c', 'd', 'b', 'a']});
|
||||
expect(w.removeNode('a').nodes).to.eql(['b', 'c', 'd', 'b']);
|
||||
it('eliminates duplicate consecutive nodes when removing internal nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abbcda'.split('') });
|
||||
expect(w1.removeNode('c').nodes.join('')).to.eql('abda', 'duplicate before');
|
||||
var w2 = iD.Way({ nodes: 'abcdda'.split('') });
|
||||
expect(w2.removeNode('c').nodes.join('')).to.eql('abda', 'duplicate after');
|
||||
var w3 = iD.Way({ nodes: 'abbcbba'.split('')});
|
||||
expect(w3.removeNode('c').nodes.join('')).to.eql('aba', 'duplicate before and after');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when removing adjacent to connecting nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcdaa'.split('') });
|
||||
expect(w1.removeNode('d').nodes.join('')).to.eql('abca', 'duplicate end connector');
|
||||
var w2 = iD.Way({ nodes: 'aabcda'.split('') });
|
||||
expect(w2.removeNode('b').nodes.join('')).to.eql('acda', 'duplicate beginning connector');
|
||||
});
|
||||
|
||||
it('eliminates duplicate consecutive nodes when removing connecting nodes along a circular way', function () {
|
||||
var w1 = iD.Way({ nodes: 'abcaa'.split('') });
|
||||
expect(w1.removeNode('a').nodes.join('')).to.eql('bcb', 'duplicate end connector');
|
||||
var w2 = iD.Way({ nodes: 'aabca'.split('') });
|
||||
expect(w2.removeNode('a').nodes.join('')).to.eql('bcb', 'duplicate beginning connector');
|
||||
var w3 = iD.Way({ nodes: 'aabcaa'.split('') });
|
||||
expect(w3.removeNode('a').nodes.join('')).to.eql('bcb', 'duplicate beginning and end connectors');
|
||||
var w4 = iD.Way({ nodes: 'aabaacaa'.split('') });
|
||||
expect(w4.removeNode('a').nodes.join('')).to.eql('bcb', 'duplicates multiple places');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ describe('iD.serviceNominatim', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
server = sinon.fakeServer.create();
|
||||
nominatim = iD.services.nominatim;
|
||||
nominatim = iD.services.geocoder;
|
||||
nominatim.reset();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user