great refactoring
git-svn-id: https://osmand.googlecode.com/svn/trunk@32 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
42919e9f14
commit
7ff15e3a0c
19 changed files with 793 additions and 263 deletions
|
@ -7,14 +7,13 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Basic algorithms that are not in jdk
|
||||
*/
|
||||
public class Algoritms {
|
||||
private static final int BUFFER_SIZE = 1024;
|
||||
private static final Log log = LogFactory.getLog(Algoritms.class);
|
||||
private static final Log log = LogUtil.getLog(Algoritms.class);
|
||||
|
||||
public static boolean isEmpty(String s){
|
||||
return s == null || s.length() == 0;
|
||||
|
|
20
DataExtractionOSM/src/com/osmand/LogUtil.java
Normal file
20
DataExtractionOSM/src/com/osmand/LogUtil.java
Normal file
|
@ -0,0 +1,20 @@
|
|||
package com.osmand;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* That class is replacing of standard LogFactory due to
|
||||
* problems with Android implementation of LogFactory.
|
||||
* See Android analog of LogUtil
|
||||
*
|
||||
* That class should be very simple & always use LogFactory methods,
|
||||
* there is an intention to delegate all static methods to LogFactory.
|
||||
*/
|
||||
public class LogUtil {
|
||||
|
||||
public static Log getLog(Class<?> cl){
|
||||
return LogFactory.getLog(cl);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,6 @@ import javax.swing.JPanel;
|
|||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.osmand.DataExtraction.ExitListener;
|
||||
import com.osmand.MapTileDownloader.DownloadRequest;
|
||||
|
@ -48,7 +47,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected static final Log log = LogFactory.getLog(MapPanel.class);
|
||||
protected static final Log log = LogUtil.getLog(MapPanel.class);
|
||||
|
||||
public static Menu getMenuToChooseSource(final MapPanel panel){
|
||||
Menu tiles = new Menu("Source tile");
|
||||
|
|
|
@ -15,12 +15,11 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class MapTileDownloader {
|
||||
|
||||
private static MapTileDownloader downloader = null;
|
||||
private static Log log = LogFactory.getLog(MapTileDownloader.class);
|
||||
private static Log log = LogUtil.getLog(MapTileDownloader.class);
|
||||
|
||||
|
||||
private ThreadPoolExecutor threadPoolExecutor;
|
||||
|
|
|
@ -10,4 +10,6 @@ public class OsmandSettings {
|
|||
|
||||
public static ITileSource tileSource = DefaultLauncherConstants.MAP_defaultTileSource;
|
||||
|
||||
public static boolean showPoiOverMap = true;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.osmand;
|
||||
|
||||
|
||||
/**
|
||||
* This class is designed to put all to do's and link them with code.
|
||||
* The whole methods could be paste or just constants.
|
||||
|
@ -9,6 +10,9 @@ package com.osmand;
|
|||
public class ToDoConstants {
|
||||
|
||||
|
||||
// use unknown implementation (not written)? How to see debug msgs?
|
||||
// Explanation of how it works
|
||||
// The task
|
||||
public int CONFIG_COMMONS_LOGGING_IN_ANDROID = 1;
|
||||
|
||||
public int SAVE_SETTINGS_IN_ANDROID_BETWEEN_SESSION = 2;
|
||||
|
@ -19,4 +23,18 @@ public class ToDoConstants {
|
|||
// it is not editable in editor
|
||||
public int MAKE_MAP_PANEL_EDITABLE_IN_EDITOR = 4;
|
||||
|
||||
// common parts : work with cache on file system & in memory
|
||||
public int EXTRACT_COMMON_PARTS_FROM_MAPPANEL_AND_OSMMAPVIEW = 5;
|
||||
|
||||
|
||||
public int REVISE_MAP_ACTIVITY_HOLD_ALL_ZOOM_LATLON_IN_ONEPLACE = 6;
|
||||
|
||||
/**
|
||||
* Resource should cache all resources & free them
|
||||
* if there is no enough memory @see tile cache in tile view
|
||||
* @see poi index in map activity
|
||||
*/
|
||||
public int INTRODUCE_RESOURCE_MANAGER = 7;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ public class OsmBaseStorage extends DefaultHandler {
|
|||
}
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
try {
|
||||
factory.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
|
||||
return saxParser = factory.newSAXParser();
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new IllegalStateException(e);
|
||||
|
@ -108,6 +109,8 @@ public class OsmBaseStorage extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
|
||||
name = saxParser.isNamespaceAware() ? localName : name;
|
||||
|
||||
if(!parseStarted){
|
||||
if(!ELEM_OSM.equals(name) || !supportedVersions.contains(attributes.getValue(ATTR_VERSION))){
|
||||
throw new OsmVersionNotSupported();
|
||||
|
@ -150,6 +153,7 @@ public class OsmBaseStorage extends DefaultHandler {
|
|||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String name) throws SAXException {
|
||||
name = saxParser.isNamespaceAware() ? localName : name;
|
||||
if (ELEM_NODE.equals(name) || ELEM_WAY.equals(name) || ELEM_RELATION.equals(name)) {
|
||||
if(currentParsedEntity != null){
|
||||
if(acceptEntityToLoad(currentParsedEntity)){
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry excluding="**/DataExtraction*|**/MapPanel*|com/osmand/osm/io/OSMStorageWriter.java" kind="src" path="use"/>
|
||||
<classpathentry excluding="**/DataExtraction*|**/MapPanel*|com/osmand/osm/io/OSMStorageWriter.java|com/osmand/LogUtil.java" kind="src" path="use"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="lib" path="lib/bzip2-20090327.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
@ -10,20 +10,22 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".activities.MapActivity">
|
||||
<activity android:name=".activities.MapActivity" android:label="@string/app_name">
|
||||
</activity>
|
||||
<activity android:name=".activities.SettingsActivity"
|
||||
android:label="@string/settings_activity"></activity>
|
||||
|
||||
|
||||
<activity android:name=".activities.SettingsActivity" android:label="@string/settings_activity"></activity>
|
||||
</application>
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
|
||||
</manifest>
|
BIN
OsmAnd/lib/bzip2-20090327.jar
Normal file
BIN
OsmAnd/lib/bzip2-20090327.jar
Normal file
Binary file not shown.
|
@ -3,10 +3,12 @@
|
|||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<com.osmand.views.OsmandMapTileView android:id="@+id/MapView" android:layout_width="wrap_content" android:layout_height="wrap_content"></com.osmand.views.OsmandMapTileView>
|
||||
<com.osmand.views.PointOfView android:id="@+id/PointOfView" android:layout_width="wrap_content" android:layout_height="wrap_content"></com.osmand.views.PointOfView>
|
||||
<com.osmand.views.OsmandMapTileView android:id="@+id/MapView" android:layout_width="fill_parent" android:layout_height="fill_parent"></com.osmand.views.OsmandMapTileView>
|
||||
<com.osmand.views.PointOfView android:id="@+id/PointOfView" android:layout_width="fill_parent" android:layout_height="fill_parent"></com.osmand.views.PointOfView>
|
||||
<com.osmand.views.POIMapLayer android:id="@+id/PoiMapLayer" android:layout_width="fill_parent" android:layout_height="fill_parent"></com.osmand.views.POIMapLayer>
|
||||
<ZoomControls android:id="@+id/ZoomControls01"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|right"></ZoomControls>
|
||||
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|right" android:id="@+id/BackToLocation" android:background="@drawable/icon"></ImageButton>
|
||||
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/settings_activity" android:layout_gravity="top|left" android:id="@+id/GoToSettingsButton" ></Button>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="show_poi_over_map_description">Show POI on map</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">Map tile source</string>
|
||||
<string name="map_source">Map source</string>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<PreferenceCategory android:title="@string/map_preferences">
|
||||
<CheckBoxPreference android:key="show_gps_location_text" android:title="@string/show_location" android:summary="@string/show_gps_coordinates_text"></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>
|
||||
</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>
|
||||
|
|
152
OsmAnd/src/com/osmand/LogUtil.java
Normal file
152
OsmAnd/src/com/osmand/LogUtil.java
Normal file
|
@ -0,0 +1,152 @@
|
|||
package com.osmand;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
/**
|
||||
* That class is replacing of standard LogFactory due to
|
||||
* problems with Android implementation of LogFactory.
|
||||
*
|
||||
* 1. It is impossible to replace standard LogFactory (that is hidden in android.jar)
|
||||
* 2. Implementation of LogFactory always creates Logger.getLogger(String name)
|
||||
* 3. + It is possible to enable logger level by calling
|
||||
* Logger.getLogger("com.osmand").setLevel(Level.ALL);
|
||||
* 4. Logger goes to low level android.util.Log where android.util.Log#isLoggable(String, int) is checked
|
||||
* String tag -> is string of length 23 (stripped full class name)
|
||||
* 5. It is impossible to set for all tags debug level (info is default) - android.util.Log#isLoggable(String, int).
|
||||
*
|
||||
*/
|
||||
public class LogUtil {
|
||||
public static String TAG = "com.osmand";
|
||||
private static class OsmandLogImplementation implements Log {
|
||||
|
||||
private final String fullName;
|
||||
private final String name;
|
||||
|
||||
public OsmandLogImplementation(String name){
|
||||
this.fullName = name;
|
||||
this.name = fullName.substring(fullName.lastIndexOf('.') + 1);
|
||||
}
|
||||
@Override
|
||||
public void debug(Object message) {
|
||||
if(isDebugEnabled()){
|
||||
android.util.Log.d(TAG, name + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Object message, Throwable t) {
|
||||
if(isDebugEnabled()){
|
||||
android.util.Log.d(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message) {
|
||||
if(isErrorEnabled()){
|
||||
android.util.Log.e(TAG, name + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message, Throwable t) {
|
||||
if(isErrorEnabled()){
|
||||
android.util.Log.e(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(Object message) {
|
||||
if(isFatalEnabled()){
|
||||
android.util.Log.e(TAG, name + " " + message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(Object message, Throwable t) {
|
||||
if(isFatalEnabled()){
|
||||
android.util.Log.e(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message) {
|
||||
if(isInfoEnabled()){
|
||||
android.util.Log.i(TAG, name + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message, Throwable t) {
|
||||
if(isInfoEnabled()){
|
||||
android.util.Log.i(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isErrorEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFatalEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfoEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTraceEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWarnEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.WARN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Object message) {
|
||||
if(isTraceEnabled()){
|
||||
android.util.Log.d(TAG, name + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Object message, Throwable t) {
|
||||
if(isTraceEnabled()){
|
||||
android.util.Log.d(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message) {
|
||||
if(isWarnEnabled()){
|
||||
android.util.Log.w(TAG, name + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message, Throwable t) {
|
||||
if(isWarnEnabled()){
|
||||
android.util.Log.w(TAG, name + " " + message, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Log getLog(String name){
|
||||
return new OsmandLogImplementation(name);
|
||||
}
|
||||
|
||||
public static Log getLog(Class<?> cl){
|
||||
return getLog(cl.getName());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,13 @@
|
|||
package com.osmand.activities;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.tools.bzip2.CBZip2InputStream;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
@ -16,11 +23,20 @@ import android.widget.Button;
|
|||
import android.widget.ImageButton;
|
||||
import android.widget.ZoomControls;
|
||||
|
||||
import com.osmand.Algoritms;
|
||||
import com.osmand.IMapLocationListener;
|
||||
import com.osmand.LogUtil;
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.R;
|
||||
import com.osmand.data.DataTileManager;
|
||||
import com.osmand.osm.Entity;
|
||||
import com.osmand.osm.LatLon;
|
||||
import com.osmand.osm.MapUtils;
|
||||
import com.osmand.osm.Node;
|
||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||
import com.osmand.osm.io.OsmBaseStorage;
|
||||
import com.osmand.views.OsmandMapTileView;
|
||||
import com.osmand.views.POIMapLayer;
|
||||
import com.osmand.views.PointOfView;
|
||||
|
||||
public class MapActivity extends Activity implements LocationListener, IMapLocationListener {
|
||||
|
@ -35,6 +51,13 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
|
||||
private PointOfView pointOfView;
|
||||
|
||||
private static final String TILES_PATH = "osmand/tiles/";
|
||||
private static final String POI_PATH = "osmand/poi/";
|
||||
private static final org.apache.commons.logging.Log log = LogUtil.getLog(MapActivity.class);
|
||||
|
||||
private DataTileManager<Node> indexPOI;
|
||||
|
||||
private POIMapLayer poiMapLayer;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -47,7 +70,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
|
||||
setContentView(R.layout.main);
|
||||
mapView = (OsmandMapTileView) findViewById(R.id.MapView);
|
||||
mapView.setFileWithTiles(new File(Environment.getExternalStorageDirectory(), "osmand/tiles/"));
|
||||
mapView.setFileWithTiles(new File(Environment.getExternalStorageDirectory(), TILES_PATH));
|
||||
mapView.addMapLocationListener(this);
|
||||
|
||||
ZoomControls zoomControls = (ZoomControls) findViewById(R.id.ZoomControls01);
|
||||
|
@ -55,12 +78,14 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
mapView.setZoom(mapView.getZoom() + 1);
|
||||
poiMapLayer.setCurrentLocationAndZoom(poiMapLayer.getCurrentLocation(), mapView.getZoom());
|
||||
}
|
||||
});
|
||||
zoomControls.setOnZoomOutClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mapView.setZoom(mapView.getZoom() - 1);
|
||||
poiMapLayer.setCurrentLocationAndZoom(poiMapLayer.getCurrentLocation(), mapView.getZoom());
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -95,8 +120,64 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
|
||||
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
|
||||
indexPOI = indexPOI();
|
||||
|
||||
poiMapLayer = (POIMapLayer)findViewById(R.id.PoiMapLayer);
|
||||
poiMapLayer.setNodeManager(indexPOI);
|
||||
|
||||
}
|
||||
|
||||
private static final boolean indexPOIFlag = false;
|
||||
|
||||
public DataTileManager<Node> indexPOI(){
|
||||
File file = new File(Environment.getExternalStorageDirectory(), POI_PATH);
|
||||
|
||||
DataTileManager<Node> r = new DataTileManager<Node>();
|
||||
if(file.exists() && file.canRead() && indexPOIFlag){
|
||||
for(File f : file.listFiles() ){
|
||||
if(f.getName().endsWith(".bz2") || f.getName().endsWith(".osm") ){
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("Starting index POI " + f.getAbsolutePath());
|
||||
}
|
||||
boolean zipped = f.getName().endsWith(".bz2");
|
||||
InputStream stream = null;
|
||||
try {
|
||||
OsmBaseStorage storage = new OsmBaseStorage();
|
||||
stream = new FileInputStream(f);
|
||||
stream = new BufferedInputStream(stream);
|
||||
if (zipped) {
|
||||
if (stream.read() != 'B' || stream.read() != 'Z') {
|
||||
log.error("Can't read poi file " + f.getAbsolutePath()
|
||||
+ "The source stream must start with the characters BZ if it is to be read as a BZip2 stream.");
|
||||
continue;
|
||||
} else {
|
||||
stream = new CBZip2InputStream(stream);
|
||||
}
|
||||
}
|
||||
storage.parseOSM(stream);
|
||||
for(Entity e : storage.getRegisteredEntities().values()){
|
||||
if(e instanceof Node && e.getTag(OSMTagKey.AMENITY) != null){
|
||||
Node n = (Node) e;
|
||||
r.registerObject(n.getLatitude(), n.getLongitude(), n);
|
||||
}
|
||||
}
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("Finishing index POI " + f.getAbsolutePath());
|
||||
}
|
||||
} catch(IOException e){
|
||||
log.error("Can't read poi file " + f.getAbsolutePath(), e);
|
||||
} catch (SAXException e) {
|
||||
log.error("Can't read poi file " + f.getAbsolutePath(), e);
|
||||
} finally {
|
||||
Algoritms.closeStream(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
|
@ -148,6 +229,12 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
// TODO Auto-generated method stub
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
|
@ -162,16 +249,31 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
|
|||
if(mapView.getMap() != OsmandSettings.tileSource){
|
||||
mapView.setMap(OsmandSettings.tileSource);
|
||||
}
|
||||
if((poiMapLayer.getVisibility() == View.VISIBLE) != OsmandSettings.showPoiOverMap){
|
||||
if(OsmandSettings.showPoiOverMap){
|
||||
poiMapLayer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
poiMapLayer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void locationChanged(double newLatitude, double newLongitude, Object source) {
|
||||
// when user
|
||||
// when user start dragging
|
||||
if(source == mapView && lastKnownLocation != null){
|
||||
linkLocationWithMap = false;
|
||||
backToLocation.setVisibility(View.VISIBLE);
|
||||
}
|
||||
poiMapLayer.setCurrentLocationAndZoom(new LatLon(newLatitude, newLongitude), mapView.getZoom());
|
||||
|
||||
validatePointOfView();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,6 @@ package com.osmand.activities;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.osmand.DefaultLauncherConstants;
|
||||
import com.osmand.R;
|
||||
import com.osmand.R.xml;
|
||||
import com.osmand.map.TileSourceManager;
|
||||
import com.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
|
@ -16,11 +10,19 @@ import android.preference.PreferenceActivity;
|
|||
import android.preference.PreferenceScreen;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.R;
|
||||
import com.osmand.map.TileSourceManager;
|
||||
import com.osmand.map.TileSourceManager.TileSourceTemplate;
|
||||
|
||||
public class SettingsActivity extends PreferenceActivity implements OnPreferenceChangeListener {
|
||||
private static final String use_internet_to_download_tiles = "use_internet_to_download_tiles";
|
||||
private static final String show_gps_location_text = "show_gps_location_text";
|
||||
private static final String map_tile_sources = "map_tile_sources";
|
||||
private static final String show_poi_over_map = "show_poi_over_map";
|
||||
|
||||
private CheckBoxPreference showGpsLocation;
|
||||
private CheckBoxPreference showPoiOnMap;
|
||||
private CheckBoxPreference useInternetToDownloadTiles;
|
||||
private ListPreference tileSourcePreference;
|
||||
|
||||
|
@ -33,6 +35,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
|||
showGpsLocation.setOnPreferenceChangeListener(this);
|
||||
useInternetToDownloadTiles =(CheckBoxPreference) screen.findPreference(use_internet_to_download_tiles);
|
||||
useInternetToDownloadTiles.setOnPreferenceChangeListener(this);
|
||||
showPoiOnMap =(CheckBoxPreference) screen.findPreference(show_poi_over_map);
|
||||
showPoiOnMap.setOnPreferenceChangeListener(this);
|
||||
|
||||
tileSourcePreference =(ListPreference) screen.findPreference(map_tile_sources);
|
||||
tileSourcePreference.setOnPreferenceChangeListener(this);
|
||||
|
@ -43,8 +47,10 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
useInternetToDownloadTiles.setChecked(DefaultLauncherConstants.loadMissingImages);
|
||||
showGpsLocation.setChecked(DefaultLauncherConstants.showGPSCoordinates);
|
||||
useInternetToDownloadTiles.setChecked(OsmandSettings.useInternetToDownloadTiles);
|
||||
showGpsLocation.setChecked(OsmandSettings.showGPSLocationOnMap);
|
||||
showPoiOnMap.setChecked(OsmandSettings.showPoiOverMap);
|
||||
|
||||
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
|
||||
String[] entries = new String[list.size()];
|
||||
for(int i=0; i<list.size(); i++){
|
||||
|
@ -52,20 +58,24 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
|||
}
|
||||
tileSourcePreference.setEntries(entries);
|
||||
tileSourcePreference.setEntryValues(entries);
|
||||
tileSourcePreference.setValue(DefaultLauncherConstants.MAP_defaultTileSource.getName());
|
||||
tileSourcePreference.setValue(OsmandSettings.tileSource.getName());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if(preference == showGpsLocation){
|
||||
DefaultLauncherConstants.showGPSCoordinates = (Boolean) newValue;
|
||||
OsmandSettings.showGPSLocationOnMap = (Boolean) newValue;
|
||||
} else if(preference == showPoiOnMap){
|
||||
OsmandSettings.showPoiOverMap = (Boolean) newValue;
|
||||
} else if(preference == useInternetToDownloadTiles){
|
||||
DefaultLauncherConstants.loadMissingImages = (Boolean) newValue;
|
||||
} else if(preference == tileSourcePreference){
|
||||
OsmandSettings.useInternetToDownloadTiles = (Boolean) newValue;
|
||||
} else if (preference == tileSourcePreference) {
|
||||
String newTile = newValue.toString();
|
||||
for(TileSourceTemplate t : TileSourceManager.getKnownSourceTemplates()){
|
||||
if(t.getName().equals(newTile)){
|
||||
DefaultLauncherConstants.MAP_defaultTileSource = t;
|
||||
for (TileSourceTemplate t : TileSourceManager.getKnownSourceTemplates()) {
|
||||
if (t.getName().equals(newTile)) {
|
||||
OsmandSettings.tileSource = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package com.osmand.views;
|
||||
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -18,14 +21,19 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.os.Handler;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
|
||||
import com.osmand.DefaultLauncherConstants;
|
||||
import com.osmand.IMapLocationListener;
|
||||
import com.osmand.LogUtil;
|
||||
import com.osmand.MapTileDownloader;
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.MapTileDownloader.DownloadRequest;
|
||||
|
@ -33,15 +41,18 @@ import com.osmand.MapTileDownloader.IMapDownloaderCallback;
|
|||
import com.osmand.map.ITileSource;
|
||||
import com.osmand.osm.MapUtils;
|
||||
|
||||
public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
||||
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback, Callback{
|
||||
|
||||
protected final int emptyTileDivisor = DefaultLauncherConstants.MAP_divNonLoadedImage;
|
||||
protected final int maxImgCacheSize = 512;
|
||||
|
||||
protected final int maxImgCacheSize = 96;
|
||||
protected int drawCoordinatesX = 0;
|
||||
protected int drawCoordinatesY = 55;
|
||||
|
||||
protected static final Log log = LogFactory.getLog(OsmandMapTileView.class);
|
||||
protected final int timeForDraggingAnimation = 300;
|
||||
protected final int minimumDistanceForDraggingAnimation = 40;
|
||||
|
||||
|
||||
protected static final Log log = LogUtil.getLog(OsmandMapTileView.class);
|
||||
/**
|
||||
* file or directory with tiles
|
||||
*/
|
||||
|
@ -66,28 +77,18 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
|
||||
private MapTileDownloader downloader = MapTileDownloader.getInstance();
|
||||
|
||||
Map<String, Bitmap> cacheOfImages = new HashMap<String, Bitmap>();
|
||||
|
||||
// cached data to draw images
|
||||
private Bitmap[][] images;
|
||||
// this value is always <= 0
|
||||
private int xStartingImage = 0;
|
||||
// this value is always <= 0
|
||||
private int yStartingImage = 0;
|
||||
|
||||
Map<String, Bitmap> cacheOfImages = new WeakHashMap<String, Bitmap>();
|
||||
private PointF startDragging = null;
|
||||
private boolean isStartedDragging = false;
|
||||
private double startDraggingX = 0d;
|
||||
private double startDraggingY = 0d;
|
||||
private PointF initStartDragging = null;
|
||||
|
||||
Paint paintGrayFill;
|
||||
Paint paintWhiteFill;
|
||||
Paint paintBlack;
|
||||
final Handler mHandler = new Handler();
|
||||
private AnimatedDragging animatedDraggingThread;
|
||||
|
||||
// Create runnable for posting
|
||||
final Runnable invalidateView = new Runnable() {
|
||||
public void run() {
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public OsmandMapTileView(Context context, AttributeSet attrs) {
|
||||
|
@ -113,9 +114,10 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
paintBlack.setStyle(Style.STROKE);
|
||||
paintBlack.setColor(Color.BLACK);
|
||||
|
||||
prepareImage();
|
||||
setClickable(true);
|
||||
getHolder().addCallback(this);
|
||||
downloader.setDownloaderCallback(this);
|
||||
asyncLoadingTiles.start();
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,31 +126,103 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
}
|
||||
|
||||
|
||||
public void dragTo(PointF p){
|
||||
double dx = (startDragging.x - (double)p.x)/getTileSize();
|
||||
double dy = (startDragging.y - (double)p.y)/getTileSize();
|
||||
public void dragTo(double fromX, double fromY, double toX, double toY){
|
||||
double dx = (fromX - toX)/getTileSize();
|
||||
double dy = (fromY - toY)/getTileSize();
|
||||
this.latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
|
||||
this.longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
|
||||
prepareImage();
|
||||
fireMapLocationListeners(this);
|
||||
// TODO
|
||||
// fireMapLocationListeners(this);
|
||||
}
|
||||
|
||||
public class AnimatedDragging extends Thread {
|
||||
private float curX;
|
||||
private float curY;
|
||||
private float vx;
|
||||
private float vy;
|
||||
private float ax;
|
||||
private float ay;
|
||||
private byte dirX;
|
||||
private byte dirY;
|
||||
private long time = System.currentTimeMillis();
|
||||
private boolean stopped;
|
||||
private final float a = 0.0005f;
|
||||
|
||||
public AnimatedDragging(float dTime, float startX, float startY, float endX, float endY) {
|
||||
vx = Math.abs((endX - startX)/dTime);
|
||||
vy = Math.abs((endY - startY)/dTime);
|
||||
dirX = (byte) (endX > startX ? 1 : -1);
|
||||
dirY = (byte) (endY > startY ? 1 : -1);
|
||||
ax = vx * a;
|
||||
ay = vy * a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while ((vx > 0 || vy > 0) && !isStartedDragging && !stopped) {
|
||||
sleep((long) (40d/(Math.max(vx, vy)+0.45)));
|
||||
long curT = System.currentTimeMillis();
|
||||
int dt = (int) (curT - time);
|
||||
float newX = vx > 0 ? curX + dirX * vx * dt : curX;
|
||||
float newY = vy > 0 ? curY + dirY * vy * dt : curY;
|
||||
if(!isStartedDragging){
|
||||
dragTo(curX, curY, newX, newY);
|
||||
}
|
||||
vx -= ax * dt;
|
||||
vy -= ay * dt;
|
||||
time = curT;
|
||||
curX = newX;
|
||||
curY = newY;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
animatedDraggingThread = null;
|
||||
}
|
||||
|
||||
public void stopEvaluation(){
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if(startDragging == null){
|
||||
startDragging = new PointF(event.getX(), event.getY());
|
||||
if(animatedDraggingThread != null){
|
||||
animatedDraggingThread.stopEvaluation();
|
||||
}
|
||||
if(!isStartedDragging){
|
||||
startDraggingX = event.getX();
|
||||
startDraggingY = event.getY();
|
||||
isStartedDragging = true;
|
||||
initStartDragging = new PointF(event.getX(), event.getY());
|
||||
}
|
||||
} else if(event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if(startDragging != null){
|
||||
dragTo(new PointF(event.getX(), event.getY()));
|
||||
startDragging = null;
|
||||
if(isStartedDragging){
|
||||
dragTo(startDraggingX, startDraggingY, event.getX(), event.getY());
|
||||
if(event.getEventTime() - event.getDownTime() < timeForDraggingAnimation &&
|
||||
Math.abs(event.getX() - initStartDragging.x) + Math.abs(event.getY() - initStartDragging.y) > minimumDistanceForDraggingAnimation){
|
||||
float timeDist = (int) (event.getEventTime() - event.getDownTime());
|
||||
if(timeDist < 20){
|
||||
timeDist = 20;
|
||||
}
|
||||
animatedDraggingThread = new AnimatedDragging(timeDist, initStartDragging.x, initStartDragging.y,
|
||||
event.getX(), event.getY());
|
||||
isStartedDragging = false;
|
||||
animatedDraggingThread.start();
|
||||
}
|
||||
isStartedDragging = false;
|
||||
|
||||
}
|
||||
} else if(event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if(startDragging != null){
|
||||
PointF p = new PointF(event.getX(), event.getY());
|
||||
dragTo(p);
|
||||
startDragging = p;
|
||||
if(isStartedDragging){
|
||||
dragTo(startDraggingX, startDraggingY, event.getX(), event.getY());
|
||||
startDraggingX = event.getX();
|
||||
startDraggingY = event.getY();
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
|
@ -178,31 +252,6 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.drawRect(0,0, getWidth(), getHeight(), paintWhiteFill);
|
||||
if (images != null) {
|
||||
for (int i = 0; i < images.length; i++) {
|
||||
for (int j = 0; j < images[i].length; j++) {
|
||||
if (images[i][j] == null) {
|
||||
drawEmptyTile(canvas, i*getTileSize()+xStartingImage, j * getTileSize() + yStartingImage);
|
||||
} else {
|
||||
canvas.drawBitmap(images[i][j], i * getTileSize() + xStartingImage, j * getTileSize() + yStartingImage, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas.drawCircle(getWidth()/2, getHeight()/2, 3, paintBlack);
|
||||
canvas.drawCircle(getWidth()/2, getHeight()/2, 6, paintBlack);
|
||||
if (OsmandSettings.showGPSLocationOnMap) {
|
||||
canvas.drawText(MessageFormat.format("Lat : {0}, lon : {1}, zoom : {2}", latitude, longitude, zoom),
|
||||
drawCoordinatesX, drawCoordinatesY, paintBlack);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
prepareImage();
|
||||
|
@ -214,22 +263,55 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
return map.getName() +"/"+zoom+"/"+(x) +"/"+y+ext+".tile";
|
||||
}
|
||||
|
||||
public Bitmap getImageFor(int x, int y, int zoom, boolean loadIfNeeded) {
|
||||
if (map == null || fileWithTiles == null || !fileWithTiles.canRead()) {
|
||||
return null;
|
||||
public AsyncLoadingThread asyncLoadingTiles = new AsyncLoadingThread();
|
||||
|
||||
public class AsyncLoadingThread extends Thread {
|
||||
Map<String, DownloadRequest> requests = Collections.synchronizedMap(new LinkedHashMap<String, DownloadRequest>());
|
||||
|
||||
public AsyncLoadingThread(){
|
||||
super("Async loading tiles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(true){
|
||||
try {
|
||||
boolean update = false;
|
||||
while(!requests.isEmpty()){
|
||||
String f = requests.keySet().iterator().next();
|
||||
DownloadRequest r = requests.remove(f);
|
||||
// TODO last param
|
||||
getImageForTile(r.xTile, r.yTile, r.zoom, OsmandSettings.useInternetToDownloadTiles);
|
||||
update = true;
|
||||
}
|
||||
if(update){
|
||||
prepareImage();
|
||||
}
|
||||
sleep(350);
|
||||
} catch (InterruptedException e) {
|
||||
log.error(e);
|
||||
} catch (RuntimeException e){
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void requestToLoadImage(String s, DownloadRequest req){
|
||||
requests.put(s, req);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private Bitmap getImageForTile(int x, int y, int zoom, boolean loadIfNeeded){
|
||||
String file = getFileForImage(x, y, zoom, map.getTileFormat());
|
||||
if (cacheOfImages.get(file) == null) {
|
||||
if(fileWithTiles == null || !fileWithTiles.canRead()){
|
||||
return null;
|
||||
}
|
||||
File en = new File(fileWithTiles, file);
|
||||
if (cacheOfImages.size() > maxImgCacheSize) {
|
||||
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
||||
for (int i = 0; i < list.size(); i += 2) {
|
||||
Bitmap bmp = cacheOfImages.remove(list.get(i));
|
||||
bmp.recycle();
|
||||
}
|
||||
System.gc();
|
||||
onLowMemory();
|
||||
}
|
||||
|
||||
if (!downloader.isFileCurrentlyDownloaded(en)) {
|
||||
if (en.exists()) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
@ -238,7 +320,11 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
log.debug("Loaded file : " + file + " " + -(time - System.currentTimeMillis()) + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
if(loadIfNeeded && cacheOfImages.get(file) == null){
|
||||
ConnectivityManager mgr = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo info = mgr.getActiveNetworkInfo();
|
||||
if (info != null && info.isConnected()) {
|
||||
String urlToLoad = map.getUrlToLoad(x, y, zoom);
|
||||
if (urlToLoad != null) {
|
||||
downloader.requestToDownload(urlToLoad, new DownloadRequest(en, x, y, zoom));
|
||||
|
@ -246,55 +332,110 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cacheOfImages.get(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getImageFor(int x, int y, int zoom, boolean loadIfNeeded) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
String file = getFileForImage(x, y, zoom, map.getTileFormat());
|
||||
if (cacheOfImages.get(file) == null && loadIfNeeded) {
|
||||
// TODO use loadIfNeeded
|
||||
asyncLoadingTiles.requestToLoadImage(file, new DownloadRequest(null, x, y, zoom));
|
||||
}
|
||||
return cacheOfImages.get(file);
|
||||
}
|
||||
|
||||
|
||||
public void tileDownloaded(String dowloadedUrl, DownloadRequest request) {
|
||||
int tileSize = getTileSize();
|
||||
double xTileLeft = getXTile() - getWidth() / (2d * tileSize);
|
||||
double yTileUp = getYTile() - getHeight() / (2d * tileSize);
|
||||
int i = request.xTile - (int)xTileLeft;
|
||||
int j = request.yTile - (int)yTileUp;
|
||||
if(request.zoom == this.zoom &&
|
||||
(i >= 0 && i < images.length) && (j >= 0 && j < images[i].length)) {
|
||||
images[i][j] = getImageFor(request.xTile, request.yTile, zoom, false);
|
||||
mHandler.post(invalidateView);
|
||||
int xTileLeft = (int) Math.floor(getXTile() - getWidth() / (2d * getTileSize()));
|
||||
int yTileUp = (int) Math.floor(getYTile() - getHeight() / (2d * getTileSize()));
|
||||
int startingX = (int) ((xTileLeft - getXTile()) * getTileSize() + getWidth() / 2);
|
||||
int startingY = (int) ((yTileUp - getYTile()) * getTileSize() + getHeight() / 2);
|
||||
int i = (request.xTile - xTileLeft) * getTileSize() + startingX;
|
||||
int j = (request.yTile - yTileUp) * getTileSize() + startingY;
|
||||
if (request.zoom == this.zoom &&
|
||||
(i + getTileSize() >= 0 && i < getWidth()) && (j + getTileSize() >= 0 && j < getHeight())) {
|
||||
SurfaceHolder holder = getHolder();
|
||||
synchronized (holder) {
|
||||
Canvas canvas = holder.lockCanvas(new Rect(i, j, getTileSize() + i, getTileSize() + j));
|
||||
if (canvas != null) {
|
||||
try {
|
||||
Bitmap bmp = getImageFor(request.xTile, request.yTile, zoom, true);
|
||||
if (bmp == null) {
|
||||
drawEmptyTile(canvas, i, j);
|
||||
} else {
|
||||
canvas.drawBitmap(bmp, i, j, null);
|
||||
}
|
||||
drawOverMap(canvas);
|
||||
} finally {
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private MessageFormat formatOverMap = new MessageFormat("Lat : {0}, lon : {1}, zoom : {2}, mem : {3}");
|
||||
java.util.Formatter formatterOMap = new java.util.Formatter();
|
||||
private ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
|
||||
private void drawOverMap(Canvas canvas){
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, 3, paintBlack);
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, 6, paintBlack);
|
||||
if (OsmandSettings.showGPSLocationOnMap) {
|
||||
float f= (Runtime.getRuntime().totalMemory())/ 1e6f;
|
||||
formatterOMap = new Formatter();
|
||||
canvas.drawText(formatterOMap.format("Lat : %.3f, lon : %.3f, zoom : %d, mem : %.3f", latitude, longitude, zoom, f).toString(),
|
||||
drawCoordinatesX, drawCoordinatesY, paintBlack);
|
||||
// canvas.drawText(formatOverMap.format(new Object[]{latitude, longitude, zoom, f}), drawCoordinatesX,
|
||||
// drawCoordinatesY, paintBlack);
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareImage(){
|
||||
prepareImage(OsmandSettings.useInternetToDownloadTiles);
|
||||
}
|
||||
|
||||
public void prepareImage(boolean loadNecessaryImages) {
|
||||
if (loadNecessaryImages) {
|
||||
public void prepareImage() {
|
||||
if (OsmandSettings.useInternetToDownloadTiles) {
|
||||
downloader.refuseAllPreviousRequests();
|
||||
}
|
||||
double xTileLeft = getXTile() - getWidth() / (2d * getTileSize());
|
||||
double xTileRight = getXTile() + getWidth() / (2d * getTileSize());
|
||||
double yTileUp = getYTile() - getHeight() / (2d * getTileSize());
|
||||
double yTileDown = getYTile() + getHeight() / (2d * getTileSize());
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int tileSize = getTileSize();
|
||||
|
||||
xStartingImage = -(int) ((xTileLeft - Math.floor(xTileLeft)) * getTileSize());
|
||||
yStartingImage = -(int) ((yTileUp - Math.floor(yTileUp)) * getTileSize());
|
||||
int xTileLeft = (int) Math.floor(getXTile() - width / (2d * getTileSize()));
|
||||
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);
|
||||
|
||||
int tileXCount = ((int) xTileRight - (int) xTileLeft + 1);
|
||||
int tileYCount = ((int) yTileDown - (int) yTileUp + 1);
|
||||
images = new Bitmap[tileXCount][tileYCount];
|
||||
for (int i = 0; i < images.length; i++) {
|
||||
for (int j = 0; j < images[i].length; j++) {
|
||||
images[i][j] = getImageFor((int) xTileLeft + i, (int) yTileUp + j, zoom, loadNecessaryImages);
|
||||
SurfaceHolder holder = getHolder();
|
||||
synchronized (holder) {
|
||||
Canvas canvas = holder.lockCanvas();
|
||||
if (canvas != null) {
|
||||
try {
|
||||
for (int i = 0; i * tileSize + startingX < width; i++) {
|
||||
for (int j = 0; j * tileSize + startingY < height; j++) {
|
||||
Bitmap bmp = getImageFor(xTileLeft + i, yTileUp + j, zoom, true);
|
||||
if (bmp == null) {
|
||||
drawEmptyTile(canvas, i * tileSize + startingX, j * tileSize + startingY);
|
||||
} else {
|
||||
canvas.drawBitmap(bmp, i * tileSize + startingX, j * tileSize + startingY, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
drawOverMap(canvas);
|
||||
} finally {
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setZoom(int zoom){
|
||||
if (map == null || (map.getMaximumZoomSupported() >= zoom && map.getMinimumZoomSupported() <= zoom)) {
|
||||
if(animatedDraggingThread != null){
|
||||
animatedDraggingThread.stopEvaluation();
|
||||
}
|
||||
this.zoom = zoom;
|
||||
prepareImage();
|
||||
}
|
||||
|
@ -344,6 +485,19 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
}
|
||||
|
||||
|
||||
public void onLowMemory(){
|
||||
log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size());
|
||||
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
|
||||
// remove first images (as we think they are older)
|
||||
for (int i = 0; i < list.size()/2; i ++) {
|
||||
Bitmap bmp = cacheOfImages.remove(list.get(i));
|
||||
if(bmp != null){
|
||||
bmp.recycle();
|
||||
}
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
|
||||
|
||||
public void addMapLocationListener(IMapLocationListener l){
|
||||
listeners.add(l);
|
||||
|
@ -359,7 +513,21 @@ public class OsmandMapTileView extends View implements IMapDownloaderCallback {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
prepareImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
prepareImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
// TODO clear cache ?
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
154
OsmAnd/src/com/osmand/views/POIMapLayer.java
Normal file
154
OsmAnd/src/com/osmand/views/POIMapLayer.java
Normal file
|
@ -0,0 +1,154 @@
|
|||
package com.osmand.views;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.osmand.DefaultLauncherConstants;
|
||||
import com.osmand.LogUtil;
|
||||
import com.osmand.OsmandSettings;
|
||||
import com.osmand.data.DataTileManager;
|
||||
import com.osmand.map.ITileSource;
|
||||
import com.osmand.osm.LatLon;
|
||||
import com.osmand.osm.MapUtils;
|
||||
import com.osmand.osm.Node;
|
||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||
|
||||
public class POIMapLayer extends View {
|
||||
private DataTileManager<Node> nodeManager = null;
|
||||
private LatLon currentLocation = null;
|
||||
private int zoomLevel = DefaultLauncherConstants.MAP_startMapZoom;
|
||||
private Map<Node, Point> points = new LinkedHashMap<Node, Point>();
|
||||
private Paint pointUI;
|
||||
private static final int radiusClick = 16;
|
||||
private Toast previousShownToast =null;
|
||||
private final static Log log = LogUtil.getLog(POIMapLayer.class);
|
||||
|
||||
|
||||
public POIMapLayer(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initUI();
|
||||
}
|
||||
|
||||
public POIMapLayer(Context context) {
|
||||
super(context);
|
||||
initUI();
|
||||
}
|
||||
|
||||
private void initUI() {
|
||||
pointUI = new Paint();
|
||||
pointUI.setColor(Color.CYAN);
|
||||
pointUI.setAlpha(150);
|
||||
pointUI.setAntiAlias(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
for(Node n : points.keySet()){
|
||||
Point p = points.get(n);
|
||||
canvas.drawCircle(p.x, p.y, radiusClick/2, pointUI);
|
||||
}
|
||||
}
|
||||
|
||||
public void preparePoints() {
|
||||
points.clear();
|
||||
if (nodeManager != null && currentLocation != null) {
|
||||
double tileNumberX = MapUtils.getTileNumberX(zoomLevel, currentLocation.getLongitude());
|
||||
double tileNumberY = MapUtils.getTileNumberY(zoomLevel, currentLocation.getLatitude());
|
||||
double xTileLeft = tileNumberX - getWidth() / (2d * getTileSize());
|
||||
double xTileRight = tileNumberX + getWidth() / (2d * getTileSize());
|
||||
double yTileUp = tileNumberY - getHeight() / (2d * getTileSize());
|
||||
double yTileDown = tileNumberY + getHeight() / (2d * getTileSize());
|
||||
|
||||
List<Node> objects = nodeManager.getObjects(MapUtils.getLatitudeFromTile(zoomLevel, yTileUp),
|
||||
MapUtils.getLongitudeFromTile(zoomLevel, xTileLeft),
|
||||
MapUtils.getLatitudeFromTile(zoomLevel, yTileDown),
|
||||
MapUtils.getLongitudeFromTile(zoomLevel, xTileRight));
|
||||
for (Node o : objects) {
|
||||
double tileX = MapUtils.getTileNumberX(zoomLevel, o.getLongitude());
|
||||
int x = (int) ((tileX - xTileLeft) * getTileSize());
|
||||
double tileY = MapUtils.getTileNumberY(zoomLevel, o.getLatitude());
|
||||
int y = (int) ((tileY - yTileUp) * getTileSize());
|
||||
points.put(o, new Point(x, y));
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if(event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
|
||||
if(previousShownToast != null){
|
||||
previousShownToast.cancel();
|
||||
previousShownToast = null;
|
||||
}
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
|
||||
for(Node n : points.keySet()){
|
||||
Point p = points.get(n);
|
||||
if(Math.abs(p.x - x) <= radiusClick && Math.abs(p.y - y) <= radiusClick){
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("This is an amenity : \n");
|
||||
b.append("type - ").append(n.getTag(OSMTagKey.AMENITY)).append("\n");
|
||||
if(n.getTag(OSMTagKey.NAME) != null){
|
||||
b.append("name - ").append(n.getTag(OSMTagKey.NAME)).append("\n");
|
||||
}
|
||||
b.append("id - ").append(n.getId());
|
||||
|
||||
previousShownToast = Toast.makeText(getContext(), b.toString(), Toast.LENGTH_SHORT);
|
||||
previousShownToast.show();
|
||||
// TODO use precision
|
||||
log.debug("Precision is " + event.getXPrecision());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setCurrentLocationAndZoom(LatLon currentLocation, int zoom) {
|
||||
this.currentLocation = currentLocation;
|
||||
this.zoomLevel = zoom;
|
||||
preparePoints();
|
||||
}
|
||||
|
||||
public int getTileSize(){
|
||||
ITileSource source = OsmandSettings.tileSource;
|
||||
return source == null ? 256 : source.getTileSize();
|
||||
|
||||
}
|
||||
|
||||
public void setNodeManager(DataTileManager<Node> nodeManager) {
|
||||
this.nodeManager = nodeManager;
|
||||
preparePoints();
|
||||
}
|
||||
|
||||
public LatLon getCurrentLocation() {
|
||||
return currentLocation;
|
||||
}
|
||||
|
||||
public DataTileManager<Node> getNodeManager() {
|
||||
return nodeManager;
|
||||
}
|
||||
|
||||
|
||||
public int getZoomLevel() {
|
||||
return zoomLevel;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
package org.apache.commons.logging;
|
||||
|
||||
public class LogFactory {
|
||||
public static String TAG = "com.osmand";
|
||||
|
||||
public static Log getLog(Class<?> cl){
|
||||
final String name = cl.getName();
|
||||
return new Log() {
|
||||
@Override
|
||||
public void debug(Object message) {
|
||||
android.util.Log.d(TAG, name + " " + message);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Object message, Throwable t) {
|
||||
android.util.Log.d(TAG, name + " " + message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message) {
|
||||
android.util.Log.e(TAG, name + " " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Object message, Throwable t) {
|
||||
android.util.Log.e(TAG, name + " " + message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(Object message) {
|
||||
android.util.Log.e(TAG, name + " " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatal(Object message, Throwable t) {
|
||||
android.util.Log.e(TAG, name + " " + message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message) {
|
||||
android.util.Log.i(TAG, name + " " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Object message, Throwable t) {
|
||||
android.util.Log.i(TAG, name + " " + message, t);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isErrorEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFatalEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfoEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTraceEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWarnEnabled() {
|
||||
return android.util.Log.isLoggable(TAG, android.util.Log.WARN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Object message) {
|
||||
android.util.Log.d(TAG, name + " " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Object message, Throwable t) {
|
||||
android.util.Log.d(TAG, name + " " + message, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message) {
|
||||
android.util.Log.w(TAG, name + " " + message);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Object message, Throwable t) {
|
||||
android.util.Log.w(TAG, name + " " + message, t);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue