Move towards compatible with existing view/edit code. This throws no

errors, but does not yet draw.
This commit is contained in:
Tom MacWright
2012-10-16 17:38:51 -04:00
parent 64bc7d5ea5
commit 0a0b1749dc
13 changed files with 84 additions and 93 deletions

View File

@@ -1,5 +1,3 @@
// iD/Connection.js
define(["dojo/_base/xhr","dojo/_base/lang","dojox/xml/DomParser","dojo/_base/array",'dojo/_base/declare',
"iD/Entity","iD/Node","iD/Way","iD/Relation","iD/actions/CreateEntityAction"],
function(xhr,lang,DomParser,array,declare,Entity){
@@ -90,19 +88,6 @@ declare("iD.Connection", null, {
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.
@@ -149,7 +134,7 @@ declare("iD.Connection", null, {
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].hasParentWays()) {
if (nodelist[i].entity.hasParentWays()) {
this.pois.remove(nodelist[i]);
} else {
this.pois.put(nodelist[i],true);
@@ -197,28 +182,28 @@ declare("iD.Connection", null, {
switch(obj.nodeName) {
case "node":
var node = new iD.Node(this,
getAttribute(obj,'id'),
getAttribute(obj,'lat'),
getAttribute(obj,'lon'),
getTags(obj));
this._assign(node);
var node = new iD.Node(this,
+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),
getTags(obj));
var way = new iD.Way(this,
getAttribute(obj,'id'),
getNodes(obj,this),
getTags(obj));
this._assign(way);
break;
case "relation":
var relation = new iD.Relation(this,
getAttribute(obj,'id'),
getMembers(obj,this),
getTags(obj));
var relation = new iD.Relation(this,
getAttribute(obj,'id'),
getMembers(obj,this),
getTags(obj));
this._assign(relation);
break;
}
@@ -228,8 +213,6 @@ declare("iD.Connection", null, {
if (this.callback) { this.callback(); }
// Private functions to parse DOM created from XML file
function filterNodeName(n) {
return function(item) {
return item.nodeName === n;

View File

@@ -1,5 +1,3 @@
// iD/Controller.js
define(['dojo/_base/declare','dojo/on','iD/actions/UndoStack'], function(declare,on){
// ----------------------------------------------------------------------

View File

@@ -1,6 +1,5 @@
// iD/Entity.js
// Entity classes for iD
if (typeof iD === 'undefined') iD = {};
iD.Entity = function() {
this.tags = {};
this.parents = new Hashtable();
@@ -8,10 +7,9 @@ iD.Entity = function() {
this.id = NaN;
this.loaded = false;
this.entityType = '';
this.parents = null;
this.modified = false;
this.deleted = false;
this.MAINKEYS = ['highway','amenity','railway','waterway'];
this.modified = false;
this.deleted = false;
this.MAINKEYS = ['highway','amenity','railway','waterway'];
};
iD.Entity.prototype = {

View File

@@ -1,10 +1,11 @@
// iD/Node.js
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.entity = new iD.Entity();
this.lat = lat;
this.lon = lon;
this.tags = tags;

View File

@@ -1,4 +1,3 @@
// iD/Relation.js
if (typeof iD === 'undefined') iD = {};
iD.Relation = function(conn, id, members, tags, loaded) {
@@ -10,7 +9,7 @@ iD.Relation = function(conn, id, members, tags, loaded) {
this.modified = this.id < 0;
this.loaded = (loaded === undefined) ? true : loaded;
_.each(members, _.bind(function(member) {
member.entity.addParent(this);
member.entity.entity.addParent(this);
}, this));
};

View File

@@ -1,17 +1,17 @@
// iD/Way.js
if (typeof iD === 'undefined') iD = {};
iD.Way = function(conn, id, nodes, tags, loaded) {
// summary: An OSM way.
this.connection = conn;
this.entityType = 'way';
this.id = id;
this.nodes = nodes || [];
this.entity = new iD.Entity();
this.tags = tags || {};
this.loaded = (loaded === undefined) ? true : loaded;
this.modified = this.id < 0;
_.each(nodes, _.bind(function(node) {
node.addParent(this);
node.entity.addParent(this);
}, this));
this._calculateBbox();
};
@@ -19,16 +19,14 @@ iD.Way = function(conn, id, nodes, tags, loaded) {
iD.Way.prototype = {
isClosed:function() {
// summary: Is this a closed way (first and last nodes the same)?
return this.nodes[this.nodes.length-1]==this.nodes[0]; // Boolean
return this.nodes[this.nodes.length - 1] === this.nodes[0]; // Boolean
},
isType:function(_type) {
isType:function(type) {
// summary: Is this a 'way' (always true), an 'area' (closed) or a 'line' (unclosed)?
switch (_type) {
case 'way': return true;
case 'area': return this.isClosed;
case 'line': return !(this.isClosed);
}
if (type === 'way') return true;
if (type === 'area') return this.isClosed();
if (type === 'line') return !(this.isClosed());
return false; // Boolean
},
@@ -39,8 +37,11 @@ iD.Way.prototype = {
(this.edgel<left && this.edger<left ) ||
(this.edgel>right && this.edger>right ) ||
(this.edgeb<bottom && this.edget<bottom) ||
(this.edgeb>top && this.edgeb>top ) || this.deleted) { return false; }
(this.edgeb>top && this.edgeb>top ) || this.deleted) {
return false;
} else {
return true;
}
},
_calculateBbox:function() {
@@ -87,8 +88,8 @@ iD.Way.prototype = {
// isSnap: Boolean Should the node position be snapped to be exactly on the segment?
// returns: The index at which the node was inserted.
var closestProportion = 1,
newIndex = 0,
snapped;
newIndex = 0,
snapped;
for (var i = 0; i < this.nodes.length - 1; i++) {
var node1 = this.nodes[i];

View File

@@ -66,14 +66,14 @@ declare("iD.actions.UndoableEntityAction", [iD.actions.UndoableAction], {
// summary: Mark a change to the entity ('dirtying' it).
if (!this.initialised) this.init();
if (!this.wasDirty) this.entity._markDirty();
if (!this.connectionWasDirty) this.entity.connection.markDirty();
if (!this.connectionWasDirty) this.entity.connection.modified = true;
},
markClean:function() {
// summary: If the entity was clean before, revert the dirty flag to that state.
if (!this.initialised) this.init();
if (!this.wasDirty) this.entity._markClean();
if (!this.connectionWasDirty) this.entity.connection.markClean();
if (!this.connectionWasDirty) this.entity.connection.modified = false;
},
init:function() {

View File

@@ -14,7 +14,7 @@ declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
},
getEnhancedTags:function() {
var tags=this.inherited(arguments);
if (!this.entity.hasParentWays()) { tags[':poi']='yes'; }
if (!this.entity.entity.hasParentWays()) { tags[':poi']='yes'; }
// add junction and dupe
return tags;
},
@@ -44,9 +44,9 @@ declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
// Draw icon
var shape;
switch (p.icon_image) {
case 'square': shape=this.targetGroup('stroke',p.sublayer).createRect({ x:x-w/2, y:y-h/2, width:w, height:h }); break;
case 'circle': shape=this.targetGroup('stroke',p.sublayer).createCircle({ cx:x, cy:y, r:w }); break;
default: shape=this.targetGroup('stroke',p.sublayer).createImage({ width:w, height:h, x: x-w/2, y: y-h/2, src:p.icon_image }); break;
case 'square':shape=this.targetGroup('stroke',p.sublayer).createRect({ x:x-w/2, y:y-h/2, width:w, height:h }); break;
case 'circle':shape=this.targetGroup('stroke',p.sublayer).createCircle({ cx:x, cy:y, r:w }); break;
default:shape=this.targetGroup('stroke',p.sublayer).createImage({ width:w, height:h, x: x-w/2, y: y-h/2, src:p.icon_image }); break;
}
switch (p.icon_image) {
case 'square':
@@ -71,7 +71,7 @@ declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
hit.connect("onmouseenter", lang.hitch(this,this.entityMouseEvent));
hit.connect("onmouseleave", lang.hitch(this,this.entityMouseEvent));
}
},
}
});

View File

@@ -28,11 +28,12 @@ declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
},
redraw:function() {
// summary: Draw the object and add hitzone sprites.
var way=this.entity;
var maxwidth=4;
var i;
var way = this.entity,
maxwidth=4,
i;
this.removeSprites();
if (way.length()==0) { return; }
if (!way.nodes.length) { return; }
// Create tags and calculate styleList
var tags=this.getEnhancedTags();
@@ -40,14 +41,17 @@ declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
// List of co-ordinates
var coords=[];
for (i=0; i<way.nodes.length; i++) {
var node=way.nodes[i];
coords.push( { x: this.map.lon2coord(node.lon), y: this.map.latp2coord(node.latp) } );
for (i = 0; i < way.nodes.length; i++) {
var node = way.nodes[i];
coords.push({
x: this.map.lon2coord(node.lon),
y: this.map.latp2coord(node.latp)
});
}
// Iterate through each subpart, drawing any styles on that layer
var drawn=false;
for (i=0; i<this.styleList.subparts.length; i++) {
var drawn = false;
for (i = 0; i < this.styleList.subparts.length; i++) {
var subpart=this.styleList.subparts[i];
if (this.styleList.shapeStyles[subpart]) {
var s=this.styleList.shapeStyles[subpart];
@@ -66,13 +70,13 @@ declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
}
// Casing
if (s.casing_width) {
if (s.casing_width) {
this.recordSprite(this.targetGroup('casing').createPolyline(coords).setStroke(s.casingStyler()));
maxwidth=Math.max(maxwidth,s.width+s.casing_width*2);
drawn=true;
}
}
// Text label on path
if (this.styleList.textStyles[subpart]) {
var t=this.styleList.textStyles[subpart];
@@ -96,26 +100,26 @@ declare("iD.renderer.WayUI", [iD.renderer.EntityUI], {
if (drawn) {
var hit=this.recordSprite(this.targetGroup('hit').createPolyline(coords).setStroke( { width:maxwidth+8, color: [0,0,0,0] } ));
hit.source=this;
hit.connect("onclick" , lang.hitch(this,this.entityMouseEvent));
hit.connect("onmousedown" , lang.hitch(this,this.entityMouseEvent));
hit.connect("onmouseup" , lang.hitch(this,this.entityMouseEvent));
hit.connect("onclick", lang.hitch(this,this.entityMouseEvent));
hit.connect("onmousedown", lang.hitch(this,this.entityMouseEvent));
hit.connect("onmouseup", lang.hitch(this,this.entityMouseEvent));
hit.connect("onmouseenter", lang.hitch(this,this.entityMouseEvent));
hit.connect("onmouseleave", lang.hitch(this,this.entityMouseEvent));
}
// Draw nodes
for (i=0; i<way.length(); i++) {
for (i=0; i<way.nodes.length; i++) {
var node=way.nodes[i];
var sc=[];
if (tags[':shownodes']) { sc.push('selectedway'); }
if (tags[':shownodeshover']) { sc.push('hoverway'); }
if (node.parentWays().length>1) { sc.push('junction'); }
if (node.entity.parentWays().length>1) { sc.push('junction'); }
this.map.createUI(node,sc);
}
},
entityMouseEvent:function(event) {
this.inherited(arguments);
},
}
});
// ----------------------------------------------------------------------

View File

@@ -29,13 +29,13 @@ declare("iD.styleparser.Rule", null, {
test:function(entity,tags,zoom) {
// summary: Evaluate the Rule on the given entity, tags and zoom level.
// returns: true if the Rule passes, false if the conditions aren't fulfilled.
if (this.subject!='' && !entity.isType(this.subject)) { return false; }
if (this.subject !== '' && !entity.entity.isType(this.subject)) { return false; }
if (zoom<this.minZoom || zoom>this.maxZoom) { return false; }
var v=true; var i=0; var isAnd=this.isAnd;
array.forEach(this.conditions, function(condition) {
var r=condition.test(tags);
if (i==0) { v=r; }
if (i === 0) { v=r; }
else if (isAnd) { v=v && r; }
else { v = v || r; }
i++;

View File

@@ -69,10 +69,10 @@ declare("iD.styleparser.RuleChain", null, {
if (!r.test(entity, tags, zoom)) { return false; }
if (pos==0) { return true; }
var o=entity.parentObjects();
var o = entity.entity.parentObjects();
for (var i=0; i<o.length; i++) {
var p=o[i];
if (this.test(pos-1, p, p.getTagsHash(), zoom)) { return true; }
if (this.test(pos-1, p, p.tags, zoom)) { return true; }
}
return false;
},

View File

@@ -15,7 +15,7 @@ declare("iD.styleparser.StyleList", null, {
maxwidth:0,
subparts:[], // List of subparts used in this StyleList
validAt:-1, // Zoom level this is valid at (or -1 at all levels - saves recomputing)
constructor:function() {
// summary: A StyleList object is the full list of all styles applied to
// a drawn entity (i.e. node/way). Each array element applies to that
@@ -28,12 +28,12 @@ declare("iD.styleparser.StyleList", null, {
this.shieldStyles={};
this.subparts=[];
},
hasStyles:function() {
// summary: Does this StyleList contain any styles?
return ( this.hasShapeStyles() || this.hasTextStyles() || this.hasPointStyles() || this.hasShieldStyles() );
},
hasFills:function() {
// summary: Does this StyleList contain any styles with a fill?
for (var s in this.shapeStyles) {
@@ -71,11 +71,10 @@ declare("iD.styleparser.StyleList", null, {
return str;
},
hasShapeStyles:function() { for (var a in shapeStyles ) { return true; }; return false; },
hasTextStyles:function() { for (var a in textStyles ) { return true; }; return false; },
hasPointStyles:function() { for (var a in pointStyles ) { return true; }; return false; },
hasShieldStyles:function() { for (var a in shieldStyles) { return true; }; return false; },
hasShapeStyles:function() { for (var a in shapeStyles ) { return true; } return false; },
hasTextStyles:function() { for (var a in textStyles ) { return true; } return false; },
hasPointStyles:function() { for (var a in pointStyles ) { return true; } return false; },
hasShieldStyles:function() { for (var a in shieldStyles) { return true; } return false; }
});
// ----------------------------------------------------------------------

View File

@@ -16,4 +16,12 @@ describe('Way', function() {
it('is closed by default', function() {
expect(way.isClosed()).toEqual(true);
});
it('is a way when it has no nodes', function() {
expect(way.isType('way')).toEqual(true);
});
it('is also an area when it has no nodes', function() {
expect(way.isType('area')).toEqual(true);
});
});