android - example - "Overzoom" tileoverlay google maps
google maps api key (1)
Tengo un problema en el que actualmente estoy tratando de construir una solución personalizada para. Estoy luchando, quizás pueda hacer que funcione, pero quizás ya haya otra solución para esto.
Mi cliente tiene un backend para obtener superposiciones de mosaicos, pero solo va hasta el nivel de zoom 8. Después de eso, no se muestran mosaicos.
Para hacer mosaicos más detallados, he usado https://stackoverflow.com/a/36696291/969016 en el pasado. Toma 4 fichas de un nivel de zoom más alto y lo construye en 1.
Pero ahora, tengo que tomar fichas de un nivel de zoom inferior y necesito hacerlas explotar. He estado tratando de tomar el anterior como base, pero aún no he tenido éxito. Si alguien sabe un enfoque diferente, estaría muy agradecido.
¿O tal vez es posible que Google Maps siga ampliando el zoom sin solicitar una nueva capa por encima de cierto nivel? Quiero decir, esto ya lo hace de todos modos entre los niveles de zoom
Tomando la solución para mejorar la resolución de los mosaicos (al componer 4 mosaicos de un nivel de zoom más alto en 1) por @RadekJ here , comencé a hacer lo contrario: tomar un nivel de zoom más bajo, cortarlo en 4 partes y usar para construir un mayor nivel de zoom a partir de ella.
Digamos que el nivel de zoom máximo para el que tienes fichas es de 8, pero quieres poder reducir a 9, 10, etc. soplando estas fichas.
Cada vez que acercas el zoom, los mosaicos se dividen por 2. Entonces, tomando el nivel de zoom 9 como ejemplo, tomé el mosaico del nivel de zoom 8 y lo corté en 4 partes. Luego determiné qué ''cuadrante'' necesitaba para la ficha solicitada en el nivel 9.
A continuación, uso la recursión para poder obtener los niveles de zoom para niveles aún más altos. Estoy muy contento con el resultado.
Establezca DRAW_DEBUG_DATA
en true
si desea ver los mosaicos con su x
, y
y el zoom level
dibujado en ellos.
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import com.google.android.gms.maps.model.Tile;
import com.google.android.gms.maps.model.TileProvider;
import java.io.ByteArrayOutputStream;
public class OverZoomTileProvider implements TileProvider {
public static final int MAX_ZOOM = 8;
private static final boolean DRAW_DEBUG_DATA = false;
private static final int TILE_SIZE = 256;
private static final int HALF_TILE_SIZE = TILE_SIZE / 2;
private Paint tilePainter = new Paint();
// these will only be used when DRAW_DEBUG_DATA is true
private Paint debugRectPaint;
private Paint debugTextPaint;
private TileProvider mTileProvider;
public OverZoomTileProvider(TileProvider tileProvider) {
mTileProvider = tileProvider;
if (DRAW_DEBUG_DATA) {
debugRectPaint = new Paint();
debugRectPaint.setColor(Color.RED);
debugRectPaint.setStrokeWidth(1);
debugRectPaint.setStyle(Paint.Style.STROKE);
debugTextPaint = new Paint();
debugTextPaint.setColor(Color.WHITE);
debugTextPaint.setStyle(Paint.Style.FILL);
debugTextPaint.setColor(Color.BLACK);
debugTextPaint.setTextSize(20);
}
}
@Override
public Tile getTile(int x, int y, int zoom) {
Bitmap image = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE,
Bitmap.Config.ARGB_8888);
image.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(image);
drawTile(canvas, zoom, x, y);
byte[] data = bitmapToByteArray(image);
image.recycle();
return new Tile(TILE_SIZE, TILE_SIZE, data);
}
private void drawTile(Canvas canvas, int zoom, int x, int y) {
Bitmap bitmap = getTileAsBitmap(x, y, zoom);
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, tilePainter);
bitmap.recycle();
}
if (DRAW_DEBUG_DATA) {
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), debugRectPaint);
canvas.drawText("" + x + ", " + x + " (" + zoom + ")", 128, 128, debugTextPaint);
}
}
private Bitmap getTileAsBitmap(int x, int y, int zoom) {
if (zoom <= MAX_ZOOM) {
Tile tile = mTileProvider.getTile(x, y, zoom);
if (tile == NO_TILE) {
return null;
}
return BitmapFactory.decodeByteArray(tile.data, 0, tile.data.length);
}
boolean leftColumn = x % 2 == 0;
boolean topRow = y % 2 == 0;
Bitmap bitmap = getTileAsBitmap(x / 2, y / 2, zoom - 1);
int quadrant;
if (leftColumn && topRow) {
quadrant = 1;
} else if (!leftColumn && topRow) {
quadrant = 2;
} else if (leftColumn) {
quadrant = 3;
} else {
quadrant = 4;
}
switch (quadrant) {
case 1:
bitmap = Bitmap.createBitmap(bitmap, 0, 0, HALF_TILE_SIZE, HALF_TILE_SIZE);
break;
case 2:
bitmap = Bitmap.createBitmap(bitmap, HALF_TILE_SIZE, 0, HALF_TILE_SIZE, HALF_TILE_SIZE);
break;
case 3:
bitmap = Bitmap.createBitmap(bitmap, 0, HALF_TILE_SIZE, HALF_TILE_SIZE, HALF_TILE_SIZE);
break;
case 4:
bitmap = Bitmap.createBitmap(bitmap, HALF_TILE_SIZE, HALF_TILE_SIZE, HALF_TILE_SIZE, HALF_TILE_SIZE);
break;
}
return Bitmap.createScaledBitmap(bitmap, TILE_SIZE, TILE_SIZE, false);
}
private static byte[] bitmapToByteArray(Bitmap bm) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, bos);
byte[] data = bos.toByteArray();
try {
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
}