package net.osmand.plus.render;
import net.osmand.core.android.MapRendererView;
import net.osmand.core.android.TileSourceProxyProvider;
import net.osmand.core.jni.MapLayerConfiguration;
import net.osmand.core.jni.PointI;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPointDouble;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.views.BaseMapLayer;
import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.corenative.NativeCoreContext;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
public class MapVectorLayer extends BaseMapLayer {
private OsmandMapTileView view;
private ResourceManager resourceManager;
private Paint paintImg;
private RectF destImage = new RectF();
private final MapTileLayer tileLayer;
private boolean visible = false;
private boolean oldRender = false;
private String cachedUnderlay;
private Integer cachedMapTransparency;
private String cachedOverlay;
private Integer cachedOverlayTransparency;
public MapVectorLayer(MapTileLayer tileLayer, boolean oldRender) {
this.tileLayer = tileLayer;
this.oldRender = oldRender;
}
@Override
public void destroyLayer() {
}
@Override
public boolean drawInScreenPixels() {
return false;
}
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
resourceManager = view.getApplication().getResourceManager();
paintImg = new Paint();
paintImg.setFilterBitmap(true);
paintImg.setAlpha(getAlpha());
}
public boolean isVectorDataVisible() {
return visible && view.getZoom() >= view.getSettings().LEVEL_TO_SWITCH_VECTOR_RASTER.get();
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
if (!visible) {
resourceManager.getRenderer().clearCache();
}
}
@Override
public int getMaximumShownMapZoom() {
return 22;
}
@Override
public int getMinimumShownMapZoom() {
return 1;
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tilesRect, DrawSettings drawSettings) {
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tilesRect, DrawSettings drawSettings) {
if (!visible) {
return;
}
// if (!isVectorDataVisible() && tileLayer != null) {
// tileLayer.drawTileMap(canvas, tilesRect);
// resourceManager.getRenderer().interruptLoadingMap();
// } else {
final MapRendererView mapRenderer = view.getMapRenderer();
if (mapRenderer != null && !oldRender) {
NativeCoreContext.getMapRendererContext().setNightMode(drawSettings.isNightMode());
OsmandSettings st = view.getApplication().getSettings();
if (!Algorithms.objectEquals(st.MAP_UNDERLAY.get(), cachedUnderlay)) {
cachedUnderlay = st.MAP_UNDERLAY.get();
ITileSource tileSource = st.getTileSourceByName(cachedUnderlay, false);
if (tileSource != null) {
TileSourceProxyProvider prov = new TileSourceProxyProvider(view.getApplication(), tileSource);
mapRenderer.setMapLayerProvider(-1, prov.instantiateProxy(true));
prov.swigReleaseOwnership();
// mapRenderer.setMapLayerProvider(-1,
// net.osmand.core.jni.OnlineTileSources.getBuiltIn().createProviderFor("Mapnik (OsmAnd)"));
} else {
mapRenderer.resetMapLayerProvider(-1);
}
}
if (!Algorithms.objectEquals(st.MAP_TRANSPARENCY.get(), cachedMapTransparency)) {
cachedMapTransparency = st.MAP_TRANSPARENCY.get();
MapLayerConfiguration mapLayerConfiguration = new MapLayerConfiguration();
mapLayerConfiguration.setOpacityFactor(((float) cachedMapTransparency) / 255.0f);
mapRenderer.setMapLayerConfiguration(0, mapLayerConfiguration);
}
if (!Algorithms.objectEquals(st.MAP_OVERLAY.get(), cachedOverlay)) {
cachedOverlay = st.MAP_OVERLAY.get();
ITileSource tileSource = st.getTileSourceByName(cachedOverlay, false);
if (tileSource != null) {
TileSourceProxyProvider prov = new TileSourceProxyProvider(view.getApplication(), tileSource);
mapRenderer.setMapLayerProvider(1, prov.instantiateProxy(true));
prov.swigReleaseOwnership();
// mapRenderer.setMapLayerProvider(1,
// net.osmand.core.jni.OnlineTileSources.getBuiltIn().createProviderFor("Mapnik (OsmAnd)"));
} else {
mapRenderer.resetMapLayerProvider(1);
}
}
if (!Algorithms.objectEquals(st.MAP_OVERLAY_TRANSPARENCY.get(), cachedOverlayTransparency)) {
cachedOverlayTransparency = st.MAP_OVERLAY_TRANSPARENCY.get();
MapLayerConfiguration mapLayerConfiguration = new MapLayerConfiguration();
mapLayerConfiguration.setOpacityFactor(((float) cachedOverlayTransparency) / 255.0f);
mapRenderer.setMapLayerConfiguration(1, mapLayerConfiguration);
}
// opengl renderer
LatLon ll = tilesRect.getLatLonFromPixel(tilesRect.getPixWidth() / 2, tilesRect.getPixHeight() / 2);
mapRenderer.setTarget(new PointI(MapUtils.get31TileNumberX(ll.getLongitude()), MapUtils.get31TileNumberY(ll
.getLatitude())));
mapRenderer.setAzimuth(-tilesRect.getRotate());
mapRenderer.setZoom((float) (tilesRect.getZoom() + tilesRect.getZoomAnimation() + tilesRect
.getZoomFloatPart()));
float zoomMagnifier = st.MAP_DENSITY.get();
mapRenderer.setVisualZoomShift(zoomMagnifier - 1.0f);
} else {
if (!view.isZooming()) {
if (resourceManager.updateRenderedMapNeeded(tilesRect, drawSettings)) {
// pixRect.set(-view.getWidth(), -view.getHeight() / 2, 2 * view.getWidth(), 3 *
// view.getHeight() / 2);
final RotatedTileBox copy = tilesRect.copy();
copy.increasePixelDimensions(copy.getPixWidth() / 3, copy.getPixHeight() / 4);
resourceManager.updateRendererMap(copy, null);
}
}
MapRenderRepositories renderer = resourceManager.getRenderer();
drawRenderedMap(canvas, renderer.getBitmap(), renderer.getBitmapLocation(), tilesRect);
drawRenderedMap(canvas, renderer.getPrevBitmap(), renderer.getPrevBmpLocation(), tilesRect);
}
}
private boolean drawRenderedMap(Canvas canvas, Bitmap bmp, RotatedTileBox bmpLoc, RotatedTileBox currentViewport) {
boolean shown = false;
if (bmp != null && bmpLoc != null) {
float rot = -bmpLoc.getRotate();
canvas.rotate(rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY());
final RotatedTileBox calc = currentViewport.copy();
calc.setRotate(bmpLoc.getRotate());
QuadPointDouble lt = bmpLoc.getLeftTopTile(bmpLoc.getZoom());
QuadPointDouble rb = bmpLoc.getRightBottomTile(bmpLoc.getZoom());
final float x1 = calc.getPixXFromTile(lt.x, lt.y, bmpLoc.getZoom());
final float x2 = calc.getPixXFromTile(rb.x, rb.y, bmpLoc.getZoom());
final float y1 = calc.getPixYFromTile(lt.x, lt.y, bmpLoc.getZoom());
final float y2 = calc.getPixYFromTile(rb.x, rb.y, bmpLoc.getZoom());
// LatLon lt = bmpLoc.getLeftTopLatLon();
// LatLon rb = bmpLoc.getRightBottomLatLon();
// final float x1 = calc.getPixXFromLatLon(lt.getLatitude(), lt.getLongitude());
// final float x2 = calc.getPixXFromLatLon(rb.getLatitude(), rb.getLongitude());
// final float y1 = calc.getPixYFromLatLon(lt.getLatitude(), lt.getLongitude());
// final float y2 = calc.getPixYFromLatLon(rb.getLatitude(), rb.getLongitude());
destImage.set(x1, y1, x2, y2);
if (!bmp.isRecycled()) {
canvas.drawBitmap(bmp, null, destImage, paintImg);
shown = true;
}
canvas.rotate(-rot, currentViewport.getCenterPixelX(), currentViewport.getCenterPixelY());
}
return shown;
}
@Override
public void setAlpha(int alpha) {
super.setAlpha(alpha);
if (paintImg != null) {
paintImg.setAlpha(alpha);
}
}
@Override
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}
}