implement rotating map
git-svn-id: https://osmand.googlecode.com/svn/trunk@78 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
891a38e697
commit
56befb372c
11 changed files with 199 additions and 74 deletions
|
@ -19,36 +19,51 @@ public class ToDoConstants {
|
||||||
*/
|
*/
|
||||||
public int DESCRIBE_ABOUT_AUTHORS = 8;
|
public int DESCRIBE_ABOUT_AUTHORS = 8;
|
||||||
|
|
||||||
// 0. Minimize memory used for index & improve time for read index
|
// TODO ANDROID
|
||||||
//// TODO for releasing version
|
// 0. Minimize memory used for index & improve time for reading index
|
||||||
// 1. POI SEARCH NEAR TO YOU
|
// 1. POI search near to map location (show categories & type). First cut. (implement incremental search)
|
||||||
// 2. FIX BACK TO your location & gps & point of view (may be compass)
|
// 3. Revise osmand UI. Preparing new icons.
|
||||||
// 3. Revise UI icons/layout
|
// 2. Showing compass on the map : use device compass if exists(?)
|
||||||
// 5. Enable city/streets/buildings index
|
// 5. Search for city/streets/buildings
|
||||||
// 7. Search for city/streets/buildings!
|
// 9. Config file log & see log from file (when exception happened to see from device)
|
||||||
// 8. Enable change POI directly on map
|
// 11. Print out additional info speed, altitude, number of satellites
|
||||||
// 9. Log to see when exception occurred (android)
|
// 8. Enable change POI directly on map (requires OSM login)
|
||||||
// 10. Specify auto-rotating map (compass).
|
// 13. Save point as favourite & introduce favourite points dialog
|
||||||
// 11. Print out additional info speed, altitude, number of satellites
|
// 14. Show zoom level on map
|
||||||
// 12. Show point where are you going (the arrow not the point)
|
// 15. Investigate interruption of any long running operation & implement where it is needed
|
||||||
// 13. Save point as favorite
|
// 16. Support open street bugs api.
|
||||||
// 14. Show zoom level directly on map
|
// 17. Enable go to location specifying coordinates
|
||||||
// 15. Investigate interruption of progress (is it available & how to support it)
|
// 18. Implement go to point
|
||||||
// -------------------
|
// 19. Show how map is rotated where north/south on map (do not consider compass)
|
||||||
|
// 20. Implement save track/route to gpx (?)
|
||||||
|
|
||||||
// BUGS Androd :
|
// FIXME Bugs Androd :
|
||||||
|
// 0. FIX TODO for partial loading rotated map
|
||||||
// 1. When firstly run osmand navigation (from notification bar) show map & go to menu shows desktop.
|
// 1. When firstly run osmand navigation (from notification bar) show map & go to menu shows desktop.
|
||||||
// No chance to close application
|
// No chance to close application
|
||||||
|
// 3. Fix progress information (loading indices) for android version
|
||||||
|
// 4. Fix when POI selected & enable button backToLocation
|
||||||
|
|
||||||
|
// TODO SWING:
|
||||||
|
// 1. download tiles without using dir tiles
|
||||||
|
// 2. Config file log & see log from file
|
||||||
|
// 3. Reinvent index mechanism (save in zip file with tile indexes, save city/town addresses separately, read partially !)
|
||||||
|
// 4. Invent different file extensions for poi.index, address.index,...
|
||||||
|
|
||||||
|
|
||||||
/// SWING version :
|
// Max letter :
|
||||||
// TODO :
|
// 1. Fix bug 1
|
||||||
// 1. Accept amenity as way
|
// 2. Create for each screen activity
|
||||||
// 1. Fix TODO in files
|
// 3. Implement incremental search (reduce first time display to 10 & depth 2)
|
||||||
|
// 4. Improve navigate back/forward between screens
|
||||||
|
// 5. Implement exit confirmation
|
||||||
|
|
||||||
|
|
||||||
|
// DONE ANDROID :
|
||||||
|
// 12. Show information of where are you going (the arrow on the map)
|
||||||
|
// 10. Specify auto-rotating map (bearing of your direction)
|
||||||
|
|
||||||
|
// DONE SWING
|
||||||
|
|
||||||
// 3. download tiles without using dir tiles
|
|
||||||
// 4. Config file log & see log from file
|
|
||||||
// 5. Reinvent index mechanism (save in zip file with tile indexes, save city/town addresses separately, read partially !)
|
|
||||||
// 6. Invent different file extensions for poi.index, address.index,...
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class DataTileManager<T> {
|
||||||
if(isEmpty()){
|
if(isEmpty()){
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
int dp = 1;
|
int dp = 0;
|
||||||
List<T> l = null;
|
List<T> l = null;
|
||||||
while (l == null || l.isEmpty()) {
|
while (l == null || l.isEmpty()) {
|
||||||
l = getClosestObjects(latitude, longitude, dp, dp + defaultStep);
|
l = getClosestObjects(latitude, longitude, dp, dp + defaultStep);
|
||||||
|
@ -106,8 +106,10 @@ public class DataTileManager<T> {
|
||||||
int tileY = (int) MapUtils.getTileNumberY(zoom, latitude);
|
int tileY = (int) MapUtils.getTileNumberY(zoom, latitude);
|
||||||
List<T> result = new ArrayList<T>();
|
List<T> result = new ArrayList<T>();
|
||||||
|
|
||||||
|
if(startDepth <= 0){
|
||||||
putObjects(tileX, tileY, result);
|
putObjects(tileX, tileY, result);
|
||||||
|
startDepth = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// that's very difficult way visiting node :
|
// that's very difficult way visiting node :
|
||||||
// similar to visit by spiral
|
// similar to visit by spiral
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal">
|
android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal">
|
||||||
<ImageView android:id="@+id/icon" android:layout_width="20px"
|
<ImageView android:id="@+id/icon" android:layout_width="25px"
|
||||||
android:paddingLeft="2px" android:paddingRight="2px"
|
android:paddingLeft="2px" android:paddingRight="2px"
|
||||||
android:paddingTop="2px" android:layout_height="fill_parent"/>
|
android:paddingTop="2px" android:layout_height="fill_parent"/>
|
||||||
<TextView android:id="@+id/label" android:layout_width="wrap_content"
|
<TextView android:id="@+id/label" android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" android:textSize="20px" />
|
android:layout_height="wrap_content" android:textSize="25px" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="rotate_map_to_bearing_descr">Rotate map to bearing of your direction</string>
|
||||||
|
<string name="rotate_map_to_bearing">Rotate map</string>
|
||||||
<string name="show_poi_over_map_description">Show POI on map</string>
|
<string name="show_poi_over_map_description">Show POI on map</string>
|
||||||
<string name="show_poi_over_map">Show POI</string>
|
<string name="show_poi_over_map">Show POI</string>
|
||||||
<string name="map_tile_source_descr">Choose the source of tiles:</string>
|
<string name="map_tile_source_descr">Choose the source of tiles:</string>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
<CheckBoxPreference android:key="use_internet_to_download_tiles" android:title="@string/use_internet" android:summary="@string/use_internet_to_download_tile"></CheckBoxPreference>
|
<CheckBoxPreference android:key="use_internet_to_download_tiles" android:title="@string/use_internet" android:summary="@string/use_internet_to_download_tile"></CheckBoxPreference>
|
||||||
<CheckBoxPreference android:key="show_poi_over_map" android:title="@string/show_poi_over_map" android:summary="@string/show_poi_over_map_description"></CheckBoxPreference>
|
<CheckBoxPreference android:key="show_poi_over_map" android:title="@string/show_poi_over_map" android:summary="@string/show_poi_over_map_description"></CheckBoxPreference>
|
||||||
|
<CheckBoxPreference android:key="rotate_map_to_bearing" android:title="@string/rotate_map_to_bearing" android:summary="@string/rotate_map_to_bearing_descr"></CheckBoxPreference>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="@string/map_source"><ListPreference android:title="@string/map_tile_source" android:summary="@string/map_tile_source_descr" android:key="map_tile_sources"></ListPreference>
|
<PreferenceCategory android:title="@string/map_source"><ListPreference android:title="@string/map_tile_source" android:summary="@string/map_tile_source_descr" android:key="map_tile_sources"></ListPreference>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
|
@ -30,6 +30,13 @@ public class OsmandSettings {
|
||||||
return prefs.getBoolean(SHOW_POI_OVER_MAP, false);
|
return prefs.getBoolean(SHOW_POI_OVER_MAP, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this value string is synchronized with android.xml preference name
|
||||||
|
public static final String ROTATE_MAP_TO_BEARING = "rotate_map_to_bearing";
|
||||||
|
public static boolean isRotateMapToBearing(Context ctx){
|
||||||
|
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||||
|
return prefs.getBoolean(ROTATE_MAP_TO_BEARING, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// this value string is synchronized with android.xml preference name
|
// this value string is synchronized with android.xml preference name
|
||||||
public static final String MAP_TILE_SOURCES = "map_tile_sources";
|
public static final String MAP_TILE_SOURCES = "map_tile_sources";
|
||||||
|
|
|
@ -135,16 +135,22 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocation(Location location){
|
public void setLocation(Location location){
|
||||||
locationLayer.setLastKnownLocation(location);
|
// Do very strange manipulation to call redraw only once
|
||||||
|
locationLayer.setLastKnownLocation(location, true);
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
if (linkLocationWithMap) {
|
if (linkLocationWithMap) {
|
||||||
mapView.setLatLon(location.getLatitude(), location.getLongitude());
|
if (location.hasBearing() && OsmandSettings.isRotateMapToBearing(this)) {
|
||||||
|
mapView.setRotateWithLocation(-location.getBearing(), location.getLatitude(), location.getLongitude());
|
||||||
|
} else {
|
||||||
|
mapView.setLatLon(location.getLatitude(), location.getLongitude());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mapView.prepareImage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!linkLocationWithMap){
|
if (!linkLocationWithMap) {
|
||||||
backToLocation.setVisibility(View.VISIBLE);
|
backToLocation.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +197,9 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
||||||
if(mapView.getMap() != OsmandSettings.getMapTileSource(this)){
|
if(mapView.getMap() != OsmandSettings.getMapTileSource(this)){
|
||||||
mapView.setMap(OsmandSettings.getMapTileSource(this));
|
mapView.setMap(OsmandSettings.getMapTileSource(this));
|
||||||
}
|
}
|
||||||
|
if(!OsmandSettings.isRotateMapToBearing(this)){
|
||||||
|
mapView.setRotate(0);
|
||||||
|
}
|
||||||
if(mapView.getLayers().contains(poiMapLayer) != OsmandSettings.isShowingPoiOverMap(this)){
|
if(mapView.getLayers().contains(poiMapLayer) != OsmandSettings.isShowingPoiOverMap(this)){
|
||||||
if(OsmandSettings.isShowingPoiOverMap(this)){
|
if(OsmandSettings.isShowingPoiOverMap(this)){
|
||||||
mapView.addLayer(poiMapLayer);
|
mapView.addLayer(poiMapLayer);
|
||||||
|
|
|
@ -113,6 +113,12 @@ public class SearchActivity extends ListActivity {
|
||||||
super(SearchActivity.this, R.layout.searchlist, (List<?>) list);
|
super(SearchActivity.this, R.layout.searchlist, (List<?>) list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
int c = super.getCount();
|
||||||
|
return c > 20 ? 20 : c;
|
||||||
|
}
|
||||||
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
LayoutInflater inflater = getLayoutInflater();
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
View row = inflater.inflate(R.layout.searchlist, parent, false);
|
View row = inflater.inflate(R.layout.searchlist, parent, false);
|
||||||
|
|
|
@ -23,6 +23,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
private CheckBoxPreference showPoiOnMap;
|
private CheckBoxPreference showPoiOnMap;
|
||||||
private CheckBoxPreference useInternetToDownloadTiles;
|
private CheckBoxPreference useInternetToDownloadTiles;
|
||||||
private ListPreference tileSourcePreference;
|
private ListPreference tileSourcePreference;
|
||||||
|
private CheckBoxPreference rotateMapToBearing;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -33,6 +34,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
useInternetToDownloadTiles.setOnPreferenceChangeListener(this);
|
useInternetToDownloadTiles.setOnPreferenceChangeListener(this);
|
||||||
showPoiOnMap =(CheckBoxPreference) screen.findPreference(OsmandSettings.SHOW_POI_OVER_MAP);
|
showPoiOnMap =(CheckBoxPreference) screen.findPreference(OsmandSettings.SHOW_POI_OVER_MAP);
|
||||||
showPoiOnMap.setOnPreferenceChangeListener(this);
|
showPoiOnMap.setOnPreferenceChangeListener(this);
|
||||||
|
rotateMapToBearing =(CheckBoxPreference) screen.findPreference(OsmandSettings.ROTATE_MAP_TO_BEARING);
|
||||||
|
rotateMapToBearing.setOnPreferenceChangeListener(this);
|
||||||
|
|
||||||
tileSourcePreference =(ListPreference) screen.findPreference(OsmandSettings.MAP_TILE_SOURCES);
|
tileSourcePreference =(ListPreference) screen.findPreference(OsmandSettings.MAP_TILE_SOURCES);
|
||||||
tileSourcePreference.setOnPreferenceChangeListener(this);
|
tileSourcePreference.setOnPreferenceChangeListener(this);
|
||||||
|
@ -45,6 +48,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
super.onResume();
|
super.onResume();
|
||||||
useInternetToDownloadTiles.setChecked(OsmandSettings.isUsingInternetToDownloadTiles(this));
|
useInternetToDownloadTiles.setChecked(OsmandSettings.isUsingInternetToDownloadTiles(this));
|
||||||
showPoiOnMap.setChecked(OsmandSettings.isShowingPoiOverMap(this));
|
showPoiOnMap.setChecked(OsmandSettings.isShowingPoiOverMap(this));
|
||||||
|
rotateMapToBearing.setChecked(OsmandSettings.isRotateMapToBearing(this));
|
||||||
|
|
||||||
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
||||||
String[] entries = new String[list.size()];
|
String[] entries = new String[list.size()];
|
||||||
|
@ -70,6 +74,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
} else if(preference == useInternetToDownloadTiles){
|
} else if(preference == useInternetToDownloadTiles){
|
||||||
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, (Boolean) newValue);
|
edit.putBoolean(OsmandSettings.USE_INTERNET_TO_DOWNLOAD_TILES, (Boolean) newValue);
|
||||||
edit.commit();
|
edit.commit();
|
||||||
|
} else if(preference == rotateMapToBearing){
|
||||||
|
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, (Boolean) newValue);
|
||||||
|
edit.commit();
|
||||||
} else if (preference == tileSourcePreference) {
|
} else if (preference == tileSourcePreference) {
|
||||||
edit.putString(OsmandSettings.MAP_TILE_SOURCES, (String) newValue);
|
edit.putString(OsmandSettings.MAP_TILE_SOURCES, (String) newValue);
|
||||||
edit.commit();
|
edit.commit();
|
||||||
|
|
|
@ -13,8 +13,10 @@ import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
import android.graphics.Paint.Style;
|
import android.graphics.Paint.Style;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.FloatMath;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
|
@ -48,6 +50,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
private double latitude = 0d;
|
private double latitude = 0d;
|
||||||
|
|
||||||
|
private float rotate = 0;
|
||||||
|
|
||||||
// name of source map
|
// name of source map
|
||||||
private ITileSource map = null;
|
private ITileSource map = null;
|
||||||
|
|
||||||
|
@ -65,6 +69,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
Paint paintGrayFill;
|
Paint paintGrayFill;
|
||||||
Paint paintWhiteFill;
|
Paint paintWhiteFill;
|
||||||
Paint paintBlack;
|
Paint paintBlack;
|
||||||
|
Paint paintBitmap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,15 +89,22 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
paintGrayFill = new Paint();
|
paintGrayFill = new Paint();
|
||||||
paintGrayFill.setColor(Color.GRAY);
|
paintGrayFill.setColor(Color.GRAY);
|
||||||
paintGrayFill.setStyle(Style.FILL);
|
paintGrayFill.setStyle(Style.FILL);
|
||||||
|
// when map rotate
|
||||||
|
paintGrayFill.setAntiAlias(true);
|
||||||
|
|
||||||
paintWhiteFill = new Paint();
|
paintWhiteFill = new Paint();
|
||||||
paintWhiteFill.setColor(Color.WHITE);
|
paintWhiteFill.setColor(Color.WHITE);
|
||||||
paintWhiteFill.setStyle(Style.FILL);
|
paintWhiteFill.setStyle(Style.FILL);
|
||||||
|
// when map rotate
|
||||||
|
paintWhiteFill.setAntiAlias(true);
|
||||||
|
|
||||||
paintBlack = new Paint();
|
paintBlack = new Paint();
|
||||||
paintBlack.setStyle(Style.STROKE);
|
paintBlack.setStyle(Style.STROKE);
|
||||||
paintBlack.setColor(Color.BLACK);
|
paintBlack.setColor(Color.BLACK);
|
||||||
|
|
||||||
|
paintBitmap = new Paint();
|
||||||
|
paintBitmap.setFilterBitmap(true);
|
||||||
|
|
||||||
setClickable(true);
|
setClickable(true);
|
||||||
getHolder().addCallback(this);
|
getHolder().addCallback(this);
|
||||||
|
|
||||||
|
@ -140,12 +152,12 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getXTile(){
|
public float getXTile(){
|
||||||
return MapUtils.getTileNumberX(zoom, longitude);
|
return (float) MapUtils.getTileNumberX(zoom, longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getYTile(){
|
public float getYTile(){
|
||||||
return MapUtils.getTileNumberY(zoom, latitude);
|
return (float) MapUtils.getTileNumberY(zoom, latitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,6 +169,27 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRotate(float rotate) {
|
||||||
|
float dif = this.rotate - rotate;
|
||||||
|
if (dif > 2 || dif < -2) {
|
||||||
|
this.rotate = rotate;
|
||||||
|
animatedDraggingThread.stopDragging();
|
||||||
|
prepareImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRotateWithLocation(float rotate, double latitude, double longitude){
|
||||||
|
animatedDraggingThread.stopDragging();
|
||||||
|
this.rotate = rotate;
|
||||||
|
this.latitude = latitude;
|
||||||
|
this.longitude = longitude;
|
||||||
|
prepareImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRotate() {
|
||||||
|
return rotate;
|
||||||
|
}
|
||||||
|
|
||||||
public ITileSource getMap() {
|
public ITileSource getMap() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -230,33 +263,59 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void calculateTileRectangle(RectF pixRect, float cx, float cy, RectF tileRect){
|
||||||
|
float x1 = calcDiffTileX(pixRect.left - cx, pixRect.top - cy);
|
||||||
|
float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy);
|
||||||
|
float x3 = calcDiffTileX(pixRect.right - cx, pixRect.top - cy);
|
||||||
|
float x4 = calcDiffTileX(pixRect.right - cx, pixRect.bottom - cy);
|
||||||
|
float y1 = calcDiffTileY(pixRect.left - cx, pixRect.top - cy);
|
||||||
|
float y2 = calcDiffTileY(pixRect.left - cx, pixRect.bottom - cy);
|
||||||
|
float y3 = calcDiffTileY(pixRect.right - cx, pixRect.top - cy);
|
||||||
|
float y4 = calcDiffTileY(pixRect.right - cx, pixRect.bottom - cy);
|
||||||
|
float l = Math.min(Math.min(x1, x2), Math.min(x3, x4)) + getXTile();
|
||||||
|
float r = Math.max(Math.max(x1, x2), Math.max(x3, x4)) + getXTile();
|
||||||
|
float t = Math.min(Math.min(y1, y2), Math.min(y3, y4)) + getYTile();
|
||||||
|
float b = Math.max(Math.max(y1, y2), Math.max(y3, y4)) + getYTile();
|
||||||
|
tileRect.set(l, t, r, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// used only to save space & reuse
|
||||||
|
protected RectF tilesRect = new RectF();
|
||||||
|
protected RectF boundsRect = new RectF();
|
||||||
|
|
||||||
public void prepareImage() {
|
public void prepareImage() {
|
||||||
if (OsmandSettings.isUsingInternetToDownloadTiles(getContext())) {
|
if (OsmandSettings.isUsingInternetToDownloadTiles(getContext())) {
|
||||||
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
MapTileDownloader.getInstance().refuseAllPreviousRequests();
|
||||||
}
|
}
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
int tileSize = getTileSize();
|
int tileSize = getTileSize();
|
||||||
|
float tileX = getXTile();
|
||||||
int xTileLeft = (int) Math.floor(getXTile() - width / (2d * getTileSize()));
|
float tileY = getYTile();
|
||||||
int yTileUp = (int) Math.floor(getYTile() - height / (2d * getTileSize()));
|
|
||||||
int startingX = (int) ((xTileLeft - getXTile()) * getTileSize() + getWidth() / 2);
|
|
||||||
int startingY = (int) ((yTileUp - getYTile()) * getTileSize() + getHeight() / 2);
|
|
||||||
|
|
||||||
SurfaceHolder holder = getHolder();
|
SurfaceHolder holder = getHolder();
|
||||||
synchronized (holder) {
|
synchronized (holder) {
|
||||||
Canvas canvas = holder.lockCanvas();
|
Canvas canvas = holder.lockCanvas();
|
||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
// canvas.rotate(45);
|
ResourceManager mgr = ResourceManager.getResourceManager();
|
||||||
|
boolean useInternet = OsmandSettings.isUsingInternetToDownloadTiles(getContext());
|
||||||
|
float w = getWidth() / 2;
|
||||||
|
float h = getHeight() / 2;
|
||||||
|
canvas.rotate(rotate, w , h);
|
||||||
|
boundsRect.set(0, 0, getWidth(), getHeight());
|
||||||
|
calculateTileRectangle(boundsRect, w, h, tilesRect);
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i * tileSize + startingX < width; i++) {
|
int left = (int) FloatMath.floor(tilesRect.left);
|
||||||
for (int j = 0; j * tileSize + startingY < height; j++) {
|
int top = (int) FloatMath.floor(tilesRect.top);
|
||||||
ResourceManager mgr = ResourceManager.getResourceManager();
|
int width = (int) (FloatMath.ceil(tilesRect.right) - left);
|
||||||
Bitmap bmp = mgr.getTileImageForMapAsync(map, xTileLeft + i, yTileUp + j, zoom, OsmandSettings.isUsingInternetToDownloadTiles(getContext()));
|
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) * tileSize + w;
|
||||||
|
float y1 = (j + top - tileY) * tileSize + h;
|
||||||
|
Bitmap bmp = mgr.getTileImageForMapAsync(map, left + i, top + j, zoom, useInternet);
|
||||||
if (bmp == null) {
|
if (bmp == null) {
|
||||||
drawEmptyTile(canvas, i * tileSize + startingX, j * tileSize + startingY);
|
drawEmptyTile(canvas, (int) x1, (int) y1);
|
||||||
} else {
|
} else {
|
||||||
canvas.drawBitmap(bmp, i * tileSize + startingX, j * tileSize + startingY, null);
|
canvas.drawBitmap(bmp, x1, y1, paintBitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +329,8 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
|
|
||||||
public void tileDownloaded(DownloadRequest request) {
|
public void tileDownloaded(DownloadRequest request) {
|
||||||
if(request == null){
|
// TODO estimate bounds for rotated map
|
||||||
|
if(request == null || rotate != 0){
|
||||||
// we don't know exact images were changed
|
// we don't know exact images were changed
|
||||||
prepareImage();
|
prepareImage();
|
||||||
return;
|
return;
|
||||||
|
@ -285,10 +345,9 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
(i + getTileSize() >= 0 && i < getWidth()) && (j + getTileSize() >= 0 && j < getHeight())) {
|
(i + getTileSize() >= 0 && i < getWidth()) && (j + getTileSize() >= 0 && j < getHeight())) {
|
||||||
SurfaceHolder holder = getHolder();
|
SurfaceHolder holder = getHolder();
|
||||||
synchronized (holder) {
|
synchronized (holder) {
|
||||||
// TODO
|
|
||||||
Canvas canvas = holder.lockCanvas(new Rect(i, j, getTileSize() + i, getTileSize() + j));
|
Canvas canvas = holder.lockCanvas(new Rect(i, j, getTileSize() + i, getTileSize() + j));
|
||||||
if (canvas != null) {
|
if (canvas != null) {
|
||||||
// canvas.rotate(45);
|
canvas.rotate(rotate,getWidth()/2, getHeight()/2);
|
||||||
try {
|
try {
|
||||||
ResourceManager mgr = ResourceManager.getResourceManager();
|
ResourceManager mgr = ResourceManager.getResourceManager();
|
||||||
Bitmap bmp = mgr.getTileImageForMapSync(map, request.xTile, request.yTile, zoom, false);
|
Bitmap bmp = mgr.getTileImageForMapSync(map, request.xTile, request.yTile, zoom, false);
|
||||||
|
@ -309,14 +368,26 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////// DRAGGING PART ///////////////////////////////////////
|
/////////////////////////////////// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float calcDiffTileX(float dx, float dy){
|
||||||
|
float rad = (float) Math.toRadians(rotate);
|
||||||
|
return (FloatMath.cos(rad) * dx + FloatMath.sin(rad) * dy) / getTileSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dragTo(float fromX, float fromY, float toX, float toY){
|
public void dragTo(float fromX, float fromY, float toX, float toY){
|
||||||
float dx = (fromX - toX)/getTileSize();
|
float dx = (fromX - toX) ;
|
||||||
float dy = (fromY - toY)/getTileSize();
|
float dy = (fromY - toY);
|
||||||
this.latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
|
float fy = calcDiffTileY(dx, dy);
|
||||||
this.longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
|
float fx = calcDiffTileX(dx, dy);
|
||||||
|
|
||||||
|
this.latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + fy);
|
||||||
|
this.longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx);
|
||||||
prepareImage();
|
prepareImage();
|
||||||
if(locationListener != null){
|
if(locationListener != null){
|
||||||
locationListener.locationChanged(latitude, longitude, this);
|
locationListener.locationChanged(latitude, longitude, this);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Paint.Style;
|
import android.graphics.Paint.Style;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
import android.util.FloatMath;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
|
@ -52,6 +53,7 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO simplify calculation if possible
|
||||||
@Override
|
@Override
|
||||||
public void onDraw(Canvas canvas) {
|
public void onDraw(Canvas canvas) {
|
||||||
if (isLocationVisible(lastKnownLocation)) {
|
if (isLocationVisible(lastKnownLocation)) {
|
||||||
|
@ -62,9 +64,7 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(), lastKnownLocation
|
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(), lastKnownLocation
|
||||||
.getAccuracy(), view.getTileSize(), view.getWidth());
|
.getAccuracy(), view.getTileSize(), view.getWidth());
|
||||||
|
|
||||||
if (locationX >= 0 && locationY >= 0) {
|
canvas.drawCircle(locationX, locationY, RADIUS, location);
|
||||||
canvas.drawCircle(locationX, locationY, RADIUS, location);
|
|
||||||
}
|
|
||||||
if (radius > RADIUS) {
|
if (radius > RADIUS) {
|
||||||
canvas.drawCircle(locationX, locationY, radius, area);
|
canvas.drawCircle(locationX, locationY, radius, area);
|
||||||
}
|
}
|
||||||
|
@ -103,12 +103,15 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
if(l == null || view == null){
|
if(l == null || view == null){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int newX = MapUtils.getPixelShiftX(view.getZoom(),
|
int cx = view.getWidth()/2;
|
||||||
l.getLongitude(), view.getLongitude(), view.getTileSize()) +
|
int cy = view.getHeight()/2;
|
||||||
view.getWidth()/2;
|
int dx = MapUtils.getPixelShiftX(view.getZoom(),
|
||||||
int newY = MapUtils.getPixelShiftY(view.getZoom(),
|
l.getLongitude(), view.getLongitude(), view.getTileSize());
|
||||||
l.getLatitude(), view.getLatitude() , view.getTileSize()) +
|
int dy = MapUtils.getPixelShiftY(view.getZoom(),
|
||||||
view.getHeight()/2;
|
l.getLatitude(), view.getLatitude() , view.getTileSize());
|
||||||
|
float rad = (float) Math.toRadians(view.getRotate());
|
||||||
|
int newX = (int) (dx * FloatMath.cos(rad) - dy * FloatMath.sin(rad) + cx);
|
||||||
|
int newY = (int) (dx * FloatMath.sin(rad) + dy * FloatMath.cos(rad) + cy);
|
||||||
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(),
|
int radius = MapUtils.getLengthXFromMeters(view.getZoom(), view.getLatitude(), view.getLongitude(),
|
||||||
l.getAccuracy(), view.getTileSize(), view.getWidth());
|
l.getAccuracy(), view.getTileSize(), view.getWidth());
|
||||||
if(newX >= 0 && newX <= view.getWidth() && newY >=0 && newY <= view.getHeight()){
|
if(newX >= 0 && newX <= view.getWidth() && newY >=0 && newY <= view.getHeight()){
|
||||||
|
@ -127,11 +130,13 @@ public class PointLocationLayer implements OsmandMapLayer {
|
||||||
return lastKnownLocation;
|
return lastKnownLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastKnownLocation(Location lastKnownLocation) {
|
public void setLastKnownLocation(Location lastKnownLocation, boolean doNotRedraw) {
|
||||||
boolean redraw = isLocationVisible(this.lastKnownLocation) || isLocationVisible(lastKnownLocation);
|
|
||||||
this.lastKnownLocation = lastKnownLocation;
|
this.lastKnownLocation = lastKnownLocation;
|
||||||
if(redraw){
|
if (!doNotRedraw) {
|
||||||
view.prepareImage();
|
boolean redraw = isLocationVisible(this.lastKnownLocation) || isLocationVisible(lastKnownLocation);
|
||||||
|
if (redraw) {
|
||||||
|
view.prepareImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue