improve rotation
git-svn-id: https://osmand.googlecode.com/svn/trunk@502 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
428fab7854
commit
55cc4ab189
11 changed files with 410 additions and 161 deletions
|
@ -8,7 +8,7 @@ package net.osmand;
|
|||
public class ToDoConstants {
|
||||
|
||||
// TODO swing
|
||||
// ! 12. Reinvent UI of swing app (remove Region object and clear other MapObject) use indexes to show results
|
||||
// !!! 12. Reinvent UI of swing app (remove Region object and clear other MapObject) use indexes to show results
|
||||
|
||||
// TODO max 87
|
||||
// ! 81. Add some objects to POI category (1) to add them into OSM 2) to help navigation)
|
||||
|
@ -20,23 +20,31 @@ public class ToDoConstants {
|
|||
// 89. Transport redesign UI (enable run from context menu, switch go to goal/not) !
|
||||
// 90. Use Junidecode library on the client for fast english translation
|
||||
|
||||
// 91. Invent binary format (minimize disk space, maximize speed)
|
||||
// 92. Replace poi index with standard map index and unify POI categories
|
||||
// 93. Implement multytype vector objects (?) - building with fence, road & tram ... (binary format)
|
||||
|
||||
// TODO small improvements for release :
|
||||
// 1. If select vector map, notice if there are no loaded maps.
|
||||
|
||||
// TODO Improvements:
|
||||
// TODO Improvements :
|
||||
// 1! VELCOM
|
||||
// 2. rotate map gps without location
|
||||
// +2. rotate map gps without location
|
||||
// 4. recalculating route when location is far from ! (error)
|
||||
// 5. keyboard (issue 43 )?
|
||||
// 6. Do not upload empty files (transport, poi... ).
|
||||
// 7. Implement auto-delete from site (done, should be ported from C#)
|
||||
// 8. In all places verify to use float lat/lon improve disk space for indexes !!!
|
||||
// 13! Support multiple database for map rendering
|
||||
//+ 15. Draw layers -> icons -> text. See intersects of double streets.
|
||||
|
||||
// +13! Support multiple database for map rendering
|
||||
// 16. Internet access bits
|
||||
// 17. Implement multipolygons to polygons
|
||||
// TODO colors for road trunk and motorway
|
||||
// 17. Implement multipolygons to polygons (!?) + coastline
|
||||
// 18. Fix loading map data in rotated mode (check properly boundaries)
|
||||
// 20. Add text to rendering (area, point, polyline)
|
||||
// 21. Shield, ref.
|
||||
// 22. Verify all POI has a point_type (in order to search them)
|
||||
|
||||
// 19. colors for road trunk and motorway
|
||||
// 12. Fix : find proper location for streets ! centralize them (when create index)?
|
||||
|
||||
// TODO Check
|
||||
|
|
|
@ -418,17 +418,17 @@ public class DataIndexWriter {
|
|||
}
|
||||
|
||||
public static void insertMapRenderObjectIndex(Map<PreparedStatement, Integer> statements,
|
||||
PreparedStatement mapStat, PreparedStatement mapWayLocationsStat, Entity e, String name,
|
||||
PreparedStatement mapStat, PreparedStatement mapWayLocationsStat, /*RTree mapTree, */Entity e, String name,
|
||||
long id, int type, boolean inversePath, boolean writeAsPoint, int batchSize) throws SQLException {
|
||||
assert IndexMapRenderObject.values().length == 4;
|
||||
if(e instanceof Relation){
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
boolean init = false;
|
||||
// int minX = Integer.MAX_VALUE;
|
||||
// int maxX = 0;
|
||||
// int minY = Integer.MAX_VALUE;
|
||||
// int maxY = 0;
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = 0;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxY = 0;
|
||||
double minLat = 180;
|
||||
double maxLat = -180;
|
||||
double minLon = 360;
|
||||
|
@ -458,10 +458,10 @@ public class DataIndexWriter {
|
|||
maxLat = Math.max(maxLat, n.getLatitude());
|
||||
minLon = Math.min(minLon, n.getLongitude());
|
||||
maxLon = Math.max(maxLon, n.getLongitude());
|
||||
// minX = Math.min(minX, x);
|
||||
// maxX = Math.max(maxX, x);
|
||||
// minY = Math.min(minY, y);
|
||||
// maxY = Math.max(maxY, y);
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxY = Math.max(maxY, y);
|
||||
init = true;
|
||||
Algoritms.putIntToBytes(bytes, offset, y);
|
||||
offset += 4;
|
||||
|
@ -475,6 +475,17 @@ public class DataIndexWriter {
|
|||
mapStat.setString(IndexMapRenderObject.NAME.ordinal() + 1, name);
|
||||
mapStat.setBytes(IndexMapRenderObject.NODES.ordinal() + 1, bytes);
|
||||
addBatch(statements, mapStat);
|
||||
|
||||
//
|
||||
// try {
|
||||
// mapTree.insert(new LeafElement(new Rect(minX, minY, maxX, maxY), id));
|
||||
// } catch (RTreeInsertException e1) {
|
||||
// // TODO
|
||||
// e1.printStackTrace();
|
||||
// } catch (IllegalValueException e1) {
|
||||
// // TODO
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
|
||||
mapWayLocationsStat.setLong(1, id);
|
||||
mapWayLocationsStat.setFloat(2, (float) minLon);
|
||||
|
|
|
@ -132,6 +132,8 @@ public class IndexCreator {
|
|||
private PreparedStatement mapLocsStatLevel0;
|
||||
private PreparedStatement mapLocsStatLevel1;
|
||||
private PreparedStatement mapLocsStatLevel2;
|
||||
// private RTree mapTree;
|
||||
|
||||
private Map<Long, List<Way>> lowLevelWaysSt = new LinkedHashMap<Long, List<Way>>();
|
||||
private Map<Long, List<Way>> lowLevelWaysEnd = new LinkedHashMap<Long, List<Way>>();
|
||||
|
||||
|
@ -1192,7 +1194,7 @@ public class IndexCreator {
|
|||
|
||||
|
||||
if (!skip) {
|
||||
DataIndexWriter.insertMapRenderObjectIndex(pStatements, mapObjStat, mapLocations, e,
|
||||
DataIndexWriter.insertMapRenderObjectIndex(pStatements, mapObjStat, mapLocations, /*mapTree, */e,
|
||||
MapRenderingTypes.getEntityName(e), id, type, false, point, BATCH_SIZE);
|
||||
}
|
||||
}
|
||||
|
@ -1313,6 +1315,12 @@ public class IndexCreator {
|
|||
mapLocsStatLevel0 = DataIndexWriter.createStatementMapWaysLocationsInsert(mapConnection);
|
||||
mapLocsStatLevel1 = DataIndexWriter.createStatementMapWaysLocationsInsertLevel2(mapConnection);
|
||||
mapLocsStatLevel2 = DataIndexWriter.createStatementMapWaysLocationsInsertLevel3(mapConnection);
|
||||
// try {
|
||||
// mapTree = new RTree(mapFile.getAbsolutePath()+"_ind");
|
||||
// } catch (RTreeException e) {
|
||||
// // TODO
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
pStatements.put(mapObjStat, 0);
|
||||
pStatements.put(mapLocsStatLevel0, 0);
|
||||
pStatements.put(mapLocsStatLevel1, 0);
|
||||
|
@ -1464,7 +1472,6 @@ public class IndexCreator {
|
|||
}
|
||||
// 5. writing low level maps
|
||||
if(indexMap){
|
||||
// TODO level !!!
|
||||
for(Long l : lowLevelWaysSt.keySet()){
|
||||
for(Way w : lowLevelWaysSt.get(l)){
|
||||
int level = (int) (w.getId() & 3);
|
||||
|
@ -1512,6 +1519,13 @@ public class IndexCreator {
|
|||
if (mapConnection != null) {
|
||||
mapConnection.commit();
|
||||
mapConnection.close();
|
||||
// try {
|
||||
// mapTree.flush();
|
||||
// } catch (RTreeException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
if (lastModifiedDate != null) {
|
||||
mapFile.setLastModified(lastModifiedDate);
|
||||
}
|
||||
|
@ -1543,7 +1557,7 @@ public class IndexCreator {
|
|||
st.close();
|
||||
dbConn.close();
|
||||
}
|
||||
// TODO steps
|
||||
|
||||
public static void main(String[] args) throws IOException, SAXException, SQLException {
|
||||
|
||||
IndexCreator creator = new IndexCreator(new File("e:/Information/OSM maps/osmand/"));
|
||||
|
@ -1551,13 +1565,28 @@ public class IndexCreator {
|
|||
|
||||
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb"));
|
||||
// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null);
|
||||
|
||||
|
||||
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/belarus_nodes.tmp.odb"));
|
||||
// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus_2010_09_03.osm.bz2"), new ConsoleProgressImplementation(3), null);
|
||||
|
||||
|
||||
creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/ams.tmp.odb"));
|
||||
creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/ams_part_map.osm"), new ConsoleProgressImplementation(3), null);
|
||||
|
||||
/*try {
|
||||
// RTree rtree = new RTree("e:/Information/OSM maps/osmand/Belarus_2010_09_03.map.odb_ind");
|
||||
// new Pack().packTree(rtree, "e:/Information/OSM maps/osmand/pack.ind");
|
||||
RTree rtree = new RTree("e:/Information/OSM maps/osmand/pack.ind");
|
||||
long rootIndex = rtree.getFileHdr().getRootIndex();
|
||||
int s = calculateSize(rtree.getReadNode(rootIndex), rtree, "!-");
|
||||
System.out.println(s);
|
||||
} catch (RTreeException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// download base
|
||||
/* MapTileDownloader instance = MapTileDownloader.getInstance();
|
||||
|
@ -1583,5 +1612,27 @@ public class IndexCreator {
|
|||
}*/
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
public static int calculateSize(rtree.Node n, RTree r, String level){
|
||||
Element[] e = n.getAllElements();
|
||||
int exc = 0; //20 + (169 - n.getTotalElements()) * 24;
|
||||
for(int i=0; i< n.getTotalElements(); i++){
|
||||
if(e[i].getElementType() == rtree.Node.LEAF_NODE){
|
||||
exc += 1;
|
||||
} else {
|
||||
// exc += 1;
|
||||
|
||||
long ptr = ((NonLeafElement) e[i]).getPtr();
|
||||
try {
|
||||
rtree.Node ns = r.getReadNode(ptr);
|
||||
System.out.println(level + " " + ns.getTotalElements());
|
||||
exc += calculateSize(ns, r, level +"-");
|
||||
} catch (RTreeException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return exc;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ public class MapRenderingTypes {
|
|||
public final static int MASK_4 = (1 << 4) - 1;
|
||||
public final static int MASK_10 = (1 << 10) - 1;
|
||||
|
||||
public final static String REF_CHAR = ((char)0x0019)+""; //$NON-NLS-1$
|
||||
|
||||
|
||||
// TODO !!! add others facilities to all types
|
||||
// TODO Internet access bits for point
|
||||
|
@ -422,9 +424,16 @@ public class MapRenderingTypes {
|
|||
return (attr & 3) == 1;
|
||||
}
|
||||
|
||||
public static String getEntityName(Entity e){
|
||||
public static String getEntityName(Entity e) {
|
||||
if (e.getTag(OSMTagKey.REF) != null) {
|
||||
String ref = e.getTag(OSMTagKey.REF);
|
||||
if (ref.length() > 5 && ref.indexOf('_') != -1) {
|
||||
ref = ref.substring(0, ref.indexOf('_'));
|
||||
}
|
||||
return REF_CHAR + ref;
|
||||
}
|
||||
String name = e.getTag(OSMTagKey.NAME);
|
||||
if(name == null){
|
||||
if (name == null) {
|
||||
name = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER);
|
||||
}
|
||||
return name;
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.content.Context;
|
|||
import android.database.sqlite.SQLiteException;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Environment;
|
||||
|
||||
/**
|
||||
|
@ -527,11 +528,13 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////// Working with map ////////////////////////////////////////////////
|
||||
public void updateRendererIfNeeded(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, float rotate){
|
||||
if(!renderer.updateMapIsNotNeeded(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, rotate)){
|
||||
asyncLoadingTiles.requestToLoadMap(
|
||||
new MapLoadRequest(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, rotate));
|
||||
}
|
||||
public boolean updateRenderedMapNeeded(RectF tilesRect, int zoom, float rotate){
|
||||
return renderer.updateMapIsNeeded(tilesRect, zoom, rotate);
|
||||
}
|
||||
|
||||
public void updateRendererMap(RectF tileRect, RectF boundsTileRect, int zoom, float rotate){
|
||||
asyncLoadingTiles.requestToLoadMap(
|
||||
new MapLoadRequest(tileRect, boundsTileRect, zoom, rotate));
|
||||
}
|
||||
|
||||
public MapRenderRepositories getRenderer() {
|
||||
|
@ -677,20 +680,15 @@ public class ResourceManager {
|
|||
}
|
||||
|
||||
private static class MapLoadRequest {
|
||||
public final double topLatitude;
|
||||
public final double bottomLatitude;
|
||||
public final double leftLongitude;
|
||||
public final double rightLongitude;
|
||||
public final RectF tileRect;
|
||||
public final RectF boundsTileRect;
|
||||
public final int zoom;
|
||||
public final float rotate;
|
||||
|
||||
public MapLoadRequest(double topLatitude, double leftLongitude,
|
||||
double bottomLatitude, double rightLongitude, int zoom, float rotate) {
|
||||
public MapLoadRequest(RectF tileRect, RectF boundsTileRect, int zoom, float rotate) {
|
||||
super();
|
||||
this.bottomLatitude = bottomLatitude;
|
||||
this.leftLongitude = leftLongitude;
|
||||
this.rightLongitude = rightLongitude;
|
||||
this.topLatitude = topLatitude;
|
||||
this.tileRect = tileRect;
|
||||
this.boundsTileRect = boundsTileRect;
|
||||
this.zoom = zoom;
|
||||
this.rotate = rotate;
|
||||
}
|
||||
|
@ -735,7 +733,7 @@ public class ResourceManager {
|
|||
} else if(req instanceof MapLoadRequest){
|
||||
if(!mapLoaded){
|
||||
MapLoadRequest r = (MapLoadRequest) req;
|
||||
renderer.loadMap(r.topLatitude, r.leftLongitude, r.bottomLatitude, r.rightLongitude, r.zoom, r.rotate);
|
||||
renderer.loadMap(r.tileRect, r.boundsTileRect, r.zoom, r.rotate);
|
||||
mapLoaded = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -382,7 +382,6 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -412,14 +411,14 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
|
||||
|
||||
private void registerUnregisterSensor(Location location){
|
||||
boolean show = currentShowingAngle || currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS;
|
||||
boolean show = (currentShowingAngle && location != null) || currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS;
|
||||
// show point view only if gps enabled
|
||||
if (sensorRegistered && (location == null || !show)) {
|
||||
if (sensorRegistered && !show) {
|
||||
Log.d(LogUtil.TAG, "Disable sensor"); //$NON-NLS-1$
|
||||
((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this);
|
||||
sensorRegistered = false;
|
||||
locationLayer.setHeading(null);
|
||||
} else if (!sensorRegistered && (location != null && show)) {
|
||||
} else if (!sensorRegistered && show) {
|
||||
Log.d(LogUtil.TAG, "Enable sensor"); //$NON-NLS-1$
|
||||
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
|
||||
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
|
||||
|
@ -671,6 +670,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
locationLayer.setAppMode(OsmandSettings.getApplicationMode(this));
|
||||
routingHelper.setAppMode(OsmandSettings.getApplicationMode(this));
|
||||
mapView.setMapPosition(OsmandSettings.getPositionOnMap(this));
|
||||
registerUnregisterSensor(getLastKnownLocation());
|
||||
updateLayers();
|
||||
}
|
||||
|
||||
|
@ -736,6 +736,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
}
|
||||
|
||||
updateApplicationModeSettings();
|
||||
|
||||
|
||||
favoritesLayer.reloadFavorites(this);
|
||||
poiMapLayer.setFilter(OsmandSettings.getPoiFilterForMap(this, (OsmandApplication) getApplication()));
|
||||
|
|
|
@ -5,42 +5,51 @@ import java.sql.Connection;
|
|||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.osm.MapRenderObject;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
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 {
|
||||
|
||||
private final static Log log = LogUtil.getLog(MapRenderRepositories.class);
|
||||
private final Context context;
|
||||
private Connection conn;
|
||||
private PreparedStatement pStatement;
|
||||
private PreparedStatement pStatement2;
|
||||
private PreparedStatement pStatement3;
|
||||
private Map<String, Connection> files = new LinkedHashMap<String, Connection>();
|
||||
private Map<Connection, RectF> connections = new LinkedHashMap<Connection, RectF>();
|
||||
private Map<Connection, PreparedStatement> pZoom0 = new LinkedHashMap<Connection, PreparedStatement>();
|
||||
private Map<Connection, PreparedStatement> pZoom1 = new LinkedHashMap<Connection, PreparedStatement>();
|
||||
private Map<Connection, PreparedStatement> pZoom2 = new LinkedHashMap<Connection, PreparedStatement>();
|
||||
private OsmandRenderer renderer;
|
||||
|
||||
private double cTopLatitude;
|
||||
private double cBottomLatitude;
|
||||
private double cLeftLongitude;
|
||||
private double cRightLongitude;
|
||||
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
|
||||
private List<MapRenderObject> cObjects = new LinkedList<MapRenderObject>();
|
||||
private RectF cachedWaysLoc = new RectF();
|
||||
private float cachedRotate = 0;
|
||||
private Bitmap bmp;
|
||||
|
||||
|
||||
|
@ -54,17 +63,24 @@ public class MapRenderRepositories {
|
|||
return context;
|
||||
}
|
||||
|
||||
private RectF getBoundsForIndex(Statement stat, String tableName) throws SQLException{
|
||||
ResultSet rs = stat.executeQuery("SELECT MIN(minLon), MAX(maxLat), MAX(maxLon), MIN(minLat) FROM " + IndexConstants.indexMapLocationsTable); //$NON-NLS-1$
|
||||
RectF bounds = new RectF();
|
||||
if(rs.next()){
|
||||
bounds.set(rs.getFloat(1), rs.getFloat(2), rs.getFloat(3), rs.getFloat(4));
|
||||
}
|
||||
rs.close();
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
public boolean initializeNewResource(final IProgress progress, File file) {
|
||||
long start = System.currentTimeMillis();
|
||||
Connection conn = null;
|
||||
if(files.containsKey(file.getAbsolutePath())){
|
||||
closeConnection(files.get(file.getAbsolutePath()), file.getAbsolutePath());
|
||||
}
|
||||
try {
|
||||
if (conn != null) {
|
||||
// close previous db
|
||||
conn.close();
|
||||
conn = null;
|
||||
pStatement = null;
|
||||
pStatement2 = null;
|
||||
pStatement3 = null;
|
||||
}
|
||||
try {
|
||||
Class.forName("org.sqlite.JDBC"); //$NON-NLS-1$
|
||||
} catch (Exception e) {
|
||||
|
@ -72,9 +88,9 @@ public class MapRenderRepositories {
|
|||
return false;
|
||||
}
|
||||
conn = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath()); //$NON-NLS-1$
|
||||
pStatement = conn.prepareStatement(loadMapQuery);
|
||||
pStatement2 = conn.prepareStatement(loadMapQuery2);
|
||||
pStatement3 = conn.prepareStatement(loadMapQuery3);
|
||||
PreparedStatement pStatement = conn.prepareStatement(loadMapQuery);
|
||||
PreparedStatement pStatement2 = conn.prepareStatement(loadMapQuery2);
|
||||
PreparedStatement pStatement3 = conn.prepareStatement(loadMapQuery3);
|
||||
Statement stat = conn.createStatement();
|
||||
ResultSet rs = stat.executeQuery("PRAGMA user_version"); //$NON-NLS-1$
|
||||
int v = rs.getInt(1);
|
||||
|
@ -82,8 +98,16 @@ public class MapRenderRepositories {
|
|||
if(v != IndexConstants.MAP_TABLE_VERSION){
|
||||
return false;
|
||||
}
|
||||
RectF bounds = foundBounds(stat);
|
||||
|
||||
|
||||
stat.close();
|
||||
|
||||
connections.put(conn, bounds);
|
||||
files.put(file.getAbsolutePath(), conn);
|
||||
pZoom0.put(conn, pStatement);
|
||||
pZoom1.put(conn, pStatement2);
|
||||
pZoom2.put(conn, pStatement3);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("No connection", e); //$NON-NLS-1$
|
||||
if(conn != null){
|
||||
|
@ -100,6 +124,49 @@ public class MapRenderRepositories {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private RectF foundBounds(Statement stat) throws SQLException {
|
||||
String metaTable = "loc_meta_locations"; //$NON-NLS-1$
|
||||
ResultSet rs = stat.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='"+metaTable+"'"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
boolean dbExist = rs.next();
|
||||
rs.close();
|
||||
boolean found = false;
|
||||
boolean write = true;
|
||||
RectF bounds = new RectF();
|
||||
if(dbExist){
|
||||
rs = stat.executeQuery("SELECT MAX_LAT, MIN_LON, MIN_LAT, MAX_LON FROM " +metaTable); //$NON-NLS-1$
|
||||
if(rs.next()){
|
||||
bounds.set(rs.getFloat(2), rs.getFloat(1), rs.getFloat(4), rs.getFloat(3));
|
||||
found = true;
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
rs.close();
|
||||
} else {
|
||||
try {
|
||||
stat.execute("CREATE TABLE " + metaTable + " (MAX_LAT DOUBLE, MIN_LON DOUBLE, MIN_LAT DOUBLE, MAX_LON DOUBLE)"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
} catch (RuntimeException e) {
|
||||
// case when database is in readonly mode
|
||||
write = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
bounds = getBoundsForIndex(stat, IndexConstants.indexMapLocationsTable);
|
||||
if(bounds.left == bounds.right || bounds.bottom == bounds.top){
|
||||
bounds = getBoundsForIndex(stat, IndexConstants.indexMapLocationsTable2);
|
||||
if(bounds.left == bounds.right || bounds.bottom == bounds.top){
|
||||
bounds = getBoundsForIndex(stat, IndexConstants.indexMapLocationsTable3);
|
||||
}
|
||||
}
|
||||
if (write) {
|
||||
stat.execute("INSERT INTO " + metaTable + " VALUES ("+Double.toString(bounds.top)+ ", "+Double.toString(bounds.left)+ ", " + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
Double.toString(bounds.bottom)+ ", "+Double.toString(bounds.right)+ ")"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
// if cache was changed different instance will be returned
|
||||
|
@ -107,41 +174,46 @@ public class MapRenderRepositories {
|
|||
return cachedWaysLoc;
|
||||
}
|
||||
|
||||
public float getCachedRotate() {
|
||||
return cachedRotate;
|
||||
}
|
||||
|
||||
protected void closeConnection(Connection c, String file){
|
||||
files.remove(c);
|
||||
connections.remove(c);
|
||||
pZoom0.remove(c);
|
||||
pZoom1.remove(c);
|
||||
pZoom2.remove(c);
|
||||
try {
|
||||
c.close();
|
||||
} catch (java.sql.SQLException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllResources(){
|
||||
clearCache();
|
||||
if(conn != null){
|
||||
try {
|
||||
conn.close();
|
||||
} catch (java.sql.SQLException e) {
|
||||
}
|
||||
conn = null;
|
||||
pStatement = null;
|
||||
pStatement2 = null;
|
||||
pStatement3 = null;
|
||||
for(String f : files.keySet()){
|
||||
closeConnection(files.get(f), f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if no need to reevaluate map
|
||||
*/
|
||||
public boolean updateMapIsNotNeeded(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, float rotate){
|
||||
if (conn == null) {
|
||||
return true;
|
||||
public boolean updateMapIsNeeded(RectF tileRect, int zoom, float rotate){
|
||||
if (connections.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean inside = insideBox(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom);
|
||||
boolean inside = insideBox(tileRect.top, tileRect.left, tileRect.bottom, tileRect.right, zoom);
|
||||
if(rotate < 0){
|
||||
rotate += 360;
|
||||
}
|
||||
|
||||
return inside && Math.abs(rotate - cRotate) < 30;
|
||||
return !inside || Math.abs(rotate - cRotate) > 30;
|
||||
|
||||
}
|
||||
|
||||
private boolean insideBox(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom) {
|
||||
boolean inside = cTopLatitude >= topLatitude && cLeftLongitude <= leftLongitude && cRightLongitude >= rightLongitude
|
||||
&& cBottomLatitude <= bottomLatitude && cZoom == zoom;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -165,15 +237,19 @@ public class MapRenderRepositories {
|
|||
" IN (SELECT id FROM "+IndexConstants.indexMapLocationsTable3 + //$NON-NLS-1$
|
||||
" WHERE ? < maxLat AND ? > minLat AND maxLon > ? AND minLon < ?)"; //$NON-NLS-1$
|
||||
|
||||
public synchronized void loadMap(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, float rotate) {
|
||||
boolean inside = insideBox(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom);
|
||||
public synchronized void loadMap(RectF tileRect, RectF boundsTileRect, int zoom, float rotate) {
|
||||
// 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) {
|
||||
// that usable for portrait view
|
||||
cBottomLatitude = bottomLatitude - (topLatitude - bottomLatitude) / 2;
|
||||
cTopLatitude = topLatitude + (topLatitude - bottomLatitude) / 2;
|
||||
cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude);
|
||||
cRightLongitude = rightLongitude + (rightLongitude - leftLongitude);
|
||||
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;
|
||||
|
||||
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
|
||||
|
@ -181,72 +257,102 @@ public class MapRenderRepositories {
|
|||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
PreparedStatement statement = null;
|
||||
if(zoom >= 15){
|
||||
statement = pStatement;
|
||||
} else if(zoom >= 10){
|
||||
statement = pStatement2;
|
||||
} else if(zoom >= 6) {
|
||||
statement = pStatement3;
|
||||
}
|
||||
|
||||
|
||||
if (statement == null || conn == null) {
|
||||
if (connections.isEmpty()) {
|
||||
cObjects = new ArrayList<MapRenderObject>();
|
||||
// keep old results
|
||||
return;
|
||||
}
|
||||
try {
|
||||
statement.setDouble(1, cBottomLatitude);
|
||||
statement.setDouble(2, cTopLatitude);
|
||||
statement.setDouble(3, cLeftLongitude);
|
||||
statement.setDouble(4, cRightLongitude);
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
int count = 0;
|
||||
List<MapRenderObject> local = new ArrayList<MapRenderObject>();
|
||||
try {
|
||||
int count = 0;
|
||||
while (result.next()) {
|
||||
long id = result.getLong(1);
|
||||
MapRenderObject obj = new MapRenderObject(id);
|
||||
obj.setData(result.getBytes(2));
|
||||
obj.setName(result.getString(3));
|
||||
obj.setType(result.getInt(4));
|
||||
count++;
|
||||
local.add(obj);
|
||||
Set<Long> ids = new LinkedHashSet<Long>();
|
||||
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);
|
||||
}
|
||||
statement.setDouble(1, cBottomLatitude);
|
||||
statement.setDouble(2, cTopLatitude);
|
||||
statement.setDouble(3, cLeftLongitude);
|
||||
statement.setDouble(4, cRightLongitude);
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
cObjects = local;
|
||||
log.info(String
|
||||
.format("Search has been done in %s ms. %s results were found.", System.currentTimeMillis() - now, count)); //$NON-NLS-1$
|
||||
} finally {
|
||||
result.close();
|
||||
|
||||
try {
|
||||
while (result.next()) {
|
||||
long id = result.getLong(1);
|
||||
if(ids.contains(id)){
|
||||
// do not add object twice
|
||||
continue;
|
||||
}
|
||||
ids.add(id);
|
||||
MapRenderObject obj = new MapRenderObject(id);
|
||||
obj.setData(result.getBytes(2));
|
||||
obj.setName(result.getString(3));
|
||||
obj.setType(result.getInt(4));
|
||||
count++;
|
||||
local.add(obj);
|
||||
}
|
||||
|
||||
} finally {
|
||||
result.close();
|
||||
}
|
||||
}
|
||||
cObjects = local;
|
||||
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)cLeftLongitude, (float)cTopLatitude, (float)cRightLongitude, (float)cBottomLatitude);
|
||||
Bitmap bmp = renderer.generateNewBitmap(newLoc, cObjects, cZoom, cRotate);
|
||||
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);
|
||||
Bitmap bmp = renderer.generateNewBitmap(width, height, tileRect.left, tileRect.top, cObjects, cZoom, cRotate);
|
||||
Bitmap oldBmp = this.bmp;
|
||||
this.bmp = bmp;
|
||||
cachedWaysLoc = newLoc;
|
||||
cachedRotate = cRotate;
|
||||
if(oldBmp != null){
|
||||
oldBmp.recycle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
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();
|
||||
cBottomLatitude = cLeftLongitude = cRightLongitude = cTopLatitude = cRotate = cZoom = 0;
|
||||
cBottomY = cLeftX = cRightX = cTopY = cRotate = cZoom = 0;
|
||||
if(bmp != null){
|
||||
bmp.recycle();
|
||||
bmp = null;
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.util.Map;
|
|||
import net.osmand.LogUtil;
|
||||
import net.osmand.osm.MapRenderObject;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -41,9 +40,14 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
|
||||
private TextPaint paintText;
|
||||
private Paint paint;
|
||||
|
||||
private Paint paintShield;
|
||||
|
||||
private Paint paintFillEmpty;
|
||||
private Paint paintIcon;
|
||||
private float[] hsv = new float[3];
|
||||
|
||||
public static final int TILE_SIZE = 256;
|
||||
|
||||
/// Colors
|
||||
private int clFillScreen = Color.rgb(241, 238, 232);
|
||||
|
@ -66,6 +70,7 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
int textColor = Color.BLACK;
|
||||
int textShadow = 0;
|
||||
int textWrap = 0;
|
||||
boolean shield = false;
|
||||
}
|
||||
|
||||
private static class IconDrawInfo {
|
||||
|
@ -78,14 +83,12 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
List<TextDrawInfo> textToDraw = new ArrayList<TextDrawInfo>();
|
||||
List<IconDrawInfo> iconsToDraw = new ArrayList<IconDrawInfo>();
|
||||
float leftX;
|
||||
float rightX;
|
||||
float bottomY;
|
||||
float topY;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
int zoom;
|
||||
float rotate;
|
||||
float cosRotate;
|
||||
float sinRotate;
|
||||
float tileDivisor;
|
||||
|
||||
// debug purpose
|
||||
|
@ -94,6 +97,8 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
|
||||
// use to calculate points
|
||||
PointF tempPoint = new PointF();
|
||||
float cosRotate;
|
||||
float sinRotate;
|
||||
|
||||
|
||||
// polyline props
|
||||
|
@ -166,6 +171,10 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
paintShield = new Paint();
|
||||
paintShield.setAntiAlias(true);
|
||||
|
||||
|
||||
paintFillEmpty = new Paint();
|
||||
paintFillEmpty.setStyle(Style.FILL);
|
||||
paintFillEmpty.setColor(clFillScreen);
|
||||
|
@ -202,30 +211,30 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
|
||||
|
||||
|
||||
public Bitmap generateNewBitmap(RectF objectLoc, List<MapRenderObject> objects, int zoom, float rotate) {
|
||||
public Bitmap generateNewBitmap(int width, int height, float leftTileX, float topTileY,
|
||||
List<MapRenderObject> objects, int zoom, float rotate) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Collections.sort(objects, this);
|
||||
Bitmap bmp = null;
|
||||
if (objects != null && !objects.isEmpty() && objectLoc.width() != 0f && objectLoc.height() != 0f) {
|
||||
if (objects != null && !objects.isEmpty() && width > 0 && height > 0) {
|
||||
// init rendering context
|
||||
RenderingContext rc = new RenderingContext();
|
||||
rc.leftX = (float) MapUtils.getTileNumberX(zoom, objectLoc.left);
|
||||
rc.rightX = (float) MapUtils.getTileNumberX(zoom, objectLoc.right);
|
||||
rc.topY = (float) MapUtils.getTileNumberY(zoom, objectLoc.top);
|
||||
rc.bottomY = (float) MapUtils.getTileNumberY(zoom, objectLoc.bottom);
|
||||
rc.leftX = leftTileX;
|
||||
rc.topY = topTileY;
|
||||
rc.zoom = zoom;
|
||||
rc.rotate = rotate;
|
||||
rc.width = width;
|
||||
rc.height = height;
|
||||
rc.tileDivisor = (int) (1 << (31 - zoom));
|
||||
rc.cosRotate = FloatMath.cos((float) Math.toRadians(rotate));
|
||||
rc.sinRotate = FloatMath.sin((float) Math.toRadians(rotate));
|
||||
rc.tileDivisor = (int) (1 << (31 - zoom));
|
||||
bmp = Bitmap.createBitmap(width, height, Config.RGB_565);
|
||||
|
||||
bmp = Bitmap.createBitmap((int) ((rc.rightX - rc.leftX) * 256), (int) ((rc.bottomY - rc.topY) * 256), Config.RGB_565);
|
||||
Canvas cv = new Canvas(bmp);
|
||||
cv.drawRect(0, 0, bmp.getWidth(), bmp.getHeight(), paintFillEmpty);
|
||||
cv.rotate(-rotate);
|
||||
for (MapRenderObject w : objects) {
|
||||
draw(w, cv, rc);
|
||||
for (MapRenderObject o : objects) {
|
||||
draw(o, cv, rc);
|
||||
}
|
||||
for(IconDrawInfo icon : rc.iconsToDraw){
|
||||
if(icon.resId != 0){
|
||||
|
@ -256,7 +265,8 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
paintText.setColor(text.textColor);
|
||||
RectF bounds = new RectF();
|
||||
float mes = paintText.measureText(text.text);
|
||||
if((text.pathRotate > 45 && text.pathRotate < 135) || (text.pathRotate > 225 && text.pathRotate < 315)){
|
||||
if(text.drawOnPath == null ||
|
||||
(text.pathRotate > 45 && text.pathRotate < 135) || (text.pathRotate > 225 && text.pathRotate < 315)){
|
||||
bounds.set(text.centerX - mes / 2, text.centerY - 3 * text.textSize / 2,
|
||||
text.centerX + mes / 2, text.centerY + 3 * text.textSize / 2);
|
||||
} else {
|
||||
|
@ -274,8 +284,25 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
}
|
||||
}
|
||||
boundsIntersect.add(bounds);
|
||||
paintText.setFakeBoldText(false);
|
||||
if(text.drawOnPath != null){
|
||||
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
|
||||
} else if(text.shield){
|
||||
bounds.set(text.centerX - mes / 2 - 4, text.centerY - text.textSize,
|
||||
text.centerX + mes / 2 + 4, text.centerY + text.textSize / 2);
|
||||
paintShield.setStyle(Style.STROKE);
|
||||
paintShield.setColor(Color.WHITE);
|
||||
paintShield.setStrokeWidth(3);
|
||||
cv.drawOval(bounds, paintShield);
|
||||
|
||||
paintShield.setStyle(Style.FILL);
|
||||
Color.colorToHSV(paintText.getColor(), hsv);
|
||||
hsv[2] *= 0.85;
|
||||
paintShield.setColor(Color.HSVToColor(hsv));
|
||||
cv.drawOval(bounds, paintShield);
|
||||
paintText.setFakeBoldText(true);
|
||||
paintText.setColor(Color.WHITE);
|
||||
cv.drawText(text.text, text.centerX, text.centerY + 3, paintText);
|
||||
} else {
|
||||
cv.drawText(text.text, text.centerX, text.centerY, paintText);
|
||||
}
|
||||
|
@ -314,14 +341,18 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
rc.pointCount ++;
|
||||
float tx = o.getPoint31XTile(ind) / rc.tileDivisor;
|
||||
float ty = o.getPoint31YTile(ind) / rc.tileDivisor;
|
||||
if(tx >= rc.leftX && tx <= rc.rightX && ty >= rc.topY && ty <= rc.bottomY){
|
||||
rc.pointInsideCount++;
|
||||
}
|
||||
float dTileX = tx - rc.leftX;
|
||||
float dTileY = ty - rc.topY;
|
||||
float x = (rc.cosRotate * dTileX - rc.sinRotate * dTileY) * 256f ;
|
||||
float y = (rc.sinRotate * dTileX + rc.cosRotate * dTileY) * 256f ;
|
||||
float x = (rc.cosRotate * dTileX - rc.sinRotate * dTileY) * TILE_SIZE ;
|
||||
float y = (rc.sinRotate * dTileX + rc.cosRotate * dTileY) * TILE_SIZE ;
|
||||
rc.tempPoint.set(x, y);
|
||||
// rc.tempPoint.set(dTileX * TILE_SIZE, dTileY * TILE_SIZE);
|
||||
if(rc.tempPoint.x >= 0 && rc.tempPoint.x < rc.width &&
|
||||
rc.tempPoint.y >= 0 && rc.tempPoint.y < rc.height){
|
||||
rc.pointInsideCount++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return rc.tempPoint;
|
||||
}
|
||||
|
@ -605,6 +636,17 @@ public class OsmandRenderer implements Comparator<MapRenderObject> {
|
|||
text.textSize = w;
|
||||
text.vOffset = rc.main.strokeWidth / 2 - 1;
|
||||
rc.textToDraw.add(text);
|
||||
if(text.text.startsWith(MapRenderingTypes.REF_CHAR)){
|
||||
if(text.text.length() > 5){
|
||||
text.text = text.text.substring(1, 5);
|
||||
} else {
|
||||
text.text = text.text.substring(1);
|
||||
}
|
||||
text.textColor = rc.second.strokeWidth != 0 ? rc.second.color : rc.main.color;
|
||||
text.shield = true;
|
||||
text.drawOnPath = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ 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 {
|
||||
|
||||
|
@ -46,24 +47,34 @@ public class RendererLayer implements OsmandMapLayer {
|
|||
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.getFloatZoom(), tileRect.top);
|
||||
double leftLongitude = MapUtils.getLongitudeFromTile(view.getFloatZoom(), tileRect.left);
|
||||
double bottomLatitude = MapUtils.getLatitudeFromTile(view.getFloatZoom(), tileRect.bottom);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(view.getFloatZoom(), tileRect.right);
|
||||
resourceManager.updateRendererIfNeeded(topLatitude, leftLongitude, bottomLatitude, rightLongitude, view.getZoom(), view.getRotate());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
MapRenderRepositories renderer = resourceManager.getRenderer();
|
||||
if (renderer != null && renderer.getBitmap() != null) {
|
||||
RectF newLoc = renderer.getCachedWaysLoc();
|
||||
double leftX1 = MapUtils.getTileNumberX(view.getFloatZoom(), newLoc.left);
|
||||
double rightX1 = MapUtils.getTileNumberX(view.getFloatZoom(), newLoc.right);
|
||||
double topY1 = MapUtils.getTileNumberY(view.getFloatZoom(), newLoc.top);
|
||||
double bottomY1 = MapUtils.getTileNumberY(view.getFloatZoom(), newLoc.bottom);
|
||||
|
||||
float x1 = (float) ((leftX1 - view.getXTile()) * view.getTileSize() + view.getCenterPointX());
|
||||
float y1 = (float) ((topY1 - view.getYTile()) * view.getTileSize() + view.getCenterPointY());
|
||||
float x2 = (float) ((rightX1 - view.getXTile()) * view.getTileSize() + view.getCenterPointX());
|
||||
float y2 = (float) ((bottomY1 - view.getYTile()) * view.getTileSize() + view.getCenterPointY());
|
||||
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();
|
||||
canvas.rotate(-rot, view.getCenterPointX(), view.getCenterPointY());
|
||||
destImage.set(x1, y1, x2, y2);
|
||||
canvas.drawBitmap(renderer.getBitmap(), null, destImage, paintImg);
|
||||
}
|
||||
|
@ -71,6 +82,15 @@ 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();
|
||||
|
|
|
@ -646,6 +646,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
return (FloatMath.cos(rad) * dTileX - FloatMath.sin(rad) * dTileY) * getTileSize() ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* These methods do not consider rotating
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,7 @@ import alice.tuprolog.Var;
|
|||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Environment;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class CommandPlayer {
|
||||
|
||||
|
@ -200,6 +201,7 @@ public class CommandPlayer {
|
|||
mediaPlayer.prepare();
|
||||
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
mp.release();
|
||||
mediaPlayer = new MediaPlayer();
|
||||
int sleep = 60;
|
||||
boolean delay = true;
|
||||
|
|
Loading…
Reference in a new issue