diff --git a/css/app.css b/css/app.css
index a516b7bf5..287507d91 100644
--- a/css/app.css
+++ b/css/app.css
@@ -29,7 +29,7 @@ p {
font-size: x-small;
}
a:visited, a {
- color: black;
+ color: #345692;
}
input[type=text] {
@@ -155,6 +155,15 @@ table td {
background:#fff;
}
+.inspector-wrap h2 {
+ font: normal 20px/20px 'Helvetica';
+}
+
+.inspector-wrap a.permalink {
+ text-decoration:none;
+ font: normal 11px/20px 'Helvetica'
+}
+
.inspector thead th {
font-size:10px;
line-height:10px;
diff --git a/css/reset.css b/css/reset.css
new file mode 100644
index 000000000..e29c0f5f4
--- /dev/null
+++ b/css/reset.css
@@ -0,0 +1,48 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/index.html b/index.html
index 1c6247a8f..03ad9a5d4 100755
--- a/index.html
+++ b/index.html
@@ -3,6 +3,7 @@
iD
+
diff --git a/js/iD/Connection.js b/js/iD/Connection.js
index fd95f25b7..24e99d7ee 100755
--- a/js/iD/Connection.js
+++ b/js/iD/Connection.js
@@ -15,7 +15,7 @@ iD.Connection = function(apiURL) {
var connection = {};
function all() {
- return _.values(entities);
+ return d3.values(entities);
}
function assign(obj) {
@@ -26,7 +26,11 @@ iD.Connection = function(apiURL) {
if (!entities[obj.id]) {
entities[obj.id] = obj;
} else {
- entities[obj.id].nodes = obj.nodes;
+ /*
+ for (var n = 0; n < obj.nodes.length; n++) {
+ entities[obj.id].addNode(obj.nodes[n]);
+ }
+ */
}
} else if (obj.entityType === 'relation') {
if (!relations[obj.id]) relations[obj.id] = obj;
@@ -71,24 +75,21 @@ iD.Connection = function(apiURL) {
function getObjectsByBbox(extent) {
// summary: Find all drawable entities that are within a given bounding box.
// Each one is an array of entities.
- return _.filter(this.entities, function(e, id) {
+ return d3.values(entities).filter(function(e, id) {
return e.within(extent);
});
}
+ // Request data within the bbox from an external OSM server.
function loadFromAPI(box, callback) {
- // summary: Request data within the bbox from an external OSM server. Currently hardcoded
- // to use Overpass API (which has the relevant CORS headers).
loadFromURL('http://www.overpass-api.de/api/xapi?map?bbox=' +
[box[0][0], box[1][1], box[1][0], box[0][1]], callback);
}
function loadFromURL(url, callback) {
- // summary: Load all data from a given URL.
d3.xml(url, parse(callback));
}
- // Private functions to parse DOM created from XML file
function filterNodeName(n) {
return function(item) { return item.nodeName === n; };
}
@@ -102,11 +103,7 @@ iD.Connection = function(apiURL) {
}
function getAttribute(obj, name) {
- for (var i = 0; i < obj.attributes.length; i++) {
- if (obj.attributes[i].nodeName === name) {
- return obj.attributes[i].nodeValue;
- }
- }
+ return obj.attributes[name].nodeValue;
}
function getTags(obj) {
@@ -134,16 +131,20 @@ iD.Connection = function(apiURL) {
}
function getMembers(obj) {
- return _(obj.childNodes).chain()
- .filter(filterNodeName('member'))
- .map(function(item) {
- var id = getAttribute(item,'ref'),
- type = getAttribute(item,'type'),
- role = getAttribute(item,'role');
+ var members = [];
+ for (var i = 0; i < obj.childNodes.length; i++) {
+ if (obj.childNodes[i].nodeName !== 'member') continue;
- var obj = getOrCreate(id, type);
- return new iD.RelationMember(obj, role);
- }).value();
+ var item = obj.childNodes[i];
+ var id = item.attributes.ref.nodeValue,
+ type = item.attributes.type.nodeValue,
+ role = item.attributes.role.nodeValue;
+
+ var o = getOrCreate(id, type);
+ members.push(new iD.RelationMember(o, role));
+ }
+
+ return members;
}
function parse(callback) {
diff --git a/js/iD/Way.js b/js/iD/Way.js
index 1ddc9d775..acb350a70 100644
--- a/js/iD/Way.js
+++ b/js/iD/Way.js
@@ -19,14 +19,20 @@ iD.Way = function(connection, id, nodes, tags, loaded) {
this.tags = tags || {};
this.loaded = (loaded === undefined) ? true : loaded;
this.modified = this.id < 0;
- this.nodes = nodes || [];
+ this.nodes = [];
this.extent = {};
+
for (var i = 0; i < nodes.length; i++) {
- nodes[i].entity.addParent(this);
+ this.addNode(nodes[i]);
}
};
iD.Way.prototype = {
+ addNode: function(node) {
+ node.entity.addParent(this);
+ this.nodes.push(node);
+ return this;
+ },
// JOSM: http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/data/osm/Way.java#L466
isClosed: function() {
diff --git a/js/iD/renderer/Map.js b/js/iD/renderer/Map.js
index 40afd5e24..f7064ed4e 100755
--- a/js/iD/renderer/Map.js
+++ b/js/iD/renderer/Map.js
@@ -52,7 +52,13 @@ iD.Map = function(obj) {
var surface = d3.selectAll(obj.selector)
.append('svg')
.attr({ width: width, height: width })
- .call(zoombehavior);
+ .call(zoombehavior).on('dblclick', function() {
+ // TODO: round zooms
+ /*
+ var s = projection.scale();
+ projection.scale(Math.round(Math.max(Math.log(s) / Math.log(2) - 7, 0)));
+ */
+ });
var defs = surface.append('defs');
@@ -155,11 +161,6 @@ iD.Map = function(obj) {
d3.select('.inspector-wrap').datum(d).call(inspector);
}
- inspector.on('update', function(way, tags) {
- connection.entities[way.id].tags = tags;
- drawVector();
- });
-
function nodeline(d) {
return linegen(d.nodes);
}
@@ -321,7 +322,6 @@ iD.Map = function(obj) {
return coords;
}
-
function tileUrl(coord) {
var tmpl = 'http://ecn.t0.tiles.virtualearth.net/tiles/a$quadkey.jpeg?g=587&mkt=en-gb&n=z';
var u = '';
diff --git a/js/iD/ui/Inspector.js b/js/iD/ui/Inspector.js
index bf679c603..73cabd149 100644
--- a/js/iD/ui/Inspector.js
+++ b/js/iD/ui/Inspector.js
@@ -4,7 +4,21 @@ iD.Inspector = function(selection) {
function inspector(selection) {
// http://jsfiddle.net/7WQjr/
selection.each(function(d, i) {
- d3.select(this).selectAll('table,button').remove();
+ // TODO: there must be a better way to do this.
+ d3.select(this).node().innerHTML = '';
+
+ var head = d3.select(this)
+ .append('div')
+ .attr('class', 'head');
+
+ head.append('h2')
+ .text(iD.Util.friendlyName(d));
+
+ head.append('a')
+ .attr('class', 'permalink')
+ .attr('href', 'http://www.openstreetmap.org/browse/' +
+ d.entityType + '/' + d.id)
+ .text('#' + d.id);
var table = d3.select(this)
.append('table')