From cc2e19d789197d4de4aa1d859b5992d9cc77e0f7 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 10 Apr 2009 16:05:26 +0000 Subject: [PATCH] added support for text labels. This also adds getCentroid methods to all geometries. Thanks crschmidt for the great help with this patch, and thanks to camptocamp for the initial work on this and rcoup for creating the first patches. r=crschmidt (closes #1895) git-svn-id: http://svn.openlayers.org/trunk/openlayers@9262 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/vector-features-with-text.html | 109 ++++++++++++++++++++++++ lib/OpenLayers/Feature/Vector.js | 11 +++ lib/OpenLayers/Geometry.js | 11 +++ lib/OpenLayers/Geometry/Collection.js | 21 +++++ lib/OpenLayers/Geometry/LinearRing.js | 23 +++++ lib/OpenLayers/Geometry/Point.js | 10 +++ lib/OpenLayers/Layer/Vector.js | 2 +- lib/OpenLayers/Renderer.js | 31 ++++++- lib/OpenLayers/Renderer/Canvas.js | 76 ++++++++++++++++- lib/OpenLayers/Renderer/Elements.js | 64 ++++++++++++-- lib/OpenLayers/Renderer/SVG.js | 96 ++++++++++++++++++++- lib/OpenLayers/Renderer/VML.js | 106 ++++++++++++++++++++--- tests/Layer/Vector.html | 2 +- tests/Layer/Vector/RootContainer.html | 16 +++- tests/Renderer/Elements.html | 32 +++---- 15 files changed, 560 insertions(+), 50 deletions(-) create mode 100644 examples/vector-features-with-text.html diff --git a/examples/vector-features-with-text.html b/examples/vector-features-with-text.html new file mode 100644 index 0000000000..1b0b64e656 --- /dev/null +++ b/examples/vector-features-with-text.html @@ -0,0 +1,109 @@ + + + + + + + +
+

This example shows drawing simple vector features with a label

+ + diff --git a/lib/OpenLayers/Feature/Vector.js b/lib/OpenLayers/Feature/Vector.js index 8d5587636b..defd0da67d 100644 --- a/lib/OpenLayers/Feature/Vector.js +++ b/lib/OpenLayers/Feature/Vector.js @@ -339,6 +339,17 @@ OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, { * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic. * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used. * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used. + * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either + * fillText or mozDrawText to be available. + * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string + * composed of two characters. The first character is for the horizontal alignment, the second for the vertical + * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical + * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". The canvas renderer does not + * support vertical alignment, it will always use "b". + * fontColor - {String} The font color for the label, to be provided like CSS. + * fontFamily - {String} The font family for the label, to be provided like in CSS. + * fontSize - {String} The font size for the label, to be provided like in CSS. + * fontWeight - {String} The font weight for the label, to be provided like in CSS. * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect. */ OpenLayers.Feature.Vector.style = { diff --git a/lib/OpenLayers/Geometry.js b/lib/OpenLayers/Geometry.js index 2dfbeda40b..d9d19a9281 100644 --- a/lib/OpenLayers/Geometry.js +++ b/lib/OpenLayers/Geometry.js @@ -224,6 +224,17 @@ OpenLayers.Geometry = OpenLayers.Class({ // return 0.0; }, + + /** + * APIMethod: getCentroid + * Calculate the centroid of this geometry. This method is defined in subclasses. + * + * Returns: + * {} The centroid of the collection + */ + getCentroid: function() { + return null; + }, /** * Method: toString diff --git a/lib/OpenLayers/Geometry/Collection.js b/lib/OpenLayers/Geometry/Collection.js index 05868d3a70..146dc7e59c 100644 --- a/lib/OpenLayers/Geometry/Collection.js +++ b/lib/OpenLayers/Geometry/Collection.js @@ -256,6 +256,27 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, { } return area; }, + + /** + * APIMethod: getCentroid + * + * Returns: + * {} The centroid of the collection + */ + getCentroid: function() { + return this.components.length && this.components[0].getCentroid(); + /* + var centroid; + for (var i=0, len=this.components.length; i} The centroid of the collection + */ + getCentroid: function() { + if ( this.components && (this.components.length > 2)) { + var sumX = 0.0; + var sumY = 0.0; + for (var i = 0; i < this.components.length - 1; i++) { + var b = this.components[i]; + var c = this.components[i+1]; + sumX += (b.x + c.x) * (b.x * c.y - c.x * b.y); + sumY += (b.y + c.y) * (b.x * c.y - c.x * b.y); + } + var area = -1 * this.getArea(); + var x = sumX / (6 * area); + var y = sumY / (6 * area); + } + return new OpenLayers.Geometry.Point(x, y); + }, /** * APIMethod: getArea diff --git a/lib/OpenLayers/Geometry/Point.js b/lib/OpenLayers/Geometry/Point.js index 643dd8cf92..203989099a 100644 --- a/lib/OpenLayers/Geometry/Point.js +++ b/lib/OpenLayers/Geometry/Point.js @@ -186,6 +186,16 @@ OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, { this.y = origin.y + (radius * Math.sin(theta)); this.clearBounds(); }, + + /** + * APIMethod: getCentroid + * + * Returns: + * {} The centroid of the collection + */ + getCentroid: function() { + return new OpenLayers.Geometry.Point(this.x, this.y); + }, /** * APIMethod: resize diff --git a/lib/OpenLayers/Layer/Vector.js b/lib/OpenLayers/Layer/Vector.js index 1aae581187..30145feac6 100644 --- a/lib/OpenLayers/Layer/Vector.js +++ b/lib/OpenLayers/Layer/Vector.js @@ -591,7 +591,7 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { feature.layer = null; if (feature.geometry) { - this.renderer.eraseGeometry(feature.geometry); + this.renderer.eraseFeatures(feature); } //in the case that this feature is one of the selected features, diff --git a/lib/OpenLayers/Renderer.js b/lib/OpenLayers/Renderer.js index dc8ce11d63..93e841f0f6 100644 --- a/lib/OpenLayers/Renderer.js +++ b/lib/OpenLayers/Renderer.js @@ -176,7 +176,13 @@ OpenLayers.Renderer = OpenLayers.Class({ if (!bounds.intersectsBounds(this.extent)) { style = {display: "none"}; } - return this.drawGeometry(feature.geometry, style, feature.id); + var rendered = this.drawGeometry(feature.geometry, style, feature.id); + if(style.display != "none" && style.label && rendered !== false) { + this.drawText(feature.id, style, feature.geometry.getCentroid()); + } else { + this.removeText(feature.id); + } + return rendered; } } }, @@ -196,6 +202,28 @@ OpenLayers.Renderer = OpenLayers.Class({ */ drawGeometry: function(geometry, style, featureId) {}, + /** + * Method: drawText + * Function for drawing text labels. + * This method is only called by the renderer itself. + * + * Parameters: + * featureId - {String} + * style - + * location - {} + */ + drawText: function(featureId, style, location) {}, + + /** + * Method: removeText + * Function for removing text labels. + * This method is only called by the renderer itself. + * + * Parameters: + * featureId - {String} + */ + removeText: function(featureId) {}, + /** * Method: clear * Clear all vectors from the renderer. @@ -231,6 +259,7 @@ OpenLayers.Renderer = OpenLayers.Class({ } for(var i=0, len=features.length; i} * style - {Object} - * featureId - {} */ drawGeometry: function(geometry, style) { var className = geometry.CLASS_NAME; @@ -334,6 +335,52 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, { ); // inner rings are 'empty' } }, + + /** + * Method: drawText + * This method is only called by the renderer itself. + * + * Parameters: + * location - {} + * style - {Object} + */ + drawText: function(location, style) { + var pt = this.getLocalXY(location); + + this.setCanvasStyle("reset"); + this.canvas.fillStyle = style.fontColor; + this.canvas.globalAlpha = 1; + var fontStyle = style.fontWeight + " " + style.fontSize + " " + style.fontFamily; + if (this.canvas.fillText) { + // HTML5 + var labelAlign = + OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]] || + "middle"; + this.canvas.font = fontStyle; + this.canvas.textAlign = labelAlign; + this.canvas.fillText(style.label, pt[0], pt[1]); + } else if (this.canvas.mozDrawText) { + // Mozilla pre-Gecko1.9.1 ( 0) { - this.root.removeChild(this.root.firstChild); + if (this.vectorRoot) { + while (this.vectorRoot.childNodes.length > 0) { + this.vectorRoot.removeChild(this.vectorRoot.firstChild); + } + } + if (this.textRoot) { + while (this.textRoot.childNodes.length > 0) { + this.textRoot.removeChild(this.textRoot.firstChild); } } if (this.indexer) { @@ -544,15 +578,15 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, { if (this.indexer) { var insert = this.indexer.insert(node); if (insert) { - this.root.insertBefore(node, insert); + this.vectorRoot.insertBefore(node, insert); } else { - this.root.appendChild(node); + this.vectorRoot.appendChild(node); } } else { // if there's no indexer, simply append the node to root, // but only if the node is a new one if (node.parentNode !== this.root){ - this.root.appendChild(node); + this.vectorRoot.appendChild(node); } } @@ -788,6 +822,20 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, { */ drawSurface: function(node, geometry) {}, + /** + * Method: removeText + * Removes a label + * + * Parameters: + * featureId - {String} + */ + removeText: function(featureId) { + var label = document.getElementById(featureId + this.LABEL_ID_SUFFIX); + if (label) { + this.textRoot.removeChild(label); + } + }, + /** * Method: getFeatureIdFromEvent * diff --git a/lib/OpenLayers/Renderer/SVG.js b/lib/OpenLayers/Renderer/SVG.js index ee630ce7df..74eff8895d 100644 --- a/lib/OpenLayers/Renderer/SVG.js +++ b/lib/OpenLayers/Renderer/SVG.js @@ -45,6 +45,12 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { * {Object} Cache for symbol sizes according to their svg coordinate space */ symbolSize: {}, + + /** + * Property: isGecko + * {Boolean} + */ + isGecko: null, /** * Constructor: OpenLayers.Renderer.SVG @@ -59,6 +65,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { OpenLayers.Renderer.Elements.prototype.initialize.apply(this, arguments); this.translationParameters = {x: 0, y: 0}; + this.isGecko = (navigator.userAgent.toLowerCase().indexOf("gecko/") != -1); }, /** @@ -337,6 +344,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { if (style.cursor != null) { node.setAttributeNS(null, "cursor", style.cursor); } + return node; }, @@ -416,11 +424,14 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { /** * Method: createRoot * + * Parameter: + * suffix - {String} suffix to append to the id + * * Returns: - * {DOMElement} The main root element to which we'll add vectors + * {DOMElement} */ - createRoot: function() { - return this.nodeFactory(this.container.id + "_root", "g"); + createRoot: function(suffix) { + return this.nodeFactory(this.container.id + suffix, "g"); }, /** @@ -633,7 +644,61 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { return false; } }, + + /** + * Method: drawText + * This method is only called by the renderer itself. + * + * Parameters: + * featureId - {String} + * style - + * location - {} + */ + drawText: function(featureId, style, location) { + var resolution = this.getResolution(); + + var x = (location.x / resolution + this.left); + var y = (location.y / resolution - this.top); + + var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "text"); + var tspan = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan", "tspan"); + label.setAttributeNS(null, "x", x); + label.setAttributeNS(null, "y", -y); + label.setAttributeNS(null, "pointer-events", "none"); + + if (style.fontColor) { + label.setAttributeNS(null, "fill", style.fontColor); + } + if (style.fontFamily) { + label.setAttributeNS(null, "font-family", style.fontFamily); + } + if (style.fontSize) { + label.setAttributeNS(null, "font-size", style.fontSize); + } + if (style.fontWeight) { + label.setAttributeNS(null, "font-weight", style.fontWeight); + } + var align = style.labelAlign || "cm"; + label.setAttributeNS(null, "text-anchor", + OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]] || "middle"); + + if (this.isGecko) { + label.setAttributeNS(null, "dominant-baseline", + OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]] || "central"); + } else { + tspan.setAttributeNS(null, "baseline-shift", + OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]] || "-35%"); + } + + tspan.textContent = style.label; + + if(!label.parentNode) { + label.appendChild(tspan); + this.textRoot.appendChild(label); + } + }, + /** * Method: getComponentString * @@ -828,3 +893,28 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { CLASS_NAME: "OpenLayers.Renderer.SVG" }); + +/** + * Constant: OpenLayers.Renderer.SVG.LABEL_ALIGN + * {Object} + */ +OpenLayers.Renderer.SVG.LABEL_ALIGN = { + "l": "start", + "r": "end", + "b": "bottom", + "t": "hanging" +}; + +/** + * Constant: OpenLayers.Renderer.SVG.LABEL_VSHIFT + * {Object} + */ +OpenLayers.Renderer.SVG.LABEL_VSHIFT = { + // according to + // http://www.w3.org/Graphics/SVG/Test/20061213/htmlObjectHarness/full-text-align-02-b.html + // a baseline-shift of -70% shifts the text exactly from the + // bottom to the top of the baseline, so -35% moves the text to + // the center of the baseline. + "t": "-70%", + "b": "0" +}; diff --git a/lib/OpenLayers/Renderer/VML.js b/lib/OpenLayers/Renderer/VML.js index 73ffc7a7e8..86c58ed3b3 100644 --- a/lib/OpenLayers/Renderer/VML.js +++ b/lib/OpenLayers/Renderer/VML.js @@ -108,13 +108,19 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, { left = left - this.offset.x; top = top - this.offset.y; } + var org = left + " " + top; this.root.setAttribute("coordorigin", org); + var roots = [this.root, this.vectorRoot, this.textRoot]; + var root; + for(var i=0, len=roots.length; i} + */ + drawText: function(featureId, style, location) { + var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "olv:rect"); + var textbox = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_textbox", "olv:textbox"); + + var resolution = this.getResolution(); + label.style.left = (location.x/resolution - this.offset.x).toFixed() + "px"; + label.style.top = (location.y/resolution - this.offset.y).toFixed() + "px"; + label.style.flip = "y"; + + textbox.innerText = style.label; + + if (style.fillColor) { + textbox.style.color = style.fontColor; + } + if (style.fontFamily) { + textbox.style.fontFamily = style.fontFamily; + } + if (style.fontSize) { + textbox.style.fontSize = style.fontSize; + } + if (style.fontWeight) { + textbox.style.fontWeight = style.fontWeight; + } + textbox.style.whiteSpace = "nowrap"; + textbox.inset = "0px,0px,0px,0px"; + + if(!label.parentNode) { + label.appendChild(textbox); + this.textRoot.appendChild(label); + } + + var align = style.labelAlign || "cm"; + var xshift = textbox.clientWidth * + (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]); + var yshift = textbox.clientHeight * + (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]); + label.style.left = parseInt(label.style.left)-xshift+"px"; + label.style.top = parseInt(label.style.top)+yshift+"px"; + }, /** * Method: drawSurface @@ -886,3 +955,16 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, { CLASS_NAME: "OpenLayers.Renderer.VML" }); + +/** + * Constant: OpenLayers.Renderer.VML.LABEL_SHIFT + * {Object} + */ +OpenLayers.Renderer.VML.LABEL_SHIFT = { + "l": 0, + "c": .5, + "r": 1, + "t": 0, + "m": .5, + "b": 1 +}; diff --git a/tests/Layer/Vector.html b/tests/Layer/Vector.html index 86faca81c4..75050d2c5a 100644 --- a/tests/Layer/Vector.html +++ b/tests/Layer/Vector.html @@ -426,7 +426,7 @@ graphicYOffset: -16 }); - var root = renderer.root; + var root = renderer.vectorRoot; if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') { feature.style = customStyle1; layer.drawFeature(feature); diff --git a/tests/Layer/Vector/RootContainer.html b/tests/Layer/Vector/RootContainer.html index 9e6e622822..982e492f6a 100644 --- a/tests/Layer/Vector/RootContainer.html +++ b/tests/Layer/Vector/RootContainer.html @@ -5,7 +5,6 @@ var layer, map; function test_RootContainer_collectResetRoots(t) { - t.plan(4); map = new OpenLayers.Map("map"); var layer1 = new OpenLayers.Layer.Vector("layer1"); @@ -13,15 +12,24 @@ layer = new OpenLayers.Layer.Vector.RootContainer("layer_1_2", { layers: [layer1, layer2] }); + + // we cannot test this with a renderer that does not hava a rendererRoot + var plan = layer.renderer.rendererRoot ? 4 : 0; + t.plan(plan); + if(plan == 0) { + return; + } + + var numRoots = layer.renderer.rendererRoot.childNodes.length; // addLayers will call setMap() for layer, which will call collectRoots() map.addLayers([layer1, layer2, layer]); - t.eq(layer.renderer.rendererRoot.childNodes.length, 3, "layer has correct number of renderer roots"); + t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots * 3, "layer has correct number of renderer roots"); t.eq(layer1.renderer.rendererRoot.childNodes.length, 0, "layer1 has no own renderer root"); layer.resetRoots(); - t.eq(layer.renderer.rendererRoot.childNodes.length, 1, "roots removed from container"); - t.eq(layer1.renderer.rendererRoot.childNodes.length, 1, "root re-added to original layer"); + t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots, "roots removed from container"); + t.eq(layer1.renderer.rendererRoot.childNodes.length, numRoots, "root re-added to original layer"); } function test_RootContainer_getFeatureFromEvent(t) { diff --git a/tests/Renderer/Elements.html b/tests/Renderer/Elements.html index 67a3670903..69adc7cf42 100644 --- a/tests/Renderer/Elements.html +++ b/tests/Renderer/Elements.html @@ -17,9 +17,8 @@ OpenLayers.Renderer.Elements.prototype._createRoot = OpenLayers.Renderer.Elements.prototype.createRoot; - var root = document.createElement("div"); OpenLayers.Renderer.Elements.prototype.createRoot = function() { - return root; + return document.createElement("div"); }; OpenLayers.Renderer.Elements.prototype._createNode = @@ -108,7 +107,7 @@ } function test_Elements_clear(t) { - t.plan(1); + t.plan(2); setUp(); @@ -121,7 +120,8 @@ r.clear(); - t.ok(r.root.childNodes.length == 0, "root is correctly cleared"); + t.ok(r.vectorRoot.childNodes.length == 0, "vector root is correctly cleared"); + t.ok(r.textRoot.childNodes.length == 0, "text root is correctly cleared"); tearDown(); } @@ -134,7 +134,7 @@ var r = create_renderer(); var element = document.createElement("div"); - r.root = element; + r.vectorRoot = element; r.nodeFactory = function(id, type) { var element = document.createElement("div"); @@ -149,7 +149,7 @@ r.redrawBackgroundNode = function(id, geometry, style, featureId) { b_Node = r.nodeFactory(); b_Node.id = "foo_background"; - r.root.appendChild(b_Node); + element.appendChild(b_Node); }; r.getNodeType = function(geometry, style) { @@ -162,8 +162,8 @@ var style = {'backgroundGraphic': 'foo'}; var featureId = 'dude'; r.drawGeometry(geometry, style, featureId); - t.ok(g_Node.parentNode == r.root, "node is correctly appended to root"); - t.ok(b_Node.parentNode == r.root, "redrawBackgroundNode appended background node"); + t.ok(g_Node.parentNode == element, "node is correctly appended to root"); + t.ok(b_Node.parentNode == element, "redrawBackgroundNode appended background node"); t.eq(g_Node._featureId, 'dude', "_featureId is correct"); t.eq(g_Node._style.backgroundGraphic, "foo", "_style is correct"); t.eq(g_Node._geometryClass, 'bar', "_geometryClass is correct"); @@ -178,8 +178,8 @@ style = {'display':'none'}; r.drawGeometry(geometry, style, featureId); - t.ok(g_Node.parentNode != r.root, "node is correctly removed"); - t.ok(b_Node.parentNode != r.root, "background node correctly removed") + t.ok(g_Node.parentNode != element, "node is correctly removed"); + t.ok(b_Node.parentNode != element, "background node correctly removed") document.getElementById = _getElement; @@ -474,7 +474,7 @@ var r = create_renderer(null, {zIndexing: true}); var element = document.createElement("div"); - r.root = element; + r.vectorRoot = element; document.body.appendChild(element); r.createNode = function(type, id) { @@ -505,14 +505,14 @@ return result; } - t.eq(r.root.childNodes.length, 1, "root is correctly filled"); + t.eq(element.childNodes.length, 1, "root is correctly filled"); t.eq(r.indexer.maxZIndex, 10, "indexer.maxZIndex is correctly filled"); t.eq(r.indexer.order.length, 1, "indexer.order is correctly filled"); t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly filled"); r.eraseGeometry(geometry); - t.eq(r.root.childNodes.length, 0, "root is correctly cleared"); + t.eq(element.childNodes.length, 0, "root is correctly cleared"); t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly reset"); t.eq(r.indexer.order.length, 0, "indexer.order is correctly reset"); t.eq(count(r.indexer.indices), 0, "indexer.indices is correctly reset"); @@ -520,14 +520,14 @@ delete(style.graphicZIndex); r.drawGeometry(geometry, style, featureId); - t.eq(r.root.childNodes.length, 1, "root is correctly filled"); + t.eq(element.childNodes.length, 1, "root is correctly filled"); t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly filled"); t.eq(r.indexer.order.length, 1, "indexer.order is correctly filled"); t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly filled"); r.clear(); - t.eq(r.root.childNodes.length, 0, "root is correctly cleared"); + t.eq(element.childNodes.length, 0, "root is correctly cleared"); t.eq(r.indexer.maxZIndex, 0, "indexer.maxZIndex is correctly reset"); t.eq(r.indexer.order.length, 0, "indexer.order is correctly reset"); t.eq(count(r.indexer.indices), 0, "indexer.indices is correctly reset"); @@ -535,7 +535,7 @@ style.graphicZIndex = 12; r.drawGeometry(geometry, style, featureId); - t.eq(r.root.childNodes.length, 1, "root is correctly filled"); + t.eq(element.childNodes.length, 1, "root is correctly filled"); t.eq(r.indexer.maxZIndex, 12, "indexer.maxZIndex is correctly filled"); t.eq(r.indexer.order.length, 1, "indexer.order is correctly filled"); t.eq(count(r.indexer.indices), 1, "indexer.indices is correctly filled");