Why do it?

To make our maps look nicer, we want to prevent tile re-scaling. This article describes a number of guidelines you can follow to prevent tile re-scaling in LuciadRIA.

What are the consequences of tile re-scaling?

When multiple RasterTileSetModels are being visualized on a LuciadRIA map, the tiles of one or more raster layers might be re-scaled. Such a tile re-scaling results in a sub-optimal visualization of those layers, especially when the tiles contain text or thin lines.

non aligned
aligned

The two images above show the consequences of tile re-scaling.  Both images show a number of USA states.  Tile re-scaling occurs in the image on the left, whereas tiles are displayed with their intended resolution in the image on the right. Tile re-scaling makes text less readable and also introduces unwanted aliasing effects in lines. The left image clearly shows that the state labels are reduced in size in comparison with the labels in the image on the right. The eastern and southern boundaries of the New Mexico state demonstrate aliasing effects in the left image: the lines are not rendered as sharply as the boundary lines in the right image.

Although you can usually still see the data when tiles are re-scaled, it is still possible to get a much prettier map by carefully preparing your raster data.

Why does this happen?

LuciadRIA rendering is based on scale levels

LuciadRIA will adapt the zoom levels of the map to the scale levels in the tile pyramid of your RasterTileSetLayer.  When a user zooms in or out, the Map selects the most appropriate scale level in the tile structure and snaps the rendering to that level. That way, the tiles at each level are rendered so that they are not scaled; 1 pixel in the tile corresponds with 1 pixel on the screen.

Things become less straightforward when there are multiple RasterTileSetLayers in your map.  In that case, LuciadRIA picks a single layer and snaps to the scale levels of the selected layer. LuciadRIA renders at the scale levels of the LayerType.BASE layer, which is always at the bottom of the map.  If there is no BASE layer in the map, LuciadRIA will use the scale levels of the bottom-most raster layer.

With more than one RasterTileSetLayer on the map, there is a possibility that the scale levels of the different layers do not align. To prevent that the tiles of the other RasterTileSetLayers are re-scaled, you must ensure that the scale levels of each layer align with the scale levels of the BASE layer.  

How do I fix it?

Determining scale levels and pixel density of the base layer

Aligning the scale levels of two layers means that you must make the pixel densities correspond between both layers.  You can only do that when you’re creating your raster data set.  By generating the scale levels of your overlay RasterTileSetLayers at the same pixel densities as your BASE layer, you guarantee that text labels and vector data won’t be scaled by the LuciadRIA Map.

Pixel density is defined as:  "the number of pixels per spatial unit", with the spatial unit typically expressed in meters.  Since raster data sets are two-dimensional, there is a pixel density on the X-axis and a pixel density on the Y-axis 

For example, if you want to use a Bing Maps layer as your base layer and create a BingTileSetModel, the pixel densities are as follows:

Scale level X pixel density (pixels/meter) Y pixel density (pixels/meter)

0

0.00001277603959636653

0.0016353330683349157

1

0.00002555207919273306

0.00002555207918098738

2

0.00005110415838546612

0.00005110415836197476

3

0.00010220831677093223

0.00010220831672394952

4

0.00020441663354186447

0.00020441663344789905

5

0.00040883326708372893

0.0004088332668957981

6

0.0008176665341674579

0.0008176665337915962

7

0.0016353330683349157

0.0016353330675831924

8

0.0032706661366698315

0.003270666135166385

…​

…​

…​

You can query pixel density information from each RasterTileSetModel with the getPixelDensity() method. 

Expressed in RasterTileSetModel parameters, a BingMapTileSet model has the following characteristics:

  • Bounds:  (X, width, Y, height) = (-20037508.34278924, 40075016.68557848, -20037508.352, 40075016.704)

  • Number of tile rows and columns at level 0: 2 by 2

  • Tile dimensions: 256x256 pixels

  • The calculation to arrive at the X-pixel density at level 0 is (2 * 256) / 40075016.68557848 = 0.00001277603959636653.

Level 1 has twice the number of pixels, because tile pyramids are modeled as quad trees. Therefore, we calculate the X-pixel density as  (4 * 256) / 40075016.68557848 = 0.00002555207919273306.

Aligning scale levels with the base layer

Suppose you want to create a raster coverage in a Web Mercator reference that visualizes street data in Belgium. You can use the raster coverage to display street data on top of the Bing Maps raster layer. The properties for the street data set are:

  • Current height and width: 450000m

  • Required number of tile rows and columns at level 0: 1 by 1

  • Required tile dimensions:  512x512 pixels

If you don’t do anything, the X-pixel density of the street coverage at level 0 will be 512 / 450000 = 0.00113777777777.  That pixel density does not align with any scale level in the Bing Maps layer. The closest scale levels are level 6 (X-pixel density of 0.0008176665341674579) or level 7 (X-pixel density of 0.0016353330683349157). Therefore, you could decide to update the bounds of your street data in one of the following ways:

  • Adapt to level 6:  extend the coverage bounds to 626172.1357m, which is the result of 512 / 0.0008176665341674579.  That means adding some padding to the coverage. The net result is a raster coverage with a level 0 that aligns with level 6 of the Bing Maps layer. The tiles will not be scaled in LuciadRIA.

  • Adapt to level 7: shrink the coverage bounds to 313086.0679m, which is the result of 512 / 0.0016353330683349157.  That means removing over 100 kilometers of possibly relevant data, which is probably not what you want. Nonetheless, the net result will be a raster coverage with a level 0 that aligns with level 7 of the Bing Maps layer.  

If you want to visualize a WMS layer using a WMSTileSetModel, you cannot define any tile parameters. The main reason for that is that WMS is not really layered. LuciadRIA will generate a tiling structure based on the bounds of the WMS layer, and pass it to the WMSTileSetModel constructor. To align the scale levels of a WMSTileSetModel, ensure that the aspect ratio of the bounds that you pass to the WMSTileSetModel correspond with the aspect ratio of the RasterTileSetModel it must align with.