Commit work towards pure models. This commit is not stable.

This commit is contained in:
Tom MacWright
2012-10-16 16:06:03 -04:00
parent 92d00f0401
commit d98007da68
6 changed files with 194 additions and 29 deletions
+3 -21
View File
@@ -8,7 +8,6 @@ define(["dojo/_base/xhr","dojo/_base/lang","dojox/xml/DomParser","dojo/_base/arr
// Connection base class
declare("iD.Connection", null, {
nodes: {}, // hash of node objects
ways: {}, // hash of way objects
relations: {}, // hash of relation objects
@@ -20,7 +19,7 @@ declare("iD.Connection", null, {
nextNode: -1, // next negative ids
nextWay: -1, // |
nextRelation: -1, // |
apiBaseURL: '', // root API address
constructor:function(apiURL) {
@@ -52,7 +51,7 @@ declare("iD.Connection", null, {
// summary: Return a way by id.
return this.ways[id]; // iD.Way
},
getRelation:function(id) {
getRelation:function(id) {
// summary: Return a relation by id.
return this.relations[id]; // iD.Relation
},
@@ -90,20 +89,6 @@ declare("iD.Connection", null, {
perform(new iD.actions.CreateEntityAction(relation, lang.hitch(this,this._assign) ));
return relation;
},
markClean:function() {
// summary: Mark the connection as clean (i.e. there's no new data to be saved).
this.modified=false;
},
markDirty:function() {
// summary: Mark the connection as dirty (i.e. there's data to be saved).
this.modified=true;
},
isDirty:function() {
// summary: Is the connection dirty?
return this.modified;
},
getObjectsByBbox:function(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.
@@ -197,7 +182,7 @@ declare("iD.Connection", null, {
var obj=jsdom.childNodes[i];
switch(obj.nodeName) {
case "node":
case "node":
var node = new iD.Node(this,
getAttribute(obj,'id'),
getAttribute(obj,'lat'),
@@ -276,9 +261,6 @@ declare("iD.Connection", null, {
}
});
// ----------------------------------------------------------------------
// End of module
});
+3 -3
View File
@@ -10,7 +10,7 @@ declare("iD.Controller", null, {
map: null, // current Map
stepper: null, // current StepPane
undoStack: null, // main undoStack
constructor:function(_map) {
// summary: The Controller marshalls ControllerStates and passes events to them.
this.map=_map;
@@ -21,7 +21,7 @@ declare("iD.Controller", null, {
// summary: Set reference for the singleton-like class for the step-by-step instruction panel.
this.stepper=_stepper;
},
setState:function(newState) {
// summary: Enter a new ControllerState, firing exitState on the old one, and enterState on the new one.
if (newState==this.state) { return; }
@@ -34,7 +34,7 @@ declare("iD.Controller", null, {
newState.enterState();
on.emit(window, "enterState", { bubbles: true, cancelable: true, state: this.state.stateNameAsArray() });
},
entityMouseEvent:function(event,entityUI) {
// summary: Pass a MouseEvent on an EntityUI (e.g. clicking a way) to the current ControllerState.
if (!this.state) { return; }
+117
View File
@@ -1,6 +1,7 @@
// iD/Entity.js
// Entity classes for iD
/*
define(['dojo/_base/declare','dojo/_base/array','dojo/_base/lang',
'iD/actions/AddNodeToWayAction','iD/actions/MoveNodeAction'
], function(declare,array,lang){
@@ -162,3 +163,119 @@ declare("iD.Entity", null, {
// ----------------------------------------------------------------------
// End of module
});
*/
if (typeof iD === 'undefined') iD = {};
iD.Entity = function() {
this.tags = {};
this.parents = new Hashtable();
this.connection = null;
this.id =  NaN;
this.loaded = false;
this.tags = null;
this.entityType = '';
this.parents = null;
this.modified = false;
this.deleted = false;
this.MAINKEYS = ['highway','amenity','railway','waterway'];
};
iD.Entity.prototype = {
isType:function(type) {
// summary: Is this entity of the specified type ('node','way','relation')?
return this.entityType==type; // Boolean
},
toString:function() {
return this.entityType+"."+this.id;
},
// --------------------------------
// Provoke redraw and other changes
refresh:function() {
// summary: Ask the connection to provoke redraw and other changes.
this.connection.refreshEntity(this);
},
// -------------------------------------
// Bounding box check (to be overridden)
within:function(left,right,top,bottom) {
// summary: Is the entity within the specified bbox?
return !this.deleted; // Boolean
},
// -------------
// Tag functions
getTagsHash:function() {
// summary: Tag getter.
// returns: The tags hash (reference to the actual object property, not a copy).
return this.tags; // Object
},
numTags:function() {
// summary: Count how many tags this entity has.
var c=0;
for (var i in this.tags) { c++; }
return c; // int
},
friendlyName:function() {
// summary: Rough-and-ready function to return a human-friendly name
// for the object. Really just a placeholder for something better.
// returns: A string such as 'river' or 'Fred's House'.
if (this.numTags()===0) { return ''; }
var n=[];
if (this.tags.name) { n.push(this.tags.name); }
if (this.tags.ref) { n.push(this.tags.ref); }
if (n.length===0) {
for (var i=0; i<this.MAINKEYS.length; i++) {
if (this.tags[this.MAINKEYS[i]]) { n.push(this.tags[this.MAINKEYS[i]]); break; }
}
}
return n.length===0 ? 'unknown' : n.join('; '); // String
},
// ---------------
// Parent-handling
addParent:function(entity) {
// summary: Record a parent (a relation or way which contains this entity).
this.parents.put(entity,true);
},
removeParent:function(entity) {
// summary: Remove a parent (e.g. when node removed from a way).
this.parents.remove(_entity);
},
hasParent:function(entity) {
// summary: Does this entity have the specified parent (e.g. is it in a certain relation)?
return this.parents.containsKey(entity); // Boolean
},
parentObjects:function() {
// summary: List of all parents of this entity.
return this.parents.keys(); // Boolean
},
hasParentWays:function() {
// summary: Does this entity have any parents which are ways?
var p=this.parentObjects();
for (var i in p) {
if (p[i].entityType=='way') { return true; }
}
return false; // Boolean
},
parentWays:function() {
// summary: Return an array of all ways that this entity is a member of.
return this._parentObjectsOfClass('way'); // Array
},
parentRelations:function() {
// summary: Return an array of all relations that this entity is a member of.
return this._parentObjectsOfClass('relation'); // Array
},
_parentObjectsOfClass:function(_class) {
var p=this.parentObjects(), c=[];
for (var i in p) {
if (p[i].entityType==_class) { c.push(p[i]); }
}
return c;
}
};
+68 -2
View File
@@ -1,5 +1,6 @@
// iD/Node.js
/*
define(['dojo/_base/declare','dojo/_base/array','dojo/_base/lang',
'iD/Entity','iD/actions/AddNodeToWayAction','iD/actions/MoveNodeAction'
], function(declare,array,lang){
@@ -55,10 +56,75 @@ declare("iD.Node", [iD.Entity], {
this.project();
var ways = this.parentWays();
for (var i=0; i<ways.length; i++) { ways[i].expandBbox(this); }
},
}
});
// ----------------------------------------------------------------------
// End of module
});
*/
if (typeof iD === 'undefined') iD = {};
iD.Node = function(conn,id,lat,lon,tags,loaded) {
// summary: An OSM node.
this.entityType = "node";
this.connection=conn;
this.id=id;
this.lat=lat;
this.lon=lon;
this.tags=tags;
this.loaded=(loaded===undefined) ? true : loaded;
this.project();
this.modified=this.id<0;
};
iD.Node.prototype = {
project:function() {
// summary: Update the projected latitude value (this.latp) from the latitude (this.lat).
this.latp=180/Math.PI * Math.log(Math.tan(Math.PI/4+this.lat*(Math.PI/180)/2));
},
latp2lat:function(a) {
// summary: Get a latitude from a projected latitude.
// returns: Latitude.
return 180/Math.PI * (2 * Math.atan(Math.exp(a*Math.PI/180)) - Math.PI/2); // Number
},
within:function(left,right,top,bottom) {
return (this.lon>=left) &&
(this.lon<=right) &&
(this.lat>=bottom) &&
(this.lat<=top) &&
!this.deleted;
},
refresh:function() {
var ways=this.parentWays();
var conn=this.connection;
array.forEach(ways,function(way) { conn.refreshEntity(way); });
this.connection.refreshEntity(this);
},
doSetLonLatp:function(lon,latproj,performAction) {
// summary: Change the position of a node, using an undo stack.
performAction(new iD.actions.MoveNodeAction(this, this.latp2lat(latproj), lon, lang.hitch(this,this._setLatLonImmediate) ));
},
_setLatLonImmediate:function(lat,lon) {
this.lat = lat;
this.lon = lon;
this.project();
var ways = this.parentWays();
for (var i=0; i<ways.length; i++) { ways[i].expandBbox(this); }
}
};
function extend(child, parent) {
for (var property in parent.prototype) {
if (typeof child.prototype[property] == "undefined") {
child.prototype[property] = parent.prototype[property];
}
}
return child;
}
extend(iD.Node, iD.Entity);
+1 -1
View File
@@ -57,7 +57,7 @@ declare("iD.Way", [iD.Entity], {
// summary: Return the first node in the way.
return this.nodes[0]; // iD.Node
},
getLastNode:function() {
getLastNode:function() {
// summary: Return the last node in the way.
return this.nodes[this.nodes.length-1]; // iD.Node
},
+2 -2
View File
@@ -78,8 +78,8 @@ declare("iD.actions.UndoableEntityAction", [iD.actions.UndoableAction], {
init:function() {
// summary: Record whether or not the entity and connection were clean before this action started
this.wasDirty = this.entity.isDirty();
this.connectionWasDirty = this.entity.connection.isDirty();
this.wasDirty = this.entity.modified;
this.connectionWasDirty = this.entity.connection.modified;
this.initialised = true;
},