p-lr / MapComposeMP

Kotlin Multiplatform port of MapCompose
Apache License 2.0
40 stars 5 forks source link

Maptiler TileSize Issue #9

Open PicoPocoo opened 4 months ago

PicoPocoo commented 4 months ago

Hey Pierre, thanks so much for your amazing work :)

I've been trying to get the map to work with MapTiler Raster Tiles and none of my changes seem to do the trick, I am using the default demo Project with the MapTiler URL;

val url = URL("https://api.maptiler.com/maps/basic-v2/256/$zoomLvl/$col/$row.png?key=qZb8Y1pCBG6YO3hIQZt8")

My Map seems to have too many Tiles: photo_6001414011394048399_y photo_6001414011394048398_y photo_6001414011394048397_y

Do you know what causes this Issue? In my old Flutter Project switching between OSM and MapTiler, I had to add the @2x modifier. https://docs.maptiler.com/cloud/api/maps/ -> Raster XYZ Tiles.

If this works I can enhance the Readme.md to include a description for the MapTiler Setup.

Thanks

p-lr commented 4 months ago

Could you share your MapState configuration? I'm suspecting a an issue with the minimum scale which forces the library to subsample the last available level. That would explain the number of tiles.

PicoPocoo commented 4 months ago

Hey Pierre, thanks for the quick reply. Here is the more than the requested code:

@Composable
@Preview
fun App() {

    val tileStreamProvider = makeOsmTileStreamProvider()

    val maxLevel = 16
    val minLevel = 12
    val mapSize = mapSizeAtLevel(maxLevel, tileSize = 256)
    val state = MapState(levelCount = maxLevel + 1, mapSize, mapSize, workerCount = 16) {
        minimumScaleMode(Forced((1 / 2.0.pow(maxLevel - minLevel)).toFloat()))
        scroll(0.5064745545387268, 0.3440358340740204)  // Paris
    }.apply {
        addLayer(tileStreamProvider)
        scale = 0f  // to zoom out initially
    }

    MaterialTheme {
        Scaffold {

            mapTilerMap(state)
        }
    }
}

/**
 * wmts level are 0 based.
 * At level 0, the map corresponds to just one tile.
 */
private fun mapSizeAtLevel(wmtsLevel: Int, tileSize: Int): Int {
    return tileSize * 2.0.pow(wmtsLevel).toInt()
}

@Composable
fun mapTilerMap(state: MapState) {

    val status = remember { state }

    return MapUI(
        Modifier,
        status
    )
}

expect fun makeOsmTileStreamProvider(): TileStreamProvider
p-lr commented 4 months ago

Looking at the code, it's not obvious to see the issue. Can you reproduce in a fork of the demo app?

PicoPocoo commented 4 months ago

There you go: https://github.com/PicoPocoo/MapComposeMPMapTilerRaster :)

p-lr commented 4 months ago

I found no issue. On a pixel 8a with a 1080px width, I have between 5 and 9 tiles on each rows. This is normal, because depending on the scale we have to fit between 1080 / 256 = 4.2 (rounded to 5) and 1080 / 128 = 8.4 (rounded to 9) tiles. When exactly at scale which are power of 2, we display less tiles. However, in the worst case, we downscale tiles to almost half their size so we display 4x as much tiles.

PicoPocoo commented 4 months ago

Hey Pierre, thanks for looking into this & the explanation. How do you recommend to proceed from here? Is it possible to configure tile-amount without touching the source code? Should I half the display resolution just for the map so everything is twice the size? Thanks for your time =)

p-lr commented 4 months ago

One way to drastically reduce the number of tiles is to tradeoff quality for performance. You can set the magnifying factor to 1 like so:

val state = MapState(levelCount = maxLevel + 1, mapSize, mapSize, workerCount = 16) {
        // other settings removed for brevity
        magnifyingFactor(1)
}

This will make the library load tiles from the immediate upper level (say you should load tiles for level 14, tiles from level 13 will be loaded instead). This results in less tiles loaded. However, they are upscaled to the point you may see some pixelisation.

PicoPocoo commented 4 months ago

Thanks so much!!! With the magnificationFactor of 2 and the maptiler upscaled tiles (@2x) the map looks and feels better :). Do you want me to document my findings in the readme? Thanks again Pierre!

p-lr commented 4 months ago

You can document your findings in a discussion, that could be nice, thanks! :)