Influence the Tile size in Android Maps TileProvider? - android

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/

Related

Google Maps - TileOverlay - Stretch tiles for higher zoom levels

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?).

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.

GroundOverlay images with dimention lengths of power 2

I'm using a GroundOverlay to display images over a Google Map on Android. The images I'm using are being pulled from a server and aren't guaranteed to have width/height with a value that is a power of 2.
According to the docs if I don't make the sides of length power 2 the API will do this for me.
Note: When the image is added to the map it will be converted to an image with sides that are powers of two. You can avoid this conversion by using an original image with dimensions that are powers of two — for example, 128x512 or 1024x1024.
Does anyone on the Google Maps for Android team have any information on whether the images are stretched/cropped etc in order to make them have sides of length power 2?
If they are stretched/cropped is this taken into account when rendering the bitmap if I specify a certain LatLngBounds as the region to overlay the image onto (e.g. are the bounds increased to match the new width/height)?
Also, is the aspect ration of the image preserved? Is this even possible if the original source image doesn't have an aspect ratio that would allow resizing to have sides of length power 2?
Thanks,
Andy.

How to get the pixel size of the full map?

I have partial map of the world (like America or Africa). and I need to know to pixel size of the world map based on the size of the partial/cropped map pixel size.
I have the size in pixel of the partial map (like 480x256), and I have the minLongitude,maxlongitude,minlatitude,maxlatitude (aka left,right,top,bottom edge)
I know that longitude is easy because linear :
FULL_CIRCLE_DEG = 360
longitudeDelta = (maxLongitude-minLongitude)/FULL_CIRCLE_DEG
MapFullSize = mapCroppedWidth/longitudeDelta
But for the latitude, it's kind of different:
FULL_LATITUDE_DEG = MAX_LAT_ON_EARTH - MIN_LAT_ON_EARTH (like 85.7543...-(-85.7543...))
latitudeDelta = (maxLatitude-minLatitude)/FULL_LATITUDE_DEG
MapFullHeight = ????
Please someone can help me ?
I find lot of algorithm to get a GPScoordinateToPixel conversion but nothing on square calculation.
Thank you.
Here's an idea. First work out the area of your rectangle which is specified by minLongitude,maxlongitude,minlatitude,maxlatitude. Then the ratio of your current map area to the area of the whole world map could be used to scale up the current number of pixels that the map currently occupies to the number of pixels that would be required for the whole map.
To work out the area that the map currently occupies, I think you need a bit of spherical trigonometry, and you can find what you need here on wikipedia. That page on wikipedia gives you a formula for the area of a spherical triangle, so if you regard your rectangle as two triangles, you can use that formula and calculate the area of the current map.

Categories

Resources