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

Load tiles and downsample images from server if needed #40

Closed mohlendo closed 11 years ago

mohlendo commented 11 years ago

In that version you can provide a protocol in the file pattern like

mapView.addZoomLevel(1024, 1024, "http://localhost:8080/tiles/256/0/%col%-%row%.png","http://localhost:8080/downsample.png", 256, 256);

and the MapView loads them over http. If you provide no protocol, it loads the files as assets. Now it would be possible to add more protocol implementations like ftp etc...

Shusshu commented 11 years ago

Link to Issue #31

moagrius commented 11 years ago

I really like the idea of allowing http tiles (especially if it "works") but want to consider implementation a little more. I think it might be a little cleaner to subclass instead of testing the file path string, or maybe a settable property... Not sure yet - let's think about it some before committing.

@Shusshu, anyone, thoughts?

Shusshu commented 11 years ago

Yes I would also prefer to have second implementation of the MapTile & DownsampleManager they would be constructed when you create your MapView with a certain parameter or something.

moagrius commented 11 years ago

or maybe a subclass (of MapView itself, that uses the other implementations of the image decoding classes)...

Shusshu commented 11 years ago

sure subclass is good also of course

Benoit Billington

On Fri, Apr 5, 2013 at 7:48 PM, moagrius notifications@github.com wrote:

or maybe a subclass...

— Reply to this email directly or view it on GitHubhttps://github.com/moagrius/MapView/pull/40#issuecomment-15970414 .

mohlendo commented 11 years ago

I think it would be easier for users of the MapView to configure the source of the tiles with the tile-pattern and with the tile-pattern alone. When you also have to change some other configuration besides the pattern, that would probably lead to a lot of errors because of misconfiguration. The protocol part of an URI should be enough to define where to load the tiles from.You should also consider to use the "file://" protocol to load the tiles from any path on the device.

moagrius commented 11 years ago

I'm curious - are you using HTTP images currently? I'd be interested in seeing how it performs - any chance you could share an .apk?

mohlendo commented 11 years ago

Yes, I am using it right now. It is fast enough, what ever that means ;-) I don't have a server in the net right now, but I will look for some other map source and share that with you.

moagrius commented 11 years ago

Looking forward to seeing it. I think this is worth a merge, but still want to consider some details - for example, it might be worthwhile to add the ImageView tiles to the tree (in the right spot) while the download is happening (which is not how it works right now - the ImageView isn't added until the decode is complete), to maybe show a stub or some kind of loading indicator - this is one of the reasons I thought it'd be nice to see it in action. I definitely like the idea of http loading - not sold on the string sniffing (at least as is) - but maybe a merge followed by another update would be appropriate.

moagrius commented 11 years ago

@mohlendo Thanks for the patch - I have implemented this behavior on my local build, but have changed access to the behavior in order to support as broad a range of implementations and adhere to best practices as closely as possible. Instead of examining the string, I'm allowing an arbitrary class instance that implements a simple interface (with a decode method which returns a bitmap) to be set. This way, the user can generate bitmaps in any way he/she sees fit - assets, https, resources, SD cart, SVG, dynamic drawing, etc. I have created one implementation of this interface (MapTileDecoderHttp) that mirrors the version you provided, and will credit you in the comments. I think it's a great idea and am glad to include it, but will be closing this pull request in favor of the alternative implementation I just described.

I'm in the middle of a big update, so probably won't commit for a while yet, but everything looks good (so far) on my local build.

Thanks again.

mohlendo commented 11 years ago

@moagrius that sounds very cool! I am looking forward to that!

moagrius commented 11 years ago

@mohlendo updated: https://github.com/moagrius/MapView/blob/master/src/com/qozix/mapview/tiles/MapTileDecoderHttp.java

derekbrameyer commented 11 years ago

Hi @moagrius, @mohlendo:

I'm hoping to use MapView (which is awesome, btw) to provide zoom levels for one image fetched via HTTP. It's not tiled, so I was hoping to rely on MapView to create zoom levels (I'm OK with the image being blurry). I can't quite wrap my head around how to accomplish this. Here's what I've got:

mMapView.setTileDecoder(new MapTileDecoderHttp() {
    @Override
    public Bitmap decode(String fileName, Context context) {
        fileName = mImageUrl;
        return super.decode(fileName, context);
    }
}
int vertWidth = 1500, vertHeight = 1500; // Set statically for now
mMapView.addZoomLevel(vertWidth, vertHeight, "tiles/125_%col%_%row%.png");
mMapView.addZoomLevel(vertWidth * 2, vertHeight * 2, "tiles/250_%col%_%row%.png");
mMapView.addZoomLevel(vertWidth * 4, vertHeight * 4, "tiles/500_%col%_%row%.png");
mMapView.addZoomLevel(vertWidth * 8, vertHeight * 8, "tiles/1000_%col%_%row%.png");

Thanks for the awesome library, and if you can point me in the right direction, I'd appreciate it!

moagrius commented 11 years ago

@derekbrameyer the component itself does not create different levels from a single image, and does not do the actual tiling (on the last project I did tiles on, on a powerful desktop PC, it took nearly an hour to generate all the tile images - it's not realistic to have a device attempt that).

The primary reason we use tiles is to keep bitmap memory low - it would be much easier to just load one big image in and fling it around, but you'd almost certainly get out-of-memory errors immediately.

If your image is small enough, you can create tiles pretty easily in PhotoShop (use the slice tool), but it only supports a limited number of slices. There are also some online utilities that will do it for you, but they're also somewhat limited - I use batch or shell scripts generally, in conjunction with ImageMagick.

Finally, tiles are not stretched - they will be rendered at their natural size. The "downsample" (low resolution background) is stretched, but this release does not support HTTP fetching of downsamples (although the most recent version does, but it's not yet committed). I plan on committing that version within the next week. At that point, you could theoretically use a single zoom level with no tiles and just a downsample, but that's likely to be really low-quality.

It'd also be possible to use the ZoomPanLayout class (http://moagrius.github.io/MapView/documentation/com/qozix/layouts/ZoomPanLayout.html) and just stick an image in it, which would give you fling/drag/etc, but you'd have to implement your own scaling mechanism on the image, and it wouldn't support markers, callouts, paths, etc.

HTH.