mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-29 07:06:04 +02:00
Split map rendering into some components
This commit is contained in:
+10
-1
@@ -30,12 +30,21 @@
|
||||
<script src='js/id/util.js'></script>
|
||||
<script src='js/id/oauth.js'></script>
|
||||
<script src='js/id/services/taginfo.js'></script>
|
||||
|
||||
<script src='js/id/renderer/style.js'></script>
|
||||
<script src='js/id/renderer/background.js'></script>
|
||||
<script src='js/id/renderer/background_source.js'></script>
|
||||
<script src='js/id/renderer/map.js'></script>
|
||||
<script src='js/id/renderer/hash.js'></script>
|
||||
<script src='js/id/renderer/points.js'></script>
|
||||
|
||||
<script src="js/id/svg.js"></script>
|
||||
<script src="js/id/svg/areas.js"></script>
|
||||
<script src="js/id/svg/lines.js"></script>
|
||||
<script src="js/id/svg/midpoints.js"></script>
|
||||
<script src="js/id/svg/points.js"></script>
|
||||
<script src="js/id/svg/vertices.js"></script>
|
||||
|
||||
<script src='js/id/ui/inspector.js'></script>
|
||||
<script src='js/id/ui/modal.js'></script>
|
||||
<script src='js/id/ui/confirm.js'></script>
|
||||
@@ -58,7 +67,7 @@
|
||||
<script src='js/id/actions/add_way.js'></script>
|
||||
<script src='js/id/actions/add_way_node.js'></script>
|
||||
<script src='js/id/actions/change_entity_tags.js'></script>
|
||||
<script src="js/id/actions/delete_node.js"></script>
|
||||
<script src='js/id/actions/delete_node.js'></script>
|
||||
<script src="js/id/actions/delete_way.js"></script>
|
||||
<script src='js/id/actions/move_node.js'></script>
|
||||
<script src='js/id/actions/move_way.js'></script>
|
||||
|
||||
+7
-191
@@ -15,7 +15,7 @@ iD.Map = function() {
|
||||
background = iD.Background()
|
||||
.projection(projection),
|
||||
transformProp = iD.util.prefixCSSProperty('Transform'),
|
||||
supersurface, surface, defs, tilegroup, r, g, alength;
|
||||
supersurface, surface, defs, tilegroup, r, g;
|
||||
|
||||
function map() {
|
||||
tilegroup = this.append('div')
|
||||
@@ -48,9 +48,6 @@ iD.Map = function() {
|
||||
return (mem[i] = r.append('g').attr('class', 'layer-g layer-' + i)) && mem;
|
||||
}, {});
|
||||
|
||||
var arrow = surface.append('text').text('►----');
|
||||
alength = arrow.node().getComputedTextLength();
|
||||
arrow.remove();
|
||||
map.size(this.size());
|
||||
map.surface = surface;
|
||||
|
||||
@@ -58,10 +55,6 @@ iD.Map = function() {
|
||||
}
|
||||
|
||||
function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
|
||||
function getline(d) { return d._line; }
|
||||
function nodeline(d) {
|
||||
return 'M' + _.pluck(d.nodes, 'loc').map(projection).map(iD.util.geo.roundCoords).join('L');
|
||||
}
|
||||
|
||||
function drawVector(difference) {
|
||||
if (surface.style(transformProp) != 'none') return;
|
||||
@@ -94,101 +87,12 @@ iD.Map = function() {
|
||||
if (all.length > 10000) return editOff();
|
||||
else editOn();
|
||||
|
||||
for (var i = 0; i < all.length; i++) {
|
||||
var entity = all[i];
|
||||
switch (entity.geometry()) {
|
||||
case 'line':
|
||||
entity._line = nodeline(entity);
|
||||
ways.push(entity);
|
||||
lines.push(entity);
|
||||
break;
|
||||
|
||||
case 'area':
|
||||
entity._line = nodeline(entity);
|
||||
ways.push(entity);
|
||||
areas.push(entity);
|
||||
break;
|
||||
|
||||
case 'point':
|
||||
points.push(entity);
|
||||
break;
|
||||
|
||||
case 'vertex':
|
||||
vertices.push(entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var parentStructure = graph.parentStructure(ways);
|
||||
var wayAccuracyHandles = [];
|
||||
for (i = 0; i < ways.length; i++) {
|
||||
accuracyHandles(ways[i], wayAccuracyHandles);
|
||||
}
|
||||
|
||||
drawVertices(vertices, parentStructure, filter);
|
||||
drawAccuracyHandles(wayAccuracyHandles, filter);
|
||||
drawCasings(lines, filter);
|
||||
drawFills(areas, filter);
|
||||
drawStrokes(lines, filter);
|
||||
drawPoints(points, filter);
|
||||
}
|
||||
|
||||
// updates handles by reference
|
||||
function accuracyHandles(way, handles) {
|
||||
for (var i = 0; i < way.nodes.length - 1; i++) {
|
||||
if (iD.util.geo.dist(way.nodes[i].loc, way.nodes[i + 1].loc) > 0.0001) {
|
||||
handles.push({
|
||||
loc: iD.util.geo.interp(way.nodes[i].loc, way.nodes[i + 1].loc, 0.5),
|
||||
way: way.id,
|
||||
index: i + 1,
|
||||
accuracy: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pointTransform(entity) {
|
||||
return 'translate(' + iD.util.geo.roundCoords(projection(entity.loc)) + ')';
|
||||
}
|
||||
|
||||
function drawVertices(vertices, parentStructure, filter) {
|
||||
function shared(d) { return parentStructure[d.id] > 1; }
|
||||
|
||||
var circles = g.hit.selectAll('g.vertex')
|
||||
.filter(filter)
|
||||
.data(vertices, iD.Entity.key);
|
||||
|
||||
circles.exit().remove();
|
||||
|
||||
var cg = circles.enter()
|
||||
.insert('g', ':first-child')
|
||||
.attr('class', 'node vertex');
|
||||
|
||||
cg.append('circle')
|
||||
.attr('class', 'stroke')
|
||||
.attr('r', 6);
|
||||
|
||||
cg.append('circle')
|
||||
.attr('class', 'fill')
|
||||
.attr('r', 4);
|
||||
|
||||
circles.attr('transform', pointTransform)
|
||||
.classed('shared', shared);
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (vertix entity) on the elements
|
||||
circles.select('circle.fill');
|
||||
circles.select('circle.stroke');
|
||||
}
|
||||
|
||||
function drawAccuracyHandles(waynodes, filter) {
|
||||
var handles = g.hit.selectAll('circle.accuracy-handle')
|
||||
.filter(filter)
|
||||
.data(waynodes, function (d) { return [d.way, d.index].join(","); });
|
||||
handles.exit().remove();
|
||||
handles.enter().append('circle')
|
||||
.attr({ r: 3, 'class': 'accuracy-handle' });
|
||||
handles.attr('transform', pointTransform);
|
||||
surface
|
||||
.call(iD.svg.Points(), graph, all, filter, projection)
|
||||
.call(iD.svg.Vertices(), graph, all, filter, projection)
|
||||
.call(iD.svg.Lines(), graph, all, filter, projection)
|
||||
.call(iD.svg.Areas(), graph, all, filter, projection)
|
||||
.call(iD.svg.Midpoints(), graph, all, filter, projection);
|
||||
}
|
||||
|
||||
function editOff() {
|
||||
@@ -197,94 +101,6 @@ iD.Map = function() {
|
||||
|
||||
function editOn() { }
|
||||
|
||||
function drawLines(data, filter, group, fixedClasses) {
|
||||
var lines = group.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(data, iD.Entity.key);
|
||||
|
||||
lines.exit().remove();
|
||||
|
||||
lines.enter().append('path')
|
||||
.attr('class', fixedClasses);
|
||||
|
||||
lines
|
||||
.order()
|
||||
.attr('d', getline)
|
||||
.call(iD.Style.styleClasses());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
function drawFills(areas, filter) {
|
||||
drawLines(areas, filter, g.fill, 'way area');
|
||||
}
|
||||
|
||||
function drawCasings(ways, filter) {
|
||||
drawLines(ways, filter, g.casing, 'way line casing');
|
||||
}
|
||||
|
||||
function drawPoints(points, filter) {
|
||||
var groups = g.hit.selectAll('g.point')
|
||||
.filter(filter)
|
||||
.data(points, iD.Entity.key);
|
||||
|
||||
groups.exit().remove();
|
||||
|
||||
var group = groups.enter().append('g')
|
||||
.attr('class', 'node point');
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'stroke')
|
||||
.attr({ r: 10 });
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'fill')
|
||||
.attr({ r: 10 });
|
||||
|
||||
group.append('image')
|
||||
.attr({ width: 16, height: 16 })
|
||||
.attr('transform', 'translate(-8, -8)');
|
||||
|
||||
groups.attr('transform', pointTransform);
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (point entity) on the element
|
||||
groups.select('image').attr('xlink:href', iD.Style.pointImage);
|
||||
}
|
||||
|
||||
function drawStrokes(ways, filter) {
|
||||
var strokes = drawLines(ways, filter, g.stroke, 'way line stroke');
|
||||
|
||||
// Determine the lengths of oneway paths
|
||||
var lengths = {},
|
||||
oneways = strokes.filter(function (d) { return d.isOneWay(); }).each(function(d) {
|
||||
lengths[d.id] = Math.floor(this.getTotalLength() / alength);
|
||||
}).data();
|
||||
|
||||
var uses = defs.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
uses.exit().remove();
|
||||
uses.enter().append('path');
|
||||
uses
|
||||
.attr('id', function(d) { return 'shadow-' + d.id; })
|
||||
.attr('d', getline);
|
||||
|
||||
var labels = g.text.selectAll('text')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
labels.exit().remove();
|
||||
var tp = labels.enter()
|
||||
.append('text').attr({ 'class': 'oneway', dy: 4 })
|
||||
.append('textPath').attr('class', 'textpath');
|
||||
g.text.selectAll('.textpath')
|
||||
.filter(filter)
|
||||
.attr('xlink:href', function(d, i) { return '#shadow-' + d.id; })
|
||||
.text(function(d) {
|
||||
return (new Array(Math.floor(lengths[d.id]))).join('►----');
|
||||
});
|
||||
}
|
||||
|
||||
function connectionLoad(err, result) {
|
||||
history.merge(result);
|
||||
redraw(Object.keys(result.entities));
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
iD.svg = {
|
||||
RoundProjection: function (projection) {
|
||||
return function (d) {
|
||||
return iD.util.geo.roundCoords(projection(d));
|
||||
}
|
||||
},
|
||||
|
||||
PointTransform: function (projection) {
|
||||
projection = iD.svg.RoundProjection(projection);
|
||||
return function (entity) {
|
||||
return 'translate(' + projection(entity.loc) + ')';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
iD.svg.Areas = function() {
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var areas = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry() === 'area') {
|
||||
areas.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
var lineStrings = {};
|
||||
|
||||
function lineString(entity) {
|
||||
return lineStrings[entity.id] || (lineStrings[entity.id] =
|
||||
'M' + _.pluck(entity.nodes, 'loc').map(iD.svg.RoundProjection(projection)).join('L'));
|
||||
}
|
||||
|
||||
function drawPaths(group, areas, filter, classes) {
|
||||
var paths = group.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(areas, iD.Entity.key);
|
||||
|
||||
paths.enter()
|
||||
.append('path')
|
||||
.attr('class', classes);
|
||||
|
||||
paths
|
||||
.order()
|
||||
.attr('d', lineString)
|
||||
.call(iD.Style.styleClasses());
|
||||
|
||||
paths.exit()
|
||||
.remove();
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
var fill = surface.select('.layer-fill'),
|
||||
paths = drawPaths(fill, areas, filter, 'way area');
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
iD.svg.Lines = function() {
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var arrow = surface.append('text').text('►----'),
|
||||
alength = arrow.node().getComputedTextLength();
|
||||
|
||||
arrow.remove();
|
||||
|
||||
var lines = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry() === 'line') {
|
||||
lines.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
var lineStrings = {};
|
||||
|
||||
function lineString(entity) {
|
||||
return lineStrings[entity.id] || (lineStrings[entity.id] =
|
||||
'M' + _.pluck(entity.nodes, 'loc').map(iD.svg.RoundProjection(projection)).join('L'));
|
||||
}
|
||||
|
||||
function drawPaths(group, lines, filter, classes) {
|
||||
var paths = group.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(lines, iD.Entity.key);
|
||||
|
||||
paths.enter()
|
||||
.append('path')
|
||||
.attr('class', classes);
|
||||
|
||||
paths
|
||||
.order()
|
||||
.attr('d', lineString)
|
||||
.call(iD.Style.styleClasses());
|
||||
|
||||
paths.exit()
|
||||
.remove();
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
var casing = surface.select('.layer-casing'),
|
||||
stroke = surface.select('.layer-stroke'),
|
||||
defs = surface.select('defs'),
|
||||
text = surface.select('.layer-text'),
|
||||
casings = drawPaths(casing, lines, filter, 'way line casing'),
|
||||
strokes = drawPaths(stroke, lines, filter, 'way line stroke');
|
||||
|
||||
// Determine the lengths of oneway paths
|
||||
var lengths = {},
|
||||
oneways = strokes.filter(function (d) { return d.isOneWay(); }).each(function(d) {
|
||||
lengths[d.id] = Math.floor(this.getTotalLength() / alength);
|
||||
}).data();
|
||||
|
||||
var uses = defs.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
|
||||
uses.enter()
|
||||
.append('path');
|
||||
|
||||
uses
|
||||
.attr('id', function(d) { return 'shadow-' + d.id; })
|
||||
.attr('d', lineString);
|
||||
|
||||
uses.exit()
|
||||
.remove();
|
||||
|
||||
var labels = text.selectAll('text')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
|
||||
var tp = labels.enter()
|
||||
.append('text')
|
||||
.attr({ 'class': 'oneway', dy: 4 })
|
||||
.append('textPath')
|
||||
.attr('class', 'textpath');
|
||||
|
||||
labels.exit().remove();
|
||||
|
||||
text.selectAll('.textpath')
|
||||
.filter(filter)
|
||||
.attr('xlink:href', function(d, i) { return '#shadow-' + d.id; })
|
||||
.text(function(d) {
|
||||
return (new Array(Math.floor(lengths[d.id]))).join('►----');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
iD.svg.Midpoints = function() {
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var midpoints = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
|
||||
if (entity.type !== 'way')
|
||||
continue;
|
||||
|
||||
for (var j = 0; j < entity.nodes.length - 1; j++) {
|
||||
if (iD.util.geo.dist(entity.nodes[j].loc, entity.nodes[j + 1].loc) > 0.0001) {
|
||||
midpoints.push({
|
||||
loc: iD.util.geo.interp(entity.nodes[j].loc, entity.nodes[j + 1].loc, 0.5),
|
||||
way: entity.id,
|
||||
index: j + 1,
|
||||
accuracy: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var handles = surface.select('.layer-hit').selectAll('circle.accuracy-handle')
|
||||
.filter(filter)
|
||||
.data(midpoints, function (d) { return [d.way, d.index].join(","); });
|
||||
|
||||
handles.enter()
|
||||
.append('circle')
|
||||
.attr({ r: 3, 'class': 'accuracy-handle' });
|
||||
|
||||
handles.attr('transform', iD.svg.PointTransform(projection));
|
||||
|
||||
handles.exit()
|
||||
.remove();
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
iD.svg.Points = function() {
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var points = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry() === 'point') {
|
||||
points.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
var groups = surface.select('.layer-hit').selectAll('g.point')
|
||||
.filter(filter)
|
||||
.data(points, iD.Entity.key);
|
||||
|
||||
var group = groups.enter()
|
||||
.append('g')
|
||||
.attr('class', 'node point');
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'stroke')
|
||||
.attr({ r: 10 });
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'fill')
|
||||
.attr({ r: 10 });
|
||||
|
||||
group.append('image')
|
||||
.attr({ width: 16, height: 16 })
|
||||
.attr('transform', 'translate(-8, -8)');
|
||||
|
||||
groups.attr('transform', iD.svg.PointTransform(projection));
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (point entity) on the element
|
||||
groups.select('image')
|
||||
.attr('xlink:href', iD.Style.pointImage);
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
iD.svg.Vertices = function() {
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var vertices = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry() === 'vertex') {
|
||||
vertices.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
var parentStructure = graph.parentStructure(vertices);
|
||||
|
||||
var groups = surface.select('.layer-hit').selectAll('g.vertex')
|
||||
.filter(filter)
|
||||
.data(vertices, iD.Entity.key);
|
||||
|
||||
var group = groups.enter()
|
||||
.insert('g', ':first-child')
|
||||
.attr('class', 'node vertex');
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'stroke')
|
||||
.attr('r', 6);
|
||||
|
||||
group.append('circle')
|
||||
.attr('class', 'fill')
|
||||
.attr('r', 4);
|
||||
|
||||
groups.attr('transform', iD.svg.PointTransform(projection))
|
||||
.classed('shared', function(d) { return parentStructure[d.id] > 1; });
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (vertix entity) on the elements
|
||||
groups.select('circle.fill');
|
||||
groups.select('circle.stroke');
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
};
|
||||
};
|
||||
@@ -39,6 +39,14 @@
|
||||
<script src='../js/id/renderer/hash.js'></script>
|
||||
<script src='../js/id/renderer/points.js'></script>
|
||||
<script src='../js/id/renderer/style.js'></script>
|
||||
|
||||
<script src="../js/id/svg.js"></script>
|
||||
<script src="../js/id/svg/areas.js"></script>
|
||||
<script src="../js/id/svg/lines.js"></script>
|
||||
<script src="../js/id/svg/midpoints.js"></script>
|
||||
<script src="../js/id/svg/points.js"></script>
|
||||
<script src="../js/id/svg/vertices.js"></script>
|
||||
|
||||
<script src='../js/id/ui/inspector.js'></script>
|
||||
<script src='../js/id/ui/commit.js'></script>
|
||||
<script src='../js/id/ui/loading.js'></script>
|
||||
|
||||
Reference in New Issue
Block a user