Google Maps - TileOverlay - Stretch tiles for higher zoom levels - android

I have built a custom TileProvider from a map image, but the original image does not cover the required map area for the resolution corresponding to the highest zoom level.
By default, the provider returns no tiles if I do not create images for the corresponding zoom levels. Is it possible to zoom on the existing tile rather? I could create zoomed tiles these which would be basically stretched and cut versions of the highest resolution I have, but this seems redundant and would take unnecessary disk space/processing.
Is there a way to stretch tiles when none is available for a high zoom level, rather than creating those tiles explicitly? I could always set the maxZoom property on the map, but I have different overlays with different resolutions. I could also add some smart processing in the provider to return a subsampled version of a tile at lower resolution on the fly, but I am hoping there is a built in way to do this.

You cannot stretch the tiles per zoom level (automatically) but you can instead wrap your URL Tile provider with one that allows you to customize the behaviour. For example I've done (some years ago) a custom tile provider whose cached the tiles in a specific folder of the phone (better and longer caching than gmaps one), but could also be possibile to check the zoom (z) and if it is higher than a specific value, you can retrieve the tile for a lower zoom and split by 4 (no zoom but cut and zoom.
The result will be very poor, and honestly I find better to create them on server side (are you using a WMS provider maybe?).

Related

Android Is it possible to change the appearance of the map in the google maps API

I have been searching in the documentation and throughout google. I would like to know if it is possible to place an image over the map the api comes from to use something else as a visual but with the maps gps functionality. Does anyone know if this is possible?
You can use two types of Overlays:
TileOverlays (reference)
A TileOverlay defines a set of images that are added on top of the base map tiles. You can also use tile overlays to add extra features to the map by providing transparent tile images. You need to provide the tiles for each zoom level that you want to support. If you have enough tiles at multiple zoom levels, you can supplement Google's map data for the entire map.
GroundOverlay (reference)
A ground overlay is an image that is fixed to a map. Unlike markers, ground overlays are oriented against the Earth's surface rather than the screen, so rotating, tilting or zooming the map will change the orientation of the image. Ground overlays are useful when you wish to fix a single image at one area on the map. If you want to add extensive imagery that covers a large portion of the map, you should consider a Tile overlay.

How to use own custom imagery instead of google map in Android app

I have developed an app in android where I am using Google Map for capturing location. I have a large satellite image ( greater than 500 mb ), this image is geo-coded. We need to display this as one of the layers in the map like google map has a choice for satellite imagery. How can it be done.
Thank you in advance.
To add custom imaginery to your map you can use TileOverlay:
From the documentation of TileOverlay
A TileOverlay defines a set of images that are added on top of the base map tiles. You can also use tile overlays to add extra features to the map by providing transparent tile images. You need to provide the tiles for each zoom level that you want to support. If you have enough tiles at multiple zoom levels, you can supplement Google's map data for the entire map.
Tile overlays are useful when you want to add extensive imagery to the map, typically covering large geographical areas. In contrast, ground overlays are useful when you wish to fix a single image at one area on the map.
To use TileOverlay you need to implement a TileProvider that returns the correct Tile object for each tile requested by the map.
Take into account that your data (your images) need to be georeferenced to return the correct tiles to be drawn on the map.
Once your data is displayed you may want to do map.setMapType(GoogleMap.MAP_TYPE_NONE); to stop asking for Google tiles.
Update based on the comments:
As you say that you want to automate the tiling for different image formats, you will need to implement a TileProvider for each of the image formats that you want to be able to load.
To return the correct Tile you will need to transform between the tile x, y, and zoom (the parameters of the public Tile getTile(int x, int y, int zoom) function of the TileProvider interface) and the coordinates (and pixels) of you georeferenced image. You can take a look at http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ to learn more about the tiling system.
Also, if the image's srid not WGS84 you will need to geotransform your data.
Take into account that if your image is big and you are showing a large area you may find OutOfMemory errors, and you may want to take a look at Loading Large Bitmaps Efficiently to load a scaled down version of your image to be returned as the tile.

Restrict OSMDroid scrolling to a specific bounding box & zoom level

I have tiles downloaded from Mobac tool, with the source being Openstreet mapQuest.
Given that we may not have tiles for all positions at a higher zoom level, when we scroll, areas that are missing tiles result in a null grid or stretched images of lower zoom-level tiles.
How can I restrict scrolling to only a given bounding box and zoom level?
Implementing MapListener interface, I overrode the OnZoom function. Depending upon current zoomlevel and the points visible on screen, the scrollable boundingbox can be set by calling mapView.setScrollableAreaLimit.

Influence the Tile size in Android Maps TileProvider?

I have been playing around with the TileOverlay in Android Maps v2 and I have built a custom TileProvider very very similar to this one
But there is something that strikes me as odd. No matter which number I pass on to the Tile constructor, the image on the screen is always the same - 4 to 9 Tiles sharing the screen space evenly, like this:
Of course this is something you would expect from reading the documentation:
The coordinates of the tiles are measured from the top left (northwest) corner of the map. At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from west to east and the y values range from 0 to 2N - 1 and increase from north to south.
But you might guess that there is in fact such a functionality from looking at the Constructors documentation
Constructs a Tile. Parameters
width the width of the image in pixels
height the height of the image in pixels
data A byte array containing the image data. The image will be created from this data by calling decodeByteArray(byte[], int, int).
So obviously I misunderstood something here. My personal guess is that the tiles have to cover an entire "Map Tile" and can therefore not be shrunken
My goal would be to make my tiles about 10dp of the screen. Therefore again my question to you:
Can I realize this with TileOverlay or will I end up using custom Markers?
The size of the tile specified in the constructor is the size of (every) bitmap tile you are supplying to the map. This allows you to provide tiles at different densities for different screens if you have such resources.
It will not change the size of the image that is drawn on the map. The physical size of a map tile is defined by the zoom level, where a zoom level of 0 is a single tile covering the entire world, 1 is 2x2 tiles, etc. This is part of an open web map standard for map tiles, not defined by Google.
API docs:
https://developers.google.com/maps/documentation/android/tileoverlay
Ref:
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

osmdroid - display tiles bigger

I'm using osmdroid and maps downloaded from OSM up to level 16. I was wondering if there is any way I could make the osmdroid use the tile from that zoom level but draw it bigger.
The thing is that tiles on that level have enough detail for me, but are drawn to small. I've seen some other apps use the same tile levels but somehow managing to draw them bigger.
Thanks
The best solution I have found to this problem (which I had myself earlier today), is to change the scaling in the tile source (I'm using my own version of OpenStreetMap):
final float scale = getBaseContext().getResources().getDisplayMetrics().density;
final int newScale = (int) (256 * scale);
String[] OSMSource = new String[2];
OSMSource[0] = "http://a.tile.openstreetmap.org/";
OSMSource[1] = "http://b.tile.openstreetmap.org/";
XYTileSource MapSource = new XYTileSource(
"OSM",
null,
1,
18,
newScale,
".png",
OSMSource
);
map.setTileSource(MapSource);
Varying the scale in accordance with the screen density is a relatively good solution. During my testing some of the images became slightly blurry, but if you decrease the scaling for that contingency you get a very good outcome.
This is not my solution BTW, I found it among the OSMDROID issues on Github. Thanks goes to stefangab95.
You can't do this without modifying the source code of osmdroid. Right now, tiles are shown at their actual resolution except when the view is being animated between zoom levels. That is, the tiles are switched when the animation is done, and the scale is set to 1 again. I have tried some tricks to keep the scaling when the user tries zooming beyond the highest level of detail. It works visually, but all the functions that map from pixels to map coordinates, as well as some of the interaction when dragging the map, breaks. It would therefore require a more significant modification of the source. It is doable, but I think it's not really worth the trouble - unless you actually want to contribute the modification to the project, and do it in a less hackish way.
mMapview.setTilesScaledToDpi(true)
https://github.com/osmdroid/osmdroid/blob/master/osmdroid-android/src/main/java/org/osmdroid/views/MapView.java#L307
that's should do the trick
I'm using offline tiles and just did this to display them at 2x resolution. The important part is the 512 pixel size even though the tiles are 256.
myMapView.setTileSource (new XYTileSource ("Mapnik", ResourceProxy.string.offline_mode, 13, 17, 512, ".png", "http://127.0.0.1"));
Cloudmade have support for high-resolution tiles that look much better on the current phones on the market now. Have a look here:
http://developers.cloudmade.com/projects/tiles/documents
I would use the normal tiles for ldpi and mdpi devices, and use the high-res ones for hdpi and xhdpi devices
To solve your problem completely, there exist two approach.
The first one is that you'd generate or render map tiles by your own by mapnik-like software.
The second one is using vector-based real-time renderer on mobile phone like mapsforge.
The configure file or style file is the key in both of these approach.
You can use a different tile source, for instance M$ Bing. That also has bigger street names.
One workaround that stays within the current working model of OSMdroid is to use an image manipulation package like ImageMagick or Photoshop to create a new set of bitmap tiles at the higher zoom level.
What you need to do is take each current tile (256x256px), resize it, doubling both size and width, and then cutting the image into 4 new tiles. Save each tile according to the naming convention for the new zoom level. The tile map naming convetion is described here, as well as an easy way of getting the 4 new names from the original name

Categories

Resources