Use an object with keys to keep track of tiles.

instead of a multidimensional array. this simplifies code and boosts
performance upon dragging.
This commit is contained in:
Tom MacWright
2012-10-17 11:10:14 -04:00
parent 65a2309252
commit a179eb2a26
8 changed files with 67 additions and 69 deletions

View File

@@ -8,9 +8,6 @@
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojox/layout/resources/FloatingPane.css">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojox/layout/resources/ResizeHandle.css">
<link rel="stylesheet" href="css/app.css">
<script src="js/lib/jshashtable.js"></script>
<script src="js/lib/jquery-1.8.2.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, baseUrl: 'js/iD/'"></script>
<style type="text/css">
:focus { outline-color: transparent; outline-style: none; }
@@ -21,9 +18,7 @@
</head>
<body class="claro">
<div id="appLayout" class="demoLayout">
<script type="text/javascript" src="js/lib/underscore-min.js"></script>
<script type="text/javascript" src="js/lib/jshashtable.js"></script>
<script type="text/javascript" src="js/lib/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/iD/Util.js"></script>
<script type="text/javascript" src="js/iD/Node.js"></script>
@@ -31,8 +26,7 @@
<script type="text/javascript" src="js/iD/Entity.js"></script>
<script type="text/javascript" src="js/iD/Way.js"></script>
<script type="text/javascript" src="js/iD/Connection.js"></script>
<script>
<script>
require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/dom",
"dijit/form/Button","dijit/form/ToggleButton",
@@ -48,15 +42,17 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
var ruleset=new iD.styleparser.RuleSet();
var conn=new iD.Connection("http://www.overpass-api.de/api/xapi?");
// Load styles
ruleset.registerCallback(styleLoaded);
ruleset.loadFromCSS("potlatch.css",styleLoaded);
// Initialise map
var map = new iD.renderer.Map({
lat: 51.87,
lon: -1.49,
lat: 38.89,
lon: -77,
// lat: 51.87,
// lon: -1.49,
scale: 17,
div: "map",
connection: conn,
@@ -69,7 +65,7 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
// Initialise controller
var controller=new iD.Controller(map);
map.setController(controller);
// Initialise event listeners
on(window, "enterState", enterStateListener);
on(window, "exitState", exitStateListener);
@@ -90,10 +86,10 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
// Load data
map.download();
}
// ----------------------------------------------------
// State event listeners
function enterStateListener(event) {
domClass.add(event.state[0]+"Button","currentMode");
};
@@ -101,7 +97,7 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
function exitStateListener(event) {
domClass.remove(event.state[0]+"Button","currentMode");
};
// ----------------------------------------------------
// Mode button handlers
@@ -111,7 +107,7 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
enterEditMode=function() {
};
finishClicked=function() {
controller.stepper.hide();
};
@@ -119,10 +115,10 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
cancelClicked=function() {
controller.stepper.hide();
};
// ----------------------------------------------------
// Map control handlers
zoomInClicked =function() { map.zoomIn(); };
zoomOutClicked=function() { map.zoomOut(); };
@@ -171,7 +167,7 @@ require(["dojo/_base/lang","dojo/dom-geometry","dojo/dom-class","dojo/on","dojo/
<!-- Floating help window -->
<div id="helpPane" data-dojo-type="dojox.layout.FloatingPane"
<div id="helpPane" data-dojo-type="dojox.layout.FloatingPane"
data-dojo-props="resizable:true, closable:false, dockable:false, title: 'Step by step'"
style="position:absolute; top:45px; left:50px; width:200px; height:200px; visibility: hidden;" >
<ol id="helpSteps">

View File

@@ -15,28 +15,28 @@ declare("iD.controller.edit.NoSelection", [iD.controller.edit.EditBaseState], {
constructor:function() {
// summary: In 'Edit object' mode but nothing selected.
},
enterState:function() {
this.controller.stepper.hide();
},
processMouseEvent:function(event,entityUI) {
this.inherited(arguments);
if (!entityUI) { return this; }
var entity=entityUI.entity;
var entity = entityUI.entity;
if (event.type=='click') {
this.inherited(arguments);
switch (entity.entityType) {
case 'node':
var ways=entity.parentWays();
if (ways.length==0) { return new iD.controller.edit.SelectedPOINode(entity); }
if (!ways.length) { return new iD.controller.edit.SelectedPOINode(entity); }
else { return new iD.controller.edit.SelectedWayNode(entity,ways[0]); }
break;
case 'way':
return new iD.controller.edit.SelectedWay(entityUI.entity, event);
}
}
return this;
}
});
// ----------------------------------------------------------------------

View File

@@ -4,7 +4,7 @@
Add road or shape -> DrawWay
The user is drawing a way.
Goes to:
-> click empty area: adds point, continues
-> click way: adds junction, continues
@@ -26,8 +26,8 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
wayUI: null,
editEnd: false,
constructor:function(_way) {
this.way=_way;
constructor: function(way) {
this.way = way;
},
enterState:function() {
this.wayUI=this.controller.map.getUI(this.way);
@@ -42,14 +42,14 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
this.wayUI.resetStateClass('shownodes');
this.wayUI.redraw();
},
processMouseEvent:function(event,entityUI) {
var entity=entityUI ? entityUI.entity : null;
var entityType=entity ? entity.entityType : null;
var map=this.controller.map;
var ways;
if (event.type=='mouseover' && entityType=='way' && entityUI!=this.wayUI) {
if (event.type=='mouseover' && entityType=='way' && entityUI!=this.wayUI) {
// Mouse over way, show hover highlight
entityUI.setStateClass('shownodeshover');
entityUI.redraw();
@@ -57,7 +57,7 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
this.updateElastic(event);
return this;
} else if (event.type=='mouseout' && entityType=='way' && entityUI!=this.wayUI) {
} else if (event.type=='mouseout' && entityType=='way' && entityUI!=this.wayUI) {
// Mouse left way, remove hover highlight
// Find what object we're moving into
var into=shape.byId((event.hasOwnProperty('toElement') ? event.toElement : event.relatedTarget).__gfxObject__);
@@ -117,7 +117,7 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
var action=this.undoAdder(); action(undo);
return this;
}
} else if (event.type=='click') {
// Click on empty space, add new node to way
var undo=new iD.actions.CompositeUndoableAction();
@@ -137,15 +137,15 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
map.mouseX(event), map.mouseY(event)
);
},
getDrawingNode:function() {
return (this.editEnd ? this.way.nodes[this.way.length()-1] : this.way.nodes[0]);
},
getStartNode:function() {
return (this.editEnd ? this.way.nodes[0] : this.way.nodes[this.way.length()-1]);
},
appendNode:function(node, performAction) {
if (this.editEnd) { this.way.doAppendNode(node, performAction); }
else { this.way.doPrependNode(node, performAction); }
@@ -154,13 +154,13 @@ declare("iD.controller.shape.DrawWay", [iD.controller.ControllerState], {
appendNewNode:function(event, undo) {
var map=this.controller.map;
var node=this.getConnection().doCreateNode(
{},
{},
map.coord2lat(map.mouseY(event)),
map.coord2lon(map.mouseX(event)), lang.hitch(undo,undo.push) );
this.appendNode(node, lang.hitch(undo,undo.push));
return node;
}
});
// ----------------------------------------------------------------------

View File

@@ -4,7 +4,7 @@
Add road or shape -> NoSelection
The user has clicked 'Add road or shape', but hasn't yet started drawing.
Goes to:
-> click empty area: goes to shape/DrawWay
-> click way: goes to shape/SelectedWay
@@ -37,7 +37,7 @@ declare("iD.controller.shape.NoSelection", [iD.controller.ControllerState], {
tag: "Set the type of the road or shape"
},['begin','draw','tag']).highlight('begin');
},
processMouseEvent:function(event,entityUI) {
var entity=entityUI ? entityUI.entity : null;
var entityType=entity ? entity.entityType : null;
@@ -70,7 +70,6 @@ declare("iD.controller.shape.NoSelection", [iD.controller.ControllerState], {
}
return this;
}
});
// ----------------------------------------------------------------------

View File

@@ -56,7 +56,7 @@ declare("iD.renderer.EntityUI", null, {
this.layer=this.styleList.layerOverride();
if (isNaN(this.layer)) {
this.layer=0;
if (tags['layer']) { this.layer=Number(tags['layer']); }
if (tags.layer) { this.layer = +tags.layer; }
}
// Iterate through each subpart, drawing any styles on that layer
@@ -78,7 +78,7 @@ declare("iD.renderer.EntityUI", null, {
// --------------------
// State class handling
setStateClasses:function(stateClasses) {
// summary: Set all state classes at once, and prompt a redraw if they're different to previously,
if (stateClasses && this.stateClasses.join(',')!=stateClasses.join(',')) {
@@ -87,7 +87,7 @@ declare("iD.renderer.EntityUI", null, {
}
return this;
},
setStateClass:function(sc) {
// summary: Set a single state class, and prompt a redraw if it wasn't set previously.
if (this.stateClasses.indexOf(sc)==-1) {

View File

@@ -75,7 +75,12 @@ declare("iD.renderer.Map", null, {
this.wayuis={},
this.div=document.getElementById(obj.div);
this.surface=Gfx.createSurface(obj.div, this.mapwidth, this.mapheight);
this.backdrop=this.surface.createRect( { x:0, y:0, width: this.mapwidth, height: this.mapheight }).setFill(new dojo.Color([255,255,245,1]));
this.backdrop=this.surface.createRect({
x: 0,
y: 0,
width: this.mapwidth,
height: this.mapheight
}).setFill(new dojo.Color([255,255,245,1]));
this.tilegroup=this.surface.createGroup();
this.container=this.surface.createGroup();
this.conn=obj.connection;
@@ -341,16 +346,16 @@ declare("iD.renderer.Map", null, {
_getTile:function(z,x,y) {
// summary: See if this tile is already loaded.
if (this.tiles[z]===undefined) { return undefined; }
if (this.tiles[z][x]===undefined) { return undefined; }
return this.tiles[z][x][y];
var k = z + ',' + x + ',' + y;
return this.tiles[k];
},
_assignTile:function(z,x,y,t) {
// summary: Store a reference to the tile so we know it's loaded.
if (this.tiles[z]===undefined) { this.tiles[z]=[]; }
if (this.tiles[z][x]===undefined) { this.tiles[z][x]=[]; }
this.tiles[z][x][y]=t;
var k = z + ',' + x + ',' + y;
if (!this.tiles[k]) {
this.tiles[z + ',' + x + ',' + y] = t;
}
},
_tileURL:function(z,x,y) {
@@ -359,8 +364,8 @@ declare("iD.renderer.Map", null, {
for (var zoom=z; zoom>0; zoom--) {
var byte=0;
var mask=1<<(zoom-1);
if ((x & mask)!=0) byte++;
if ((y & mask)!=0) byte+=2;
if ((x & mask) !== 0) byte++;
if ((y & mask) !== 0) byte += 2;
u=u+byte.toString();
}
return this.tilebaseURL.replace('$z',z).replace('$x',x).replace('$y',y).replace('$quadkey',u);
@@ -369,7 +374,7 @@ declare("iD.renderer.Map", null, {
_blankTiles:function() {
// summary: Unload all tiles and remove from the display.
this.tilegroup.clear();
this.tiles=[];
this.tiles = {};
},
// -------------------------------------------
@@ -426,12 +431,12 @@ declare("iD.renderer.Map", null, {
},
_mouseEvent:function(e) {
// summary: Catch mouse events on the surface but not the tiles - in other words,
// on drawn items that don't have their own hitzones, like the fill of a shape.
if (e.type=='mousedown') { this.startDrag(e); }
// ** FIXME: we may want to reinstate this at some point...
// this.controller.entityMouseEvent(e,null);
},
// summary: Catch mouse events on the surface but not the tiles - in other words,
// on drawn items that don't have their own hitzones, like the fill of a shape.
if (e.type=='mousedown') { this.startDrag(e); }
// ** FIXME: we may want to reinstate this at some point...
// this.controller.entityMouseEvent(e,null);
},
updateCoordsFromViewportPosition:function(e) {
// summary: Update centre and bbox from the current viewport origin.
@@ -439,10 +444,10 @@ declare("iD.renderer.Map", null, {
},
updateCoordsFromLatLon:function(lat,lon) {
// summary: Update centre and bbox to a specified lat/lon.
this._updateCoords(-(this.lon2coord(lon)-this.mapwidth/2),
-(this.lat2coord(lat)-this.mapheight/2));
},
// summary: Update centre and bbox to a specified lat/lon.
this._updateCoords(-(this.lon2coord(lon)-this.mapwidth/2),
-(this.lat2coord(lat)-this.mapheight/2));
},
_updateCoords:function(x,y) {
// summary: Set centre and bbox.

View File

@@ -1,7 +1,7 @@
// iD/renderer/NodeUI.js
// NodeUI classes for iD
define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array','dojox/gfx/_base','iD/renderer/EntityUI'],
define(['dojo/_base/declare','dojo/_base/lang','dojo/_base/array','dojox/gfx/_base','iD/renderer/EntityUI'],
function(declare,lang,array,g){
// ----------------------------------------------------------------------
@@ -63,7 +63,7 @@ declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
}
hit.setFill([0,1,0,0]).setStroke( { width:2, color:[0,0,0,0] } );
this.recordSprite(hit);
hit.source=this;
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));
@@ -71,7 +71,6 @@ declare("iD.renderer.NodeUI", [iD.renderer.EntityUI], {
hit.connect("onmouseleave", lang.hitch(this,this.entityMouseEvent));
}
}
});

View File

@@ -6,7 +6,6 @@
Based heavily on:
MapCSS demonstration stylesheet
Richard Fairhurst, October 2009
*/
/* A set of fairly standard rules.
@@ -20,13 +19,13 @@ way[highway=primary],way[highway=primary_link],
way[highway=secondary],way[highway=secondary_link],
way[highway=tertiary],way[highway=tertiary_link],
way[highway=unclassified],
way[highway=residential] { text: name; text-color: black; font-size: 6; text-position: line;}
way[highway=residential] { text: name; text-color: black; font-size: 6; text-position: line;}
way[highway=motorway],way[highway=motorway_link] { z-index: 9; color: #809BC0; width: 7; casing-color: black; casing-width: 1; }
way[highway=trunk],way[highway=trunk_link] { z-index: 9; color: #7FC97F; width: 7; casing-color: black; casing-width: 1; }
way[highway=primary],way[highway=primary_link] { z-index: 8; color: #E46D71; width: 7; casing-color: black; casing-width: 1; }
way[highway=primary],way[highway=primary_link] { z-index: 8; color: #E46D71; width: 9; casing-color: black; casing-width: 1; }
way[highway=secondary],way[highway=secondary_link] { z-index: 7; color: #FDBF6F; width: 7; casing-width: 1; }
way[highway=tertiary],way[highway=unclassified] { z-index: 6; color: #FEFECB; width: 5; casing-width: 1; }
way[highway=residential] { z-index: 5; color: #E8E8E8; width: 5; casing-color: gray; casing-width: 1; }
way[highway=residential] { z-index: 5; color: #E8E8E8; width: 6; casing-color: gray; casing-width: 1; }
way[highway=service] { color: white; width: 3; casing-width: 1; }
/* Pedestrian precincts need to be treated carefully. Only closed-loops with an explicit