| | 8 | |
|---|
| | 9 | OpenLayers.ElementsIndexer = OpenLayers.Class({ |
|---|
| | 10 | |
|---|
| | 11 | maxZIndex: null, |
|---|
| | 12 | order: null, |
|---|
| | 13 | |
|---|
| | 14 | initialize: function() { |
|---|
| | 15 | this.order = []; |
|---|
| | 16 | this.maxZIndex = 0; |
|---|
| | 17 | }, |
|---|
| | 18 | |
|---|
| | 19 | /** |
|---|
| | 20 | * |
|---|
| | 21 | * @param {Object} item |
|---|
| | 22 | */ |
|---|
| | 23 | insert: function(nodeId, zIndex) { |
|---|
| | 24 | |
|---|
| | 25 | // Everything must have a zIndex. If none is specified, |
|---|
| | 26 | // we'll use the maximum at the time of drawing. |
|---|
| | 27 | if (zIndex == null) { |
|---|
| | 28 | zIndex == this.maxZIndex; |
|---|
| | 29 | } |
|---|
| | 30 | |
|---|
| | 31 | if (zIndex > this.maxZIndex) { |
|---|
| | 32 | this.maxZIndex = zIndex; |
|---|
| | 33 | } |
|---|
| | 34 | |
|---|
| | 35 | var indexer = this; |
|---|
| | 36 | |
|---|
| | 37 | // Create a hash that holds the id of the node and the zIndex. |
|---|
| | 38 | var item = { |
|---|
| | 39 | id: nodeId, |
|---|
| | 40 | zIndex: zIndex |
|---|
| | 41 | }; |
|---|
| | 42 | |
|---|
| | 43 | this.order.push(item); |
|---|
| | 44 | |
|---|
| | 45 | // Sort the items in the array based on their zIndex. Since itemA |
|---|
| | 46 | // represents the item being added, we want to make it as high |
|---|
| | 47 | // up in the index order as possible (ie., if there are other items |
|---|
| | 48 | // with the same zIndex, the newest one should be the highest one). |
|---|
| | 49 | var sortByZIndex = function(itemA, itemB) { |
|---|
| | 50 | var zIndexA = itemA.zIndex; |
|---|
| | 51 | var zIndexB = itemB.zIndex; |
|---|
| | 52 | |
|---|
| | 53 | if(zIndexA <= zIndexB) { |
|---|
| | 54 | return -1; |
|---|
| | 55 | } else { |
|---|
| | 56 | return 1; |
|---|
| | 57 | } |
|---|
| | 58 | } |
|---|
| | 59 | |
|---|
| | 60 | this.order.sort(sortByZIndex); |
|---|
| | 61 | |
|---|
| | 62 | // Return the next item in the array -- the id of the node that should |
|---|
| | 63 | // follow this one directly in the index order -- if any. |
|---|
| | 64 | var nextIndex = this.order.indexOf(item) + 1; |
|---|
| | 65 | |
|---|
| | 66 | var returnVal = null; |
|---|
| | 67 | if (nextIndex > 0 && nextIndex < this.order.length) { |
|---|
| | 68 | returnVal = this.order[nextIndex].id; |
|---|
| | 69 | } |
|---|
| | 70 | return returnVal; |
|---|
| | 71 | }, |
|---|
| | 72 | |
|---|
| | 73 | exists: function(nodeId) { |
|---|
| | 74 | return this.items[nodeId] != null; |
|---|
| | 75 | }, |
|---|
| | 76 | |
|---|
| | 77 | CLASS_NAME: "OpenLayers.ElementsIndexer" |
|---|
| | 78 | }); |
|---|
| 130 | | if (style.backgroundGraphic) { |
|---|
| 131 | | |
|---|
| 132 | | var backgroundStyle = OpenLayers.Util.extend({}, style); |
|---|
| 133 | | backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic; |
|---|
| 134 | | |
|---|
| 135 | | backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset; |
|---|
| 136 | | backgroundStyle.graphicYOffset = backgroundStyle.backgroundYOffset; |
|---|
| 137 | | |
|---|
| 138 | | var backgroundNode = this.nodeFactory(geometry.id + this.BACKGROUND_ID_SUFFIX, nodeType, geometry); |
|---|
| 139 | | backgroundNode._geometryClass = geometry.CLASS_NAME; |
|---|
| 140 | | backgroundNode._style = backgroundStyle; |
|---|
| 141 | | |
|---|
| 142 | | this.root.appendChild(backgroundNode); |
|---|
| 143 | | this.drawGeometryNode(backgroundNode, geometry); |
|---|
| 144 | | } |
|---|
| 145 | | |
|---|
| 146 | | //first we create the basic node and add it to the root |
|---|
| 147 | | var nodeType = this.getNodeType(geometry, style); |
|---|
| 148 | | var node = this.nodeFactory(geometry.id, nodeType); |
|---|
| 149 | | node._featureId = featureId; |
|---|
| 150 | | node._geometryClass = geometry.CLASS_NAME; |
|---|
| 151 | | node._style = style; |
|---|
| 152 | | |
|---|
| 153 | | //now actually draw the node, and style it |
|---|
| 154 | | node = this.drawGeometryNode(node, geometry); |
|---|
| 155 | | this.root.appendChild(node); |
|---|
| 156 | | this.postDraw(node); |
|---|
| | 211 | var node = this.redrawNode(id, geometry, style, featureId); |
|---|
| 161 | | if (style.backgroundGraphic) { |
|---|
| 162 | | var backgroundNode = OpenLayers.Util.getElement( |
|---|
| 163 | | geometry.id + this.BACKGROUND_ID_SUFFIX |
|---|
| 164 | | ); |
|---|
| 165 | | backgroundNode.parentNode.removeChild(backgroundNode); |
|---|
| 166 | | } |
|---|
| 167 | | } |
|---|
| 168 | | } |
|---|
| | 216 | } |
|---|
| | 217 | } |
|---|
| | 218 | }, |
|---|
| | 219 | |
|---|
| | 220 | redrawNode: function(id, geometry, style, featureId) { |
|---|
| | 221 | // Get the node if it's already on the map. |
|---|
| | 222 | var currentNode = OpenLayers.Util.getElement(id); |
|---|
| | 223 | |
|---|
| | 224 | // Create a new node with the correct data. |
|---|
| | 225 | var nodeType = this.getNodeType(geometry, style); |
|---|
| | 226 | var newNode = this.createNode(nodeType, id); |
|---|
| | 227 | newNode._featureId = featureId; |
|---|
| | 228 | newNode._geometryClass = geometry.CLASS_NAME; |
|---|
| | 229 | newNode._style = style; |
|---|
| | 230 | |
|---|
| | 231 | // Draw the node (but not append it, yet). |
|---|
| | 232 | newNode = this.drawGeometryNode(newNode, geometry, style); |
|---|
| | 233 | |
|---|
| | 234 | // If we currently have a node, replace the current one |
|---|
| | 235 | // with the new one. This will get the browser to redraw it. |
|---|
| | 236 | if (currentNode) { |
|---|
| | 237 | this.root.replaceChild(newNode, currentNode); |
|---|
| | 238 | } else { |
|---|
| | 239 | // This is a new node. Throw this new node into our |
|---|
| | 240 | // indexer so it can show us where to place it. |
|---|
| | 241 | var zIndex = style.graphicZIndex; |
|---|
| | 242 | |
|---|
| | 243 | var nextNodeId = this.indexer.insert(id, zIndex); |
|---|
| | 244 | |
|---|
| | 245 | // If the new node should be before another in the index |
|---|
| | 246 | // order, insert the new node before the next; else, lets just |
|---|
| | 247 | // append new one on the end, making it the highest in the index order). |
|---|
| | 248 | if (nextNodeId) { |
|---|
| | 249 | var nextNode = OpenLayers.Util.getElement(nextNodeId); |
|---|
| | 250 | this.root.insertBefore(newNode, nextNode); |
|---|
| | 251 | } else { |
|---|
| | 252 | this.root.appendChild(newNode) |
|---|
| | 253 | } |
|---|
| | 254 | } |
|---|
| | 255 | |
|---|
| | 256 | this.postDraw(newNode); |
|---|
| | 257 | |
|---|
| | 258 | return newNode; |
|---|
| | 259 | }, |
|---|
| | 260 | |
|---|
| | 261 | redrawBackgroundNode: function(id, geometry, style, featureId) { |
|---|
| | 262 | var backgroundStyle = OpenLayers.Util.extend({}, style); |
|---|
| | 263 | |
|---|
| | 264 | // Set regular style attributes to apply to the background styles. |
|---|
| | 265 | backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic; |
|---|
| | 266 | backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset; |
|---|
| | 267 | backgroundStyle.graphicYOffset = backgroundStyle.backgroundYOffset; |
|---|
| | 268 | backgroundStyle.graphicZIndex = backgroundStyle.backgroundGraphicZIndex; |
|---|
| | 269 | |
|---|
| | 270 | // Erase background styles. |
|---|
| | 271 | backgroundStyle.backgroundGraphic = null; |
|---|
| | 272 | backgroundStyle.backgroundXOffset = null; |
|---|
| | 273 | backgroundStyle.backgroundYOffset = null; |
|---|
| | 274 | backgroundStyle.backgroundGraphicZIndex = null; |
|---|
| | 275 | |
|---|
| | 276 | this.redrawNode(id + this.BACKGROUND_ID_SUFFIX, geometry, backgroundStyle, null); |
|---|
| 369 | | |
|---|
| 370 | | /** |
|---|
| 371 | | * Method: nodeFactory |
|---|
| 372 | | * Create new node of the specified type, with the (optional) specified id. |
|---|
| 373 | | * |
|---|
| 374 | | * If node already exists with same ID and type, we remove it and then |
|---|
| 375 | | * call ourselves again to recreate it. |
|---|
| 376 | | * |
|---|
| 377 | | * Parameters: |
|---|
| 378 | | * id - {String} |
|---|
| 379 | | * type - {String} type Kind of node to draw |
|---|
| 380 | | * |
|---|
| 381 | | * Returns: |
|---|
| 382 | | * {DOMElement} A new node of the given type and id |
|---|
| 383 | | */ |
|---|
| 384 | | nodeFactory: function(id, type) { |
|---|
| 385 | | var node = OpenLayers.Util.getElement(id); |
|---|
| 386 | | if (node) { |
|---|
| 387 | | if (!this.nodeTypeCompare(node, type)) { |
|---|
| 388 | | node.parentNode.removeChild(node); |
|---|
| 389 | | node = this.nodeFactory(id, type); |
|---|
| 390 | | } |
|---|
| 391 | | } else { |
|---|
| 392 | | node = this.createNode(type, id); |
|---|
| 393 | | } |
|---|
| 394 | | return node; |
|---|
| | 477 | |
|---|
| | 478 | replaceNode: function(newNode, previousNode) { |
|---|
| | 479 | this.root.replaceChild(newNode, previousNode); |
|---|