If you already try addPolygon()
and GroundOverlay
there are two possibilities left:
using Tile Overlays (preferred);
using custom drawing over MapView
or MapFragment
.
IMHO Tile Overlay is a better way due possibility of high performance TileProvider
implementation. For example, you can create tiles for "low" zoom levels and "current" (level that should be shown to user at the beginning) zoom level and store them in array (HashMap
, etc.) or file system path ..\zoom_level\x\y\tile.png
if there are a lot of tiles. And more "detailed" tiles you can create "on the fly" (in separate thread) when it needs to be shown, and then also store them for future using (if needed). Of course, you need custom module for fast GeoJson
reading (something like Jackson) and rendering it to the .png
tiles. So, seems it is possible to create TileProvider
for your case, optimal by performance and memory consumption. You can use this answer of Alex Vasilkov as first iteration.
If you choose custom drawing you should override onDraw()
method for MapView
or dispatchDraw()
for MapFragment
. like in this answer. In that case you can control all of the process, but that way is more complex for implementation.
Update:
You can implement action for onCameraMove()
, like in this answer (some tricky passing of GoogleMap
object used there):
public class RadarMapView extends MapView implements OnMapReadyCallback {
private OnMapReadyCallback mMapReadyCallback;
private GoogleMap mGoogleMap;
private Marker mMarker;
private Paint mPaintRadar;
public RadarMapView(@NonNull Context context) {
super(context);
init();
}
public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public RadarMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
super(context, options);
init();
}
@Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
drawRadarOverTheMap(canvas);
canvas.restore();
}
private void drawRadarOverTheMap(Canvas canvas) {
if (mGoogleMap == null) {
return;
}
final float centerX = getX() + getWidth() / 2;
final float centerY = getY() + getHeight() / 2;
canvas.drawCircle(centerX, centerY, 150, mPaintRadar);
canvas.drawCircle(centerX, centerY, 300, mPaintRadar);
canvas.drawCircle(centerX, centerY, 450, mPaintRadar);
}
private void init() {
setWillNotDraw(false);
mPaintRadar = new Paint();
mPaintRadar.setColor(Color.GREEN);
mPaintRadar.setStyle(Paint.Style.STROKE);
mPaintRadar.setStrokeWidth(10);
}
@Override
public void getMapAsync(OnMapReadyCallback callback) {
mMapReadyCallback = callback;
super.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
invalidate(); // NB! Exactly this line you need
}
});
if (mMapReadyCallback != null) {
mMapReadyCallback.onMapReady(googleMap);
}
}
}
Update #2:
You can make "screenshot" (not exactly screenshot, but create image of polyigons on the bitmap) of current view of polygons and move it in onCameraMove()
(not redraw all polygons). And then in onCameraIdle()
create and show new full polygons view. Also, you can create bitmap slightly bigger then map screen view (for zooming out and scrolling properly). Or you can "skip" some of the onCameraMove()
calls (e.g. call invalidate()
once per 3 onCameraMove()
calls etc.).
By the way: in case of Tile Overlays moving and zooming are available "from the box". You only need to create a tricky TileProvider. There are only several tiles need to be generated for whole device screen (size of the single tile is 256x256). So, you can generate tiles for current screen, for currentZoomLevel-1, for currentZoomLevel+1 (in case of zooming) and + 2 (or 3) tiles to the left, right, top and bottom (in case of scrolling). Also you can store generated tiles for future using in some cache (HashMap, LRU, etc.). And you can generate "extra" (not currently visible) tiles in separate threads.