From ab53ba3982e082e96c970e8f1307bc25598517c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 13 Sep 2007 20:36:36 +0000 Subject: [PATCH] allow user to specify offsets for externalGraphic (closes #893) git-svn-id: http://svn.openlayers.org/trunk/openlayers@4268 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/vector-features.html | 2 ++ lib/OpenLayers/Feature/Vector.js | 2 ++ lib/OpenLayers/Renderer/SVG.js | 12 ++++++--- lib/OpenLayers/Renderer/VML.js | 10 +++++-- tests/Layer/test_Vector.html | 46 +++++++++++++++++++++++++++++--- 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/examples/vector-features.html b/examples/vector-features.html index 567c39be0a..812eab174c 100644 --- a/examples/vector-features.html +++ b/examples/vector-features.html @@ -58,6 +58,8 @@ // of the image will be ignored style_mark.graphicWidth = 24; style_mark.graphicHeight = 20; + style_mark.graphicXOffset = -(style_mark.graphicWidth/2); // this is the default value + style_mark.graphicYOffset = -style_mark.graphicHeight; style_mark.externalGraphic = "../img/marker.png"; var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", {style: layer_style}); diff --git a/lib/OpenLayers/Feature/Vector.js b/lib/OpenLayers/Feature/Vector.js index 423af1b8fa..dec6a753da 100644 --- a/lib/OpenLayers/Feature/Vector.js +++ b/lib/OpenLayers/Feature/Vector.js @@ -263,6 +263,8 @@ OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, { * - graphicWidth, * - graphicHeight, * - graphicOpacity + * - graphicXOffset + * - graphicYOffset */ OpenLayers.Feature.Vector.style = { 'default': { diff --git a/lib/OpenLayers/Renderer/SVG.js b/lib/OpenLayers/Renderer/SVG.js index f0a12813fe..525bb749c6 100644 --- a/lib/OpenLayers/Renderer/SVG.js +++ b/lib/OpenLayers/Renderer/SVG.js @@ -184,8 +184,8 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { if (style.externalGraphic) { // remove old node var id = node.getAttributeNS(null, "id"); - var x = node.getAttributeNS(null, "cx"); - var y = node.getAttributeNS(null, "cy"); + var x = parseFloat(node.getAttributeNS(null, "cx")); + var y = parseFloat(node.getAttributeNS(null, "cy")); var _featureId = node._featureId; var _geometryClass = node._geometryClass; var _style = node._style; @@ -206,10 +206,14 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { var height = style.graphicHeight || style.graphicWidth; width = width ? width : style.pointRadius*2; height = height ? height : style.pointRadius*2; + var xOffset = (style.graphicXOffset != undefined) ? + style.graphicXOffset : -(0.5 * width); + var yOffset = (style.graphicYOffset != undefined) ? + style.graphicYOffset : -(0.5 * height); var opacity = style.graphicOpacity || style.fillOpacity; - node.setAttributeNS(null, "x", x-(.5*width).toFixed()); - node.setAttributeNS(null, "y", -y-(.5*height).toFixed()); + node.setAttributeNS(null, "x", (x + xOffset).toFixed()); + node.setAttributeNS(null, "y", (-y + yOffset).toFixed()); node.setAttributeNS(null, "width", width); node.setAttributeNS(null, "height", height); node.setAttributeNS("http://www.w3.org/1999/xlink", "href", style.externalGraphic); diff --git a/lib/OpenLayers/Renderer/VML.js b/lib/OpenLayers/Renderer/VML.js index 1c39759f21..2d63dd0b25 100644 --- a/lib/OpenLayers/Renderer/VML.js +++ b/lib/OpenLayers/Renderer/VML.js @@ -181,9 +181,15 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, { var height = style.graphicHeight || style.graphicWidth; width = width ? width : style.pointRadius*2; height = height ? height : style.pointRadius*2; + var resolution = this.getResolution(); - node.style.left = (geometry.x/resolution-.5*width).toFixed(); - node.style.top = (geometry.y/resolution-.5*height).toFixed(); + var xOffset = (style.graphicXOffset != undefined) ? + style.graphicXOffset : -(0.5 * width); + var yOffset = (style.graphicYOffset != undefined) ? + style.graphicYOffset : -(0.5 * height); + + node.style.left = ((geometry.x/resolution)+xOffset).toFixed(); + node.style.top = ((geometry.y/resolution)-(yOffset+height)).toFixed(); node.style.width = width; node.style.height = height; diff --git a/tests/Layer/test_Vector.html b/tests/Layer/test_Vector.html index b916338cd7..ec950dfdb2 100644 --- a/tests/Layer/test_Vector.html +++ b/tests/Layer/test_Vector.html @@ -158,7 +158,7 @@ } function test_Layer_Vector_externalGraphic(t) { - t.plan(9); + t.plan(11); // base layer is needed for getResolution() to return a value, // otherwise VML test will fail because style.left and style.top // cannot be set @@ -169,12 +169,17 @@ format: 'image/png'}); var layer = new OpenLayers.Layer.Vector("Test Layer"); + var renderer = layer.renderer; var map = new OpenLayers.Map('map'); map.addLayers([baseLayer, layer]); - var geometry = new OpenLayers.Geometry.Point(10, 10); + var geometryX = 10; + var geometryY = 10; + var geometry = new OpenLayers.Geometry.Point(geometryX, geometryY); var feature = new OpenLayers.Feature.Vector(geometry); + map.zoomToMaxExtent(); + var customStyle1 = new Object({ externalGraphic: 'test.png', pointRadius: 10 @@ -197,8 +202,15 @@ graphicWidth: 24, graphicOpacity: 1 }); + var customStyle6 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicHeight: 16, + graphicXOffset: -24, + graphicYOffset: -16 + }); - var root = layer.renderer.root; + var root = renderer.root; if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') { feature.style = customStyle1; layer.drawFeature(feature); @@ -237,6 +249,23 @@ t.eq(root.firstChild.getAttributeNS(null, 'style'), 'opacity: '+customStyle5.graphicOpacity.toString()+';', "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var x = geometryX / renderer.getResolution() + renderer.left; + var y = geometryY / renderer.getResolution() - renderer.top; + // SVG setStyle() gets x and y using getAttributeNS(), which returns + // a value with only 3 decimal digits. To mimic this we use toFixed(3) here + x = x.toFixed(3); + y = y.toFixed(3); + // toFixed() returns a string + x = parseFloat(x); + y = parseFloat(y); + t.eq(root.firstChild.getAttributeNS(null, 'x'), + (x + customStyle6.graphicXOffset).toFixed().toString(), + "graphicXOffset correctly set"); + t.eq(root.firstChild.getAttributeNS(null, 'y'), + (-y + customStyle6.graphicYOffset).toFixed().toString(), + "graphicYOffset correctly set"); } if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') { feature.style = customStyle1; @@ -279,6 +308,17 @@ t.eq(opacity, customStyle5.graphicOpacity, "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var x = geometryX / renderer.getResolution(); + var y = geometryY / renderer.getResolution(); + t.eq(root.firstChild.style.left, + (x + customStyle6.graphicXOffset).toFixed().toString()+'px', + "graphicXOffset correctly set"); + + t.eq(root.firstChild.style.top, + (y - (customStyle6.graphicYOffset+parseInt(root.firstChild.style.height))).toFixed().toString()+'px', + "graphicYOffset correctly set"); } }