mapsopenlayerscoordsxyz

cant set feature (marker/icon) from forEachTileCoord coords, openlayers


new to openlayers, i am currently trying to grab all tiles at certain zoom level within the view extent and add a feature/icon to each tile location, i can grab tile coords using

src.getSource().getTileGrid().forEachTileCoord

problem is it returns Z,X,Y tile coords (ie [16, 31689, 20858]) and i cant find anyway to either set icons location with these coords or convert them to lon/lat (eg 'EPSG:4326'[-5.928909184411161, 54.5921176536682]

iv tried

ol.proj.toLonLat

but it returns 0.00014373044545912343, 0.284665959233962, 20858.

as im new i may have something fundamentally wrong with my setup, or im completely missing something,thanks


Solution

  • To get actual coordinates you can use getTileCoordExtent / getCenter. This will get you the center coordinates for each tile. By default the coordinate format is EPSG:3857 and no conversion should be needed to add a Feature.

    const zDirection = 0;
    const tileLayer = new ol.layer.Tile({
      source: new ol.source.TileDebug({
        zDirection: zDirection,
      })
    });
    
    const style = new ol.style.Style({
      image: new ol.style.Circle({
        radius: 70,
        fill: new ol.style.Fill({color: 'rgba(255, 0, 0, .2)'}),
      }),
    });
    const layer = new ol.layer.Vector({
      style: style,
    });
    
    const map = new ol.Map({
      target: 'map',
      view: new ol.View({
        center: [0, 5000000],
        zoom: 2,
      }),
      layers: [tileLayer, layer],
    });
    
    map.on('moveend', function () {
      const view = map.getView();
      const tileGrid = tileLayer.getSource().getTileGrid();
      const extent = view.calculateExtent();
      const zoom = tileGrid.getZForResolution(view.getResolution(), zDirection);
      const features = [];
      tileGrid.forEachTileCoord(extent, zoom, function (tileCoord) {
        const center = ol.extent.getCenter(tileGrid.getTileCoordExtent(tileCoord));
        features.push(new ol.Feature(new ol.geom.Point(center)));
      });
      layer.setSource(new ol.source.Vector({features: features}));
    });
    html, body {
      padding: 0;
      margin: 0;
    }
    body {
      display: flex;
      justify-content: stretch;
      height: 100vh;
      width: 100vw;
    }
    #map {
      flex: 1;
    }
    <head>
      <link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers@v6.14.1/src/ol/ol.css" rel="stylesheet"/>
    </head>
    <body>
      <div id="map"></div>
      <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js"></script>
    </body>