Replace Entity.{lat,lon} with Entity.loc

Fixes #189
This commit is contained in:
John Firebaugh
2012-12-04 22:29:57 -05:00
parent ce4c6c4fec
commit 551a2df24e
12 changed files with 57 additions and 72 deletions

View File

@@ -61,12 +61,9 @@ iD.actions.changeTags = function(node, tags) {
// 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
iD.actions.move = function(entity, to) {
iD.actions.move = function(entity, loc) {
return function(graph) {
return graph.replace(entity.update({
lon: to.lon || to[0],
lat: to.lat || to[1]
}), 'moved an element');
return graph.replace(entity.update({loc: loc}), 'moved an element');
};
};

View File

@@ -1,11 +1,7 @@
iD.modes = {};
iD.modes._node = function(ll) {
return iD.Node({
lat: ll[1],
lon: ll[0],
tags: {}
});
return iD.Node({loc: ll});
};
@@ -129,9 +125,7 @@ iD.modes.DrawRoad = function(way_id, direction) {
function mousemove() {
var ll = this.map.projection.invert(d3.mouse(surface.node()));
var node = iD.Entity(this.history.graph().entity(nextnode_id), {
lon: ll[0], lat: ll[1]
});
var node = iD.Entity(this.history.graph().entity(nextnode_id), {loc: ll});
this.history.replace(iD.actions.addWayNode(way, node, index));
}
@@ -265,10 +259,7 @@ iD.modes.DrawArea = function(way_id) {
function mousemove() {
var ll = this.map.projection.invert(d3.mouse(surface.node()));
var node = iD.Entity(this.history.graph().entity(nextnode_id), {
lon: ll[0],
lat: ll[1]
});
var node = iD.Entity(this.history.graph().entity(nextnode_id), {loc: ll});
this.history.replace(iD.actions.addWayNode(way, node));
}

View File

@@ -62,8 +62,11 @@ iD.Connection = function() {
var v = obj.attributes[i].nodeValue;
o[n] = v;
}
if (o.lat) o.lat = parseFloat(o.lat);
if (o.lon) o.lon = parseFloat(o.lon);
if (o.lon && o.lat) {
o.loc = [parseFloat(o.lon), parseFloat(o.lat)];
delete o.lon;
delete o.lat;
}
o._id = o.id;
o.id = o.type[0] + o.id;
return iD.Entity(o);

View File

@@ -11,7 +11,7 @@ iD.format.GeoJSON = {
properties: entity.tags,
geometry: {
type: 'Point',
coordinates: [entity.lon, entity.lat]
coordinates: entity.loc
}
};
},
@@ -22,7 +22,7 @@ iD.format.GeoJSON = {
geometry: {
'type': 'LineString',
'coordinates': entity.nodes.map(function(node) {
return [node.lon, node.lat];
return node.loc;
})
}
};

View File

@@ -76,7 +76,8 @@ iD.format.XML = {
var r = {
node: {
'@id': entity.id.replace('n', ''),
'@lat': entity.lat, '@lon': entity.lon,
'@lon': entity.loc[0],
'@lat': entity.loc[1],
'@version': (entity.version || 0),
tag: _.map(entity.tags, function(v, k) {
return { keyAttributes: { k: k, v: v } };

View File

@@ -42,10 +42,10 @@ iD.Graph.prototype = {
},
nodeIntersect: function(entity, extent) {
return entity.lon > extent[0][0] &&
entity.lon < extent[1][0] &&
entity.lat < extent[0][1] &&
entity.lat > extent[1][1];
return entity.loc[0] > extent[0][0] &&
entity.loc[0] < extent[1][0] &&
entity.loc[1] < extent[0][1] &&
entity.loc[1] > extent[1][1];
},
wayIntersect: function(entity, extent) {
@@ -61,10 +61,10 @@ iD.Graph.prototype = {
var extent = [[-Infinity, Infinity], [Infinity, -Infinity]];
var w = way;
for (var j = 0, l = w.nodes.length; j < l; j++) {
if (w.nodes[j].lon > extent[0][0]) extent[0][0] = w.nodes[j].lon;
if (w.nodes[j].lon < extent[1][0]) extent[1][0] = w.nodes[j].lon;
if (w.nodes[j].lat < extent[0][1]) extent[0][1] = w.nodes[j].lat;
if (w.nodes[j].lat > extent[1][1]) extent[1][1] = w.nodes[j].lat;
if (w.nodes[j].loc[0] > extent[0][0]) extent[0][0] = w.nodes[j].loc[0];
if (w.nodes[j].loc[0] < extent[1][0]) extent[1][0] = w.nodes[j].loc[0];
if (w.nodes[j].loc[1] < extent[0][1]) extent[0][1] = w.nodes[j].loc[1];
if (w.nodes[j].loc[1] > extent[1][1]) extent[1][1] = w.nodes[j].loc[1];
}
way._extent = extent;
}

View File

@@ -18,7 +18,7 @@ iD.Map = function() {
dragbehavior = d3.behavior.drag()
.origin(function(entity) {
if (!dragEnabled) return { x: 0, y: 0 };
var p = projection(ll2a(entity));
var p = projection(entity.loc);
return { x: p[0], y: p[1] };
})
.on('drag', function(entity) {
@@ -47,7 +47,7 @@ iD.Map = function() {
}),
waydragbehavior = d3.behavior.drag()
.origin(function(entity) {
var p = projection(ll2a(entity.nodes[0]));
var p = projection(entity.nodes[0].loc);
return { x: p[0], y: p[1] };
})
.on('drag', function(entity) {
@@ -62,10 +62,9 @@ iD.Map = function() {
}
entity.nodes.forEach(function(node) {
var start = projection(ll2a(node));
var start = projection(node.loc);
var end = projection.invert([start[0] + d3.event.dx, start[1] + d3.event.dy]);
node.lon = end[0];
node.lat = end[1];
node.loc = end;
history.replace(iD.actions.move(node, end));
});
})
@@ -133,13 +132,12 @@ iD.Map = function() {
map.surface = surface;
}
function ll2a(o) { return [o.lon, o.lat]; }
function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
function classActive(d) { return d.id === selection; }
function getline(d) { return d._line; }
function key(d) { return d.id; }
function nodeline(d) {
return 'M' + d.nodes.map(ll2a).map(projection).map(iD.util.geo.roundCoords).join('L');
return 'M' + _.pluck(d.nodes, 'loc').map(projection).map(iD.util.geo.roundCoords).join('L');
}
function hideInspector() {
@@ -189,7 +187,8 @@ iD.Map = function() {
function accuracyHandles(way) {
var handles = [];
for (var i = 0; i < way.nodes.length - 1; i++) {
handles[i] = iD.Node(iD.util.geo.interp(way.nodes[i], way.nodes[i + 1], 0.5));
handles[i] = iD.Node();
handles[i].loc = iD.util.geo.interp(way.nodes[i].loc, way.nodes[i + 1].loc, 0.5);
handles[i].way = way.id;
handles[i].index = i + 1;
handles[i].accuracy = true;
@@ -210,7 +209,7 @@ iD.Map = function() {
.attr({ width: 6, height: 6, 'class': 'handle', 'xlink:href': 'css/handle.png' })
.call(dragbehavior);
handles.attr('transform', function(entity) {
var p = projection(ll2a(entity));
var p = projection(entity.loc);
return 'translate(' + [~~p[0], ~~p[1]] + ') translate(-3, -3) rotate(45, 3, 3)';
})
.classed('active', classActive)
@@ -225,7 +224,7 @@ iD.Map = function() {
.attr({ r: 2, 'class': 'accuracy-handle' })
.call(dragbehavior);
handles.attr('transform', function(entity) {
var p = projection(ll2a(entity));
var p = projection(entity.loc);
return 'translate(' + [~~p[0], ~~p[1]] + ')';
}).classed('active', classActive);
}
@@ -261,7 +260,7 @@ iD.Map = function() {
marker.append('image')
.attr({ width: 16, height: 16 });
markers.attr('transform', function(d) {
var pt = projection([d.lon, d.lat]);
var pt = projection(d.loc);
return 'translate(' + [~~pt[0], ~~pt[1]] + ') translate(-8, -8)';
})
.classed('active', classActive);

View File

@@ -79,10 +79,8 @@ iD.util.geo.roundCoords = function(c) {
};
iD.util.geo.interp = function(p1, p2, t) {
return {
lon: p1.lon + (p2.lon - p1.lon) * t,
lat: p1.lat + (p2.lat - p1.lat) * t
};
return [p1[0] + (p2[0] - p1[0]) * t,
p1[1] + (p2[1] - p1[1]) * t]
};
iD.util.geo.dist = function(a, b) {
@@ -91,16 +89,16 @@ iD.util.geo.dist = function(a, b) {
};
iD.util.geo.nodeIntersect = function(entity, extent) {
return entity.lon > extent[0][0] &&
entity.lon < extent[1][0] &&
entity.lat < extent[0][1] &&
entity.lat > extent[1][1];
return entity.loc[0] > extent[0][0] &&
entity.loc[0] < extent[1][0] &&
entity.loc[1] < extent[0][1] &&
entity.loc[1] > extent[1][1];
};
iD.util.geo.chooseIndex = function(way, point, map) {
var dist = iD.util.geo.dist;
var projNodes = way.nodes.map(function(n) {
return map.projection([n.lon, n.lat]);
return map.projection(n.loc);
});
for (var i = 0, changes = []; i < projNodes.length - 1; i++) {
changes[i] =

View File

@@ -2,7 +2,7 @@ describe('GeoJSON', function() {
describe('#mapping', function() {
it('should be able to map a node to geojson', function() {
expect(iD.format.GeoJSON.mapping({ type: 'node', lat: 38, lon: -77 }).geometry.type).to.equal('Point');
expect(iD.format.GeoJSON.mapping({ type: 'node', loc: [-77, 38] }).geometry.type).to.equal('Point');
});
it('should be able to map a way to geojson', function() {
var way = { type: 'way', nodes: [] };

View File

@@ -7,7 +7,7 @@ describe('XML', function() {
describe('#rep', function() {
it('converts a node to jxon', function() {
expect(iD.format.XML.rep({ id: 'n-1', type: 'node', lat: 38, lon: -77 }))
expect(iD.format.XML.rep({ id: 'n-1', type: 'node', loc: [-77, 38] }))
.to.eql({ node : { '@id': '-1', '@lat': 38, '@lon': -77, '@version': 0, tag: [ ] } });
});
it('converts a way to jxon', function() {
@@ -18,8 +18,8 @@ describe('XML', function() {
describe('#mapping', function() {
it('serializes a node to xml', function() {
expect(iD.format.XML.mapping({ id: 'n-1', type: 'node', lat: 38, lon: -77 }))
.to.equal('&lt;node id=&quot;-1&quot; lat=&quot;38&quot; lon=&quot;-77&quot; version=&quot;0&quot;/&gt;');
expect(iD.format.XML.mapping({ id: 'n-1', type: 'node', loc: [-77, 38] }))
.to.equal('&lt;node id=&quot;-1&quot; lon=&quot;-77&quot; lat=&quot;38&quot; version=&quot;0&quot;/&gt;');
});
it('serializes a way to xml', function() {

View File

@@ -4,8 +4,7 @@ describe('Graph', function() {
it('entity', function() {
var entities = { 'n-1': {
type: 'node',
lat: 30,
lon: -80,
loc: [-80, 30],
id: 'n-1'
}
};
@@ -23,8 +22,7 @@ describe('Graph', function() {
it('#remove', function() {
var entities = { 'n-1': {
type: 'node',
lat: 30,
lon: -80,
loc: [-80, 30],
id: 'n-1'
}
};
@@ -36,21 +34,19 @@ describe('Graph', function() {
it('#replace', function() {
var entities = { 'n-1': {
type: 'node',
lat: 30,
lon: -80,
loc: [-80, 30],
id: 'n-1'
}
};
var replacement = {
type: 'node',
lat: 40,
lon: -80,
loc: [-80, 40],
id: 'n-1'
};
var graph = iD.Graph(entities, 'first graph');
var g2 = graph.replace(replacement, 'Removed node');
expect(graph.entity('n-1').lat).to.equal(30);
expect(g2.entity('n-1').lat).to.equal(40);
expect(graph.entity('n-1').loc[1]).to.equal(30);
expect(g2.entity('n-1').loc[1]).to.equal(40);
});
});

View File

@@ -25,26 +25,26 @@ describe('Util', function() {
describe('geo', function() {
describe('#interp', function() {
it('interpolates halfway', function() {
var a = { lat: 0, lon: 0 },
b = { lat: 10, lon: 10 };
expect(iD.util.geo.interp(a, b, 0.5)).to.eql({ lat: 5, lon: 5});
var a = [0, 0],
b = [10, 10];
expect(iD.util.geo.interp(a, b, 0.5)).to.eql([5, 5]);
});
it('interpolates to one side', function() {
var a = { lat: 0, lon: 0 },
b = { lat: 10, lon: 10 };
expect(iD.util.geo.interp(a, b, 0)).to.eql({ lat: 0, lon: 0});
var a = [0, 0],
b = [10, 10];
expect(iD.util.geo.interp(a, b, 0)).to.eql([0, 0]);
});
});
describe('#nodeIntersect', function() {
it('correctly says that a node is in an extent', function() {
expect(iD.util.geo.nodeIntersect({
lat: 0, lon: 0
loc: [0, 0]
}, [[-180, 90],
[180, -90]])).to.be.true;
});
it('correctly says that a node is outside of an extent', function() {
expect(iD.util.geo.nodeIntersect({
lat: 0, lon: 0
loc: [0, 0]
}, [[100, 90],
[180, -90]])).to.be.false;
});