mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-23 16:49:40 +02:00
Use scope and don't bind in connection.
This commit is contained in:
@@ -53,7 +53,6 @@ require(["dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/dom","dojo/Evented
|
||||
width: dom.byId('map').offsetWidth,
|
||||
height: dom.byId('map').offsetHeight
|
||||
});
|
||||
conn.registerMap(map);
|
||||
map.ruleset = ruleset;
|
||||
|
||||
// Initialise controller
|
||||
|
||||
+147
-173
@@ -7,68 +7,65 @@
|
||||
|
||||
if (typeof iD === 'undefined') iD = {};
|
||||
iD.Connection = function(apiURL) {
|
||||
// summary: The data store, including methods to fetch data from (and, eventually, save data to)
|
||||
// an OSM API server.
|
||||
this.nextNode = -1; // next negative ids
|
||||
this.nextWay = -1; // |
|
||||
this.nextRelation = -1; // |
|
||||
this.nodes={};
|
||||
this.ways={};
|
||||
this.relations= {};
|
||||
this.pois = {};
|
||||
this.maps=[];
|
||||
this.modified=false;
|
||||
this.apiBaseURL=apiURL;
|
||||
this.callback = null;
|
||||
};
|
||||
// summary: The data store, including methods to fetch data from (and, eventually, save data to)
|
||||
// an OSM API server.
|
||||
var nextNode = -1, // next negative ids
|
||||
nextWay = -1, // |
|
||||
nextRelation = -1, // |
|
||||
nodes = {},
|
||||
ways = {},
|
||||
relations = {},
|
||||
pois = {},
|
||||
modified = false,
|
||||
apiBaseURL = apiURL;
|
||||
|
||||
iD.Connection.prototype = {
|
||||
_assign:function(obj) {
|
||||
// summary: Save an entity to the data store.
|
||||
switch (obj.entityType) {
|
||||
case "node": this.nodes[obj.id]=obj; break;
|
||||
case "way": this.ways[obj.id]=obj; break;
|
||||
case "relation": this.relations[obj.id]=obj; break;
|
||||
}
|
||||
},
|
||||
var connection = {};
|
||||
|
||||
_getOrCreate:function(id,type) {
|
||||
// summary: Return an entity if it exists: if not, create an empty one with the given id, and return that.
|
||||
switch (type) {
|
||||
case "node":
|
||||
if (!this.nodes[id]) this._assign(new iD.Node(this, id, NaN, NaN, {}, false));
|
||||
return this.nodes[id];
|
||||
case "way":
|
||||
if (!this.ways[id]) this._assign(new iD.Way(this, id, [], {}, false));
|
||||
return this.ways[id];
|
||||
case "relation":
|
||||
if (!this.relations[id]) this._assign(new iD.Relation(this, id, [], {}, false));
|
||||
return this.relations[id];
|
||||
}
|
||||
},
|
||||
function assign(obj) {
|
||||
// summary: Save an entity to the data store.
|
||||
switch (obj.entityType) {
|
||||
case "node": nodes[obj.id]=obj; break;
|
||||
case "way": ways[obj.id]=obj; break;
|
||||
case "relation": relations[obj.id]=obj; break;
|
||||
}
|
||||
}
|
||||
|
||||
doCreateNode:function(tags, lat, lon, perform) {
|
||||
// summary: Create a new node and save it in the data store, using an undo stack.
|
||||
var node = new iD.Node(this, this.nextNode--, lat, lon, tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(node, _.bind(this._assign, this) ));
|
||||
return node; // iD.Node
|
||||
},
|
||||
function getOrCreate(id, type) {
|
||||
// summary: Return an entity if it exists: if not, create an empty one with the given id, and return that.
|
||||
if (type === 'node') {
|
||||
if (!nodes[id]) assign(new iD.Node(connection, id, NaN, NaN, {}, false));
|
||||
return nodes[id];
|
||||
} else if (type === 'way') {
|
||||
if (!ways[id]) assign(new iD.Way(connection, id, [], {}, false));
|
||||
return ways[id];
|
||||
} else if (type === 'relation') {
|
||||
if (!relations[id]) assign(new iD.Relation(connection, id, [], {}, false));
|
||||
return relations[id];
|
||||
}
|
||||
}
|
||||
|
||||
doCreateWay:function(tags, nodes, perform) {
|
||||
// summary: Create a new way and save it in the data store, using an undo stack.
|
||||
var way = new iD.Way(this, this.nextWay--, nodes.concat(), tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(way, _.bind(this._assign, this) ));
|
||||
return way;
|
||||
},
|
||||
function doCreateNode(tags, lat, lon, perform) {
|
||||
// summary: Create a new node and save it in the data store, using an undo stack.
|
||||
var node = new iD.Node(connection, nextNode--, lat, lon, tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(node, assign));
|
||||
return node; // iD.Node
|
||||
}
|
||||
|
||||
doCreateRelation:function(tags, members, perform) {
|
||||
// summary: Create a new relation and save it in the data store, using an undo stack.
|
||||
var relation = new iD.Relation(this, this.nextRelation--, members.concat(), tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(relation, _.bind(this._assign, this) ));
|
||||
return relation;
|
||||
},
|
||||
function doCreateWay(tags, nodes, perform) {
|
||||
// summary: Create a new way and save it in the data store, using an undo stack.
|
||||
var way = new iD.Way(connection, nextWay--, nodes.concat(), tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(way, assign));
|
||||
return way;
|
||||
}
|
||||
|
||||
getObjectsByBbox:function(left,right,top,bottom) {
|
||||
function doCreateRelation(tags, members, perform) {
|
||||
// summary: Create a new relation and save it in the data store, using an undo stack.
|
||||
var relation = new iD.Relation(connection, nextRelation--, members.concat(), tags, true);
|
||||
perform(new iD.actions.CreateEntityAction(relation, assign));
|
||||
return relation;
|
||||
}
|
||||
|
||||
function getObjectsByBbox(left,right,top,bottom) {
|
||||
// summary: Find all drawable entities that are within a given bounding box.
|
||||
// returns: Object An object with four properties: .poisInside, .poisOutside, .waysInside, .waysOutside.
|
||||
// Each one is an array of entities.
|
||||
@@ -78,162 +75,139 @@ iD.Connection.prototype = {
|
||||
waysInside: [],
|
||||
waysOutside: []
|
||||
};
|
||||
for (var id in this.ways) {
|
||||
var way = this.ways[id];
|
||||
for (var id in ways) {
|
||||
var way = ways[id];
|
||||
if (way.within(left,right,top,bottom)) { o.waysInside.push(way); }
|
||||
else { o.waysOutside.push(way); }
|
||||
}
|
||||
_.each(this.pois, function(node) {
|
||||
_.each(pois, function(node) {
|
||||
if (node.within(left,right,top,bottom)) { o.poisInside.push(node); }
|
||||
else { o.poisOutside.push(node); }
|
||||
});
|
||||
return o;
|
||||
},
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// Redraw handling
|
||||
// ------------
|
||||
// POI handling
|
||||
function updatePOIs(nodelist) {
|
||||
// summary: Update the list of POIs (nodes not in ways) from a supplied array of nodes.
|
||||
_.each(nodelist, function(node) {
|
||||
if (node.entity.hasParentWays()) {
|
||||
delete pois[node._id];
|
||||
} else {
|
||||
pois[node._id] = node;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registerMap:function(map) {
|
||||
// summary: Record that a Map object wants updates from this Connection.
|
||||
this.maps.push(map);
|
||||
},
|
||||
function getPOIs() {
|
||||
// summary: Return a list of all the POIs in connection Connection.
|
||||
return _.values(pois);
|
||||
}
|
||||
|
||||
refreshMaps:function() {
|
||||
// summary: Redraw all the Map objects that take data from this Connection.
|
||||
_.each(this.maps, function(map) {
|
||||
map.updateUIs(false,true);
|
||||
});
|
||||
},
|
||||
function registerPOI(node) {
|
||||
// summary: Register a node as a POI (not in a way).
|
||||
pois[node._id] = node;
|
||||
}
|
||||
|
||||
refreshEntity: function(entity) {
|
||||
// summary: Redraw a particular entity on all the Map objects that take data from this Connection.
|
||||
_.each(this.maps, function(map) {
|
||||
map.refreshUI(entity);
|
||||
});
|
||||
},
|
||||
function unregisterPOI(node) {
|
||||
// summary: Mark a node as no longer being a POI (it's now in a way).
|
||||
delete pois[node._id];
|
||||
}
|
||||
|
||||
// ------------
|
||||
// POI handling
|
||||
updatePOIs:function(nodelist) {
|
||||
// summary: Update the list of POIs (nodes not in ways) from a supplied array of nodes.
|
||||
for (var i in nodelist) {
|
||||
if (nodelist[i].entity.hasParentWays()) {
|
||||
delete this.pois[nodelist[i]._id];
|
||||
} else {
|
||||
this.pois[nodelist[i]._id] = nodelist[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
// ----------
|
||||
// OSM parser
|
||||
|
||||
getPOIs:function() {
|
||||
// summary: Return a list of all the POIs in this Connection.
|
||||
return _.values(this.pois);
|
||||
},
|
||||
|
||||
registerPOI:function(node) {
|
||||
// summary: Register a node as a POI (not in a way).
|
||||
this.pois[node._id] = node;
|
||||
},
|
||||
|
||||
unregisterPOI:function(node) {
|
||||
// summary: Mark a node as no longer being a POI (it's now in a way).
|
||||
delete this.pois[node._id];
|
||||
},
|
||||
|
||||
// ----------
|
||||
// OSM parser
|
||||
|
||||
loadFromAPI: function(box) {
|
||||
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).
|
||||
this.loadFromURL("http://www.overpass-api.de/api/xapi?map?bbox=" + [box.west, box.south, box.east, box.north]);
|
||||
},
|
||||
loadFromURL("http://www.overpass-api.de/api/xapi?map?bbox=" +
|
||||
[box.west, box.south, box.east, box.north], callback);
|
||||
}
|
||||
|
||||
loadFromURL: function(url) {
|
||||
// summary: Load all data from a given URL.
|
||||
$.ajax({
|
||||
function loadFromURL(url, callback) {
|
||||
// summary: Load all data from a given URL.
|
||||
$.ajax({
|
||||
url: url,
|
||||
context: this,
|
||||
headers: { "X-Requested-With": null },
|
||||
success: this._processOSM
|
||||
success: parse(callback)
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_processOSM:function(dom) {
|
||||
var nodelist = [];
|
||||
for (var i in dom.childNodes[0].childNodes) {
|
||||
var obj = dom.childNodes[0].childNodes[i];
|
||||
switch(obj.nodeName) {
|
||||
|
||||
case "node":
|
||||
var node = new iD.Node(this,
|
||||
function parse(callback) {
|
||||
return function(dom) {
|
||||
var nodelist = _.compact(_.map(dom.childNodes[0].childNodes, function(obj) {
|
||||
if (obj.nodeName === 'node') {
|
||||
var node = new iD.Node(connection,
|
||||
+getAttribute(obj, 'id'),
|
||||
+getAttribute(obj, 'lat'),
|
||||
+getAttribute(obj, 'lon'),
|
||||
getTags(obj));
|
||||
this._assign(node);
|
||||
nodelist.push(node);
|
||||
break;
|
||||
|
||||
case "way":
|
||||
var way = new iD.Way(this,
|
||||
getAttribute(obj,'id'),
|
||||
getNodes(obj, this),
|
||||
assign(node);
|
||||
return node;
|
||||
} else if (obj.nodeName === 'way') {
|
||||
var way = new iD.Way(connection,
|
||||
getAttribute(obj, 'id'),
|
||||
getNodes(obj, connection),
|
||||
getTags(obj));
|
||||
this._assign(way);
|
||||
break;
|
||||
|
||||
case "relation":
|
||||
var relation = new iD.Relation(this,
|
||||
getAttribute(obj,'id'),
|
||||
getMembers(obj, this),
|
||||
assign(way);
|
||||
} else if (obj.nodeName === 'relation') {
|
||||
var relation = new iD.Relation(connection,
|
||||
getAttribute(obj, 'id'),
|
||||
getMembers(obj, connection),
|
||||
getTags(obj));
|
||||
this._assign(relation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.updatePOIs(nodelist);
|
||||
this.refreshMaps();
|
||||
if (this.callback) { this.callback(); }
|
||||
assign(relation);
|
||||
}
|
||||
}));
|
||||
updatePOIs(nodelist);
|
||||
if (callback) { callback(nodelist); }
|
||||
|
||||
// Private functions to parse DOM created from XML file
|
||||
function filterNodeName(n) {
|
||||
return function(item) {
|
||||
return item.nodeName === n;
|
||||
};
|
||||
}
|
||||
// Private functions to parse DOM created from XML file
|
||||
function filterNodeName(n) {
|
||||
return function(item) { return item.nodeName === n; };
|
||||
}
|
||||
|
||||
function getAttribute(obj, name) {
|
||||
return _.find(obj.attributes, filterNodeName(name)).nodeValue;
|
||||
}
|
||||
function getAttribute(obj, name) {
|
||||
return _.find(obj.attributes, filterNodeName(name)).nodeValue;
|
||||
}
|
||||
|
||||
function getTags(obj) {
|
||||
return _(obj.childNodes).chain()
|
||||
function getTags(obj) {
|
||||
return _(obj.childNodes).chain()
|
||||
.filter(filterNodeName('tag'))
|
||||
.map(function(item) {
|
||||
return [getAttribute(item,'k'), getAttribute(item,'v')];
|
||||
}).object().value();
|
||||
}
|
||||
}
|
||||
|
||||
function getNodes(obj,conn) {
|
||||
return _(obj.childNodes).chain()
|
||||
function getNodes(obj,conn) {
|
||||
return _(obj.childNodes).chain()
|
||||
.filter(filterNodeName('nd'))
|
||||
.map(function(item) {
|
||||
return conn.nodes[getAttribute(item,'ref')];
|
||||
return nodes[getAttribute(item,'ref')];
|
||||
}).value();
|
||||
}
|
||||
}
|
||||
|
||||
function getMembers(obj,conn) {
|
||||
return _(obj.childNodes).chain()
|
||||
.filter(filterNodeName('member'))
|
||||
.map(function(item) {
|
||||
var id = getAttribute(item,'ref'),
|
||||
function getMembers(obj,conn) {
|
||||
return _(obj.childNodes).chain()
|
||||
.filter(filterNodeName('member'))
|
||||
.map(function(item) {
|
||||
var id = getAttribute(item,'ref'),
|
||||
type = getAttribute(item,'type'),
|
||||
role = getAttribute(item,'role');
|
||||
|
||||
var obj = conn._getOrCreate(id,type);
|
||||
return new iD.RelationMember(obj,role);
|
||||
}).value();
|
||||
}
|
||||
}
|
||||
var obj = getOrCreate(id,type);
|
||||
return new iD.RelationMember(obj,role);
|
||||
}).value();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
connection.nodes = nodes;
|
||||
connection.ways = ways;
|
||||
connection.relations = relations;
|
||||
connection.loadFromAPI = loadFromAPI;
|
||||
connection.loadFromURL = loadFromURL;
|
||||
connection.getObjectsByBbox = getObjectsByBbox;
|
||||
|
||||
return connection;
|
||||
};
|
||||
|
||||
@@ -224,10 +224,10 @@ declare("iD.renderer.Map", null, {
|
||||
|
||||
download:function() {
|
||||
// summary: Ask the connection to download data for the current viewport.
|
||||
this.conn.loadFromAPI(this.extent);
|
||||
this.conn.loadFromAPI(this.extent, _.bind(this.updateUIs, this));
|
||||
},
|
||||
|
||||
updateUIs:function(redraw,remove) {
|
||||
updateUIs: function(redraw, remove) {
|
||||
// summary: Draw/refresh all EntityUIs within the bbox, and remove any others.
|
||||
// redraw: Boolean Should we redraw any UIs that are already present?
|
||||
// remove: Boolean Should we delete any UIs that are no longer in the bbox?
|
||||
@@ -243,7 +243,7 @@ declare("iD.renderer.Map", null, {
|
||||
else if (redraw) { m.wayuis[way.id].recalculate(); m.wayuis[way.id].redraw(); }
|
||||
});
|
||||
|
||||
if (remove) {
|
||||
if (remove !== false) {
|
||||
array.forEach(o.waysOutside, function(way) {
|
||||
if (m.wayuis[way.id]) { // && !m.wayuis[way.id].purgable
|
||||
if (redraw) { m.wayuis[way.id].recalculate(); m.wayuis[way.id].redraw(); }
|
||||
@@ -257,7 +257,7 @@ declare("iD.renderer.Map", null, {
|
||||
else if (redraw) { m.nodeuis[poi.id].redraw(); }
|
||||
});
|
||||
|
||||
if (remove) {
|
||||
if (remove !== false) {
|
||||
array.forEach(o.poisOutside, function(poi) {
|
||||
if (m.nodeuis[poi.id]) { // && !m.nodeuis[poi.id].purgable
|
||||
if (redraw) { m.nodeuis[poi.id].redraw(); }
|
||||
|
||||
Reference in New Issue
Block a user