OpenLayers OpenLayers

Ticket #1433: 1433-r6497-A0.patch

File 1433-r6497-A0.patch, 10.3 kB (added by ahocevar, 10 months ago)
  • examples/styles-rotation.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <style type="text/css"> 
     4        #map { 
     5            width: 800px; 
     6            height: 475px; 
     7            border: 1px solid black; 
     8        } 
     9    </style> 
     10    <script src="../lib/OpenLayers.js" type="text/javascript"></script> 
     11    <script type="text/javascript"> 
     12         
     13        var map; 
     14        var vectors; 
     15         
     16        function init(){ 
     17            map = new OpenLayers.Map('map'); 
     18            var wms = new OpenLayers.Layer.WMS( 
     19                "OpenLayers WMS",  
     20                "http://labs.metacarta.com/wms/vmap0", 
     21                {layers: 'basic'} 
     22            ); 
     23 
     24            vectors = new OpenLayers.Layer.Vector( 
     25                "Simple Geometry", 
     26                { 
     27                    styleMap: new OpenLayers.StyleMap({ 
     28                        "default": { 
     29                            externalGraphic: "../img/marker-gold.png", 
     30                            //graphicWidth: 17, 
     31                            graphicHeight: 20, 
     32                            graphicYOffset: -19, 
     33                            rotation: "${angle}", 
     34                            fillOpacity: "${opacity}" 
     35                        }, 
     36                        "select": { 
     37                            externalGraphic: "../img/marker.png" 
     38                        } 
     39                    }) 
     40                } 
     41            ); 
     42             
     43            map.addLayers([wms, vectors]); 
     44             
     45            var features = []; 
     46            var x = -111.04; 
     47            var y = 45.68; 
     48            for(var i = 0; i < 10; i++){ 
     49                x += i * .5; 
     50                y += i * .1; 
     51                features.push( 
     52                    new OpenLayers.Feature.Vector( 
     53                        new OpenLayers.Geometry.Point(x, y), {angle: (i*36)%360-180, opacity:i/10+.1} 
     54                    ) 
     55                ); 
     56                features.push( 
     57                    new OpenLayers.Feature.Vector( 
     58                        new OpenLayers.Geometry.Point(x, y), {angle: (i*36)%360, opacity:i/10+.1} 
     59                    ) 
     60                ); 
     61            } 
     62             
     63            map.setCenter(new OpenLayers.LonLat(x-10, y), 5); 
     64            vectors.addFeatures(features); 
     65        }; 
     66         
     67    </script> 
     68  </head> 
     69  <body onload="init()"> 
     70    <div id="map"></div> 
     71    <p>Use the pan buttons.  See flicker at end of animated pan.</p> 
     72  </body> 
     73</html> 
  • lib/OpenLayers/Renderer/SVG.js

    old new  
    222223            } else { 
    223224                node.setAttributeNS(null, "r", style.pointRadius); 
    224225            } 
     226 
     227            if (style.rotation) { 
     228                var rotation = OpenLayers.String.format( 
     229                    "rotate(${0} ${1} ${2})", [style.rotation, x, y]); 
     230                node.setAttributeNS(null, "transform", rotation); 
     231            } 
    225232        } 
    226233         
    227234        if (options.isFilled) { 
  • lib/OpenLayers/Renderer/VML.js

    old new  
    171171                node.style.top = ((geometry.y/resolution)-(yOffset+height)).toFixed(); 
    172172                node.style.width = width; 
    173173                node.style.height = height;     
     174                node.style.flip = "y"; 
    174175                 
    175176                // modify style/options for fill and stroke styling below 
    176177                style.fillColor = "none"; 
     
    176177                style.fillColor = "none"; 
    177178                options.isStroked = false; 
    178179                          
     180                // alternative way of graphic rendering for rotated graphics 
     181                if (style.rotation) { 
     182                    this.graphicRotate(node, xOffset, yOffset); 
     183                } 
     184 
    179185            } else { 
    180186                this.drawCircle(node, geometry, style.pointRadius); 
    181187            } 
     
    209215                 
    210216                fill.setAttribute("src", style.externalGraphic); 
    211217                fill.setAttribute("type", "frame"); 
    212                 node.style.flip = "y"; 
    213218                 
    214219                if (!(style.graphicWidth && style.graphicHeight)) { 
    215220                  fill.aspect = "atmost"; 
     
    250255    }, 
    251256 
    252257    /** 
     258     * Method: graphicRotate 
     259     * If a point is to be styled with externalGraphic and rotation, VML fills 
     260     * cannot be used to display the graphic, because rotation of graphic 
     261     * fills is not supported by the VML implementation of Internet Explorer. 
     262     * This method creates a HTML div inside the VML node, uses 
     263     * DXImageTransform.AlphaImageLoader to load the image (which results 
     264     * in smooth bilinear scaling of the graphic and better alpha handling), 
     265     * and DXImageTransform.Matrix and Alpha filters for rotation and opacity. 
     266     * Finally, OpenLayers methods are used to determine the correct insertion 
     267     * point of the rotated image, because DXImageTransform.Matrix does the 
     268     * rotation without the ability to specify a rotation center point. 
     269     *  
     270     * Parameters: 
     271     * node    - {DOMElement} 
     272     * xOffset - {Number} 
     273     * yOffset - {Number} 
     274     */ 
     275    graphicRotate: function(node, xOffset, yOffset) { 
     276        var style = node._style; 
     277        var options = node._options; 
     278         
     279        var aspectRatio, size; 
     280        if (!(style.graphicWidth && style.graphicHeight)) { 
     281            // load the image to determine its size 
     282            var img = new Image(); 
     283            img.src = style.externalGraphic; 
     284            aspectRatio = img.width / img.height; 
     285            size = Math.max(style.pointRadius * 2, style.graphicWidth || 0, 
     286                style.graphicHeight || 0); 
     287            xOffset = xOffset * aspectRatio; 
     288        } else { 
     289            size = Math.max(style.graphicWidth, style.graphicHeight); 
     290            aspectRatio = style.graphicWidth / style.graphicHeight; 
     291        } 
     292         
     293        width = Math.round(style.graphicWidth || size * aspectRatio); 
     294        height = Math.round(style.graphicHeight || size); 
     295        node.style.width = width; 
     296        node.style.height = height; 
     297         
     298        var image = document.getElementById(node.id + "_image"); 
     299        if (!image) { 
     300            image = this.createNode("div", node.id + "_image"); 
     301            node.appendChild(image); 
     302        } 
     303        image.style.width = width; 
     304        image.style.height = height; 
     305        // load the image 
     306        image.style.filter = 
     307            "progid:DXImageTransform.Microsoft.AlphaImageLoader(" +  
     308            "src='" + style.externalGraphic + "', sizingMethod='scale')"; 
     309 
     310        var rotation = style.rotation * Math.PI / 180; 
     311        var sintheta = Math.sin(rotation); 
     312        var costheta = Math.cos(rotation); 
     313 
     314        // do the rotation on the image 
     315        var filter = 
     316            "progid:DXImageTransform.Microsoft.Matrix(M11=" + costheta + 
     317            ",M12=" + (-sintheta) + ",M21=" + sintheta + ",M22=" + costheta + 
     318            ",SizingMethod='auto expand')\n" 
     319 
     320        var opacity = style.graphicOpacity || style.fillOpacity; 
     321        if (opacity && opacity != 1) { 
     322            filter +=  
     323                "progid:DXImageTransform.Microsoft.Alpha(opacity=" +  
     324                opacity*100+")\n"; 
     325        } 
     326        node.style.filter = filter; 
     327 
     328        // do the rotation again on a box, so we know the insertion point 
     329        var centerPoint = new OpenLayers.Geometry.Point(-xOffset, -yOffset); 
     330        var imgBox = new OpenLayers.Bounds(0, 0, width, height).toGeometry(); 
     331        imgBox.rotate(style.rotation, centerPoint); 
     332        var imgBounds = imgBox.getBounds(); 
     333 
     334        node.style.left = Math.round( 
     335            parseInt(node.style.left) + imgBounds.left); 
     336        node.style.top = Math.round( 
     337            parseInt(node.style.top) - imgBounds.bottom); 
     338 
     339        // turn off fill (we already have the graphic, and do not need the 
     340        // fill which we use for non-rotated graphics) 
     341        options.isFilled = false; 
     342    }, 
     343 
     344    /** 
    253345     * Method: postDraw 
    254346     * Some versions of Internet Explorer seem to be unable to set fillcolor 
    255347     * and strokecolor to "none" correctly before the fill node is appended to 
  • tests/Renderer/test_VML.html

    old new  
    143143        t.eq(node.style.width, (2 * radius) + "px", "width is correct"); 
    144144        t.eq(node.style.height, (2 * radius) + "px", "height is correct"); 
    145145    } 
     146     
     147    function test_VML_drawGraphic(t) { 
     148        if (!OpenLayers.Renderer.VML.prototype.supported()) { 
     149            t.plan(0); 
     150            return; 
     151        } 
     152         
     153        t.plan(6); 
     154         
     155        var r = new OpenLayers.Renderer.VML(document.body); 
     156        r.resolution = 1; 
     157         
     158        var node = document.createElement('div'); 
     159        node.id = "test" 
     160        node._geometryClass = "OpenLayers.Geometry.Point"; 
     161         
     162        var geometry = { 
     163            x: 1, 
     164            y: 2 
     165        } 
     166         
     167        var style = { 
     168            externalGraphic: "foo.png", 
     169            graphicWidth: 7, 
     170            graphicHeight: 10 
     171        } 
     172         
     173        r.drawGeometryNode(node, geometry, style); 
     174 
     175        t.eq(node.childNodes[0].id, "test_fill", "fill child node correctly created"); 
     176        t.eq(node.style.left, "-3px", "x of insertion point with calculated xOffset correct"); 
     177        t.eq(node.style.top, "-3px", "y of insertion point with calculated yOffset correct"); 
     178         
     179        style.rotation = 90; 
     180         
     181        r.drawGeometryNode(node, geometry, style); 
     182         
     183        t.eq(node.childNodes[0].id, "test_image", "image child node correctly created"); 
     184        t.eq(node.style.left, "-4px", "x of insertion point of rotated image correct"); 
     185        t.eq(node.style.top, "-4px", "y of insertion point of rotated image correct"); 
     186    } 
    146187 
    147188    function test_VML_drawlinestring(t) { 
    148189        if (!OpenLayers.Renderer.VML.prototype.supported()) {