We are producing tiles from a geotiff using gdal2tiles.py (GDAL 2.1.0dev) to feed a web-system we are developing. We use openlayers 3 (v3.18.2) on the web-system. The gdal2tiles.py by @Klokan Technologies Gmb works great. and we can nicely view the tiles using the automatically generated webviewer: openlayers.html, leaflet.html, etc.
The problem is that when we tried to use the tiles inside our ol3 code (inside the web-system), the tiles are shifted eastward in respect to the basemap. It is not a projection problem, we deal with this on our ol3 code. I guess it come from the fact that for the first zoom, the generated tile presents margins (transparent, alpha), I mean, the image is not fitted on the bottom-left corner. To overcome the problem (provisionally, because it is not convenient), we modified the correct origin (more westward) up to the point when the tile fit to the basemap.
The strange thing is ol2 webviewer (automaticaly generated by gdal2tiles.py) seems to nicely deal with this "extra" space on margins, because the tiles viewed with openlayers.html do not present any shift.
here is the code to generate the tiles:
gdal2tiles.py -z 0-8 mygeotiff.tiff
here a screenshot of the 0/0.png tile to see extra space on bottom-left corner, and the tile viewed with openlayers.html (v2.12). No problem!
here is our ol3 code to use the tiles inside our web-system
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Test·</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.18.2/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.18.2/build/ol.js"></script>
<script>
var resolutions = [156543.03390000000945, 78271.51695000000473, 39135.75847500000236, 19567.87923750000118, 9783.93961875000059, 4891.96980937500030, 2445.98490468750015, 1222.99245234375007, 611.49622617187504];
var extent = ol.proj.transformExtent([-119.99800110000001, -77.49100082418495, -53.03354490678051, -18.38559910000000], "EPSG:4326", "EPSG:3857");
//var origin = ol.proj.transform([-180, -85.049], "EPSG:4326", "EPSG:3857");
var origin = [extent[0], extent[1]];
function init() {
// Layer with Tiles
var testLayer = new ol.layer.Tile({
source:new ol.source.TileImage({
crossOrigin:null,
extent: extent,
projection:ol.proj.get("EPSG:3857"),
tileGrid: new ol.tilegrid.TileGrid({
origin: origin,
resolutions: resolutions,
}),
tileUrlFunction: function(coordinate) {
if (coordinate === null) return undefined;
var z = coordinate[0];
var x = coordinate[1];
var y = coordinate[2];
var url = './'+z+'/'+ x +'/'+y +'.png';
return url;
}
})
});
var originLayer = new ol.layer.Vector({
source:new ol.source.Vector()
});
var area = ol.geom.Polygon.fromExtent(extent);
var areaFeature = new ol.Feature({name:"test2", geometry:area});
areaFeature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgb(200,200,200)',
width: 2
}),
fill: null
})
);
originLayer.getSource().addFeature(areaFeature);
var punto = new ol.geom.Circle(origin, 200000);
puntoFeature = new ol.Feature({name:"origen", geometry:punto});
puntoFeature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'yellow',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.8)'
})
}));
originLayer.getSource().addFeature(puntoFeature);
var baseLayer = new ol.layer.Tile();
baseLayer.setSource(new ol.source.OSM());
this.mapa = new ol.Map({
target: 'mapa',
layers: [
baseLayer,
testLayer, originLayer
],
view: new ol.View({
center: ol.proj.fromLonLat([-74, -32]),
zoom: 7
})
});
}
</script>
</head>
<body onload="init()">
<h1>Test OL3</h1>
<div id="mapa" style="width: 800px; height: 600px;"></div>
</body>
</html>
here is the tile viewed with our ol3 code. Eastward shifted !!. And the tile viewed with our ol3 code, but with the origin artificially westward shifted:
Additional information:
- There is NO extra space on margins for our Geotiff !
- We know that ol2 uses OpenLayers.Layer.TMS, but this is not available in ol3. Instead we use ol.layer.Tile with source TileImage (or XYZ)
How to deal with this shift (or extra space) on an ol3 code, without artificially changing the image's origin, or to avoid producing this extra space on gdal2tiles ?
It is an "academic Project" and we work only with opensource libraries.
For the sake of curiosity, when producing the same tile but with maptiler interface, the tile fits perfectly the bottom-left corner and there is no problem to view it with our ol3 code ...