Open GoogleCodeExporter opened 8 years ago
I tried with osmdroid-android-3.0.10.jar but no effect, could it be possible to
scale the available tiles in previous zoom level in fake zoom even in scrolling.
Original comment by min2bhan...@gmail.com
on 29 May 2013 at 5:56
We don't provide this functionality. If you'd like it, write it yourself and
contribute back.
Original comment by kurtzm...@gmail.com
on 29 May 2013 at 12:53
Original comment by kurtzm...@gmail.com
on 29 May 2013 at 12:53
It would be great if you could provide some guidelines or hint to implement the
same.
Thanks & Regards
Original comment by devendra...@gmail.com
on 29 May 2013 at 1:23
You will want to create a new tileprovider module and add it to your
MapTileProviderArray. The modules are what feed tiles to the TileOverlay. It
will be tricky because you will need to request tiles from other tileprovider
modules for the higher zoom levels and then pull them from the tile cache and
then scale them. You can either try to use the existing MapTileProviderArray or
create a new one just for the scaled tiles.
So let's say you decide to use a second MapTileProviderArray for just the
scaled tiles. The tile request chain should look like:
Request for tile 4/4/17.
Request tile from offline tile provider. Not found.
Request tile from new scaled tile provider.
Scaled tile provider checks its "scaled" tile cache for one zoom level up (2/2/16). Not found.
Request tile for one zoom level up through its "scaled" MapTileProviderArray. Since the request is asynchronous, the tile request will fail for this cycle.
Re-request for tile 4/4/17.
Request tile from offline tile provider. Not found.
Request tile from new scaled tile provider.
Scaled tile provider checks its "scaled" tile cache for 2/2/16. This time it's found, scaled, and returned.
Original comment by kurtzm...@gmail.com
on 29 May 2013 at 1:47
Thanks for the suggestions!!
Original comment by devendra...@gmail.com
on 30 May 2013 at 6:13
do you have any plans to implement this enhancement?
Thanks
Original comment by min2bhan...@gmail.com
on 30 May 2013 at 9:48
This is something that is desired but there are no active plans to implement
this.
Original comment by kurtzm...@gmail.com
on 30 May 2013 at 1:09
min2bhandari I am facing the same problem, did you find any solution for the
same ?
If you have resolved this issue then please share the source code.
thanks in advance
Original comment by ashwanik...@gmail.com
on 4 Jul 2013 at 1:03
I have tried to understand the library but unable to resolve it, its not so
trivial to implement this issue by own, as it would require more help by the
owner.
Original comment by min2bhan...@gmail.com
on 5 Jul 2013 at 3:03
kurtzm...@gmail.com
I am also facing the 18 zoom level issue.I have read you suggestion and what i
understand that when i am trying to zoom for 18 level actually i should get 16
level tiles for the same position then enlarge tiles to 18 level tiles and then
put on map.
But now i am facing the issue that how can i relate 18 level zoom position to
16 level zoom position so that i can get tiles and enlarge them.
Please give me some guideline for this.I am Waiting for your positive response.
Thanking you.
Original comment by ashwanik...@gmail.com
on 17 Jul 2013 at 2:25
I am attaching an experimental and rough cut at a scaled tile overlay. It needs
work to be complete and to perform well but it works to some degree.
All it does is draw all cached tiles that are not in the current zoom level to
the screen and properly scaled to the current zoom level.
One thing that it really needs to do is check to see if the correct tile exists
in the current zoom level before drawing the scaled tile.
Original comment by kurtzm...@gmail.com
on 18 Jul 2013 at 9:31
Issue 469 has been merged into this issue.
Original comment by kurtzm...@gmail.com
on 23 Aug 2013 at 8:56
Hi. This is exactly what I was looking to do as well. I tested the patch by
manually incorporating your drawSafe() into my own Overlay based on the
ItemizedIconOverlay class as I need markers being drawn. One thing this patch
should consider if trying to combine it with ItemizedIconOverlay is that an
overrided drawSafe() that attempts to scale tiles needs to call
super.drawSafe() in order for the extended drawSafe to do what it's intended
to. e.g. with ItemizedIconOverlay, it would actually draw markers. I don't know
if this means that tiles are technically drawn twice, (by the override
drawSafe, then by the super.drawSafe) but effectively it doesn't matter as the
super.drawSafe doesn't have the tiles for that zoom level to draw anyways, so
you get the scaled tile, and the underlying super.drawSafe can do its extra
work, like draw markers, etc...
One deficiency I'd like to sort out is that when you zoom to a level where
scaling is necessary and being drawn, then you pan the map to an area outside
of that scaled tile, its empty. When you zoom out to the available tile level,
then in again, the tiles are available and scaled like before.
Original comment by ch...@mckenzieic.com
on 8 Jan 2014 at 4:02
Ah it appears that my cached tile set doesn't have the required tiles loaded
when panning after zooming below the available tile max zoom level. For
example, I have tiles for 17 to 19 zoom levels. I zoom to level 20, then pan
over past the tiles already cached at zoom level 19. In safeDraw(),
mTileProvider.getTileCache().getAllTiles(null), which are additions to
MapTileProviderBase and MapTileCache, will not have the the tiles panned to
cache yet.
I believe because the patch implements the scaling in the Overlay, its stuck
working with what it already has cached. drawSafe could be enhanced to try and
pull any of the viewable tiles from the tile source,added to the cache, then
scaled, if I could get access to more than the cache from my Overlay. (as a
result of the patch adding a getTileCache method to MapTileProviderBase)
However I have no clue how to determine the MapTile's that would be used in the
MapView at any given time. e.g. if I knew at Overlay drawSafe or draw time what
MapTile's the MapView if trying to display, then I could try loading them from
the TileSource and scaling them myself.
Any tips? I really want the panning support to work. This might not be the best
way to do it, but I'm desperate and this is a prototype. Thanks!
Original comment by ch...@mckenzieic.com
on 8 Jan 2014 at 9:20
Ugh, this is painful. I tried implementing my own MapTileFileArchiveProvider,
that has a TileLoader which will attempt to retrieve tiles a zoom level up and
scale them, but I have no clue how to deal with returning a scaled image. If we
try to support this in a Tile Provider, then we need to scale the image from a
level up then split it, and pick the correct split section and return it.
When trying to return the image that should belong to a non-existent tile, the
image from a level up that's zoomed covers a larger geographic area than the
tile is intended to. So the image needs to be scaled, then split. The problem
is, how do I safely split it and determine where the map tile's X/Y should be?
I'd like to draw an image illustrating this, but I think you get the point.
There's two ways to work with tile images you want to scale:
1) At the file load level
2) At the point of drawing the tile images.
At least when the tiles are drawn you have access to the Projection, MapView,
zoom, etc... and can do stuff like kurtzm has done in his patch. (from an
Overlay)
Can someone from osmdroid comment on this? Maybe provide some clear guidance?
I'm essentially looking for zoom to levels I don't have tiles for. Sure the
tile image will get pixelated, but close markers on the map can be reasonably
zoomed into. This is a real problem on high resolution screens.
Thanks!
Original comment by ch...@mckenzieic.com
on 8 Jan 2014 at 11:59
Ok, I worked out a Tile Provider only solution. This should be a stick note
somewhere. As mentioned, I ended up implementing my own
MapTileScaledFileArchiveProvider as an alternative to
MapTileFileArchiveProvider. I probably could have extended
MapTileFileArchiveProvider but I was trying to work around all the inaccessible
parts and just wanted to get this working.
I don't have a patch, I'm just going to paste in a clip of my TileLoader class,
its got all the goods and can likely be improved/adapted to work with an online
Tile Provider. I expected that Tile caching would be handled based on what's
returned from loadTile, but it seems like the tiles are constantly loaded from
the archive. Also, it seems to work fine with my tiles that have a maximum of
19, and "fake" zoom to level 21. When I zoom to level 22 I get missing tile
loads. I'm not sure why, maybe there's a round error, but it's all integer.
(e.g. int rx = pTile.getX()/(2*z); where rx is used as the X when looking for
the tile image)
Panning works with this approach as well. When I zoom in to level 20 or 21,
then pan around, the higher levels tiles are loaded, resized, and cropped as
needed.
Improvements could include a fake zoom cache as part of the Tile Provider
itself, or access to the actual tile cache from the Tile Provider so it
wouldn't try to load every tile request afresh. (from what I can tell) Also,
there's probably a more efficient way to resize and crop the tiles.
The up side to this approach is that no changes are needed to the osmdroid API.
You can simply implement your own Tile Provider, and/or extend an existing one,
then handle up sizing and cropping lower level tiles.
public class MapTileScaledFileArchiveProvider extends
MapTileFileStorageProviderBase {
...
@Override
protected Runnable getTileLoader() {
return new TileLoader();
}
protected class TileLoader extends MapTileModuleProviderBase.TileLoader {
@Override
public Drawable loadTile(final MapTileRequestState pState) {
ITileSource tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
final MapTile pTile = pState.getMapTile();
// if there's no sdcard then don't do anything
if (!getSdCardAvailable()) {
Log.d(TAG, "No sdcard - do nothing for tile: " + pTile);
return null;
}
InputStream inputStream = null;
try {
inputStream = getInputStream(pTile, tileSource);
if (inputStream != null) {
Log.d(TAG, "Use tile from archive: " + pTile);
final Drawable drawable = tileSource.getDrawable(inputStream);
return drawable;
} else {
final int requestedZoom = pTile.getZoomLevel();
final int maxZoom = 3;
MapTile rTile = null;
for(int z=1; z<maxZoom; z++) {
int rx = pTile.getX()/(2*z);
int ry = pTile.getY()/(2*z);
rTile = new MapTile(requestedZoom - z, rx, ry); // We have to construct a new MapTile request for the higher zoom level
inputStream = getInputStream(rTile, tileSource);
if (inputStream != null) {
final Drawable redrawable = resize(tileSource.getDrawable(inputStream), pTile.getX(), pTile.getY(), z);
return redrawable;
} else {
Log.d(TAG, "Tile doesn't exist and I couldn't find a tile to scale: " + pTile);
}
}
}
} catch (final Throwable e) {
Log.e(TAG, "Error loading tile", e);
} finally {
if (inputStream != null) {
StreamUtils.closeStream(inputStream);
}
}
return null;
}
final int mTileSizePixels = 256;
private Drawable resize(Drawable image, final int rx, final int ry, final int zoomLevelDiff) {
int px = rx%(2*zoomLevelDiff);
int py = ry%(2*zoomLevelDiff);
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createBitmap(
Bitmap.createScaledBitmap(b, (mTileSizePixels*2)*zoomLevelDiff, (mTileSizePixels*2)*zoomLevelDiff, false),
(px == 0) ? 0 : mTileSizePixels*px,
(py == 0) ? 0 : mTileSizePixels*py,
mTileSizePixels,
mTileSizePixels);
return new BitmapDrawable(Tec3Application.context().getResources(), bitmapResized);
}
}
Original comment by ch...@mckenzieic.com
on 9 Jan 2014 at 5:51
Hi, can you provide a readable answer on this I am stuck for like 2 days on
this issue and I would appreciate it if you share your custom
MapTileScaledFileArchiveProvider
Original comment by tagru...@gmail.com
on 11 Feb 2014 at 2:09
Are you talking to me? You have the source to MapTileFileStorageProviderBase. I
gave you the override and TileLoader I did in that sample along with how I
scaled the tile.
Maybe you should offer a bit more information on how you're "stuck".
Original comment by ch...@mckenzieic.com
on 11 Feb 2014 at 2:49
I am trying to reimplement the #18. Could you please explain where does the
getInputStream come from?
Original comment by tam...@gmail.com
on 1 May 2014 at 6:14
Hi Tam.
As I mentioned, my suggested approach, (which I find doesn't perform great and
needs some scaled tile caching added) is an alternative to the
MapTileFileArchiveProvider class
(https://code.google.com/p/osmdroid/source/browse/trunk/osmdroid-android/src/org
/osmdroid/tileprovider/modules/MapTileFileArchiveProvider.java?r=687).
The code I included in post #18 were the primary changes to a copy of the
MapTileFileArchiveProvider class. Basically I took MapTileFileArchiveProvider
and implemented my own TileLoader. The rest is from MapTileFileArchiveProvider.
The getInputStream() method of the MapTileFileArchiveProvider which I copied
into my MapTileScaledFileArchiveProvider class.
Original comment by ch...@mckenzieic.com
on 1 May 2014 at 3:22
Also, if you're planning on C&P my code into your own copy of
MapTileFileArchiveProvider, the resize() method I included in post #18 needs a
little change. BitmapDrawable needs your application context. In the version I
included I had my own way to retrieve it, you should too. The only change below
is to "return new BitmapDrawable()" where you need to specify your context.
private Drawable resize(Drawable image, final int rx, final int ry, final int zoomLevelDiff) {
int px = rx%(2*zoomLevelDiff);
int py = ry%(2*zoomLevelDiff);
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createBitmap(
Bitmap.createScaledBitmap(b, (mTileSizePixels*2)*zoomLevelDiff, (mTileSizePixels*2)*zoomLevelDiff, false),
(px == 0) ? 0 : mTileSizePixels*px,
(py == 0) ? 0 : mTileSizePixels*py,
mTileSizePixels,
mTileSizePixels);
return new BitmapDrawable(context.getResources(), bitmapResized);
}
Original comment by ch...@mckenzieic.com
on 1 May 2014 at 3:29
Excellent approach. I was thinking of doing the exact same thing and happily
stumbled on your posting before doing exactly what you're doing in #18 and #23
- the resize/crop math was what I was looking for when I found your post as
that is hairy to a non graphics person like me.
The only addition I was planning to make is to have a "water mark" tile for
when there are no upper tiles to scale, or the tile to scale is too high up so
as not to be useful. This is for a situation where the mapped area has a very
irregular shape (definitely not a rectangle) and the app does not want to allow
any underlying online map to show through. This allows me to significantly
compress the MB Tiles file by using a single watermark tile (e.g.
zoom=column=tile=-1) rather than lots of empty tiles that although individually
take up little space will accumulate to occupy a lot of space. Also the
run-time configurable maximum scale setting will allow islands of deep five
zoom levels in an otherwise low zoom level wide area map, with the border being
a little fuzzy at the first few zoom levels in, and then switching over to the
watermark tile when probably the user is nowhere near the edge of the zoom
level anyway.
I also find the all the private/final method definitions frustrating requiring
a copy/paste/edit model with the "fun" of redoing the work when upgrading to a
more modern library version. I understand why the developers have done this, I
just don't like it.
I'll try to remember to post back my code if I get it to work, and work
efficiently.
Original comment by colin.gr...@gmail.com
on 9 Sep 2014 at 5:28
ch...@mckenzieic.com
Thanks for a great approach,however If I pan map to the sides, other tiles,
then the one which is already fake zoomed, are not displayed. Do you have any
more workaround about this?
Thanks
Original comment by mujSams...@gmail.com
on 10 Sep 2014 at 12:03
Original issue reported on code.google.com by
min2bhan...@gmail.com
on 28 May 2013 at 1:38