mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
add external imports to actions
This commit is contained in:
6
Makefile
6
Makefile
@@ -43,7 +43,7 @@ $(BUILDJS_TARGETS): $(BUILDJS_SOURCES) build.js
|
||||
|
||||
|
||||
MODULE_TARGETS = \
|
||||
js/lib/id/actions.js \
|
||||
js/lib/id/index.js \
|
||||
js/lib/id/behavior.js \
|
||||
js/lib/id/core.js \
|
||||
js/lib/id/geo.js \
|
||||
@@ -61,9 +61,9 @@ MODULE_TARGETS = \
|
||||
js/lib/id/util.js \
|
||||
js/lib/id/validations.js
|
||||
|
||||
js/lib/id/actions.js: $(shell find modules/actions -type f)
|
||||
js/lib/id/index.js: $(shell find modules/index.js -type f)
|
||||
@rm -f $@
|
||||
node_modules/.bin/rollup -f umd -n iD.actions modules/actions/index.js --no-strict -o $@
|
||||
node_modules/.bin/rollup -f umd -n iD modules/index.js --no-strict -o $@
|
||||
|
||||
js/lib/id/behavior.js: $(shell find modules/behavior -type f)
|
||||
@rm -f $@
|
||||
|
||||
3435
js/lib/id/index.js
Normal file
3435
js/lib/id/index.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
import { joinWays } from '../geo/index';
|
||||
export function AddMember(relationId, member, memberIndex) {
|
||||
return function(graph) {
|
||||
var relation = graph.entity(relationId);
|
||||
@@ -6,7 +7,7 @@ export function AddMember(relationId, member, memberIndex) {
|
||||
var members = relation.indexedMembers();
|
||||
members.push(member);
|
||||
|
||||
var joined = iD.geo.joinWays(members, graph);
|
||||
var joined = joinWays(members, graph);
|
||||
for (var i = 0; i < joined.length; i++) {
|
||||
var segment = joined[i];
|
||||
for (var j = 0; j < segment.length && segment.length >= 2; j++) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { edgeEqual } from '../geo/index';
|
||||
export function AddMidpoint(midpoint, node) {
|
||||
return function(graph) {
|
||||
graph = graph.replace(node.move(midpoint.loc));
|
||||
@@ -8,7 +9,7 @@ export function AddMidpoint(midpoint, node) {
|
||||
|
||||
parents.forEach(function(way) {
|
||||
for (var i = 0; i < way.nodes.length - 1; i++) {
|
||||
if (iD.geo.edgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
|
||||
if (edgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
|
||||
graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
|
||||
|
||||
// Add only one midpoint on doubled-back segments,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
export function Circularize(wayId, projection, maxAngle) {
|
||||
import { Node } from '../core/index';
|
||||
import { interp, euclideanDistance } from '../geo/index';
|
||||
|
||||
export function Circularize(wayId
|
||||
, projection, maxAngle) {
|
||||
maxAngle = (maxAngle || 20) * Math.PI / 180;
|
||||
|
||||
var action = function(graph) {
|
||||
@@ -12,8 +16,8 @@ export function Circularize(wayId, projection, maxAngle) {
|
||||
keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
|
||||
points = nodes.map(function(n) { return projection(n.loc); }),
|
||||
keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
|
||||
centroid = (points.length === 2) ? iD.geo.interp(points[0], points[1], 0.5) : d3.geom.polygon(points).centroid(),
|
||||
radius = d3.median(points, function(p) { return iD.geo.euclideanDistance(centroid, p); }),
|
||||
centroid = (points.length === 2) ? interp(points[0], points[1], 0.5) : d3.geom.polygon(points).centroid(),
|
||||
radius = d3.median(points, function(p) { return euclideanDistance(centroid, p); }),
|
||||
sign = d3.geom.polygon(points).area() > 0 ? 1 : -1,
|
||||
ids;
|
||||
|
||||
@@ -52,7 +56,7 @@ export function Circularize(wayId, projection, maxAngle) {
|
||||
}
|
||||
|
||||
// position this key node
|
||||
distance = iD.geo.euclideanDistance(centroid, keyPoints[i]);
|
||||
distance = euclideanDistance(centroid, keyPoints[i]);
|
||||
if (distance === 0) { distance = 1e-4; }
|
||||
keyPoints[i] = [
|
||||
centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
|
||||
@@ -92,7 +96,7 @@ export function Circularize(wayId, projection, maxAngle) {
|
||||
centroid[0] + Math.cos(angle) * radius,
|
||||
centroid[1] + Math.sin(angle) * radius]);
|
||||
|
||||
node = iD.Node({loc: loc});
|
||||
node = Node({loc: loc});
|
||||
graph = graph.replace(node);
|
||||
|
||||
nodes.splice(endNodeIndex + j, 0, node);
|
||||
@@ -166,7 +170,7 @@ export function Circularize(wayId, projection, maxAngle) {
|
||||
|
||||
// move interior nodes to the surface of the convex hull..
|
||||
for (var j = 1; j < indexRange; j++) {
|
||||
var point = iD.geo.interp(hull[i], hull[i+1], j / indexRange),
|
||||
var point = interp(hull[i], hull[i+1], j / indexRange),
|
||||
node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
|
||||
graph = graph.replace(node);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
|
||||
// https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
|
||||
//
|
||||
import { Node } from '../core/index';
|
||||
export function Disconnect(nodeId, newNodeId) {
|
||||
var wayIds;
|
||||
|
||||
@@ -21,7 +22,7 @@ export function Disconnect(nodeId, newNodeId) {
|
||||
|
||||
connections.forEach(function(connection) {
|
||||
var way = graph.entity(connection.wayID),
|
||||
newNode = iD.Node({id: newNodeId, loc: node.loc, tags: node.tags});
|
||||
newNode = Node({id: newNodeId, loc: node.loc, tags: node.tags});
|
||||
|
||||
graph = graph.replace(newNode);
|
||||
if (connection.index === 0 && way.isArea()) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { DeleteWay } from './delete_way';
|
||||
|
||||
// Join ways at the end node they share.
|
||||
//
|
||||
// This is the inverse of `iD.actions.Split`.
|
||||
@@ -8,6 +6,10 @@ import { DeleteWay } from './delete_way';
|
||||
// https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
|
||||
// https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
|
||||
//
|
||||
import { joinWays } from '../geo/index';
|
||||
import { interestingTag } from '../core/index';
|
||||
import { DeleteWay } from './delete_way';
|
||||
|
||||
export function Join(ids) {
|
||||
|
||||
function groupEntitiesByGeometry(graph) {
|
||||
@@ -27,7 +29,7 @@ export function Join(ids) {
|
||||
}
|
||||
}
|
||||
|
||||
var joined = iD.geo.joinWays(ways, graph)[0];
|
||||
var joined = joinWays(ways, graph)[0];
|
||||
|
||||
survivor = survivor.update({nodes: _.map(joined.nodes, 'id')});
|
||||
graph = graph.replace(survivor);
|
||||
@@ -54,7 +56,7 @@ export function Join(ids) {
|
||||
if (ids.length < 2 || ids.length !== geometries.line.length)
|
||||
return 'not_eligible';
|
||||
|
||||
var joined = iD.geo.joinWays(ids.map(graph.entity, graph), graph);
|
||||
var joined = joinWays(ids.map(graph.entity, graph), graph);
|
||||
if (joined.length > 1)
|
||||
return 'not_adjacent';
|
||||
|
||||
@@ -73,7 +75,7 @@ export function Join(ids) {
|
||||
for (var k in way.tags) {
|
||||
if (!(k in tags)) {
|
||||
tags[k] = way.tags[k];
|
||||
} else if (tags[k] && iD.interestingTag(k) && tags[k] !== way.tags[k]) {
|
||||
} else if (tags[k] && interestingTag(k) && tags[k] !== way.tags[k]) {
|
||||
conflicting = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { joinWays, polygonContainsPolygon } from '../geo/index';
|
||||
import { Relation } from '../core/index';
|
||||
|
||||
export function MergePolygon(ids, newRelationId) {
|
||||
|
||||
function groupEntities(graph) {
|
||||
@@ -25,7 +28,7 @@ export function MergePolygon(ids, newRelationId) {
|
||||
// Each element is itself an array of objects with an id property, and has a
|
||||
// locs property which is an array of the locations forming the polygon.
|
||||
var polygons = entities.multipolygon.reduce(function(polygons, m) {
|
||||
return polygons.concat(iD.geo.joinWays(m.members, graph));
|
||||
return polygons.concat(joinWays(m.members, graph));
|
||||
}, []).concat(entities.closedWay.map(function(d) {
|
||||
var member = [{id: d.id}];
|
||||
member.nodes = graph.childNodes(d);
|
||||
@@ -38,7 +41,7 @@ export function MergePolygon(ids, newRelationId) {
|
||||
var contained = polygons.map(function(w, i) {
|
||||
return polygons.map(function(d, n) {
|
||||
if (i === n) return null;
|
||||
return iD.geo.polygonContainsPolygon(
|
||||
return polygonContainsPolygon(
|
||||
_.map(d.nodes, 'loc'),
|
||||
_.map(w.nodes, 'loc'));
|
||||
});
|
||||
@@ -79,7 +82,7 @@ export function MergePolygon(ids, newRelationId) {
|
||||
|
||||
// Move all tags to one relation
|
||||
var relation = entities.multipolygon[0] ||
|
||||
iD.Relation({ id: newRelationId, tags: { type: 'multipolygon' }});
|
||||
Relation({ id: newRelationId, tags: { type: 'multipolygon' }});
|
||||
|
||||
entities.multipolygon.slice(1).forEach(function(m) {
|
||||
relation = relation.mergeTags(m.tags);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DeleteMultiple } from './delete_multiple';
|
||||
import { Entity } from '../core/index';
|
||||
|
||||
export function MergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
|
||||
var option = 'safe', // 'safe', 'force_local', 'force_remote'
|
||||
@@ -96,14 +97,14 @@ export function MergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
|
||||
updates.replacements.push(remote);
|
||||
|
||||
} else if (option === 'force_local' && local) {
|
||||
target = iD.Entity(local);
|
||||
target = Entity(local);
|
||||
if (remote) {
|
||||
target = target.update({ version: remote.version });
|
||||
}
|
||||
updates.replacements.push(target);
|
||||
|
||||
} else if (option === 'safe' && local && remote && local.version !== remote.version) {
|
||||
target = iD.Entity(local, { version: remote.version });
|
||||
target = Entity(local, { version: remote.version });
|
||||
if (remote.visible) {
|
||||
target = mergeLocation(remote, target);
|
||||
} else {
|
||||
@@ -201,7 +202,7 @@ export function MergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
|
||||
base = graph.base().entities[id],
|
||||
local = localGraph.entity(id),
|
||||
remote = remoteGraph.entity(id),
|
||||
target = iD.Entity(local, { version: remote.version });
|
||||
target = Entity(local, { version: remote.version });
|
||||
|
||||
// delete/undelete
|
||||
if (!remote.visible) {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
// https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
|
||||
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
|
||||
import {
|
||||
angle as getAngle,
|
||||
sphericalDistance,
|
||||
chooseEdge,
|
||||
pathLength,
|
||||
interp,
|
||||
pathIntersections
|
||||
} from '../geo/index';
|
||||
import { Node } from '../core/index';
|
||||
|
||||
export function Move(moveIds, tryDelta, projection, cache) {
|
||||
var delta = tryDelta;
|
||||
|
||||
@@ -114,7 +124,7 @@ export function Move(moveIds, tryDelta, projection, cache) {
|
||||
var key = wayId + '_' + nodeId,
|
||||
orig = cache.replacedVertex[key];
|
||||
if (!orig) {
|
||||
orig = iD.Node();
|
||||
orig = Node();
|
||||
cache.replacedVertex[key] = orig;
|
||||
cache.startLoc[orig.id] = cache.startLoc[nodeId];
|
||||
}
|
||||
@@ -128,21 +138,21 @@ export function Move(moveIds, tryDelta, projection, cache) {
|
||||
}
|
||||
orig = orig.move(end);
|
||||
|
||||
var angle = Math.abs(iD.geo.angle(orig, prev, projection) -
|
||||
iD.geo.angle(orig, next, projection)) * 180 / Math.PI;
|
||||
var angle = Math.abs(getAngle(orig, prev, projection) -
|
||||
getAngle(orig, next, projection)) * 180 / Math.PI;
|
||||
|
||||
// Don't add orig vertex if it would just make a straight line..
|
||||
if (angle > 175 && angle < 185) return graph;
|
||||
|
||||
// Don't add orig vertex if another point is already nearby (within 10m)
|
||||
if (iD.geo.sphericalDistance(prev.loc, orig.loc) < 10 ||
|
||||
iD.geo.sphericalDistance(orig.loc, next.loc) < 10) return graph;
|
||||
if (sphericalDistance(prev.loc, orig.loc) < 10 ||
|
||||
sphericalDistance(orig.loc, next.loc) < 10) return graph;
|
||||
|
||||
// moving forward or backward along way?
|
||||
var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
|
||||
p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
|
||||
d1 = iD.geo.pathLength(p1),
|
||||
d2 = iD.geo.pathLength(p2),
|
||||
d1 = pathLength(p1),
|
||||
d2 = pathLength(p2),
|
||||
insertAt = (d1 < d2) ? movedIndex : nextIndex;
|
||||
|
||||
// moving around closed loop?
|
||||
@@ -169,17 +179,17 @@ export function Move(moveIds, tryDelta, projection, cache) {
|
||||
if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
|
||||
if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
|
||||
|
||||
var edge1 = !isEP1 && iD.geo.chooseEdge(nodes1, projection(vertex.loc), projection),
|
||||
edge2 = !isEP2 && iD.geo.chooseEdge(nodes2, projection(vertex.loc), projection),
|
||||
var edge1 = !isEP1 && chooseEdge(nodes1, projection(vertex.loc), projection),
|
||||
edge2 = !isEP2 && chooseEdge(nodes2, projection(vertex.loc), projection),
|
||||
loc;
|
||||
|
||||
// snap vertex to nearest edge (or some point between them)..
|
||||
if (!isEP1 && !isEP2) {
|
||||
var epsilon = 1e-4, maxIter = 10;
|
||||
for (var i = 0; i < maxIter; i++) {
|
||||
loc = iD.geo.interp(edge1.loc, edge2.loc, 0.5);
|
||||
edge1 = iD.geo.chooseEdge(nodes1, projection(loc), projection);
|
||||
edge2 = iD.geo.chooseEdge(nodes2, projection(loc), projection);
|
||||
loc = interp(edge1.loc, edge2.loc, 0.5);
|
||||
edge1 = chooseEdge(nodes1, projection(loc), projection);
|
||||
edge2 = chooseEdge(nodes2, projection(loc), projection);
|
||||
if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
|
||||
}
|
||||
} else if (!isEP1) {
|
||||
@@ -227,11 +237,11 @@ export function Move(moveIds, tryDelta, projection, cache) {
|
||||
function(loc) { return vecAdd(projection(loc), delta); }),
|
||||
unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
|
||||
unmovedPath = _.map(_.map(unmovedNodes, 'loc'), projection),
|
||||
hits = iD.geo.pathIntersections(movedPath, unmovedPath);
|
||||
hits = pathIntersections(movedPath, unmovedPath);
|
||||
|
||||
for (var i = 0; i < hits.length; i++) {
|
||||
if (_.isEqual(hits[i], end)) continue;
|
||||
var edge = iD.geo.chooseEdge(unmovedNodes, end, projection);
|
||||
var edge = chooseEdge(unmovedNodes, end, projection);
|
||||
delta = vecSub(projection(edge.loc), start);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DeleteNode } from './delete_node';
|
||||
|
||||
import { euclideanDistance } from '../geo/index';
|
||||
/*
|
||||
* Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
|
||||
*/
|
||||
@@ -86,7 +86,7 @@ export function Orthogonalize(wayId, projection) {
|
||||
q = subtractPoints(c, b),
|
||||
scale, dotp;
|
||||
|
||||
scale = 2 * Math.min(iD.geo.euclideanDistance(p, [0, 0]), iD.geo.euclideanDistance(q, [0, 0]));
|
||||
scale = 2 * Math.min(euclideanDistance(p, [0, 0]), euclideanDistance(q, [0, 0]));
|
||||
p = normalizePoint(p, 1.0);
|
||||
q = normalizePoint(q, 1.0);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Split } from './split';
|
||||
|
||||
import { inferRestriction } from '../geo/index';
|
||||
import { Relation, Way } from '../core/index';
|
||||
// Create a restriction relation for `turn`, which must have the following structure:
|
||||
//
|
||||
// {
|
||||
@@ -14,7 +15,7 @@ import { Split } from './split';
|
||||
// (The action does not check that these entities form a valid intersection.)
|
||||
//
|
||||
// If `restriction` is not provided, it is automatically determined by
|
||||
// iD.geo.inferRestriction.
|
||||
// inferRestriction.
|
||||
//
|
||||
// If necessary, the `from` and `to` ways are split. In these cases, `from.node`
|
||||
// and `to.node` are used to determine which portion of the split ways become
|
||||
@@ -35,7 +36,7 @@ export function RestrictTurn(turn, projection, restrictionId) {
|
||||
}
|
||||
|
||||
function split(toOrFrom) {
|
||||
var newID = toOrFrom.newID || iD.Way().id;
|
||||
var newID = toOrFrom.newID || Way().id;
|
||||
graph = Split(via.id, [newID])
|
||||
.limitWays([toOrFrom.way])(graph);
|
||||
|
||||
@@ -68,12 +69,12 @@ export function RestrictTurn(turn, projection, restrictionId) {
|
||||
to = split(turn.to)[0];
|
||||
}
|
||||
|
||||
return graph.replace(iD.Relation({
|
||||
return graph.replace(Relation({
|
||||
id: restrictionId,
|
||||
tags: {
|
||||
type: 'restriction',
|
||||
restriction: turn.restriction ||
|
||||
iD.geo.inferRestriction(
|
||||
inferRestriction(
|
||||
graph,
|
||||
turn.from,
|
||||
turn.via,
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { AddMember } from './add_member';
|
||||
import { sphericalDistance, isSimpleMultipolygonOuterMember} from '../geo/index';
|
||||
import { wrap as Wrap } from '../util/index';
|
||||
import { Way, Relation } from '../core/index';
|
||||
|
||||
// Split a way at the given node.
|
||||
//
|
||||
// Optionally, split only the given ways, if multiple ways share
|
||||
@@ -34,11 +38,11 @@ export function Split(nodeId, newWayIds) {
|
||||
idxB;
|
||||
|
||||
function wrap(index) {
|
||||
return iD.util.wrap(index, nodes.length);
|
||||
return Wrap(index, nodes.length);
|
||||
}
|
||||
|
||||
function dist(nA, nB) {
|
||||
return iD.geo.sphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
|
||||
return sphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
|
||||
}
|
||||
|
||||
// calculate lengths
|
||||
@@ -68,11 +72,11 @@ export function Split(nodeId, newWayIds) {
|
||||
}
|
||||
|
||||
function split(graph, wayA, newWayId) {
|
||||
var wayB = iD.Way({id: newWayId, tags: wayA.tags}),
|
||||
var wayB = Way({id: newWayId, tags: wayA.tags}),
|
||||
nodesA,
|
||||
nodesB,
|
||||
isArea = wayA.isArea(),
|
||||
isOuter = iD.geo.isSimpleMultipolygonOuterMember(wayA, graph);
|
||||
isOuter = isSimpleMultipolygonOuterMember(wayA, graph);
|
||||
|
||||
if (wayA.isClosed()) {
|
||||
var nodes = wayA.nodes.slice(0, -1),
|
||||
@@ -123,7 +127,7 @@ export function Split(nodeId, newWayIds) {
|
||||
});
|
||||
|
||||
if (!isOuter && isArea) {
|
||||
var multipolygon = iD.Relation({
|
||||
var multipolygon = Relation({
|
||||
tags: _.extend({}, wayA.tags, {type: 'multipolygon'}),
|
||||
members: [
|
||||
{id: wayA.id, role: 'outer', type: 'way'},
|
||||
|
||||
5
modules/index.js
Normal file
5
modules/index.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import * as actions from './actions/index';
|
||||
|
||||
export {
|
||||
actions
|
||||
};
|
||||
@@ -41,7 +41,7 @@
|
||||
<script src='../js/lib/osmauth.js'></script>
|
||||
|
||||
<script src='../js/id/id.js'></script>
|
||||
<script src='../js/lib/id/actions.js'></script>
|
||||
<script src='../js/lib/id/index.js'></script>
|
||||
<script src='../js/lib/id/core.js'></script>
|
||||
<script src='../js/lib/id/behavior.js'></script>
|
||||
<script src='../js/lib/id/geo.js'></script>
|
||||
|
||||
Reference in New Issue
Block a user