Introduce new lat/lon math

This commit is contained in:
vshcherb 2013-09-27 14:07:07 +02:00
parent 4cad736511
commit 368f9b7493
32 changed files with 659 additions and 508 deletions

View file

@ -7,6 +7,7 @@ public class RotatedTileBox {
private double lat;
private double lon;
private float rotate;
private float density;
private int zoom;
private float zoomScale;
private int cx;
@ -30,17 +31,39 @@ public class RotatedTileBox {
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);
private RotatedTileBox(){
}
public RotatedTileBox(RotatedTileBox r){
// TODO
this.pixWidth = r.pixWidth;
this.pixHeight = r.pixHeight;
this.lat = r.lat;
this.lon = r.lon;
this.zoom = r.zoom;
this.zoomScale = r.zoomScale;
this.rotate = r.rotate;
this.density = r.density;
this.cx = r.cx;
this.cy = r.cy;
copyDerivedFields(r);
}
private void copyDerivedFields(RotatedTileBox r) {
zoomFactor = r.zoomFactor;
rotateCos = r.rotateCos;
rotateSin = r.rotateSin;
oxTile = r.oxTile;
oyTile =r.oyTile;
tileBounds = new QuadRect(r.tileBounds);
latLonBounds = new QuadRect(r.latLonBounds);
tileLT = new QuadPoint(r.tileLT);
tileRT = new QuadPoint(r.tileRT);
tileRB = new QuadPoint(r.tileRB);
tileLB = new QuadPoint(r.tileLB);
}
private void init(int pixWidth, int pixHeight, float centerX, float centerY, double lat, double lon,
int zoom, float zoomScale, float rotate) {
int zoom, float zoomScale, float rotate, float density) {
this.pixWidth = pixWidth;
this.pixHeight = pixHeight;
this.lat = lat;
@ -48,6 +71,7 @@ public class RotatedTileBox {
this.zoom = zoom;
this.zoomScale = zoomScale;
this.rotate = rotate;
this.density = density;
cx = (int) (pixWidth * centerX);
cy = (int) (pixHeight * centerY);
// derived
@ -55,7 +79,7 @@ public class RotatedTileBox {
}
private void calculateDerivedFields() {
public void calculateDerivedFields() {
zoomFactor = (float) Math.pow(2, zoomScale) * 256;
float rad = (float) Math.toRadians(this.rotate);
rotateCos = (float) Math.cos(rad);
@ -71,10 +95,49 @@ public class RotatedTileBox {
calculateTileRectangle();
}
public double getLatFromPixel(float x, float y) {
return MapUtils.getLatitudeFromTile(zoom, getTileYFromPixel(x, y));
}
protected float getTileXFromPixel(int x, int y) {
int dx = x - cx;
int dy = y - cy;
public double getLonFromPixel(float x, float y) {
return MapUtils.getLongitudeFromTile(zoom, getTileXFromPixel(x, y));
}
public LatLon getLatLonFromPixel(float x, float y) {
return new LatLon(getLatFromPixel(x, y), getLonFromPixel(x, y));
}
public LatLon getCenterLatLon() {
return new LatLon(lat, lon);
}
public QuadPoint getCenterPixelPoint() {
return new QuadPoint(cx, cy);
}
public int getCenterPixelX(){
return cx;
}
public int getCenterPixelY(){
return cy;
}
public void setDensity(float density) {
this.density = density;
}
public double getCenterTileX(){
return oxTile;
}
public double getCenterTileY(){
return oyTile;
}
protected float getTileXFromPixel(float x, float y) {
float dx = x - cx;
float dy = y - cy;
float dtilex;
if(isMapRotateEnabled()){
dtilex = (rotateCos * (float) dx + rotateSin * (float) dy);
@ -84,9 +147,9 @@ public class RotatedTileBox {
return dtilex / zoomFactor + oxTile;
}
protected float getTileYFromPixel(int x, int y) {
int dx = x - cx;
int dy = y - cy;
protected float getTileYFromPixel(float x, float y) {
float dx = x - cx;
float dy = y - cy;
float dtiley;
if(isMapRotateEnabled()){
dtiley = (-rotateSin * (float) dx + rotateCos * (float) dy);
@ -97,6 +160,10 @@ public class RotatedTileBox {
}
public QuadRect getTileBounds() {
return tileBounds;
}
public void calculateTileRectangle() {
float x1 = getTileXFromPixel(0, 0);
float x2 = getTileXFromPixel(pixWidth, 0);
@ -171,6 +238,16 @@ public class RotatedTileBox {
return (int) (dy + cy);
}
public int getPixXFromLonNoRot(double longitude) {
float dTilex = (float) MapUtils.getTileNumberX(zoom, longitude) - oxTile;
return (int) (dTilex * zoomFactor + cx);
}
public int getPixYFromLatNoRot(double latitude) {
float dTileY = (float) MapUtils.getTileNumberY(zoom, latitude) - oyTile;
return (int) ((dTileY * zoomFactor) + cy);
}
private boolean isMapRotateEnabled() {
return rotate != 0;
@ -188,18 +265,79 @@ public class RotatedTileBox {
return rotateSin;
}
public float getZoom() {
public int getZoom() {
return zoom;
}
public int getIntZoom() {
return Math.round(zoom);
// Change lat/lon center
public void setLatLonCenter(double lat, double lon) {
this.lat = lat;
this.lon = lon;
calculateDerivedFields();
}
public void setRotate(float rotate) {
this.rotate = rotate;
calculateDerivedFields();
}
public void setPixelDimensions(int width, int height) {
setPixelDimensions(width, height, 0.5f, 0.5f);
}
public void setPixelDimensions(int width, int height, float ratiocx, float ratiocy) {
this.pixHeight = height;
this.pixWidth = width;
this.cx = (int) (pixWidth * ratiocx);
this.cy = (int) (pixHeight * ratiocy);
calculateDerivedFields();
}
public void setCenterLocation(float ratiocx, float ratiocy) {
this.cx = (int) (pixWidth * ratiocx);
this.cy = (int) (pixHeight * ratiocy);
calculateDerivedFields();
}
public QuadPoint getLeftTopTilePoint() {
return tileLT;
}
public LatLon getLeftTopLatLon() {
return new LatLon(MapUtils.getLatitudeFromTile(zoom, tileLT.y),
MapUtils.getLongitudeFromTile(zoom, tileLT.x));
}
public LatLon getRightBottomLatLon() {
return new LatLon(MapUtils.getLatitudeFromTile(zoom, tileRB.y),
MapUtils.getLongitudeFromTile(zoom, tileRB.x));
}
public void setZoom(int zoom, float zoomScale) {
this.zoom = zoom;
this.zoomScale = zoomScale;
calculateDerivedFields();
}
public float getZoomScale() {
return zoomScale;
}
public float getRotate() {
return rotate;
}
public float getDensity() {
return density;
}
public RotatedTileBox copy() {
return new RotatedTileBox(this);
}
public boolean containsTileBox(RotatedTileBox box) {
QuadPoint temp = new QuadPoint();
if(box.zoom != zoom){
@ -226,4 +364,95 @@ public class RotatedTileBox {
return tx >= 0 && tx <= pixWidth && ty >= 0 && ty <= pixHeight;
}
public boolean containsLatLon(double lat, double lon) {
double tx = getPixXFromLatLon(lat, lon);
double ty = getPixYFromLatLon(lat, lon);
return tx >= 0 && tx <= pixWidth && ty >= 0 && ty <= pixHeight;
}
public double getDistance(int pixX, int pixY, int pixX2, int pixY2) {
final double lat1 = getLatFromPixel(pixX, pixY);
final double lon1 = getLonFromPixel(pixX, pixY);
final double lat2 = getLatFromPixel(pixX2, pixY2);
final double lon2 = getLatFromPixel(pixX2, pixY2);
return MapUtils.getDistance(lat1,lon1, lat2, lon2);
}
public static class RotatedTileBoxBuilder {
private RotatedTileBox tb;
private boolean pixelDimensionsSet = false;
private boolean locationSet = false;
private boolean zoomSet = false;
public RotatedTileBoxBuilder() {
tb = new RotatedTileBox();
tb.density = 1;
tb.rotate = 0;
}
public RotatedTileBoxBuilder density(float d) {
tb.density = d;
return this;
}
public RotatedTileBoxBuilder setZoomAndScale(int zoom, float scale) {
tb.zoom = zoom;
tb.zoomScale = scale;
zoomSet = true;
return this;
}
public RotatedTileBoxBuilder setLocation(double lat, double lon) {
tb.lat = lat;
tb.lon = lon;
locationSet = true;
return this;
}
public RotatedTileBoxBuilder setRotate(float degrees) {
tb.rotate = degrees;
return this;
}
public RotatedTileBoxBuilder setPixelDimensions(int pixWidth, int pixHeight, float centerX, float centerY) {
tb.pixWidth = pixWidth;
tb.pixHeight = pixHeight;
tb.cx = (int) (pixWidth * centerX);
tb.cy = (int) (pixHeight * centerY);
pixelDimensionsSet = true;
return this;
}
public RotatedTileBoxBuilder setPixelDimensions(int pixWidth, int pixHeight) {
return setPixelDimensions(pixWidth, pixHeight, 0.5f, 0.5f);
}
public RotatedTileBox build() {
if(!pixelDimensionsSet) {
throw new IllegalArgumentException("Please specify pixel dimensions");
}
if(!zoomSet) {
throw new IllegalArgumentException("Please specify zoom");
}
if(!locationSet) {
throw new IllegalArgumentException("Please specify location");
}
final RotatedTileBox local = tb;
local.calculateDerivedFields();
tb = null;
return local;
}
}
public double getLongitude() {
return lon;
}
public double getLatitude() {
return lat;
}
}

View file

@ -1,11 +1,12 @@
package net.osmand.access;
import android.graphics.PointF;
import net.osmand.data.RotatedTileBox;
// This interface is intended for defining prioritized actions
// to be performed in touch exploration mode. Implementations
// should do nothing and return false when accessibility is disabled.
public interface AccessibilityActionsProvider {
public boolean onClick(PointF point);
public boolean onLongClick(PointF point);
public boolean onClick(PointF point, RotatedTileBox tileBox);
public boolean onLongClick(PointF point, RotatedTileBox tileBox);
}

View file

@ -1,6 +1,7 @@
package net.osmand.access;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapTileView;
@ -17,7 +18,7 @@ public class MapAccessibilityActions implements AccessibilityActionsProvider {
}
@Override
public boolean onClick(PointF point) {
public boolean onClick(PointF point, RotatedTileBox tileBox) {
if ((Build.VERSION.SDK_INT >= 14) && activity.getMyApplication().getInternalAPI().accessibilityEnabled()) {
// not sure if it is very clear why should I mark destination first when I tap on the object
return activity.getMyApplication().getLocationProvider().emitNavigationHint();
@ -26,16 +27,17 @@ public class MapAccessibilityActions implements AccessibilityActionsProvider {
}
@Override
public boolean onLongClick(PointF point) {
public boolean onLongClick(PointF point, RotatedTileBox tileBox) {
if ((Build.VERSION.SDK_INT >= 14) && activity.getMyApplication().getInternalAPI().accessibilityEnabled()) {
final OsmandMapTileView mapView = activity.getMapView();
LatLon pressedLoc = mapView.getLatLonFromScreenPoint(point.x, point.y);
final double lat = tileBox.getLatFromPixel((int)point.x, (int) point.y);
final double lon = tileBox.getLonFromPixel((int)point.x, (int) point.y);
ContextMenuLayer cm = activity.getMapLayers().getContextMenuLayer();
LatLon loc = cm.selectObjectsForContextMenu(point);
LatLon loc = cm.selectObjectsForContextMenu(tileBox, point);
if (cm.getSelectedObjectName() != null) {
cm.showContextMenuForSelectedObjects(loc);
} else {
activity.getMapActions().contextMenuPoint(pressedLoc.getLatitude(), pressedLoc.getLongitude());
activity.getMapActions().contextMenuPoint(lat, lon);
}
// activity.getMapActions().contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());

View file

@ -6,6 +6,8 @@ import java.util.List;
import java.util.Map;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.R;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
@ -29,7 +31,6 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
private OsmandMapTileView mapView;
private OnGestureListener fallback;
private Map<Object, IContextMenuProvider> selectedObjects = null;
private final DisplayMetrics dm = new DisplayMetrics();
// OnGestureListener specified as a second argument
@ -38,7 +39,6 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
public MapExplorer(OsmandMapTileView mapView, OnGestureListener fallback) {
this.mapView = mapView;
this.fallback = fallback;
((WindowManager)(mapView.getContext().getSystemService(Context.WINDOW_SERVICE))).getDefaultDisplay().getMetrics(dm);
}
@ -52,14 +52,14 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
// Find touched objects if any and emit accessible toast message
// with it's brief description.
private void describePointedObjects(MotionEvent event) {
private void describePointedObjects(RotatedTileBox tb, MotionEvent event) {
PointF point = new PointF(event.getX(), event.getY());
List<Object> ns = new ArrayList<Object>();
Map<Object, IContextMenuProvider> newSelectedObjects = new LinkedHashMap<Object, ContextMenuLayer.IContextMenuProvider>();
for (OsmandMapLayer layer : mapView.getLayers()) {
if (layer instanceof IContextMenuProvider) {
ns.clear();
((IContextMenuProvider) layer).collectObjectsFromPoint(point, ns);
((IContextMenuProvider) layer).collectObjectsFromPoint(point, tb , ns);
for(Object o : ns) {
newSelectedObjects.put(o, (IContextMenuProvider) layer);
}
@ -67,7 +67,7 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
}
if (newSelectedObjects.isEmpty()) {
ns.clear();
collectObjectsFromPoint(point, ns);
collectObjectsFromPoint(point, tb, ns);
for(Object o : ns) {
newSelectedObjects.put(o, this);
}
@ -96,7 +96,7 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
if (contextMenuLayer != null)
contextMenuLayer.setSelections(null);
selectedObjects = null;
describePointedObjects(e);
describePointedObjects(mapView.getCurrentRotatedTileBox(), e);
return false;
}
@ -117,7 +117,7 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
if ((Build.VERSION.SDK_INT >= 14) || mapView.getSettings().SCROLL_MAP_BY_GESTURES.get()) {
return fallback.onScroll(e1, e2, distanceX, distanceY);
} else {
describePointedObjects(e2);
describePointedObjects(mapView.getCurrentRotatedTileBox(), e2);
}
return true;
}
@ -137,17 +137,19 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
// IContextMenuProvider interface implementation.
@Override
public void collectObjectsFromPoint(PointF point, List<Object> objects) {
int radius = (int)(VICINITY_RADIUS * dm.density);
int dx = (int)Math.abs(point.x - mapView.getCenterPointX());
int dy = (int)Math.abs(point.y - mapView.getCenterPointY());
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> objects) {
int radius = (int)(VICINITY_RADIUS * tileBox.getDensity());
final QuadPoint p = tileBox.getCenterPixelPoint();
int dx = (int)Math.abs(point.x - p.x);
int dy = (int)Math.abs(point.y - p.y);
if ((dx < radius) && (dy < radius))
objects.add(this);
}
@Override
public LatLon getObjectLocation(Object o) {
return mapView.getLatLonFromScreenPoint(mapView.getCenterPointX(), mapView.getCenterPointY());
final RotatedTileBox tb = mapView.getCurrentRotatedTileBox();
return tb.getCenterLatLon();
}
@Override

View file

@ -5,6 +5,8 @@ import java.util.ArrayList;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
import net.osmand.map.MapTileDownloader;
import net.osmand.map.MapTileDownloader.DownloadRequest;
@ -58,15 +60,12 @@ public class DownloadTilesDialog {
AccessibleToast.makeText(ctx, R.string.maps_could_not_be_downloaded, Toast.LENGTH_SHORT).show();
return;
}
final RotatedTileBox rb = mapView.getCurrentRotatedTileBox();
final int max = mapSource.getMaximumZoomSupported();
// get narrow zoom
final int zoom = mapView.getZoom();
final int zoom = rb.getZoom();
// calculate pixel rectangle
Rect boundsRect = new Rect(0, 0, mapView.getWidth(), mapView.getHeight());
final RectF latlonRect = new RectF();
mapView.calculateLatLonRectangle(boundsRect, latlonRect);
Builder builder = new AlertDialog.Builder(ctx);
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.download_tiles, null);
@ -83,12 +82,12 @@ public class DownloadTilesDialog {
final String template = ctx.getString(R.string.tiles_to_download_estimated_size);
updateLabel(zoom, latlonRect, downloadText, template, seekBar.getProgress());
updateLabel(zoom, rb.getLatLonBounds(), downloadText, template, seekBar.getProgress());
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
updateLabel(zoom, latlonRect, downloadText, template, progress);
updateLabel(zoom, rb.getLatLonBounds(), downloadText, template, progress);
}
@Override
@ -105,7 +104,7 @@ public class DownloadTilesDialog {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
run(zoom, seekBar.getProgress(), latlonRect, mapSource);
run(zoom, seekBar.getProgress(), rb.getLatLonBounds(), mapSource);
}
});
builder.setNegativeButton(R.string.default_buttons_cancel, null);
@ -115,7 +114,7 @@ public class DownloadTilesDialog {
private volatile boolean cancel = false;
public void run(final int zoom, final int progress, final RectF latlonRect, final ITileSource map){
public void run(final int zoom, final int progress, final QuadRect latlonRect, final ITileSource map){
cancel = false;
int numberTiles = 0;
for (int z = zoom; z <= progress + zoom; z++) {
@ -222,7 +221,7 @@ public class DownloadTilesDialog {
}
private void updateLabel(final int zoom, final RectF latlonRect, final TextView downloadText, final String template, int progress) {
private void updateLabel(final int zoom, final QuadRect latlonRect, final TextView downloadText, final String template, int progress) {
int numberTiles = 0;
for (int z = zoom; z <= progress + zoom; z++) {
int x1 = (int) MapUtils.getTileNumberX(z, latlonRect.left);

View file

@ -13,6 +13,8 @@ import net.osmand.access.AccessibleActivity;
import net.osmand.access.AccessibleToast;
import net.osmand.access.MapAccessibilityActions;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.MapTileDownloader.DownloadRequest;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.ApplicationMode;
@ -424,7 +426,9 @@ public class MapActivity extends AccessibleActivity {
if(event.getAction() == MotionEvent.ACTION_MOVE && settings.USE_TRACKBALL_FOR_MOVEMENTS.get()){
float x = event.getX();
float y = event.getY();
LatLon l = mapView.getLatLonFromScreenPoint(mapView.getCenterPointX() + x * 15, mapView.getCenterPointY() + y * 15);
final RotatedTileBox tb = mapView.getCurrentRotatedTileBox();
final QuadPoint cp = tb.getCenterPixelPoint();
final LatLon l = tb.getLatLonFromPixel(cp.x + x * 15, cp.y + y * 15);
setMapLocation(l.getLatitude(), l.getLongitude());
return true;
}
@ -580,7 +584,9 @@ public class MapActivity extends AccessibleActivity {
keyCode == KeyEvent.KEYCODE_DPAD_UP) {
int dx = keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 15 : (keyCode == KeyEvent.KEYCODE_DPAD_LEFT ? - 15 : 0);
int dy = keyCode == KeyEvent.KEYCODE_DPAD_DOWN ? 15 : (keyCode == KeyEvent.KEYCODE_DPAD_UP ? -15 : 0);
LatLon l = mapView.getLatLonFromScreenPoint(mapView.getCenterPointX() + dx, mapView.getCenterPointY() + dy);
final RotatedTileBox tb = mapView.getCurrentRotatedTileBox();
final QuadPoint cp = tb.getCenterPixelPoint();
final LatLon l = tb.getLatLonFromPixel(cp.x + dx, cp.y + dy);
setMapLocation(l.getLatitude(), l.getLongitude());
return true;
} else if(OsmandPlugin.onMapActivityKeyUp(this, keyCode)) {

View file

@ -23,6 +23,8 @@ import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.access.AccessibleToast;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
@ -1012,10 +1014,8 @@ public class MapActivityActions implements DialogProvider {
AccessibleToast.makeText(mapActivity, R.string.maps_could_not_be_downloaded, Toast.LENGTH_SHORT).show();
return;
}
Rect pixRect = new Rect(0, 0, mapView.getWidth(), mapView.getHeight());
RectF tilesRect = new RectF();
mapView.calculateTileRectangle(pixRect, mapView.getCenterPointX(), mapView.getCenterPointY(),
mapView.getXTile(), mapView.getYTile(), tilesRect);
final RotatedTileBox tb = mapView.getCurrentRotatedTileBox();
final QuadRect tilesRect = tb.getTileBounds();
int left = (int) FloatMath.floor(tilesRect.left);
int top = (int) FloatMath.floor(tilesRect.top);
int width = (int) (FloatMath.ceil(tilesRect.right) - left);

View file

@ -7,10 +7,11 @@ import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.access.AccessibleToast;
import net.osmand.data.DataTileManager;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
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;
@ -35,7 +36,6 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
private static final int startZoom = 10;
private MapActivity activity;
private AudioVideoNotesPlugin plugin;
private DisplayMetrics dm;
private Paint pointAltUI;
private Paint paintIcon;
private Paint point;
@ -52,9 +52,6 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
pointAltUI = new Paint();
pointAltUI.setColor(0xa0FF3344);
@ -72,24 +69,25 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
point.setStyle(Style.STROKE);
}
public int getRadiusPoi(int zoom){
public int getRadiusPoi(RotatedTileBox tb){
int r = 0;
if(zoom < startZoom){
if(tb.getZoom() < startZoom){
r = 0;
} else {
r = 15;
}
return (int) (r * dm.density);
return (int) (r * tb.getDensity());
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (view.getZoom() >= startZoom) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
if (tb.getZoom() >= startZoom) {
DataTileManager<Recording> recs = plugin.getRecordings();
List<Recording> objects = recs.getObjects(tileBox.top, tileBox.left, tileBox.bottom, tileBox.right);
final QuadRect tiles = tb.getTileBounds();
List<Recording> objects = recs.getObjects(tiles. top, tiles.left, tiles.bottom, tiles.right);
for (Recording o : objects) {
int x = view.getRotatedMapXForPoint(o.getLatitude(), o.getLongitude());
int y = view.getRotatedMapYForPoint(o.getLatitude(), o.getLongitude());
int x = tb.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
int y = tb.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
Bitmap b;
if (o.isPhoto()) {
b = photo;
@ -177,18 +175,18 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> objects) {
getRecordingsFromPoint(point, objects);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> objects) {
getRecordingsFromPoint(point, tileBox, objects);
}
public void getRecordingsFromPoint(PointF point, List<? super Recording> am) {
public void getRecordingsFromPoint(PointF point, RotatedTileBox tileBox, List<? super Recording> am) {
int ex = (int) point.x;
int ey = (int) point.y;
int compare = getRadiusPoi(view.getZoom());
int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
int compare = getRadiusPoi(tileBox);
int radius = compare * 3 / 2;
for (Recording n : plugin.getAllRecordings()) {
int x = view.getRotatedMapXForPoint(n.getLatitude(), n.getLongitude());
int y = view.getRotatedMapYForPoint(n.getLatitude(), n.getLongitude());
int x = tileBox.getPixXFromLatLon(n.getLatitude(), n.getLongitude());
int y = tileBox.getPixYFromLatLon(n.getLatitude(), n.getLongitude());
if (calculateBelongs(ex, ey, x, y, compare)) {
compare = radius;
am.add(n);
@ -201,9 +199,9 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
ArrayList<Recording> o = new ArrayList<Recording>();
getRecordingsFromPoint(point, o);
getRecordingsFromPoint(point, tileBox, o);
if(o.size() > 0){
StringBuilder b = new StringBuilder();
for(Recording r : o) {

View file

@ -15,6 +15,7 @@ import net.osmand.CallbackWithObject;
import net.osmand.IndexConstants;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.GPXUtilities.GPXFile;
@ -437,7 +438,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
if(distanceMeasurementMode == 1) {
LatLon l = view.getLatLonFromScreenPoint(point.x, point.y);
if(measurementPoints.size() == 0) {
@ -456,7 +457,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
if (distanceMeasurementMode == 1 && measurementPoints.size() > 0) {
LinkedList<WptPt> lt = measurementPoints.get(measurementPoints.size() - 1);
if (lt.size() > 0) {
@ -526,7 +527,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> o) {
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o) {
getMPointsFromPoint(point, o);
}

View file

@ -13,6 +13,8 @@ import java.util.List;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.activities.DialogProvider;
@ -66,7 +68,6 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
private double cRightLongitude;
private int czoom;
private final MapActivity activity;
private DisplayMetrics dm;
private static final String KEY_AUTHOR = "author";
private static final String KEY_MESSAGE = "message";
@ -98,9 +99,6 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
synchronized (this) {
if (handlerToLoop == null) {
new Thread("Open street bugs layer") { //$NON-NLS-1$
@ -146,22 +144,24 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
if (tb.getZoom() >= startZoom) {
// request to load
requestToLoad(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom());
final QuadRect latLonBounds = tb.getLatLonBounds();
requestToLoad(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, tb.getZoom());
for (OpenStreetNote o : objects) {
int x = view.getMapXForPoint(o.getLongitude());
int y = view.getMapYForPoint(o.getLatitude());
canvas.drawCircle(x, y, getRadiusBug(view.getZoom()), o.isLocal() ? pointNotSubmitedUI : (o.isOpened() ? pointOpenedUI
int x = tb.getPixXFromLonNoRot(o.getLongitude());
int y = tb.getPixYFromLatNoRot(o.getLatitude());
canvas.drawCircle(x, y, getRadiusBug(tb), o.isLocal() ? pointNotSubmitedUI : (o.isOpened() ? pointOpenedUI
: pointClosedUI));
}
}
}
public int getRadiusBug(int zoom) {
public int getRadiusBug(RotatedTileBox tb) {
int z;
final int zoom = tb.getZoom();
if (zoom < startZoom) {
z = 0;
} else if (zoom <= 12) {
@ -175,7 +175,7 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
} else {
z = 16;
}
return (int) (z * dm.density);
return (int) (z * tb.getDensity());
}
public void requestToLoad(double topLatitude, double leftLongitude, double bottomLatitude,double rightLongitude, final int zoom){
@ -211,21 +211,22 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
public void getBugFromPoint(PointF point, List<? super OpenStreetNote> res){
public void getBugFromPoint(RotatedTileBox tb, PointF point, List<? super OpenStreetNote> res){
if (objects != null && view != null) {
int ex = (int) point.x;
int ey = (int) point.y;
int radius = getRadiusBug(view.getZoom()) * 3 / 2;
int small = getRadiusBug(view.getZoom()) * 3 / 4;
final int rad = getRadiusBug(tb);
int radius = rad * 3 / 2;
int small = rad * 3 / 4;
try {
for (int i = 0; i < objects.size(); i++) {
OpenStreetNote n = objects.get(i);
int x = view.getRotatedMapXForPoint(n.getLatitude(), n.getLongitude());
int y = view.getRotatedMapYForPoint(n.getLatitude(), n.getLongitude());
int x = tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude());
int y = tb.getPixYFromLatLon(n.getLatitude(), n.getLongitude());
if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
radius = small;
res.add(n);
@ -238,9 +239,9 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
ArrayList<OpenStreetNote> list = new ArrayList<OpenStreetNote>();
getBugFromPoint(point, list);
getBugFromPoint(tileBox, point, list);
if(!list.isEmpty()){
StringBuilder res = new StringBuilder();
int i = 0;
@ -560,8 +561,8 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> res) {
getBugFromPoint(point, res);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> res) {
getBugFromPoint(tileBox, point, res);
}
@Override

View file

@ -5,6 +5,7 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.activities.MapActivity;
@ -184,7 +185,7 @@ public class OsMoDroidLayer extends OsmandMapLayer implements ContextMenuLayer.I
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
List<OsMoDroidPoint> om = new ArrayList<OsMoDroidPoint>();
getOsMoDroidPointFromPoint(point, om);
if (!om.isEmpty()) {
@ -221,7 +222,7 @@ public class OsMoDroidLayer extends OsmandMapLayer implements ContextMenuLayer.I
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> o) {
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o) {
getOsMoDroidPointFromPoint(point, o);
}

View file

@ -5,8 +5,8 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
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;
@ -99,7 +99,7 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
List <LatLon> parkPos = new ArrayList<LatLon>();
getParkingFromPoint(point, parkPos);
if(!parkPos.isEmpty()){
@ -121,7 +121,7 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> o) {
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o) {
getParkingFromPoint(point, o);
}

View file

@ -29,14 +29,15 @@ import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
import net.osmand.data.QuadPoint;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.development.OsmandDevelopmentPlugin;
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
@ -528,10 +529,10 @@ public class MapRenderRepositories {
boolean loaded;
if(nativeLib != null) {
cObjects = new LinkedList<BinaryMapDataObject>();
loaded = loadVectorDataNative(dataBox, requestedBox.getIntZoom(), renderingReq, nativeLib);
loaded = loadVectorDataNative(dataBox, requestedBox.getZoom(), renderingReq, nativeLib);
} else {
cNativeObjects = null;
loaded = loadVectorData(dataBox, requestedBox.getIntZoom(), renderingReq);
loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq);
}
if (!loaded || checkWhetherInterrupted()) {
@ -542,22 +543,23 @@ public class MapRenderRepositories {
currentRenderingContext = new OsmandRenderer.RenderingContext(context);
renderingReq.clearState();
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getIntZoom());
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getZoom());
if(renderingReq.searchRenderingAttribute(RenderingRuleStorageProperties.A_DEFAULT_COLOR)) {
currentRenderingContext.defaultColor = renderingReq.getIntPropertyValue(renderingReq.ALL.R_ATTR_COLOR_VALUE);
}
renderingReq.clearState();
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getIntZoom());
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, requestedBox.getZoom());
if(renderingReq.searchRenderingAttribute(RenderingRuleStorageProperties.A_SHADOW_RENDERING)) {
currentRenderingContext.shadowRenderingMode = renderingReq.getIntPropertyValue(renderingReq.ALL.R_ATTR_INT_VALUE);
currentRenderingContext.shadowRenderingColor = renderingReq.getIntPropertyValue(renderingReq.ALL.R_SHADOW_COLOR);
}
currentRenderingContext.leftX = requestedBox.getLeftTileX();
currentRenderingContext.topY = requestedBox.getTopTileY() ;
currentRenderingContext.zoom = requestedBox.getIntZoom();
final QuadPoint lt = requestedBox.getLeftTopTilePoint();
currentRenderingContext.leftX = lt.x;
currentRenderingContext.topY = lt.y ;
currentRenderingContext.zoom = requestedBox.getZoom();
currentRenderingContext.rotate = requestedBox.getRotate();
currentRenderingContext.width = (int) (requestedBox.getTileWidth() * OsmandRenderer.TILE_SIZE);
currentRenderingContext.height = (int) (requestedBox.getTileHeight() * OsmandRenderer.TILE_SIZE);
currentRenderingContext.width = requestedBox.getPixWidth();
currentRenderingContext.height = requestedBox.getPixHeight();
currentRenderingContext.nightMode = nightMode;
currentRenderingContext.useEnglishNames = prefs.USE_ENGLISH_NAMES.get();
currentRenderingContext.setDensityValue(prefs.USE_HIGH_RES_MAPS.get(),

View file

@ -1,6 +1,6 @@
package net.osmand.plus.render;
import net.osmand.plus.RotatedTileBox;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.views.BaseMapLayer;
import net.osmand.plus.views.MapTileLayer;
@ -17,7 +17,9 @@ public class MapVectorLayer extends BaseMapLayer {
private OsmandMapTileView view;
private Rect pixRect = new Rect();
private RotatedTileBox rotatedTileBox = new RotatedTileBox(0, 0, 0, 0, 0, 0);
private RotatedTileBox rotatedTileBox =
new RotatedTileBox.RotatedTileBoxBuilder().setPixelDimensions(0, 0).
setLocation(0, 0).setZoomAndScale(5, 0).build();
private ResourceManager resourceManager;
private Paint paintImg;
@ -84,7 +86,7 @@ public class MapVectorLayer extends BaseMapLayer {
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings drawSettings) {
public void onDraw(Canvas canvas, RotatedTileBox tilesRect, DrawSettings drawSettings) {
if (!visible) {
return;
}
@ -111,10 +113,11 @@ public class MapVectorLayer extends BaseMapLayer {
}
private boolean drawRenderedMap(Canvas canvas, Bitmap bmp, RotatedTileBox bmpLoc) {
private boolean drawRenderedMap(Canvas canvas, Bitmap bmp, RotatedTileBox bmpLoc, RotatedTileBox currentViewport) {
boolean shown = false;
if (bmp != null && bmpLoc != null) {
float rot = bmpLoc.getRotate();
bmpLoc.getLeftTopTilePoint()
float mult = (float) MapUtils.getPowZoom(view.getZoom() - bmpLoc.getZoom());
float fmult = (float) MapUtils.getPowZoom(view.getFloatZoom() - bmpLoc.getZoom());
@ -152,12 +155,12 @@ public class MapVectorLayer extends BaseMapLayer {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}
}

View file

@ -9,6 +9,7 @@ import java.util.Stack;
import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.data.Amenity;
import net.osmand.data.RotatedTileBox;
import net.osmand.data.TransportStop;
import net.osmand.map.ITileSource;
import net.osmand.map.MapTileDownloader.DownloadRequest;
@ -16,7 +17,6 @@ import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.BusyIndicator;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.PoiFilter;
import net.osmand.plus.RotatedTileBox;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;

View file

@ -18,7 +18,6 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.os.AsyncTask;
import net.osmand.AndroidUtils;
import net.osmand.GeoidAltitudeCorrection;
import net.osmand.IProgress;
@ -27,10 +26,7 @@ import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.CachedOsmandIndexes;
import net.osmand.data.Amenity;
import net.osmand.data.AmenityType;
import net.osmand.data.LatLon;
import net.osmand.data.TransportStop;
import net.osmand.data.*;
import net.osmand.map.ITileSource;
import net.osmand.map.MapTileDownloader;
import net.osmand.map.MapTileDownloader.DownloadRequest;
@ -40,7 +36,6 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.PoiFilter;
import net.osmand.plus.R;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SearchByNameFilter;
import net.osmand.plus.Version;
@ -843,7 +838,7 @@ public class ResourceManager {
public void updateRendererMap(RotatedTileBox rotatedTileBox){
renderer.interruptLoadingMap();
asyncLoadingThread.requestToLoadMap(
new MapLoadRequest(new RotatedTileBox(rotatedTileBox)));
new MapLoadRequest(rotatedTileBox.copy()));
}
public void interruptRendering(){

View file

@ -5,11 +5,6 @@ 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

@ -8,9 +8,9 @@ import java.util.Map;
import java.util.Map.Entry;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
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;
@ -35,7 +35,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
public interface IContextMenuProvider {
public void collectObjectsFromPoint(PointF point, List<Object> o);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o);
public LatLon getObjectLocation(Object o);
@ -53,7 +53,6 @@ public class ContextMenuLayer extends OsmandMapLayer {
private TextView textView;
private ImageView closeButton;
private DisplayMetrics dm;
private OsmandMapTileView view;
private int BASE_TEXT_SIZE = 170;
private int SHADOW_OF_LEG = 5;
@ -82,14 +81,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
scaleCoefficient = dm.density;
if (Math.min(dm.widthPixels / (dm.density * 160), dm.heightPixels / (dm.density * 160)) > 2.5f) {
// large screen
scaleCoefficient *= 1.5f;
}
scaleCoefficient = view.getDensity();
BASE_TEXT_SIZE = (int) (BASE_TEXT_SIZE * scaleCoefficient);
SHADOW_OF_LEG = (int) (SHADOW_OF_LEG * scaleCoefficient);
CLOSE_BTN = (int) (CLOSE_BTN * scaleCoefficient);
@ -125,10 +117,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox box, DrawSettings nightMode) {
if(latLon != null){
int x = view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude());
int y = view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude());
int x = box.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude());
int y = box.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude());
int tx = x - boxLeg.getMinimumWidth() / 2;
int ty = y - boxLeg.getMinimumHeight() + SHADOW_OF_LEG;
@ -194,34 +186,35 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
if ((Build.VERSION.SDK_INT < 14) && !view.getSettings().SCROLL_MAP_BY_GESTURES.get()) {
if (!selectedObjects.isEmpty())
view.showMessage(activity.getMyApplication().getLocationProvider().getNavigationHint(latLon));
return true;
}
if(pressedInTextView(point.x, point.y) > 0){
if(pressedInTextView(tileBox, point.x, point.y) > 0){
setLocation(null, ""); //$NON-NLS-1$
view.refreshMap();
return true;
}
LatLon latLon = selectObjectsForContextMenu(point);
LatLon latLon = selectObjectsForContextMenu(tileBox, point);
String description = getSelectedObjectDescription();
setLocation(latLon, description);
view.refreshMap();
return true;
}
public LatLon selectObjectsForContextMenu(PointF point) {
LatLon pressedLoc = view.getLatLonFromScreenPoint(point.x, point.y);
public LatLon selectObjectsForContextMenu(RotatedTileBox tileBox, PointF point) {
final double lat = tileBox.getLatFromPixel((int) point.x, (int) point.y);
final double lon = tileBox.getLonFromPixel((int) point.x, (int) point.y);
selectedObjects.clear();
List<Object> s = new ArrayList<Object>();
LatLon latLon = null;
for(OsmandMapLayer l : view.getLayers()){
if(l instanceof ContextMenuLayer.IContextMenuProvider){
s.clear();
((ContextMenuLayer.IContextMenuProvider) l).collectObjectsFromPoint(point, s);
((ContextMenuLayer.IContextMenuProvider) l).collectObjectsFromPoint(point, tileBox, s);
for(Object o : s) {
selectedObjects.put(o, ((ContextMenuLayer.IContextMenuProvider) l));
if(latLon == null) {
@ -231,7 +224,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
}
if(latLon == null) {
latLon = pressedLoc;
latLon = new LatLon(lat, lon);
}
return latLon;
}
@ -241,12 +234,12 @@ public class ContextMenuLayer extends OsmandMapLayer {
return true;
}
public int pressedInTextView(float px, float py) {
public int pressedInTextView(RotatedTileBox tb, float px, float py) {
if (latLon != null) {
Rect bs = textView.getBackground().getBounds();
Rect closes = closeButton.getDrawable().getBounds();
int x = (int) (px - view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude()));
int y = (int) (py - view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude()));
int x = (int) (px - tb.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude()));
int y = (int) (py - tb.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude()));
x += bs.width() / 2;
y += bs.height() + boxLeg.getMinimumHeight() - SHADOW_OF_LEG;
int localSize = CLOSE_BTN * 3 / 2;
@ -295,9 +288,9 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
boolean nativeMode = (Build.VERSION.SDK_INT >= 14) || view.getSettings().SCROLL_MAP_BY_GESTURES.get();
int val = pressedInTextView(point.x, point.y);
int val = pressedInTextView(tileBox, point.x, point.y);
if (val == 2) {
setLocation(null, ""); //$NON-NLS-1$
view.refreshMap();
@ -347,10 +340,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
@Override
public boolean onTouchEvent(MotionEvent event) {
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) {
if (latLon != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int vl = pressedInTextView(event.getX(), event.getY());
int vl = pressedInTextView(tileBox, event.getX(), event.getY());
if(vl == 1){
textView.setPressed(true);
view.refreshMap();

View file

@ -17,10 +17,11 @@ import android.widget.Button;
import android.widget.FrameLayout;
import net.osmand.IndexConstants;
import net.osmand.binary.BinaryMapDataObject;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.OsmandRegions;
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;
@ -45,7 +46,7 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
private List<BinaryMapDataObject> objectsToDraw = new ArrayList<BinaryMapDataObject>();
private RectF queriedBBox = new RectF();
private QuadRect queriedBBox = new QuadRect();
private int queriedZoom = 0;
private boolean basemapExists = true;
private boolean noMapsPresent = false;
@ -108,17 +109,18 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
private static int ZOOM_TO_SHOW_MAP_NAMES = 12;
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBox, DrawSettings nightMode) {
final int zoom = view.getZoom();
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
final int zoom = tb.getZoom();
if(downloadBtn.getVisibility() == View.VISIBLE) {
downloadBtn.setVisibility(View.GONE);
}
if (zoom >= ZOOM_TO_SHOW_BORDERS_ST && (zoom < ZOOM_TO_SHOW_BORDERS || zoom >= ZOOM_TO_SHOW_MAP_NAMES) &&
osmandRegions.isInitialized()) {
final QuadRect latLonBox = tb.getLatLonBounds();
if (!queriedBBox.contains(latLonBox) || Math.abs(queriedZoom - zoom) > 2) {
float w = Math.abs(latLonBox.width() / 2);
float h = Math.abs(latLonBox.height() / 2);
final RectF rf = new RectF(latLonBox.left - w, latLonBox.top + h, latLonBox.right + w, latLonBox.bottom - h);
final QuadRect rf = new QuadRect(latLonBox.left - w, latLonBox.top + h, latLonBox.right + w, latLonBox.bottom - h);
AsyncTask<Object, Object, List<BinaryMapDataObject>> task = createNewTask(zoom, rf);
if (currentTask == null) {
task.execute();
@ -172,12 +174,12 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
double lat = MapUtils.get31LatitudeY(o.getPoint31YTile(0));
double lon = MapUtils.get31LongitudeX(o.getPoint31XTile(0));
path.moveTo(view.getRotatedMapXForPoint(lat, lon), view.getRotatedMapYForPoint(lat, lon));
path.moveTo(tb.getPixXFromLonNoRot(lon), tb.getPixYFromLatNoRot(lat));
for(int j = 1 ; j < o.getPointsLength(); j++) {
lat = MapUtils.get31LatitudeY(o.getPoint31YTile(j));
lon = MapUtils.get31LongitudeX(o.getPoint31XTile(j));
path.lineTo(view.getRotatedMapXForPoint(lat, lon),
view.getRotatedMapYForPoint(lat, lon));
path.lineTo(tb.getPixXFromLonNoRot(lon),
tb.getPixYFromLatNoRot(lat));
}
}
canvas.drawPath(path, paint);
@ -187,7 +189,7 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
}
}
private AsyncTask<Object, Object, List<BinaryMapDataObject>> createNewTask(final int zoom, final RectF rf) {
private AsyncTask<Object, Object, List<BinaryMapDataObject>> createNewTask(final int zoom, final QuadRect rf) {
return new AsyncTask<Object, Object, List<BinaryMapDataObject>>() {
@Override
protected List<BinaryMapDataObject> doInBackground(Object... params) {
@ -259,12 +261,12 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}

View file

@ -6,6 +6,8 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.FavouritesDbHelper;
@ -23,7 +25,6 @@ import android.graphics.PointF;
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 {
@ -31,7 +32,6 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
private OsmandMapTileView view;
private Paint paint;
private DisplayMetrics dm;
private FavouritesDbHelper favorites;
private Bitmap favoriteIcon;
@ -43,10 +43,6 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
@ -75,14 +71,15 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
if (tb.getZoom() >= startZoom) {
// request to load
final QuadRect latLonBounds = tb.getLatLonBounds();
for (FavouritePoint o : favorites.getFavouritePoints()) {
if (o.getLatitude() >= latLonBounds.bottom && o.getLatitude() <= latLonBounds.top && o.getLongitude() >= latLonBounds.left
&& o.getLongitude() <= latLonBounds.right ) {
int x = view.getRotatedMapXForPoint(o.getLatitude(), o.getLongitude());
int y = view.getRotatedMapYForPoint(o.getLatitude(), o.getLongitude());
int x = tb.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
int y = tb.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
canvas.drawBitmap(favoriteIcon, x - favoriteIcon.getWidth() / 2,
y - favoriteIcon.getHeight(), paint);
}
@ -92,17 +89,17 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
public void getFavoriteFromPoint(PointF point, List<? super FavouritePoint> res) {
int r = (int) (15* dm.density);
public void getFavoriteFromPoint(RotatedTileBox tb, PointF point, List<? super FavouritePoint> res) {
int r = (int) (15 * tb.getDensity());
int ex = (int) point.x;
int ey = (int) point.y;
for (FavouritePoint n : favorites.getFavouritePoints()) {
int x = view.getRotatedMapXForPoint(n.getLatitude(), n.getLongitude());
int y = view.getRotatedMapYForPoint(n.getLatitude(), n.getLongitude());
int x = tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude());
int y = tb.getPixXFromLatLon(n.getLatitude(), n.getLongitude());
if (calculateBelongs(ex, ey, x, y, r)) {
res.add(n);
}
@ -110,9 +107,9 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
List<FavouritePoint> favs = new ArrayList<FavouritePoint>();
getFavoriteFromPoint(point, favs);
getFavoriteFromPoint(tileBox, point, favs);
if(!favs.isEmpty()){
StringBuilder res = new StringBuilder();
int i = 0;
@ -146,8 +143,8 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.I
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> res) {
getFavoriteFromPoint(point, res);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> res) {
getFavoriteFromPoint(tileBox, point, res);
}
@Override

View file

@ -2,11 +2,12 @@ package net.osmand.plus.views;
import java.util.List;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
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;
@ -71,7 +72,7 @@ public class GPXLayer extends OsmandMapLayer {
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
GPXFile gpxFile = view.getApplication().getGpxFileToDisplay();
if(gpxFile == null){
return;
@ -80,6 +81,7 @@ public class GPXLayer extends OsmandMapLayer {
paint.setColor(getColor(nightMode));
final QuadRect latLonBounds = tb.getLatLonBounds();
for (List<WptPt> l : points) {
path.rewind();
int startIndex = -1;
@ -93,12 +95,12 @@ public class GPXLayer extends OsmandMapLayer {
}
} else if (!(latLonBounds.left <= ls.lon + 0.1 && ls.lon - 0.1 <= latLonBounds.right
&& latLonBounds.bottom <= ls.lat + 0.1 && ls.lat - 0.1 <= latLonBounds.top)) {
drawSegment(canvas, l, startIndex, i);
drawSegment(canvas, tb, l, startIndex, i);
startIndex = -1;
}
}
if (startIndex != -1) {
drawSegment(canvas, l, startIndex, l.size() - 1);
drawSegment(canvas, tb, l, startIndex, l.size() - 1);
continue;
}
}
@ -106,14 +108,14 @@ public class GPXLayer extends OsmandMapLayer {
}
private void drawSegment(Canvas canvas, List<WptPt> l, int startIndex, int endIndex) {
int px = view.getMapXForPoint(l.get(startIndex).lon);
int py = view.getMapYForPoint(l.get(startIndex).lat);
private void drawSegment(Canvas canvas, RotatedTileBox tb, List<WptPt> l, int startIndex, int endIndex) {
int px = tb.getPixXFromLonNoRot(l.get(startIndex).lon);
int py = tb.getPixYFromLatNoRot(l.get(startIndex).lat);
path.moveTo(px, py);
for (int i = startIndex + 1; i <= endIndex; i++) {
WptPt p = l.get(i);
int x = view.getMapXForPoint(p.lon);
int y = view.getMapYForPoint(p.lat);
int x = tb.getPixXFromLonNoRot(p.lon);
int y = tb.getPixYFromLatNoRot(p.lat);
path.lineTo(x, y);
}
canvas.drawPath(path, paint);
@ -135,12 +137,12 @@ public class GPXLayer extends OsmandMapLayer {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}

View file

@ -2,11 +2,11 @@ package net.osmand.plus.views;
import net.londatiga.android.ActionItem;
import net.londatiga.android.QuickAction;
import net.osmand.data.RotatedTileBox;
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;
@ -109,8 +109,8 @@ public class MapControlsLayer extends OsmandMapLayer {
@Override
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();
boolean zoomInEnabled = mainLayer != null && tileBox.getZoom() < mainLayer.getMaximumShownMapZoom();
boolean zoomOutEnabled = mainLayer != null && tileBox.getZoom() > mainLayer.getMinimumShownMapZoom();
if(zoomInButton.isEnabled() != zoomInEnabled){
zoomInButton.setEnabled(zoomInEnabled);
}
@ -138,9 +138,9 @@ public class MapControlsLayer extends OsmandMapLayer {
rulerTextPaint.setColor(sh == Color.WHITE ? Color.BLACK : 0xffC8C8C8);
}
if (showZoomLevel || !view.getSettings().SHOW_RULER.get()) {
drawZoomLevel(canvas);
drawZoomLevel(canvas ,tileBox);
} else {
drawRuler(canvas);
drawRuler(canvas, tileBox);
}
}
@ -204,9 +204,9 @@ public class MapControlsLayer extends OsmandMapLayer {
}
private void drawZoomLevel(Canvas canvas) {
String zoomText = view.getZoom() + "";
float frac = view.getFloatZoom() - view.getZoom();
private void drawZoomLevel(Canvas canvas, RotatedTileBox tb) {
String zoomText = tb.getZoom() + "";
float frac = tb.getZoomScale();
while(frac > OsmandMapTileView.ZOOM_DELTA_1) {
frac -= OsmandMapTileView.ZOOM_DELTA_1;
zoomText += "'";
@ -239,7 +239,7 @@ public class MapControlsLayer extends OsmandMapLayer {
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
if (modeShadow.getBounds().contains((int) point.x, (int) point.y)) {
onApplicationModePress();
return true;
@ -419,20 +419,17 @@ public class MapControlsLayer extends OsmandMapLayer {
double cacheRulerTileY = 0;
float cacheRulerTextLen = 0;
private void drawRuler(Canvas canvas) {
private void drawRuler(Canvas canvas, RotatedTileBox tb) {
// update cache
if (view.isZooming()) {
cacheRulerText = null;
} else if(view.getFloatZoom() != cacheRulerZoom ||
Math.abs(view.getXTile() - cacheRulerTileX) + Math.abs(view.getYTile() - cacheRulerTileY) > 1){
cacheRulerZoom = view.getFloatZoom();
cacheRulerTileX = view.getXTile();
cacheRulerTileY = view.getYTile();
double latitude = view.getLatitude();
double leftLon = view.calcLongitude(- view.getWidth() / 2);
double rightLon = view.calcLongitude(+ view.getWidth() / 2);
double dist = MapUtils.getDistance(latitude, leftLon, latitude, rightLon);
double pixDensity = view.getWidth() / dist;
} else if((tb.getZoom() + tb.getZoomScale()) != cacheRulerZoom ||
Math.abs(tb.getCenterTileX() - cacheRulerTileX) + Math.abs(tb.getCenterTileY() - cacheRulerTileY) > 1){
cacheRulerZoom = (tb.getZoom() + tb.getZoomScale());
cacheRulerTileX = tb.getCenterTileX();
cacheRulerTileY = tb.getCenterTileY();
final double dist = tb.getDistance(0, tb.getPixHeight() / 2, tb.getPixWidth(), tb.getPixHeight() / 2);
double pixDensity = tb.getPixWidth() / dist;
double roundedDist = OsmAndFormatter.calculateRoundedDist(dist * screenRulerPercent, view.getApplication());

View file

@ -1,12 +1,12 @@
package net.osmand.plus.views;
import net.osmand.access.AccessibleToast;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
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;
@ -15,6 +15,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.util.FloatMath;
import android.widget.Toast;
import net.osmand.util.MapUtils;
public class MapTileLayer extends BaseMapLayer {
@ -120,7 +121,7 @@ public class MapTileLayer extends BaseMapLayer {
drawTileMap(canvas, tilesRect);
}
public void drawTileMap(Canvas canvas, RectF tilesRect) {
public void drawTileMap(Canvas canvas, RotatedTileBox tileBox) {
if(map == null){
return;
}
@ -134,6 +135,7 @@ public class MapTileLayer extends BaseMapLayer {
// recalculate for ellipsoid coordinates
if (map.isEllipticYTile()) {
// return (float) MapUtils.getTileEllipsoidNumberY(getZoom(), currentViewport.get);
float ellipticYTile = view.getEllipticYTile();
tilesRect.bottom += (ellipticYTile - tileY);
tilesRect.top += (ellipticYTile - tileY);

View file

@ -2,11 +2,11 @@ package net.osmand.plus.views;
import java.util.Map;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.ContextMenuAdapter;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.view.MotionEvent;
import net.osmand.plus.RotatedTileBox;
public abstract class OsmandMapLayer {
@ -24,19 +24,19 @@ public abstract class OsmandMapLayer {
public void populateObjectContextMenu(Object o, ContextMenuAdapter adapter) {}
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
public boolean onTouchEvent(MotionEvent event) { return false;}
public boolean onTouchEvent(MotionEvent event, RotatedTileBox tileBox) { return false;}
/**
* This method returns whether canvas should be rotated as
* map rotated before {@link #onDraw(android.graphics.Canvas, net.osmand.plus.RotatedTileBox, net.osmand.plus.views.OsmandMapLayer.DrawSettings)}.
* map rotated before {@link #onDraw(android.graphics.Canvas, net.osmand.data.RotatedTileBox, net.osmand.plus.views.OsmandMapLayer.DrawSettings)}.
* If the layer draws simply layer over screen (not over map)
* it should return true.
*/

View file

@ -15,7 +15,6 @@ import net.osmand.map.IMapLocationListener;
import net.osmand.map.MapTileDownloader.DownloadRequest;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
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;
@ -62,6 +61,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public static final float ZOOM_DELTA_1 = 1/3f;
public interface OnTrackBallListener {
public boolean onTrackBallEvent(MotionEvent e);
}
@ -75,19 +76,9 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
protected static final Log log = PlatformUtil.getLog(OsmandMapTileView.class);
/**MapTree
* zoom level - could be float to show zoomed tiles
*/
private float zoom = 3;
private double longitude = 0d;
private double latitude = 0d;
private float rotate = 0;
private float rotateSin = 0;
private float rotateCos = 1;
private RotatedTileBox currentViewport;
private float rotate; // accumulate
private int mapPosition;
@ -131,6 +122,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public OsmandMapTileView(Context context, AttributeSet attrs) {
super(context, attrs);
application = (OsmandApplication) context.getApplicationContext();
currentViewport = new RotatedTileBox.RotatedTileBoxBuilder().
setLocation(0, 0).setZoomAndScale(3, 1).build();
initView();
}
@ -138,6 +131,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public OsmandMapTileView(Context context) {
super(context);
application = (OsmandApplication) context.getApplicationContext();
currentViewport = new RotatedTileBox.RotatedTileBoxBuilder().
setLocation(0, 0).setZoomAndScale(3, 1).build();
initView();
}
@ -181,6 +176,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
WindowManager mgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
dm = new DisplayMetrics();
mgr.getDefaultDisplay().getMetrics(dm);
currentViewport.setPixelDimensions(getWidth(), getHeight());
currentViewport.setDensity(dm.density);
}
@ -240,20 +237,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
// ///////////////////////// NON UI PART (could be extracted in common) /////////////////////////////
/**
* Returns real tile size in pixels for float zoom .
*/
public float getTileSize() {
float res = getSourceTileSize();
if (zoom != (int) zoom) {
res *= (float) Math.pow(2, zoom - (int) zoom);
}
return res;
}
public int getSourceTileSize() {
// TODO
int r = 256;
if (mainLayer instanceof MapTileLayer) {
r = ((MapTileLayer) mainLayer).getSourceTileSize();
@ -267,30 +252,18 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return r;
}
/**
* @return y tile based on (int) zoom
*/
public float getEllipticYTile() {
return (float) MapUtils.getTileEllipsoidNumberY(getZoom(), latitude);
}
public void setZoom(float zoom) {
if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() + 0.01 && zoom >= mainLayer.getMinimumShownMapZoom() - 0.01) {
public void setZoom(int zoom, float zoomScale) {
if (mainLayer != null && zoom <= mainLayer.getMaximumShownMapZoom() && zoom >= mainLayer.getMinimumShownMapZoom()) {
animatedDraggingThread.stopAnimating();
// avoid round error
if(zoom < Math.round(zoom)){
this.zoom = zoom + 0.001f;
} else {
this.zoom = zoom;
}
currentViewport.setZoom(zoom, zoomScale);
currentViewport.setRotate(zoom > LOWEST_ZOOM_TO_ROTATE ? rotate : 0 );
refreshMap();
}
}
public boolean isMapRotateEnabled(){
return zoom > LOWEST_ZOOM_TO_ROTATE;
return getZoom() > LOWEST_ZOOM_TO_ROTATE;
}
public void setRotate(float rotate) {
@ -311,31 +284,30 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
public float getRotate() {
return isMapRotateEnabled() ? rotate : 0;
return currentViewport.getRotate();
}
public void setLatLon(double latitude, double longitude) {
animatedDraggingThread.stopAnimating();
this.latitude = latitude;
this.longitude = longitude;
currentViewport.setLatLonCenter(latitude, longitude);
refreshMap();
}
public double getLatitude() {
return latitude;
return currentViewport.getLatitude();
}
public double getLongitude() {
return longitude;
return currentViewport.getLongitude();
}
public int getZoom() {
return (int) zoom;
return currentViewport.getZoom();
}
public float getFloatZoom() {
return zoom;
public float getZoomScale() {
return currentViewport.getZoomScale();
}
public boolean isZooming(){
@ -375,40 +347,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
refreshMap();
}
public int getCenterPointX() {
TODO;
return getWidth() / 2;
}
public int getCenterPointY() {
TODO;
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
return 4 * getHeight() / 5;
}
return getHeight() / 2;
}
public void setMapPosition(int type) {
this.mapPosition = type;
}
public void calculateLatLonRectangle(Rect pixRect, RectF latLonRect) {
int z = (int) zoom;
float tileX = (float) MapUtils.getTileNumberX(z, getLongitude());
float tileY = (float) MapUtils.getTileNumberY(z, getLatitude());
float w = getCenterPointX();
float h = getCenterPointY();
RectF tilesRect = new RectF();
calculateTileRectangle(pixRect, w, h, tileX, tileY, tilesRect);
latLonRect.top = (float) MapUtils.getLatitudeFromTile(z, tilesRect.top);
latLonRect.left = (float) MapUtils.getLongitudeFromTile(z, tilesRect.left);
latLonRect.bottom = (float) MapUtils.getLatitudeFromTile(z, tilesRect.bottom);
latLonRect.right = (float) MapUtils.getLongitudeFromTile(z, tilesRect.right);
}
protected OsmandSettings settings = null;
public OsmandSettings getSettings(){
if(settings == null){
@ -437,14 +379,21 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
try {
updateLatLonBounds();
final float ratioy = mapPosition == OsmandSettings.BOTTOM_CONSTANT ? 0.8f : 0.5f;
final int cy = (int) (ratioy * getHeight());
if(currentViewport.getPixWidth() != getWidth() || currentViewport.getPixHeight() != getHeight() ||
currentViewport.getCenterPixelY() != cy) {
currentViewport.setPixelDimensions(getWidth(), getHeight(), 0.5f, ratioy);
}
// TODO high res
// (getSettings().USE_HIGH_RES_MAPS.get() ? 0 : 0.5f)
boolean nightMode = application.getDaynightHelper().isNightMode();
if (nightMode) {
canvas.drawARGB(255, 100, 100, 100);
} else {
canvas.drawARGB(255, 225, 225, 225);
}
drawOverMap(canvas, latlonRect, tilesRect, new DrawSettings(nightMode, updateVectorRendering));
drawOverMap(canvas, currentViewport, new DrawSettings(nightMode, updateVectorRendering), false);
} finally {
holder.unlockCanvasAndPost(canvas);
}
@ -476,8 +425,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
private void drawOverMap(Canvas canvas, RotatedTileBox tileBox, DrawSettings drawSettings, boolean
onPrepareImage) {
int w = getCenterPointX();
int h = getCenterPointY();
final QuadPoint c = tileBox.getCenterPixelPoint();
// long prev = System.currentTimeMillis();
@ -488,7 +436,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
canvas.save();
// rotate if needed
if (!layer.drawInScreenPixels()) {
canvas.rotate(getRotate(), w, h);
canvas.rotate(tileBox.getRotate(), c.x, c.y);
}
if(onPrepareImage) {
layer.onPrepareBufferImage(canvas, tileBox, drawSettings);
@ -501,8 +449,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
}
if (showMapPosition && !onPrepareImage) {
canvas.drawCircle(w, h, 3 * dm.density, paintCenter);
canvas.drawCircle(w, h, 7 * dm.density, paintCenter);
canvas.drawCircle(c.x, c.y, 3 * dm.density, paintCenter);
canvas.drawCircle(c.x, c.y, 7 * dm.density, paintCenter);
}
}
@ -544,36 +492,25 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
// ///////////////////////////////// DRAGGING PART ///////////////////////////////////////
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 net.osmand.data.RotatedTileBox getCurrentRotatedTileBox() {
return currentViewport;
}
public float getDensity() {
return currentViewport.getDensity();
}
public float getScaleCoefficient() {
float scaleCoefficient = getDensity();
if (Math.min(dm.widthPixels / (dm.density * 160), dm.heightPixels / (dm.density * 160)) > 2.5f) {
// large screen
scaleCoefficient *= 1.5f;
}
return scaleCoefficient;
}
/**
* These methods do not consider rotating
*/
public int getMapXForPoint(double longitude) {
double tileX = MapUtils.getTileNumberX(getZoom(), longitude);
return (int) ((tileX - getXTile()) * getTileSize() + getCenterPointX());
}
public int getMapYForPoint(double latitude) {
double tileY = MapUtils.getTileNumberY(getZoom(), latitude);
return (int) ((tileY - getYTile()) * getTileSize() + getCenterPointY());
}
public int getRotatedMapXForPoint(double latitude, double longitude) {
return getCurrentRotatedTileBox().getPixXFromLatLon(latitude, longitude);
}
public int getRotatedMapYForPoint(double latitude, double longitude) {
return getCurrentRotatedTileBox().getPixYFromLatLon(latitude, longitude);
}
public boolean isPointOnTheRotatedMap(double latitude, double longitude) {
return getCurrentRotatedTileBox().containsLatLon(latitude, longitude);
}
protected void dragToAnimate(float fromX, float fromY, float toX, float toY, boolean notify) {
float dx = (fromX - toX);
float dy = (fromY - toY);
@ -586,16 +523,15 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
protected void rotateToAnimate(float rotate) {
if (isMapRotateEnabled()) {
this.rotate = MapUtils.unifyRotationTo360(rotate);
float rotateRad = (float) Math.toRadians(rotate);
this.rotateCos = FloatMath.cos(rotateRad);
this.rotateSin = FloatMath.sin(rotateRad);
if(isMapRotateEnabled()) {
currentViewport.setRotate(this.rotate);
}
refreshMap();
}
}
protected void setLatLonAnimate(double latitude, double longitude, boolean notify) {
this.latitude = latitude;
this.longitude = longitude;
currentViewport.setLatLonCenter(latitude, longitude);
refreshMap();
if (locationListener != null && notify) {
locationListener.locationChanged(latitude, longitude, this);
@ -608,17 +544,16 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
this.zoom = zoom;
refreshMap();
if (notify && locationListener != null) {
locationListener.locationChanged(latitude, longitude, this);
locationListener.locationChanged(getLatitude(), getLongitude(), this);
}
}
}
public void moveTo(float dx, float dy) {
float fy = calcDiffTileY(dx, dy);
float fx = calcDiffTileX(dx, dy);
this.latitude = MapUtils.getLatitudeFromTile(getZoom(), getYTile() + fy);
this.longitude = MapUtils.getLongitudeFromTile(getZoom(), getXTile() + fx);
final RotatedTileBox tb = currentViewport;
final QuadPoint cp = currentViewport.getCenterPixelPoint();
final LatLon latlon = currentViewport.getLatLonFromPixel(cp.x + dx, cp.y + dy);
currentViewport.setLatLonCenter(latlon.getLatitude(), latlon.getLongitude());
refreshMap();
// do not notify here listener
@ -630,7 +565,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
animatedDraggingThread.stopAnimating();
}
for(int i=layers.size() - 1; i >= 0; i--) {
if(layers.get(i).onTouchEvent(event)) {
if(layers.get(i).onTouchEvent(event, getCurrentRotatedTileBox())) {
return true;
}
}
@ -665,18 +600,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
public LatLon getLatLonFromScreenPoint(float x, float y) {
float dx = x - getCenterPointX();
float dy = y - getCenterPointY();
float fy = calcDiffTileY(dx, dy);
float fx = calcDiffTileX(dx, dy);
double latitude = MapUtils.getLatitudeFromTile(getZoom(), getYTile() + fy);
double longitude = MapUtils.getLongitudeFromTile(getZoom(), getXTile() + fx);
return new LatLon(latitude, longitude);
}
public AnimateDraggingMapThread getAnimatedDraggingThread() {
return animatedDraggingThread;
@ -693,27 +616,27 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
private class MapTileViewMultiTouchZoomListener implements MultiTouchZoomListener {
private float initialMultiTouchZoom;
private PointF initialMultiTouchCenterPoint;
private LatLon initialMultiTouchLocation;
private RotatedTileBox initialViewport;
private float x1;
private float y1;
private float x2;
private float y2;
private LatLon initialCenterLatLon;
@Override
public void onZoomEnded(float distance, float relativeToStart) {
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
float calcZoom = initialMultiTouchZoom + dz;
float calcZoom = initialViewport.getZoom() + dz;
setZoom(Math.round(calcZoom));
final int newZoom = getZoom();
zoomPositionChanged(newZoom);
if (application.getInternalAPI().accessibilityEnabled()) {
if (newZoom != initialMultiTouchZoom) {
if (newZoom != initialViewport.getZoom()) {
showMessage(getContext().getString(R.string.zoomIs) + " " + newZoom); //$NON-NLS-1$
} else {
final LatLon p1 = getLatLonFromScreenPoint(x1, y1);
final LatLon p2 = getLatLonFromScreenPoint(x2, y2);
final LatLon p1 = initialViewport.getLatLonFromPixel(x1, y1);
final LatLon p2 = initialViewport.getLatLonFromPixel(x2, y2);
showMessage(OsmAndFormatter.getFormattedDistance((float)MapUtils.getDistance(p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude()), application));
}
}
@ -730,14 +653,15 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
@Override
public void onZoomStarted(float distance, PointF centerPoint) {
initialMultiTouchCenterPoint = centerPoint;
initialMultiTouchLocation = getLatLonFromScreenPoint(centerPoint.x, centerPoint.y);
initialMultiTouchZoom = zoom;
initialViewport = getCurrentRotatedTileBox().copy();
initialCenterLatLon = initialViewport.getLatLonFromPixel(initialMultiTouchCenterPoint.x,
initialMultiTouchCenterPoint.y);
}
@Override
public void onZooming(float distance, float relativeToStart) {
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
float calcZoom = initialMultiTouchZoom + dz;
float calcZoom = initialViewport.getZoom() + dz;
if (Math.abs(calcZoom - zoom) > 0.05) {
setZoom(calcZoom);
zoomPositionChanged(calcZoom);
@ -745,16 +669,13 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
private void zoomPositionChanged(float calcZoom) {
float dx = initialMultiTouchCenterPoint.x - getCenterPointX();
float dy = initialMultiTouchCenterPoint.y - getCenterPointY();
float ex = calcDiffTileX(dx, dy);
float ey = calcDiffTileY(dx, dy);
int z = (int)calcZoom;
double tx = MapUtils.getTileNumberX(z, initialMultiTouchLocation.getLongitude());
double ty = MapUtils.getTileNumberY(z, initialMultiTouchLocation.getLatitude());
double lat = MapUtils.getLatitudeFromTile(z, ty - ey);
double lon = MapUtils.getLongitudeFromTile(z, tx - ex);
setLatLon(lat, lon);
final QuadPoint cp = initialViewport.getCenterPixelPoint();
float dx = initialMultiTouchCenterPoint.x - cp.x;
float dy = initialMultiTouchCenterPoint.y - cp.y;
final RotatedTileBox calc = initialViewport.copy();
calc.setLatLonCenter(initialCenterLatLon.getLatitude(), initialCenterLatLon.getLongitude());
final LatLon r = calc.getLatLonFromPixel(cp.x + dx, cp.y + dy);
setLatLon(r.getLatitude(), r.getLongitude());
}
}
@ -781,11 +702,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
log.debug("On long click event " + e.getX() + " " + e.getY()); //$NON-NLS-1$ //$NON-NLS-2$
}
PointF point = new PointF(e.getX(), e.getY());
if ((accessibilityActions != null) && accessibilityActions.onLongClick(point)) {
if ((accessibilityActions != null) && accessibilityActions.onLongClick(point, getCurrentRotatedTileBox() )) {
return;
}
for (int i = layers.size() - 1; i >= 0; i--) {
if (layers.get(i).onLongPressEvent(point)) {
if (layers.get(i).onLongPressEvent(point, getCurrentRotatedTileBox())) {
return;
}
}
@ -810,11 +731,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
if (log.isDebugEnabled()) {
log.debug("On click event " + point.x + " " + point.y); //$NON-NLS-1$ //$NON-NLS-2$
}
if ((accessibilityActions != null) && accessibilityActions.onClick(point)) {
if ((accessibilityActions != null) && accessibilityActions.onClick(point, getCurrentRotatedTileBox())) {
return true;
}
for (int i = layers.size() - 1; i >= 0; i--) {
if (layers.get(i).onSingleTap(point)) {
if (layers.get(i).onSingleTap(point, getCurrentRotatedTileBox())) {
return true;
}
}
@ -829,8 +750,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
private class MapTileViewOnDoubleTapListener implements OnDoubleTapListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
LatLon l = getLatLonFromScreenPoint(e.getX(), e.getY());
getAnimatedDraggingThread().startMoving(l.getLatitude(), l.getLongitude(), getZoom() + 1, true);
final RotatedTileBox tb = getCurrentRotatedTileBox();
final double lat = tb.getLatFromPixel(e.getX(), e.getY());
final double lon = tb.getLonFromPixel(e.getX(), e.getY());
getAnimatedDraggingThread().startMoving(lat, lon, getZoom() + 1, true);
return true;
}

View file

@ -7,9 +7,7 @@ import java.util.List;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.data.Amenity;
import net.osmand.data.AmenityType;
import net.osmand.data.LatLon;
import net.osmand.data.*;
import net.osmand.osm.MapRenderingTypes;
import net.osmand.plus.*;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
@ -50,7 +48,6 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
private ResourceManager resourceManager;
private PoiFilter filter;
private DisplayMetrics dm;
public POIMapLayer(MapActivity activity) {
}
@ -64,17 +61,18 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
this.filter = filter;
}
public void getAmenityFromPoint(PointF point, List<? super Amenity> am){
public void getAmenityFromPoint(RotatedTileBox tb, PointF point, List<? super Amenity> am){
if (objects != null) {
int ex = (int) point.x;
int ey = (int) point.y;
int compare = getRadiusPoi(view.getZoom());
int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
final int rp = getRadiusPoi(tb);
int compare = rp;
int radius = rp * 3 / 2;
try {
for (int i = 0; i < objects.size(); i++) {
Amenity n = objects.get(i);
int x = view.getRotatedMapXForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int y = view.getRotatedMapYForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int x = tb.getPixXFromLatLon(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int y = tb.getPixYFromLatLon(n.getLocation().getLatitude(), n.getLocation().getLongitude());
if (Math.abs(x - ex) <= compare && Math.abs(y - ey) <= compare) {
compare = radius;
am.add(n);
@ -88,9 +86,9 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
List<Amenity> am = new ArrayList<Amenity>();
getAmenityFromPoint(point, am);
getAmenityFromPoint(tileBox, point, am);
if(!am.isEmpty()){
StringBuilder res = new StringBuilder();
for (int i = 0; i < MAXIMUM_SHOW_AMENITIES && i < am.size(); i++) {
@ -126,10 +124,6 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
pointAltUI = new Paint();
pointAltUI.setColor(view.getApplication().getResources().getColor(R.color.poi_background));
pointAltUI.setStyle(Style.FILL);
@ -137,7 +131,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
paintIcon = new Paint();
paintTextIcon = new Paint();
paintTextIcon.setTextSize(12 * dm.density);
paintTextIcon.setTextSize(12 * view.getDensity());
paintTextIcon.setTextAlign(Align.CENTER);
paintTextIcon.setAntiAlias(true);
@ -148,8 +142,9 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
resourceManager = view.getApplication().getResourceManager();
}
public int getRadiusPoi(int zoom){
public int getRadiusPoi(RotatedTileBox tb){
int r = 0;
final int zoom = tb.getZoom();
if(zoom < startZoom){
r = 0;
} else if(zoom <= 15){
@ -161,20 +156,21 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
} else {
r = 18;
}
return (int) (r * dm.density);
return (int) (r * tb.getDensity());
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
if (tb.getZoom() >= startZoom) {
objects.clear();
resourceManager.searchAmenitiesAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), filter, objects);
int r = getRadiusPoi(view.getZoom());
final QuadRect latLonBounds = tb.getLatLonBounds();
resourceManager.searchAmenitiesAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom,
latLonBounds.right, tb.getZoom(), filter, objects);
int r = getRadiusPoi(tb);
for (Amenity o : objects) {
int x = view.getRotatedMapXForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int y = view.getRotatedMapYForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int x = tb.getPixXFromLatLon(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int y = tb.getPixYFromLatLon(o.getLocation().getLatitude(), o.getLocation().getLongitude());
canvas.drawCircle(x, y, r, pointAltUI);
canvas.drawCircle(x, y, r, point);
String id = null;
@ -197,10 +193,10 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
if (view.getSettings().SHOW_POI_LABEL.get()) {
TIntHashSet set = new TIntHashSet();
for (Amenity o : objects) {
int x = view.getRotatedMapXForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int y = view.getRotatedMapYForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int tx = view.getMapXForPoint(o.getLocation().getLongitude());
int ty = view.getMapYForPoint(o.getLocation().getLatitude());
int x = tb.getPixXFromLatLon(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int y = tb.getPixYFromLatLon(o.getLocation().getLatitude(), o.getLocation().getLongitude());
int tx = tb.getPixXFromLonNoRot(o.getLocation().getLongitude());
int ty = tb.getPixYFromLatNoRot(o.getLocation().getLatitude());
String name = o.getName(view.getSettings().USE_ENGLISH_NAMES.get());
if (name != null && name.length() > 0) {
int lines = 0;
@ -365,8 +361,8 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> objects) {
getAmenityFromPoint(point, objects);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> objects) {
getAmenityFromPoint(tileBox, point, objects);
}
@Override

View file

@ -2,10 +2,10 @@ package net.osmand.plus.views;
import net.osmand.Location;
import net.osmand.data.RotatedTileBox;
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;
@ -78,7 +78,7 @@ public class PointLocationLayer extends OsmandMapLayer {
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox box, DrawSettings nightMode) {
// draw
boolean nm = nightMode != null && nightMode.isNightMode();
if(nm != this.nm) {
@ -90,21 +90,19 @@ public class PointLocationLayer extends OsmandMapLayer {
if(lastKnownLocation == null || view == null){
return;
}
int locationX = view.getMapXForPoint(lastKnownLocation.getLongitude());
int locationY = view.getMapYForPoint(lastKnownLocation.getLatitude());
int locationX = box.getPixXFromLonNoRot(lastKnownLocation.getLongitude());
int locationY = box.getPixYFromLatNoRot(lastKnownLocation.getLatitude());
double lonLeft = view.calcLongitude(- view.getWidth() / 2);
double lonRight = view.calcLongitude(+ view.getWidth() / 2);
double dist = MapUtils.getDistance(view.getLatitude(), lonLeft, view.getLatitude(), lonRight);
int radius = (int) (((double) view.getWidth()) / dist * lastKnownLocation.getAccuracy());
final double dist = box.getDistance(0, box.getPixHeight() / 2, box.getPixWidth(), box.getPixHeight() / 2);
int radius = (int) (((double) box.getPixWidth()) / dist * lastKnownLocation.getAccuracy());
if (radius > RADIUS * dm.density) {
int allowedRad = Math.min(view.getWidth() / 2, view.getHeight() / 2);
int allowedRad = Math.min(box.getPixWidth() / 2, box.getPixHeight() / 2);
canvas.drawCircle(locationX, locationY, Math.min(radius, allowedRad), area);
canvas.drawCircle(locationX, locationY, Math.min(radius, allowedRad), aroundArea);
}
// draw bearing/direction/location
if (isLocationVisible(lastKnownLocation)) {
if (isLocationVisible(box, lastKnownLocation)) {
checkAppMode(view.getSettings().getApplicationMode());
boolean isBearing = lastKnownLocation.hasBearing();
if (!isBearing) {
@ -126,11 +124,11 @@ public class PointLocationLayer extends OsmandMapLayer {
}
}
public boolean isLocationVisible(Location l){
if(l == null || view == null){
public boolean isLocationVisible(RotatedTileBox tb, Location l){
if(l == null ){
return false;
}
return view.isPointOnTheRotatedMap(l.getLatitude(), l.getLongitude());
return tb.containsLatLon(l.getLatitude(), l.getLongitude());
}

View file

@ -3,10 +3,11 @@ package net.osmand.plus.views;
import java.util.List;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox;
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;
@ -32,7 +33,6 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
private OsmandMapTileView view;
private float[] calculations = new float[2];
private DisplayMetrics dm;
private Bitmap targetPoint;
private Bitmap intermediatePoint;
private Bitmap arrowToDestination;
@ -79,57 +79,55 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
initUI();
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
int index = 0;
TargetPointsHelper targetPoints = map.getMyApplication().getTargetPointsHelper();
for (LatLon ip : targetPoints.getIntermediatePoints()) {
index ++;
if (isLocationVisible(ip)) {
if (isLocationVisible(tb, ip)) {
int marginX = intermediatePoint.getWidth() / 3;
int marginY = intermediatePoint.getHeight();
int locationX = view.getMapXForPoint(ip.getLongitude());
int locationY = view.getMapYForPoint(ip.getLatitude());
canvas.rotate(-view.getRotate(), locationX, locationY);
int locationX = tb.getPixXFromLonNoRot(ip.getLongitude());
int locationY = tb.getPixYFromLatNoRot(ip.getLatitude());
canvas.rotate(-tb.getRotate(), locationX, locationY);
canvas.drawBitmap(intermediatePoint, locationX - marginX, locationY - marginY, bitmapPaint);
canvas.drawText(index + "", locationX + marginX, locationY - 2 * marginY / 3, textPaint);
canvas.rotate(view.getRotate(), locationX, locationY);
canvas.rotate(tb.getRotate(), locationX, locationY);
}
}
LatLon pointToNavigate = targetPoints.getPointToNavigate();
if (isLocationVisible(pointToNavigate)) {
if (isLocationVisible(tb, pointToNavigate)) {
int marginX = targetPoint.getWidth() / 3;
int marginY = targetPoint.getHeight();
int locationX = view.getMapXForPoint(pointToNavigate.getLongitude());
int locationY = view.getMapYForPoint(pointToNavigate.getLatitude());
canvas.rotate(-view.getRotate(), locationX, locationY);
int locationX = tb.getPixXFromLonNoRot(pointToNavigate.getLongitude());
int locationY = tb.getPixYFromLatNoRot(pointToNavigate.getLatitude());
canvas.rotate(-tb.getRotate(), locationX, locationY);
canvas.drawBitmap(targetPoint, locationX - marginX, locationY - marginY, bitmapPaint);
} else if (pointToNavigate != null && view.getSettings().SHOW_DESTINATION_ARROW.get()) {
net.osmand.Location.distanceBetween(view.getLatitude(), view.getLongitude(), pointToNavigate.getLatitude(),
pointToNavigate.getLongitude(), calculations);
float bearing = calculations[1] - 90;
float radiusBearing = DIST_TO_SHOW * dm.density;
canvas.rotate(bearing, view.getCenterPointX(), view.getCenterPointY());
canvas.translate(-24 * dm.density + radiusBearing, -22 * dm.density);
canvas.drawBitmap(arrowToDestination, view.getCenterPointX(), view.getCenterPointY(), bitmapPaint);
float radiusBearing = DIST_TO_SHOW * tb.getDensity();
final QuadPoint cp = tb.getCenterPixelPoint();
canvas.rotate(bearing, cp.x, cp.y);
canvas.translate(-24 * tb.getDensity() + radiusBearing, -22 * tb.getDensity());
canvas.drawBitmap(arrowToDestination, cp.x, cp.y, bitmapPaint);
}
}
public boolean isLocationVisible(LatLon p){
if(p == null || view == null){
public boolean isLocationVisible(RotatedTileBox tb, LatLon p){
if(p == null || tb == null){
return false;
}
return view.isPointOnTheRotatedMap(p.getLatitude(), p.getLongitude());
return tb.containsLatLon(p.getLatitude(), p.getLongitude());
}
@ -144,30 +142,30 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> o) {
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> o) {
TargetPointsHelper tg = map.getMyApplication().getTargetPointsHelper();
List<LatLon> intermediatePoints = tg.getIntermediatePointsWithTarget();
List<String> names = tg.getIntermediatePointNamesWithTarget();
int r = getRadiusPoi(view.getZoom());
int r = getRadiusPoi(tileBox);
for (int i = 0; i < intermediatePoints.size(); i++) {
LatLon latLon = intermediatePoints.get(i);
boolean target = i == intermediatePoints.size() - 1;
if (latLon != null) {
int ex = (int) point.x;
int ey = (int) point.y;
int x = view.getRotatedMapXForPoint(latLon.getLatitude(), latLon.getLongitude());
int y = view.getRotatedMapYForPoint(latLon.getLatitude(), latLon.getLongitude());
int x = tileBox.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude());
int y = tileBox.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude());
if (calculateBelongs(ex, ey, x, y, r)) {
TargetPoint tp = new TargetPoint();
tp.location = latLon;
@ -190,8 +188,9 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius && (objy - ey) <= 2.5 * radius ;
}
public int getRadiusPoi(int zoom){
public int getRadiusPoi(RotatedTileBox tb){
int r = 0;
final int zoom = tb.getZoom();
if(zoom <= 15){
r = 10;
} else if(zoom == 16){
@ -201,7 +200,7 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
} else {
r = 18;
}
return (int) (r * dm.density);
return (int) (r * tb.getDensity());
}
@Override

View file

@ -2,8 +2,8 @@ package net.osmand.plus.views;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
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;
@ -150,12 +150,12 @@ public class RouteInfoLayer extends OsmandMapLayer implements IRouteInformationL
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}

View file

@ -4,8 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import net.osmand.Location;
import net.osmand.data.RotatedTileBox;
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;
@ -177,12 +177,12 @@ public class RouteLayer extends OsmandMapLayer {
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
return false;
}

View file

@ -4,10 +4,10 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
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;
@ -110,7 +110,7 @@ public class TransportInfoLayer extends OsmandMapLayer {
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
int ex = (int) point.x;
int ey = (int) point.y;
if (visible && !routeHelper.getRoute().isEmpty()) {

View file

@ -5,11 +5,12 @@ import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
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;
@ -43,17 +44,18 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
pointAltUI.setAntiAlias(true);
}
public void getFromPoint(PointF point, List<? super TransportStop> res) {
public void getFromPoint(RotatedTileBox tb,PointF point, List<? super TransportStop> res) {
if (objects != null) {
int ex = (int) point.x;
int ey = (int) point.y;
int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
int small = getRadiusPoi(view.getZoom());
final int rp = getRadiusPoi(tb);
int radius = rp * 3 / 2;
int small = rp;
try {
for (int i = 0; i < objects.size(); i++) {
TransportStop n = objects.get(i);
int x = view.getRotatedMapXForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int y = view.getRotatedMapYForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int x = tb.getPixXFromLatLon(n.getLocation().getLatitude(), n.getLocation().getLongitude());
int y = tb.getPixYFromLatLon(n.getLocation().getLatitude(), n.getLocation().getLongitude());
if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
radius = small;
res.add(n);
@ -70,9 +72,9 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
@Override
public boolean onSingleTap(PointF point) {
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
ArrayList<TransportStop> stops = new ArrayList<TransportStop >();
getFromPoint(point, stops);
getFromPoint(tileBox, point, stops);
if(!stops.isEmpty()){
StringBuilder res = new StringBuilder();
int i = 0;
@ -116,30 +118,35 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
return text.toString();
}
public int getRadiusPoi(int zoom){
public int getRadiusPoi(RotatedTileBox tb){
final int zoom = tb.getZoom();
int r;
if(zoom < startZoom){
return 0;
r = 0;
} else if(zoom <= 15){
return 8;
r = 8;
} else if(zoom == 16){
return 10;
r = 10;
} else if(zoom == 17){
return 14;
r = 14;
} else {
return 18;
r = 18;
}
return (int) (r * tb.getDensity());
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox latLonBounds, DrawSettings nightMode) {
if (view.getZoom() >= startZoom) {
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
if (tb.getZoom() >= startZoom) {
objects.clear();
view.getApplication().getResourceManager().searchTransportAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), objects);
int r = 3 * getRadiusPoi(view.getZoom()) / 4;
final QuadRect latLonBounds = tb.getLatLonBounds();
view.getApplication().getResourceManager().searchTransportAsync(latLonBounds.top, latLonBounds.left,
latLonBounds.bottom, latLonBounds.right, tb.getZoom(), objects);
int r = 3 * getRadiusPoi(tb) / 4;
for (TransportStop o : objects) {
int x = view.getMapXForPoint(o.getLocation().getLongitude());
int y = view.getMapYForPoint(o.getLocation().getLatitude());
int x = tb.getPixXFromLonNoRot(o.getLocation().getLongitude());
int y = tb.getPixYFromLatNoRot(o.getLocation().getLatitude());
canvas.drawRect(x - r, y - r, x + r, y + r, pointAltUI);
}
@ -156,7 +163,7 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
}
@Override
public boolean onLongPressEvent(PointF point) {
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
return false;
}
@ -184,8 +191,8 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
}
@Override
public void collectObjectsFromPoint(PointF point, List<Object> res) {
getFromPoint(point, res);
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> res) {
getFromPoint(tileBox, point, res);
}
@Override