p-lr / MapView

A Fast, memory efficient Android library to display tiled maps, with support for markers, paths, and rotation.
Apache License 2.0
184 stars 38 forks source link

Offset/padding? #44

Closed devjta closed 8 months ago

devjta commented 10 months ago

Hey!

Turns out, for whatever reasons our tiles have 1 pixel offset on each side, resulting in a 258x258 tile.

Would there be a way to add such offsets? If you dont want to add features in the non-compose version, I fully understand (we will probably switch to it at the end off the year), but could I even do such a thing, without redrawing the bitmaps?

I already need to fork your version anyway, because of the tileSize being the widthXheight for the bitmap, which didnt work.

I found in the mapConfiguration a setPadding, but didnt had any effect.

Problem is, that on high zoom ratio, the images/tiles are not stiched correctly.

BR

p-lr commented 10 months ago

Hi, I'm not sure I understand correctly. Are your tiles 258x258px? If this is the case, setting the tileSize of MapViewConfiguration to 258 should work. Is there something I missed?

p-lr commented 10 months ago

Maybe you thought that the tileSize parameter was number of pixels. Actually, this is the width (or height) in pixels of tiles (as MapView only supports square tiles).

p-lr commented 10 months ago

Besides that, you're right about the compose vs view library. I'm only fixing issues on MapView and adding features to MapCompose.

devjta commented 10 months ago

We have non rectanlge tiles (the one at the edges). We fixed it, by drawing them on a white background.

The problem with setting it to 258, is probably than the calculation of the pins. As the webapp (openlayers) and iOS are using tileSize = 256, with the 258x258 tiles (iOS also has that bug, when zooming much. Only OpenLayers handle it correctly).

Whats even more strange: If I set the tileSize to 258, the issue is still present. On full zoom, its not stitched correctly.

Its really strange.. need to investigate it..

What fixes it, but is massive performance loss would be, adding that in the TileCollector: val tile = Tile(spec.zoom, spec.row, spec.col, spec.subSample).apply { //if height or width is not 256, make the bitmap like that if(bitmap.height != 256 || bitmap.width != 256){ this.bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888) val canvas = Canvas(this.bitmap) canvas.drawColor(Color.WHITE) canvas.drawBitmap(bitmap, 0.0f, 0.0f, null) }else { this.bitmap = bitmap } }

This would also fix the issue, with tiles not being squares. But as I wrote, i basically redraw each bitmap and create a bitmap for each tile..

p-lr commented 10 months ago

FWIW, creating bitmaps of size 258x258 with Bitmap.createBitmap(258, 258, Bitmap.Config.ARGB_8888) may work for 256x256 tiles. However, I have to admit, MapView was never designed to display tiles of different sizes.

devjta commented 8 months ago

@p-lr Hey, just wanted to let you know, you basically had already everything which I needed.

In the TileCanvasView.kt in the drawTiles function you had this line:

canvas.drawBitmap(tile.bitmap, null, dest, paint)

I looked then at the API documentation and basically I can also provide a Rect for the source. So fix was that:

private val source = Rect(1,1,257,257)

and in drawTiles then

canvas.drawBitmap(tile.bitmap, source, dest, paint)

I added a detection logic, to see if width or height is 258.

p-lr commented 8 months ago

Nice, looks like it will be easy to maintain your fork. This part of the library isn't likely to change.