moagrius / MapView

(Deprecated, prefer https://github.com/moagrius/TileView) Android widget roughly described as a hybrid between com.google.android.maps.MapView and iOS's CATiledLayer
http://moagrius.github.com/MapView/documentation
69 stars 35 forks source link

Centering the map #39

Closed mohlendo closed 11 years ago

mohlendo commented 11 years ago

I have a flat map that is in its smallest zoom level much smaller than the size of the MapView Container. Right now, the MapView container just draws the map from the top-left corner, which leads to a lot of empty space on the rest of the screen. Would it be possible to center the map?

moagrius commented 11 years ago

if you don't use mess with the minimum scale, and leave scaleToFitTrue (which is default), the MapView will never show space, and will always fit it's layout dimensions - you can have it fill parent or fixed size, and it'll figure out the minimum scale to so that it's never smaller on the smallest axis. I feel like I'm not explaining that well - does that make sense?

mohlendo commented 11 years ago

In my usecase I always want to provide all possible zoom levels - regardless of the device size/view size - because every zoom level contains different kind information that should always be available. So if the Map is very small in zoom level 0 and there will be a lot of space left I still want to be able to present that zoom level. Then it would be great when this small map is centered in the available space. Maybe that is a new option or something.

BTW: When I set scaleToFit to false I am still not able to see the smallest map but instead the one that fits best. I thought, that when scaleToFit is false, the MapView shows every zoom level as-is there is still scaling. How can I disable that?

moagrius commented 11 years ago

scaleToFit effectively just sets the minimum allowed scale value to whatever it would be based on the size of the tileset and the dimensions of the device. if you've set the minimum scale elsewhere, that could also prevent some levels from showing. try setting minimum scale to 0 (or something ridiculously small).

i'll point out that i always intended the mapview to never be smaller than it's container, and both the minimum/maximum scale methods and setScaleToFit are undocumented deliberately - they're not well tested and could introduce other bugs. i think it's probably safe, but as I said I didn't spend much time on situations where it could be smaller than the screen. I'll look into this next update, mid-month.

I think the only way to center it would have to be external - within the widget itself, everything (positioning, geolocation, intersection detection, tile placement), is based on a 0,0 coordinate system. I'd probably do it like this:

  1. Put the MapView inside a FrameLayout, and set the FrameLayout's position to whatever you want.
  2. Add a MapEventListener and override onScaleChanged.
  3. During scale change events, check getScaledWidth and getScaledHeight, and compare that to the width and height of the containing FrameLayout. If it's smaller, than set the MapViews layout width and layout height to the scaled values, and do the math to position it manually, something like
int containingWidth = frameLayout.getWidth();
int containingHeight = frameLayout.getHeight();
int mapWidth = mapView.getScaledWidth();
int mapHeight = mapView.getScaledHeight();
// if mapWidth/Height are bigger than containingWidth/Height
// set layout params to match_parent and margins to 0
// otherwise...
LayoutParams lp = mapView.getLayoutParams();
lp.width = mapWidth;
lp.height = mapHeight;
lp.leftMargin = (int) ((containingWidth - mapWidth) * 0.5);
lp.topMargin = (int) ((containingHeight - mapHeight) * 0.5);
mapView.setLayoutParams(lp);

That's just off the top of my head - there could be errors in logic or syntax, but that's probably where I'd start.

HTH, LMK how it goes.

moagrius commented 11 years ago

@mohlendo how did this work out? can I close this issue?

mohlendo commented 11 years ago

Ok, the Map is centered, but now I cannot scroll anymore...

moagrius commented 11 years ago

Hm... No idea why that would happen. I'll try to recreate the concept tomorrow and see if I notice anything.

moagrius commented 11 years ago

@mohlendo - I just did a quick POC of the basic concept and it works as expected. It centers to the container, and continues to scroll if there's still unshown area (e.g., if its shorter than the view it centers along the y axis, but if there's still content along the x axis, it'll still scroll). Obviously, if the whole thing is smaller than the container, there's nothing to scroll.

This is pretty much exactly as I'd expect. Here's a gist using a RelativeLayout. I can post the apk if you think it'd be helpful.

If that's now what you're looking for, maybe you can post more detailed "rules" about how you want it to behave and I'll do my best to point out the relevant code.

mohlendo commented 11 years ago

@moagrius using your gist with the RelativeLayout does the trick! Thanks!