implement showing compass

git-svn-id: https://osmand.googlecode.com/svn/trunk@90 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-05-27 21:06:46 +00:00
parent 5e30a13588
commit 8555ac76ee
11 changed files with 177 additions and 47 deletions

View file

@ -13,27 +13,28 @@ public class ToDoConstants {
public int DESCRIBE_ABOUT_AUTHORS = 8; public int DESCRIBE_ABOUT_AUTHORS = 8;
// TODO ANDROID // TODO ANDROID
// 1. POI search near to map location (show categories & type). First cut. (implement incremental search) // 25. POI search near to map location (show categories & type). Second cut. (implement incremental search)
// 3. Revise osmand UI. Preparing new icons.
// 2. Showing compass on the map : use device compass if exists(?) // 3. Revise osmand UI. Preparing new icons (revise UI 18, 2, ).
// 5. Search for city/streets/buildings
// 9. Configure file log & see log from file (when exception happened to see from device)
// 11. Print out additional info speed, altitude, number of satellites
// 8. Enable change POI directly on map (requires OSM login)
// 13. Save point as favorite & introduce favorite points dialog // 13. Save point as favorite & introduce favorite points dialog
// 14. Show zoom level on map // 14. Show zoom level on map
// 15. Investigate interruption of any long running operation & implement where it is needed
// 16. Support open street bugs api.
// 17. Enable go to location by specifying coordinates
// 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 (?)
// 21. Implement zooming tile (if tile doesn't exist local, we can zoom in previous tile).
// 23. Implement moving point from center to bottom (for rotating map).
// It is not very useful to see what was before.
// 24. Implement ResourceManager on Low memory (clear previous all addresses cities, remove all amenities cache) // 24. Implement ResourceManager, load cities/streets/buildings on Low memory (clear previous all addresses cities).
// Use async loading tile thread, to preload amenities also. // 5. Search for city/streets/buildings
// 9. Configure file log & see log from file (when exception happened to see from device)
// 15. Investigate interruption of any long running operation & implement where it is needed
// 17. Enable go to location by specifying coordinates
// 11. Print out additional info speed, altitude, number of satellites
// 19. Show how map is rotated where north/south on map (do not consider compass)
// 23. Implement moving point from center to bottom (for rotating map). (+)
// 21. Implement zooming tile (if tile doesn't exist local, we can zoom in previous tile).
// 8. Enable change POI directly on map (requires OSM login)
// 16. Support open street bugs api.
// 20. Implement save track/route to gpx (?)
// FIXME Bugs Android : // FIXME Bugs Android :
// 0. FIX TODO for partial loading rotated map // 0. FIX TODO for partial loading rotated map
@ -41,6 +42,11 @@ public class ToDoConstants {
// No chance to close application // No chance to close application
// 3. Fix progress information (loading indices) for android version // 3. Fix progress information (loading indices) for android version
// 4. Fix when POI selected & enable button backToLocation // 4. Fix when POI selected & enable button backToLocation
// 5. Call ResourceManager.close when it is needed
// 6. Understand concept of application where to save/restore global setting
// (for example reset navigate to point, reset link map with location). It should be reset after user call exit.
// 7. Implement search amenities by type (!).
// Rewrite search activity in order to limit amenities not to all types.
// TODO SWING: // TODO SWING:
// 1. Download tiles without using dir tiles // 1. Download tiles without using dir tiles
@ -49,16 +55,9 @@ public class ToDoConstants {
// DONE ANDROID : // DONE ANDROID :
// 12. Show information of where are you going (the arrow on the map) // 18. Implement go to point
// 10. Specify auto-rotating map (bearing of your direction) // 2. Showing compass on the map : use device compass if exists(?)
// 22. Investigate 3D tile view (how it is done in osmand). Looking not very good, because of
// angle of perspective (best perspective angle = 60) use
// android.graphics.Camera.rotateX(60), getMatrix(m), canvas.concat(m) (find example in internet)
// Problems : to calculate how to drag point on map, to calculate how many tiles are needed, is location visible ....
// 0. Minimize memory used for index & improve time for reading index
// DONE SWING // DONE SWING
// 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,...
} }

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="show_view_angle_descr">Show aspect of vew based on compass</string>
<string name="show_view_angle">Show aspect of view</string>
<string name="stop_navigation">Unmark location</string> <string name="stop_navigation">Unmark location</string>
<string name="navigate_to_point">Mark location</string> <string name="navigate_to_point">Mark location</string>
<string name="map_view_3d_descr">Enable 3D view of the map</string> <string name="map_view_3d_descr">Enable 3D view of the map</string>

View file

@ -6,6 +6,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> <CheckBoxPreference android:key="rotate_map_to_bearing" android:title="@string/rotate_map_to_bearing" android:summary="@string/rotate_map_to_bearing_descr"></CheckBoxPreference>
<CheckBoxPreference android:key="show_view_angle" android:title="@string/show_view_angle" android:summary="@string/show_view_angle_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>

View file

@ -58,7 +58,7 @@ public class AmenityIndexRepository {
} }
} while(query.moveToNext()); } while(query.moveToNext());
} }
query.deactivate(); query.close();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(String.format("Search for %s done in %s ms found %s.", log.debug(String.format("Search for %s done in %s ms found %s.",
@ -128,6 +128,12 @@ public class AmenityIndexRepository {
} }
public void close(){
if(db != null){
db.close();
}
}
public String getName() { public String getName() {
return name; return name;
} }

View file

@ -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 SHOW_VIEW_ANGLE = "show_view_angle";
public static boolean isShowingViewAngle(Context ctx){
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
return prefs.getBoolean(SHOW_VIEW_ANGLE, true);
}
// this value string is synchronized with android.xml preference name // this value string is synchronized with android.xml preference name
public static final String ROTATE_MAP_TO_BEARING = "rotate_map_to_bearing"; public static final String ROTATE_MAP_TO_BEARING = "rotate_map_to_bearing";
public static boolean isRotateMapToBearing(Context ctx){ public static boolean isRotateMapToBearing(Context ctx){

View file

@ -148,7 +148,7 @@ public class ResourceManager {
// POI INDEX // // POI INDEX //
public void indexingPoi(final IProgress progress) { public void indexingPoi(final IProgress progress) {
File file = new File(Environment.getExternalStorageDirectory(), POI_PATH); File file = new File(Environment.getExternalStorageDirectory(), POI_PATH);
amenityRepositories.clear(); clearAmenities();
if (file.exists() && file.canRead()) { if (file.exists() && file.canRead()) {
for (File f : file.listFiles()) { for (File f : file.listFiles()) {
if (f.getName().endsWith(IndexConstants.POI_INDEX_EXT)) { if (f.getName().endsWith(IndexConstants.POI_INDEX_EXT)) {
@ -164,7 +164,7 @@ public class ResourceManager {
public void indexingAddresses(final IProgress progress){ public void indexingAddresses(final IProgress progress){
File file = new File(Environment.getExternalStorageDirectory(), ADDRESS_PATH); File file = new File(Environment.getExternalStorageDirectory(), ADDRESS_PATH);
addressMap.clear(); clearAddresses();
if (file.exists() && file.canRead()) { if (file.exists() && file.canRead()) {
for (File f : file.listFiles()) { for (File f : file.listFiles()) {
if (f.getName().endsWith(IndexConstants.ADDRESS_INDEX_EXT)) { if (f.getName().endsWith(IndexConstants.ADDRESS_INDEX_EXT)) {
@ -208,6 +208,23 @@ public class ResourceManager {
////////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// ////////////////////////////////////////////// Working with amenities ////////////////////////////////////////////////
public void clearAmenities(){
for(AmenityIndexRepository r : amenityRepositories){
r.close();
}
amenityRepositories.clear();
}
public void clearAddresses(){
// TODO close db connections
addressMap.clear();
}
public synchronized void close(){
clearAmenities();
clearAddresses();
}
/// On low memory method /// /// On low memory method ///
public void onLowMemory() { public void onLowMemory() {
log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size()); log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size());

View file

@ -5,6 +5,10 @@ import java.text.MessageFormat;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location; import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
@ -33,13 +37,12 @@ import com.osmand.views.POIMapLayer;
import com.osmand.views.PointLocationLayer; import com.osmand.views.PointLocationLayer;
import com.osmand.views.PointNavigationLayer; import com.osmand.views.PointNavigationLayer;
public class MapActivity extends Activity implements LocationListener, IMapLocationListener { public class MapActivity extends Activity implements LocationListener, IMapLocationListener, SensorEventListener {
/** Called when the activity is first created. */ /** Called when the activity is first created. */
private OsmandMapTileView mapView; private OsmandMapTileView mapView;
private boolean linkLocationWithMap = true;
private ImageButton backToLocation; private ImageButton backToLocation;
private ImageButton backToMenu; private ImageButton backToMenu;
@ -48,7 +51,16 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
private POIMapLayer poiMapLayer; private POIMapLayer poiMapLayer;
private WakeLock wakeLock; private WakeLock wakeLock;
private boolean sensorRegistered = false;
private final static String BACK_TO_LOCATION = "BACK_TO_LOCATION";
private final static String POINT_NAVIGATE_LAT = "POINT_NAVIGATE_LAT";
private final static String POINT_NAVIGATE_LON = "POINT_NAVIGATE_LON";
private boolean getBackToLocation(){
return getPreferences(MODE_WORLD_READABLE).getBoolean(BACK_TO_LOCATION, true);
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -58,7 +70,6 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN); // WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main); setContentView(R.layout.main);
mapView = (OsmandMapTileView) findViewById(R.id.MapView); mapView = (OsmandMapTileView) findViewById(R.id.MapView);
MapTileDownloader.getInstance().addDownloaderCallback(mapView); MapTileDownloader.getInstance().addDownloaderCallback(mapView);
@ -69,6 +80,11 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
mapView.addLayer(navigationLayer); mapView.addLayer(navigationLayer);
locationLayer = new PointLocationLayer(); locationLayer = new PointLocationLayer();
mapView.addLayer(locationLayer); mapView.addLayer(locationLayer);
SharedPreferences lprefs = getPreferences(MODE_WORLD_READABLE);
if(lprefs.contains(POINT_NAVIGATE_LAT)){
navigationLayer.setPointToNavigate(new LatLon(lprefs.getFloat(POINT_NAVIGATE_LAT, 0),
lprefs.getFloat(POINT_NAVIGATE_LON, 0)));
}
SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE); SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE);
if(prefs != null && prefs.contains(OsmandSettings.LAST_KNOWN_MAP_LAT)){ if(prefs != null && prefs.contains(OsmandSettings.LAST_KNOWN_MAP_LAT)){
@ -99,14 +115,13 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
mapView.setZoom(mapView.getZoom() - 1); mapView.setZoom(mapView.getZoom() - 1);
} }
}); });
backToLocation = (ImageButton)findViewById(R.id.BackToLocation); backToLocation = (ImageButton)findViewById(R.id.BackToLocation);
backToLocation.setVisibility(linkLocationWithMap ? View.INVISIBLE : View.VISIBLE); backToLocation.setVisibility(View.INVISIBLE);
backToLocation.setOnClickListener(new OnClickListener(){ backToLocation.setOnClickListener(new OnClickListener(){
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(!linkLocationWithMap){ if(!getBackToLocation()){
linkLocationWithMap = true; getPreferences(MODE_WORLD_READABLE).edit().putBoolean(BACK_TO_LOCATION, true).commit();
backToLocation.setVisibility(View.INVISIBLE); backToLocation.setVisibility(View.INVISIBLE);
if(locationLayer.getLastKnownLocation() != null){ if(locationLayer.getLastKnownLocation() != null){
Location lastKnownLocation = locationLayer.getLastKnownLocation(); Location lastKnownLocation = locationLayer.getLastKnownLocation();
@ -132,14 +147,41 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
SharedPreferences lprefs = getPreferences(MODE_WORLD_READABLE);
if(navigationLayer.getPointToNavigate() == null){
lprefs.edit().remove(POINT_NAVIGATE_LAT).remove(POINT_NAVIGATE_LON).commit();
} else {
LatLon p = navigationLayer.getPointToNavigate();
lprefs.edit().putFloat(POINT_NAVIGATE_LAT, (float) p.getLatitude()).
putFloat(POINT_NAVIGATE_LON, (float) p.getLongitude()).commit();
}
MapTileDownloader.getInstance().removeDownloaderCallback(mapView); MapTileDownloader.getInstance().removeDownloaderCallback(mapView);
} }
public void setLocation(Location location){ public void setLocation(Location location){
// Do very strange manipulation to call redraw only once // Do very strange manipulation to call redraw only once
// show point view only if gps enabled
if(location == null){
if(sensorRegistered) {
((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this);
sensorRegistered = false;
locationLayer.setHeading(null, true);
}
} else {
if(!sensorRegistered && OsmandSettings.isShowingViewAngle(this)){
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION);
if (s != null) {
sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI);
}
sensorRegistered = true;
}
}
locationLayer.setLastKnownLocation(location, true); locationLayer.setLastKnownLocation(location, true);
if (location != null) { if (location != null) {
if (linkLocationWithMap) { if (getBackToLocation()) {
if (location.hasBearing() && OsmandSettings.isRotateMapToBearing(this)) { if (location.hasBearing() && OsmandSettings.isRotateMapToBearing(this)) {
mapView.setRotateWithLocation(-location.getBearing(), location.getLatitude(), location.getLongitude()); mapView.setRotateWithLocation(-location.getBearing(), location.getLatitude(), location.getLongitude());
} else { } else {
@ -149,7 +191,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
mapView.prepareImage(); mapView.prepareImage();
} }
} else { } else {
if (!linkLocationWithMap) { if (!getBackToLocation()) {
backToLocation.setVisibility(View.VISIBLE); backToLocation.setVisibility(View.VISIBLE);
} }
} }
@ -195,6 +237,11 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
super.onPause(); super.onPause();
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.removeUpdates(this); service.removeUpdates(this);
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.unregisterListener(this);
sensorRegistered = false;
OsmandSettings.setLastKnownMapLocation(this, (float) mapView.getLatitude(), (float) mapView.getLongitude()); OsmandSettings.setLastKnownMapLocation(this, (float) mapView.getLatitude(), (float) mapView.getLongitude());
OsmandSettings.setLastKnownMapZoom(this, mapView.getZoom()); OsmandSettings.setLastKnownMapZoom(this, mapView.getZoom());
if (wakeLock != null) { if (wakeLock != null) {
@ -212,6 +259,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
if(!OsmandSettings.isRotateMapToBearing(this)){ if(!OsmandSettings.isRotateMapToBearing(this)){
mapView.setRotate(0); 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);
@ -222,6 +270,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, this); service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, this);
if (wakeLock == null) { if (wakeLock == null) {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "com.osmand.map"); wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "com.osmand.map");
@ -242,7 +291,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
public void locationChanged(double newLatitude, double newLongitude, Object source) { public void locationChanged(double newLatitude, double newLongitude, Object source) {
// when user start dragging // when user start dragging
if(locationLayer.getLastKnownLocation() != null){ if(locationLayer.getLastKnownLocation() != null){
linkLocationWithMap = false; getPreferences(MODE_WORLD_READABLE).edit().putBoolean(BACK_TO_LOCATION, false).commit();
if (backToLocation.getVisibility() != View.VISIBLE) { if (backToLocation.getVisibility() != View.VISIBLE) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
@ -285,4 +334,13 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
locationLayer.setHeading(event.values[0], false);
}
} }

View file

@ -70,7 +70,7 @@ public class SearchActivity extends ListActivity {
filter = new TreeMap<AmenityType, List<Amenity>>(); filter = new TreeMap<AmenityType, List<Amenity>>();
LatLon lastKnownMapLocation = OsmandSettings.getLastKnownMapLocation(this); LatLon lastKnownMapLocation = OsmandSettings.getLastKnownMapLocation(this);
List<Amenity> closestAmenities = resourceManager.searchAmenities(lastKnownMapLocation.getLatitude(), List<Amenity> closestAmenities = resourceManager.searchAmenities(lastKnownMapLocation.getLatitude(),
lastKnownMapLocation.getLongitude(), 13, 500); lastKnownMapLocation.getLongitude(), 12, 500);
MapUtils.sortListOfMapObject(closestAmenities, lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude()); MapUtils.sortListOfMapObject(closestAmenities, lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude());
for (Amenity n : closestAmenities) { for (Amenity n : closestAmenities) {
AmenityType type = n.getType(); AmenityType type = n.getType();

View file

@ -24,6 +24,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
private CheckBoxPreference useInternetToDownloadTiles; private CheckBoxPreference useInternetToDownloadTiles;
private ListPreference tileSourcePreference; private ListPreference tileSourcePreference;
private CheckBoxPreference rotateMapToBearing; private CheckBoxPreference rotateMapToBearing;
private CheckBoxPreference showViewAngle;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -36,6 +37,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
showPoiOnMap.setOnPreferenceChangeListener(this); showPoiOnMap.setOnPreferenceChangeListener(this);
rotateMapToBearing =(CheckBoxPreference) screen.findPreference(OsmandSettings.ROTATE_MAP_TO_BEARING); rotateMapToBearing =(CheckBoxPreference) screen.findPreference(OsmandSettings.ROTATE_MAP_TO_BEARING);
rotateMapToBearing.setOnPreferenceChangeListener(this); rotateMapToBearing.setOnPreferenceChangeListener(this);
showViewAngle =(CheckBoxPreference) screen.findPreference(OsmandSettings.SHOW_VIEW_ANGLE);
showViewAngle.setOnPreferenceChangeListener(this);
tileSourcePreference =(ListPreference) screen.findPreference(OsmandSettings.MAP_TILE_SOURCES); tileSourcePreference =(ListPreference) screen.findPreference(OsmandSettings.MAP_TILE_SOURCES);
tileSourcePreference.setOnPreferenceChangeListener(this); tileSourcePreference.setOnPreferenceChangeListener(this);
@ -49,6 +52,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
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)); rotateMapToBearing.setChecked(OsmandSettings.isRotateMapToBearing(this));
showViewAngle.setChecked(OsmandSettings.isShowingViewAngle(this));
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates(); List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
String[] entries = new String[list.size()]; String[] entries = new String[list.size()];
@ -77,6 +81,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
} else if(preference == rotateMapToBearing){ } else if(preference == rotateMapToBearing){
edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, (Boolean) newValue); edit.putBoolean(OsmandSettings.ROTATE_MAP_TO_BEARING, (Boolean) newValue);
edit.commit(); edit.commit();
} else if(preference == showViewAngle){
edit.putBoolean(OsmandSettings.SHOW_VIEW_ANGLE, (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();

View file

@ -5,6 +5,7 @@ import android.graphics.Color;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Paint.Style; import android.graphics.Paint.Style;
import android.location.Location; import android.location.Location;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -12,14 +13,22 @@ import android.view.MotionEvent;
import com.osmand.osm.MapUtils; import com.osmand.osm.MapUtils;
public class PointLocationLayer implements OsmandMapLayer { public class PointLocationLayer implements OsmandMapLayer {
protected final static int RADIUS = 7;
protected final static int HEADING_RADIUS = 60;
protected final static float HEADING_ANGLE = 60;
private Paint location; private Paint location;
private Paint bearing; private Paint bearing;
private Paint area; private Paint area;
private Paint headingPaint;
private Path pathForDirection;
protected Location lastKnownLocation = null; protected Location lastKnownLocation = null;
protected final static int RADIUS = 7;
private OsmandMapTileView view; private OsmandMapTileView view;
private Path pathForDirection;
private Float heading = null;
private void initUI() { private void initUI() {
location = new Paint(); location = new Paint();
@ -31,6 +40,12 @@ public class PointLocationLayer implements OsmandMapLayer {
area.setColor(Color.BLUE); area.setColor(Color.BLUE);
area.setAlpha(40); area.setAlpha(40);
headingPaint = new Paint();
headingPaint.setColor(Color.BLUE);
headingPaint.setAlpha(50);
headingPaint.setAntiAlias(true);
headingPaint.setStyle(Style.FILL);
bearing = new Paint(); bearing = new Paint();
bearing.setColor(Color.BLUE); bearing.setColor(Color.BLUE);
bearing.setAlpha(150); bearing.setAlpha(150);
@ -51,6 +66,10 @@ public class PointLocationLayer implements OsmandMapLayer {
return false; return false;
} }
private RectF getHeadingRect(int locationX, int locationY){
int rad = Math.min(3*view.getWidth()/8, 3*view.getHeight()/8);
return new RectF(locationX - rad, locationY - rad, locationX + rad, locationY + rad);
}
// TODO simplify calculation if possible // TODO simplify calculation if possible
@Override @Override
@ -67,6 +86,11 @@ public class PointLocationLayer implements OsmandMapLayer {
if (radius > RADIUS) { if (radius > RADIUS) {
canvas.drawCircle(locationX, locationY, radius, area); canvas.drawCircle(locationX, locationY, radius, area);
} }
if(heading != null){
canvas.drawArc(getHeadingRect(locationX, locationY),
heading - HEADING_ANGLE/ 2 - 90, HEADING_ANGLE, true, headingPaint);
}
if(lastKnownLocation.hasBearing()){ if(lastKnownLocation.hasBearing()){
float bearing = lastKnownLocation.getBearing(); float bearing = lastKnownLocation.getBearing();
int radiusBearing = 30; int radiusBearing = 30;
@ -84,7 +108,7 @@ public class PointLocationLayer implements OsmandMapLayer {
pathForDirection.lineTo(0, 0); pathForDirection.lineTo(0, 0);
Matrix m = new Matrix(); Matrix m = new Matrix();
m.reset(); m.reset();
m.postScale(1, radiusBearing*0.5f); m.postScale(1, radiusBearing * 0.5f);
m.postTranslate(0, -radiusBearing); m.postTranslate(0, -radiusBearing);
m.postTranslate(locationX, locationY); m.postTranslate(locationX, locationY);
m.postRotate(bearing, locationX, locationY); m.postRotate(bearing, locationX, locationY);
@ -93,8 +117,6 @@ public class PointLocationLayer implements OsmandMapLayer {
canvas.drawPath(pathForDirection, this.bearing); canvas.drawPath(pathForDirection, this.bearing);
} }
} }
} }
@ -110,6 +132,17 @@ public class PointLocationLayer implements OsmandMapLayer {
return lastKnownLocation; return lastKnownLocation;
} }
public void setHeading(Float heading, boolean doNotRedraw){
this.heading = heading;
if(!doNotRedraw && isLocationVisible(this.lastKnownLocation)){
view.prepareImage();
}
}
public Float getHeading() {
return heading;
}
public void setLastKnownLocation(Location lastKnownLocation, boolean doNotRedraw) { public void setLastKnownLocation(Location lastKnownLocation, boolean doNotRedraw) {
this.lastKnownLocation = lastKnownLocation; this.lastKnownLocation = lastKnownLocation;
if (!doNotRedraw) { if (!doNotRedraw) {

View file

@ -64,8 +64,8 @@ public class PointNavigationLayer implements OsmandMapLayer {
float bearing = calculations[1]; float bearing = calculations[1];
pathForDirection.reset(); pathForDirection.reset();
pathForDirection.moveTo(0, 0); pathForDirection.moveTo(0, 0);
pathForDirection.lineTo(0.5f, 1f); pathForDirection.lineTo(0.5f, 1.5f);
pathForDirection.lineTo(-0.5f, 1f); pathForDirection.lineTo(-0.5f, 1.5f);
pathForDirection.lineTo(0, 0); pathForDirection.lineTo(0, 0);
float radiusBearing = DIST_TO_SHOW ; float radiusBearing = DIST_TO_SHOW ;
Matrix m = new Matrix(); Matrix m = new Matrix();