OpenLayers OpenLayers

Changeset 2979

Show
Ignore:
Timestamp:
04/02/07 13:18:38 (2 years ago)
Author:
tschaub
Message:

#529 give tiles gutters - all layers that use Tile.Image must now look after layer.imageSize and layer.imageOffset - this is handled by layer.setTileSize - for untiled layers, setTileSize must be defined by the subclass - gutters are currently supported in Layer.Mapserver and Layer.WMS

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/examples/mapserver.html

    r2978 r2979  
    1919            map = new OpenLayers.Map( 'map' ); 
    2020            layer = new OpenLayers.Layer.MapServer( "OpenLayers WMS",  
    21                     "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); 
     21                    "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'}, 
     22                    {gutter: 15}); 
    2223            map.addLayer(layer); 
    2324 
  • trunk/openlayers/examples/mapserver_untiled.html

    r2978 r2979  
    33    <style type="text/css"> 
    44        #map { 
    5             width: 800px
    6             height: 475px
     5            width: 100%
     6            height: 100%
    77            border: 1px solid black; 
    88        } 
  • trunk/openlayers/lib/OpenLayers/Layer.js

    r2894 r2979  
    6666     */ 
    6767    inRange: false, 
     68     
     69    /** 
     70     * For layers that use Tile.Image, the image size is cached here.  For 
     71     * layers without a gutter, the image size is equal to the tile size. 
     72     * For layers with a gutter, the image is larger than the tile by twice 
     73     * the gutter in each dimension. 
     74     *  
     75     * @type OpenLayers.Size 
     76     * @private 
     77     */ 
     78    imageSize: null, 
     79     
     80    /** 
     81     * For layers that use Tile.Image, the image offset is cached here. 
     82     * Layers without a gutter have zero offset.  For layers with a gutter, 
     83     * the image offset represents displacement due to the gutter. 
     84     *  
     85     * @type OpenLayers.Pixel 
     86     * @private 
     87     */ 
     88    imageOffset: null, 
    6889 
    6990  // OPTIONS 
     
    7192    /** @type Array */ 
    7293    options: null, 
     94 
     95    /** Determines the width (in pixels) of the gutter around image tiles  
     96     * to ignore.  By setting this property to a non-zero value, images  
     97     * will be requested that are wider and taller than the tile size by  
     98     * a value of 2 x gutter.  This allows artifacts of rendering at tile  
     99     * edges to be ignored.  Set a gutter value that is equal to half the size  
     100     * of the widest symbol that needs to be displayed.  Defaults to zero. 
     101     * Non-tiled layers always have zero gutter. 
     102     *   
     103     * @type Int  
     104    */  
     105    gutter: 0,  
    73106 
    74107    /** @type String */ 
     
    244277        if (!this.isBaseLayer) { 
    245278            this.inRange = this.calculateInRange(); 
    246         }     
     279        } 
     280         
     281        // deal with gutters 
     282        this.setTileSize(); 
    247283    }, 
    248284   
     285    /** 
     286     * Set the tile size based on the map size.  This also sets layer.imageSize 
     287     * and layer.imageOffset for use by Tile.Image. 
     288     * 
     289     * @param OpenLayers.Size 
     290     */ 
     291    setTileSize: function(size) { 
     292        var tileSize = (size) ? size : 
     293                                ((this.tileSize) ? this.tileSize : 
     294                                                   this.map.getTileSize()); 
     295        this.tileSize = tileSize; 
     296        if(this.gutter) { 
     297            // layers with gutters need non-null tile sizes 
     298            //if(tileSize == null) { 
     299            //    OpenLayers.console.error("Error in layer.setMap() for " + 
     300            //                              this.name + ": layers with gutters " + 
     301            //                              "need non-null tile sizes"); 
     302            //} 
     303            this.imageOffset = new OpenLayers.Pixel(-this.gutter, -this.gutter);  
     304            this.imageSize = new OpenLayers.Size(tileSize.w + (2 * this.gutter),  
     305                                                 tileSize.h + (2 * this.gutter));  
     306        } else { 
     307            // layers without gutters may have null tile size - as long 
     308            // as they don't rely on Tile.Image 
     309            this.imageSize = tileSize; 
     310            this.imageOffset = new OpenLayers.Pixel(0, 0); 
     311        } 
     312    }, 
     313 
    249314    /** 
    250315    * @returns Whether or not the layer should be displayed (if in range) 
     
    561626     
    562627    /** 
     628     * Adjusts the extent of a bounds in map units by the layer's gutter 
     629     * in pixels. 
     630     *  
     631     * @param {OpenLayers.Bounds} bounds 
     632     * @type OpenLayers.Bounds 
     633     * @return A bounds adjusted in height and width by the gutter 
     634     */ 
     635    adjustBoundsByGutter: function(bounds) { 
     636        var mapGutter = this.gutter * this.map.getResolution(); 
     637        bounds = new OpenLayers.Bounds(bounds.left - mapGutter, 
     638                                       bounds.bottom - mapGutter, 
     639                                       bounds.right + mapGutter, 
     640                                       bounds.top + mapGutter); 
     641        return bounds; 
     642    }, 
     643     
     644    /** 
    563645     * Sets the opacity for the entire layer (all images) 
    564646     * @param {Float} opacity 
     
    567649        this.opacity = opacity; 
    568650        for(var i=0; i<this.div.childNodes.length; ++i) { 
    569             var element = this.div.childNodes[i]
     651            var element = this.div.childNodes[i].firstChild
    570652            OpenLayers.Util.modifyDOMElement(element, null, null, null,  
    571653                                             null, null, null, opacity); 
  • trunk/openlayers/lib/OpenLayers/Layer/MapServer.js

    r2920 r2979  
    8888     */ 
    8989    getURL: function (bounds) { 
    90          
     90        if(this.gutter) { 
     91            bounds = this.adjustBoundsByGutter(bounds); 
     92        } 
    9193        // Make a list, so that getFullRequestString uses literal ","  
    9294        var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top]; 
     
    9698                     {mapext:   extent, 
    9799                      imgext:   extent, 
    98                       map_size: [this.tileSize.w,this.tileSize.h], 
    99                       imgx:     this.tileSize.w/2, 
    100                       imgy:     this.tileSize.h/2, 
    101                       imgxy:    [this.tileSize.w,this.tileSize.h] 
     100                      map_size: [this.imageSize.w, this.imageSize.h], 
     101                      imgx:     this.imageSize.w / 2, 
     102                      imgy:     this.imageSize.h / 2, 
     103                      imgxy:    [this.imageSize.w, this.imageSize.h] 
    102104                      }); 
    103105         
  • trunk/openlayers/lib/OpenLayers/Layer/MapServer/Untiled.js

    r2978 r2979  
    100100     */ 
    101101    setMap: function(map) { 
    102         //determine new tile size 
    103         this.tileSize = map.getSize(); 
    104         this.tileSize.w = this.tileSize.w * this.ratio; 
    105         this.tileSize.h = this.tileSize.h * this.ratio; 
    106102        OpenLayers.Layer.HTTPRequest.prototype.setMap.apply(this, arguments); 
     103    }, 
     104     
     105    /** 
     106     * Set the tile size based on the map size.  This also sets layer.imageSize 
     107     * and layer.imageOffset for use by Tile.Image. 
     108     */ 
     109    setTileSize: function() { 
     110        var tileSize = this.map.getSize(); 
     111        tileSize.w = tileSize.w * this.ratio; 
     112        tileSize.h = tileSize.h * this.ratio; 
     113        this.tileSize = tileSize; 
     114        this.imageSize = tileSize; 
     115        this.imageOffset = new OpenLayers.Pixel(0, 0); 
    107116    }, 
    108117 
     
    150159 
    151160            //determine new tile size 
    152             this.tileSize = this.map.getSize(); 
    153             this.tileSize.w = this.tileSize.w * this.ratio; 
    154             this.tileSize.h = this.tileSize.h * this.ratio; 
     161            this.setTileSize(); 
    155162 
    156163            //formulate request url string 
  • trunk/openlayers/lib/OpenLayers/Layer/WMS.js

    r2543 r2979  
    2525     
    2626    reproject: true, 
    27  
     27  
    2828    /** 
    2929    * @constructor 
     
    9494     */ 
    9595    getURL: function (bounds) { 
     96        if(this.gutter) { 
     97            bounds = this.adjustBoundsByGutter(bounds); 
     98        } 
    9699        return this.getFullRequestString( 
    97100                     {BBOX:bounds.toBBOX(), 
    98                       WIDTH:this.tileSize.w, 
    99                       HEIGHT:this.tileSize.h}); 
     101                      WIDTH:this.imageSize.w, 
     102                      HEIGHT:this.imageSize.h}); 
    100103    }, 
    101104 
     
    110113    */ 
    111114    addTile:function(bounds,position) { 
    112         url = this.getURL(bounds); 
     115        var url = this.getURL(bounds); 
    113116        return new OpenLayers.Tile.Image(this, position, bounds,  
    114117                                             url, this.tileSize); 
  • trunk/openlayers/lib/OpenLayers/Layer/WMS/Untiled.js

    r2974 r2979  
    103103     */ 
    104104    setMap: function(map) { 
    105         //determine new tile size 
    106         this.tileSize = map.getSize(); 
    107         this.tileSize.w = this.tileSize.w * this.ratio; 
    108         this.tileSize.h = this.tileSize.h * this.ratio; 
    109105        OpenLayers.Layer.HTTPRequest.prototype.setMap.apply(this, arguments); 
     106    }, 
     107 
     108    /** 
     109     * Set the tile size based on the map size.  This also sets layer.imageSize 
     110     * and layer.imageOffset for use by Tile.Image. 
     111     */ 
     112    setTileSize: function() { 
     113        var tileSize = this.map.getSize(); 
     114        tileSize.w = tileSize.w * this.ratio; 
     115        tileSize.h = tileSize.h * this.ratio; 
     116        this.tileSize = tileSize; 
     117        this.imageSize = tileSize; 
     118        this.imageOffset = new OpenLayers.Pixel(0, 0); 
    110119    }, 
    111120 
     
    153162 
    154163            //determine new tile size 
    155             this.tileSize = this.map.getSize(); 
    156             this.tileSize.w = this.tileSize.w * this.ratio; 
    157             this.tileSize.h = this.tileSize.h * this.ratio; 
     164            this.setTileSize(); 
    158165 
    159166            //formulate request url string 
  • trunk/openlayers/lib/OpenLayers/Tile/Image.js

    r2917 r2979  
    1616    imgDiv: null, 
    1717 
     18    /** 
     19     * The image element is appended to the frame.  Any gutter on the image  
     20     * will be hidden behind the frame.  
     21     *  
     22     * @type DOMElement div */  
     23    frame: null,  
     24 
    1825    /**  
    1926    * @constructor 
     
    2734    initialize: function(layer, position, bounds, url, size) { 
    2835        OpenLayers.Tile.prototype.initialize.apply(this, arguments); 
     36        this.frame = document.createElement('div');  
     37        this.frame.style.overflow = 'hidden';  
     38        this.frame.style.position = 'absolute';  
    2939    }, 
    3040 
     
    3545        if (this.imgDiv != null)  { 
    3646            OpenLayers.Event.stopObservingElement(this.imgDiv.id); 
    37             if (this.imgDiv.parentNode == this.layer.div) { 
    38                 this.layer.div.removeChild(this.imgDiv); 
     47            if (this.imgDiv.parentNode == this.frame) { 
     48                this.frame.removeChild(this.imgDiv); 
    3949                this.imgDiv.map = null; 
    4050            } 
    4151        } 
    4252        this.imgDiv = null; 
     53        if ((this.frame != null) && (this.frame.parentNode == this.layer.div)) {  
     54            this.layer.div.removeChild(this.frame);  
     55        } 
     56        this.frame = null;  
    4357        OpenLayers.Tile.prototype.destroy.apply(this, arguments); 
    4458    }, 
     
    6175         
    6276        this.url = this.layer.getURL(this.bounds); 
    63    
     77        // position the frame  
     78        OpenLayers.Util.modifyDOMElement(this.frame,  
     79                                         null, this.position, this.size);    
     80 
    6481        if (this.layer.alpha) { 
    6582            OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv, 
    66                     null, this.position, this.size, this.url); 
     83                    null, null, this.layer.imageSize, this.url); 
    6784        } else { 
    6885            this.imgDiv.src = this.url; 
    6986            OpenLayers.Util.modifyDOMElement(this.imgDiv, 
    70                     null, this.position, this.size) ; 
     87                    null, null, this.layer.imageSize) ; 
    7188        } 
    7289        this.drawn = true; 
     
    103120        if (this.layer.alpha) { 
    104121            this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null, 
    105                                                            this.position
    106                                                            this.size, 
     122                                                           this.layer.imageOffset
     123                                                           this.layer.imageSize, 
    107124                                                           null, 
    108                                                            "absolute", 
     125                                                           "relative", 
    109126                                                           null, 
    110127                                                           null, 
     
    113130        } else { 
    114131            this.imgDiv = OpenLayers.Util.createImage(null, 
    115                                                       this.position
    116                                                       this.size, 
     132                                                      this.layer.imageOffset
     133                                                      this.layer.imageSize, 
    117134                                                      null, 
    118                                                       "absolute", 
     135                                                      "relative", 
    119136                                                      null, 
    120137                                                      null, 
     
    132149                        this.checkImgURL.bindAsEventListener(this) ); 
    133150        */ 
    134         this.layer.div.appendChild(this.imgDiv); 
     151        this.frame.appendChild(this.imgDiv);  
     152        this.layer.div.appendChild(this.frame);  
     153 
    135154        if(this.layer.opacity != null) { 
    136155             
  • trunk/openlayers/tests/Layer/test_MapServer.html

    r2978 r2979  
    5555             url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"), 
    5656             "image src is created correctly via addtile" ); 
    57         t.eq( tile.imgDiv.style.top, "6px", "image top is set correctly via addtile" ); 
    58         t.eq( tile.imgDiv.style.left, "5px", "image top is set correctly via addtile" ); 
    59  
    60         var firstChild = layer.div.firstChild
     57        t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" ); 
     58        t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" ); 
     59 
     60        var firstChild = layer.div.firstChild.firstChild
    6161        if (!isMozilla) 
    6262            t.ok( true, "skipping element test outside of Mozilla"); 
     
    187187        map.zoomToMaxExtent(); 
    188188        t.eq(tLayer.opacity, "0.5", "Opacity is set correctly"); 
    189         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
     189        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
    190190        tLayer.setOpacity("0.6"); 
    191191        t.eq(tLayer.opacity, "0.6", "setOpacity works properly"); 
    192         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
     192        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
    193193        var pixel = new OpenLayers.Pixel(5,6); 
    194194        var tile = tLayer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); 
  • trunk/openlayers/tests/Layer/test_MapServer_Untiled.html

    r2978 r2979  
    128128        map.zoomToMaxExtent(); 
    129129        t.eq(tLayer.opacity, "0.5", "Opacity is set correctly"); 
    130         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
     130        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
    131131        tLayer.setOpacity("0.6"); 
    132132        t.eq(tLayer.opacity, "0.6", "setOpacity works properly"); 
    133         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
     133        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
    134134 
    135135    }     
  • trunk/openlayers/tests/Layer/test_WMS.html

    r2852 r2979  
    5151             url + "?" + OpenLayers.Util.getParameterString(tParams), 
    5252             "image src is created correctly via addtile" ); 
    53         t.eq( tile.imgDiv.style.top, "6px", "image top is set correctly via addtile" ); 
    54         t.eq( tile.imgDiv.style.left, "5px", "image top is set correctly via addtile" ); 
    55  
    56         var firstChild = layer.div.firstChild
     53        t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" ); 
     54        t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" ); 
     55 
     56        var firstChild = layer.div.firstChild.firstChild
    5757        if (!isMozilla) 
    5858            t.ok( true, "skipping element test outside of Mozilla"); 
     
    192192        map.zoomToMaxExtent(); 
    193193        t.eq(tLayer.opacity, "0.5", "Opacity is set correctly"); 
    194         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
     194        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct"); 
    195195        tLayer.setOpacity("0.6"); 
    196196        t.eq(tLayer.opacity, "0.6", "setOpacity works properly"); 
    197         t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
     197        t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly"); 
    198198        var pixel = new OpenLayers.Pixel(5,6); 
    199199        var tile = tLayer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel); 
     
    230230 
    231231        map.destroy(); 
     232    } 
     233     
     234    function test_21_Layer_WMS_noGutters (t) {  
     235        t.plan(2); 
     236        var map = new OpenLayers.Map('map'); 
     237        var layer = new OpenLayers.Layer.WMS("no gutter layer", url, params, {gutter: 0}); 
     238        map.addLayer(layer); 
     239        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     240        var tile = layer.grid[0][0]; 
     241        var request = layer.getURL(tile.bounds); 
     242        var args = OpenLayers.Util.getArgs(request); 
     243        t.eq(parseInt(args['WIDTH']), 
     244             tile.size.w, 
     245             "layer without gutter requests images that are as wide as the tile"); 
     246        t.eq(parseInt(args['HEIGHT']), 
     247             tile.size.h, 
     248             "layer without gutter requests images that are as tall as the tile"); 
     249         
     250        layer.destroy(); 
     251        map.destroy(); 
     252    } 
     253 
     254    function test_22_Layer_WMS_gutters (t) {  
     255        t.plan(2); 
     256        var gutter = 15; 
     257        var map = new OpenLayers.Map('map'); 
     258        var layer = new OpenLayers.Layer.WMS("gutter layer", url, params, {gutter: gutter}); 
     259        map.addLayer(layer); 
     260        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     261        var tile = layer.grid[0][0]; 
     262        var request = layer.getURL(tile.bounds); 
     263        var args = OpenLayers.Util.getArgs(request); 
     264        t.eq(parseInt(args['WIDTH']), 
     265             tile.size.w + (2 * gutter), 
     266             "layer with gutter requests images that are wider by twice the gutter"); 
     267        t.eq(parseInt(args['HEIGHT']), 
     268             tile.size.h + (2 * gutter), 
     269             "layer with gutter requests images that are taller by twice the gutter"); 
     270 
     271        layer.destroy(); 
     272        map.destroy(); 
     273 
    232274    } 
    233275     
  • trunk/openlayers/tests/Tile/test_Image.html

    r2803 r2979  
    3030        var map = new OpenLayers.Map('map'); 
    3131         
    32         layer = new OpenLayers.Layer.WMS("Name", "http://labs.metacarta.com/TESTURL");   
     32        var size = new OpenLayers.Size(5,6); 
     33        layer = new OpenLayers.Layer.WMS("Name", 
     34                                         "http://labs.metacarta.com/TESTURL", 
     35                                         null, 
     36                                         {tileSize: size});   
    3337        map.addLayer(layer);   
    3438        var position = new OpenLayers.Pixel(20,30); 
    3539        var bounds = new OpenLayers.Bounds(1,2,3,4); 
    3640        var url = "http://www.openlayers.org/dev/tests/tileimage"; 
    37         var size = new OpenLayers.Size(5,6); 
    3841        tile = new OpenLayers.Tile.Image(layer, position, bounds, url, size); 
    3942         
     
    5457            EXCEPTIONS: "application/vnd.ogc.se_inimage", FORMAT: "image/jpeg", 
    5558            SRS: "EPSG:4326", BBOX: "1,2,3,4", 
    56             WIDTH: "256", HEIGHT: "256" 
     59            WIDTH: String(size.w), HEIGHT: String(size.h) 
    5760        }; 
    5861        t.eq( img.src, 
     
    168171         
    169172    } 
     173 
     174    function test_05_Tile_Image_gutters(t) { 
     175        t.plan(5); 
     176         
     177        var gutter = 0; 
     178        var name = 'Test Layer'; 
     179        var url = "http://octo.metacarta.com/cgi-bin/mapserv"; 
     180        var params = { map: '/mapdata/vmap_wms.map',  
     181                       layers: 'basic',  
     182                       format: 'image/png'}; 
     183 
     184 
     185        var map = new OpenLayers.Map('map'); 
     186        var layer = new OpenLayers.Layer.WMS(name, url, params, {gutter: gutter}); 
     187        map.addLayer(layer); 
     188        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     189         
     190        var tile = layer.grid[0][0]; 
     191         
     192        t.ok(tile.layer.imageSize.equals(tile.size), 
     193             "zero size gutter doesn't change image size");  
     194 
     195        t.ok(tile.layer.imageOffset.equals(new OpenLayers.Pixel(0, 0)), 
     196             "zero size gutter doesn't affect image offset"); 
     197 
     198        map.destroy(); 
     199         
     200        var gutter = 15; 
     201        var map = new OpenLayers.Map('map'); 
     202        var layer = new OpenLayers.Layer.WMS(name, url, params, {gutter: gutter}); 
     203        map.addLayer(layer); 
     204        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     205        var tile = layer.grid[0][0]; 
     206        t.ok(tile.layer.imageSize.equals(new OpenLayers.Size(tile.size.w + (2 * gutter), 
     207                                                             tile.size.h + (2 * gutter))), 
     208             "gutter properly changes image size");  
     209 
     210        t.ok(tile.layer.imageOffset.equals(new OpenLayers.Pixel(-gutter, -gutter)), 
     211             "gutter properly sets image offset"); 
     212 
     213        t.ok(tile.bounds.equals(new OpenLayers.Bounds(-33.75, 33.75, -22.5, 45)), 
     214             "gutter doesn't affect tile bounds"); 
     215 
     216        map.destroy(); 
     217    } 
     218     
    170219  // --> 
    171220  </script> 
    172221</head> 
    173222<body> 
    174 <div id="map" style="height:500px;width:500px"></div> 
     223<div id="map" style="height:550px;width:500px"></div> 
    175224</body> 
    176225</html>