Introduce new lat/lon math

This commit is contained in:
vshcherb 2013-09-27 11:04:49 +02:00
parent 67880f2b15
commit 4cad736511
26 changed files with 338 additions and 227 deletions

View file

@ -0,0 +1,229 @@
package net.osmand.data;
import net.osmand.util.MapUtils;
public class RotatedTileBox {
/// primary fields
private double lat;
private double lon;
private float rotate;
private int zoom;
private float zoomScale;
private int cx;
private int cy;
private int pixWidth;
private int pixHeight;
// derived
// all geometry math is done in tileX, tileY of phisycal given zoom
// zoomFactor is conversion factor, from dtileX * zoomFactor = dPixelX
private float zoomFactor;
private float rotateCos;
private float rotateSin;
private float oxTile;
private float oyTile;
private QuadRect tileBounds;
private QuadRect latLonBounds;
private QuadPoint tileLT;
private QuadPoint tileRT;
private QuadPoint tileRB;
private QuadPoint tileLB;
public RotatedTileBox(int pixWidth, int pixHeight, float centerX, float centerY,
double lat, double lon, int zoom, float zoomScale, float rotate) {
init(pixWidth, pixHeight, centerX, centerY, lat, lon, zoom, zoomScale, rotate);
}
public RotatedTileBox(RotatedTileBox r){
// TODO
}
private void init(int pixWidth, int pixHeight, float centerX, float centerY, double lat, double lon,
int zoom, float zoomScale, float rotate) {
this.pixWidth = pixWidth;
this.pixHeight = pixHeight;
this.lat = lat;
this.lon = lon;
this.zoom = zoom;
this.zoomScale = zoomScale;
this.rotate = rotate;
cx = (int) (pixWidth * centerX);
cy = (int) (pixHeight * centerY);
// derived
calculateDerivedFields();
}
private void calculateDerivedFields() {
zoomFactor = (float) Math.pow(2, zoomScale) * 256;
float rad = (float) Math.toRadians(this.rotate);
rotateCos = (float) Math.cos(rad);
rotateSin = (float) Math.sin(rad);
oxTile = (float) MapUtils.getTileNumberX(zoom, lon);
oyTile = (float) MapUtils.getTileNumberY(zoom, lat);
while(rotate < 0){
rotate += 360;
}
while(rotate > 360){
rotate -= 360;
}
calculateTileRectangle();
}
protected float getTileXFromPixel(int x, int y) {
int dx = x - cx;
int dy = y - cy;
float dtilex;
if(isMapRotateEnabled()){
dtilex = (rotateCos * (float) dx + rotateSin * (float) dy);
} else {
dtilex = (float) dx;
}
return dtilex / zoomFactor + oxTile;
}
protected float getTileYFromPixel(int x, int y) {
int dx = x - cx;
int dy = y - cy;
float dtiley;
if(isMapRotateEnabled()){
dtiley = (-rotateSin * (float) dx + rotateCos * (float) dy);
} else {
dtiley = (float) dy;
}
return dtiley / zoomFactor + oyTile;
}
public void calculateTileRectangle() {
float x1 = getTileXFromPixel(0, 0);
float x2 = getTileXFromPixel(pixWidth, 0);
float x3 = getTileXFromPixel(pixWidth, pixHeight);
float x4 = getTileXFromPixel(0, pixHeight);
float y1 = getTileYFromPixel(0, 0);
float y2 = getTileYFromPixel(pixWidth, 0);
float y3 = getTileYFromPixel(pixWidth, pixHeight);
float y4 = getTileYFromPixel(0, pixHeight);
tileLT = new QuadPoint(x1, y1);
tileRT = new QuadPoint(x2, y2);
tileRB = new QuadPoint(x3, y3);
tileLB = new QuadPoint(x4, y4);
float l = Math.min(Math.min(x1, x2), Math.min(x3, x4)) ;
float r = Math.max(Math.max(x1, x2), Math.max(x3, x4)) ;
float t = Math.min(Math.min(y1, y2), Math.min(y3, y4)) ;
float b = Math.max(Math.max(y1, y2), Math.max(y3, y4)) ;
tileBounds = new QuadRect(l, t, r, b);
float top = (float) MapUtils.getLatitudeFromTile(zoom, tileBounds.top);
float left = (float) MapUtils.getLongitudeFromTile(zoom, tileBounds.left);
float bottom = (float) MapUtils.getLatitudeFromTile(zoom, tileBounds.bottom);
float right = (float) MapUtils.getLongitudeFromTile(zoom, tileBounds.right);
latLonBounds = new QuadRect(left, top, right, bottom);
}
public int getPixWidth() {
return pixWidth;
}
public int getPixHeight() {
return pixHeight;
}
public int getPixXFromLatLon(double latitude, double longitude) {
float xTile = (float) MapUtils.getTileNumberX(zoom, longitude);
float yTile = (float) MapUtils.getTileNumberY(zoom, latitude);
return getPixXFromTile(xTile, yTile);
}
protected int getPixXFromTile(float xTile, float yTile) {
float rotX;
final float dTileX = xTile - oxTile;
final float dTileY = yTile - oyTile;
if(isMapRotateEnabled()){
rotX = (rotateCos * dTileX - rotateSin * dTileY);
} else {
rotX = dTileX;
}
float dx = rotX * zoomFactor;
return (int) (dx + cx);
}
public int getPixYFromLatLon(double latitude, double longitude) {
float xTile = (float) MapUtils.getTileNumberX(zoom, longitude);
float yTile = (float) MapUtils.getTileNumberY(zoom, latitude);
return getPixYFromTile(xTile, yTile);
}
protected int getPixYFromTile(float xTile, float yTile) {
final float dTileX = xTile - oxTile;
final float dTileY = yTile - oyTile;
float rotY;
if(isMapRotateEnabled()){
rotY = (rotateSin * dTileX + rotateCos * dTileY);
} else {
rotY = dTileY;
}
float dy = rotY * zoomFactor;
return (int) (dy + cy);
}
private boolean isMapRotateEnabled() {
return rotate != 0;
}
public QuadRect getLatLonBounds() {
return latLonBounds;
}
public float getRotateCos() {
return rotateCos;
}
public float getRotateSin() {
return rotateSin;
}
public float getZoom() {
return zoom;
}
public int getIntZoom() {
return Math.round(zoom);
}
public float getRotate() {
return rotate;
}
public boolean containsTileBox(RotatedTileBox box) {
QuadPoint temp = new QuadPoint();
if(box.zoom != zoom){
throw new UnsupportedOperationException();
}
if(!containsTilePoint(box.tileLB)){
return false;
}
if(!containsTilePoint(box.tileLT)){
return false;
}
if(!containsTilePoint(box.tileRB)){
return false;
}
if(!containsTilePoint(box.tileRT)){
return false;
}
return true;
}
public boolean containsTilePoint(QuadPoint qp) {
double tx = getPixXFromTile(qp.x, qp.y);
double ty = getPixYFromTile(qp.x, qp.y);
return tx >= 0 && tx <= pixWidth && ty >= 0 && ty <= pixHeight;
}
}

View file

@ -12,6 +12,11 @@ public class RotatedTileBox {
private float zoom;
private float rotateCos;
private float rotateSin;
private QuadRect latLonBounds;
private int pixelWidth;
private int pixelHeight;
public RotatedTileBox(float leftTileX, float topTileY, float tileWidth, float tileHeight, float rotate, int zoom) {
set(leftTileX, topTileY, tileWidth, tileHeight, rotate, zoom);
@ -40,6 +45,26 @@ public class RotatedTileBox {
this.topTileY = topTileY;
this.zoom = zoom;
init();
latLonBounds = calculateLatLonBox(new QuadRect());
}
public int getPixelWidth() {
return pixelWidth;
}
public int getPixelHeight() {
return pixelHeight;
}
public void setPixelDimensions(int width, int height) {
this.pixelHeight = height;
this.pixelWidth = width;
}
public QuadRect getLatLonBounds() {
return latLonBounds;
}
public float getRotateCos() {
@ -102,7 +127,7 @@ public class RotatedTileBox {
return true;
}
public QuadRect calculateLatLonBox(QuadRect rectF) {
private QuadRect calculateLatLonBox(QuadRect rectF) {
float tx = calcPointTileX(tileWidth, 0);
float tx2 = calcPointTileX(tileWidth, tileHeight);
float tx3 = calcPointTileX(0, tileHeight);

View file

@ -10,6 +10,7 @@ import net.osmand.data.LatLon;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
@ -25,7 +26,6 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;
@ -83,10 +83,10 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
}
@Override
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings settings) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (view.getZoom() >= startZoom) {
DataTileManager<Recording> recs = plugin.getRecordings();
List<Recording> objects = recs.getObjects(latlonRect.top, latlonRect.left, latlonRect.bottom, latlonRect.right);
List<Recording> objects = recs.getObjects(tileBox.top, tileBox.left, tileBox.bottom, tileBox.right);
for (Recording o : objects) {
int x = view.getRotatedMapXForPoint(o.getLatitude(), o.getLongitude());
int y = view.getRotatedMapYForPoint(o.getLatitude(), o.getLongitude());

View file

@ -15,20 +15,14 @@ import net.osmand.CallbackWithObject;
import net.osmand.IndexConstants;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.Route;
import net.osmand.plus.GPXUtilities.Track;
import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.MapInfoLayer;
@ -52,7 +46,6 @@ import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.text.Editable;
import android.text.TextWatcher;
@ -478,7 +471,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
}
@Override
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings settings) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (measurementPoints.size() > 0) {
path.reset();
int marginY = originIcon.getHeight();

View file

@ -13,11 +13,8 @@ import java.util.List;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.DialogProvider;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.osmedit.OsmPoint.Action;
@ -37,7 +34,6 @@ import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@ -150,7 +146,7 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
// request to load
requestToLoad(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom());

View file

@ -2,17 +2,11 @@ package net.osmand.plus.osmodroid;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import net.osmand.access.AccessibleToast;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapLayer;
@ -24,11 +18,8 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.RemoteException;
import android.text.format.DateFormat;
import android.text.format.Time;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;
@ -100,7 +91,7 @@ public class OsMoDroidLayer extends OsmandMapLayer implements ContextMenuLayer.I
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
for (OsMoDroidPoint op : OsMoDroidPointArrayList) {
LatLon newLatlon;

View file

@ -6,6 +6,7 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapLayer;
@ -16,7 +17,6 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.text.format.DateFormat;
import android.text.format.Time;
import android.util.DisplayMetrics;
@ -75,7 +75,7 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
LatLon parkingPoint = getParkingPoint();
if (parkingPoint == null)
return;

View file

@ -144,7 +144,6 @@ public class MapRenderRepositories {
nativeFiles.remove(file);
}
}
try {
c.close();
} catch (IOException e) {
@ -510,7 +509,7 @@ public class MapRenderRepositories {
requestedBox = new RotatedTileBox(tileRect);
// calculate data box
QuadRect dataBox = requestedBox.calculateLatLonBox(new QuadRect());
QuadRect dataBox = requestedBox.getLatLonBounds();
long now = System.currentTimeMillis();
if (cObjectsBox.left > dataBox.left || cObjectsBox.top > dataBox.top || cObjectsBox.right < dataBox.right

View file

@ -84,7 +84,7 @@ public class MapVectorLayer extends BaseMapLayer {
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings drawSettings) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings drawSettings) {
if (!visible) {
return;
}

View file

@ -5,6 +5,11 @@ public abstract class BaseMapLayer extends OsmandMapLayer {
private int alpha = 255;
protected int warningToSwitchMapShown = 0;
@Override
public boolean isLightweightLayer() {
return false;
}
public int getMaximumShownMapZoom(){
return 21;
}

View file

@ -10,6 +10,7 @@ import java.util.Map.Entry;
import net.osmand.data.LatLon;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@ -20,7 +21,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.DisplayMetrics;
@ -125,7 +125,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if(latLon != null){
int x = view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude());
int y = view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude());

View file

@ -18,15 +18,12 @@ import android.widget.FrameLayout;
import net.osmand.IndexConstants;
import net.osmand.binary.BinaryMapDataObject;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.DownloadIndexActivity;
import net.osmand.plus.activities.OsmandIntents;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
@ -111,7 +108,7 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
private static int ZOOM_TO_SHOW_MAP_NAMES = 12;
@Override
public void onDraw(Canvas canvas, RectF latLonBox, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBox, DrawSettings nightMode) {
final int zoom = view.getZoom();
if(downloadBtn.getVisibility() == View.VISIBLE) {
downloadBtn.setVisibility(View.GONE);

View file

@ -20,10 +20,10 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;
import net.osmand.plus.RotatedTileBox;
public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
@ -75,7 +75,7 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
// request to load
for (FavouritePoint o : favorites.getFavouritePoints()) {

View file

@ -6,6 +6,7 @@ import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import android.graphics.Canvas;
@ -15,7 +16,6 @@ import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
public class GPXLayer extends OsmandMapLayer {
@ -71,7 +71,7 @@ public class GPXLayer extends OsmandMapLayer {
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
GPXFile gpxFile = view.getApplication().getGpxFileToDisplay();
if(gpxFile == null){
return;

View file

@ -6,6 +6,7 @@ import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.util.MapUtils;
import android.content.Context;
@ -13,7 +14,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
@ -107,7 +107,7 @@ public class MapControlsLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
BaseMapLayer mainLayer = view.getMainLayer();
boolean zoomInEnabled = mainLayer != null && view.getZoom() < mainLayer.getMaximumShownMapZoom();
boolean zoomOutEnabled = mainLayer != null && view.getZoom() > mainLayer.getMinimumShownMapZoom();

View file

@ -17,10 +17,7 @@ import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout.LayoutParams;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.*;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivityActions;
import net.osmand.plus.routing.RoutingHelper;
@ -531,7 +528,7 @@ public class MapInfoLayer extends OsmandMapLayer {
@Override
public void onDraw(Canvas canvas, RectF latlonBounds, RectF tilesRect, DrawSettings drawSettings) {
public void onDraw(Canvas canvas, RotatedTileBox latlonBounds, DrawSettings drawSettings) {
updateColorShadowsOfText(drawSettings);
// update data on draw
rightStack.updateInfo(drawSettings);

View file

@ -6,6 +6,7 @@ import net.osmand.map.TileSourceManager;
import net.osmand.map.TileSourceManager.TileSourceTemplate;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.resources.ResourceManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@ -109,12 +110,12 @@ public class MapTileLayer extends BaseMapLayer {
@Override
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings drawSettings) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings drawSettings) {
if ((map == null && mapTileAdapter == null) || !visible) {
return;
}
if(mapTileAdapter != null){
mapTileAdapter.onDraw(canvas, latlonRect, tilesRect, drawSettings.isNightMode());
mapTileAdapter.onDraw(canvas, tileBox, tilesRect, drawSettings.isNightMode());
}
drawTileMap(canvas, tilesRect);
}

View file

@ -5,15 +5,18 @@ import java.util.Map;
import net.osmand.plus.ContextMenuAdapter;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
import android.view.MotionEvent;
import net.osmand.plus.RotatedTileBox;
public abstract class OsmandMapLayer {
public abstract void initLayer(OsmandMapTileView view);
public abstract void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings settings);
public abstract void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings);
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
}
public abstract void destroyLayer();
@ -33,7 +36,7 @@ public abstract class OsmandMapLayer {
/**
* This method returns whether canvas should be rotated as
* map rotated before {@link #onDraw(Canvas)}.
* map rotated before {@link #onDraw(android.graphics.Canvas, net.osmand.plus.RotatedTileBox, net.osmand.plus.views.OsmandMapLayer.DrawSettings)}.
* If the layer draws simply layer over screen (not over map)
* it should return true.
*/

View file

@ -10,14 +10,12 @@ import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityActionsProvider;
import net.osmand.access.AccessibleToast;
import net.osmand.access.MapExplorer;
import net.osmand.data.LatLon;
import net.osmand.data.*;
import net.osmand.map.IMapLocationListener;
import net.osmand.map.MapTileDownloader.DownloadRequest;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.*;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.util.MapUtils;
@ -269,20 +267,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return r;
}
/**
* @return x tile based on (int) zoom
*/
public float getXTile() {
return (float) MapUtils.getTileNumberX(getZoom(), longitude);
}
/**
* @return y tile based on (int) zoom
*/
public float getYTile() {
return (float) MapUtils.getTileNumberY(getZoom(), latitude);
}
/**
* @return y tile based on (int) zoom
*/
@ -376,22 +360,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
// ////////////////////////////// DRAWING MAP PART /////////////////////////////////////////////
protected void drawEmptyTile(Canvas cvs, float x, float y, float ftileSize, boolean nightMode) {
float tileDiv = (ftileSize / emptyTileDivisor);
for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
float xk = x + tileDiv * k1;
float yk = y + tileDiv * k2;
if ((k1 + k2) % 2 == 0) {
cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, paintGrayFill);
} else {
cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, nightMode ? paintBlackFill : paintWhiteFill);
}
}
}
}
public BaseMapLayer getMainLayer() {
return mainLayer;
}
@ -408,10 +376,13 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
public int getCenterPointX() {
TODO;
return getWidth() / 2;
}
public int getCenterPointY() {
TODO;
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
return 4 * getHeight() / 5;
}
@ -422,14 +393,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
this.mapPosition = type;
}
public double calcLongitude(int pixelFromCenter) {
return MapUtils.getLongitudeFromTile(getZoom(), getXTile() + pixelFromCenter / getTileSize());
}
public double calcLatitude(int pixelFromCenter) {
return MapUtils.getLatitudeFromTile(getZoom(), getXTile() + pixelFromCenter / getTileSize());
}
public void calculateLatLonRectangle(Rect pixRect, RectF latLonRect) {
int z = (int) zoom;
float tileX = (float) MapUtils.getTileNumberX(z, getLongitude());
@ -446,46 +409,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
public void calculateTileRectangle(Rect pixRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect) {
float x1 = calcDiffTileX(pixRect.left - cx, pixRect.top - cy);
float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy);
float x3 = calcDiffTileX(pixRect.right - cx, pixRect.top - cy);
float x4 = calcDiffTileX(pixRect.right - cx, pixRect.bottom - cy);
float y1 = calcDiffTileY(pixRect.left - cx, pixRect.top - cy);
float y2 = calcDiffTileY(pixRect.left - cx, pixRect.bottom - cy);
float y3 = calcDiffTileY(pixRect.right - cx, pixRect.top - cy);
float y4 = calcDiffTileY(pixRect.right - cx, pixRect.bottom - cy);
float l = Math.min(Math.min(x1, x2), Math.min(x3, x4)) + ctilex;
float r = Math.max(Math.max(x1, x2), Math.max(x3, x4)) + ctilex;
float t = Math.min(Math.min(y1, y2), Math.min(y3, y4)) + ctiley;
float b = Math.max(Math.max(y1, y2), Math.max(y3, y4)) + ctiley;
tileRect.set(l, t, r, b);
}
public void calculatePixelRectangle(Rect pixelRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect) {
float x1 = calcDiffPixelX(tileRect.left - ctilex, tileRect.top - ctiley);
float x2 = calcDiffPixelX(tileRect.left - ctilex, tileRect.bottom - ctiley);
float x3 = calcDiffPixelX(tileRect.right - ctilex, tileRect.top - ctiley);
float x4 = calcDiffPixelX(tileRect.right - ctilex, tileRect.bottom - ctiley);
float y1 = calcDiffPixelY(tileRect.left - ctilex, tileRect.top - ctiley);
float y2 = calcDiffPixelY(tileRect.left - ctilex, tileRect.bottom - ctiley);
float y3 = calcDiffPixelY(tileRect.right - ctilex, tileRect.top - ctiley);
float y4 = calcDiffPixelY(tileRect.right - ctilex, tileRect.bottom - ctiley);
int l = Math.round(Math.min(Math.min(x1, x2), Math.min(x3, x4)) + cx);
int r = Math.round(Math.max(Math.max(x1, x2), Math.max(x3, x4)) + cx);
int t = Math.round(Math.min(Math.min(y1, y2), Math.min(y3, y4)) + cy);
int b = Math.round(Math.max(Math.max(y1, y2), Math.max(y3, y4)) + cy);
pixelRect.set(l, t, r, b);
}
// used only to save space & reuse
protected RectF tilesRect = new RectF();
protected RectF latlonRect = new RectF();
protected Rect boundsRect = new Rect();
protected RectF bitmapToDraw = new RectF();
protected Rect bitmapToZoom = new Rect();
protected OsmandSettings settings = null;
public OsmandSettings getSettings(){
if(settings == null){
settings = getApplication().getSettings();
@ -493,6 +417,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return settings;
}
private void refreshMapNonLightweightMap() {
}
private void refreshMapInternal(boolean updateVectorRendering) {
handler.removeMessages(1);
long ms = SystemClock.elapsedRealtime();
@ -506,21 +434,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
SurfaceHolder holder = getHolder();
synchronized (holder) {
int nzoom = getZoom();
float tileX = (float) MapUtils.getTileNumberX(nzoom, longitude);
float tileY = (float) MapUtils.getTileNumberY(nzoom, latitude);
float w = getCenterPointX();
float h = getCenterPointY();
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
boolean nightMode = application.getDaynightHelper().isNightMode();
try {
boundsRect.set(0, 0, getWidth(), getHeight());
calculateTileRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
latlonRect.top = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.top);
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
updateLatLonBounds();
boolean nightMode = application.getDaynightHelper().isNightMode();
if (nightMode) {
canvas.drawARGB(255, 100, 100, 100);
} else {
@ -556,7 +474,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return fps;
}
private void drawOverMap(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings drawSettings) {
private void drawOverMap(Canvas canvas, RotatedTileBox tileBox, DrawSettings drawSettings, boolean
onPrepareImage) {
int w = getCenterPointX();
int h = getCenterPointY();
@ -571,16 +490,17 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
if (!layer.drawInScreenPixels()) {
canvas.rotate(getRotate(), w, h);
}
layer.onDraw(canvas, latlonRect, tilesRect, drawSettings);
if(onPrepareImage) {
layer.onPrepareBufferImage(canvas, tileBox, drawSettings);
} else {
layer.onDraw(canvas, tileBox, drawSettings);
}
canvas.restore();
} catch (IndexOutOfBoundsException e) {
// skip it
}
// long time = System.currentTimeMillis();
// log.debug("Layer time " + (time - prev) + " " + zOrders.get(layers.get(i)));
// prev = time;
}
if (showMapPosition) {
if (showMapPosition && !onPrepareImage) {
canvas.drawCircle(w, h, 3 * dm.density, paintCenter);
canvas.drawCircle(w, h, 7 * dm.density, paintCenter);
}
@ -623,40 +543,12 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
// ///////////////////////////////// DRAGGING PART ///////////////////////////////////////
public float calcDiffTileY(float dx, float dy) {
if(isMapRotateEnabled()){
return (-rotateSin * dx + rotateCos * dy) / getTileSize();
} else {
return dy / getTileSize();
}
private net.osmand.data.RotatedTileBox getCurrentRotatedTileBox() {
return new net.osmand.data.RotatedTileBox(getWidth(), getHeight(), 0.5f,
mapPosition == OsmandSettings.BOTTOM_CONSTANT? 0.8f : 0.5f, getLatitude(), getLongitude(),
(int) zoom, (getSettings().USE_HIGH_RES_MAPS.get() ? 0 : 0.5f) + (zoom - (int) zoom),rotate);
}
public float calcDiffTileX(float dx, float dy) {
if(isMapRotateEnabled()){
return (rotateCos * dx + rotateSin * dy) / getTileSize();
} else {
return dx / getTileSize();
}
}
public float calcDiffPixelY(float dTileX, float dTileY) {
if(isMapRotateEnabled()){
return (rotateSin * dTileX + rotateCos * dTileY) * getTileSize();
} else {
return dTileY * getTileSize();
}
}
public float calcDiffPixelX(float dTileX, float dTileY) {
if(isMapRotateEnabled()){
return (rotateCos * dTileX - rotateSin * dTileY) * getTileSize();
} else {
return dTileX * getTileSize();
}
}
/**
* These methods do not consider rotating
*/
@ -671,30 +563,15 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
public int getRotatedMapXForPoint(double latitude, double longitude) {
int cx = getCenterPointX();
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
return (int) (calcDiffPixelX((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cx);
return getCurrentRotatedTileBox().getPixXFromLatLon(latitude, longitude);
}
public int getRotatedMapYForPoint(double latitude, double longitude) {
int cy = getCenterPointY();
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
return (int) (calcDiffPixelY((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cy);
return getCurrentRotatedTileBox().getPixYFromLatLon(latitude, longitude);
}
public boolean isPointOnTheRotatedMap(double latitude, double longitude) {
int cx = getCenterPointX();
int cy = getCenterPointY();
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
int newX = (int) (calcDiffPixelX((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cx);
int newY = (int) (calcDiffPixelY((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cy);
if (newX >= 0 && newX <= getWidth() && newY >= 0 && newY <= getHeight()) {
return true;
}
return false;
return getCurrentRotatedTileBox().containsLatLon(latitude, longitude);
}
protected void dragToAnimate(float fromX, float fromY, float toX, float toY, boolean notify) {

View file

@ -11,11 +11,8 @@ import net.osmand.data.Amenity;
import net.osmand.data.AmenityType;
import net.osmand.data.LatLon;
import net.osmand.osm.MapRenderingTypes;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.PoiFilter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.resources.ResourceManager;
@ -31,7 +28,6 @@ import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.graphics.RectF;
import android.net.Uri;
import android.util.DisplayMetrics;
import android.view.WindowManager;
@ -170,7 +166,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
objects.clear();

View file

@ -5,6 +5,7 @@ import net.osmand.Location;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmAndLocationProvider;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.util.MapUtils;
import android.content.Context;
import android.graphics.Bitmap;
@ -77,7 +78,7 @@ public class PointLocationLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
// draw
boolean nm = nightMode != null && nightMode.isNightMode();
if(nm != this.nm) {

View file

@ -6,6 +6,7 @@ import net.osmand.data.LatLon;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
@ -19,7 +20,6 @@ import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
@ -88,7 +88,7 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
int index = 0;
TargetPointsHelper targetPoints = map.getMyApplication().getTargetPointsHelper();

View file

@ -3,6 +3,7 @@ package net.osmand.plus.views;
import net.osmand.data.LatLon;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.ShowRouteInfoActivity;
import net.osmand.plus.routing.RouteDirectionInfo;
@ -12,7 +13,6 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
@ -177,7 +177,7 @@ public class RouteInfoLayer extends OsmandMapLayer implements IRouteInformationL
}
@Override
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import net.osmand.Location;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
@ -79,7 +80,7 @@ public class RouteLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
path.reset();
if (helper.getFinalLocation() != null && helper.getRoute().isCalculated()) {
paint.setColor(getColor(nightMode));

View file

@ -7,13 +7,13 @@ import net.osmand.data.LatLon;
import net.osmand.data.TransportRoute;
import net.osmand.data.TransportStop;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.activities.TransportRouteHelper;
import net.osmand.plus.resources.TransportIndexRepository.RouteInfoLocation;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;
@ -58,7 +58,7 @@ public class TransportInfoLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if(routeHelper.routeIsCalculated() && visible){
List<RouteInfoLocation> list = routeHelper.getRoute();
for(RouteInfoLocation l : list){

View file

@ -9,6 +9,7 @@ import net.osmand.data.TransportStop;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.resources.TransportIndexRepository;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@ -17,7 +18,6 @@ import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;
@ -132,7 +132,7 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
@Override
public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
objects.clear();
view.getApplication().getResourceManager().searchTransportAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), objects);