Merge pull request #82 from fredj/2897

don't create div for image tile when no gutter is used. p=ahocevar,pgiraud,elemoine,fredj
This commit is contained in:
Frédéric Junod
2011-12-07 23:03:26 -08:00
9 changed files with 114 additions and 108 deletions

View File

@@ -13,26 +13,6 @@
}
</style>
<script src="../lib/OpenLayers.js"></script>
<script type="text/javascript">
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 2;
var map;
window.onload = function() {
options = {maxExtent: new OpenLayers.Bounds(-73.5295, 41.2318,
-69.9097, 42.8883),
maxResolution: 0.0003};
map = new OpenLayers.Map('map', options);
var roads15 = new OpenLayers.Layer.WMS( "Roads (15px gutter)",
"http://boston.freemap.in/cgi-bin/mapserv?map=/www/freemap.in/boston/map/gmaps.map&",
{layers: 'roads_200_40'},
{gutter: 15});
var roads = new OpenLayers.Layer.WMS( "Roads (no gutter)",
"http://boston.freemap.in/cgi-bin/mapserv?map=/www/freemap.in/boston/map/gmaps.map&",
{layers: 'roads_200_40'});
map.addLayers([roads, roads15]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.setCenter(new OpenLayers.LonLat(-71.848, 42.2), 0);
}
</script>
</head>
<body>
<h1 id="title">Gutter Example</h1>
@@ -42,19 +22,34 @@
</div>
<p id="shortdesc">
Demonstrates map tiling artifacts, and OpenLayer's facility for correcting this distortion.
Demonstrates OpenLayer's facility for dealing with tiling artifacts.
</p>
<div id="map" class="smallmap"></div>
<div id="docs">
<p class="caption">
When you render tiles with certain types of symbols, there are artifacts
at tile edges that make symbology not look continuous. In the center of
the above map (when it first loads), the large orange road is split
vertically by a tile. Open the layer switcher and change to the layer
with a 15 pixel gutter to see how the symbology looks nicer.
When you render tiles with certain types of symbols, some map
servers may render artifacts at tile edges that make symbology not
look continuous. Look at the state abbreviations, open the layer
switcher and change to the layer with a 15 pixel gutter to see how
the symbology looks different (the server in this example doesn't
render such artifacts, so the client-side gutter won't make things
look nicer).
</p>
</div>
</body>
<script type="text/javascript">
var map = new OpenLayers.Map('map');
var states15 = new OpenLayers.Layer.WMS( "States (15px gutter)",
"http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'},
{gutter: 15});
var states = new OpenLayers.Layer.WMS( "Roads (no gutter)",
"http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'});
map.addLayers([states, states15]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.setCenter(new OpenLayers.LonLat(-71.848, 42.2), 5);
</script>
</html>

View File

@@ -1271,8 +1271,9 @@ OpenLayers.Layer = OpenLayers.Class({
setOpacity: function(opacity) {
if (opacity != this.opacity) {
this.opacity = opacity;
for(var i=0, len=this.div.childNodes.length; i<len; ++i) {
var element = this.div.childNodes[i].firstChild;
var childNodes = this.div.childNodes;
for(var i = 0, len = childNodes.length; i < len; ++i) {
var element = childNodes[i].firstChild || childNodes[i];
OpenLayers.Util.modifyDOMElement(element, null, null, null,
null, null, null, opacity);
}

View File

@@ -35,7 +35,8 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
/**
* Property: frame
* {DOMElement} The image element is appended to the frame. Any gutter on
* the image will be hidden behind the frame.
* the image will be hidden behind the frame. If no gutter is set,
* this will be null.
*/
frame: null,
@@ -99,13 +100,15 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
OpenLayers.Tile.prototype.initialize.apply(this, arguments);
this.url = url; //deprecated remove me
this.frame = document.createElement("div");
this.frame.style.position = "absolute";
this.frame.style.overflow = "hidden";
this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();
if (this.maxGetUrlLength != null || this.layer.gutter || this.layerAlphaHack) {
// only create frame if it's needed
this.frame = document.createElement("div");
this.frame.style.position = "absolute";
this.frame.style.overflow = "hidden";
}
if (this.maxGetUrlLength != null) {
OpenLayers.Util.extend(this, OpenLayers.Tile.Image.IFrame);
}
@@ -116,7 +119,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* nullify references to prevent circular references and memory leaks
*/
destroy: function() {
if (this.frame != null) {
if (this.imgDiv) {
this.clear();
this.imgDiv = null;
this.frame = null;
@@ -162,7 +165,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* position it correctly, and set its url.
*/
renderTile: function() {
this.layer.div.appendChild(this.frame);
this.layer.div.appendChild(this.getTile());
if (this.layer.async) {
// Asynchronous image requests call the asynchronous getURL method
// on the layer to fetch an image that covers 'this.bounds', in the scope of
@@ -188,7 +191,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* code.
*/
positionTile: function() {
var style = this.frame.style;
var style = this.getTile().style;
style.left = this.position.x + "%";
style.top = this.position.y + "%";
style.width = this.size.w + "%";
@@ -204,8 +207,9 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
var img = this.imgDiv;
if (img) {
OpenLayers.Event.stopObservingElement(img);
if (this.frame.parentNode === this.layer.div) {
this.layer.div.removeChild(this.frame);
var tile = this.getTile();
if (tile.parentNode === this.layer.div) {
this.layer.div.removeChild(tile);
}
this.setImgSrc();
if (this.layerAlphaHack === true) {
@@ -216,45 +220,49 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
},
/**
* Method: createImage
* Creates the content for the frame on the tile.
* Method: getImage
* Returns or creates and returns the tile image.
*/
createImage: function() {
var img = document.createElement("img");
this.imgDiv = img;
getImage: function() {
if (!this.imgDiv) {
this.imgDiv = document.createElement("img");
img.className = "olTileImage";
// avoid image gallery menu in IE6
img.galleryImg = "no";
this.imgDiv.className = "olTileImage";
// avoid image gallery menu in IE6
this.imgDiv.galleryImg = "no";
var style = img.style,
gutter = this.layer.gutter;
if (gutter) {
var tileSize = this.layer.tileSize,
left = (gutter / tileSize.w * 100),
top = (gutter / tileSize.h * 100);
style.left = -left + "%";
style.top = -top + "%";
style.width = (2 * left + 100) + "%";
style.height = (2 * top + 100) + "%";
var style = this.imgDiv.style;
if (this.layer.gutter) {
var left = this.layer.gutter / this.layer.tileSize.w * 100;
var top = this.layer.gutter / this.layer.tileSize.h * 100;
style.left = -left + "%";
style.top = -top + "%";
style.width = (2 * left + 100) + "%";
style.height = (2 * top + 100) + "%";
style.position = "absolute";
} else {
style.width = "100%";
style.height = "100%";
}
style.display = "none";
style.position = "absolute";
} else {
style.width = "100%";
style.height = "100%";
}
style.display = "none";
if (this.layer.opacity < 1) {
OpenLayers.Util.modifyDOMElement(img, null, null, null, null, null,
null, this.layer.opacity);
}
if (this.layerAlphaHack) {
// move the image out of sight
style.paddingTop = style.height;
style.height = "0";
if (this.layer.opacity < 1) {
OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null,
null, null, null, null,
this.layer.opacity);
}
if (this.layerAlphaHack) {
// move the image out of sight
style.paddingTop = style.height;
style.height = "0";
style.width = "100%";
}
if (this.frame) {
this.frame.appendChild(this.imgDiv);
}
}
this.frame.appendChild(img);
return img;
return this.imgDiv;
},
/**
@@ -262,7 +270,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* Creates the content for the frame on the tile.
*/
initImage: function() {
var img = this.imgDiv || this.createImage();
var img = this.getImage();
if (this.url && img.getAttribute("src") == this.url) {
this.onImageLoad();
} else {
@@ -318,7 +326,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* {DOMElement} The tile's markup
*/
getTile: function() {
return this.frame;
return this.frame ? this.frame : this.getImage();
},
/**
@@ -332,11 +340,13 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* or if it's currently loading.
*/
createBackBuffer: function() {
if(!this.imgDiv || this.isLoading) {
return;
var backBuffer;
if (this.frame) {
backBuffer = this.frame.cloneNode(false);
backBuffer.appendChild(this.imgDiv);
} else {
backBuffer = this.imgDiv;
}
var backBuffer = this.frame.cloneNode(false);
backBuffer.appendChild(this.imgDiv);
this.imgDiv = null;
return backBuffer;
},

View File

@@ -55,7 +55,7 @@ OpenLayers.Tile.Image.IFrame = {
// We remove the imgDiv (really either an image or an iframe)
// from the frame and set it to null to make sure initImage
// will call createImage.
// will call getImage.
if(this.imgDiv && this.imgDiv.parentNode === this.frame) {
this.frame.removeChild(this.imgDiv);
@@ -73,10 +73,10 @@ OpenLayers.Tile.Image.IFrame = {
},
/**
* Method: createImage
* Method: getImage
* Creates the content for the frame on the tile.
*/
createImage: function() {
getImage: function() {
if (this.useIFrame === true) {
if (!this.frame.childNodes.length) {
var eventPane = document.createElement("div"),
@@ -130,7 +130,7 @@ OpenLayers.Tile.Image.IFrame = {
this.imgDiv = iframe;
return iframe;
} else {
return OpenLayers.Tile.Image.prototype.createImage.apply(this, arguments);
return OpenLayers.Tile.Image.prototype.getImage.apply(this, arguments);
}
},
@@ -180,7 +180,6 @@ OpenLayers.Tile.Image.IFrame = {
if (this.useIFrame === true) {
if (url) {
var form = this.createRequestForm();
this.frame.appendChild(this.imgDiv);
this.frame.appendChild(form);
form.submit();
this.frame.removeChild(form);

View File

@@ -75,10 +75,10 @@
t.eq( tile.url,
url + "?" + OpenLayers.Util.getParameterString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.frame.style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.frame.style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild.firstChild;
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
t.ok( firstChild == img, "div first child is correct image object" );
t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
@@ -203,10 +203,10 @@
map.addLayer(tLayer);
map.zoomToMaxExtent();
t.eq(tLayer.opacity, "0.5", "Opacity is set correctly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
tLayer.setOpacity("0.6");
t.eq(tLayer.opacity, "0.6", "setOpacity works properly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
var pixel = new OpenLayers.Pixel(5,6);
var tile = tLayer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);
tile.draw();

View File

@@ -56,10 +56,10 @@
t.eq( tile.url,
url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"),
"image src is created correctly via addtile" );
t.eq( tile.frame.style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.frame.style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild.firstChild;
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
t.ok( firstChild == img, "div first child is correct image object" );
t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
@@ -204,10 +204,10 @@
map.addLayer(tLayer);
map.zoomToMaxExtent();
t.eq(tLayer.opacity, "0.5", "Opacity is set correctly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
tLayer.setOpacity("0.6");
t.eq(tLayer.opacity, "0.6", "setOpacity works properly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
var pixel = new OpenLayers.Pixel(5,6);
var tile = tLayer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);
tile.draw();

View File

@@ -86,10 +86,10 @@
t.eq( tile.url,
layer.getFullRequestString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.frame.style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.frame.style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild.firstChild;
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
t.ok( firstChild == img, "div first child is correct image object" );
t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
@@ -117,10 +117,10 @@
t.eq( tile.url,
layer.getFullRequestString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.frame.style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.frame.style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild.firstChild;
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
t.ok( firstChild, img, "div first child is correct image object" );
t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
@@ -284,10 +284,10 @@
map.addLayer(tLayer);
map.zoomToMaxExtent();
t.eq(tLayer.opacity, "0.5", "Opacity is set correctly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
tLayer.setOpacity("0.6");
t.eq(tLayer.opacity, "0.6", "setOpacity works properly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
var pixel = new OpenLayers.Pixel(5,6);
var tile = tLayer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);
tile.draw();

View File

@@ -110,7 +110,7 @@
}
function test_Tile_Image_draw (t) {
t.plan( 7 );
t.plan(8);
var map = new OpenLayers.Map('map');
@@ -157,8 +157,9 @@
"http://labs.metacarta.com/TESTURL?" + OpenLayers.Util.getParameterString(tParams),
"tile.draw creates an image");
});
t.eq( tile.imgDiv.style.width, "100%", "Image width is correct" );
t.eq( tile.imgDiv.style.height, "100%", "Image height is correct" );
t.eq( tile.imgDiv.style.width, "5%", "Image width is correct" );
t.eq( tile.imgDiv.style.height, "6%", "Image height is correct" );
t.ok( tile.imgDiv.parentNode === layer.div, "Image is directly appended to the layer div" );
// this should trigger a "reload" event (since the image never actually
// loads in tests)
@@ -334,10 +335,10 @@
OpenLayers.Event.stopObservingElement(tile.imgDiv);
var img = tile.imgDiv;
var left = img.style.left;
var bb = tile.createBackBuffer();
t.eq(bb.style.left, tile.frame.style.left,
"backbuffer has same left style as frame");
t.ok(bb.firstChild === img, "image appended to bb");
t.eq(bb.style.left, left, "backbuffer has same left style as frame");
t.ok(bb === img, "image appended to bb");
t.ok(tile.imgDiv == null, "image reference removed from tile");
map.destroy();
}

View File

@@ -131,10 +131,10 @@
map.addLayer(tLayer);
map.zoomToMaxExtent();
t.eq(tLayer.opacity, "0.5", "Opacity is set correctly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.5, "Opacity on tile is correct");
tLayer.setOpacity("0.6");
t.eq(tLayer.opacity, "0.6", "setOpacity works properly");
t.eq(parseFloat(tLayer.div.firstChild.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
t.eq(parseFloat(tLayer.div.firstChild.style.opacity), 0.6, "Opacity on tile is changed correctly");
map.destroy();
}