OpenLayers OpenLayers

Changeset 3323

Show
Ignore:
Timestamp:
06/12/07 14:03:59 (1 year ago)
Author:
euzuro
Message:

patch for #487 -- dateline wrapping

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/BaseTypes.js

    r3150 r3323  
    298298        } 
    299299        return equals; 
     300    }, 
     301     
     302    /** 
     303     * @param {OpenLayers.Bounds} maxExtent 
     304     *  
     305     * @returns A copy of this lonlat, but wrapped around the "dateline" (as 
     306     *           specified by the borders of maxExtent) 
     307     * @type OpenLayers.LonLat 
     308     */ 
     309    wrapDateLine: function(maxExtent) {     
     310 
     311        var newLonLat = this.clone(); 
     312     
     313        if (maxExtent) { 
     314            //shift right? 
     315            while (newLonLat.lon < maxExtent.left) { 
     316                newLonLat.lon +=  maxExtent.getWidth(); 
     317            }     
     318            
     319            //shift left? 
     320            while (newLonLat.lon > maxExtent.right) { 
     321                newLonLat.lon -= maxExtent.getWidth(); 
     322            }     
     323        } 
     324                 
     325        return newLonLat; 
    300326    }, 
    301327     
     
    667693    }, 
    668694 
     695    /** 
     696     * @param {OpenLayers.Bounds} maxExtent 
     697     * @param {Object} options 
     698     *     @option {float} leftTolerance Allow for a margin of error with the  
     699     *                                    'left' value of this bound. 
     700     *                                    Default is 0 
     701     *     @option {float} rightTolerance Allow for a margin of error with the  
     702     *                                     'right' value of this bound. 
     703     *                                     Default is 0 
     704     *  
     705     * @returns A copy of this bounds, but wrapped around the "dateline" (as 
     706     *           specified by the borders of maxExtent). Note that this  
     707     *           function only returns a different bounds value if this bounds 
     708     *           is *entirely* outside of the maxExtent. If this bounds  
     709     *           straddles the dateline (is part in/part out of maxExtent), 
     710     *           the returned bounds will be merely a copy of this one. 
     711     * @type OpenLayers.Bounds 
     712     */ 
     713    wrapDateLine: function(maxExtent, options) {     
     714        options = options || new Object(); 
     715         
     716        var leftTolerance = options.leftTolerance || 0; 
     717        var rightTolerance = options.rightTolerance || 0; 
     718 
     719        var newBounds = this.clone(); 
     720     
     721        if (maxExtent) { 
     722 
     723           //shift right? 
     724           while ( newBounds.left < maxExtent.left &&  
     725                   (newBounds.right - rightTolerance) <= maxExtent.left ) {  
     726                newBounds = newBounds.add(maxExtent.getWidth(), 0); 
     727           } 
     728 
     729           //shift left? 
     730           while ( (newBounds.left + leftTolerance) >= maxExtent.right &&  
     731                   newBounds.right > maxExtent.right ) {  
     732                newBounds = newBounds.add(-maxExtent.getWidth(), 0); 
     733           } 
     734        } 
     735                 
     736        return newBounds; 
     737    }, 
     738     
    669739    /** @final @type String */ 
    670740    CLASS_NAME: "OpenLayers.Bounds" 
  • trunk/openlayers/lib/OpenLayers/Layer.js

    r3162 r3323  
    140140    /** @type Boolean */ 
    141141    displayOutsideMaxExtent: false, 
     142 
     143    /** wrapDateLine -- #487 for more info.    
     144     *  
     145     * @type @Boolean  
     146     */ 
     147    wrapDateLine: false, 
    142148     
    143149     
     
    165171            this.events = new OpenLayers.Events(this, this.div,  
    166172                                                this.EVENT_TYPES); 
     173        } 
     174 
     175        if (this.wrapDateLine) { 
     176            this.displayOutsideMaxExtent = true; 
    167177        } 
    168178    }, 
     
    617627                lonlat = new OpenLayers.LonLat(center.lon + delta_x * res , 
    618628                                             center.lat - delta_y * res);  
     629 
     630                if (this.wrapDateLine) { 
     631                    lonlat = lonlat.wrapDateLine(this.maxExtent); 
     632                } 
    619633            } // else { DEBUG STATEMENT } 
    620634        } 
     
    643657     
    644658    /** 
    645      * Adjusts the extent of a bounds in map units by the layer's gutter 
    646      * in pixels. 
    647      *  
    648      * @param {OpenLayers.Bounds} bounds 
    649      * @type OpenLayers.Bounds 
    650      * @return A bounds adjusted in height and width by the gutter 
    651      */ 
    652     adjustBoundsByGutter: function(bounds) { 
    653         var mapGutter = this.gutter * this.map.getResolution(); 
    654         bounds = new OpenLayers.Bounds(bounds.left - mapGutter, 
    655                                        bounds.bottom - mapGutter, 
    656                                        bounds.right + mapGutter, 
    657                                        bounds.top + mapGutter); 
    658         return bounds; 
    659     }, 
    660      
    661     /** 
    662659     * Sets the opacity for the entire layer (all images) 
    663660     * @param {Float} opacity 
     
    682679    }, 
    683680 
     681    /** 
     682    * This function will take a bounds, and if wrapDateLine option is set 
     683    * on the layer, it will return a bounds which is wrapped around the world. 
     684    * We do not wrap for bounds which *cross* the maxExtent.left/right, only 
     685    * bounds which are entirely to the left or entirely to the right. 
     686    * 
     687    * @param {OpenLayers.Bounds} bounds 
     688    * @private 
     689    */ 
     690    adjustBounds: function (bounds) { 
     691 
     692        if (this.gutter) { 
     693            // Adjust the extent of a bounds in map units by the  
     694            // layer's gutter in pixels. 
     695            var mapGutter = this.gutter * this.map.getResolution(); 
     696            bounds = new OpenLayers.Bounds(bounds.left - mapGutter, 
     697                                           bounds.bottom - mapGutter, 
     698                                           bounds.right + mapGutter, 
     699                                           bounds.top + mapGutter); 
     700        } 
     701 
     702        if (this.wrapDateLine) { 
     703            // wrap around the date line, within the limits of rounding error 
     704            var wrappingOptions = {  
     705                'rightTolerance':this.getResolution() 
     706            };     
     707            bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions); 
     708                               
     709        } 
     710        return bounds; 
     711    }, 
     712 
    684713    /** @final @type String */ 
    685714    CLASS_NAME: "OpenLayers.Layer" 
  • trunk/openlayers/lib/OpenLayers/Layer/KaMap.js

    r3087 r3323  
    5050     */ 
    5151    getURL: function (bounds) { 
     52        bounds = this.adjustBounds(bounds); 
    5253        var mapRes = this.map.getResolution(); 
    5354        var scale = Math.round((this.map.getScale() * 10000)) / 10000; 
  • trunk/openlayers/lib/OpenLayers/Layer/MapServer.js

    r2979 r3323  
    8888     */ 
    8989    getURL: function (bounds) { 
    90         if(this.gutter) { 
    91             bounds = this.adjustBoundsByGutter(bounds); 
    92         } 
     90        bounds = this.adjustBounds(bounds); 
    9391        // Make a list, so that getFullRequestString uses literal ","  
    9492        var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top]; 
  • trunk/openlayers/lib/OpenLayers/Layer/TMS.js

    r2821 r3323  
    7272     */ 
    7373    getURL: function (bounds) { 
     74        bounds = this.adjustBounds(bounds); 
    7475        var res = this.map.getResolution(); 
    7576        var x = (bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w); 
  • trunk/openlayers/lib/OpenLayers/Layer/WMS.js

    r3290 r3323  
    9595     */ 
    9696    getURL: function (bounds) { 
    97         if(this.gutter) { 
    98             bounds = this.adjustBoundsByGutter(bounds); 
    99         } 
     97        bounds = this.adjustBounds(bounds); 
    10098        return this.getFullRequestString( 
    10199                     {BBOX:bounds.toBBOX(), 
  • trunk/openlayers/lib/OpenLayers/Layer/WorldWind.js

    r1721 r3323  
    7070     */ 
    7171    getURL: function (bounds) { 
     72        bounds = this.adjustBounds(bounds); 
    7273        var zoom = this.getZoom(); 
    7374        var extent = this.map.getMaxExtent(); 
  • trunk/openlayers/lib/OpenLayers/Map.js

    r3282 r3323  
    11691169     */ 
    11701170    zoomToExtent: function(bounds) { 
    1171         this.setCenter(bounds.getCenterLonLat(),  
    1172                        this.getZoomForExtent(bounds)); 
     1171        var center = bounds.getCenterLonLat(); 
     1172        if (this.baseLayer.wrapDateLine) { 
     1173            var maxExtent = this.getMaxExtent(); 
     1174 
     1175            //fix straddling bounds (in the case of a bbox that straddles the  
     1176            // dateline, it's left and right boundaries will appear backwards.  
     1177            // we fix this by allowing a right value that is greater than the 
     1178            // max value at the dateline -- this allows us to pass a valid  
     1179            // bounds to calculate zoom) 
     1180            // 
     1181            bounds = bounds.clone(); 
     1182            while (bounds.right < bounds.left) { 
     1183                bounds.right += maxExtent.getWidth(); 
     1184            } 
     1185            //if the bounds was straddling (see above), then the center point  
     1186            // we got from it was wrong. So we take our new bounds and ask it 
     1187            // for the center. Because our new bounds is at least partially  
     1188            // outside the bounds of maxExtent, the new calculated center  
     1189            // might also be. We don't want to pass a bad center value to  
     1190            // setCenter, so we have it wrap itself across the date line. 
     1191            // 
     1192            center = bounds.getCenterLonLat().wrapDateLine(maxExtent); 
     1193        } 
     1194        this.setCenter(center, this.getZoomForExtent(bounds)); 
    11731195    }, 
    11741196 
  • trunk/openlayers/tests/BaseTypes/test_Bounds.html

    r2943 r3323  
    380380 
    381381     } 
     382      
     383      
     384     function test_16_Bounds_wrapDateLine(t) { 
     385        t.plan( 13 ); 
     386         
     387        var testBounds, wrappedBounds, desiredBounds; 
     388 
     389        var maxExtent = new OpenLayers.Bounds(-10,-10,10,10); 
     390        var exactBounds = maxExtent.clone(); 
     391        var simpleBounds = new OpenLayers.Bounds( -5,-5,5,5); 
     392 
     393 
     394 
     395    //bad maxextent 
     396        testBounds = simpleBounds.clone(); 
     397        wrappedBounds = testBounds.wrapDateLine(null); 
     398        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds with a bad maxextent does nothing"); 
     399 
     400 
     401 
     402    //exactly inside  
     403        testBounds = exactBounds.clone(); 
     404        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     405        t.ok(wrappedBounds.equals(exactBounds), "wrapping a bounds precisely within (equal to) maxextent does nothing"); 
     406 
     407 
     408    //inside  
     409        testBounds = simpleBounds.clone(); 
     410        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     411        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds within maxextent does nothing"); 
     412     
     413// LEFT // 
     414 
     415    //straddling left 
     416        testBounds = simpleBounds.add(-10,0); 
     417        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     418        t.ok(wrappedBounds.equals(testBounds), "wrapping a bounds that straddles the left of maxextent does nothing"); 
     419     
     420    //left rightTolerance 
     421        testBounds = simpleBounds.add(-14,0); 
     422        wrappedBounds =  
     423            testBounds.wrapDateLine(maxExtent, {'rightTolerance': 1} ); 
     424        desiredBounds = simpleBounds.add(6,0); 
     425        t.ok(wrappedBounds.equals(desiredBounds), "wrapping a bounds rightTolerance left of maxextent works"); 
     426 
     427    //exactly left 
     428        testBounds = exactBounds.add(-20,0); 
     429        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     430        t.ok(wrappedBounds.equals(exactBounds), "wrapping an exact bounds once left of maxextent works"); 
     431     
     432    //left 
     433        testBounds = simpleBounds.add(-20,0); 
     434        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     435        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds once left of maxextent works"); 
     436     
     437    //way left 
     438        testBounds = simpleBounds.add(-200,0); 
     439        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     440        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds way left of maxextent works"); 
     441 
     442// RIGHT // 
     443 
     444    //straddling right 
     445        testBounds = simpleBounds.add(10,0); 
     446        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     447        t.ok(wrappedBounds.equals(testBounds), "wrapping a bounds that straddles the right of maxextent does nothing"); 
     448     
     449    //right leftTolerance 
     450        testBounds = simpleBounds.add(14,0); 
     451        wrappedBounds =  
     452            testBounds.wrapDateLine(maxExtent, {'leftTolerance': 1} ); 
     453        desiredBounds = simpleBounds.add(-6,0); 
     454        t.ok(wrappedBounds.equals(desiredBounds), "wrapping a bounds leftTolerance right of maxextent works"); 
     455     
     456    //exactly right 
     457        testBounds = exactBounds.add(20,0); 
     458        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     459        t.ok(wrappedBounds.equals(exactBounds), "wrapping an exact bounds once right of maxextent works"); 
     460     
     461    //right 
     462        testBounds = simpleBounds.add(20,0); 
     463        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     464        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds once right of maxextent works"); 
     465     
     466    //way right 
     467        testBounds = simpleBounds.add(200,0); 
     468        wrappedBounds = testBounds.wrapDateLine(maxExtent); 
     469        t.ok(wrappedBounds.equals(simpleBounds), "wrapping a bounds way right of maxextent works"); 
     470 
     471 
     472 
     473      } 
    382474 
    383475  // --> 
  • trunk/openlayers/tests/BaseTypes/test_LonLat.html

    r2803 r3323  
    8989    } 
    9090 
     91    function test_08_LonLat_wrapDateLine(t) { 
     92        t.plan( 6 ); 
     93 
     94        var goodLL = new OpenLayers.LonLat(0,0); 
     95        var testLL, wrappedLL; 
     96 
     97  //bad maxextent 
     98        var maxExtent = null; 
     99 
     100        testLL = goodLL.clone(); 
     101        wrappedLL = testLL.wrapDateLine(maxExtent); 
     102        t.ok(wrappedLL.equals(goodLL), "wrapping a ll with a bad maxextent does nothing"); 
     103         
     104         
     105  //good maxextent 
     106        maxExtent = new OpenLayers.Bounds(-10,-10,10,10); 
     107 
     108    //inside 
     109        testLL = goodLL.clone(); 
     110        wrappedLL = testLL.wrapDateLine(maxExtent); 
     111        t.ok(wrappedLL.equals(goodLL), "wrapping a ll within the maxextent does nothing"); 
     112         
     113    //left 
     114        testLL = goodLL.add(-20,0); 
     115        wrappedLL = testLL.wrapDateLine(maxExtent); 
     116        t.ok(wrappedLL.equals(goodLL), "wrapping a ll once left of maxextent works"); 
     117         
     118    //way left 
     119        testLL = goodLL.add(-200,0); 
     120        wrappedLL = testLL.wrapDateLine(maxExtent); 
     121        t.ok(wrappedLL.equals(goodLL), "wrapping a ll way left of maxextent works"); 
     122 
     123    //right 
     124        testLL = goodLL.add(20,0); 
     125        wrappedLL = testLL.wrapDateLine(maxExtent); 
     126        t.ok(wrappedLL.equals(goodLL), "wrapping a ll once right of maxextent works"); 
     127         
     128    //way right 
     129        testLL = goodLL.add(200,0); 
     130        wrappedLL = testLL.wrapDateLine(maxExtent); 
     131        t.ok(wrappedLL.equals(goodLL), "wrapping a ll way right of maxextent works"); 
     132 
     133    } 
     134 
    91135  // --> 
    92136  </script> 
  • trunk/openlayers/tests/list-tests.html

    r3320 r3323  
    5050    <li>Layer/test_Vector.html</li> 
    5151    <li>Layer/test_GML.html</li> 
     52    <li>Layer/test_WrapDateLine.html</li> 
    5253    <li>test_Tile.html</li> 
    5354    <li>Tile/test_Image.html</li>