fix zoom issues
git-svn-id: https://osmand.googlecode.com/svn/trunk@544 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
9454618ddb
commit
27ed10f078
22 changed files with 694 additions and 631 deletions
|
@ -15,10 +15,8 @@ public class ToDoConstants {
|
|||
// ! 81. Add some objects to POI category (1) to add them into OSM 2) to help navigation)
|
||||
// highway (?), traffic_calming (?), barrier(?), military(?-), landuse (?), office(?), man_made(?), power(?),
|
||||
// railway( station, subway?) - issue 17
|
||||
// !_22. Verify all POI has a point_type (in order to search them)
|
||||
// !_22. Verify all POI has a point_type (in order to search them) - !
|
||||
|
||||
// !_30. Fix rotate (_)
|
||||
|
||||
// Outside base 0.4 release
|
||||
// 97. For voice navigation consider current speed of vehicle. Especially when speed > 50 pronounce more than 200 m
|
||||
// 98. Implement rendering of different app mode. For Car render streets name with large font.
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.apache.commons.logging.Log;
|
|||
import android.database.sqlite.SQLiteException;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Environment;
|
||||
|
||||
/**
|
||||
|
@ -560,14 +559,14 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////// Working with map ////////////////////////////////////////////////
|
||||
public boolean updateRenderedMapNeeded(RectF tilesRect, int zoom, float rotate){
|
||||
return renderer.updateMapIsNeeded(tilesRect, zoom, rotate);
|
||||
public boolean updateRenderedMapNeeded(RotatedTileBox rotatedTileBox){
|
||||
return renderer.updateMapIsNeeded(rotatedTileBox);
|
||||
}
|
||||
|
||||
public void updateRendererMap(RectF tileRect, RectF boundsTileRect, int zoom, float rotate){
|
||||
public void updateRendererMap(RotatedTileBox rotatedTileBox){
|
||||
renderer.interruptLoadingMap();
|
||||
asyncLoadingTiles.requestToLoadMap(
|
||||
new MapLoadRequest(tileRect, boundsTileRect, zoom, rotate));
|
||||
new MapLoadRequest(new RotatedTileBox(rotatedTileBox)));
|
||||
}
|
||||
|
||||
public MapRenderRepositories getRenderer() {
|
||||
|
@ -721,17 +720,11 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
private static class MapLoadRequest {
|
||||
public final RectF tileRect;
|
||||
public final RectF boundsTileRect;
|
||||
public final int zoom;
|
||||
public final float rotate;
|
||||
public final RotatedTileBox tileBox;
|
||||
|
||||
public MapLoadRequest(RectF tileRect, RectF boundsTileRect, int zoom, float rotate) {
|
||||
public MapLoadRequest(RotatedTileBox tileBox) {
|
||||
super();
|
||||
this.tileRect = tileRect;
|
||||
this.boundsTileRect = boundsTileRect;
|
||||
this.zoom = zoom;
|
||||
this.rotate = rotate;
|
||||
this.tileBox = tileBox;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,7 +781,7 @@ public class ResourceManager {
|
|||
} else if(req instanceof MapLoadRequest){
|
||||
if(!mapLoaded){
|
||||
MapLoadRequest r = (MapLoadRequest) req;
|
||||
renderer.loadMap(r.tileRect, r.boundsTileRect, r.zoom, r.rotate);
|
||||
renderer.loadMap(r.tileBox);
|
||||
mapLoaded = true;
|
||||
}
|
||||
}
|
||||
|
|
158
OsmAnd/src/net/osmand/RotatedTileBox.java
Normal file
158
OsmAnd/src/net/osmand/RotatedTileBox.java
Normal file
|
@ -0,0 +1,158 @@
|
|||
package net.osmand;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.util.FloatMath;
|
||||
|
||||
public class RotatedTileBox {
|
||||
private float leftTileX;
|
||||
private float topTileY;
|
||||
private float tileWidth;
|
||||
private float tileHeight;
|
||||
private float rotate;
|
||||
private int zoom;
|
||||
private float rotateCos;
|
||||
private float rotateSin;
|
||||
|
||||
public RotatedTileBox(float leftTileX, float topTileY, float tileWidth, float tileHeight, float rotate, int zoom) {
|
||||
set(leftTileX, topTileY, tileWidth, tileHeight, rotate, zoom);
|
||||
}
|
||||
|
||||
public RotatedTileBox(RotatedTileBox r){
|
||||
set(r.leftTileX, r.topTileY, r.tileWidth, r.tileHeight, r.rotate, r.zoom);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
float rad = (float) Math.toRadians(this.rotate);
|
||||
rotateCos = FloatMath.cos(rad);
|
||||
rotateSin = FloatMath.sin(rad);
|
||||
}
|
||||
|
||||
public void set(float leftTileX, float topTileY, float tileWidth, float tileHeight, float rotate, int zoom) {
|
||||
this.leftTileX = leftTileX;
|
||||
if(rotate < 0){
|
||||
rotate += 360;
|
||||
} else if(rotate > 360){
|
||||
rotate -= 360;
|
||||
}
|
||||
this.rotate = rotate;
|
||||
this.tileHeight = tileHeight;
|
||||
this.tileWidth = tileWidth;
|
||||
this.topTileY = topTileY;
|
||||
this.zoom = zoom;
|
||||
init();
|
||||
}
|
||||
|
||||
public float getRotateCos() {
|
||||
return rotateCos;
|
||||
}
|
||||
|
||||
public float getRotateSin() {
|
||||
return rotateSin;
|
||||
}
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public float getRotate() {
|
||||
return rotate;
|
||||
}
|
||||
|
||||
public float getTileHeight() {
|
||||
return tileHeight;
|
||||
}
|
||||
|
||||
public float getTileWidth() {
|
||||
return tileWidth;
|
||||
}
|
||||
|
||||
public float getLeftTileX() {
|
||||
return leftTileX;
|
||||
}
|
||||
|
||||
public float getTopTileY() {
|
||||
return topTileY;
|
||||
}
|
||||
|
||||
public boolean containsTileBox(RotatedTileBox box) {
|
||||
PointF temp = new PointF();
|
||||
if(box.getZoom() != zoom){
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
box.calcPointTile(0, 0, temp);
|
||||
if(!containsPoint(temp.x, temp.y)){
|
||||
return false;
|
||||
}
|
||||
box.calcPointTile(box.tileWidth, 0, temp);
|
||||
if(!containsPoint(temp.x, temp.y)){
|
||||
return false;
|
||||
}
|
||||
box.calcPointTile(0, box.tileHeight, temp);
|
||||
if(!containsPoint(temp.x, temp.y)){
|
||||
return false;
|
||||
}
|
||||
box.calcPointTile(box.tileWidth, box.tileHeight, temp);
|
||||
if(!containsPoint(temp.x, temp.y)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public RectF calculateLatLonBox(RectF rectF) {
|
||||
float tx = calcPointTileX(tileWidth, 0);
|
||||
float tx2 = calcPointTileX(tileWidth, tileHeight);
|
||||
float tx3 = calcPointTileX(0, tileHeight);
|
||||
float minTileX = Math.min(Math.min(leftTileX, tx), Math.min(tx2, tx3)) ;
|
||||
float maxTileX = Math.max(Math.max(leftTileX, tx), Math.max(tx2, tx3)) ;
|
||||
|
||||
rectF.left = (float) MapUtils.getLongitudeFromTile(zoom, minTileX);
|
||||
rectF.right = (float) MapUtils.getLongitudeFromTile(zoom, maxTileX);
|
||||
|
||||
float ty = calcPointTileY(tileWidth, 0);
|
||||
float ty2 = calcPointTileY(tileWidth, tileHeight);
|
||||
float ty3 = calcPointTileY(0, tileHeight);
|
||||
|
||||
float minTileY = Math.min(Math.min(topTileY, ty), Math.min(ty2, ty3)) ;
|
||||
float maxTileY = Math.max(Math.max(topTileY, ty), Math.max(ty2, ty3)) ;
|
||||
|
||||
rectF.top = (float) MapUtils.getLatitudeFromTile(zoom, minTileY);
|
||||
rectF.bottom = (float) MapUtils.getLatitudeFromTile(zoom, maxTileY);
|
||||
|
||||
return rectF;
|
||||
}
|
||||
|
||||
public boolean containsPoint(float tileX, float tileY) {
|
||||
tileX -= leftTileX;
|
||||
tileY -= topTileY;
|
||||
double tx = rotateCos * tileX - rotateSin * tileY;
|
||||
double ty = rotateSin * tileX + rotateCos * tileY;
|
||||
return tx >= 0 && tx <= tileWidth && ty >= 0 && ty <= tileHeight;
|
||||
}
|
||||
|
||||
protected PointF calcPointTile(float dx, float dy, PointF p){
|
||||
float tx = rotateCos * dx + rotateSin * dy + leftTileX;
|
||||
float ty = - rotateSin * dx + rotateCos * dy + topTileY;
|
||||
p.set(tx, ty);
|
||||
return p;
|
||||
}
|
||||
|
||||
protected float calcPointTileX(float dx, float dy){
|
||||
return rotateCos * dx + rotateSin * dy + leftTileX;
|
||||
}
|
||||
|
||||
protected float calcPointTileY(float dx, float dy){
|
||||
return - rotateSin * dx + rotateCos * dy + topTileY;
|
||||
}
|
||||
|
||||
public float getRightBottomTileX() {
|
||||
return calcPointTileX(tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
public float getRightBottomTileY() {
|
||||
return calcPointTileY(tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -379,10 +379,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
Intent newIntent = new Intent(MapActivity.this, SearchActivity.class);
|
||||
startActivity(newIntent);
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_R) {
|
||||
// Is it needed
|
||||
mapView.setRotate(mapView.getRotate() + 45);
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Set;
|
|||
import net.osmand.IProgress;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.OsmandSettings;
|
||||
import net.osmand.RotatedTileBox;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.osm.MapRenderObject;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
|
@ -35,7 +36,6 @@ import org.apache.commons.logging.Log;
|
|||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.RectF;
|
||||
import android.util.FloatMath;
|
||||
|
||||
public class MapRenderRepositories {
|
||||
|
||||
|
@ -47,18 +47,20 @@ public class MapRenderRepositories {
|
|||
private Map<Connection, PreparedStatement> pZoom1 = new LinkedHashMap<Connection, PreparedStatement>();
|
||||
private Map<Connection, PreparedStatement> pZoom2 = new LinkedHashMap<Connection, PreparedStatement>();
|
||||
private OsmandRenderer renderer;
|
||||
|
||||
|
||||
private double cTopY;
|
||||
private double cBottomY;
|
||||
private double cLeftX;
|
||||
private double cRightX;
|
||||
private int cZoom;
|
||||
private float cRotate;
|
||||
|
||||
// cached objects in order to rotate without
|
||||
// lat/lon box of requested vector data
|
||||
private RectF cObjectsBox = new RectF();
|
||||
// cached objects in order to render rotation without reloading data from db
|
||||
private List<MapRenderObject> cObjects = new LinkedList<MapRenderObject>();
|
||||
private RectF cachedWaysLoc = new RectF();
|
||||
private float cachedRotate = 0;
|
||||
|
||||
// currently rendered box (not the same as already rendered)
|
||||
// this box is checked for interrupted process or
|
||||
private RotatedTileBox requestedBox = null;
|
||||
|
||||
// location of rendered bitmap
|
||||
private RotatedTileBox bmpLocation = null;
|
||||
// already rendered bitmap
|
||||
private Bitmap bmp;
|
||||
|
||||
private boolean interrupted = false;
|
||||
|
@ -179,14 +181,8 @@ public class MapRenderRepositories {
|
|||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
// if cache was changed different instance will be returned
|
||||
public RectF getCachedWaysLoc() {
|
||||
return cachedWaysLoc;
|
||||
}
|
||||
|
||||
public float getCachedRotate() {
|
||||
return cachedRotate;
|
||||
public RotatedTileBox getBitmapLocation() {
|
||||
return bmpLocation;
|
||||
}
|
||||
|
||||
protected void closeConnection(Connection c, String file){
|
||||
|
@ -208,32 +204,34 @@ public class MapRenderRepositories {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean updateMapIsNeeded(RectF tileRect, int zoom, float rotate){
|
||||
if (connections.isEmpty()) {
|
||||
|
||||
public boolean updateMapIsNeeded(RotatedTileBox box){
|
||||
if (connections.isEmpty() || box == null) {
|
||||
return false;
|
||||
}
|
||||
boolean inside = insideBox(tileRect.top, tileRect.left, tileRect.bottom, tileRect.right, zoom);
|
||||
if(rotate < 0){
|
||||
rotate += 360;
|
||||
}
|
||||
|
||||
return !inside || Math.abs(rotate - cRotate) > 45; // leave only 15 to find that UI box out of searched
|
||||
if(requestedBox == null){
|
||||
return true;
|
||||
}
|
||||
if(requestedBox.getZoom() != box.getZoom()){
|
||||
return true;
|
||||
}
|
||||
|
||||
float deltaRotate = requestedBox.getRotate() - box.getRotate();
|
||||
if(deltaRotate > 180){
|
||||
deltaRotate -= 360;
|
||||
} else if(deltaRotate < -180){
|
||||
deltaRotate += 360;
|
||||
}
|
||||
if(Math.abs(deltaRotate) > 25){
|
||||
return true;
|
||||
}
|
||||
return !requestedBox.containsTileBox(box);
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return connections.isEmpty();
|
||||
}
|
||||
|
||||
// MapUtils.getLatitudeFromTile(17, topY)
|
||||
private boolean insideBox(double topY, double leftX, double bottomY, double rightX, int zoom) {
|
||||
boolean inside = cZoom == zoom && cTopY <= topY && cLeftX <= leftX && cRightX >= rightX
|
||||
&& cBottomY >= bottomY;
|
||||
return inside;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String loadMapQuery = "SELECT "+IndexConstants.IndexMapRenderObject.ID +", " + IndexConstants.IndexMapRenderObject.NODES +", " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
IndexConstants.IndexMapRenderObject.NAME + ", " + IndexConstants.IndexMapRenderObject.TYPE + //$NON-NLS-1$
|
||||
" FROM " + IndexConstants.IndexMapRenderObject.getTable() + " WHERE "+IndexConstants.IndexMapRenderObject.ID+ //$NON-NLS-1$//$NON-NLS-2$
|
||||
|
@ -261,151 +259,167 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
private boolean checkWhetherInterrupted(){
|
||||
if(interrupted){
|
||||
// clear zoom to enable refreshing next time
|
||||
cZoom = 1;
|
||||
if(interrupted || (currentRenderingContext != null && currentRenderingContext.interrupted)){
|
||||
requestedBox = bmpLocation;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized void loadMap(RectF tileRect, RectF boundsTileRect, int zoom, float rotate) {
|
||||
interrupted = false;
|
||||
// currently doesn't work properly (every rotate bounds will be outside)
|
||||
boolean inside = insideBox(boundsTileRect.top, boundsTileRect.left, boundsTileRect.bottom, boundsTileRect.right, zoom);
|
||||
cRotate = rotate < 0 ? rotate + 360 : rotate;
|
||||
if (!inside) {
|
||||
cTopY = boundsTileRect.top;
|
||||
cLeftX = boundsTileRect.left;
|
||||
cRightX = boundsTileRect.right;
|
||||
cBottomY = boundsTileRect.bottom;
|
||||
double cBottomLatitude = MapUtils.getLatitudeFromTile(zoom, cBottomY);
|
||||
double cTopLatitude = MapUtils.getLatitudeFromTile(zoom, cTopY);
|
||||
double cLeftLongitude = MapUtils.getLongitudeFromTile(zoom, cLeftX);
|
||||
double cRightLongitude = MapUtils.getLongitudeFromTile(zoom, cRightX);
|
||||
cZoom = zoom;
|
||||
private boolean loadVectorData(RectF dataBox, int zoom){
|
||||
double cBottomLatitude = dataBox.bottom;
|
||||
double cTopLatitude = dataBox.top;
|
||||
double cLeftLongitude = dataBox.left;
|
||||
double cRightLongitude = dataBox.right;
|
||||
|
||||
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
|
||||
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, cZoom));
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
|
||||
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
if (connections.isEmpty()) {
|
||||
cObjectsBox = dataBox;
|
||||
cObjects = new ArrayList<MapRenderObject>();
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
int count = 0;
|
||||
ArrayList<MapRenderObject> tempList = new ArrayList<MapRenderObject>();
|
||||
System.gc(); // to clear previous objects
|
||||
// Set<Long> ids = new HashSet<Long>(1000);
|
||||
TLongSet ids = new TLongHashSet();
|
||||
Map<Integer, List<MapRenderObject>> multiPolygons = new LinkedHashMap<Integer, List<MapRenderObject>>();
|
||||
for (Connection c : connections.keySet()) {
|
||||
RectF r = connections.get(c);
|
||||
boolean intersects = r.top >= cBottomLatitude && r.left <= cRightLongitude && r.right >= cLeftLongitude &&
|
||||
r.bottom <= cTopLatitude;
|
||||
if(!intersects){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connections.isEmpty()) {
|
||||
cObjects = new ArrayList<MapRenderObject>();
|
||||
// keep old results
|
||||
PreparedStatement statement = null;
|
||||
if (zoom >= 15) {
|
||||
statement = pZoom0.get(c);
|
||||
} else if (zoom >= 10) {
|
||||
statement = pZoom1.get(c);
|
||||
} else if (zoom >= 6) {
|
||||
statement = pZoom2.get(c);
|
||||
} else {
|
||||
// TODO show raster tiles ?
|
||||
continue;
|
||||
}
|
||||
statement.setDouble(1, cBottomLatitude);
|
||||
statement.setDouble(2, cTopLatitude);
|
||||
statement.setDouble(3, cLeftLongitude);
|
||||
statement.setDouble(4, cRightLongitude);
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
|
||||
try {
|
||||
while (result.next()) {
|
||||
long id = result.getLong(1);
|
||||
if (PerformanceFlags.checkForDuplicateObjectIds) {
|
||||
if (ids.contains(id)) {
|
||||
// do not add object twice
|
||||
continue;
|
||||
}
|
||||
ids.add(id);
|
||||
}
|
||||
int type = result.getInt(4);
|
||||
MapRenderObject obj = new MapRenderObject(id);
|
||||
obj.setType(type);
|
||||
obj.setData(result.getBytes(2));
|
||||
obj.setName(result.getString(3));
|
||||
|
||||
count++;
|
||||
int mainType = obj.getMainType();
|
||||
// be attentive we need 16 bits from main type (not 15 bits!)
|
||||
// the last bit shows direction of multipolygon way
|
||||
registerMultipolygon(multiPolygons, mainType, obj);
|
||||
int sec = obj.getSecondType();
|
||||
if(sec != 0){
|
||||
registerMultipolygon(multiPolygons, sec, obj);
|
||||
}
|
||||
for (int k = 0; k < obj.getMultiTypes(); k++) {
|
||||
registerMultipolygon(multiPolygons, obj.getAdditionalType(k), obj);
|
||||
}
|
||||
if(checkWhetherInterrupted()){
|
||||
return false;
|
||||
}
|
||||
tempList.add(obj);
|
||||
}
|
||||
|
||||
} finally {
|
||||
result.close();
|
||||
}
|
||||
}
|
||||
int leftX = MapUtils.get31TileNumberX(cLeftLongitude);
|
||||
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
|
||||
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
|
||||
int topY = MapUtils.get31TileNumberY(cTopLatitude);
|
||||
List<MultyPolygon> pMulti = proccessMultiPolygons(multiPolygons, leftX, rightX, bottomY, topY);
|
||||
tempList.addAll(pMulti);
|
||||
log.info(String.format("Search has been done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
|
||||
|
||||
cObjects = tempList;
|
||||
cObjectsBox = dataBox;
|
||||
} catch (java.sql.SQLException e) {
|
||||
log.debug("Search failed", e); //$NON-NLS-1$
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void loadMap(RotatedTileBox tileRect) {
|
||||
interrupted = false;
|
||||
if(currentRenderingContext != null){
|
||||
currentRenderingContext = null;
|
||||
}
|
||||
// prevent editing
|
||||
requestedBox = new RotatedTileBox(tileRect);
|
||||
|
||||
// calculate data box
|
||||
RectF dataBox = requestedBox.calculateLatLonBox(new RectF());
|
||||
if (cObjectsBox.left > dataBox.left || cObjectsBox.top > dataBox.top ||
|
||||
cObjectsBox.right < dataBox.right || cObjectsBox.bottom < dataBox.bottom) {
|
||||
// increase data box in order for rotate
|
||||
if ((dataBox.right - dataBox.left) > (dataBox.top - dataBox.bottom)) {
|
||||
double wi = (dataBox.right - dataBox.left) * .2;
|
||||
dataBox.left -= wi;
|
||||
dataBox.right += wi;
|
||||
} else {
|
||||
double hi = (dataBox.bottom - dataBox.top) * .2;
|
||||
dataBox.top -= hi;
|
||||
dataBox.bottom += hi;
|
||||
}
|
||||
boolean loaded = loadVectorData(dataBox, requestedBox.getZoom());
|
||||
if(!loaded || checkWhetherInterrupted()){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int count = 0;
|
||||
cObjects = new ArrayList<MapRenderObject>();
|
||||
System.gc(); // to clear previous objects
|
||||
// Set<Long> ids = new HashSet<Long>(1000);
|
||||
TLongSet ids = new TLongHashSet();
|
||||
Map<Integer, List<MapRenderObject>> multiPolygons = new LinkedHashMap<Integer, List<MapRenderObject>>();
|
||||
for (Connection c : connections.keySet()) {
|
||||
RectF r = connections.get(c);
|
||||
boolean intersects = r.top >= cBottomLatitude && r.left <= cRightLongitude && r.right >= cLeftLongitude &&
|
||||
r.bottom <= cTopLatitude;
|
||||
if(!intersects){
|
||||
continue;
|
||||
}
|
||||
|
||||
PreparedStatement statement = null;
|
||||
if (zoom >= 15) {
|
||||
statement = pZoom0.get(c);
|
||||
} else if (zoom >= 10) {
|
||||
statement = pZoom1.get(c);
|
||||
} else if (zoom >= 6) {
|
||||
statement = pZoom2.get(c);
|
||||
} else {
|
||||
// TODO show tiles ?
|
||||
continue;
|
||||
}
|
||||
statement.setDouble(1, cBottomLatitude);
|
||||
statement.setDouble(2, cTopLatitude);
|
||||
statement.setDouble(3, cLeftLongitude);
|
||||
statement.setDouble(4, cRightLongitude);
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
|
||||
try {
|
||||
while (result.next()) {
|
||||
long id = result.getLong(1);
|
||||
if (PerformanceFlags.checkForDuplicateObjectIds) {
|
||||
if (ids.contains(id)) {
|
||||
// do not add object twice
|
||||
continue;
|
||||
}
|
||||
ids.add(id);
|
||||
}
|
||||
int type = result.getInt(4);
|
||||
MapRenderObject obj = new MapRenderObject(id);
|
||||
obj.setType(type);
|
||||
obj.setData(result.getBytes(2));
|
||||
obj.setName(result.getString(3));
|
||||
|
||||
count++;
|
||||
int mainType = obj.getMainType();
|
||||
// be attentive we need 16 bits from main type (not 15 bits!)
|
||||
// the last bit shows direction of multipolygon way
|
||||
registerMultipolygon(multiPolygons, mainType, obj);
|
||||
int sec = obj.getSecondType();
|
||||
if(sec != 0){
|
||||
registerMultipolygon(multiPolygons, sec, obj);
|
||||
}
|
||||
for (int k = 0; k < obj.getMultiTypes(); k++) {
|
||||
registerMultipolygon(multiPolygons, obj.getAdditionalType(k), obj);
|
||||
}
|
||||
if(checkWhetherInterrupted()){
|
||||
return;
|
||||
}
|
||||
cObjects.add(obj);
|
||||
}
|
||||
|
||||
} finally {
|
||||
result.close();
|
||||
}
|
||||
}
|
||||
int leftX = MapUtils.get31TileNumberX(cLeftLongitude);
|
||||
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
|
||||
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
|
||||
int topY = MapUtils.get31TileNumberY(cTopLatitude);
|
||||
List<MultyPolygon> pMulti = proccessMultiPolygons(multiPolygons, leftX, rightX, bottomY, topY);
|
||||
if(checkWhetherInterrupted()){
|
||||
return;
|
||||
}
|
||||
cObjects.addAll(pMulti);
|
||||
log.info(String
|
||||
.format("Search has been done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
|
||||
} catch (java.sql.SQLException e) {
|
||||
log.debug("Search failed", e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// create new instance to distinguish that cache was changed
|
||||
RectF newLoc = new RectF((float)MapUtils.getLongitudeFromTile(zoom, tileRect.left), (float)MapUtils.getLatitudeFromTile(zoom, tileRect.top),
|
||||
(float)MapUtils.getLongitudeFromTile(zoom, tileRect.right), (float)MapUtils.getLatitudeFromTile(zoom, tileRect.bottom));
|
||||
|
||||
int width = (int) calcDiffPixelX(cRotate, tileRect.right - tileRect.left, tileRect.bottom - tileRect.top);
|
||||
int height = (int) calcDiffPixelY(cRotate, tileRect.right - tileRect.left, tileRect.bottom - tileRect.top);
|
||||
currentRenderingContext = new OsmandRenderer.RenderingContext();
|
||||
currentRenderingContext.leftX = tileRect.left;
|
||||
currentRenderingContext.topY = tileRect.top;
|
||||
currentRenderingContext.zoom = cZoom;
|
||||
currentRenderingContext.rotate = cRotate;
|
||||
currentRenderingContext.width = width;
|
||||
currentRenderingContext.height = height;
|
||||
Bitmap bmp = renderer.generateNewBitmap(currentRenderingContext, cObjects, OsmandSettings.usingEnglishNames(context));
|
||||
if(currentRenderingContext.interrupted){
|
||||
cZoom = 1;
|
||||
currentRenderingContext.leftX = (float) requestedBox.getLeftTileX();
|
||||
currentRenderingContext.topY = (float) requestedBox.getTopTileY();
|
||||
currentRenderingContext.zoom = requestedBox.getZoom();
|
||||
currentRenderingContext.rotate = requestedBox.getRotate();
|
||||
currentRenderingContext.width = (int) (requestedBox.getTileWidth() * OsmandRenderer.TILE_SIZE);
|
||||
currentRenderingContext.height = (int) (requestedBox.getTileHeight() * OsmandRenderer.TILE_SIZE);
|
||||
if(checkWhetherInterrupted()){
|
||||
return;
|
||||
}
|
||||
|
||||
Bitmap bmp = renderer.generateNewBitmap(currentRenderingContext, cObjects, OsmandSettings.usingEnglishNames(context));
|
||||
if(checkWhetherInterrupted()){
|
||||
currentRenderingContext = null;
|
||||
return;
|
||||
}
|
||||
currentRenderingContext = null;
|
||||
Bitmap oldBmp = this.bmp;
|
||||
this.bmp = bmp;
|
||||
cachedWaysLoc = newLoc;
|
||||
cachedRotate = cRotate;
|
||||
this.bmpLocation = tileRect;
|
||||
if(oldBmp != null){
|
||||
oldBmp.recycle();
|
||||
}
|
||||
|
@ -416,24 +430,15 @@ public class MapRenderRepositories {
|
|||
return bmp;
|
||||
}
|
||||
|
||||
public float calcDiffPixelX(float rotate, float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * OsmandRenderer.TILE_SIZE;
|
||||
}
|
||||
|
||||
public float calcDiffPixelY(float rotate, float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.sin(rad) * dTileX + FloatMath.cos(rad) * dTileY) * OsmandRenderer.TILE_SIZE;
|
||||
}
|
||||
|
||||
public synchronized void clearCache() {
|
||||
cObjects.clear();
|
||||
cBottomY = cLeftX = cRightX = cTopY = cRotate = cZoom = 0;
|
||||
cObjectsBox = new RectF();
|
||||
if(bmp != null){
|
||||
bmp.recycle();
|
||||
bmp = null;
|
||||
}
|
||||
cachedWaysLoc = new RectF();
|
||||
requestedBox = bmpLocation = null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.render;
|
||||
|
||||
import net.osmand.ResourceManager;
|
||||
import net.osmand.RotatedTileBox;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.views.OsmandMapLayer;
|
||||
import net.osmand.views.OsmandMapTileView;
|
||||
|
@ -10,14 +11,13 @@ import android.graphics.Paint;
|
|||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.FloatMath;
|
||||
|
||||
public class RendererLayer implements OsmandMapLayer {
|
||||
|
||||
private OsmandMapTileView view;
|
||||
private final static int startZoom = 5;
|
||||
private Rect pixRect = new Rect();
|
||||
private RectF tileRect = new RectF();
|
||||
private RotatedTileBox rotatedTileBox = new RotatedTileBox(0, 0, 0, 0, 0, 0);
|
||||
private ResourceManager resourceManager;
|
||||
private Paint paintImg;
|
||||
|
||||
|
@ -41,42 +41,55 @@ public class RendererLayer implements OsmandMapLayer {
|
|||
paintImg = new Paint();
|
||||
paintImg.setFilterBitmap(true);
|
||||
}
|
||||
|
||||
private void updateRotatedTileBox(){
|
||||
float ts = view.getTileSize();
|
||||
float xL = view.calcDiffTileX(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY()) + view.getXTile();
|
||||
float yT = view.calcDiffTileY(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY()) + view.getYTile();
|
||||
rotatedTileBox.set(xL, yT, ((float) pixRect.width()) / ts, ((float) pixRect.height()) / ts, view.getRotate(), view.getZoom());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (view.getZoom() >= startZoom && visible) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
if (view.getFloatZoom() == view.getZoom()
|
||||
&& resourceManager.updateRenderedMapNeeded(tileRect, view.getZoom(), view.getRotate())) {
|
||||
pixRect.set(-view.getWidth(), -view.getHeight()/2, 2*view.getWidth(), 3*view.getHeight()/2);
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
float xL = view.calcDiffTileX(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY()) + view.getXTile();
|
||||
float xR = view.calcDiffTileX(pixRect.right - view.getCenterPointX(), pixRect.bottom - view.getCenterPointY()) + view.getXTile();
|
||||
float yT = view.calcDiffTileY(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY())+ view.getYTile();
|
||||
float yB = view.calcDiffTileY(pixRect.right - view.getCenterPointX(), pixRect.bottom - view.getCenterPointY()) + view.getYTile();
|
||||
RectF verticesRect = new RectF(xL, yT, xR, yB);
|
||||
resourceManager.updateRendererMap(verticesRect, tileRect, view.getZoom(), view.getRotate());
|
||||
if (!view.isZooming()){
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
updateRotatedTileBox();
|
||||
if(resourceManager.updateRenderedMapNeeded(rotatedTileBox)){
|
||||
pixRect.set(-view.getWidth(), -view.getHeight() / 2, 2 * view.getWidth(), 3 * view.getHeight() / 2);
|
||||
updateRotatedTileBox();
|
||||
resourceManager.updateRendererMap(rotatedTileBox);
|
||||
}
|
||||
}
|
||||
|
||||
MapRenderRepositories renderer = resourceManager.getRenderer();
|
||||
Bitmap bmp = renderer.getBitmap();
|
||||
if (renderer != null && bmp != null) {
|
||||
RectF newLoc = renderer.getCachedWaysLoc();
|
||||
float rot = renderer.getCachedRotate();
|
||||
float leftX1 = (float) MapUtils.getTileNumberX(view.getFloatZoom(), newLoc.left);
|
||||
float rightX1 = (float) MapUtils.getTileNumberX(view.getFloatZoom(), newLoc.right);
|
||||
float topY1 = (float) MapUtils.getTileNumberY(view.getFloatZoom(), newLoc.top);
|
||||
float bottomY1 = (float) MapUtils.getTileNumberY(view.getFloatZoom(), newLoc.bottom);
|
||||
|
||||
float x1 = calcDiffPixelX(rot, leftX1 - view.getXTile(), topY1 - view.getYTile()) + view.getCenterPointX();
|
||||
float y1 = calcDiffPixelY(rot, leftX1 - view.getXTile(), topY1 - view.getYTile()) + view.getCenterPointY();
|
||||
float x2 = calcDiffPixelX(rot, rightX1 - view.getXTile(), bottomY1 - view.getYTile()) + view.getCenterPointX();
|
||||
float y2 = calcDiffPixelY(rot, rightX1 - view.getXTile(), bottomY1 - view.getYTile()) + view.getCenterPointY();
|
||||
RotatedTileBox bmpLoc = renderer.getBitmapLocation();
|
||||
if (bmp != null && bmpLoc != null) {
|
||||
float rot = bmpLoc.getRotate();
|
||||
float mult = (float) MapUtils.getPowZoom(view.getZoom() - bmpLoc.getZoom());
|
||||
|
||||
float tx = view.getXTile();
|
||||
float ty = view.getYTile();
|
||||
float dleftX1 = (bmpLoc.getLeftTileX() * mult - tx) ;
|
||||
float dtopY1 = (bmpLoc.getTopTileY() * mult - ty);
|
||||
|
||||
|
||||
float cos = bmpLoc.getRotateCos();
|
||||
float sin = bmpLoc.getRotateSin();
|
||||
float x1 = MapUtils.calcDiffPixelX(sin, cos, dleftX1, dtopY1, view.getTileSize()) + view.getCenterPointX();
|
||||
float y1 = MapUtils.calcDiffPixelY(sin, cos, dleftX1, dtopY1, view.getTileSize()) + view.getCenterPointY();
|
||||
|
||||
/*float drightX1 = (bmpLoc.getRightBottomTileX() * mult - tx) ;
|
||||
float dbottomY1 = (bmpLoc.getRightBottomTileY() * mult - ty);
|
||||
float x2 = MapUtils.calcDiffPixelX(sin, cos, drightX1, dbottomY1, view.getTileSize()) + view.getCenterPointX();
|
||||
float y2 = MapUtils.calcDiffPixelY(sin, cos, drightX1, dbottomY1, view.getTileSize()) + view.getCenterPointY();
|
||||
destImage.set(x1, y1, x2, y2);*/
|
||||
|
||||
canvas.rotate(-rot, view.getCenterPointX(), view.getCenterPointY());
|
||||
destImage.set(x1, y1, x2, y2);
|
||||
destImage.set(x1, y1, x1 + bmpLoc.getTileWidth() * mult * view.getTileSize(), y1 + bmpLoc.getTileHeight() * mult * view.getTileSize());
|
||||
if(!bmp.isRecycled()){
|
||||
canvas.drawBitmap(bmp, null, destImage, paintImg);
|
||||
}
|
||||
|
@ -84,16 +97,6 @@ public class RendererLayer implements OsmandMapLayer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public float calcDiffPixelX(float rotate, float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * view.getTileSize();
|
||||
}
|
||||
|
||||
public float calcDiffPixelY(float rotate, float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.sin(rad) * dTileX + FloatMath.cos(rad) * dTileY) * view.getTileSize() ;
|
||||
}
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
view.refreshMap();
|
||||
|
|
|
@ -93,7 +93,7 @@ public class ContextMenuLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if(latLon != null){
|
||||
int x = view.getMapXForPoint(latLon.getLongitude());
|
||||
int y = view.getMapYForPoint(latLon.getLatitude());
|
||||
|
|
|
@ -7,7 +7,6 @@ import net.osmand.activities.FavouritesActivity;
|
|||
import net.osmand.activities.FavouritesActivity.FavouritePoint;
|
||||
import net.osmand.activities.FavouritesActivity.FavouritesDbHelper;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -15,7 +14,6 @@ import android.graphics.Matrix;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.util.DisplayMetrics;
|
||||
|
@ -31,8 +29,6 @@ public class FavoritesLayer implements OsmandMapLayer, ContextMenuLayer.IContext
|
|||
private OsmandMapTileView view;
|
||||
private List<FavouritePoint> favouritePoints;
|
||||
private List<FavouritePoint> additionalPoints;
|
||||
private Rect pixRect = new Rect();
|
||||
private RectF tileRect = new RectF();
|
||||
private Path path;
|
||||
private Path pathDst;
|
||||
private Paint paint;
|
||||
|
@ -76,7 +72,6 @@ public class FavoritesLayer implements OsmandMapLayer, ContextMenuLayer.IContext
|
|||
paintBlack.setAntiAlias(true);
|
||||
paintBlack.setStrokeWidth(2);
|
||||
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
reloadFavorites(view.getContext());
|
||||
}
|
||||
|
||||
|
@ -99,22 +94,17 @@ public class FavoritesLayer implements OsmandMapLayer, ContextMenuLayer.IContext
|
|||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (view.getZoom() >= startZoom) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), view.getYTile(),
|
||||
tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
|
||||
|
||||
// request to load
|
||||
for (FavouritePoint o : favouritePoints) {
|
||||
if (o.getLatitude() <= topLatitude && o.getLatitude() >= bottomLatitude && o.getLongitude() >= leftLongitude
|
||||
&& o.getLongitude() <= rightLongitude) {
|
||||
if (o.getLatitude() >= latLonBounds.bottom && o.getLatitude() <= latLonBounds.top && o.getLongitude() >= latLonBounds.left
|
||||
&& o.getLongitude() <= latLonBounds.right ) {
|
||||
int x = view.getMapXForPoint(o.getLongitude());
|
||||
int y = view.getMapYForPoint(o.getLatitude());
|
||||
matrix.setTranslate(x, y);
|
||||
|
@ -125,8 +115,8 @@ public class FavoritesLayer implements OsmandMapLayer, ContextMenuLayer.IContext
|
|||
}
|
||||
if(additionalPoints != null){
|
||||
for (FavouritePoint o : additionalPoints) {
|
||||
if (o.getLatitude() <= topLatitude && o.getLatitude() >= bottomLatitude && o.getLongitude() >= leftLongitude
|
||||
&& o.getLongitude() <= rightLongitude) {
|
||||
if (o.getLatitude() >= latLonBounds.bottom && o.getLatitude() <= latLonBounds.top && o.getLongitude() >= latLonBounds.left
|
||||
&& o.getLongitude() <= latLonBounds.right ) {
|
||||
int x = view.getMapXForPoint(o.getLongitude());
|
||||
int y = view.getMapYForPoint(o.getLatitude());
|
||||
matrix.setTranslate(x, y);
|
||||
|
|
|
@ -3,13 +3,11 @@ package net.osmand.views;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Join;
|
||||
|
@ -21,8 +19,6 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private Rect boundsRect;
|
||||
private RectF tileRect;
|
||||
private List<List<Location>> points = new ArrayList<List<Location>>();
|
||||
private Paint paint;
|
||||
|
||||
|
@ -34,8 +30,6 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
|
||||
|
||||
private void initUI() {
|
||||
boundsRect = new Rect(0, 0, view.getWidth(), view.getHeight());
|
||||
tileRect = new RectF();
|
||||
paint = new Paint();
|
||||
paint.setColor(Color.argb(180, 160, 10, 215));
|
||||
paint.setStyle(Style.STROKE);
|
||||
|
@ -56,20 +50,10 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if(points.isEmpty()){
|
||||
return;
|
||||
}
|
||||
int w = view.getWidth();
|
||||
int h = view.getHeight();
|
||||
boundsRect = new Rect(0, 0, w, h);
|
||||
view.calculateTileRectangle(boundsRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), view.getYTile(),
|
||||
tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
|
||||
for (List<Location> l : points) {
|
||||
path.rewind();
|
||||
|
@ -79,12 +63,12 @@ public class GPXLayer implements OsmandMapLayer {
|
|||
for (int i = 0; i < l.size(); i++) {
|
||||
Location ls = l.get(i);
|
||||
if (startIndex == -1) {
|
||||
if (leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && bottomLatitude <= ls.getLatitude()
|
||||
&& ls.getLatitude() <= topLatitude) {
|
||||
if (ls.getLatitude() >= latLonBounds.bottom && ls.getLatitude() <= latLonBounds.top && ls.getLongitude() >= latLonBounds.left
|
||||
&& ls.getLongitude() <= latLonBounds.right ) {
|
||||
startIndex = i > 0 ? i - 1 : i;
|
||||
}
|
||||
} else if (!(leftLongitude <= ls.getLongitude() + 0.01 && ls.getLongitude() - 0.01 <= rightLongitude
|
||||
&& bottomLatitude <= ls.getLatitude() + 0.01 && ls.getLatitude() - 0.01 <= topLatitude)) {
|
||||
} else if (!(latLonBounds.left <= ls.getLongitude() + 0.01 && ls.getLongitude() - 0.01 <= latLonBounds.right
|
||||
&& latLonBounds.bottom <= ls.getLatitude() + 0.01 && ls.getLatitude() - 0.01 <= latLonBounds.top)) {
|
||||
endIndex = i;
|
||||
// do not continue make method more efficient (because it calls in UI thread)
|
||||
// this break also has logical sense !
|
||||
|
|
|
@ -190,7 +190,7 @@ public class MapInfoLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latlonBounds) {
|
||||
// prepare data (left distance, speed)
|
||||
if(map.getPointToNavigate() != null){
|
||||
int d = 0;
|
||||
|
@ -287,18 +287,18 @@ public class MapInfoLayer implements OsmandMapLayer {
|
|||
|
||||
|
||||
// update cache
|
||||
if (view.getFloatZoom() != (int) view.getFloatZoom()) {
|
||||
if (view.isZooming()) {
|
||||
rulerDistName = null;
|
||||
} else if(view.getFloatZoom() != rulerCZoom ||
|
||||
} else if(view.getZoom() != rulerCZoom ||
|
||||
Math.abs(view.getXTile() - rulerCTileX) + Math.abs(view.getYTile() - rulerCTileY) > 1){
|
||||
rulerCZoom = (int) view.getFloatZoom();
|
||||
rulerCZoom = view.getZoom();
|
||||
rulerCTileX = view.getXTile();
|
||||
rulerCTileY = view.getYTile();
|
||||
double latitude = view.getLatitude();
|
||||
double tileNumberLeft = rulerCTileX - ((double) view.getWidth()) / (2d * view.getTileSize());
|
||||
double tileNumberRight = rulerCTileX + ((double) view.getWidth()) / (2d * view.getTileSize());
|
||||
double dist = MapUtils.getDistance(latitude, MapUtils.getLongitudeFromTile(view.getFloatZoom(), tileNumberLeft), latitude,
|
||||
MapUtils.getLongitudeFromTile(view.getFloatZoom(), tileNumberRight));
|
||||
double dist = MapUtils.getDistance(latitude, MapUtils.getLongitudeFromTile(view.getZoom(), tileNumberLeft), latitude,
|
||||
MapUtils.getLongitudeFromTile(view.getZoom(), tileNumberRight));
|
||||
|
||||
dist *= screenPercent;
|
||||
int baseDist = 5;
|
||||
|
|
|
@ -91,7 +91,7 @@ public class MultiTouchSupport {
|
|||
Float x2 = (Float) getX.invoke(event, 1);
|
||||
Float y1 = (Float) getY.invoke(event, 0);
|
||||
Float y2 = (Float) getY.invoke(event, 1);
|
||||
float distance = FloatMath.sqrt((x2 - x1)*(x2 -x1) + (y2-y1)*(y2-y1));
|
||||
float distance = FloatMath.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
|
||||
previousZoom = distance / zoomStartedDistance;
|
||||
if (actionCode == ACTION_POINTER_DOWN) {
|
||||
centerPoint = new PointF((x1 + x2) / 2, (y1 + y2) / 2);
|
||||
|
|
|
@ -15,7 +15,6 @@ import net.osmand.LogUtil;
|
|||
import net.osmand.OsmandSettings;
|
||||
import net.osmand.R;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -29,7 +28,6 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
@ -49,8 +47,6 @@ public class OsmBugsLayer implements OsmandMapLayer, ContextMenuLayer.IContextMe
|
|||
|
||||
private OsmandMapTileView view;
|
||||
private Handler handlerToLoop;
|
||||
private Rect pixRect = new Rect();
|
||||
private RectF tileRect = new RectF();
|
||||
|
||||
private List<OpenStreetBug> objects = new ArrayList<OpenStreetBug>();
|
||||
private Paint pointClosedUI;
|
||||
|
@ -98,7 +94,6 @@ public class OsmBugsLayer implements OsmandMapLayer, ContextMenuLayer.IContextMe
|
|||
pointClosedUI.setColor(Color.GREEN);
|
||||
pointClosedUI.setAlpha(200);
|
||||
pointClosedUI.setAntiAlias(true);
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,19 +117,10 @@ public class OsmBugsLayer implements OsmandMapLayer, ContextMenuLayer.IContextMe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (view.getZoom() >= startZoom) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
|
||||
|
||||
// request to load
|
||||
requestToLoad(topLatitude, leftLongitude, bottomLatitude, rightLongitude, view.getZoom());
|
||||
requestToLoad(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom());
|
||||
for (OpenStreetBug o : objects) {
|
||||
int x = view.getMapXForPoint(o.getLongitude());
|
||||
int y = view.getMapYForPoint(o.getLatitude());
|
||||
|
|
|
@ -2,13 +2,14 @@ package net.osmand.views;
|
|||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
|
||||
public interface OsmandMapLayer {
|
||||
|
||||
|
||||
public void initLayer(OsmandMapTileView view);
|
||||
|
||||
public void onDraw(Canvas canvas);
|
||||
public void onDraw(Canvas canvas, RectF latlonRect);
|
||||
|
||||
public void destroyLayer();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package net.osmand.views;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -45,69 +44,72 @@ import android.view.GestureDetector.OnDoubleTapListener;
|
|||
import android.view.GestureDetector.OnGestureListener;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
|
||||
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback,
|
||||
Callback, AnimateDraggingCallback, OnGestureListener, OnDoubleTapListener, MultiTouchZoomListener {
|
||||
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback, Callback, AnimateDraggingCallback, OnGestureListener,
|
||||
OnDoubleTapListener, MultiTouchZoomListener {
|
||||
|
||||
public static final int OVERZOOM_IN = 2;
|
||||
|
||||
|
||||
protected final int emptyTileDivisor = 16;
|
||||
|
||||
public interface OnTrackBallListener{
|
||||
|
||||
public interface OnTrackBallListener {
|
||||
public boolean onTrackBallEvent(MotionEvent e);
|
||||
}
|
||||
|
||||
|
||||
public interface OnLongClickListener {
|
||||
public boolean onLongPressEvent(PointF point);
|
||||
}
|
||||
|
||||
public interface OnClickListener {
|
||||
public boolean onPressEvent(PointF point);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected static final Log log = LogUtil.getLog(OsmandMapTileView.class);
|
||||
/**
|
||||
* 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 int mapPosition;
|
||||
|
||||
|
||||
private boolean showMapPosition = true;
|
||||
|
||||
// name of source map
|
||||
|
||||
// name of source map
|
||||
private ITileSource map = null;
|
||||
|
||||
|
||||
private IMapLocationListener locationListener;
|
||||
|
||||
|
||||
private OnLongClickListener onLongClickListener;
|
||||
|
||||
|
||||
private OnClickListener onClickListener;
|
||||
|
||||
|
||||
private OnTrackBallListener trackBallDelegate;
|
||||
|
||||
|
||||
private List<OsmandMapLayer> layers = new ArrayList<OsmandMapLayer>();
|
||||
private Map<OsmandMapLayer, Float> zOrders = new HashMap<OsmandMapLayer, Float>();
|
||||
|
||||
|
||||
// UI Part
|
||||
// handler to refresh map (in ui thread - not necessary in ui thread, but msg queue is desirable).
|
||||
// handler to refresh map (in ui thread - not necessary in ui thread, but msg queue is desirable).
|
||||
protected Handler handler = new Handler();
|
||||
|
||||
|
||||
private AnimateDraggingMapThread animatedDraggingThread;
|
||||
|
||||
|
||||
private float initialMultiTouchZoom;
|
||||
private PointF initialMultiTouchCenterPoint;
|
||||
private LatLon initialMultiTouchLocation;
|
||||
|
||||
|
||||
private GestureDetector gestureDetector;
|
||||
|
||||
|
||||
private MultiTouchSupport multiTouchSupport;
|
||||
|
||||
|
||||
Paint paintGrayFill;
|
||||
Paint paintWhiteFill;
|
||||
Paint paintCenter;
|
||||
|
@ -116,22 +118,21 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
private DisplayMetrics dm;
|
||||
|
||||
private final OsmandApplication application;
|
||||
|
||||
|
||||
|
||||
public OsmandMapTileView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initView();
|
||||
application = (OsmandApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
|
||||
public OsmandMapTileView(Context context) {
|
||||
super(context);
|
||||
initView();
|
||||
application = (OsmandApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
/////////////////////////////// INITIALIZING UI PART ///////////////////////////////////
|
||||
public void initView(){
|
||||
|
||||
// ///////////////////////////// INITIALIZING UI PART ///////////////////////////////////
|
||||
public void initView() {
|
||||
paintGrayFill = new Paint();
|
||||
paintGrayFill.setColor(Color.GRAY);
|
||||
paintGrayFill.setStyle(Style.FILL);
|
||||
|
@ -143,35 +144,33 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
paintWhiteFill.setStyle(Style.FILL);
|
||||
// when map rotate
|
||||
paintWhiteFill.setAntiAlias(true);
|
||||
|
||||
|
||||
paintCenter = new Paint();
|
||||
paintCenter.setStyle(Style.STROKE);
|
||||
paintCenter.setColor(Color.rgb(60, 60, 60));
|
||||
paintCenter.setStrokeWidth(2);
|
||||
paintCenter.setAntiAlias(true);
|
||||
|
||||
|
||||
paintBitmap = new Paint();
|
||||
paintBitmap.setFilterBitmap(true);
|
||||
|
||||
setClickable(true);
|
||||
setLongClickable(true);
|
||||
setFocusable(true);
|
||||
|
||||
|
||||
getHolder().addCallback(this);
|
||||
|
||||
|
||||
animatedDraggingThread = new AnimateDraggingMapThread();
|
||||
animatedDraggingThread.setCallback(this);
|
||||
gestureDetector = new GestureDetector(getContext(), this);
|
||||
multiTouchSupport = new MultiTouchSupport(getContext(), this);
|
||||
gestureDetector.setOnDoubleTapListener(this);
|
||||
|
||||
|
||||
WindowManager mgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
dm = new DisplayMetrics();
|
||||
mgr.getDefaultDisplay().getMetrics(dm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
refreshMap();
|
||||
|
@ -185,13 +184,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void addLayer(OsmandMapLayer layer, float zOrder){
|
||||
int i=0;
|
||||
for(i=0; i<layers.size(); i++){
|
||||
if(zOrders.get(layers.get(i)) > zOrder){
|
||||
|
||||
public void addLayer(OsmandMapLayer layer, float zOrder) {
|
||||
int i = 0;
|
||||
for (i = 0; i < layers.size(); i++) {
|
||||
if (zOrders.get(layers.get(i)) > zOrder) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -199,147 +196,156 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
layers.add(i, layer);
|
||||
zOrders.put(layer, zOrder);
|
||||
}
|
||||
|
||||
public void removeLayer(OsmandMapLayer layer){
|
||||
|
||||
public void removeLayer(OsmandMapLayer layer) {
|
||||
layers.remove(layer);
|
||||
zOrders.remove(layer);
|
||||
layer.destroyLayer();
|
||||
}
|
||||
|
||||
|
||||
public List<OsmandMapLayer> getLayers() {
|
||||
return layers;
|
||||
}
|
||||
|
||||
|
||||
public OsmandApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////// NON UI PART (could be extracted in common) /////////////////////////////
|
||||
// ///////////////////////// NON UI PART (could be extracted in common) /////////////////////////////
|
||||
/**
|
||||
* Returns real tile size in pixels for float zoom .
|
||||
*/
|
||||
public float getTileSize() {
|
||||
float res = map == null ? 256 : map.getTileSize();
|
||||
if(zoom != (int) zoom){
|
||||
res *= (float) Math.pow(2, zoom - (int) zoom);
|
||||
}
|
||||
// TODO introduce settings for these part
|
||||
if(dm != null && dm.density > 1f){
|
||||
res *= dm.density;
|
||||
if (zoom != (int) zoom) {
|
||||
res *= (float) Math.pow(2, zoom - (int) zoom);
|
||||
}
|
||||
|
||||
// that trigger allows to scale tiles for certain devices
|
||||
// for example for device with density > 1 draw tiles the same size as with density = 1
|
||||
// It makes text bigger but blurry, the settings could be introduced for that
|
||||
// if (dm != null && dm.density > 1f) {
|
||||
// res *= dm.density;
|
||||
// }
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public int getSourceTileSize() {
|
||||
return map == null ? 256 : map.getTileSize();
|
||||
}
|
||||
|
||||
|
||||
public float getXTile(){
|
||||
return (float) MapUtils.getTileNumberX(zoom, longitude);
|
||||
/**
|
||||
* @return x tile based on (int) zoom
|
||||
*/
|
||||
public float getXTile() {
|
||||
return (float) MapUtils.getTileNumberX(getZoom(), longitude);
|
||||
}
|
||||
|
||||
public float getYTile(){
|
||||
return (float) MapUtils.getTileNumberY(zoom, latitude);
|
||||
|
||||
/**
|
||||
* @return y tile based on (int) zoom
|
||||
*/
|
||||
public float getYTile() {
|
||||
return (float) MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
}
|
||||
|
||||
|
||||
public void setZoom(float zoom){
|
||||
if ((map == null && zoom < 22 && zoom > 0) ||
|
||||
(map != null && (map.getMaximumZoomSupported() + OVERZOOM_IN) >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||
|
||||
public void setZoom(float zoom) {
|
||||
if ((map == null && zoom < 22 && zoom > 0)
|
||||
|| (map != null && (map.getMaximumZoomSupported() + OVERZOOM_IN) >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||
animatedDraggingThread.stopAnimating();
|
||||
this.zoom = zoom;
|
||||
refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// for internal usage
|
||||
@Override
|
||||
public void zoomTo(float zoom, boolean notify) {
|
||||
if ((map == null && zoom < 23) ||
|
||||
(map != null && (map.getMaximumZoomSupported() + OVERZOOM_IN) >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||
if ((map == null && zoom < 23)
|
||||
|| (map != null && (map.getMaximumZoomSupported() + OVERZOOM_IN) >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||
this.zoom = zoom;
|
||||
refreshMap();
|
||||
if(notify && locationListener != null){
|
||||
if (notify && locationListener != null) {
|
||||
locationListener.locationChanged(latitude, longitude, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setRotate(float rotate) {
|
||||
float dif = this.rotate - rotate;
|
||||
if (dif > 2 || dif < -2) {
|
||||
float diff = this.rotate - rotate;
|
||||
if (diff > 4 || diff < -4) {
|
||||
this.rotate = rotate;
|
||||
float rotateRad = (float) Math.toRadians(rotate);
|
||||
this.rotateCos = FloatMath.cos(rotateRad);
|
||||
this.rotateSin = FloatMath.sin(rotateRad);
|
||||
animatedDraggingThread.stopAnimating();
|
||||
refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isShowMapPosition() {
|
||||
return showMapPosition;
|
||||
}
|
||||
|
||||
|
||||
public void setShowMapPosition(boolean showMapPosition) {
|
||||
this.showMapPosition = showMapPosition;
|
||||
}
|
||||
|
||||
|
||||
public float getRotate() {
|
||||
return rotate;
|
||||
}
|
||||
|
||||
|
||||
public ITileSource getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public void setMap(ITileSource map) {
|
||||
this.map = map;
|
||||
if(map !=null && map.getMaximumZoomSupported() + OVERZOOM_IN < this.zoom){
|
||||
if (map != null && map.getMaximumZoomSupported() + OVERZOOM_IN < this.zoom) {
|
||||
zoom = map.getMaximumZoomSupported() + OVERZOOM_IN;
|
||||
}
|
||||
if(map !=null && map.getMinimumZoomSupported() > this.zoom){
|
||||
if (map != null && map.getMinimumZoomSupported() > this.zoom) {
|
||||
zoom = map.getMinimumZoomSupported();
|
||||
}
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
public void setLatLon(double latitude, double longitude){
|
||||
|
||||
public void setLatLon(double latitude, double longitude) {
|
||||
animatedDraggingThread.stopAnimating();
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
refreshMap();
|
||||
}
|
||||
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
|
||||
public int getZoom() {
|
||||
return (int) zoom;
|
||||
}
|
||||
|
||||
public float getFloatZoom(){
|
||||
return zoom;
|
||||
|
||||
public boolean isZooming(){
|
||||
return zoom != getZoom();
|
||||
}
|
||||
|
||||
|
||||
public void setMapLocationListener(IMapLocationListener l){
|
||||
public void setMapLocationListener(IMapLocationListener l) {
|
||||
locationListener = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds listener to control when map is dragging
|
||||
* Adds listener to control when map is dragging
|
||||
*/
|
||||
public IMapLocationListener setMapLocationListener(){
|
||||
public IMapLocationListener setMapLocationListener() {
|
||||
return locationListener;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////// DRAWING MAP PART /////////////////////////////////////////////
|
||||
|
||||
protected void drawEmptyTile(Canvas cvs, float x, float y, float ftileSize){
|
||||
|
||||
// ////////////////////////////// DRAWING MAP PART /////////////////////////////////////////////
|
||||
|
||||
protected void drawEmptyTile(Canvas cvs, float x, float y, float ftileSize) {
|
||||
float tileDiv = (ftileSize / emptyTileDivisor);
|
||||
for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
|
||||
for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
|
||||
|
@ -354,27 +360,26 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
}
|
||||
}
|
||||
|
||||
public int getCenterPointX(){
|
||||
public int getCenterPointX() {
|
||||
return getWidth() / 2;
|
||||
}
|
||||
|
||||
public int getCenterPointY(){
|
||||
if(mapPosition == OsmandSettings.BOTTOM_CONSTANT){
|
||||
|
||||
public int getCenterPointY() {
|
||||
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
|
||||
return 3 * getHeight() / 4;
|
||||
}
|
||||
return getHeight() / 2;
|
||||
}
|
||||
|
||||
public void setMapPosition(int type){
|
||||
|
||||
public void setMapPosition(int type) {
|
||||
this.mapPosition = type;
|
||||
}
|
||||
|
||||
|
||||
private void drawOverMap(Canvas canvas){
|
||||
|
||||
private void drawOverMap(Canvas canvas, RectF latlonRect) {
|
||||
int w = getCenterPointX();
|
||||
int h = getCenterPointY();
|
||||
canvas.restore();
|
||||
|
||||
|
||||
for (int i = 0; i < layers.size(); i++) {
|
||||
try {
|
||||
OsmandMapLayer layer = layers.get(i);
|
||||
|
@ -382,7 +387,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
if (!layer.drawInScreenPixels()) {
|
||||
canvas.rotate(rotate, w, h);
|
||||
}
|
||||
layer.onDraw(canvas);
|
||||
layer.onDraw(canvas, latlonRect);
|
||||
canvas.restore();
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// skip it
|
||||
|
@ -393,8 +398,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
canvas.drawCircle(w, h, 7 * dm.density, paintCenter);
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateTileRectangle(Rect pixRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
|
||||
|
||||
public void calculateTileRectangle(Rect pixRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect) {
|
||||
float x1 = calcDiffTileX(pixRect.left - cx, pixRect.top - cy);
|
||||
float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy);
|
||||
float x3 = calcDiffTileX(pixRect.right - cx, pixRect.top - cy);
|
||||
|
@ -409,8 +414,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
float b = Math.max(Math.max(y1, y2), Math.max(y3, y4)) + ctiley;
|
||||
tileRect.set(l, t, r, b);
|
||||
}
|
||||
|
||||
public void calculatePixelRectangle(Rect pixelRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
|
||||
|
||||
public void calculatePixelRectangle(Rect pixelRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect) {
|
||||
float x1 = calcDiffPixelX(tileRect.left - ctilex, tileRect.top - ctiley);
|
||||
float x2 = calcDiffPixelX(tileRect.left - ctilex, tileRect.bottom - ctiley);
|
||||
float x3 = calcDiffPixelX(tileRect.right - ctilex, tileRect.top - ctiley);
|
||||
|
@ -425,49 +430,56 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
int b = Math.round(Math.max(Math.max(y1, y2), Math.max(y3, y4)) + cy);
|
||||
pixelRect.set(l, t, r, b);
|
||||
}
|
||||
|
||||
// used only to save space & reuse
|
||||
|
||||
// used only to save space & reuse
|
||||
protected RectF tilesRect = new RectF();
|
||||
protected RectF latlonRect = new RectF();
|
||||
protected Rect boundsRect = new Rect();
|
||||
protected RectF bitmapToDraw = new RectF();
|
||||
protected Rect bitmapToZoom = new Rect();
|
||||
|
||||
private void refreshMapInternal(){
|
||||
if(handler.hasMessages(1)){
|
||||
|
||||
private void refreshMapInternal() {
|
||||
if (handler.hasMessages(1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean useInternet = OsmandSettings.isUsingInternetToDownloadTiles(getContext());
|
||||
if (useInternet) {
|
||||
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
||||
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
||||
}
|
||||
float ftileSize = getTileSize();
|
||||
int tileSize = map == null ? 256 : map.getTileSize();
|
||||
float tileX = getXTile();
|
||||
float tileY = getYTile();
|
||||
float w = getCenterPointX();
|
||||
float h = getCenterPointY();
|
||||
int tileSize = getSourceTileSize();
|
||||
|
||||
|
||||
SurfaceHolder holder = getHolder();
|
||||
synchronized (holder) {
|
||||
int nzoom = (int) zoom;
|
||||
int nzoom = getZoom();
|
||||
float tileX = (float) MapUtils.getTileNumberX(nzoom, longitude);
|
||||
float tileY = (float) MapUtils.getTileNumberY(nzoom, latitude);
|
||||
float w = getCenterPointX();
|
||||
float h = getCenterPointY();
|
||||
Canvas canvas = holder.lockCanvas();
|
||||
if (canvas != null) {
|
||||
canvas.save();
|
||||
boundsRect.set(0, 0, getWidth(), getHeight());
|
||||
canvas.rotate(rotate, w , h);
|
||||
canvas.rotate(rotate, w, h);
|
||||
try {
|
||||
calculateTileRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
|
||||
int left = (int) FloatMath.floor(tilesRect.left);
|
||||
int top = (int) FloatMath.floor(tilesRect.top );
|
||||
int width = (int) FloatMath.ceil(tilesRect.right - left);
|
||||
int height = (int) FloatMath.ceil(tilesRect.bottom - top);
|
||||
latlonRect.top = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.top);
|
||||
latlonRect.left = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.left);
|
||||
latlonRect.bottom = (float) MapUtils.getLatitudeFromTile(nzoom, tilesRect.bottom);
|
||||
latlonRect.right = (float) MapUtils.getLongitudeFromTile(nzoom, tilesRect.right);
|
||||
if (map != null) {
|
||||
ResourceManager mgr = getApplication().getResourceManager();
|
||||
useInternet = useInternet && OsmandSettings.isInternetConnectionAvailable(getContext())
|
||||
&& map.couldBeDownloadedFromInternet();
|
||||
int maxLevel = Math.min(OsmandSettings.getMaximumLevelToDownloadTile(getContext()), map.getMaximumZoomSupported());
|
||||
|
||||
|
||||
calculateTileRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
|
||||
int left = (int) FloatMath.floor(tilesRect.left);
|
||||
int top = (int) FloatMath.floor(tilesRect.top);
|
||||
int width = (int) (FloatMath.ceil(tilesRect.right) - left);
|
||||
int height = (int) (FloatMath.ceil(tilesRect.bottom) - top);
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
float x1 = (i + left - tileX) * ftileSize + w;
|
||||
|
@ -524,11 +536,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
}
|
||||
}
|
||||
} else {
|
||||
calculateTileRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
|
||||
int left = (int) FloatMath.floor(tilesRect.left);
|
||||
int top = (int) FloatMath.floor(tilesRect.top);
|
||||
int width = (int) (FloatMath.ceil(tilesRect.right) - left);
|
||||
int height = (int) (FloatMath.ceil(tilesRect.bottom) - top);
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
float x1 = (i + left - tileX) * ftileSize + w;
|
||||
|
@ -537,28 +544,29 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
}
|
||||
}
|
||||
}
|
||||
drawOverMap(canvas);
|
||||
drawOverMap(canvas, latlonRect);
|
||||
} finally {
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean mapIsRefreshing(){
|
||||
|
||||
public boolean mapIsRefreshing() {
|
||||
return handler.hasMessages(1);
|
||||
}
|
||||
|
||||
public boolean mapIsAnimating(){
|
||||
|
||||
public boolean mapIsAnimating() {
|
||||
return animatedDraggingThread != null && animatedDraggingThread.isAnimating();
|
||||
}
|
||||
|
||||
// this method could be called in non UI thread
|
||||
public void refreshMap() {
|
||||
if(!handler.hasMessages(1)){
|
||||
Message msg = Message.obtain(handler, new Runnable(){
|
||||
if (!handler.hasMessages(1)) {
|
||||
Message msg = Message.obtain(handler, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void run() {
|
||||
refreshMapInternal();
|
||||
}
|
||||
});
|
||||
|
@ -566,21 +574,20 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
handler.sendMessageDelayed(msg, 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void tileDownloaded(DownloadRequest request) {
|
||||
if (request == null || rotate != 0 ) {
|
||||
if (request == null || rotate != 0) {
|
||||
// if image is rotated call refresh the whole canvas
|
||||
// because we can't find dirty rectangular region but all pixels should be drawn
|
||||
// because we can't find dirty rectangular region
|
||||
|
||||
// we don't know exact images were changed
|
||||
// if request null then we don't know exact images were changed
|
||||
refreshMap();
|
||||
return;
|
||||
}
|
||||
if(request.error){
|
||||
if (request.error) {
|
||||
return;
|
||||
}
|
||||
if (request.zoom != this.zoom) {
|
||||
if (request.zoom != getZoom()) {
|
||||
return;
|
||||
}
|
||||
float w = getCenterPointX();
|
||||
|
@ -592,16 +599,16 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
synchronized (holder) {
|
||||
tilesRect.set(request.xTile, request.yTile, request.xTile + 1, request.yTile + 1);
|
||||
calculatePixelRectangle(boundsRect, w, h, tileX, tileY, tilesRect);
|
||||
|
||||
if(boundsRect.left > getWidth() || boundsRect.right < 0 || boundsRect.bottom < 0 || boundsRect.top > getHeight()){
|
||||
|
||||
if (boundsRect.left > getWidth() || boundsRect.right < 0 || boundsRect.bottom < 0 || boundsRect.top > getHeight()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Canvas canvas = holder.lockCanvas(boundsRect);
|
||||
if (canvas != null) {
|
||||
canvas.save();
|
||||
canvas.rotate(rotate, w , h);
|
||||
|
||||
canvas.rotate(rotate, w, h);
|
||||
|
||||
try {
|
||||
Bitmap bmp = null;
|
||||
if (map != null) {
|
||||
|
@ -619,116 +626,107 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
bitmapToDraw.set(x, y, x + tileSize, y + tileSize);
|
||||
canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
|
||||
}
|
||||
drawOverMap(canvas);
|
||||
drawOverMap(canvas, latlonRect);
|
||||
} finally {
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////// DRAGGING PART ///////////////////////////////////////
|
||||
public float calcDiffTileY(float dx, float dy){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (-FloatMath.sin(rad) * dx + FloatMath.cos(rad) * dy) / (getTileSize() );
|
||||
// ///////////////////////////////// DRAGGING PART ///////////////////////////////////////
|
||||
public float calcDiffTileY(float dx, float dy) {
|
||||
return (-rotateSin * dx + rotateCos * dy) / getTileSize();
|
||||
}
|
||||
|
||||
public float calcDiffTileX(float dx, float dy){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.cos(rad) * dx + FloatMath.sin(rad) * dy) / (getTileSize() );
|
||||
|
||||
public float calcDiffTileX(float dx, float dy) {
|
||||
return (rotateCos * dx + rotateSin * dy) / getTileSize();
|
||||
}
|
||||
|
||||
public float calcDiffPixelY(float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.sin(rad) * dTileX + FloatMath.cos(rad) * dTileY) * getTileSize() ;
|
||||
|
||||
public float calcDiffPixelY(float dTileX, float dTileY) {
|
||||
return (rotateSin * dTileX + rotateCos * dTileY) * getTileSize();
|
||||
}
|
||||
|
||||
public float calcDiffPixelX(float dTileX, float dTileY){
|
||||
float rad = (float) Math.toRadians(rotate);
|
||||
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * getTileSize() ;
|
||||
|
||||
public float calcDiffPixelX(float dTileX, float dTileY) {
|
||||
return (rotateCos * dTileX - rotateSin * dTileY) * getTileSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* These methods do not consider rotating
|
||||
*/
|
||||
public int getMapXForPoint(double longitude){
|
||||
double tileX = MapUtils.getTileNumberX(zoom, longitude);
|
||||
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(zoom, latitude);
|
||||
return (int) ((tileY - getYTile()) * getTileSize() + getCenterPointY());
|
||||
|
||||
public int getMapYForPoint(double latitude) {
|
||||
double tileY = MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
return (int) ((tileY - getYTile()) * getTileSize() + getCenterPointY());
|
||||
}
|
||||
|
||||
public int getRotatedMapXForPoint(double latitude, double longitude){
|
||||
|
||||
public int getRotatedMapXForPoint(double latitude, double longitude) {
|
||||
int cx = getCenterPointX();
|
||||
double xTile = MapUtils.getTileNumberX(zoom, longitude);
|
||||
double yTile = MapUtils.getTileNumberY(zoom, latitude);
|
||||
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
|
||||
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
return (int) (calcDiffPixelX((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cx);
|
||||
}
|
||||
public int getRotatedMapYForPoint(double latitude, double longitude){
|
||||
|
||||
public int getRotatedMapYForPoint(double latitude, double longitude) {
|
||||
int cy = getCenterPointY();
|
||||
double xTile = MapUtils.getTileNumberX(zoom, longitude);
|
||||
double yTile = MapUtils.getTileNumberY(zoom, latitude);
|
||||
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
|
||||
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
return (int) (calcDiffPixelY((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cy);
|
||||
}
|
||||
|
||||
|
||||
public boolean isPointOnTheRotatedMap(double latitude, double longitude){
|
||||
|
||||
public boolean isPointOnTheRotatedMap(double latitude, double longitude) {
|
||||
int cx = getCenterPointX();
|
||||
int cy = getCenterPointY();
|
||||
double xTile = MapUtils.getTileNumberX(zoom, longitude);
|
||||
double yTile = MapUtils.getTileNumberY(zoom, latitude);
|
||||
double xTile = MapUtils.getTileNumberX(getZoom(), longitude);
|
||||
double yTile = MapUtils.getTileNumberY(getZoom(), latitude);
|
||||
int newX = (int) (calcDiffPixelX((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cx);
|
||||
int newY = (int) (calcDiffPixelY((float) (xTile - getXTile()), (float) (yTile - getYTile())) + cy);
|
||||
if(newX >= 0 && newX <= getWidth() && newY >=0 && newY <= getHeight()){
|
||||
if (newX >= 0 && newX <= getWidth() && newY >= 0 && newY <= getHeight()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dragTo(float fromX, float fromY, float toX, float toY, boolean notify){
|
||||
float dx = (fromX - toX) ;
|
||||
public void dragTo(float fromX, float fromY, float toX, float toY, boolean notify) {
|
||||
float dx = (fromX - toX);
|
||||
float dy = (fromY - toY);
|
||||
moveTo(dx, dy);
|
||||
if(locationListener != null && notify){
|
||||
if (locationListener != null && notify) {
|
||||
locationListener.locationChanged(latitude, longitude, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setLatLon(double latitude, double longitude, boolean notify) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
refreshMap();
|
||||
if(locationListener != null && notify){
|
||||
if (locationListener != null && notify) {
|
||||
locationListener.locationChanged(latitude, longitude, this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void moveTo(float dx, float dy) {
|
||||
float fy = calcDiffTileY(dx, dy);
|
||||
float fx = calcDiffTileX(dx, dy);
|
||||
|
||||
this.latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + fy);
|
||||
this.longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx);
|
||||
|
||||
this.latitude = MapUtils.getLatitudeFromTile(getZoom(), getYTile() + fy);
|
||||
this.longitude = MapUtils.getLongitudeFromTile(getZoom(), getXTile() + fx);
|
||||
refreshMap();
|
||||
// do not notify here listener
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(event.getAction() == MotionEvent.ACTION_DOWN){
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
animatedDraggingThread.stopAnimating();
|
||||
}
|
||||
if (!multiTouchSupport.onTouchEvent(event)) {
|
||||
|
@ -736,69 +734,67 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent event) {
|
||||
if(trackBallDelegate != null){
|
||||
if (trackBallDelegate != null) {
|
||||
trackBallDelegate.onTrackBallEvent(event);
|
||||
}
|
||||
return super.onTrackballEvent(event);
|
||||
}
|
||||
|
||||
|
||||
public void setTrackBallDelegate(OnTrackBallListener trackBallDelegate) {
|
||||
this.trackBallDelegate = trackBallDelegate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setOnLongClickListener(OnLongClickListener l) {
|
||||
this.onLongClickListener = l;
|
||||
}
|
||||
|
||||
|
||||
public void setOnClickListener(OnClickListener l) {
|
||||
this.onClickListener = l;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
// enable double tap animation
|
||||
// animatedDraggingThread.stopAnimating();
|
||||
// enable double tap animation
|
||||
// animatedDraggingThread.stopAnimating();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onZoomEnded(float distance, float relativeToStart) {
|
||||
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
|
||||
float calcZoom = initialMultiTouchZoom + dz;
|
||||
setZoom(Math.round(calcZoom));
|
||||
zoomPositionChanged(getFloatZoom());
|
||||
zoomPositionChanged(getZoom());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onZoomStarted(float distance, PointF centerPoint) {
|
||||
initialMultiTouchCenterPoint = centerPoint;
|
||||
initialMultiTouchLocation = getLatLonFromScreenPoint(centerPoint.x, centerPoint.y);
|
||||
initialMultiTouchZoom = zoom;
|
||||
}
|
||||
private void zoomPositionChanged(float calcZoom){
|
||||
float dtx = calcDiffTileX(getCenterPointX() - initialMultiTouchCenterPoint.x, getCenterPointY() - initialMultiTouchCenterPoint.y);
|
||||
float dty = calcDiffTileY(getCenterPointX() - initialMultiTouchCenterPoint.x, getCenterPointY() - initialMultiTouchCenterPoint.y);
|
||||
double tx = MapUtils.getTileNumberX(calcZoom, initialMultiTouchLocation.getLongitude());
|
||||
double ty = MapUtils.getTileNumberY(calcZoom, initialMultiTouchLocation.getLatitude());
|
||||
double lat = MapUtils.getLatitudeFromTile(calcZoom, ty + dty);
|
||||
double lon = MapUtils.getLongitudeFromTile(calcZoom, tx + dtx);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onZooming(float distance, float relativeToStart) {
|
||||
float dz = (float) (Math.log(relativeToStart) / Math.log(2) * 1.5);
|
||||
float calcZoom = initialMultiTouchZoom + dz;
|
||||
if(Math.abs(calcZoom - zoom) > 0.05){
|
||||
if (Math.abs(calcZoom - zoom) > 0.05) {
|
||||
setZoom(calcZoom);
|
||||
zoomPositionChanged(calcZoom);
|
||||
}
|
||||
|
@ -806,25 +802,26 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
if(Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density){
|
||||
animatedDraggingThread.startDragging(Math.abs(velocityX/1000), Math.abs(velocityY/1000), e1.getX(), e1.getY(), e2.getX(), e2.getY());
|
||||
if (Math.abs(e1.getX() - e2.getX()) + Math.abs(e1.getX() - e2.getX()) > 50 * dm.density) {
|
||||
animatedDraggingThread.startDragging(Math.abs(velocityX / 1000), Math.abs(velocityY / 1000), e1.getX(), e1.getY(), e2.getX(),
|
||||
e2.getY());
|
||||
} else {
|
||||
onScroll(e1, e2, e1.getX() - e2.getX(), e1.getY() - e2.getY());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public AnimateDraggingMapThread getAnimatedDraggingThread() {
|
||||
return animatedDraggingThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
if(multiTouchSupport.isInZoomMode()){
|
||||
if (multiTouchSupport.isInZoomMode()) {
|
||||
return;
|
||||
}
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("On long click event "+ e.getX() + " " + e.getY()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("On long click event " + e.getX() + " " + e.getY()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
PointF point = new PointF(e.getX(), e.getY());
|
||||
for (int i = layers.size() - 1; i >= 0; i--) {
|
||||
|
@ -832,12 +829,10 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
return;
|
||||
}
|
||||
}
|
||||
if(onLongClickListener != null && onLongClickListener.onLongPressEvent(point)){
|
||||
if (onLongClickListener != null && onLongClickListener.onLongPressEvent(point)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
|
@ -852,37 +847,35 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
PointF point = new PointF(e.getX(), e.getY());
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("On click event "+ point.x + " " + point.y); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("On click event " + point.x + " " + point.y); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
for (int i = layers.size() - 1; i >= 0; i--) {
|
||||
if (layers.get(i).onTouchEvent(point)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(onClickListener != null && onClickListener.onPressEvent(point)){
|
||||
if (onClickListener != null && onClickListener.onPressEvent(point)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public LatLon getLatLonFromScreenPoint(float x, float y){
|
||||
|
||||
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(zoom, getYTile() + fy);
|
||||
double longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx);
|
||||
double latitude = MapUtils.getLatitudeFromTile(getZoom(), getYTile() + fy);
|
||||
double longitude = MapUtils.getLongitudeFromTile(getZoom(), getXTile() + fx);
|
||||
return new LatLon(latitude, longitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
LatLon l = getLatLonFromScreenPoint(e.getX(), e.getY());
|
||||
getAnimatedDraggingThread().startMoving(getLatitude(), getLongitude(),
|
||||
l.getLatitude(), l.getLongitude(), getZoom(), getZoom() + 1, getSourceTileSize(), getRotate(), true);
|
||||
getAnimatedDraggingThread().startMoving(getLatitude(), getLongitude(), l.getLatitude(), l.getLongitude(), getZoom(), getZoom() + 1,
|
||||
getSourceTileSize(), getRotate(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -895,9 +888,5 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import net.osmand.ResourceManager;
|
|||
import net.osmand.activities.EditingPOIActivity;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
|
@ -18,14 +17,12 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMenuProvider {
|
||||
// it is very slow to use with 15 level
|
||||
private static final int startZoom = 10;
|
||||
public static final int LIMIT_POI = 200;
|
||||
|
||||
|
@ -102,7 +99,6 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
pointAltUI.setAlpha(200);
|
||||
pointAltUI.setAntiAlias(true);
|
||||
resourceManager = view.getApplication().getResourceManager();
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
}
|
||||
|
||||
public int getRadiusPoi(int zoom){
|
||||
|
@ -121,22 +117,12 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
return (int) (r * dm.density);
|
||||
}
|
||||
|
||||
Rect pixRect = new Rect();
|
||||
RectF tileRect = new RectF();
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (view.getZoom() >= startZoom) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
|
||||
objects.clear();
|
||||
resourceManager.searchAmenitiesAsync(topLatitude, leftLongitude, bottomLatitude, rightLongitude, view.getZoom(), filter, objects);
|
||||
resourceManager.searchAmenitiesAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), filter, objects);
|
||||
for (Amenity o : objects) {
|
||||
int x = view.getMapXForPoint(o.getLocation().getLongitude());
|
||||
int y = view.getMapYForPoint(o.getLocation().getLatitude());
|
||||
|
|
|
@ -82,11 +82,11 @@ public class PointLocationLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (isLocationVisible(lastKnownLocation)) {
|
||||
int locationX = view.getMapXForPoint(lastKnownLocation.getLongitude());
|
||||
int locationY = view.getMapYForPoint(lastKnownLocation.getLatitude());
|
||||
int radius = MapUtils.getLengthXFromMeters(view.getFloatZoom(), view.getLatitude(), view.getLongitude(),
|
||||
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(),
|
||||
lastKnownLocation.getAccuracy(), view.getTileSize(), view.getWidth());
|
||||
|
||||
if(appMode == ApplicationMode.CAR){
|
||||
|
@ -111,7 +111,7 @@ public class PointLocationLayer implements OsmandMapLayer {
|
|||
int radiusBearing = (int) (30 * dm.density);
|
||||
if(lastKnownLocation.hasSpeed() && appMode != ApplicationMode.CAR){
|
||||
radiusBearing =
|
||||
Math.max(MapUtils.getLengthXFromMeters(view.getFloatZoom(), view.getLatitude(), view.getLongitude(),
|
||||
Math.max(MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(),
|
||||
lastKnownLocation.getSpeed(), view.getTileSize(), view.getWidth()) * 2, radiusBearing);
|
||||
radiusBearing = Math.min(radiusBearing, view.getHeight() / 4);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.graphics.Matrix;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.location.Location;
|
||||
import android.util.DisplayMetrics;
|
||||
|
@ -46,7 +47,7 @@ public class PointNavigationLayer implements OsmandMapLayer {
|
|||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if(pointToNavigate == null){
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ public class RouteInfoLayer implements OsmandMapLayer, IRouteInformationListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if(isVisible()){
|
||||
border.set(layout.getLeft() - 10 * dm.density, layout.getTop() - 4 * dm.density,
|
||||
layout.getRight() - 5 * dm.density, layout.getBottom() + 4 * dm.density);
|
||||
|
|
|
@ -58,7 +58,7 @@ public class RouteLayer implements OsmandMapLayer {
|
|||
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
path.reset();
|
||||
if (helper.hasPointsToShow()) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
@ -78,7 +78,7 @@ public class RouteLayer implements OsmandMapLayer {
|
|||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
double lat = topLatitude - bottomLatitude + 0.1;
|
||||
double lon = rightLongitude - leftLongitude + 0.1;
|
||||
helper.fillLocationsToShow(topLatitude +lat, leftLongitude - lon, bottomLatitude - lat, rightLongitude + lon, points);
|
||||
helper.fillLocationsToShow(topLatitude + lat, leftLongitude - lon, bottomLatitude - lat, rightLongitude + lon, points);
|
||||
if((System.currentTimeMillis() - time) > 80){
|
||||
Log.e(LogUtil.TAG, "Calculate route layer " + (System.currentTimeMillis() - time)); //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -8,13 +8,11 @@ import net.osmand.activities.TransportRouteHelper;
|
|||
import net.osmand.data.TransportRoute;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
|
@ -23,9 +21,7 @@ import android.widget.Toast;
|
|||
public class TransportInfoLayer implements OsmandMapLayer {
|
||||
|
||||
private final TransportRouteHelper routeHelper;
|
||||
private Rect pixRect;
|
||||
private OsmandMapTileView view;
|
||||
private RectF tileRect;
|
||||
private Paint paintInt;
|
||||
private Paint paintEnd;
|
||||
private boolean visible = true;
|
||||
|
@ -37,8 +33,6 @@ public class TransportInfoLayer implements OsmandMapLayer {
|
|||
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
this.view = view;
|
||||
pixRect = new Rect();
|
||||
tileRect = new RectF();
|
||||
dm = new DisplayMetrics();
|
||||
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
wmgr.getDefaultDisplay().getMetrics(dm);
|
||||
|
@ -65,16 +59,9 @@ public class TransportInfoLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if(routeHelper.routeIsCalculated() && visible){
|
||||
List<RouteInfoLocation> list = routeHelper.getRoute();
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
for(RouteInfoLocation l : list){
|
||||
if(l == null){
|
||||
// once l is null in list
|
||||
|
@ -100,8 +87,8 @@ public class TransportInfoLayer implements OsmandMapLayer {
|
|||
}
|
||||
if(start){
|
||||
LatLon location = st.getLocation();
|
||||
if(location.getLatitude() <= topLatitude && location.getLatitude() >= bottomLatitude &&
|
||||
location.getLongitude() >= leftLongitude && location.getLongitude() <= rightLongitude){
|
||||
if (location.getLatitude() >= latLonBounds.bottom && location.getLatitude() <= latLonBounds.top && location.getLongitude() >= latLonBounds.left
|
||||
&& location.getLongitude() <= latLonBounds.right ) {
|
||||
int x = view.getRotatedMapXForPoint(location.getLatitude(), location.getLongitude());
|
||||
int y = view.getRotatedMapYForPoint(location.getLatitude(), location.getLongitude());
|
||||
canvas.drawRect(x - getRadius(), y - getRadius(), x + getRadius(), y + getRadius(), toShow);
|
||||
|
|
|
@ -8,14 +8,12 @@ import net.osmand.R;
|
|||
import net.osmand.TransportIndexRepository;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
|
@ -41,7 +39,6 @@ public class TransportStopsLayer implements OsmandMapLayer, ContextMenuLayer.ICo
|
|||
pointAltUI.setColor(Color.rgb(0, 0, 255));
|
||||
pointAltUI.setAlpha(150);
|
||||
pointAltUI.setAntiAlias(true);
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
}
|
||||
|
||||
public TransportStop getFromPoint(PointF point){
|
||||
|
@ -116,22 +113,12 @@ public class TransportStopsLayer implements OsmandMapLayer, ContextMenuLayer.ICo
|
|||
}
|
||||
}
|
||||
|
||||
Rect pixRect = new Rect();
|
||||
RectF tileRect = new RectF();
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (view.getZoom() >= startZoom) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(),
|
||||
view.getCenterPointY(), view.getXTile(), view.getYTile(), tileRect);
|
||||
double topLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getZoom(), tileRect.right);
|
||||
|
||||
objects.clear();
|
||||
view.getApplication().getResourceManager().searchTransportAsync(topLatitude, leftLongitude, bottomLatitude, rightLongitude, view.getZoom(), objects);
|
||||
view.getApplication().getResourceManager().searchTransportAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), objects);
|
||||
int r = 3 * getRadiusPoi(view.getZoom()) / 4;
|
||||
for (TransportStop o : objects) {
|
||||
int x = view.getMapXForPoint(o.getLocation().getLongitude());
|
||||
|
|
|
@ -208,16 +208,15 @@ public class YandexTrafficLayer implements OsmandMapLayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
public void onDraw(Canvas canvas, RectF latLonBounds) {
|
||||
if (visible) {
|
||||
pixRect.set(0, 0, view.getWidth(), view.getHeight());
|
||||
double lat = MapUtils.getLatitudeFromTile(view.getFloatZoom(), view.getYTile());
|
||||
float tileY = (float) MapUtils.getTileEllipsoidNumberY(view.getFloatZoom(), lat);
|
||||
float tileY = (float) MapUtils.getTileEllipsoidNumberY(view.getZoom(), view.getLatitude());
|
||||
view.calculateTileRectangle(pixRect, view.getCenterPointX(), view.getCenterPointY(), view.getXTile(), tileY, tileRect);
|
||||
double topLat = MapUtils.getLatitudeFromEllipsoidTileY(view.getFloatZoom(), (int) tileRect.top);
|
||||
double leftLon = MapUtils.getLongitudeFromTile(view.getFloatZoom(), (int) tileRect.left);
|
||||
int x = view.getRotatedMapXForPoint(topLat, leftLon);
|
||||
int y = view.getRotatedMapYForPoint(topLat, leftLon);
|
||||
double topLat = MapUtils.getLatitudeFromEllipsoidTileY(view.getZoom(), (int) tileRect.top);
|
||||
double leftLon = MapUtils.getLongitudeFromTile(view.getZoom(), (int) tileRect.left);
|
||||
int x = view.getMapXForPoint(leftLon);
|
||||
int y = view.getMapYForPoint(topLat);
|
||||
checkedCachedImages(view.getZoom());
|
||||
float right = FloatMath.ceil(tileRect.right);
|
||||
float bottom = FloatMath.ceil(tileRect.bottom);
|
||||
|
|
Loading…
Reference in a new issue