From 3e1f2e43051ae85536df6600e900f403ef95dc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 30 Aug 2007 05:59:29 +0000 Subject: [PATCH] add new vector style property "graphicOpacity" enabling mixing non-opaque vector geometries with opaque external graphics on the same vector layer (closes #873) git-svn-id: http://svn.openlayers.org/trunk/openlayers@4114 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/vector-features.html | 26 +++++++++++++----- lib/OpenLayers/Feature/Vector.js | 7 +++++ lib/OpenLayers/Renderer/SVG.js | 3 ++- lib/OpenLayers/Renderer/VML.js | 7 ++++- tests/Layer/test_Vector.html | 45 +++++++++++++++++++++++--------- 5 files changed, 67 insertions(+), 21 deletions(-) diff --git a/examples/vector-features.html b/examples/vector-features.html index a8ba5040c3..8701ca704c 100644 --- a/examples/vector-features.html +++ b/examples/vector-features.html @@ -17,12 +17,22 @@ var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); map.addLayer(layer); + + /* + * Layer style + */ + // we want opaque external graphics and non-opaque internal graphics + var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']); + layer_style.fillOpacity = 0.2; + layer_style.graphicOpacity = 1; - var style_blue = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']); + /* + * Blue style + */ + var style_blue = OpenLayers.Util.extend({}, layer_style); style_blue.strokeColor = "blue"; style_blue.fillColor = "blue"; style_blue.externalGraphic = "../img/marker.png"; - // each of the three lines below means the same, if only one of // them is active: the image will have a size of 24px, and the // aspect ratio will be kept @@ -30,7 +40,9 @@ //style_blue.graphicWidth = 24; //style_blue.graphicHeight = 24; - style_blue.fillOpacity = 1; + /* + * Green style + */ var style_green = { strokeColor: "#00FF00", strokeOpacity: 1, @@ -38,16 +50,18 @@ pointRadius: 6, pointerEvents: "visiblePainted" }; + + /* + * Mark style + */ var style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']); - // if graphicWidth and graphicHeight are both set, the aspect ratio // of the image will be ignored style_mark.graphicWidth = 24; style_mark.graphicHeight = 20; - style_mark.externalGraphic = "../img/marker.png"; - var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry"); + var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", {style: layer_style}); // create a point feature var point = new OpenLayers.Geometry.Point(-111.04, 45.68); diff --git a/lib/OpenLayers/Feature/Vector.js b/lib/OpenLayers/Feature/Vector.js index 431038c59f..423af1b8fa 100644 --- a/lib/OpenLayers/Feature/Vector.js +++ b/lib/OpenLayers/Feature/Vector.js @@ -256,6 +256,13 @@ OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, { * - hoverPointRadius: 1, * - hoverPointUnit: "%", * - pointerEvents: "visiblePainted" + * + * Other style properties that have no default values: + * + * - externalGraphic, + * - graphicWidth, + * - graphicHeight, + * - graphicOpacity */ OpenLayers.Feature.Vector.style = { 'default': { diff --git a/lib/OpenLayers/Renderer/SVG.js b/lib/OpenLayers/Renderer/SVG.js index 9c7510d43b..f0a12813fe 100644 --- a/lib/OpenLayers/Renderer/SVG.js +++ b/lib/OpenLayers/Renderer/SVG.js @@ -206,6 +206,7 @@ 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 opacity = style.graphicOpacity || style.fillOpacity; node.setAttributeNS(null, "x", x-(.5*width).toFixed()); node.setAttributeNS(null, "y", -y-(.5*height).toFixed()); @@ -213,7 +214,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, { node.setAttributeNS(null, "height", height); node.setAttributeNS("http://www.w3.org/1999/xlink", "href", style.externalGraphic); node.setAttributeNS(null, "transform", "scale(1,-1)"); - node.setAttributeNS(null, "style", "opacity: "+style.fillOpacity); + node.setAttributeNS(null, "style", "opacity: "+opacity); } else { node.setAttributeNS(null, "r", style.pointRadius); } diff --git a/lib/OpenLayers/Renderer/VML.js b/lib/OpenLayers/Renderer/VML.js index 7dbc518a2f..1c39759f21 100644 --- a/lib/OpenLayers/Renderer/VML.js +++ b/lib/OpenLayers/Renderer/VML.js @@ -210,7 +210,12 @@ OpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, { fill = this.createNode('v:fill', node.id + "_fill"); node.appendChild(fill); } - if (style.fillOpacity) { + // if graphicOpacity is set use it in priority for external graphic + if (node._geometryClass == "OpenLayers.Geometry.Point" && + style.externalGraphic && + style.graphicOpacity) { + fill.setAttribute("opacity", style.graphicOpacity); + } else if (style.fillOpacity) { fill.setAttribute("opacity", style.fillOpacity); } } diff --git a/tests/Layer/test_Vector.html b/tests/Layer/test_Vector.html index 4d0d4d37d0..d6da02cd17 100644 --- a/tests/Layer/test_Vector.html +++ b/tests/Layer/test_Vector.html @@ -157,15 +157,15 @@ } function test_Layer_Vector_externalGraphic(t) { - t.plan(8); - // base layer is needed for getResolution() to return a value, - // otherwise VML test will fail because style.left and style.top - // cannot be set - var baseLayer = new OpenLayers.Layer.WMS("Base Layer", - "http://octo.metacarta.com/cgi-bin/mapserv", - { map: '/mapdata/vmap_wms.map', - layers: 'basic', - format: 'image/png'}); + t.plan(9); + // base layer is needed for getResolution() to return a value, + // otherwise VML test will fail because style.left and style.top + // cannot be set + var baseLayer = new OpenLayers.Layer.WMS("Base Layer", + "http://octo.metacarta.com/cgi-bin/mapserv", + { map: '/mapdata/vmap_wms.map', + layers: 'basic', + format: 'image/png'}); var layer = new OpenLayers.Layer.Vector("Test Layer"); var map = new OpenLayers.Map('map'); @@ -191,6 +191,11 @@ graphicWidth: 24, graphicHeight: 16 }); + var customStyle5 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicOpacity: 1 + }); var root = layer.renderer.root; if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') { @@ -222,10 +227,15 @@ layer.drawFeature(feature); t.eq(root.firstChild.getAttributeNS(null, 'height'), customStyle4.graphicHeight.toString(), - "given graphicHeight and graphicWidth, both are set: height") + "given graphicHeight and graphicWidth, both are set: height"); t.eq(root.firstChild.getAttributeNS(null, 'width'), customStyle4.graphicWidth.toString(), - "given graphicHeight and graphicWidth, both are set: width") + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'style'), + 'opacity: '+customStyle5.graphicOpacity.toString()+';', + "graphicOpacity correctly set"); } if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') { feature.style = customStyle1; @@ -256,10 +266,19 @@ layer.drawFeature(feature); t.eq(root.firstChild.style.height, customStyle4.graphicHeight.toString()+'px', - "given graphicHeight and graphicWidth, both are set: height") + "given graphicHeight and graphicWidth, both are set: height"); t.eq(root.firstChild.style.width, customStyle4.graphicWidth.toString()+'px', - "given graphicHeight and graphicWidth, both are set: width") + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.drawFeature(feature); + var fill = root.firstChild.getElementsByTagName("fill")[0]; + if (fill == null) fill = root.firstChild.getElementsByTagName("v:fill"); + var opacity = fill.getAttribute('opacity'); + t.eq(opacity, + customStyle5.graphicOpacity, + "graphicOpacity correctly set"); + } }