PMTiles icon indicating copy to clipboard operation
PMTiles copied to clipboard

Cannot render with magic number error

Open tolidano opened this issue 1 year ago • 5 comments

I'm not even sure if this is the repo to solve this issue, but I figured I would start here.

I am using open layers and ol-pmtiles like this:

const layers = {}
   layers.base = new ol.layer.VectorTile({
     declutter: true,
     source: new olpmtiles.PMTilesVectorSource({
       url: 'https://d1b2p6fo2pi78e.cloudfront.net/us-northeast/{z}/{x}/{-y}.mvt',
       attributions: ['© OSM, MTA, & others']
     }),
     style: new ol.style.Style({
       stroke: new ol.style.Stroke({
         color: 'gray',
         width: 1,
       }),
       fill: new ol.style.Fill({
         color: 'rgba(20,20,20,0.9)',
       })
     })
   })
  const view = new ol.View({ // eslint-disable-line
     center: [-8235252, 4969073],
     minZoom: 10,
     maxZoom: 17,
     zoom: 14,
     constrainResolution: true,
     extent: [-8375000, 4795000, -8000000, 5125000]
   })
    map = new ol.Map({ // eslint-disable-line
     target: 'map',
     view,
     layers: [
       layers.base,
     ],
     interactions: ol.interaction.defaults.defaults({ zoomDuration: 0 }) // eslint-disable-line
   })

I've pulled ol 9.2.4 and olpmtiles 0.4.0 locally.

my html is simple:

<html>
<head>
   <link rel="stylesheet" href="/ol.css">
   <script src="/ol.js"></script>
   <script src="/olpmtiles.js"></script>
</head>
<body>
   <div id="map" tabindex="0"></div>
</body>
</html>

I used serverlessmaps to generate us-northeast and upload to S3 + CloudFront

It works here: https://d3gsiaxhde69bo.cloudfront.net/basemap.html#15.49/40.721384/-73.843143 and here: https://d3gsiaxhde69bo.cloudfront.net/#16/40.7206/-73.8382

I would like it to render with open layers since my existing application uses that and not, for example, maplibregl or leaflet. When I try it like this, it talks about a failed magic number, probably because it's always a bad URL

When I use the sample website, it makes calls to the tile cloud front like this: https://d1b2p6fo2pi78e.cloudfront.net/us-northeast/14/4831/6159.mvt

This uses a lambda defined here: https://github.com/serverlessmaps/serverlessmaps/blob/main/iac/functions/pmTilesProxy.ts to do a range request in the zip archive in the S3 bucket and return it.

Screenshot 2024-06-04 at 6 36 50 PM

Is there a way to set this up so that it renders with Open Layers using the same URL scheme? I'm obviously missing something, but I'm not sure how to make it call for the URLs properly.

tolidano avatar Jun 04 '24 22:06 tolidano

If you are using the lambda you do not need anything PMTiles related on the client side, just use normal {z}/{x}/{y} URLs in OpenLayers.

bdon avatar Jun 05 '24 02:06 bdon

Could you explain a bit more?

Do I:

  • remove the olpmtiles.js file?
  • change the definition of the base layer in my JS?
  • if so, what should I change it to? do I use the MVT() setup?

tolidano avatar Jun 05 '24 04:06 tolidano

remove the olpmtiles.js file.

https://openlayers.org/en/latest/examples/webgl-vector-tiles.html

bdon avatar Jun 05 '24 04:06 bdon

Ok, so I have this as my base layer:

layers.base = new ol.layer.VectorTile({
       declutter: true,
       source: new ol.source.VectorTile({
         attributions:
           '© <a href="https://www.openstreetmap.org/copyright">' +
           'OpenStreetMap contributors</a>',
         format: new ol.format.MVT(),
         url: 'https://d1b2p6fo2pi78e.cloudfront.net/us-northeast/{z}/{x}/{y}.mvt',
       }),
       style: new ol.style.Style({
         stroke: new ol.style.Stroke({
           color: 'gray',
           width: 1,
         }),
         fill: new ol.style.Fill({
           color: 'rgba(20,20,20,0.9)',
         })
       })
     })

Thank you, I am much closer. Here is where I am at now.

On the sample basemap (you can click this), https://d3gsiaxhde69bo.cloudfront.net/#18/40.71993/-73.83873 you get this: Screenshot 2024-06-05 at 10 34 52 PM

But when I use the code above, I get this: Screenshot 2024-06-05 at 10 36 42 PM

So it is trying to load a lot more files, and unfortunately, all the street labels (and basically everything!) is missing.

Can you point me in the right direction? Is this because I'm using raster vs vector?

tolidano avatar Jun 06 '24 02:06 tolidano

there isn't a labeled basemap implementation for OpenLayers. You can try to use ol-mapbox-style to load a MapLibre JSON but the performance isn't great generally. Your demo page is using Leaflet, not OpenLayers, and it's also using an older major version of protomaps-leaflet.

bdon avatar Jun 08 '24 12:06 bdon

Closing as this is working as intended.

bdon avatar Sep 11 '24 02:09 bdon