diff --git a/css/app.css b/css/app.css
index 55c3db3a1..9d9946040 100644
--- a/css/app.css
+++ b/css/app.css
@@ -98,9 +98,10 @@ table th {
#modebuttons button {
width:100px;
cursor:pointer;
+ display:inline-block;
background:#fff;
color:#555;
- font:bold 19px/30px 'Helvetica Neue';
+ font:bold 19px/30px 'Helvetica Neue', sans-serif;
border:0;
border-right:1px solid #222;
border-bottom:1px solid #222;
diff --git a/index.html b/index.html
index e8d2f9a7d..a379776cc 100755
--- a/index.html
+++ b/index.html
@@ -35,9 +35,9 @@
@@ -85,8 +85,8 @@
width: $(document).width(),
height: $(document).height()
});
- map.setZoom(18)
- .setCentre({ lat: 40.796, lon: -74.691 });
+ map.setZoom(19)
+ .setCentre({ lat: 40.7965621, lon: -74.4773184 });
// ----------------------------------------------------
// Data is loaded and app ready to go
diff --git a/js/iD/renderer/Map.js b/js/iD/renderer/Map.js
index ad82bbbf9..62344a131 100755
--- a/js/iD/renderer/Map.js
+++ b/js/iD/renderer/Map.js
@@ -16,7 +16,7 @@ iD.renderer.Map = function(obj) {
layers = {};
var tagclasses = [
- 'highway', 'railway', 'motorway', 'amenity', 'landuse', 'building'];
+ 'highway', 'railway', 'motorway', 'amenity', 'landuse', 'building', 'bridge'];
var linegen = d3.svg.line()
.x(function(d) { return projection(d)[0]; })
@@ -24,7 +24,8 @@ iD.renderer.Map = function(obj) {
var zoombehavior = d3.behavior.zoom()
.translate(projection.translate())
- .scale(projection.scale());
+ .scale(projection.scale())
+ .scaleExtent([256, 134217728]);
zoombehavior.on('zoom', redraw);
@@ -33,8 +34,9 @@ iD.renderer.Map = function(obj) {
.attr({ width: width, height: width })
.call(zoombehavior);
- var clip = surface.append('defs')
- .append('clipPath')
+ var defs = surface.append('defs');
+
+ var clipPath = defs.append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('id', 'clip-rect')
@@ -46,18 +48,16 @@ iD.renderer.Map = function(obj) {
container = surface.append('g')
.attr('clip-path', 'url(#clip)');
- var minlayer = -5, maxlayer = 5;
- for (var l = minlayer; l <= maxlayer; l++) {
- var r = container.append('g');
- layers[l] = {
- root: r,
- fill: r.append('g'),
- casing: r.append('g'),
- stroke: r.append('g'),
- text: r.append('g'),
- hit: r.append('g')
- };
- }
+ var r = container.append('g');
+
+ layers[0] = {
+ root: r,
+ fill: r.append('g'),
+ casing: r.append('g'),
+ stroke: r.append('g'),
+ text: r.append('g'),
+ hit: r.append('g')
+ };
var elastic = container.append('g');
@@ -77,21 +77,56 @@ iD.renderer.Map = function(obj) {
function key(d) { return d._id; }
- function classes(d) {
- var tags = d.tags;
- var c = [];
- function clean(x) {
- return tagclasses.indexOf(x) !== -1;
+ function classes(pre) {
+ return function(d) {
+ var tags = d.tags;
+ var c = [pre];
+ function clean(x) {
+ return tagclasses.indexOf(x) !== -1;
+ }
+ for (var k in tags) {
+ if (!clean(k)) continue;
+ c.push(k + '-' + tags[k]);
+ c.push(k);
+ }
+ if (selection.indexOf(d._id) !== -1) {
+ c.push('active');
+ }
+ return c.join(' ');
+ };
+ }
+
+ var icons = {
+ tourism: ['hotel'],
+ shop: [
+ 'convenience',
+ 'supermarket'],
+ amenity:
+ [
+ 'atm',
+ 'bank',
+ 'cafe',
+ 'pub',
+ 'place',
+ 'parking',
+ 'bicycle_parking',
+ 'pharmacy',
+ 'pharmacy',
+ 'police',
+ 'post_box',
+ 'recycling',
+ 'restaurant',
+ 'school',
+ 'taxi',
+ 'telephone']
+ };
+
+ function markerimage(d) {
+ for (var k in icons) {
+ if (d.tags[k] && icons[k].indexOf(d.tags[k]) !== -1) {
+ return 'icons/' + d.tags[k] + '.png';
+ }
}
- for (var k in tags) {
- if (!clean(k)) continue;
- c.push(k + '-' + tags[k]);
- c.push(k);
- }
- if (selection.indexOf(d._id) !== -1) {
- c.push('active');
- }
- return c.join(' ');
}
function selectClick(d) {
@@ -99,58 +134,67 @@ iD.renderer.Map = function(obj) {
drawVector();
}
+ function nodeline(d) {
+ return linegen(d.nodes);
+ }
+
+ var highway_stack = [
+ 'motorway',
+ 'motorway_link',
+ 'trunk',
+ 'trunk_link',
+ 'primary',
+ 'primary_link',
+ 'secondary',
+ 'tertiary',
+ 'unclassified',
+ 'residential',
+ 'service',
+ 'footway'
+ ];
+
+ function waystack(a, b) {
+ if (!a || !b) return 0;
+ if (a.tags.layer !== undefined && b.tags.layer !== undefined) {
+ return a.tags.layer - b.tags.layer;
+ }
+ if (a.tags.bridge) return 1;
+ if (b.tags.bridge) return -1;
+ var as = 0, bs = 0;
+ if (a.tags.highway && b.tags.highway) {
+ as -= highway_stack.indexOf(a.tags.highway);
+ bs -= highway_stack.indexOf(b.tags.highway);
+ }
+ return as - bs;
+ }
+
function drawVector() {
var all = connection.all();
var ways = all.filter(function(a) {
- return a.entityType === 'way' && !a.isClosed();
- });
+ return a.entityType === 'way' && !a.isClosed();
+ }),
+ areas = all.filter(function(a) {
+ return a.entityType === 'way' && a.isClosed();
+ }),
+ points = all.filter(function(a) {
+ return a.entityType === 'node';
+ });
- var areas = all.filter(function(a) {
- return a.entityType === 'way' && a.isClosed();
- });
-
- var fills = layers[0].fill.selectAll('path.area')
- .data(areas, key);
-
- fills.enter().append('path')
- .on('click', selectClick);
-
- fills.exit().remove();
-
- fills.attr('d', function(d) {
- return linegen(d.nodes);
- }).attr('class', function(d) {
- return 'area ' + classes(d);
- });
-
- var casings = layers[0].casing.selectAll('path.casing')
- .data(ways, key);
-
- casings.enter().append('path');
- casings.exit().remove();
- casings.attr('d', function(d) {
- return linegen(d.nodes);
- }).attr('class', function(d) {
- return 'casing ' + classes(d);
- });
-
- var strokes = layers[0].stroke.selectAll('path.stroke')
- .data(ways, key);
-
- strokes.enter().append('path')
- .attr('class', function(d) {
- return 'stroke ' + classes(d);
- })
- .on('click', selectClick);
-
- strokes.exit().remove();
-
- strokes.attr('d', function(d) {
- return linegen(d.nodes);
- }).attr('class', function(d) {
- return 'stroke ' + classes(d);
- });
+ var defpaths = defs.selectAll('path')
+ .data(ways, key),
+ fills = layers[0].fill.selectAll('path.area')
+ .data(areas, key),
+ casings = layers[0].casing.selectAll('use.casing')
+ .data(ways, key),
+ strokes = layers[0].stroke.selectAll('use.stroke')
+ .data(ways, key),
+ texts = layers[0].text.selectAll('text')
+ .data(ways.filter(function(w) {
+ return !!w.tags.name;
+ }), key),
+ markers = layers[0].hit.selectAll('image.marker')
+ .data(points, key);
var _id = selection[0];
var active_entity = all.filter(function(a) {
@@ -160,13 +204,62 @@ iD.renderer.Map = function(obj) {
var handles = layers[0].hit.selectAll('circle.handle')
.data(active_entity.length ? active_entity[0].nodes : [], key);
+ defpaths.exit().remove();
+ texts.exit().remove();
+ handles.exit().remove();
+ fills.exit().remove();
+ markers.exit().remove();
+ casings.exit().remove();
+ strokes.exit().remove();
+
+ defpaths.enter().append('path');
+
+ defpaths.attr('d', nodeline)
+ .attr('id', function(d) {
+ return 'd' + d._id;
+ });
+
+ function usehref(d) {
+ return '#d' + d._id;
+ }
+
+ fills.enter().append('path')
+ .on('click', selectClick);
+
+ fills.attr('d', nodeline)
+ .attr('class', classes('area'));
+
+ casings.enter().append('use');
+ casings.sort(waystack)
+ .attr('xlink:href', usehref)
+ .attr('class', classes('casing'));
+
+ strokes.enter().append('use')
+ .on('click', selectClick);
+
+ strokes.sort(waystack).attr('xlink:href', usehref)
+ .attr('class', classes('stroke'));
+
+ markers.enter().append('image');
+ markers.attr('class', classes('marker'))
+ .attr({ width: 16, height: 16 })
+ .attr('xlink:href', markerimage)
+ .attr('transform', function(d) {
+ return 'translate(' + projection(d) + ')';
+ });
+
+ var textems = texts.enter().append('text')
+ .attr('dy', 3);
+
+ textems.append('textPath')
+ .attr('xlink:href', usehref)
+ .attr('startOffset', '50%')
+ .text(function(d) { return d.tags.name; });
+
handles.enter().append('circle')
.attr('class', 'handle')
.attr('r', 5)
.on('click', selectClick);
-
- handles.exit().remove();
-
handles.attr('transform', function(d) {
return 'translate(' + projection(d) + ')';
});