0

I am using a XYZ layer to display the custom tile map generated from gdal2tiles, I have set a tile grid like below:

  //width =1065, height =950
  this.extent = [0.0, -this.imgHeight, this.imgWidth, 0];
     this.view = new View({
        projection: viewProjection, //EPSG:3857
        center: getCenter(viewProjection.getExtent()),
        maxResolution: 8.0,
        resolution: 4,
        extent: viewProjection.getExtent(),
    });
    this.projection = new Projection({
        extent: this.extent,
        code: "EPSG:12341234",
        units: "m",
    });
  
  const tileGrid = new TileGrid({
        resolutions: [8, 4, 2, 1],
        origin: [0, 0],
        tileSize: 256,
        extent: this.projection.getExtent(),
        minZoom: 1,
    });
 this.tileSource = new XYZ({
        url: "assets/tile_map/{z}/{x}/{-y}.png",
        tileGrid,
        maxZoom: 4,
        tileSize: 256,
        maxResolution: 8,
        projection: this.projection,
    });

and the tilemap source:

<?xml version="1.0" encoding="utf-8"?>
<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
  <Title>zhonglv_office.png</Title>
  <Abstract></Abstract>
  <SRS></SRS>
  <BoundingBox minx="0.00000000000000" miny="-950.00000000000000" maxx="1065.00000000000000" maxy="0.00000000000000"/>
  <Origin x="0.00000000000000" y="-950.00000000000000"/>
  <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>
  <TileSets profile="raster">
    <TileSet href="0" units-per-pixel="8.00000000000000" order="0"/>
    <TileSet href="1" units-per-pixel="4.00000000000000" order="1"/>
    <TileSet href="2" units-per-pixel="2.00000000000000" order="2"/>
    <TileSet href="3" units-per-pixel="1.00000000000000" order="3"/>
  </TileSets>
</TileMap>

The js code generated by gdal2tiles:

var map;
          var mapBounds = new OpenLayers.Bounds( 0.0, -950.0, 1065.0, 0.0);
          var mapMinZoom = 0;
          var mapMaxZoom = 3;
          var emptyTileURL = "http://www.maptiler.org/img/none.png";
          OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;

          function init(){
              var options = {
                  div: "map",
                  controls: [],
                  maxExtent: new OpenLayers.Bounds(0.0, -950.0, 1065.0, 0.0),
                  maxResolution: 8.000000,
                  numZoomLevels: 4
              };
              map = new OpenLayers.Map(options);

              var layer = new OpenLayers.Layer.TMS("TMS Layer", "",
              {
                  serviceVersion: '.',
                  layername: '.',
                  alpha: true,
                  type: 'png',
                  getURL: getURL
              });

              map.addLayer(layer);
              map.zoomToExtent(mapBounds);
    
              map.addControls([new OpenLayers.Control.PanZoomBar(),
                               new OpenLayers.Control.Navigation(),
                               new OpenLayers.Control.MousePosition(),
                               new OpenLayers.Control.ArgParser(),
                               new OpenLayers.Control.Attribution()]);
          }
    
          function getURL(bounds) {
              bounds = this.adjustBounds(bounds);
              var res = this.getServerResolution();
 
              var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));
              var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h));
             
              var z = this.getServerZoom();
              var path = this.serviceVersion + "/" + this.layername + "/" + z + "/" + x + "/" + y + "." + this.type;
              var url = this.url;
              if (OpenLayers.Util.isArray(url)) {
                  url = this.selectUrl(path, url);
              }
              if (mapBounds.intersectsBounds(bounds) && (z >= mapMinZoom) && (z <= mapMaxZoom)) {
                  return url + path;
              } else {
                  return emptyTileURL;
              }
          }

Wrong output I need to add 256 to the top i.e.[0,-704] to get the closest result The tile are not correct loaded in y axis

Wrong output (Using same projection for view and source with origin=[0,950], extent=[0,0,width,height], url=/z/x/y.png; tried origin=[0,-950], no tiles displayed on the map) Using same projection for view and source, origin=[0,950], extent=[0,0,width,height]

Expected output The tile map should be like this

4
  • If your view is in a different projection to the source you would need to define a transform between the projections. You should probably be using the same projection as the source. Also the {-y} placeholder in urls is intended for origins at the bottom left of the extent, but your origin is top right.
    – Mike
    Nov 17, 2020 at 15:01
  • Sorry, I don't get it, why my origin is top right? I thought it should be top left.I tried using same projection for view and source with extent=[0, 0, this.imgWidth, this.imgHeight] and origin = [0,950](other origins don't work), but the tiles are not placed at right place. gdal2tiles generated some example code to display the tiles, but it is using OpenLayers 2, I don't know how to convert it to OpenLayers 6 , I will update it in the question
    – Chi
    Nov 17, 2020 at 16:10
  • Correction, your origin is top left.
    – Mike
    Nov 17, 2020 at 17:42
  • I have tried to set the tile gird origin to [0,-950] with extent [0.0, -950,1065, 0.0] and using same projection for view and source, but the top left of the tile image still not meet the tile grid top left which is [0,0], I need to add 256 from the tile grid origin to get closest result, i.e. origin =[0,-704], but tile image top left still not placed at tile grid top left. What did I do wrong?
    – Chi
    Nov 18, 2020 at 6:13

1 Answer 1

0

It seems tile x 0, y 0 at any zoom level is at the bottom left (i.e. TMS). As you have a custom tile grid the simplest solution would be to set the tilegrid origin at the bottom left and use a tileUrlFunction replacing

 url: "assets/tile_map/{z}/{x}/{-y}.png",

with

 tileUrlFunction: function(coordinate) {
   return 'assets/tile_map/' + coordinate[0] + '/' +
     coordinate[1] + '/' + (-coordinate[2] - 1) + '.png';
 }
1
  • Thanks, I found out the tiles at 0,0,0 was generated with some transparent pixels at the top to fit 256 * 256, that's why the tiles not fully displayed in extent [0,-950,1065,0]
    – Chi
    Nov 18, 2020 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.