Ticket #1357: reviewwithexample.patch
| File reviewwithexample.patch, 34.9 kB (added by tcoulter, 1 month ago) |
|---|
-
tests/Renderer/Elements.html
old new 3 3 <script src="../../lib/OpenLayers.js"></script> 4 4 <script type="text/javascript"> 5 5 6 function test_Elements_constructor(t) { 7 t.plan(5); 8 var el = document.createElement('div'); 9 document.body.appendChild(el); 10 el.id = "foo"; 11 6 function setUp() { 7 // Stub out functions that are meant to be overridden by 8 // subclasses. 12 9 OpenLayers.Renderer.Elements.prototype._createRenderRoot = 13 10 OpenLayers.Renderer.Elements.prototype.createRenderRoot; 14 11 … … 25 22 return root; 26 23 }; 27 24 28 var r = new OpenLayers.Renderer.Elements("foo"); 25 OpenLayers.Renderer.Elements.prototype._createNode = 26 OpenLayers.Renderer.Elements.prototype.createNode; 29 27 30 t.ok(r instanceof OpenLayers.Renderer.Elements, "new OpenLayers.Renderer.Elements returns Elements object" ); 31 t.ok(r.rendererRoot != null, "elements rendererRoot is not null"); 32 t.ok(r.root != null, "elements root is not null"); 28 OpenLayers.Renderer.Elements.prototype.createNode = function() { 29 return document.createElement("div"); 30 }; 31 } 32 33 // Create a new Elements renderer based on an id and an ordering 34 // type. For these tests, both of these parameters are optional. 35 function create_renderer(id, ordering) { 33 36 34 t.ok(r.root.parentNode == rendererRoot, "elements root is correctly appended to rendererRoot"); 35 t.ok(r.rendererRoot.parentNode == el, "elements rendererRoot is correctly appended to container"); 37 rendererRoot = null; 36 38 39 if (id == null) { 40 var el = document.createElement('div'); 41 document.body.appendChild(el); 42 el.id = OpenLayers.Util.createUniqueID(); 43 id = el.id; 44 } 45 46 return new OpenLayers.Renderer.Elements(id, ordering); 47 } 48 49 // Cleanup stubs made in the function above. 50 function tearDown() { 37 51 OpenLayers.Renderer.Elements.prototype.createRenderRoot = 38 52 OpenLayers.Renderer.Elements.prototype._createRenderRoot; 39 53 OpenLayers.Renderer.Elements.prototype.createRoot = 40 54 OpenLayers.Renderer.Elements.prototype._createRoot; 55 OpenLayers.Renderer.Elements.prototype.createNode = 56 OpenLayers.Renderer.Elements.prototype._createNode; 41 57 } 58 59 function test_Elements_constructor(t) { 60 t.plan(6); 61 62 setUp(); 63 64 var r = create_renderer(); 65 66 t.ok(r instanceof OpenLayers.Renderer.Elements, "new OpenLayers.Renderer.Elements returns Elements object" ); 67 t.ok(r.rendererRoot != null, "elements rendererRoot is not null"); 68 t.ok(r.root != null, "elements root is not null"); 69 t.ok(r.indexer != null, "indexer is not null."); 70 71 t.ok(r.root.parentNode == r.rendererRoot, "elements root is correctly appended to rendererRoot"); 72 t.ok(r.rendererRoot.parentNode == r.container, "elements rendererRoot is correctly appended to container"); 73 74 tearDown(); 75 } 42 76 43 77 function test_Elements_destroy(t) { 44 t.plan( 5);78 t.plan(8); 45 79 46 OpenLayers.Renderer.Elements.prototype._initialize =47 OpenLayers.Renderer.Elements.prototype.initialize;48 49 OpenLayers.Renderer.Elements.prototype.initialize = function() {}50 51 80 var g_Clear = false, g_Destroy = false; 52 81 53 82 OpenLayers.Renderer.prototype._destroy = … … 57 86 g_Destroy = true; 58 87 }; 59 88 89 // Stub out SVG's nodeFactory 90 OpenLayers.Renderer.SVG.prototype.nodeFactory = function() { 91 return document.createElement("div"); 92 } 93 60 94 var r = new OpenLayers.Renderer.SVG(document.body); 95 61 96 r.clear = function() { 62 97 g_Clear = true; 63 98 }; 64 r.rendererRoot = 'foo';65 r.root = 'bar';66 r.xmlns = 'dude';67 99 100 // Test assumptions. 101 t.ok(r.rendererRoot !== null, "rendererRoot not null"); 102 t.ok(r.rootnull !== "root not null"); 103 t.ok(r.xmlns !== "xmlns not null"); 104 68 105 r.destroy(); 69 106 70 107 t.eq(g_Clear, true, "OpenLayers.Renderer.Elements.clear() called"); … … 73 110 t.eq(r.xmlns, null, "xmlns nullified"); 74 111 t.eq(g_Destroy, true, "OpenLayers.Renderer.destroy() called"); 75 112 76 OpenLayers.Renderer.Elements.prototype.initialize =77 OpenLayers.Renderer.Elements.prototype._initialize;78 113 OpenLayers.Renderer.prototype.destroy = 79 114 OpenLayers.Renderer.prototype._destroy; 80 115 } … … 82 117 function test_Elements_clear(t) { 83 118 t.plan(1); 84 119 85 OpenLayers.Renderer.Elements.prototype._initialize = 86 OpenLayers.Renderer.Elements.prototype.initialize; 120 setUp(); 87 121 88 OpenLayers.Renderer.Elements.prototype.initialize = function() {} 89 90 var r = new OpenLayers.Renderer.Elements(); 122 var r = create_renderer(); 91 123 var element = document.createElement("div"); 92 124 r.root = element; 93 125 … … 98 130 99 131 t.ok(r.root.childNodes.length == 0, "root is correctly cleared"); 100 132 101 OpenLayers.Renderer.Elements.prototype.initialize = 102 OpenLayers.Renderer.Elements.prototype._initialize; 133 tearDown(); 103 134 } 104 135 105 136 function test_Elements_drawGeometry(t) { 106 137 t.plan(5); 138 139 setUp(); 140 141 var r = create_renderer(); 107 142 108 OpenLayers.Renderer.Elements.prototype._initialize =109 OpenLayers.Renderer.Elements.prototype.initialize;110 111 OpenLayers.Renderer.Elements.prototype.initialize = function() {};112 113 var r = new OpenLayers.Renderer.Elements();114 115 143 var element = document.createElement("div"); 116 144 r.root = element; 117 145 … … 147 175 var style = {'display':'none'}; 148 176 r.drawGeometry(geometry, style, featureId); 149 177 t.ok(g_Node.parentNode != r.root, "node is correctly removed"); 150 151 OpenLayers.Util.getElement = _getElement; 152 OpenLayers.Renderer.Elements.prototype.initialize = 153 OpenLayers.Renderer.Elements.prototype._initialize; 178 179 tearDown(); 154 180 } 155 181 156 182 function test_Elements_drawGeometry_2(t) { 157 183 t.plan(9); 158 184 159 OpenLayers.Renderer.Elements.prototype._initialize = 160 OpenLayers.Renderer.Elements.prototype.initialize; 161 162 OpenLayers.Renderer.Elements.prototype.initialize = function() {}; 163 164 var r = new OpenLayers.Renderer.Elements(); 185 setUp(); 165 186 187 var r = create_renderer(); 188 166 189 var element = document.createElement("div"); 167 190 r.root = element; 168 191 … … 281 304 style = true; 282 305 r.drawGeometry(geometry, style); 283 306 t.ok(properDraw, "drawGeometry called drawPolygon when passed a multi-polygon"); 284 285 OpenLayers.Renderer.Elements.prototype.initialize = 286 OpenLayers.Renderer.Elements.prototype._initialize; 307 308 tearDown(); 287 309 } 288 310 289 311 function test_Elements_getfeatureidfromevent(t) { … … 310 332 function test_Elements_erasegeometry(t) { 311 333 t.plan(5); 312 334 335 setUp(); 336 313 337 var el = document.createElement('div'); 314 338 document.body.appendChild(el); 315 339 el.id = 'bar'; 316 340 var geometry = { 317 id: 'bar'341 id: el.id 318 342 }; 319 343 320 OpenLayers.Renderer.Elements.prototype.eraseGeometry(geometry); 344 var r = create_renderer(el.id); 345 346 r.eraseGeometry(geometry); 321 347 t.ok(el.parentNode != document.body, "element correctly removed"); 322 348 323 349 var el = document.createElement('div'); … … 330 356 }] 331 357 }; 332 358 333 OpenLayers.Renderer.Elements.prototype.eraseGeometry(geometry);359 r.eraseGeometry(geometry); 334 360 t.ok(el.parentNode != document.body, "geometry components correctly removed when passed a multipoint"); 335 361 336 362 var el = document.createElement('div'); … … 343 369 }] 344 370 }; 345 371 346 OpenLayers.Renderer.Elements.prototype.eraseGeometry(geometry);372 r.eraseGeometry(geometry); 347 373 t.ok(el.parentNode != document.body, "geometry components correctly removed when passed a multilinestring"); 348 374 349 375 var el = document.createElement('div'); … … 356 382 }] 357 383 }; 358 384 359 OpenLayers.Renderer.Elements.prototype.eraseGeometry(geometry);385 r.eraseGeometry(geometry); 360 386 t.ok(el.parentNode != document.body, "geometry components correctly removed when passed a multipolygon"); 361 387 362 388 var el = document.createElement('div'); … … 369 395 }] 370 396 }; 371 397 372 OpenLayers.Renderer.Elements.prototype.eraseGeometry(geometry);398 r.eraseGeometry(geometry); 373 399 t.ok(el.parentNode != document.body, "geometry components correctly removed when passed a collection"); 400 401 tearDown(); 374 402 } 375 403 376 404 </script> -
lib/OpenLayers/Renderer/Elements.js
old new 5 5 /** 6 6 * @requires OpenLayers/Renderer.js 7 7 */ 8 /** 9 * Class: OpenLayers.ElementsIndexer 10 * This class takes care of figuring out which order elements should be 11 * placed in the DOM based on given indexing methods. 12 */ 13 OpenLayers.ElementsIndexer = OpenLayers.Class({ 14 15 /** 16 * Property: maxZIndex 17 * {Integer} This is the largest-most z-index value for a node 18 * contained within the indexer. 19 */ 20 maxZIndex: null, 21 22 /** 23 * Property: order 24 * {Array<String>} This is an array of node id's stored in the 25 * order that they should show up on screen. Id's higher up in the 26 * array (higher array index) represent nodes with higher z-indeces. 27 */ 28 order: null, 29 30 /** 31 * Property: indices 32 * {Hash} This is a hash that maps node ids to their z-index value 33 * stored in the indexer. This is done to make finding a nodes z-index 34 * value O(1). 35 */ 36 indices: null, 37 38 /** 39 * Property: compare 40 * {Function} This is the function used to determine placement of 41 * of a new node within the indexer. If null, this defaults to to 42 * the Z_ORDER_DRAWING_ORDER comparison method. 43 */ 44 compare: null, 45 46 /** 47 * APIMethod: initialize 48 * Create a new indexer with 49 * 50 * Parameters: 51 * yOordering - {Function} Whether to use y-ordering. 52 */ 53 initialize: function(yOrdering) { 8 54 55 this.compare = yOrdering ? 56 OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER : 57 OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER; 58 59 this.order = []; 60 this.indices = {}; 61 this.maxZIndex = 0; 62 }, 63 64 /** 65 * APIMethod: insert 66 * Insert a new node into the indexer. In order to find the correct positioning for 67 * the node to be inserted, this method uses a binary search. This makes inserting 68 * O(log(n)). 69 * 70 * Parameters: 71 * newNode - The new node to be inserted. 72 */ 73 insert: function(newNode) { 74 var nodeId = this.getNodeId(newNode); 75 76 this.determineZIndex(newNode); 77 78 var leftIndex = -1; 79 var rightIndex = this.order.length; 80 var middle; 81 82 while (rightIndex - leftIndex > 1) { 83 middle = parseInt((leftIndex + rightIndex) / 2); 84 85 var nextId = this.order[middle]; 86 var next = OpenLayers.Util.getElement(nextId); 87 88 var placement = this.compare(this, newNode, next); 89 90 if (placement > 0) { 91 leftIndex = middle; 92 } else { 93 rightIndex = middle; 94 } 95 } 96 97 this.order.splice(rightIndex, 0, nodeId); 98 this.indices[nodeId] = this.getZIndex(newNode); 99 100 // Return the next item in the array -- the id of the node that should 101 // follow this one directly in the index order -- if any. 102 var nextIndex = rightIndex + 1; 103 104 var returnVal = null; 105 if (nextIndex > 0 && nextIndex < this.order.length) { 106 returnVal = this.order[nextIndex]; 107 } 108 return returnVal; 109 }, 110 111 remove: function(node) { 112 var nodeId = this.getNodeId(node); 113 var arrayIndex = this.order.indexOf(nodeId); 114 if (arrayIndex >= 0) { 115 // Remove it from the order array, as well as deleting the node 116 // from the indeces hash. 117 this.order.splice(arrayIndex, 1); 118 delete this.indices[nodeId]; 119 120 // Reset the maxium z-index based on the last item in the order array. 121 var lastId = this.order[this.order.length - 1]; 122 this.maxZIndex = this.indices[lastId]; 123 } 124 }, 125 126 exists: function(node) { 127 var nodeId = this.getNodeId(node); 128 return this.indices[nodeId] != null; 129 }, 130 131 /** 132 * APIMethod: getZIndex 133 * Get the z-index value for the current node from the node data itself. 134 */ 135 getZIndex: function(node) { 136 return node._style.graphicZIndex; 137 }, 138 139 /** 140 * APIMethod: getMaxZIndex 141 * Get the maximum z-index stored within the indexer. 142 */ 143 getMaxZIndex: function() { 144 return this.maxZIndex; 145 }, 146 147 /** 148 * APIMethod: setZIndex 149 * Set the z-index for the given node. 150 */ 151 setZIndex: function(node, zIndex) { 152 node._style.graphicZIndex = zIndex; 153 }, 154 155 /** 156 * Method: determineZIndex 157 * Determine the z-index for the current node if there isn't one, 158 * and set the maximum value if we've found a new maximum. 159 */ 160 determineZIndex: function(node) { 161 var zIndex = node._style.graphicZIndex; 162 163 // Everything must have a zIndex. If none is specified, 164 // this means the user *must* (hint: assumption) want this 165 // node to succomb to drawing order. To enforce drawing order 166 // over all indexing methods, we'll create a new z-index that's 167 // greater than any currently in the indexer. 168 if (zIndex == null) { 169 zIndex = this.maxZIndex; 170 } 171 172 if (zIndex > this.maxZIndex) { 173 this.maxZIndex = zIndex; 174 } 175 176 node._style.graphicZIndex = zIndex; 177 }, 178 179 /** 180 * Method: getNodeId 181 * Get the id of the node passed in. 182 */ 183 getNodeId: function(node) { 184 return node.id; 185 }, 186 187 CLASS_NAME: "OpenLayers.ElementsIndexer" 188 }); 189 190 191 // These are the compare methods for figuring out where a new 192 // node should be placed within the indexer. These methods are very 193 // similar to general sorting methods in that they return -1, 0, and 1 194 // to specify the direction in which new nodes fall in the ordering. 195 OpenLayers.ElementsIndexer.IndexingMethods = { 196 /** 197 * Method: Z_ORDER 198 * This compare method is used by other comparison methods. 199 * It can be used individually for ordering, but is not recommended, 200 * because it doesn't subscribe to drawing order. 201 */ 202 Z_ORDER: function(indexer, newNode, next) { 203 var newZIndex = indexer.getZIndex(newNode); 204 205 var returnVal = 0; 206 if (next) { 207 var nextZIndex = indexer.getZIndex(next); 208 returnVal = newZIndex - nextZIndex; 209 } 210 211 return returnVal; 212 }, 213 /** 214 * API Method: Z_ORDER_DRAWING_ORDER 215 * This method orders nodes by their z-index, but does so in a way 216 * that, if there are other nodes with the same z-index, the newest drawn 217 * will be the front most within that z-index. This is the default 218 * indexing method. 219 */ 220 Z_ORDER_DRAWING_ORDER: function(indexer, newNode, next) { 221 var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer, newNode, next); 222 223 // Make Z_ORDER subscribe to drawing order by pushing it above 224 // all of the other nodes with the same z-index. 225 if (next && returnVal == 0) { 226 returnVal = 1; 227 } 228 229 return returnVal; 230 }, 231 /** 232 * API Method: Z_ORDER_Y_ORDER 233 * This one should really be called Z_ORDER_Y_ORDER_DRAWING_ORDER, as it 234 * best describes which ordering methods have precedence (though, the name would 235 * be too long). This method orders nodes by their z-index, but does so in a way 236 * that, if there are other nodes with the same z-index, the nodes with the 237 * lower y position will be "closer" than those with a higher y position. 238 * If two nodes have the exact same y position, however, then this method 239 * will revert to using drawing order to decide placement. 240 */ 241 Z_ORDER_Y_ORDER: function(indexer, newNode, next) { 242 var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer, newNode, next); 243 244 if (next && returnVal == 0) { 245 var newLat = newNode._geometry.getBounds().bottom; 246 var nextLat = next._geometry.getBounds().bottom; 247 248 var result = nextLat - newLat; 249 250 if (result == 0) { 251 returnVal = 1; 252 } else { 253 returnVal = result; 254 } 255 } 256 257 return returnVal; 258 } 259 } 260 9 261 /** 10 262 * Class: OpenLayers.Renderer.Elements 11 263 * This is another virtual class in that it should never be instantiated by … … 42 294 xmlns: null, 43 295 44 296 /** 297 * Property: Indexer 298 * An instance of OpenLayers.ElementsIndexer created upon 299 * initialization. 300 */ 301 indexer: null, 302 303 BACKGROUND_ID_SUFFIX: "_background", 304 305 /** 45 306 * Property: minimumSymbolizer 46 307 * {Object} 47 308 */ … … 57 318 * 58 319 * Parameters: 59 320 * containerID - {String} 321 * yOrdering - {Boolean} Whether or not y-ordering is enabled. 60 322 */ 61 initialize: function(containerID ) {323 initialize: function(containerID, yOrdering) { 62 324 OpenLayers.Renderer.prototype.initialize.apply(this, arguments); 63 325 64 326 this.rendererRoot = this.createRenderRoot(); … … 66 328 67 329 this.rendererRoot.appendChild(this.root); 68 330 this.container.appendChild(this.rendererRoot); 331 332 this.indexer = new OpenLayers.ElementsIndexer(yOrdering); 69 333 }, 70 334 71 335 /** … … 135 399 return; 136 400 }; 137 401 402 var id = geometry.id; 403 404 if (style.backgroundGraphic) { 405 this.redrawBackgroundNode(id, geometry, style, featureId); 406 } 407 138 408 if (style.display != "none") { 139 //first we create the basic node and add it to the root 140 var nodeType = this.getNodeType(geometry, style); 141 var node = this.nodeFactory(geometry.id, nodeType); 142 node._featureId = featureId; 143 node._geometryClass = geometry.CLASS_NAME; 144 node._style = style; 145 146 //now actually draw the node, and style it 147 node = this.drawGeometryNode(node, geometry); 148 149 // append the node to root (but only if it's new) 150 if (node.parentNode != this.root) { 151 this.root.appendChild(node); 152 } 153 this.postDraw(node); 409 this.redrawNode(id, geometry, style, featureId); 154 410 } else { 155 node = OpenLayers.Util.getElement( geometry.id);411 node = OpenLayers.Util.getElement(id); 156 412 if (node) { 157 413 node.parentNode.removeChild(node); 158 414 } 159 415 } 160 416 }, 417 418 redrawNode: function(id, geometry, style, featureId) { 419 // Get the node if it's already on the map. 420 var currentNode = OpenLayers.Util.getElement(id); 421 422 // Create a new node, or use the current one if it's 423 // already there. 424 var newNode; 425 if (!currentNode) { 426 var nodeType = this.getNodeType(geometry, style); 427 newNode = this.createNode(nodeType, id); 428 } else { 429 newNode = currentNode; 430 } 431 432 // Set the data for the node, then draw it. 433 newNode._featureId = featureId; 434 newNode._geometry = geometry; 435 newNode._geometryClass = geometry.CLASS_NAME; 436 newNode._style = style; 437 newNode = this.drawGeometryNode(newNode, geometry, style); 438 439 // If the node is known to the indexer, remove it so we can 440 // recalculate where it should go. 441 if (this.indexer.exists(newNode)) { 442 this.indexer.remove(newNode); 443 } 444 445 // Insert the node into the indexer so it can show us where to place it. 446 // Note that this operation is O(log(n)). If there's a performance problem 447 // (when dragging, for instance) this is likely where it would be. 448 var nextNodeId = this.indexer.insert(newNode); 161 449 450 // If the new node should be before another in the index 451 // order, insert the new node before the next; else, lets just 452 // append the new one on the end, making it the highest in the index order. 453 if (nextNodeId) { 454 var nextNode = OpenLayers.Util.getElement(nextNodeId); 455 this.root.insertBefore(newNode, nextNode); 456 } else { 457 this.root.appendChild(newNode); 458 } 459 460 this.postDraw(newNode); 461 }, 462 463 redrawBackgroundNode: function(id, geometry, style, featureId) { 464 var backgroundStyle = OpenLayers.Util.extend({}, style); 465 466 // Set regular style attributes to apply to the background styles. 467 backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic; 468 backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset; 469 backgroundStyle.graphicYOffset = backgroundStyle.backgroundYOffset; 470 backgroundStyle.graphicZIndex = backgroundStyle.backgroundGraphicZIndex; 471 472 // Erase background styles. 473 backgroundStyle.backgroundGraphic = null; 474 backgroundStyle.backgroundXOffset = null; 475 backgroundStyle.backgroundYOffset = null; 476 backgroundStyle.backgroundGraphicZIndex = null; 477 478 this.redrawNode(id + this.BACKGROUND_ID_SUFFIX, geometry, backgroundStyle, null); 479 }, 480 162 481 /** 163 482 * Method: drawGeometryNode 164 483 * Given a node, draw a geometry on the specified layer. … … 338 657 this.eraseGeometry(geometry.components[i]); 339 658 } 340 659 } else { 341 var element = OpenLayers.Util.getElement(geometry.id); 660 661 // TODO: Functionalize the next two blocks. 662 var elementId = geometry.id; 663 var element = OpenLayers.Util.getElement(elementId); 342 664 if (element && element.parentNode) { 665 if (element.geometry) { 666 element.geometry.destroy(); 667 element.geometry = null; 668 } 343 669 element.parentNode.removeChild(element); 670 671 this.indexer.remove(element); 344 672 } 673 674 var backgroundId = geometry.id + this.BACKGROUND_ID_SUFFIX; 675 var backgroundElement = OpenLayers.Util.getElement(backgroundId); 676 if (backgroundElement && backgroundElement.parentNode) { 677 if (backgroundElement.geometry) { 678 backgroundElement.geometry.destroy(); 679 backgroundElement.geometry = null; 680 } 681 backgroundElement.parentNode.removeChild(backgroundElement); 682 683 this.indexer.remove(backgroundElement); 684 } 345 685 } 346 }, 347 686 }, 687 348 688 /** 349 689 * Method: nodeFactory 350 690 * Create new node of the specified type, with the (optional) specified id. … … 371 711 } 372 712 return node; 373 713 }, 714 715 /** 716 * Method: createNode 717 * 718 * Parameters: 719 * type - {String} Kind of node to draw 720 * id - {String} Id for node 721 * 722 * Returns: 723 * {DOMElement} A new node of the given type and id. 724 * This function must be overridden by subclasses. 725 */ 726 createNode: function(type, id) {}, 374 727 375 728 CLASS_NAME: "OpenLayers.Renderer.Elements" 376 729 }); -
lib/OpenLayers/Layer/Vector.js
old new 140 140 * {<OpenLayers.Renderer>} 141 141 */ 142 142 renderer: null, 143 144 /** 145 * APIProperty: yOrdering 146 * {String} Whether or not externalGraphic y-ordering is enabled on this 147 * layer. Default is false. 148 */ 149 yOrdering: false, 143 150 144 151 /** 145 152 * APIProperty: geometryType … … 222 229 for (var i = 0; i < this.renderers.length; i++) { 223 230 var rendererClass = OpenLayers.Renderer[this.renderers[i]]; 224 231 if (rendererClass && rendererClass.prototype.supported()) { 225 this.renderer = new rendererClass(this.div);226 break;232 this.renderer = new rendererClass(this.div, this.yOrdering); 233 break; 227 234 } 228 235 } 229 236 }, -
examples/ordering.html
old new 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <link rel="stylesheet" href="../theme/default/style.css" type="text/css" /> 4 <link rel="stylesheet" href="style.css" type="text/css" /> 5 <style type="text/css"> 6 .smallmap { 7 width: 300px; 8 } 9 10 .docs { 11 padding: 0px 5px; 12 } 13 14 td { 15 vertical-align: top; 16 } 17 18 </style> 19 <script src="../lib/OpenLayers.js" type="text/javascript"></script> 20 <script type="text/javascript"> 21 22 var GOLD_Z_INDEX = 15; 23 var FIRST_RED_Z_INDEX = 10; 24 var SECOND_RED_Z_INDEX = 11; 25 26 var RADIUS_FROM_CENTER = 40; 27 var POINT_DISTANCE = 10; 28 29 function initYOrderMap() { 30 var map = new OpenLayers.Map("yorder"); 31 32 var layer = new OpenLayers.Layer.Vector( 33 "Y-Order", 34 { 35 styleMap: new OpenLayers.StyleMap({ 36 externalGraphic: "../img/marker-gold.png", 37 pointRadius: 10, 38 graphicZIndex: GOLD_Z_INDEX 39 }), 40 isBaseLayer: true, 41 yOrdering: true 42 } 43 ); 44 45 map.addLayers([layer]); 46 map.zoomToMaxExtent(); 47 48 // Add features to the layers to show off z-index/y-ordering. 49 // We do this after adding the layer so we can work in pixels. 50 var center = map.getViewPortPxFromLonLat(map.getCenter()); 51 52 var top = new OpenLayers.Pixel(center.x, center.y - RADIUS_FROM_CENTER); 53 var bottom = new OpenLayers.Pixel(center.x, center.y + RADIUS_FROM_CENTER); 54 var left = new OpenLayers.Pixel(center.x - RADIUS_FROM_CENTER, center.y - POINT_DISTANCE / 2); 55 var right = new OpenLayers.Pixel(center.x + RADIUS_FROM_CENTER, center.y - POINT_DISTANCE / 2); 56 57 // Add the ordering features. These are the gold ones that all have the same z-index 58 // and succomb to y-ordering. 59 var orderingFeatures = []; 60 // Note: We use > here on purpose (instead of >= ), as well as subtracting the 61 // the POINT_DISTANCE in the beginning of the loop (as opposed to the end). 62 // This is purely for symmetry. Also note that the gold features are drawn 63 // from bottom to top so as to quickly signal whether or not y-ordering is working. 64 while (bottom.y > top.y) { 65 bottom.y -= POINT_DISTANCE; 66 var lonLat = map.getLonLatFromViewPortPx(bottom); 67 orderingFeatures.push( 68 new OpenLayers.Feature.Vector( 69 new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat) 70 ) 71 ); 72 } 73 74 layer.addFeatures(orderingFeatures); 75 76 // Add the z-index features. Technically, these features succomb to y-ordering 77 // as well; however, since they have different z-indexes, the z-indexes take 78 // precedence. 79 var indexFeatures = []; 80 var useFirst = true; 81 while (left.x <= right.x) { 82 var lonLat = map.getLonLatFromViewPortPx(left); 83 var point = new OpenLayers.Feature.Vector( 84 new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat) 85 ); 86 87 // This is where the magic happens. We override the style on the layer 88 // to give our own style with alternativing z-indexes. 89 point.style = { 90 graphicZIndex: useFirst ? FIRST_RED_Z_INDEX : SECOND_RED_Z_INDEX, 91 externalGraphic: "../img/marker.png", 92 pointRadius: 10 93 } 94 95 indexFeatures.push( 96 point 97 ); 98 99 left.x += POINT_DISTANCE; 100 useFirst = !useFirst; 101 } 102 103 layer.addFeatures(indexFeatures); 104 } 105 106 function initDrawingOrderMap() { 107 var map = new OpenLayers.Map("drawingorder"); 108 109 var layer = new OpenLayers.Layer.Vector( 110 "Drawing Order", 111 { 112 // Note there's no z-index set, and yOrdering is left 113 // to its default. 114 styleMap: new OpenLayers.StyleMap({ 115 externalGraphic: "../img/marker-green.png", 116 pointRadius: 10 117 }), 118 isBaseLayer: true 119 } 120 ); 121 122 map.addLayers([layer]); 123 map.zoomToMaxExtent(); 124 125 // Add features to the layers to show off z-index/y-ordering. 126 // We do this after adding the layer so we can work in pixels. 127 var center = map.getViewPortPxFromLonLat(map.getCenter()); 128 129 var top = new OpenLayers.Pixel(center.x, center.y - RADIUS_FROM_CENTER); 130 var bottom = new OpenLayers.Pixel(center.x, center.y + RADIUS_FROM_CENTER); 131 var left = new OpenLayers.Pixel(center.x - RADIUS_FROM_CENTER, center.y); 132 var right = new OpenLayers.Pixel(center.x + RADIUS_FROM_CENTER, center.y); 133 134 // Add the ordering features. These are the gold ones that all have the same z-index 135 // and succomb to y-ordering. 136 var orderingFeatures = []; 137 while (bottom.y > top.y && left.x < right.x) { 138 var bottomLonLat = map.getLonLatFromViewPortPx(bottom); 139 var leftLonLat = map.getLonLatFromViewPortPx(left); 140 orderingFeatures.push( 141 new OpenLayers.Feature.Vector( 142 new OpenLayers.Geometry.Point(leftLonLat.lon, bottomLonLat.lat) 143 ) 144 ); 145 bottom.y -= POINT_DISTANCE / 2; // Divide by 2 for better visual. 146 left.x += POINT_DISTANCE / 2; 147 } 148 149 layer.addFeatures(orderingFeatures); 150 } 151 152 function init(){ 153 initYOrderMap(); 154 initDrawingOrderMap(); 155 }; 156 157 </script> 158 </head> 159 <body onload="init()"> 160 <h1 id="title">Z-Index/Y-Order Example</h1> 161 162 <div id="tags"> 163 </div> 164 165 <p id="shortdesc"> 166 This example shows the use of z-indexing and y-ordering of external graphics. Zoom in and out to see this behavior. 167 </p> 168 169 <h3>Z-Index (with Y-Ordering enabled)</h3> 170 <table> 171 <tr> 172 <td> 173 <div id="yorder" class="smallmap"></div> 174 </td> 175 <td> 176 <div class="docs"> 177 In this map, the gold features all have the same z-index, and the red features have alternating z-indeces. The gold features' z-index is greater than the red features' z-indeces, which is why gold features look to be drawn on top of the red features. Since each gold feature has the same z-index, gold features succomb to y-ordering: this is where features that seem closest to the viewer (lower lattitude) show up above those that seem farther away (higher lattitude). 178 <br><br> 179 All vector layers have z-indexing enabled by default, but are not enabled with y-ordering. You can enable y-ordering by passing the parameter <i>yOrdering: true</i> in the vector layer's options hash. For all configurations, if features have the same z-index -- and if y-ordering is enabled: the same lattitude -- those features will succomb to drawing order, where the last feature to be drawn will appear above the rest. 180 </div> 181 </td> 182 </tr> 183 </table> 184 <br> 185 <h3>Drawing Order (no Z-Indexes set, and Y-Ordering disabled)</h3> 186 <table> 187 <tr> 188 <td> 189 <div id="drawingorder" class="smallmap"></div> 190 </td> 191 <td> 192 <div class="docs"> 193 In this map, features are not given z-indexes, and the layer's <i>yOrdering</i> parameter is set to the default (false). This configuration makes features succomb to drawing order instead of z-index order or y-order. 194 <br><br> 195 The features in this map were drawn from left to right and bottom to top, diagonally, to show that y-ordering is not enabled. 196 </div> 197 </td> 198 </tr> 199 </table> 200 201 202 </body> 203 </html>
