p-lr / MapView

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

scrollTo / scrollToAndCenter using different coordinates after scaling #29

Closed Starcross closed 3 years ago

Starcross commented 3 years ago

Hi, I'm having an issue once the map has been scaled, calling scrollTo causes the map to jump to a completely different place, depending on how much the map has been scaled.

It looks like this has something to do with setConstrainedScroll being called and the values there being clipped to scrollLimitX/Y

I'm using a single level with min and max limits set

        MapViewConfiguration config = new MapViewConfiguration(
                1,
                PIXEL_WIDTH,
                PIXEL_HEIGHT,
                RemoteTileStream.tileSize,
                tileStreamProvider
        );
        config.setMaxScale(2f);
        config.setMinScale(0.5f);
        config.setTileOptionsProvider(tileOptionsProvider);
        mMapView.configure(config);

I wonder if this setup is correct. I'm also having an issue with defineBounds not having any effect. This isn't a problem, as it's easy enough to calculate the pixels required, but I'm mentioning it in case it's related.

p-lr commented 3 years ago

Hi, it's possible that the jump is caused by using wrong coordinates for scrollTo. I need a working example to figure out what's going on. Could you fork the demo app and reproduce the issue?

Starcross commented 3 years ago

I've created a fork here

There's a button on the first fragment that calls scrollToAndCenter with fixed pixel co-ordinates.

If you zoom in a bit at a time and click the button, you should see it jumps to a different place each time. It's more noticeable the more you zoom in.

p-lr commented 3 years ago

That's because the scroll is affected by the scale.

p-lr commented 3 years ago

8192 is the size of the map at scale 1. So 4096 corresponds to the center of the map, at scale 1. If you want the button to center on the map, use this:

button.setOnClickListener{
      mapView.scrollToAndCenter((4096 * mapView.scale).toInt(), (4096 * mapView.scale).toInt())
}
p-lr commented 3 years ago

Alternatively, a common use case is to center on a marker. That's when defineBounds is handy. For an example, have a look at MapMarkersFragment. Suppose you set bounds like this: mapView.defineBounds(0.0, 0.0, 1.0, 1.0), and you add a marker at the center:

mapView.addMarker(marker, 0.5, 0.5)

You can then center on that marker using the moveToMarker api: mapView.moveToMarker(marker, destinationScale = 0.8, shouldAnimate = true)

Starcross commented 3 years ago

Thanks for you help. I have it working using the scale now.

I think I got confused as I am porting over from TileView, where I was able to call defineBounds, then scrollToAndCenter without making any transformations.