Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow specifying a custom rendering pixel size #139

Closed
wants to merge 1 commit into from
Closed

allow specifying a custom rendering pixel size #139

wants to merge 1 commit into from

Conversation

restaste
Copy link

Hi 👋

We've been using morecantile successfully for a while now and we started using it to connect to ArcGIS Online services, which generates custom tiling schemes.

Doing so, we noticed ArcGIS servers give a tileInfo.dpi value (with a value of 96 in this case). Converting this to mm gives 0.264mm, which we figured we should use instead of 0.28mm as the rendering pixel size. Since this number is used to compute scaleDenominator, resolution and finally tile coordinates, our reasoning was that getting this number right mattered. So we forked morecantile to extend it to support a custom rendering_pixel_size parameter.

The OGC specs do mention this 96 DPI vs 0.28mm as a potential source of confusion, and digging further into how tile coordinates are computed in morecantile, it seems like rendering_pixel_size cancels itself out in the math?

  • scaleDenominator is computed as scaleDenominator = resolution * meters_per_unit / rendering_pixel_size, where resolution is defined as (bbox_width_meters / tile_width / 2**zoom_level)
  • To generate tile coordinates, resolution is later recomputed from the scaleDenominator as resolution = scaleDenominator * rendering_pixel_size / meters_per_unit.
  • This simplifies to the original resolution = bbox_width_meters / tile_width / 2**zoom_level, where the rendering pixel size doesn't appear anymore.

I'm probably misunderstanding some important bits, but:

  • Is my understanding correct that changing rendering_pixel_size to some value other than 0.28 does not impact the tile coordinates computations?
  • Would it have other (positive or negative) side-effects?
  • Is this ArcGIS DPI value safe to ignore? We'll have to ask the folks at ESRI, but I wondered if you had an idea what other purpose this value could have (some purely rendering concerns?)

Disclaimer: this is out of my comfort zone, happy to learn more!

description="The physical size (in meters) of a pixel when rendered on a screen"
),
] = 0.28e-3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renderingPixelSize is not part of the OGC specification for the TileMatrix object but we could resolve it by using `private variable like https://github.com/developmentseed/morecantile/blob/main/morecantile/models.py#L384-L387

@@ -713,8 +724,15 @@ def _resolution(self, matrix: TileMatrix) -> float:
The pixel size of the tile can be obtained from the scaleDenominator
by multiplying the later by 0.28 10-3 / metersPerUnit.

Note that 0.28e-3 is a standardized rendering pixel size representing the physical size
of a pixel when rendered on a screen. Some usages might favor a different size, which is
why this default value can be overridden when constructing a custom TileMatrixSet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@vincentsarago
Copy link
Member

NOTE: Since the 1980s, the Microsoft Windows operating system has set their default standard display pixels per inch (PPI) to 96. This value results in an approximated 0.264 mm per pixel. The similarity of this value with the actual 0.28 mm adopted in this standard can create some confusion.

Microsoft Windows and ESRI together 🤝 😅

Thanks for this great explanation and PR @restaste 🙏

This simplifies to the original resolution = bbox_width_meters / tile_width / 2**zoom_level, where the rendering pixel size doesn't appear anymore.

yeah, makes absolute sense BUT we don't have access to the bbox_with_meters variable once the TMS is created

NOTE 3 The bounding box of a tile matrix is not supplied explicitly because it can be calculated from cornerOfOrigin, pointOfOrigin, tileWidth, tileHeight and scaleDenominator.

😓 🕳️

I don't think we can have renderingPixelSize at the TileMatrix level mostly because it does not respect the OGC TMS specification. So I don't think there is an easy way to have this value both at TMS creation time and at usage time :-(

To enable custom implementation we could maybe have an environment variable which will be use in Morecantile (but this is custom and won't enable sharing TMS document (because there is no way for a client to know if values used was 0.28 or 0.26

At the same time (if we can't make ESRI Change) you could open an issue in https://github.com/opengeospatial/2D-Tile-Matrix-Set/tree/master to see it we can add screenPixelSize in the TMS Spec (at tileMatrixSet or tileMatrix level)

@vincentsarago
Copy link
Member

For the purposes of this International Standard, the common pixel size is defined to be 0,28 mm × 0,28 mm. Because arbitrary clients can request maps from a server, the true pixel size of the final rendering device is unknown to the server.

WTF Esri is not using 0.28 😓

@vincentsarago
Copy link
Member

vincentsarago commented Dec 21, 2023

I think there IS a solution, the resolution for the tileMatrix is the cellSize 😅

ref opengeospatial/2D-Tile-Matrix-Set#4

@restaste
Copy link
Author

restaste commented Jan 8, 2024

Closing this one since #140 was merged.

Thanks @vincentsarago !

@restaste restaste closed this Jan 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants