- making oscimap default backend
- added about-screen - added TreeTile for Tile lookup, dropping that HashMap - using simple line-shader instead of std-derivatives one, about twice as faster here - use distance calculation from MapRenderer - removing TileScheduler - no need for MapGeneratorJob, pass MapTile directly to MapWorkers - added two-finger tap gestures for zoom-in/out - added tub/tron rendertheme - started caching for oscimap - add x/y coordinates to MapPosition, using it in MapRenderer - create tag hash when needed - no need for long tile coordinates max zoomlevel 31 should suffice
This commit is contained in:
parent
78e39af35a
commit
1a27f56313
@ -29,6 +29,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".preferences.EditPreferences" />
|
<activity android:name=".preferences.EditPreferences" />
|
||||||
<activity android:name=".filepicker.FilePicker" />
|
<activity android:name=".filepicker.FilePicker" />
|
||||||
|
<activity android:name=".InfoView" android:theme="@android:style/Theme.NoTitleBar" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -6,9 +6,10 @@
|
|||||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||||
</head>
|
</head>
|
||||||
<body style="padding: 0.5em;">
|
<body style="padding: 0.5em;">
|
||||||
<p style="text-align: center;"><img alt="mapsforge logo" src="file:///android_asset/mapsforge_logo.png" style="width: 255px; height: 223px;" /><br />Version 0.2.4</p>
|
<p style="text-align: center;"><img alt="mapsforge logo" src="file:///android_asset/globe2.png" style="width: 72px; height: 72px;" /><br />Version 0.2.1</p>
|
||||||
<p>This software is a part of the <a href="http://mapsforge.org/">mapsforge</a> project and distributed under the <a href="http://www.gnu.org/licenses/lgpl.html">LGPL3 license</a>.</p>
|
<p> <a href="https://code.google.com/p/vector-tile-map">OpenScienceMap</a> is distributed under the <a href="http://www.gnu.org/licenses/lgpl.html">LGPL3 license</a>.</p>
|
||||||
<p>Map data © <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.</p>
|
<p> This software is based on <a href="https://code.google.com/p/mapsforge">mapsforge</a> library 0.2.4.</p>
|
||||||
<p>Please report all bugs and feature requests either via our <a href="https://code.google.com/p/mapsforge/issues/list">issue tracker</a> or our public <a href="http://groups.google.com/group/mapsforge-dev">mapsforge-dev mailing list</a>.</p>
|
<p>Map data © <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, still using <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.</p>
|
||||||
|
<p>Please report all bugs and feature requests via our <a href="https://code.google.com/p/vector-tile-map/issues/list">issue tracker</a> </p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB |
@ -11,17 +11,17 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent" />
|
android:layout_height="fill_parent" />
|
||||||
|
|
||||||
<ToggleButton
|
<!-- <ToggleButton
|
||||||
android:id="@+id/snapToLocationView"
|
android:id="@+id/snapToLocationView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_marginRight="10dip"
|
android:layout_marginRight="10dip"
|
||||||
android:layout_marginTop="10dip"
|
android:layout_marginBottom="10dip"
|
||||||
android:background="@drawable/snap_to_position"
|
android:background="@drawable/snap_to_position"
|
||||||
android:textOff=""
|
android:textOff=""
|
||||||
android:textOn=""
|
android:textOn=""
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />-->
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
@ -47,6 +47,9 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/menu_render_theme_osmarender"
|
android:id="@+id/menu_render_theme_osmarender"
|
||||||
android:title="@string/menu_render_theme_osmarender"/>
|
android:title="@string/menu_render_theme_osmarender"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_render_theme_tronrender"
|
||||||
|
android:title="@string/menu_render_theme_tronrender"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_render_theme_select_file"
|
android:id="@+id/menu_render_theme_select_file"
|
||||||
android:title="@string/menu_render_theme_select_file"/>
|
android:title="@string/menu_render_theme_select_file"/>
|
||||||
@ -58,9 +61,9 @@
|
|||||||
|
|
||||||
android:showAsAction="never"
|
android:showAsAction="never"
|
||||||
android:title="@string/menu_mapfile"/>
|
android:title="@string/menu_mapfile"/>
|
||||||
<!-- <item
|
<item
|
||||||
android:id="@+id/menu_info_map_file"
|
android:id="@+id/menu_info_about"
|
||||||
android:title="@string/menu_info_map_file"/> -->
|
android:title="@string/menu_info_about"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -48,6 +48,9 @@
|
|||||||
<!-- <item
|
<!-- <item
|
||||||
android:id="@+id/menu_info_map_file"
|
android:id="@+id/menu_info_map_file"
|
||||||
android:title="@string/menu_info_map_file"/> -->
|
android:title="@string/menu_info_map_file"/> -->
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_info_about"
|
||||||
|
android:title="@string/menu_info_about"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
</item>
|
</item>
|
||||||
@ -61,6 +64,9 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/menu_render_theme_osmarender"
|
android:id="@+id/menu_render_theme_osmarender"
|
||||||
android:title="@string/menu_render_theme_osmarender"/>
|
android:title="@string/menu_render_theme_osmarender"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_render_theme_tronrender"
|
||||||
|
android:title="@string/menu_render_theme_tronrender"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_render_theme_select_file"
|
android:id="@+id/menu_render_theme_select_file"
|
||||||
android:title="@string/menu_render_theme_select_file"/>
|
android:title="@string/menu_render_theme_select_file"/>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="preferences_map_generator_values">
|
<!-- <string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
<item>OpenScienceMap</item>
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array> -->
|
||||||
|
|
||||||
<string-array name="preferences_scale_bar_unit_values">
|
<string-array name="preferences_scale_bar_unit_values">
|
||||||
<item>angloamerikanisch</item>
|
<item>angloamerikanisch</item>
|
||||||
|
|||||||
@ -1,11 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="preferences_map_generator_values">
|
|
||||||
<item>Mapfile</item>
|
|
||||||
<item>PostGIS</item>
|
|
||||||
<item>OpenScienceMap</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="preferences_text_scale_values">
|
<string-array name="preferences_text_scale_values">
|
||||||
<item>hyvin pieni</item>
|
<item>hyvin pieni</item>
|
||||||
<item>pieni</item>
|
<item>pieni</item>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="preferences_map_generator_values">
|
<!-- <string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
<item>OpenScienceMap</item>
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array> -->
|
||||||
|
|
||||||
<string-array name="preferences_text_scale_values">
|
<string-array name="preferences_text_scale_values">
|
||||||
<item>minuscola</item>
|
<item>minuscola</item>
|
||||||
|
|||||||
@ -1,31 +1,37 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="preferences_map_database_keys">
|
|
||||||
<item>MAP_READER</item>
|
|
||||||
<item>POSTGIS_READER</item>
|
|
||||||
<item>PBMAP_READER</item>
|
|
||||||
</string-array>
|
|
||||||
<string name="preferences_map_database_default">POSTGIS_READER</string>
|
|
||||||
|
|
||||||
<string-array name="preferences_scale_bar_unit_keys">
|
<string-array name="preferences_map_database_keys">
|
||||||
<item>imperial</item>
|
|
||||||
<item>metric</item>
|
<!-- <item>MAP_READER</item> -->
|
||||||
</string-array>
|
<item>POSTGIS_READER</item>
|
||||||
<string name="preferences_scale_bar_unit_default">metric</string>
|
<item>PBMAP_READER</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string name="preferences_map_database_default">PBMAP_READER</string>
|
||||||
|
|
||||||
|
<string-array name="preferences_scale_bar_unit_keys">
|
||||||
|
<item>imperial</item>
|
||||||
|
<item>metric</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string name="preferences_scale_bar_unit_default">metric</string>
|
||||||
|
|
||||||
|
<string-array name="preferences_text_scale_keys">
|
||||||
|
<item>0.7</item>
|
||||||
|
<item>0.85</item>
|
||||||
|
<item>1.0</item>
|
||||||
|
<item>1.3</item>
|
||||||
|
<item>1.6</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string name="preferences_text_scale_default">1.0</string>
|
||||||
|
|
||||||
|
<string-array name="view_sections">
|
||||||
|
<item>Map</item>
|
||||||
|
<item>Routes</item>
|
||||||
|
<item>Overlays</item>
|
||||||
|
<item>etc</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="preferences_text_scale_keys">
|
|
||||||
<item>0.7</item>
|
|
||||||
<item>0.85</item>
|
|
||||||
<item>1.0</item>
|
|
||||||
<item>1.3</item>
|
|
||||||
<item>1.6</item>
|
|
||||||
</string-array>
|
|
||||||
<string name="preferences_text_scale_default">1.0</string>
|
|
||||||
|
|
||||||
<string-array name="view_sections">
|
|
||||||
<item>Map</item>
|
|
||||||
<item>Routes</item>
|
|
||||||
<item>Overlays</item>
|
|
||||||
<item>etc</item>
|
|
||||||
</string-array>
|
|
||||||
</resources>
|
</resources>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="preferences_map_generator_values">
|
<string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<!-- <item>Mapfile</item> -->
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
<item>OpenScienceMap</item>
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
@ -59,6 +59,7 @@
|
|||||||
<string name="menu_preferences">Preferences</string>
|
<string name="menu_preferences">Preferences</string>
|
||||||
<string name="menu_render_theme">Render theme</string>
|
<string name="menu_render_theme">Render theme</string>
|
||||||
<string name="menu_render_theme_osmarender">Default Theme</string>
|
<string name="menu_render_theme_osmarender">Default Theme</string>
|
||||||
|
<string name="menu_render_theme_tronrender">Tube Theme</string>
|
||||||
<string name="menu_render_theme_select_file">Select XML file …</string>
|
<string name="menu_render_theme_select_file">Select XML file …</string>
|
||||||
<string name="menu_screenshot">Screenshot</string>
|
<string name="menu_screenshot">Screenshot</string>
|
||||||
<string name="menu_screenshot_jpeg">JPEG (lossy)</string>
|
<string name="menu_screenshot_jpeg">JPEG (lossy)</string>
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
<style name="MyActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
|
<style name="MyActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
|
||||||
<item name="android:background">@drawable/action_bar</item>
|
<item name="android:background">@drawable/action_bar</item>
|
||||||
<item name="android:windowActionBarOverlay">true</item>
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.TileMap" parent="android:style/Theme.Holo">
|
<style name="Theme.TileMap" parent="android:style/Theme.Holo">
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
package org.mapsforge.android;
|
package org.mapsforge.android;
|
||||||
|
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
|
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
@ -26,11 +26,11 @@ import android.opengl.GLSurfaceView;
|
|||||||
public interface IMapRenderer extends GLSurfaceView.Renderer {
|
public interface IMapRenderer extends GLSurfaceView.Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapGeneratorJob
|
* @param tile
|
||||||
* the mapGeneratorJob holding Tile data
|
* the mapGeneratorJob holding Tile data
|
||||||
* @return true if the tile was processed
|
* @return true if the tile was processed
|
||||||
*/
|
*/
|
||||||
public boolean passTile(MapGeneratorJob mapGeneratorJob);
|
public boolean passTile(MapTile tile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true when tile passed to renderer is processed false otherwise. used to lock overwriting resources passed
|
* @return true when tile passed to renderer is processed false otherwise. used to lock overwriting resources passed
|
||||||
|
|||||||
@ -96,7 +96,7 @@ public abstract class MapActivity extends Activity {
|
|||||||
// save the map position and zoom level
|
// save the map position and zoom level
|
||||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
if (mapPosition != null) {
|
if (mapPosition != null) {
|
||||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
GeoPoint geoPoint = new GeoPoint(mapPosition.lat, mapPosition.lon);
|
||||||
editor.putInt(KEY_LATITUDE, geoPoint.latitudeE6);
|
editor.putInt(KEY_LATITUDE, geoPoint.latitudeE6);
|
||||||
editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
|
editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
|
||||||
editor.putInt(KEY_ZOOM_LEVEL, mapPosition.zoomLevel);
|
editor.putInt(KEY_ZOOM_LEVEL, mapPosition.zoomLevel);
|
||||||
|
|||||||
@ -65,9 +65,12 @@ public class MapScaleBar {
|
|||||||
private static final int ONE_MILE = 5280;
|
private static final int ONE_MILE = 5280;
|
||||||
private static final Paint SCALE_BAR = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private static final Paint SCALE_BAR = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
private static final Paint SCALE_BAR_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private static final Paint SCALE_BAR_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
private static final int[] SCALE_BAR_VALUES_IMPERIAL = { 26400000, 10560000, 5280000, 2640000, 1056000, 528000,
|
private static final int[] SCALE_BAR_VALUES_IMPERIAL = { 26400000, 10560000, 5280000,
|
||||||
264000, 105600, 52800, 26400, 10560, 5280, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };
|
2640000, 1056000, 528000,
|
||||||
private static final int[] SCALE_BAR_VALUES_METRIC = { 10000000, 5000000, 2000000, 1000000, 500000, 200000, 100000,
|
264000, 105600, 52800, 26400, 10560, 5280, 2000, 1000, 500, 200, 100, 50, 20,
|
||||||
|
10, 5, 2, 1 };
|
||||||
|
private static final int[] SCALE_BAR_VALUES_METRIC = { 10000000, 5000000, 2000000,
|
||||||
|
1000000, 500000, 200000, 100000,
|
||||||
50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };
|
50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };
|
||||||
private static final Paint SCALE_TEXT = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private static final Paint SCALE_TEXT = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
private static final Paint SCALE_TEXT_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private static final Paint SCALE_TEXT_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
@ -101,7 +104,8 @@ public class MapScaleBar {
|
|||||||
|
|
||||||
MapScaleBar(MapView mapView) {
|
MapScaleBar(MapView mapView) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
mMapScaleBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Bitmap.Config.ARGB_4444);
|
mMapScaleBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT,
|
||||||
|
Bitmap.Config.ARGB_4444);
|
||||||
mMapScaleCanvas = new Canvas(mMapScaleBitmap);
|
mMapScaleCanvas = new Canvas(mMapScaleBitmap);
|
||||||
mTextFields = new HashMap<TextField, String>();
|
mTextFields = new HashMap<TextField, String>();
|
||||||
setDefaultTexts();
|
setDefaultTexts();
|
||||||
@ -173,8 +177,8 @@ public class MapScaleBar {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double latitudeDiff = Math.abs(currentMapPosition.geoPoint.getLatitude()
|
double latitudeDiff = Math.abs(currentMapPosition.lat
|
||||||
- mMapPosition.geoPoint.getLatitude());
|
- mMapPosition.lat);
|
||||||
if (latitudeDiff > LATITUDE_REDRAW_THRESHOLD) {
|
if (latitudeDiff > LATITUDE_REDRAW_THRESHOLD) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -245,7 +249,8 @@ public class MapScaleBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
double groundResolution = MercatorProjection.calculateGroundResolution(mMapPosition.geoPoint.getLatitude(),
|
double groundResolution = MercatorProjection.calculateGroundResolution(
|
||||||
|
mMapPosition.lat,
|
||||||
mMapPosition.zoomLevel);
|
mMapPosition.zoomLevel);
|
||||||
|
|
||||||
int[] scaleBarValues;
|
int[] scaleBarValues;
|
||||||
|
|||||||
@ -24,13 +24,12 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
|
|
||||||
import org.mapsforge.android.input.TouchHandler;
|
import org.mapsforge.android.input.TouchHandler;
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
|
||||||
import org.mapsforge.android.mapgenerator.JobQueue;
|
import org.mapsforge.android.mapgenerator.JobQueue;
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabases;
|
import org.mapsforge.android.mapgenerator.MapDatabases;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
|
||||||
import org.mapsforge.android.mapgenerator.MapRendererFactory;
|
import org.mapsforge.android.mapgenerator.MapRendererFactory;
|
||||||
import org.mapsforge.android.mapgenerator.MapRenderers;
|
import org.mapsforge.android.mapgenerator.MapRenderers;
|
||||||
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.android.mapgenerator.MapWorker;
|
import org.mapsforge.android.mapgenerator.MapWorker;
|
||||||
import org.mapsforge.android.mapgenerator.Theme;
|
import org.mapsforge.android.mapgenerator.Theme;
|
||||||
import org.mapsforge.android.rendertheme.ExternalRenderTheme;
|
import org.mapsforge.android.rendertheme.ExternalRenderTheme;
|
||||||
@ -80,9 +79,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
||||||
|
|
||||||
private final MapController mMapController;
|
private final MapController mMapController;
|
||||||
// private final MapMover mMapMover;
|
|
||||||
// private final ZoomAnimator mZoomAnimator;
|
|
||||||
// private final MapScaleBar mMapScaleBar;
|
|
||||||
private final MapViewPosition mMapViewPosition;
|
private final MapViewPosition mMapViewPosition;
|
||||||
|
|
||||||
private final MapZoomControls mMapZoomControls;
|
private final MapZoomControls mMapZoomControls;
|
||||||
@ -95,10 +91,11 @@ public class MapView extends GLSurfaceView {
|
|||||||
private JobQueue mJobQueue;
|
private JobQueue mJobQueue;
|
||||||
private MapWorker mMapWorkers[];
|
private MapWorker mMapWorkers[];
|
||||||
private int mNumMapWorkers = 4;
|
private int mNumMapWorkers = 4;
|
||||||
private JobParameters mJobParameters;
|
private DebugSettings debugSettings;
|
||||||
public DebugSettings debugSettings;
|
|
||||||
private String mMapFile;
|
private String mMapFile;
|
||||||
|
|
||||||
|
private File cacheDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context
|
* @param context
|
||||||
* the enclosing MapActivity instance.
|
* the enclosing MapActivity instance.
|
||||||
@ -139,30 +136,25 @@ public class MapView extends GLSurfaceView {
|
|||||||
// TODO make this dpi dependent
|
// TODO make this dpi dependent
|
||||||
Tile.TILE_SIZE = 400;
|
Tile.TILE_SIZE = 400;
|
||||||
|
|
||||||
// setWillNotDraw(true);
|
|
||||||
// setWillNotCacheDrawing(true);
|
|
||||||
|
|
||||||
MapActivity mapActivity = (MapActivity) context;
|
MapActivity mapActivity = (MapActivity) context;
|
||||||
|
|
||||||
|
cacheDir = context.getFilesDir();
|
||||||
|
|
||||||
debugSettings = new DebugSettings(false, false, false, false);
|
debugSettings = new DebugSettings(false, false, false, false);
|
||||||
|
|
||||||
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
|
|
||||||
mMapController = new MapController(this);
|
mMapController = new MapController(this);
|
||||||
|
|
||||||
mMapDatabaseType = mapDatabaseType;
|
mMapDatabaseType = mapDatabaseType;
|
||||||
|
|
||||||
mMapViewPosition = new MapViewPosition(this);
|
mMapViewPosition = new MapViewPosition(this);
|
||||||
// mMapScaleBar = new MapScaleBar(this);
|
|
||||||
mMapZoomControls = new MapZoomControls(mapActivity, this);
|
mMapZoomControls = new MapZoomControls(mapActivity, this);
|
||||||
|
|
||||||
mProjection = new MapViewProjection(this);
|
mProjection = new MapViewProjection(this);
|
||||||
|
|
||||||
mTouchEventHandler = new TouchHandler(mapActivity, this);
|
mTouchEventHandler = new TouchHandler(mapActivity, this);
|
||||||
|
|
||||||
mJobQueue = new JobQueue(this);
|
mJobQueue = new JobQueue();
|
||||||
|
|
||||||
// mMapMover = new MapMover(this);
|
|
||||||
// mMapMover.start();
|
|
||||||
// mZoomAnimator = new ZoomAnimator(this);
|
|
||||||
// mZoomAnimator.start();
|
|
||||||
|
|
||||||
mMapRenderer = MapRendererFactory.createMapRenderer(this, mapGeneratorType);
|
mMapRenderer = MapRendererFactory.createMapRenderer(this, mapGeneratorType);
|
||||||
mMapWorkers = new MapWorker[mNumMapWorkers];
|
mMapWorkers = new MapWorker[mNumMapWorkers];
|
||||||
@ -172,7 +164,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
if (mDebugDatabase) {
|
if (mDebugDatabase) {
|
||||||
mapDatabase = MapDatabaseFactory
|
mapDatabase = MapDatabaseFactory
|
||||||
.createMapDatabase(MapDatabases.JSON_READER);
|
.createMapDatabase(MapDatabases.JSON_READER);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mapDatabase = MapDatabaseFactory.createMapDatabase(mapDatabaseType);
|
mapDatabase = MapDatabaseFactory.createMapDatabase(mapDatabaseType);
|
||||||
}
|
}
|
||||||
@ -180,16 +171,18 @@ public class MapView extends GLSurfaceView {
|
|||||||
IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
|
IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
|
||||||
mapGenerator.setMapDatabase(mapDatabase);
|
mapGenerator.setMapDatabase(mapDatabase);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0)
|
||||||
mMapDatabase = mapDatabase;
|
mMapDatabase = mapDatabase;
|
||||||
initMapStartPosition();
|
|
||||||
}
|
|
||||||
mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
|
mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
|
||||||
mMapWorkers[i].start();
|
mMapWorkers[i].start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!setRenderTheme(InternalRenderTheme.OSMARENDER)) {
|
setMapFile("default");
|
||||||
Log.d(TAG, "EEEK could parse theme");
|
initMapStartPosition();
|
||||||
|
|
||||||
|
if (!setRenderTheme(DEFAULT_RENDER_THEME)) {
|
||||||
|
Log.d(TAG, "X could not parse theme");
|
||||||
// FIXME show init error dialog
|
// FIXME show init error dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,11 +190,15 @@ public class MapView extends GLSurfaceView {
|
|||||||
setEGLContextClientVersion(2);
|
setEGLContextClientVersion(2);
|
||||||
|
|
||||||
setRenderer(mMapRenderer);
|
setRenderer(mMapRenderer);
|
||||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
|
||||||
|
if (!debugFrameTime)
|
||||||
|
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||||
|
|
||||||
mapActivity.registerMapView(this);
|
mapActivity.registerMapView(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final static boolean debugFrameTime = false;
|
||||||
|
|
||||||
private void initMapStartPosition() {
|
private void initMapStartPosition() {
|
||||||
GeoPoint startPoint = getStartPoint();
|
GeoPoint startPoint = getStartPoint();
|
||||||
if (startPoint != null) {
|
if (startPoint != null) {
|
||||||
@ -212,7 +209,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
if (startZoomLevel != null) {
|
if (startZoomLevel != null) {
|
||||||
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,13 +246,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mMapFile;
|
return mMapFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return the MapMover which is used by this MapView.
|
|
||||||
// */
|
|
||||||
// public MapMover getMapMover() {
|
|
||||||
// return mMapMover;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the current position and zoom level of this MapView.
|
* @return the current position and zoom level of this MapView.
|
||||||
*/
|
*/
|
||||||
@ -264,20 +253,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mMapViewPosition;
|
return mMapViewPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return the scale bar which is used in this MapView.
|
|
||||||
// */
|
|
||||||
// public MapScaleBar getMapScaleBar() {
|
|
||||||
// return mMapScaleBar;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return the zoom controls instance which is used in this MapView.
|
|
||||||
// */
|
|
||||||
// public MapZoomControls getMapZoomControls() {
|
|
||||||
// return mMapZoomControls;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the currently used projection of the map. Do not keep this object for a longer time.
|
* @return the currently used projection of the map. Do not keep this object for a longer time.
|
||||||
*/
|
*/
|
||||||
@ -285,33 +260,11 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mProjection;
|
return mProjection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return true if the ZoomAnimator is currently running, false otherwise.
|
|
||||||
// */
|
|
||||||
// public boolean isZoomAnimatorRunning() {
|
|
||||||
// return mZoomAnimator.isExecuting();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
|
|
||||||
// return mMapMover.onKeyDown(keyCode, keyEvent);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
|
|
||||||
// return mMapMover.onKeyUp(keyCode, keyEvent);
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent motionEvent) {
|
public boolean onTouchEvent(MotionEvent motionEvent) {
|
||||||
return mTouchEventHandler.handleMotionEvent(motionEvent);
|
return mTouchEventHandler.handleMotionEvent(motionEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean onTrackballEvent(MotionEvent motionEvent) {
|
|
||||||
// return mMapMover.onTrackballEvent(motionEvent);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates all necessary tiles and adds jobs accordingly.
|
* Calculates all necessary tiles and adds jobs accordingly.
|
||||||
*/
|
*/
|
||||||
@ -372,21 +325,13 @@ public class MapView extends GLSurfaceView {
|
|||||||
public boolean setMapFile(String mapFile) {
|
public boolean setMapFile(String mapFile) {
|
||||||
FileOpenResult fileOpenResult = null;
|
FileOpenResult fileOpenResult = null;
|
||||||
|
|
||||||
Log.d(TAG, "set mapfile " + mapFile);
|
Log.i(TAG, "set mapfile " + mapFile);
|
||||||
|
|
||||||
if (mapFile != null && mapFile.equals(mMapFile)) {
|
if (mapFile != null && mapFile.equals(mMapFile)) {
|
||||||
// same map file as before
|
// same map file as before
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mZoomAnimator.pause();
|
|
||||||
// mMapMover.pause();
|
|
||||||
// mZoomAnimator.awaitPausing();
|
|
||||||
// mMapMover.awaitPausing();
|
|
||||||
// mZoomAnimator.proceed();
|
|
||||||
// mMapMover.stopMove();
|
|
||||||
// mMapMover.proceed();
|
|
||||||
|
|
||||||
boolean initialized = false;
|
boolean initialized = false;
|
||||||
|
|
||||||
mJobQueue.clear();
|
mJobQueue.clear();
|
||||||
@ -403,7 +348,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
if (mapFile != null)
|
if (mapFile != null)
|
||||||
fileOpenResult = mapDatabase.openFile(new File(mapFile));
|
fileOpenResult = mapDatabase.openFile(new File(mapFile));
|
||||||
else
|
else
|
||||||
fileOpenResult = mapDatabase.openFile(null);
|
fileOpenResult = mapDatabase.openFile(cacheDir);
|
||||||
|
|
||||||
if (fileOpenResult != null && fileOpenResult.isSuccess()) {
|
if (fileOpenResult != null && fileOpenResult.isSuccess()) {
|
||||||
mMapFile = mapFile;
|
mMapFile = mapFile;
|
||||||
@ -417,12 +362,12 @@ public class MapView extends GLSurfaceView {
|
|||||||
|
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
clearAndRedrawMapView();
|
clearAndRedrawMapView();
|
||||||
Log.d(TAG, "mapfile set");
|
Log.i(TAG, "mapfile set");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMapFile = null;
|
mMapFile = null;
|
||||||
Log.d(TAG, "loading mapfile failed");
|
Log.i(TAG, "loading mapfile failed");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -430,6 +375,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
private GeoPoint getStartPoint() {
|
private GeoPoint getStartPoint() {
|
||||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||||
|
|
||||||
if (mapFileInfo.startPosition != null) {
|
if (mapFileInfo.startPosition != null) {
|
||||||
return mapFileInfo.startPosition;
|
return mapFileInfo.startPosition;
|
||||||
} else if (mapFileInfo.mapCenter != null) {
|
} else if (mapFileInfo.mapCenter != null) {
|
||||||
@ -443,6 +389,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
private Byte getStartZoomLevel() {
|
private Byte getStartZoomLevel() {
|
||||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||||
|
|
||||||
if (mapFileInfo.startZoomLevel != null) {
|
if (mapFileInfo.startZoomLevel != null) {
|
||||||
return mapFileInfo.startZoomLevel;
|
return mapFileInfo.startZoomLevel;
|
||||||
}
|
}
|
||||||
@ -464,7 +411,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
|
|
||||||
IMapGenerator mapGenerator;
|
IMapGenerator mapGenerator;
|
||||||
|
|
||||||
Log.d(TAG, "setMapDatabase " + mapDatabaseType.name());
|
Log.i(TAG, "setMapDatabase " + mapDatabaseType.name());
|
||||||
|
|
||||||
if (mMapDatabaseType == mapDatabaseType)
|
if (mMapDatabaseType == mapDatabaseType)
|
||||||
return;
|
return;
|
||||||
@ -487,8 +434,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
setMapFile(mapFile);
|
setMapFile(mapFile);
|
||||||
|
|
||||||
mapWorkersProceed();
|
mapWorkersProceed();
|
||||||
|
|
||||||
Log.d(TAG, ">>>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -568,10 +513,10 @@ public class MapView extends GLSurfaceView {
|
|||||||
* @param textScale
|
* @param textScale
|
||||||
* the new text scale for the map rendering.
|
* the new text scale for the map rendering.
|
||||||
*/
|
*/
|
||||||
public void setTextScale(float textScale) {
|
// public void setTextScale(float textScale) {
|
||||||
mJobParameters = new JobParameters(mJobParameters.theme, textScale);
|
// mJobParameters = new JobParameters(mJobParameters.theme, textScale);
|
||||||
clearAndRedrawMapView();
|
// clearAndRedrawMapView();
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zooms in or out by the given amount of zoom levels.
|
* Zooms in or out by the given amount of zoom levels.
|
||||||
@ -603,32 +548,10 @@ public class MapView extends GLSurfaceView {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
||||||
// super.onLayout(changed, left, top, right, bottom);
|
|
||||||
// // mMapZoomControls.onLayout(changed, left, top, right, bottom);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
// // find out how big the zoom controls should be
|
|
||||||
// mMapZoomControls.measure(
|
|
||||||
// MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec),
|
|
||||||
// MeasureSpec.AT_MOST),
|
|
||||||
// MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
|
|
||||||
// MeasureSpec.AT_MOST));
|
|
||||||
//
|
|
||||||
// // make sure that MapView is big enough to display the zoom controls
|
|
||||||
// setMeasuredDimension(
|
|
||||||
// Math.max(MeasureSpec.getSize(widthMeasureSpec),
|
|
||||||
// mMapZoomControls.getMeasuredWidth()),
|
|
||||||
// Math.max(MeasureSpec.getSize(heightMeasureSpec),
|
|
||||||
// mMapZoomControls.getMeasuredHeight()));
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
||||||
int oldHeight) {
|
int oldHeight) {
|
||||||
|
|
||||||
mJobQueue.clear();
|
mJobQueue.clear();
|
||||||
|
|
||||||
mapWorkersPause(true);
|
mapWorkersPause(true);
|
||||||
@ -639,9 +562,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
// mMapMover.interrupt();
|
|
||||||
// mZoomAnimator.interrupt();
|
|
||||||
|
|
||||||
for (MapWorker mapWorker : mMapWorkers) {
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
mapWorker.pause();
|
mapWorker.pause();
|
||||||
mapWorker.interrupt();
|
mapWorker.interrupt();
|
||||||
@ -655,9 +575,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
IMapDatabase mapDatabase = mapWorker.getMapGenerator().getMapDatabase();
|
IMapDatabase mapDatabase = mapWorker.getMapGenerator().getMapDatabase();
|
||||||
mapDatabase.closeFile();
|
mapDatabase.closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// mMapScaleBar.destroy();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -693,18 +610,12 @@ public class MapView extends GLSurfaceView {
|
|||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
mapWorkersPause(false);
|
mapWorkersPause(false);
|
||||||
|
|
||||||
// mMapMover.pause();
|
|
||||||
// mZoomAnimator.pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
mapWorkersProceed();
|
mapWorkersProceed();
|
||||||
|
|
||||||
// mMapMover.proceed();
|
|
||||||
// mZoomAnimator.proceed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -715,34 +626,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
*/
|
*/
|
||||||
void setCenterAndZoom(MapPosition mapPosition) {
|
void setCenterAndZoom(MapPosition mapPosition) {
|
||||||
|
|
||||||
// if (hasValidCenter()) {
|
|
||||||
// // calculate the distance between previous and current position
|
|
||||||
// MapPosition mapPositionOld = mapViewPosition.getMapPosition();
|
|
||||||
|
|
||||||
// GeoPoint geoPointOld = mapPositionOld.geoPoint;
|
|
||||||
// GeoPoint geoPointNew = mapPosition.geoPoint;
|
|
||||||
// double oldPixelX =
|
|
||||||
// MercatorProjection.longitudeToPixelX(geoPointOld.getLongitude(),
|
|
||||||
// mapPositionOld.zoomLevel);
|
|
||||||
// double newPixelX =
|
|
||||||
// MercatorProjection.longitudeToPixelX(geoPointNew.getLongitude(),
|
|
||||||
// mapPosition.zoomLevel);
|
|
||||||
//
|
|
||||||
// double oldPixelY =
|
|
||||||
// MercatorProjection.latitudeToPixelY(geoPointOld.getLatitude(),
|
|
||||||
// mapPositionOld.zoomLevel);
|
|
||||||
// double newPixelY =
|
|
||||||
// MercatorProjection.latitudeToPixelY(geoPointNew.getLatitude(),
|
|
||||||
// mapPosition.zoomLevel);
|
|
||||||
|
|
||||||
// float matrixTranslateX = (float) (oldPixelX - newPixelX);
|
|
||||||
// float matrixTranslateY = (float) (oldPixelY - newPixelY);
|
|
||||||
// frameBuffer.matrixPostTranslate(matrixTranslateX,
|
|
||||||
// matrixTranslateY);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
mMapViewPosition.setMapCenterAndZoomLevel(mapPosition);
|
mMapViewPosition.setMapCenterAndZoomLevel(mapPosition);
|
||||||
// mapZoomControls.onZoomLevelChange(mapViewPosition.getZoomLevel());
|
|
||||||
redrawTiles();
|
redrawTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,20 +637,17 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mMapViewPosition;
|
return mMapViewPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return current JobParameters
|
|
||||||
*/
|
|
||||||
public JobParameters getJobParameters() {
|
|
||||||
return mJobParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add jobs and remember MapWorkers that stuff needs to be done
|
* add jobs and remember MapWorkers that stuff needs to be done
|
||||||
*
|
*
|
||||||
* @param jobs
|
* @param jobs
|
||||||
* tile jobs
|
* tile jobs
|
||||||
*/
|
*/
|
||||||
public void addJobs(ArrayList<MapGeneratorJob> jobs) {
|
public void addJobs(ArrayList<MapTile> jobs) {
|
||||||
|
if (jobs == null) {
|
||||||
|
mJobQueue.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
mJobQueue.setJobs(jobs);
|
mJobQueue.setJobs(jobs);
|
||||||
|
|
||||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||||
@ -795,4 +676,17 @@ public class MapView extends GLSurfaceView {
|
|||||||
mapWorker.proceed();
|
mapWorker.proceed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public final int
|
||||||
|
// public Handler messageHandler = new Handler() {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void handleMessage(Message msg) {
|
||||||
|
// switch (msg.what) {
|
||||||
|
// // handle update
|
||||||
|
// // .....
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import org.mapsforge.core.MapPosition;
|
|||||||
import org.mapsforge.core.MercatorProjection;
|
import org.mapsforge.core.MercatorProjection;
|
||||||
|
|
||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MapPosition stores the latitude and longitude coordinate of a MapView together with its zoom level.
|
* A MapPosition stores the latitude and longitude coordinate of a MapView together with its zoom level.
|
||||||
@ -33,8 +34,7 @@ public class MapViewPosition {
|
|||||||
private final MapView mMapView;
|
private final MapView mMapView;
|
||||||
private byte mZoomLevel;
|
private byte mZoomLevel;
|
||||||
private float mScale;
|
private float mScale;
|
||||||
|
private float mRotation;
|
||||||
// private float mRotation;
|
|
||||||
|
|
||||||
MapViewPosition(MapView mapView) {
|
MapViewPosition(MapView mapView) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
@ -43,7 +43,7 @@ public class MapViewPosition {
|
|||||||
mLongitude = Double.NaN;
|
mLongitude = Double.NaN;
|
||||||
mZoomLevel = -1;
|
mZoomLevel = -1;
|
||||||
mScale = 1;
|
mScale = 1;
|
||||||
// mRotation = 0.0f;
|
mRotation = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,8 +61,7 @@ public class MapViewPosition {
|
|||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
GeoPoint geoPoint = new GeoPoint(mLatitude, mLongitude);
|
return new MapPosition(mLatitude, mLongitude, mZoomLevel, mScale, mRotation);
|
||||||
return new MapPosition(geoPoint, mZoomLevel, mScale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,28 +104,50 @@ public class MapViewPosition {
|
|||||||
/**
|
/**
|
||||||
* Moves this MapViewPosition by the given amount of pixels.
|
* Moves this MapViewPosition by the given amount of pixels.
|
||||||
*
|
*
|
||||||
* @param moveHorizontal
|
* @param mx
|
||||||
* the amount of pixels to move the map horizontally.
|
* the amount of pixels to move the map horizontally.
|
||||||
* @param moveVertical
|
* @param my
|
||||||
* the amount of pixels to move the map vertically.
|
* the amount of pixels to move the map vertically.
|
||||||
*/
|
*/
|
||||||
public synchronized void moveMap(float moveHorizontal, float moveVertical) {
|
public synchronized void moveMap(float mx, float my) {
|
||||||
double pixelX = MercatorProjection.longitudeToPixelX(mLongitude, mZoomLevel);
|
double pixelX = MercatorProjection.longitudeToPixelX(mLongitude, mZoomLevel);
|
||||||
double pixelY = MercatorProjection.latitudeToPixelY(mLatitude, mZoomLevel);
|
double pixelY = MercatorProjection.latitudeToPixelY(mLatitude, mZoomLevel);
|
||||||
|
|
||||||
mLatitude = MercatorProjection.pixelYToLatitude(pixelY - moveVertical / mScale,
|
// float rad = (float) Math.toRadians(mRotation);
|
||||||
mZoomLevel);
|
// mx /= mScale;
|
||||||
|
// my /= mScale;
|
||||||
|
//
|
||||||
|
// double x = mx * FloatMath.cos(rad) + my * -FloatMath.sin(rad);
|
||||||
|
// double y = mx * FloatMath.sin(rad) + my * FloatMath.cos(rad);
|
||||||
|
//
|
||||||
|
// double dx = pixelX - x;
|
||||||
|
// double dy = pixelY - y;
|
||||||
|
|
||||||
|
double dx = pixelX - mx / mScale;
|
||||||
|
double dy = pixelY - my / mScale;
|
||||||
|
|
||||||
|
mLatitude = MercatorProjection.pixelYToLatitude(dy, mZoomLevel);
|
||||||
mLatitude = MercatorProjection.limitLatitude(mLatitude);
|
mLatitude = MercatorProjection.limitLatitude(mLatitude);
|
||||||
|
|
||||||
mLongitude = MercatorProjection.pixelXToLongitude(pixelX - moveHorizontal
|
mLongitude = MercatorProjection.pixelXToLongitude(dx, mZoomLevel);
|
||||||
/ mScale,
|
|
||||||
mZoomLevel);
|
//
|
||||||
mLongitude = MercatorProjection.limitLongitude(mLongitude);
|
// mLatitude = MercatorProjection.pixelYToLatitude(pixelY - moveVertical / mScale,
|
||||||
|
// mZoomLevel);
|
||||||
|
// mLatitude = MercatorProjection.limitLatitude(mLatitude);
|
||||||
|
//
|
||||||
|
// mLongitude = MercatorProjection.pixelXToLongitude(pixelX - moveHorizontal
|
||||||
|
// / mScale, mZoomLevel);
|
||||||
|
|
||||||
|
mLongitude = MercatorProjection.wrapLongitude(mLongitude);
|
||||||
|
// mLongitude = MercatorProjection.limitLongitude(mLongitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public synchronized void rotateMap(float angle) {
|
public synchronized void rotateMap(float angle) {
|
||||||
// mRotation = angle;
|
mRotation -= angle;
|
||||||
// }
|
Log.d("...", "angle:" + mRotation);
|
||||||
|
// mRotation %= 360;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized void setMapCenter(GeoPoint geoPoint) {
|
synchronized void setMapCenter(GeoPoint geoPoint) {
|
||||||
mLatitude = MercatorProjection.limitLatitude(geoPoint.getLatitude());
|
mLatitude = MercatorProjection.limitLatitude(geoPoint.getLatitude());
|
||||||
@ -134,9 +155,8 @@ public class MapViewPosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setMapCenterAndZoomLevel(MapPosition mapPosition) {
|
synchronized void setMapCenterAndZoomLevel(MapPosition mapPosition) {
|
||||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
mLatitude = MercatorProjection.limitLatitude(mapPosition.lat);
|
||||||
mLatitude = MercatorProjection.limitLatitude(geoPoint.getLatitude());
|
mLongitude = MercatorProjection.limitLongitude(mapPosition.lon);
|
||||||
mLongitude = MercatorProjection.limitLongitude(geoPoint.getLongitude());
|
|
||||||
mZoomLevel = mMapView.limitZoomLevel(mapPosition.zoomLevel);
|
mZoomLevel = mMapView.limitZoomLevel(mapPosition.zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +177,9 @@ public class MapViewPosition {
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
public synchronized void scaleMap(float scale, float pivotX, float pivotY) {
|
public synchronized void scaleMap(float scale, float pivotX, float pivotY) {
|
||||||
moveMap(pivotX * (1.0f - scale),
|
if (pivotY != 0 || pivotY != 0)
|
||||||
pivotY * (1.0f - scale));
|
moveMap(pivotX * (1.0f - scale),
|
||||||
|
pivotY * (1.0f - scale));
|
||||||
|
|
||||||
float s = mScale * scale;
|
float s = mScale * scale;
|
||||||
|
|
||||||
|
|||||||
@ -38,14 +38,14 @@ class MapViewProjection implements Projection {
|
|||||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
|
|
||||||
// calculate the pixel coordinates of the top left corner
|
// calculate the pixel coordinates of the top left corner
|
||||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
double pixelX = MercatorProjection.longitudeToPixelX(mapPosition);
|
||||||
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
|
double pixelY = MercatorProjection.latitudeToPixelY(mapPosition);
|
||||||
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
|
|
||||||
pixelX -= mMapView.getWidth() >> 1;
|
pixelX -= mMapView.getWidth() >> 1;
|
||||||
pixelY -= mMapView.getHeight() >> 1;
|
pixelY -= mMapView.getHeight() >> 1;
|
||||||
|
|
||||||
// convert the pixel coordinates to a GeoPoint and return it
|
// convert the pixel coordinates to a GeoPoint and return it
|
||||||
return new GeoPoint(MercatorProjection.pixelYToLatitude(pixelY + y, mapPosition.zoomLevel),
|
return new GeoPoint(MercatorProjection.pixelYToLatitude(pixelY + y,
|
||||||
|
mapPosition.zoomLevel),
|
||||||
MercatorProjection.pixelXToLongitude(pixelX + x, mapPosition.zoomLevel));
|
MercatorProjection.pixelXToLongitude(pixelX + x, mapPosition.zoomLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,8 @@ class MapViewProjection implements Projection {
|
|||||||
@Override
|
@Override
|
||||||
public float metersToPixels(float meters, byte zoom) {
|
public float metersToPixels(float meters, byte zoom) {
|
||||||
double latitude = mMapView.getMapPosition().getMapCenter().getLatitude();
|
double latitude = mMapView.getMapPosition().getMapCenter().getLatitude();
|
||||||
double groundResolution = MercatorProjection.calculateGroundResolution(latitude, zoom);
|
double groundResolution = MercatorProjection.calculateGroundResolution(latitude,
|
||||||
|
zoom);
|
||||||
return (float) (meters * (1 / groundResolution));
|
return (float) (meters * (1 / groundResolution));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,22 +86,25 @@ class MapViewProjection implements Projection {
|
|||||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
|
|
||||||
// calculate the pixel coordinates of the top left corner
|
// calculate the pixel coordinates of the top left corner
|
||||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
double pixelX = MercatorProjection.longitudeToPixelX(mapPosition);
|
||||||
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
|
double pixelY = MercatorProjection.latitudeToPixelY(mapPosition);
|
||||||
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
|
|
||||||
pixelX -= mMapView.getWidth() >> 1;
|
pixelX -= mMapView.getWidth() >> 1;
|
||||||
pixelY -= mMapView.getHeight() >> 1;
|
pixelY -= mMapView.getHeight() >> 1;
|
||||||
|
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
// create a new point and return it
|
// create a new point and return it
|
||||||
return new Point(
|
return new Point(
|
||||||
(int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX),
|
(int) (MercatorProjection.longitudeToPixelX(in.getLongitude(),
|
||||||
(int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY));
|
mapPosition.zoomLevel) - pixelX),
|
||||||
|
(int) (MercatorProjection.latitudeToPixelY(in.getLatitude(),
|
||||||
|
mapPosition.zoomLevel) - pixelY));
|
||||||
}
|
}
|
||||||
|
|
||||||
// reuse the existing point
|
// reuse the existing point
|
||||||
out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX);
|
out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(),
|
||||||
out.y = (int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY);
|
mapPosition.zoomLevel) - pixelX);
|
||||||
|
out.y = (int) (MercatorProjection.latitudeToPixelY(in.getLatitude(),
|
||||||
|
mapPosition.zoomLevel) - pixelY);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +112,8 @@ class MapViewProjection implements Projection {
|
|||||||
public Point toPoint(GeoPoint in, Point out, byte zoom) {
|
public Point toPoint(GeoPoint in, Point out, byte zoom) {
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
// create a new point and return it
|
// create a new point and return it
|
||||||
return new Point((int) MercatorProjection.longitudeToPixelX(in.getLongitude(), zoom),
|
return new Point((int) MercatorProjection.longitudeToPixelX(
|
||||||
|
in.getLongitude(), zoom),
|
||||||
(int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom));
|
(int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,8 @@ public class MapZoomControls {
|
|||||||
/**
|
/**
|
||||||
* Default {@link Gravity} of the zoom controls.
|
* Default {@link Gravity} of the zoom controls.
|
||||||
*/
|
*/
|
||||||
private static final int DEFAULT_ZOOM_CONTROLS_GRAVITY = Gravity.BOTTOM | Gravity.RIGHT;
|
private static final int DEFAULT_ZOOM_CONTROLS_GRAVITY = Gravity.BOTTOM
|
||||||
|
| Gravity.RIGHT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default maximum zoom level.
|
* Default maximum zoom level.
|
||||||
@ -97,7 +98,8 @@ public class MapZoomControls {
|
|||||||
/**
|
/**
|
||||||
* Delay in milliseconds after which the zoom controls disappear.
|
* Delay in milliseconds after which the zoom controls disappear.
|
||||||
*/
|
*/
|
||||||
private static final long ZOOM_CONTROLS_TIMEOUT = ViewConfiguration.getZoomControlsTimeout();
|
private static final long ZOOM_CONTROLS_TIMEOUT = ViewConfiguration
|
||||||
|
.getZoomControlsTimeout();
|
||||||
|
|
||||||
private boolean mGravityChanged;
|
private boolean mGravityChanged;
|
||||||
private boolean mShowMapZoomControls;
|
private boolean mShowMapZoomControls;
|
||||||
@ -220,7 +222,8 @@ public class MapZoomControls {
|
|||||||
return (right - left - zoomControlsWidth) / 2;
|
return (right - left - zoomControlsWidth) / 2;
|
||||||
|
|
||||||
case Gravity.RIGHT:
|
case Gravity.RIGHT:
|
||||||
return right - left - zoomControlsWidth - ZOOM_CONTROLS_HORIZONTAL_PADDING;
|
return right - left - zoomControlsWidth
|
||||||
|
- ZOOM_CONTROLS_HORIZONTAL_PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("unknown horizontal gravity: " + gravity);
|
throw new IllegalArgumentException("unknown horizontal gravity: " + gravity);
|
||||||
@ -251,7 +254,8 @@ public class MapZoomControls {
|
|||||||
|
|
||||||
private void showZoomControlsWithTimeout() {
|
private void showZoomControlsWithTimeout() {
|
||||||
showZoomControls();
|
showZoomControls();
|
||||||
mZoomControlsHideHandler.sendEmptyMessageDelayed(MSG_ZOOM_CONTROLS_HIDE, ZOOM_CONTROLS_TIMEOUT);
|
mZoomControlsHideHandler.sendEmptyMessageDelayed(MSG_ZOOM_CONTROLS_HIDE,
|
||||||
|
ZOOM_CONTROLS_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMeasuredHeight() {
|
int getMeasuredHeight() {
|
||||||
|
|||||||
@ -15,38 +15,33 @@
|
|||||||
package org.mapsforge.android.glrenderer;
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
import org.mapsforge.android.mapgenerator.MapTile;
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.core.Tile;
|
|
||||||
|
|
||||||
class GLMapTile extends MapTile {
|
class GLMapTile extends MapTile {
|
||||||
long lastDraw = 0;
|
long lastDraw = 0;
|
||||||
|
|
||||||
|
// VBO layout:
|
||||||
|
// 16 bytes fill coordinates
|
||||||
|
// n bytes polygon vertices
|
||||||
|
// m bytes lines vertices
|
||||||
VertexBufferObject vbo;
|
VertexBufferObject vbo;
|
||||||
|
|
||||||
// polygonOffset is always 8
|
// polygonOffset in vbo is always 16 bytes,
|
||||||
int lineOffset;
|
int lineOffset;
|
||||||
|
|
||||||
TextTexture texture;
|
TextTexture texture;
|
||||||
|
|
||||||
|
// Tile data set by MapGenerator:
|
||||||
LineLayer lineLayers;
|
LineLayer lineLayers;
|
||||||
PolygonLayer polygonLayers;
|
PolygonLayer polygonLayers;
|
||||||
|
|
||||||
TextItem labels;
|
TextItem labels;
|
||||||
|
|
||||||
boolean newData;
|
boolean newData;
|
||||||
boolean loading;
|
|
||||||
|
|
||||||
// pixel coordinates (y-flipped)
|
// pointer in TileTree
|
||||||
final long x;
|
TreeTile rel;
|
||||||
final long y;
|
|
||||||
|
|
||||||
final GLMapTile[] child = { null, null, null, null };
|
GLMapTile(int tileX, int tileY, byte zoomLevel) {
|
||||||
GLMapTile parent;
|
|
||||||
|
|
||||||
GLMapTile(long tileX, long tileY, byte zoomLevel) {
|
|
||||||
super(tileX, tileY, zoomLevel);
|
super(tileX, tileY, zoomLevel);
|
||||||
|
|
||||||
x = pixelX;
|
|
||||||
y = pixelY + Tile.TILE_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,8 @@ class LineLayers {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final boolean mFast = true;
|
||||||
|
|
||||||
static LineLayer drawLines(GLMapTile tile, LineLayer layer, int next, float[] matrix,
|
static LineLayer drawLines(GLMapTile tile, LineLayer layer, int next, float[] matrix,
|
||||||
float div, double zoom, float scale) {
|
float div, double zoom, float scale) {
|
||||||
|
|
||||||
@ -88,18 +90,17 @@ class LineLayers {
|
|||||||
|
|
||||||
glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0);
|
glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0);
|
||||||
|
|
||||||
// if (diff != 0)
|
|
||||||
// // diff < 0 means tile is parent
|
|
||||||
// z = (diff > 0) ? 1.0f / (1 << diff) : (1 << -diff);
|
|
||||||
|
|
||||||
// scale factor to map one pixel on tile to one pixel on screen:
|
// scale factor to map one pixel on tile to one pixel on screen:
|
||||||
// float pixel = 2.0f / (scale * z);
|
float pixel = 2.0f / (scale * z);
|
||||||
// GLES20.glUniform1f(hLineScale, pixel);
|
|
||||||
|
if (mFast)
|
||||||
|
GLES20.glUniform1f(hLineScale, pixel);
|
||||||
|
else
|
||||||
|
GLES20.glUniform1f(hLineScale, 0);
|
||||||
|
|
||||||
// line scale factor (for non fixed lines)
|
// line scale factor (for non fixed lines)
|
||||||
float s = FloatMath.sqrt(scale * z);
|
float s = FloatMath.sqrt(scale * z);
|
||||||
boolean blur = false;
|
boolean blur = false;
|
||||||
GLES20.glUniform1f(hLineScale, 0);
|
|
||||||
|
|
||||||
LineLayer l = layer;
|
LineLayer l = layer;
|
||||||
for (; l != null && l.layer < next; l = l.next) {
|
for (; l != null && l.layer < next; l = l.next) {
|
||||||
@ -120,11 +121,16 @@ class LineLayers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (blur) {
|
if (blur) {
|
||||||
GLES20.glUniform1f(hLineScale, 0);
|
if (mFast)
|
||||||
|
GLES20.glUniform1f(hLineScale, pixel);
|
||||||
|
else
|
||||||
|
GLES20.glUniform1f(hLineScale, 0);
|
||||||
blur = false;
|
blur = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l.isOutline) {
|
if (l.isOutline) {
|
||||||
for (LineLayer o = l.outlines; o != null; o = o.outlines) {
|
for (LineLayer o = l.outlines; o != null; o = o.outlines) {
|
||||||
|
|
||||||
if (line.blur != 0) {
|
if (line.blur != 0) {
|
||||||
GLES20.glUniform1f(hLineScale, (l.width + o.width) / (scale * z)
|
GLES20.glUniform1f(hLineScale, (l.width + o.width) / (scale * z)
|
||||||
- (line.blur / (scale * z)));
|
- (line.blur / (scale * z)));
|
||||||
|
|||||||
@ -14,8 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.glrenderer;
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
|
import org.mapsforge.android.DebugSettings;
|
||||||
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||||
@ -81,12 +83,24 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
private RenderInstruction[] mRenderInstructions = null;
|
private RenderInstruction[] mRenderInstructions = null;
|
||||||
|
|
||||||
private final String TAG_WATER = "water".intern();
|
private final String TAG_WATER = "water".intern();
|
||||||
|
private final MapView mMapView;
|
||||||
|
|
||||||
|
private final Tag[] debugTagBox = { new Tag("debug", "box") };
|
||||||
|
private final Tag[] debugTagWay = { new Tag("debug", "way") };
|
||||||
|
private final Tag[] debugTagArea = { new Tag("debug", "area") };
|
||||||
|
private final float[] debugBoxCoords = { 0, 0, 0, Tile.TILE_SIZE,
|
||||||
|
Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, 0, 0, 0 };
|
||||||
|
private final short[] debugBoxIndex = { 10 };
|
||||||
|
|
||||||
|
private float mProjectionScaleFactor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param mapView
|
||||||
|
* the MapView
|
||||||
*/
|
*/
|
||||||
public MapGenerator() {
|
public MapGenerator(MapView mapView) {
|
||||||
Log.d(TAG, "init DatabaseRenderer");
|
Log.d(TAG, "init DatabaseRenderer");
|
||||||
|
mMapView = mapView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float mPoiX = 256;
|
private float mPoiX = 256;
|
||||||
@ -115,8 +129,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
|
|
||||||
if (mMapProjection != null)
|
if (mMapProjection != null)
|
||||||
{
|
{
|
||||||
long x = mCurrentTile.x;
|
long x = mCurrentTile.pixelX;
|
||||||
long y = mCurrentTile.y;
|
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||||
|
|
||||||
double divx, divy;
|
double divx, divy;
|
||||||
@ -163,6 +177,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
|
|
||||||
mTagName = null;
|
mTagName = null;
|
||||||
mProjected = false;
|
mProjected = false;
|
||||||
|
mCurLineLayer = null;
|
||||||
|
|
||||||
mDrawingLayer = getValidLayer(layer) * mLevels;
|
mDrawingLayer = getValidLayer(layer) * mLevels;
|
||||||
mSimplify = 0.5f;
|
mSimplify = 0.5f;
|
||||||
@ -325,9 +340,10 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lineLayer == null)
|
if (lineLayer == null) {
|
||||||
|
mCurLineLayer = null;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (line.outline) {
|
if (line.outline) {
|
||||||
lineLayer.addOutline(mCurLineLayer);
|
lineLayer.addOutline(mCurLineLayer);
|
||||||
return;
|
return;
|
||||||
@ -355,45 +371,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
}
|
}
|
||||||
pos += length;
|
pos += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (line.outline < 0)
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// Line outline = MapGenerator.renderTheme.getOutline(line.outline);
|
|
||||||
//
|
|
||||||
// if (outline == null)
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// numLayer = mDrawingLayer + outline.getLevel();
|
|
||||||
//
|
|
||||||
// l = mLineLayers;
|
|
||||||
//
|
|
||||||
// if (l == null || l.layer > numLayer) {
|
|
||||||
// // insert new layer at start
|
|
||||||
// outlineLayer = new LineLayer(numLayer, outline, w, true);
|
|
||||||
// // outlineLayer = LineLayers.get(numLayer, outline, w, true);
|
|
||||||
// outlineLayer.next = l;
|
|
||||||
// mLineLayers = outlineLayer;
|
|
||||||
// } else {
|
|
||||||
// while (l != null) {
|
|
||||||
// if (l.layer == numLayer) {
|
|
||||||
// outlineLayer = l;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// // insert new layer between current and next layer
|
|
||||||
// if (l.next == null || l.next.layer > numLayer) {
|
|
||||||
// outlineLayer = new LineLayer(numLayer, outline, w, true);
|
|
||||||
// // outlineLayer = LineLayers.get(numLayer, outline, w, true);
|
|
||||||
// outlineLayer.next = l.next;
|
|
||||||
// l.next = outlineLayer;
|
|
||||||
// }
|
|
||||||
// l = l.next;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (outlineLayer != null)
|
|
||||||
// outlineLayer.addOutline(lineLayer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -469,20 +446,27 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
boolean mDebugDrawUnmatched;
|
boolean mDebugDrawUnmatched;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
|
public boolean executeJob(MapTile mapTile) {
|
||||||
GLMapTile tile;
|
GLMapTile tile;
|
||||||
|
|
||||||
if (mMapDatabase == null)
|
if (mMapDatabase == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tile = mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
|
tile = mCurrentTile = (GLMapTile) mapTile;
|
||||||
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
|
DebugSettings debugSettings = mMapView.getDebugSettings();
|
||||||
mDebugDrawUnmatched = mapGeneratorJob.debugSettings.mDrawUnmatchted;
|
|
||||||
|
|
||||||
if (tile.isLoading || tile.isReady || tile.isCanceled)
|
mDebugDrawPolygons = !debugSettings.mDisablePolygons;
|
||||||
|
mDebugDrawUnmatched = debugSettings.mDrawUnmatchted;
|
||||||
|
|
||||||
|
// fixed now....
|
||||||
|
if (tile.newData || tile.isReady || tile.isCanceled) {
|
||||||
|
Log.d(TAG, "XXX tile already loaded "
|
||||||
|
+ tile + " "
|
||||||
|
+ tile.newData + " "
|
||||||
|
+ tile.isReady + " "
|
||||||
|
+ tile.isCanceled);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
tile.isLoading = true;
|
|
||||||
|
|
||||||
mLevels = MapGenerator.renderTheme.getLevels();
|
mLevels = MapGenerator.renderTheme.getLevels();
|
||||||
|
|
||||||
@ -492,10 +476,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
else
|
else
|
||||||
setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
|
setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
|
||||||
|
|
||||||
mLineLayers = null;
|
|
||||||
mPolyLayers = null;
|
|
||||||
mLabels = null;
|
|
||||||
|
|
||||||
// firstMatch = true;
|
// firstMatch = true;
|
||||||
countLines = 0;
|
countLines = 0;
|
||||||
countNodes = 0;
|
countNodes = 0;
|
||||||
@ -516,12 +496,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
if (debugSettings.mDrawTileFrames) {
|
||||||
|
|
||||||
final float[] debugBoxCoords = { 0, 0, 0, Tile.TILE_SIZE,
|
|
||||||
Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, 0, 0, 0 };
|
|
||||||
final short[] debugBoxIndex = { 10 };
|
|
||||||
|
|
||||||
mTagName = new Tag("name", countLines + " " + countNodes + " "
|
mTagName = new Tag("name", countLines + " " + countNodes + " "
|
||||||
+ tile.toString(), false);
|
+ tile.toString(), false);
|
||||||
mPoiX = Tile.TILE_SIZE >> 1;
|
mPoiX = Tile.TILE_SIZE >> 1;
|
||||||
@ -533,21 +508,20 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
mDrawingLayer = 10 * mLevels;
|
mDrawingLayer = 10 * mLevels;
|
||||||
MapGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
|
MapGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.lineLayers = mLineLayers;
|
tile.lineLayers = mLineLayers;
|
||||||
tile.polygonLayers = mPolyLayers;
|
tile.polygonLayers = mPolyLayers;
|
||||||
tile.labels = mLabels;
|
tile.labels = mLabels;
|
||||||
|
|
||||||
mCurPolyLayer = null;
|
mCurPolyLayer = null;
|
||||||
mCurLineLayer = null;
|
mCurLineLayer = null;
|
||||||
|
mLineLayers = null;
|
||||||
|
mPolyLayers = null;
|
||||||
|
mLabels = null;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Tag[] debugTagBox = { new Tag("debug", "box") };
|
|
||||||
private final Tag[] debugTagWay = { new Tag("debug", "way") };
|
|
||||||
private final Tag[] debugTagArea = { new Tag("debug", "area") };
|
|
||||||
|
|
||||||
private float mProjectionScaleFactor;
|
|
||||||
|
|
||||||
private static byte getValidLayer(byte layer) {
|
private static byte getValidLayer(byte layer) {
|
||||||
if (layer < 0) {
|
if (layer < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -612,8 +586,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
|||||||
|
|
||||||
float[] coords = mWayNodes;
|
float[] coords = mWayNodes;
|
||||||
|
|
||||||
long x = mCurrentTile.x;
|
long x = mCurrentTile.pixelX;
|
||||||
long y = mCurrentTile.y;
|
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||||
float min = mSimplify;
|
float min = mSimplify;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -82,9 +82,7 @@ class PolygonLayers {
|
|||||||
// do not modify stencil buffer
|
// do not modify stencil buffer
|
||||||
glStencilMask(0);
|
glStencilMask(0);
|
||||||
|
|
||||||
// clip with depth mask
|
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
// GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
|
||||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
|
|
||||||
for (int c = 0; c < count; c++) {
|
for (int c = 0; c < count; c++) {
|
||||||
PolygonLayer l = mFillPolys[c];
|
PolygonLayer l = mFillPolys[c];
|
||||||
@ -139,13 +137,10 @@ class PolygonLayers {
|
|||||||
|
|
||||||
if (blend)
|
if (blend)
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
// glDisable(GLES20.GL_DEPTH_TEST);
|
|
||||||
// glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PolygonLayer drawPolygons(PolygonLayer layer, int next,
|
static PolygonLayer drawPolygons(PolygonLayer layer, int next,
|
||||||
float[] matrix, double zoom, float scale, short drawCount, boolean clip) {
|
float[] matrix, double zoom, float scale, boolean clip) {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
glUseProgram(polygonProgram);
|
glUseProgram(polygonProgram);
|
||||||
@ -182,10 +177,8 @@ class PolygonLayers {
|
|||||||
// clear stencilbuffer (tile region)
|
// clear stencilbuffer (tile region)
|
||||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
|
|
||||||
|
// draw depth clipper
|
||||||
if (first) {
|
if (first) {
|
||||||
// glEnable(GLES20.GL_DEPTH_TEST);
|
|
||||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glPolygonOffset(0, drawCount);
|
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
}
|
}
|
||||||
@ -196,13 +189,16 @@ class PolygonLayers {
|
|||||||
first = false;
|
first = false;
|
||||||
GLES20.glDepthMask(false);
|
GLES20.glDepthMask(false);
|
||||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
// glDisable(GLES20.GL_DEPTH_TEST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// stencil op for stencil method polygon drawing
|
// stencil op for stencil method polygon drawing
|
||||||
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||||
|
|
||||||
|
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
mFillPolys[cnt] = l;
|
mFillPolys[cnt] = l;
|
||||||
|
|
||||||
// set stencil mask to draw to
|
// set stencil mask to draw to
|
||||||
@ -223,7 +219,7 @@ class PolygonLayers {
|
|||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
if (clip && first)
|
if (clip && first)
|
||||||
drawDepthClip(drawCount);
|
drawDepthClip();
|
||||||
|
|
||||||
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
||||||
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
|
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
|
||||||
@ -231,53 +227,16 @@ class PolygonLayers {
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static void drawStencilClip(byte drawCount) {
|
static void drawDepthClip() {
|
||||||
// // set stencil mask for line drawing... HACK!!!
|
|
||||||
// glColorMask(false, false, false, false);
|
|
||||||
//
|
|
||||||
// int c = drawCount % 16;
|
|
||||||
// // never pass the test, i.e. always apply first stencil op (sfail)
|
|
||||||
// // glStencilFunc(GLES20.GL_NEVER, drawCount, 0);
|
|
||||||
// glStencilFunc(GLES20.GL_NEVER, flipdabit[c], 0);
|
|
||||||
//
|
|
||||||
// // replace stencilbuffer
|
|
||||||
// glStencilMask(0xff);
|
|
||||||
//
|
|
||||||
// // set stencilbuffer for (tile region)
|
|
||||||
// glStencilOp(GLES20.GL_REPLACE, GLES20.GL_KEEP, GLES20.GL_KEEP);
|
|
||||||
// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
//
|
|
||||||
// glStencilFunc(GL_EQUAL, flipdabit[c], 0xff);
|
|
||||||
// // do not modify stencil buffer
|
|
||||||
// glStencilMask(0);
|
|
||||||
//
|
|
||||||
// glColorMask(true, true, true, true);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this only increases the chance for the stencil buffer clip to work
|
|
||||||
// should check for clipping with depth buffer or sth
|
|
||||||
// private static short[] flipdabit = {
|
|
||||||
// 255, 254, 253, 251,
|
|
||||||
// 247, 239, 223, 191,
|
|
||||||
// 127, 63, 252, 250,
|
|
||||||
// 249, 243, 231, 207 };
|
|
||||||
|
|
||||||
static void drawDepthClip(short drawCount) {
|
|
||||||
|
|
||||||
glColorMask(false, false, false, false);
|
glColorMask(false, false, false, false);
|
||||||
// glEnable(GLES20.GL_DEPTH_TEST);
|
|
||||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glPolygonOffset(0, drawCount);
|
|
||||||
|
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
GLES20.glDepthMask(false);
|
GLES20.glDepthMask(false);
|
||||||
glColorMask(true, true, true, true);
|
glColorMask(true, true, true, true);
|
||||||
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ package org.mapsforge.android.glrenderer;
|
|||||||
class Shaders {
|
class Shaders {
|
||||||
|
|
||||||
final static String lineVertexShader = ""
|
final static String lineVertexShader = ""
|
||||||
+ "precision mediump float; \n"
|
+ "precision mediump float;"
|
||||||
+ "uniform mat4 mvp;"
|
+ "uniform mat4 mvp;"
|
||||||
+ "attribute vec4 a_position;"
|
+ "attribute vec4 a_position;"
|
||||||
+ "attribute vec2 a_st;"
|
+ "attribute vec2 a_st;"
|
||||||
@ -32,7 +32,26 @@ class Shaders {
|
|||||||
+ " v_st = u_width * a_st;"
|
+ " v_st = u_width * a_st;"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
|
final static String lineFragmentShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform float u_wscale;"
|
||||||
|
+ "uniform float u_width;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "varying vec2 v_st;"
|
||||||
|
+ "const float zero = 0.0;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " vec4 color = u_color;"
|
||||||
|
+ " float len;"
|
||||||
|
+ " if (v_st.t == zero)"
|
||||||
|
+ " len = abs(v_st.s);"
|
||||||
|
+ " else "
|
||||||
|
+ " len = length(v_st);"
|
||||||
|
+ " color.a *= smoothstep(zero, u_wscale, u_width - len);"
|
||||||
|
+ " gl_FragColor = color;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
// final static String lineFragmentShader = ""
|
// final static String lineFragmentShader = ""
|
||||||
|
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
// + "precision mediump float;\n"
|
// + "precision mediump float;\n"
|
||||||
// + "uniform float u_wscale;"
|
// + "uniform float u_wscale;"
|
||||||
// + "uniform float u_width;"
|
// + "uniform float u_width;"
|
||||||
@ -41,39 +60,18 @@ class Shaders {
|
|||||||
// + "const float zero = 0.0;"
|
// + "const float zero = 0.0;"
|
||||||
// + "void main() {"
|
// + "void main() {"
|
||||||
// + " vec4 color = u_color;"
|
// + " vec4 color = u_color;"
|
||||||
|
// + " float width = u_width;"
|
||||||
// + " float len;"
|
// + " float len;"
|
||||||
// + " if (v_st.t == zero)"
|
// + " if (v_st.t == zero)"
|
||||||
// + " len = abs(v_st.s);"
|
// + " len = abs(v_st.s);"
|
||||||
// + " else "
|
// + " else "
|
||||||
// + " len = length(v_st);"
|
// + " len = length(v_st);"
|
||||||
// + " color.a *= smoothstep(zero, u_wscale, u_width - len);"
|
// + " vec2 st_width = fwidth(v_st);"
|
||||||
|
// + " float fuzz = max(st_width.s, st_width.t) * 1.5;"
|
||||||
|
// + " color.a *= smoothstep(zero, fuzz + u_wscale, u_width - len);"
|
||||||
// + " gl_FragColor = color;"
|
// + " gl_FragColor = color;"
|
||||||
// + "}";
|
// + "}";
|
||||||
|
|
||||||
final static String lineFragmentShader = ""
|
|
||||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
+ "precision mediump float;\n"
|
|
||||||
+ "uniform float u_wscale;"
|
|
||||||
+ "uniform float u_width;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "varying vec2 v_st;"
|
|
||||||
+ "const float zero = 0.0;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " vec4 color = u_color;"
|
|
||||||
+ " float width = u_width;"
|
|
||||||
+ " float len;"
|
|
||||||
+ " if (v_st.t == zero)"
|
|
||||||
+ " len = abs(v_st.s);"
|
|
||||||
+ " else "
|
|
||||||
+ " len = length(v_st);"
|
|
||||||
// + " if (u_width - len < 2.0){"
|
|
||||||
+ " vec2 st_width = fwidth(v_st);"
|
|
||||||
+ " float fuzz = max(st_width.s, st_width.t) * 1.5;"
|
|
||||||
+ " color.a *= smoothstep(zero, fuzz + u_wscale, u_width - len);"
|
|
||||||
// + " }"
|
|
||||||
+ " gl_FragColor = color;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
final static String polygonVertexShader = ""
|
final static String polygonVertexShader = ""
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform mat4 mvp;"
|
+ "uniform mat4 mvp;"
|
||||||
@ -113,7 +111,7 @@ class Shaders {
|
|||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
// final static String lineVertexZigZagShader = ""
|
// final static String lineVertexZigZagShader = ""
|
||||||
// + "precision mediump float; \n"
|
// + "precision mediump float;"
|
||||||
// + "uniform mat4 mvp;"
|
// + "uniform mat4 mvp;"
|
||||||
// + "attribute vec4 a_pos1;"
|
// + "attribute vec4 a_pos1;"
|
||||||
// + "attribute vec2 a_st1;"
|
// + "attribute vec2 a_st1;"
|
||||||
@ -135,7 +133,7 @@ class Shaders {
|
|||||||
|
|
||||||
// final static String lineFragmentShader = ""
|
// final static String lineFragmentShader = ""
|
||||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
// + "precision mediump float;\n"
|
// + "precision mediump float;"
|
||||||
// + "uniform vec2 u_mode;"
|
// + "uniform vec2 u_mode;"
|
||||||
// + "uniform vec4 u_color;"
|
// + "uniform vec4 u_color;"
|
||||||
// + "varying vec2 v_st;"
|
// + "varying vec2 v_st;"
|
||||||
|
|||||||
@ -23,7 +23,7 @@ public class ShortPool {
|
|||||||
static private int count = 0;
|
static private int count = 0;
|
||||||
static private int countAll = 0;
|
static private int countAll = 0;
|
||||||
|
|
||||||
static synchronized void finish() {
|
static synchronized void init() {
|
||||||
count = 0;
|
count = 0;
|
||||||
countAll = 0;
|
countAll = 0;
|
||||||
pool = null;
|
pool = null;
|
||||||
|
|||||||
@ -45,7 +45,6 @@ public class TextRenderer {
|
|||||||
private static int mFontPadY = 1;
|
private static int mFontPadY = 1;
|
||||||
private static int mBitmapFormat;
|
private static int mBitmapFormat;
|
||||||
private static int mBitmapType;
|
private static int mBitmapType;
|
||||||
private static ByteBuffer mByteBuffer;
|
|
||||||
private static ShortBuffer mShortBuffer;
|
private static ShortBuffer mShortBuffer;
|
||||||
private static TextTexture[] mTextures;
|
private static TextTexture[] mTextures;
|
||||||
|
|
||||||
@ -57,9 +56,8 @@ public class TextRenderer {
|
|||||||
private static int hTextVertex;
|
private static int hTextVertex;
|
||||||
private static int hTextScale;
|
private static int hTextScale;
|
||||||
private static int hTextTextureCoord;
|
private static int hTextTextureCoord;
|
||||||
// private static int hTextUColor;
|
|
||||||
|
|
||||||
static Paint mPaint = new Paint(Color.BLACK);
|
private static Paint mPaint = new Paint(Color.BLACK);
|
||||||
|
|
||||||
private static boolean debug = false;
|
private static boolean debug = false;
|
||||||
private static short[] debugVertices = {
|
private static short[] debugVertices = {
|
||||||
@ -79,13 +77,24 @@ public class TextRenderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static boolean init(int numTextures) {
|
static boolean init(int numTextures) {
|
||||||
mBitmap = Bitmap
|
int bufferSize = numTextures
|
||||||
.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
* MAX_LABELS * VERTICES_PER_SPRITE
|
||||||
|
* SHORTS_PER_VERTICE * (Short.SIZE / 8);
|
||||||
|
|
||||||
|
// if (mBitmap == null) {
|
||||||
|
mBitmap = Bitmap.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT,
|
||||||
|
Bitmap.Config.ARGB_8888);
|
||||||
mCanvas = new Canvas(mBitmap);
|
mCanvas = new Canvas(mBitmap);
|
||||||
|
|
||||||
mBitmapFormat = GLUtils.getInternalFormat(mBitmap);
|
mBitmapFormat = GLUtils.getInternalFormat(mBitmap);
|
||||||
mBitmapType = GLUtils.getType(mBitmap);
|
mBitmapType = GLUtils.getType(mBitmap);
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize)
|
||||||
|
.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
mShortBuffer = buf.asShortBuffer();
|
||||||
|
// }
|
||||||
|
|
||||||
mTextProgram = GlUtils.createProgram(Shaders.textVertexShader,
|
mTextProgram = GlUtils.createProgram(Shaders.textVertexShader,
|
||||||
Shaders.textFragmentShader);
|
Shaders.textFragmentShader);
|
||||||
|
|
||||||
@ -94,15 +103,6 @@ public class TextRenderer {
|
|||||||
hTextScale = GLES20.glGetUniformLocation(mTextProgram, "scale");
|
hTextScale = GLES20.glGetUniformLocation(mTextProgram, "scale");
|
||||||
hTextTextureCoord = GLES20.glGetAttribLocation(mTextProgram, "tex_coord");
|
hTextTextureCoord = GLES20.glGetAttribLocation(mTextProgram, "tex_coord");
|
||||||
|
|
||||||
int bufferSize = numTextures
|
|
||||||
* MAX_LABELS * VERTICES_PER_SPRITE
|
|
||||||
* SHORTS_PER_VERTICE * (Short.SIZE / 8);
|
|
||||||
|
|
||||||
mByteBuffer = ByteBuffer.allocateDirect(bufferSize)
|
|
||||||
.order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
mShortBuffer = mByteBuffer.asShortBuffer();
|
|
||||||
|
|
||||||
int[] textureIds = new int[numTextures];
|
int[] textureIds = new int[numTextures];
|
||||||
TextTexture[] textures = new TextTexture[numTextures];
|
TextTexture[] textures = new TextTexture[numTextures];
|
||||||
GLES20.glGenTextures(numTextures, textureIds, 0);
|
GLES20.glGenTextures(numTextures, textureIds, 0);
|
||||||
@ -136,24 +136,23 @@ public class TextRenderer {
|
|||||||
int len = indices.length;
|
int len = indices.length;
|
||||||
short j = 0;
|
short j = 0;
|
||||||
for (int i = 0; i < len; i += INDICES_PER_SPRITE, j += VERTICES_PER_SPRITE) {
|
for (int i = 0; i < len; i += INDICES_PER_SPRITE, j += VERTICES_PER_SPRITE) {
|
||||||
// indices[i + 0] = (short) (j + 0);
|
|
||||||
// indices[i + 1] = (short) (j + 1);
|
|
||||||
// indices[i + 2] = (short) (j + 2);
|
|
||||||
// indices[i + 3] = (short) (j + 2);
|
|
||||||
// indices[i + 4] = (short) (j + 3);
|
|
||||||
// indices[i + 5] = (short) (j + 0);
|
|
||||||
indices[i + 0] = (short) (j + 0);
|
indices[i + 0] = (short) (j + 0);
|
||||||
indices[i + 1] = (short) (j + 0);
|
indices[i + 1] = (short) (j + 1);
|
||||||
indices[i + 2] = (short) (j + 1);
|
indices[i + 2] = (short) (j + 2);
|
||||||
indices[i + 3] = (short) (j + 3);
|
indices[i + 3] = (short) (j + 2);
|
||||||
indices[i + 4] = (short) (j + 2);
|
indices[i + 4] = (short) (j + 3);
|
||||||
indices[i + 5] = (short) (j + 2);
|
indices[i + 5] = (short) (j + 0);
|
||||||
|
// indices[i + 0] = (short) (j + 0);
|
||||||
|
// indices[i + 1] = (short) (j + 0);
|
||||||
|
// indices[i + 2] = (short) (j + 1);
|
||||||
|
// indices[i + 3] = (short) (j + 3);
|
||||||
|
// indices[i + 4] = (short) (j + 2);
|
||||||
|
// indices[i + 5] = (short) (j + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortBuffer tmpIndices = mByteBuffer.asShortBuffer();
|
mShortBuffer.clear();
|
||||||
|
mShortBuffer.put(indices, 0, len);
|
||||||
tmpIndices.put(indices, 0, len);
|
mShortBuffer.flip();
|
||||||
tmpIndices.flip();
|
|
||||||
|
|
||||||
int[] mVboIds = new int[2];
|
int[] mVboIds = new int[2];
|
||||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||||
@ -162,13 +161,15 @@ public class TextRenderer {
|
|||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
|
||||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, len * (Short.SIZE / 8),
|
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, len * (Short.SIZE / 8),
|
||||||
tmpIndices, GLES20.GL_STATIC_DRAW);
|
mShortBuffer, GLES20.GL_STATIC_DRAW);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
mShortBuffer.clear();
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, bufferSize,
|
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, bufferSize,
|
||||||
mShortBuffer, GLES20.GL_DYNAMIC_DRAW);
|
mShortBuffer, GLES20.GL_DYNAMIC_DRAW);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,10 +361,13 @@ public class TextRenderer {
|
|||||||
tex.length = pos;
|
tex.length = pos;
|
||||||
tile.texture = tex;
|
tile.texture = tex;
|
||||||
tex.tile = tile;
|
tex.tile = tile;
|
||||||
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.id);
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.id);
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mBitmap,
|
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mBitmap,
|
||||||
mBitmapFormat, mBitmapType);
|
mBitmapFormat, mBitmapType);
|
||||||
|
|
||||||
|
GLES20.glFlush();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,9 +392,7 @@ public class TextRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mShortBuffer.flip();
|
mShortBuffer.flip();
|
||||||
// Log.d(TAG, "compileTextures" + mFloatBuffer.remaining() + " " + offset);
|
|
||||||
|
|
||||||
// TODO use sub-bufferdata function
|
|
||||||
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, offset * (Short.SIZE / 8),
|
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, offset * (Short.SIZE / 8),
|
||||||
mShortBuffer);
|
mShortBuffer);
|
||||||
}
|
}
|
||||||
@ -442,7 +444,7 @@ public class TextRenderer {
|
|||||||
GLES20.GL_SHORT, false, 12, tile.texture.offset * (Short.SIZE / 8)
|
GLES20.GL_SHORT, false, 12, tile.texture.offset * (Short.SIZE / 8)
|
||||||
+ 8);
|
+ 8);
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, (tile.texture.length / 24) *
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, (tile.texture.length / 24) *
|
||||||
INDICES_PER_SPRITE, GLES20.GL_UNSIGNED_SHORT, 0);
|
INDICES_PER_SPRITE, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
152
src/org/mapsforge/android/glrenderer/TreeTile.java
Normal file
152
src/org/mapsforge/android/glrenderer/TreeTile.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
class TreeTile {
|
||||||
|
private static String TAG = "TreeTile";
|
||||||
|
|
||||||
|
private static TreeTile root;
|
||||||
|
|
||||||
|
// parent pointer is used to link pool items
|
||||||
|
private static TreeTile pool;
|
||||||
|
|
||||||
|
// TreeTile members
|
||||||
|
TreeTile parent;
|
||||||
|
final TreeTile[] child = new TreeTile[4];
|
||||||
|
int refs = 0;
|
||||||
|
byte id;
|
||||||
|
GLMapTile tile;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
|
||||||
|
pool = null;
|
||||||
|
root = new TreeTile();
|
||||||
|
root.parent = root;
|
||||||
|
|
||||||
|
TreeTile t;
|
||||||
|
for (int i = 0; i < 200; i++) {
|
||||||
|
t = new TreeTile();
|
||||||
|
t.parent = pool;
|
||||||
|
pool = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean remove(GLMapTile t) {
|
||||||
|
if (t.rel == null) {
|
||||||
|
Log.d(TAG, "already removed " + t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeTile cur = t.rel;
|
||||||
|
TreeTile next;
|
||||||
|
|
||||||
|
for (; cur != root;) {
|
||||||
|
// keep pointer to parent
|
||||||
|
next = cur.parent;
|
||||||
|
cur.refs--;
|
||||||
|
|
||||||
|
// if current node has no children
|
||||||
|
if (cur.refs == 0) {
|
||||||
|
// unhook from parent
|
||||||
|
next.child[cur.id] = null;
|
||||||
|
|
||||||
|
// add item back to pool
|
||||||
|
cur.parent = pool;
|
||||||
|
pool = cur;
|
||||||
|
}
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.refs--;
|
||||||
|
|
||||||
|
t.rel.tile = null;
|
||||||
|
t.rel = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TreeTile add(GLMapTile tile) {
|
||||||
|
|
||||||
|
int x = tile.tileX;
|
||||||
|
int y = tile.tileY;
|
||||||
|
int z = tile.zoomLevel;
|
||||||
|
|
||||||
|
TreeTile cur;
|
||||||
|
|
||||||
|
// if (x < 0 || x >= 1 << z) {
|
||||||
|
// Log.d(TAG, "invalid position");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// if (y < 0 || y >= 1 << z) {
|
||||||
|
// Log.d(TAG, "invalid position");
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
TreeTile leaf = root;
|
||||||
|
|
||||||
|
for (int level = z - 1; level >= 0; level--) {
|
||||||
|
|
||||||
|
int id = ((x >> level) & 1) | ((y >> level) & 1) << 1;
|
||||||
|
|
||||||
|
leaf.refs++;
|
||||||
|
|
||||||
|
cur = leaf.child[id];
|
||||||
|
|
||||||
|
if (cur != null) {
|
||||||
|
leaf = cur;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pool != null) {
|
||||||
|
cur = pool;
|
||||||
|
pool = pool.parent;
|
||||||
|
} else {
|
||||||
|
cur = new TreeTile();
|
||||||
|
}
|
||||||
|
|
||||||
|
cur.refs = 0;
|
||||||
|
cur.id = (byte) id;
|
||||||
|
cur.parent = leaf;
|
||||||
|
cur.parent.child[id] = cur;
|
||||||
|
|
||||||
|
leaf = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf.refs++;
|
||||||
|
leaf.tile = tile;
|
||||||
|
tile.rel = leaf;
|
||||||
|
|
||||||
|
return leaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLMapTile getTile(int x, int y, int z) {
|
||||||
|
TreeTile leaf = root;
|
||||||
|
|
||||||
|
for (int level = z - 1; level >= 0; level--) {
|
||||||
|
|
||||||
|
leaf = leaf.child[((x >> level) & 1) | ((y >> level) & 1) << 1];
|
||||||
|
|
||||||
|
if (leaf == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (level == 0) {
|
||||||
|
return leaf.tile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,10 +25,10 @@ final class WayDecorator {
|
|||||||
// */
|
// */
|
||||||
// private static final int DISTANCE_BETWEEN_SYMBOLS = 200;
|
// private static final int DISTANCE_BETWEEN_SYMBOLS = 200;
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Minimum distance in pixels before the way name is repeated.
|
// * Minimum distance in pixels before the way name is repeated.
|
||||||
*/
|
// */
|
||||||
private static final int DISTANCE_BETWEEN_WAY_NAMES = 500;
|
// private static final int DISTANCE_BETWEEN_WAY_NAMES = 500;
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Distance in pixels to skip from both ends of a segment.
|
// * Distance in pixels to skip from both ends of a segment.
|
||||||
|
|||||||
@ -17,18 +17,19 @@ package org.mapsforge.android.input;
|
|||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.MapViewPosition;
|
import org.mapsforge.android.MapViewPosition;
|
||||||
|
|
||||||
|
import android.os.CountDownTimer;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {
|
class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {
|
||||||
private final MapView mMapView;
|
private final MapView mMapView;
|
||||||
private MapViewPosition mMapPosition;
|
private MapViewPosition mMapPosition;
|
||||||
private float mCenterX;
|
private float mCenterX;
|
||||||
private float mCenterY;
|
private float mCenterY;
|
||||||
// private float mFocusX;
|
|
||||||
// private float mFocusY;
|
|
||||||
private float mScale;
|
private float mScale;
|
||||||
|
private boolean mBeginScale;
|
||||||
|
|
||||||
// private boolean mScaling;
|
|
||||||
/**
|
/**
|
||||||
* Creates a new ScaleListener for the given MapView.
|
* Creates a new ScaleListener for the given MapView.
|
||||||
*
|
*
|
||||||
@ -40,52 +41,104 @@ class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
|
public boolean onScale(ScaleGestureDetector gd) {
|
||||||
|
|
||||||
float focusX = scaleGestureDetector.getFocusX();
|
float focusX = gd.getFocusX();
|
||||||
float focusY = scaleGestureDetector.getFocusY();
|
float focusY = gd.getFocusY();
|
||||||
mScale = scaleGestureDetector.getScaleFactor();
|
mScale = gd.getScaleFactor();
|
||||||
|
|
||||||
// mMapPosition.moveMap((focusX - mFocusX), (focusY - mFocusY));
|
mSumScale *= mScale;
|
||||||
// if (mScale > 1.001 || mScale < 0.999) {
|
|
||||||
|
|
||||||
mMapPosition.scaleMap(mScale,
|
mTimeEnd = SystemClock.elapsedRealtime();
|
||||||
focusX - mCenterX,
|
|
||||||
focusY - mCenterY);
|
if (!mBeginScale) {
|
||||||
|
if (mTimeEnd - mTimeStart > 100) {
|
||||||
|
mBeginScale = true;
|
||||||
|
mScale = mSumScale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMapPosition.scaleMap(mScale, focusX - mCenterX, focusY - mCenterY);
|
||||||
mMapView.redrawTiles();
|
mMapView.redrawTiles();
|
||||||
// mScale = 1;
|
|
||||||
|
|
||||||
// mFocusX = focusX;
|
|
||||||
// mFocusY = focusY;
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else if (Math.abs(focusX - mFocusX) > 0.5 || Math.abs(focusY - mFocusY) > 0.5) {
|
|
||||||
// mMapPosition.moveMap((focusX - mFocusX), (focusY - mFocusY));
|
|
||||||
//
|
|
||||||
// mFocusX = focusX;
|
|
||||||
// mFocusY = focusY;
|
|
||||||
// mScale = 1;
|
|
||||||
// mMapView.redrawTiles();
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private long mTimeStart;
|
||||||
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
|
private long mTimeEnd;
|
||||||
|
private float mSumScale;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onScaleBegin(ScaleGestureDetector gd) {
|
||||||
|
mTimeEnd = mTimeStart = SystemClock.elapsedRealtime();
|
||||||
|
mSumScale = 1;
|
||||||
|
mBeginScale = false;
|
||||||
mCenterX = mMapView.getWidth() >> 1;
|
mCenterX = mMapView.getWidth() >> 1;
|
||||||
mCenterY = mMapView.getHeight() >> 1;
|
mCenterY = mMapView.getHeight() >> 1;
|
||||||
// mFocusX = scaleGestureDetector.getFocusX();
|
|
||||||
// mFocusY = scaleGestureDetector.getFocusY();
|
|
||||||
mScale = 1;
|
mScale = 1;
|
||||||
mMapPosition = mMapView.getMapPosition();
|
mMapPosition = mMapView.getMapPosition();
|
||||||
// mScaling = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
|
public void onScaleEnd(ScaleGestureDetector gd) {
|
||||||
// do nothing
|
// Log.d("ScaleListener", "Sum " + mSumScale + " " + (mTimeEnd - mTimeStart));
|
||||||
|
if (mTimer == null && mTimeEnd - mTimeStart < 150
|
||||||
|
&& (mSumScale < 0.99 || mSumScale > 1.01)) {
|
||||||
|
|
||||||
|
mPrevScale = 0;
|
||||||
|
|
||||||
|
mZooutOut = mSumScale < 0.99;
|
||||||
|
|
||||||
|
mTimer = new CountDownTimer((int) mScaleDuration, 30) {
|
||||||
|
@Override
|
||||||
|
public void onTick(long tick) {
|
||||||
|
scale(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
scale(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private DecelerateInterpolator mBounce = new DecelerateInterpolator();
|
||||||
|
private float mPrevScale;
|
||||||
|
private CountDownTimer mTimer;
|
||||||
|
boolean mZooutOut;
|
||||||
|
private final float mScaleDuration = 350;
|
||||||
|
|
||||||
|
boolean scale(long tick) {
|
||||||
|
|
||||||
|
if (mPrevScale >= 1) {
|
||||||
|
mTimer = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float adv = (mScaleDuration - tick) / mScaleDuration;
|
||||||
|
adv = mBounce.getInterpolation(adv);
|
||||||
|
|
||||||
|
float scale = adv - mPrevScale;
|
||||||
|
mPrevScale += scale;
|
||||||
|
|
||||||
|
if (mZooutOut) {
|
||||||
|
scale = 1 - scale;
|
||||||
|
} else {
|
||||||
|
scale = 1 + scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMapPosition.scaleMap(scale, 0, 0);
|
||||||
|
mMapView.redrawTiles();
|
||||||
|
|
||||||
|
if (tick == 0)
|
||||||
|
mTimer = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,16 +15,17 @@
|
|||||||
package org.mapsforge.android.input;
|
package org.mapsforge.android.input;
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
|
import org.mapsforge.android.MapViewPosition;
|
||||||
import org.mapsforge.core.Tile;
|
import org.mapsforge.core.Tile;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.Scroller;
|
import android.widget.Scroller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,15 +34,15 @@ import android.widget.Scroller;
|
|||||||
public class TouchHandler {
|
public class TouchHandler {
|
||||||
private static final int INVALID_POINTER_ID = -1;
|
private static final int INVALID_POINTER_ID = -1;
|
||||||
|
|
||||||
/**
|
|
||||||
* is pritected correct? share MapView with inner class
|
|
||||||
*/
|
|
||||||
protected final MapView mMapView;
|
protected final MapView mMapView;
|
||||||
|
protected final MapViewPosition mMapPosition;
|
||||||
|
|
||||||
private final float mMapMoveDelta;
|
private final float mMapMoveDelta;
|
||||||
private boolean mMoveThresholdReached;
|
private boolean mMoveThresholdReached;
|
||||||
private float mPreviousPositionX;
|
private float mPosX;
|
||||||
private float mPreviousPositionY;
|
private float mPosY;
|
||||||
|
private float mAngle;
|
||||||
|
|
||||||
private int mActivePointerId;
|
private int mActivePointerId;
|
||||||
|
|
||||||
private final ScaleGestureDetector mScaleGestureDetector;
|
private final ScaleGestureDetector mScaleGestureDetector;
|
||||||
@ -56,11 +57,13 @@ public class TouchHandler {
|
|||||||
public TouchHandler(Context context, MapView mapView) {
|
public TouchHandler(Context context, MapView mapView) {
|
||||||
ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
|
ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
|
mMapPosition = mapView.getMapPosition();
|
||||||
mMapMoveDelta = viewConfiguration.getScaledTouchSlop();
|
mMapMoveDelta = viewConfiguration.getScaledTouchSlop();
|
||||||
mActivePointerId = INVALID_POINTER_ID;
|
mActivePointerId = INVALID_POINTER_ID;
|
||||||
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener(
|
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener(
|
||||||
mMapView));
|
mMapView));
|
||||||
mGestureDetector = new GestureDetector(new MapGestureDetector(mMapView));
|
mGestureDetector = new GestureDetector(context, new MapGestureDetector(mMapView));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getAction(MotionEvent motionEvent) {
|
private static int getAction(MotionEvent motionEvent) {
|
||||||
@ -72,22 +75,30 @@ public class TouchHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean onActionDown(MotionEvent motionEvent) {
|
private boolean onActionDown(MotionEvent event) {
|
||||||
mPreviousPositionX = motionEvent.getX();
|
mPosX = event.getX();
|
||||||
mPreviousPositionY = motionEvent.getY();
|
mPosY = event.getY();
|
||||||
mMoveThresholdReached = false;
|
mMoveThresholdReached = false;
|
||||||
// save the ID of the pointer
|
// save the ID of the pointer
|
||||||
mActivePointerId = motionEvent.getPointerId(0);
|
mActivePointerId = event.getPointerId(0);
|
||||||
|
// Log.d("...", "set active pointer" + mActivePointerId);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean onActionMove(MotionEvent motionEvent) {
|
private boolean mScaling = false;
|
||||||
int pointerIndex = motionEvent.findPointerIndex(mActivePointerId);
|
|
||||||
|
private boolean onActionMove(MotionEvent event) {
|
||||||
|
int pointerIndex = event.findPointerIndex(mActivePointerId);
|
||||||
|
|
||||||
// calculate the distance between previous and current position
|
// calculate the distance between previous and current position
|
||||||
float moveX = motionEvent.getX(pointerIndex) - mPreviousPositionX;
|
float moveX = event.getX(pointerIndex) - mPosX;
|
||||||
float moveY = motionEvent.getY(pointerIndex) - mPreviousPositionY;
|
float moveY = event.getY(pointerIndex) - mPosY;
|
||||||
|
|
||||||
boolean scaling = mScaleGestureDetector.isInProgress();
|
boolean scaling = mScaleGestureDetector.isInProgress();
|
||||||
|
if (!mScaling) {
|
||||||
|
mScaling = scaling;
|
||||||
|
}
|
||||||
if (!scaling && !mMoveThresholdReached) {
|
if (!scaling && !mMoveThresholdReached) {
|
||||||
|
|
||||||
if (Math.abs(moveX) > 3 * mMapMoveDelta
|
if (Math.abs(moveX) > 3 * mMapMoveDelta
|
||||||
@ -97,36 +108,57 @@ public class TouchHandler {
|
|||||||
mMoveThresholdReached = true;
|
mMoveThresholdReached = true;
|
||||||
|
|
||||||
// save the position of the event
|
// save the position of the event
|
||||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
mPosX = event.getX(pointerIndex);
|
||||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
mPosY = event.getY(pointerIndex);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (multi > 0) {
|
||||||
|
// double dx = event.getX(0) - event.getX(1);
|
||||||
|
// double dy = event.getY(0) - event.getY(1);
|
||||||
|
// double rad = Math.atan2(dy, dx);
|
||||||
|
// float angle = (float) Math.toDegrees(rad);
|
||||||
|
// mMapPosition.rotateMap(angle - mAngle);
|
||||||
|
// mAngle = angle;
|
||||||
|
// mMapView.redrawTiles();
|
||||||
|
// }
|
||||||
|
|
||||||
// save the position of the event
|
// save the position of the event
|
||||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
mPosX = event.getX(pointerIndex);
|
||||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
mPosY = event.getY(pointerIndex);
|
||||||
|
|
||||||
if (scaling) {
|
if (scaling) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMapView.getMapPosition().moveMap(moveX, moveY);
|
mMapPosition.moveMap(moveX, moveY);
|
||||||
mMapView.redrawTiles();
|
mMapView.redrawTiles();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private boolean onActionPointerDown(MotionEvent motionEvent) {
|
private int multi = 0;
|
||||||
// longPressDetector.pressStop();
|
|
||||||
// multiTouchDownTime = motionEvent.getEventTime();
|
private boolean onActionPointerDown(MotionEvent event) {
|
||||||
// return true;
|
// longPressDetector.pressStop();
|
||||||
// }
|
// multiTouchDownTime = motionEvent.getEventTime();
|
||||||
|
multi++;
|
||||||
|
if (multi == 1) {
|
||||||
|
double dx = event.getX(0) - event.getX(1);
|
||||||
|
double dy = event.getY(0) - event.getY(1);
|
||||||
|
double rad = Math.atan2(dy, dx);
|
||||||
|
mAngle = (float) Math.toDegrees(rad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean onActionPointerUp(MotionEvent motionEvent) {
|
private boolean onActionPointerUp(MotionEvent motionEvent) {
|
||||||
|
|
||||||
// extract the index of the pointer that left the touch sensor
|
// extract the index of the pointer that left the touch sensor
|
||||||
int pointerIndex = (motionEvent.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
int pointerIndex = (motionEvent.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||||
|
|
||||||
if (motionEvent.getPointerId(pointerIndex) == mActivePointerId) {
|
if (motionEvent.getPointerId(pointerIndex) == mActivePointerId) {
|
||||||
// the active pointer has gone up, choose a new one
|
// the active pointer has gone up, choose a new one
|
||||||
if (pointerIndex == 0) {
|
if (pointerIndex == 0) {
|
||||||
@ -135,19 +167,12 @@ public class TouchHandler {
|
|||||||
pointerIndex = 0;
|
pointerIndex = 0;
|
||||||
}
|
}
|
||||||
// save the position of the event
|
// save the position of the event
|
||||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
mPosX = motionEvent.getX(pointerIndex);
|
||||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
mPosY = motionEvent.getY(pointerIndex);
|
||||||
mActivePointerId = motionEvent.getPointerId(pointerIndex);
|
mActivePointerId = motionEvent.getPointerId(pointerIndex);
|
||||||
}
|
}
|
||||||
|
multi--;
|
||||||
|
|
||||||
// calculate the time difference since the pointer has gone down
|
|
||||||
// long multiTouchTime = motionEvent.getEventTime() -
|
|
||||||
// multiTouchDownTime;
|
|
||||||
// if (multiTouchTime < doubleTapTimeout) {
|
|
||||||
// // multi-touch tap event, zoom out
|
|
||||||
// previousEventTap = false;
|
|
||||||
// mapView.zoom((byte) -1);
|
|
||||||
// }
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,83 +182,53 @@ public class TouchHandler {
|
|||||||
* @return ...
|
* @return ...
|
||||||
*/
|
*/
|
||||||
private boolean onActionUp(MotionEvent motionEvent) {
|
private boolean onActionUp(MotionEvent motionEvent) {
|
||||||
// longPressDetector.pressStop();
|
|
||||||
// int pointerIndex = motionEvent.findPointerIndex(mActivePointerId);
|
|
||||||
|
|
||||||
mActivePointerId = INVALID_POINTER_ID;
|
mActivePointerId = INVALID_POINTER_ID;
|
||||||
// if (mMoveThresholdReached // || longPressDetector.isEventHandled()
|
mScaling = false;
|
||||||
// ) {
|
|
||||||
// mPreviousEventTap = false;
|
|
||||||
// } else {
|
|
||||||
// if (mPreviousEventTap) {
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// mPreviousEventTap = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // store the position and the time of this tap event
|
|
||||||
// mPreviousTapX = motionEvent.getX(pointerIndex);
|
|
||||||
// mPreviousTapY = motionEvent.getY(pointerIndex);
|
|
||||||
// mPreviousTapTime = motionEvent.getEventTime();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long lastRun = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param motionEvent
|
* @param event
|
||||||
* ...
|
* ...
|
||||||
* @return ...
|
* @return ...
|
||||||
*/
|
*/
|
||||||
public boolean handleMotionEvent(MotionEvent motionEvent) {
|
public boolean handleMotionEvent(MotionEvent event) {
|
||||||
|
|
||||||
// workaround for a bug in the ScaleGestureDetector, see Android issue
|
// workaround for a bug in the ScaleGestureDetector, see Android issue
|
||||||
// #12976
|
// #12976
|
||||||
if (motionEvent.getAction() != MotionEvent.ACTION_MOVE
|
// if (event.getAction() != MotionEvent.ACTION_MOVE
|
||||||
|| motionEvent.getPointerCount() > 1) {
|
// || event.getPointerCount() > 1) {
|
||||||
mScaleGestureDetector.onTouchEvent(motionEvent);
|
mScaleGestureDetector.onTouchEvent(event);
|
||||||
}
|
|
||||||
|
|
||||||
mGestureDetector.onTouchEvent(motionEvent);
|
|
||||||
// if () {
|
|
||||||
// // mActivePointerId = INVALID_POINTER_ID;
|
|
||||||
// // return true;
|
|
||||||
// }
|
// }
|
||||||
int action = getAction(motionEvent);
|
|
||||||
|
if (!mScaling)
|
||||||
|
mGestureDetector.onTouchEvent(event);
|
||||||
|
|
||||||
|
int action = getAction(event);
|
||||||
boolean ret = false;
|
boolean ret = false;
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
ret = onActionDown(motionEvent);
|
ret = onActionDown(event);
|
||||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||||
ret = onActionMove(motionEvent);
|
ret = onActionMove(event);
|
||||||
} else if (action == MotionEvent.ACTION_UP) {
|
} else if (action == MotionEvent.ACTION_UP) {
|
||||||
ret = onActionUp(motionEvent);
|
ret = onActionUp(event);
|
||||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||||
ret = onActionCancel();
|
ret = onActionCancel();
|
||||||
// } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||||
// return onActionPointerDown(motionEvent);
|
return onActionPointerDown(event);
|
||||||
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
||||||
ret = onActionPointerUp(motionEvent);
|
ret = onActionPointerUp(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (ret) {
|
|
||||||
// // throttle input
|
|
||||||
// long diff = SystemClock.uptimeMillis() - lastRun;
|
|
||||||
// if (diff < 16 && diff > 5) {
|
|
||||||
// // Log.d("", "" + diff);
|
|
||||||
// SystemClock.sleep(16 - diff);
|
|
||||||
// }
|
|
||||||
// lastRun = SystemClock.uptimeMillis();
|
|
||||||
// }
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapGestureDetector extends SimpleOnGestureListener {
|
class MapGestureDetector extends SimpleOnGestureListener {
|
||||||
private Scroller mScroller;
|
private Scroller mScroller;
|
||||||
private float mPrevX, mPrevY;
|
private float mPrevX, mPrevY, mPrevScale;
|
||||||
private CountDownTimer mTimer = null;
|
private CountDownTimer mTimer = null;
|
||||||
|
private boolean fling = false;
|
||||||
|
|
||||||
public MapGestureDetector(MapView mapView) {
|
public MapGestureDetector(MapView mapView) {
|
||||||
mScroller = new Scroller(mapView.getContext(),
|
mScroller = new Scroller(mapView.getContext(),
|
||||||
@ -242,12 +237,17 @@ public class TouchHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDown(MotionEvent e) {
|
public boolean onDown(MotionEvent e) {
|
||||||
mScroller.forceFinished(true);
|
if (fling) {
|
||||||
|
mScroller.forceFinished(true);
|
||||||
|
|
||||||
if (mTimer != null) {
|
if (mTimer != null) {
|
||||||
mTimer.cancel();
|
mTimer.cancel();
|
||||||
mTimer = null;
|
mTimer = null;
|
||||||
|
}
|
||||||
|
fling = false;
|
||||||
}
|
}
|
||||||
|
// Log.d("mapsforge", "onDown");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,11 +256,12 @@ public class TouchHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mScroller.computeScrollOffset();
|
mScroller.computeScrollOffset();
|
||||||
|
|
||||||
float moveX = mScroller.getCurrX() - mPrevX;
|
float moveX = mScroller.getCurrX() - mPrevX;
|
||||||
float moveY = mScroller.getCurrY() - mPrevY;
|
float moveY = mScroller.getCurrY() - mPrevY;
|
||||||
|
|
||||||
if (moveX >= 1 || moveY >= 1 || moveX <= -1 || moveY <= -1) {
|
if (moveX >= 1 || moveY >= 1 || moveX <= -1 || moveY <= -1) {
|
||||||
mMapView.getMapPosition().moveMap(moveX, moveY);
|
mMapPosition.moveMap(moveX, moveY);
|
||||||
mMapView.redrawTiles();
|
mMapView.redrawTiles();
|
||||||
mPrevX = mScroller.getCurrX();
|
mPrevX = mScroller.getCurrX();
|
||||||
mPrevY = mScroller.getCurrY();
|
mPrevY = mScroller.getCurrY();
|
||||||
@ -271,8 +272,8 @@ public class TouchHandler {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||||
float velocityY) {
|
float velocityY) {
|
||||||
int w = Tile.TILE_SIZE * 10;
|
int w = Tile.TILE_SIZE * 20;
|
||||||
int h = Tile.TILE_SIZE * 10;
|
int h = Tile.TILE_SIZE * 20;
|
||||||
mPrevX = 0;
|
mPrevX = 0;
|
||||||
mPrevY = 0;
|
mPrevY = 0;
|
||||||
|
|
||||||
@ -283,12 +284,12 @@ public class TouchHandler {
|
|||||||
|
|
||||||
mScroller.fling(0, 0, Math.round(velocityX) / 2, Math.round(velocityY) / 2,
|
mScroller.fling(0, 0, Math.round(velocityX) / 2, Math.round(velocityY) / 2,
|
||||||
-w, w, -h, h);
|
-w, w, -h, h);
|
||||||
|
|
||||||
// animate for two seconds
|
// animate for two seconds
|
||||||
mTimer = new CountDownTimer(2000, 40) {
|
mTimer = new CountDownTimer(1500, 50) {
|
||||||
@Override
|
@Override
|
||||||
public void onTick(long tick) {
|
public void onTick(long tick) {
|
||||||
if (!scroll())
|
scroll();
|
||||||
cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -296,21 +297,61 @@ public class TouchHandler {
|
|||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
|
fling = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DecelerateInterpolator mBounce = new DecelerateInterpolator();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLongPress(MotionEvent e) {
|
public void onLongPress(MotionEvent e) {
|
||||||
// mMapView.zoom((byte) 1);
|
// mMapView.zoom((byte) 1);
|
||||||
Log.d("mapsforge", "long press");
|
// Log.d("mapsforge", "long press");
|
||||||
// return true;
|
}
|
||||||
|
|
||||||
|
private final float mScaleDuration = 300;
|
||||||
|
|
||||||
|
boolean scale(long tick) {
|
||||||
|
|
||||||
|
fling = true;
|
||||||
|
if (mPrevScale >= 1)
|
||||||
|
return false;
|
||||||
|
float adv = (mScaleDuration - tick) / mScaleDuration;
|
||||||
|
adv = mBounce.getInterpolation(adv);
|
||||||
|
|
||||||
|
float scale = adv - mPrevScale;
|
||||||
|
mPrevScale += scale;
|
||||||
|
scale += 1;
|
||||||
|
adv += 1;
|
||||||
|
|
||||||
|
if (scale > 1) {
|
||||||
|
mMapPosition.scaleMap(scale, mPrevX / adv, mPrevY / adv);
|
||||||
|
mMapView.redrawTiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTap(MotionEvent e) {
|
public boolean onDoubleTap(MotionEvent e) {
|
||||||
mMapView.zoom((byte) 1);
|
// Log.d("mapsforge", "double tap");
|
||||||
Log.d("mapsforge", "double tap");
|
|
||||||
|
mPrevX = (e.getX(0) - (mMapView.getWidth() >> 1)) * 2f;
|
||||||
|
mPrevY = (e.getY(0) - (mMapView.getHeight() >> 1)) * 2f;
|
||||||
|
mPrevScale = 0;
|
||||||
|
|
||||||
|
mTimer = new CountDownTimer((int) mScaleDuration, 30) {
|
||||||
|
@Override
|
||||||
|
public void onTick(long tick) {
|
||||||
|
scale(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
scale(0);
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,11 +29,11 @@ public interface IMapGenerator {
|
|||||||
/**
|
/**
|
||||||
* Called when a job needs to be executed.
|
* Called when a job needs to be executed.
|
||||||
*
|
*
|
||||||
* @param mapGeneratorJob
|
* @param tile
|
||||||
* the job that should be executed.
|
* the job that should be executed.
|
||||||
* @return true if the job was executed successfully, false otherwise.
|
* @return true if the job was executed successfully, false otherwise.
|
||||||
*/
|
*/
|
||||||
boolean executeJob(MapGeneratorJob mapGeneratorJob);
|
boolean executeJob(MapTile tile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapDatabase
|
* @param mapDatabase
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.mapgenerator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A JobParameters instance is a simple DTO to store the rendering parameters for a job.
|
|
||||||
*/
|
|
||||||
public class JobParameters {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The render theme which should be used.
|
|
||||||
*/
|
|
||||||
public final Theme theme;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The text scale factor which should applied to the render theme.
|
|
||||||
*/
|
|
||||||
public final float textScale;
|
|
||||||
|
|
||||||
private final int mHashCodeValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param theme
|
|
||||||
* render theme which should be used.
|
|
||||||
* @param textScale
|
|
||||||
* the text scale factor which should applied to the render theme.
|
|
||||||
*/
|
|
||||||
public JobParameters(Theme theme, float textScale) {
|
|
||||||
this.theme = theme;
|
|
||||||
this.textScale = textScale;
|
|
||||||
mHashCodeValue = calculateHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof JobParameters)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
JobParameters other = (JobParameters) obj;
|
|
||||||
if (theme == null) {
|
|
||||||
if (other.theme != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!theme.equals(other.theme)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Float.floatToIntBits(textScale) != Float.floatToIntBits(other.textScale)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return mHashCodeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hash code of this object.
|
|
||||||
*/
|
|
||||||
private int calculateHashCode() {
|
|
||||||
int result = 7;
|
|
||||||
result = 31 * result + ((theme == null) ? 0 : theme.hashCode());
|
|
||||||
result = 31 * result + Float.floatToIntBits(textScale);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -17,54 +17,29 @@ package org.mapsforge.android.mapgenerator;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
|
|
||||||
import android.os.SystemClock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
||||||
*/
|
*/
|
||||||
public class JobQueue {
|
public class JobQueue {
|
||||||
private static final int INITIAL_CAPACITY = 128;
|
private static final int INITIAL_CAPACITY = 64;
|
||||||
|
|
||||||
private final MapView mMapView;
|
private PriorityQueue<MapTile> mPriorityQueue;
|
||||||
private PriorityQueue<MapGeneratorJob> mPriorityQueue;
|
|
||||||
private boolean mScheduleNeeded;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapView
|
|
||||||
* the MapView whose jobs should be organized.
|
|
||||||
*/
|
*/
|
||||||
public JobQueue(MapView mapView) {
|
public JobQueue() {
|
||||||
mMapView = mapView;
|
mPriorityQueue = new PriorityQueue<MapTile>(INITIAL_CAPACITY);
|
||||||
mPriorityQueue = new PriorityQueue<MapGeneratorJob>(INITIAL_CAPACITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given job to this queue. Does nothing if the given job is already in this queue.
|
* @param tiles
|
||||||
*
|
|
||||||
* @param mapGeneratorJob
|
|
||||||
* the job to be added to this queue.
|
* the job to be added to this queue.
|
||||||
*/
|
*/
|
||||||
// public synchronized void addJob(MapGeneratorJob mapGeneratorJob) {
|
public synchronized void setJobs(ArrayList<MapTile> tiles) {
|
||||||
// if (!mPriorityQueue.contains(mapGeneratorJob))
|
|
||||||
// // priorityQueue.remove(mapGeneratorJob);
|
|
||||||
// {
|
|
||||||
// //mapGeneratorJob.tile.isLoading = true;
|
|
||||||
// mPriorityQueue.offer(mapGeneratorJob);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param jobs
|
|
||||||
* the job to be added to this queue.
|
|
||||||
*/
|
|
||||||
public synchronized void setJobs(ArrayList<MapGeneratorJob> jobs) {
|
|
||||||
mPriorityQueue.clear();
|
mPriorityQueue.clear();
|
||||||
for (MapGeneratorJob job : jobs)
|
mPriorityQueue.addAll(tiles);
|
||||||
mPriorityQueue.offer(job);
|
// for (int i = 0, n = tiles.size(); i < n; i++)
|
||||||
// priorityQueue.addAll(jobs);
|
// mPriorityQueue.offer(tiles.get(i));
|
||||||
mScheduleNeeded = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,39 +59,11 @@ public class JobQueue {
|
|||||||
/**
|
/**
|
||||||
* @return the most important job from this queue or null, if empty.
|
* @return the most important job from this queue or null, if empty.
|
||||||
*/
|
*/
|
||||||
public synchronized MapGeneratorJob poll() {
|
public synchronized MapTile poll() {
|
||||||
if (mScheduleNeeded) {
|
MapTile tile = mPriorityQueue.poll();
|
||||||
mScheduleNeeded = false;
|
if (tile != null)
|
||||||
schedule();
|
tile.isLoading = true;
|
||||||
}
|
|
||||||
return mPriorityQueue.poll();
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request a scheduling of all jobs that are currently in this queue.
|
|
||||||
*/
|
|
||||||
public synchronized void requestSchedule() {
|
|
||||||
mScheduleNeeded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules all jobs in this queue.
|
|
||||||
*/
|
|
||||||
private void schedule() {
|
|
||||||
PriorityQueue<MapGeneratorJob> tempJobQueue = new PriorityQueue<MapGeneratorJob>(
|
|
||||||
INITIAL_CAPACITY);
|
|
||||||
|
|
||||||
TileScheduler.time = SystemClock.uptimeMillis();
|
|
||||||
TileScheduler.mapPosition = mMapView.getMapPosition().getMapPosition();
|
|
||||||
|
|
||||||
while (!mPriorityQueue.isEmpty()) {
|
|
||||||
MapGeneratorJob mapGeneratorJob = mPriorityQueue.poll();
|
|
||||||
double priority = TileScheduler.getPriority(mapGeneratorJob, mMapView);
|
|
||||||
mapGeneratorJob.setPriority(priority);
|
|
||||||
tempJobQueue.offer(mapGeneratorJob);
|
|
||||||
}
|
|
||||||
|
|
||||||
mPriorityQueue = tempJobQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public final class MapDatabaseFactory {
|
|||||||
String mapDatabaseName = attributeSet.getAttributeValue(null,
|
String mapDatabaseName = attributeSet.getAttributeValue(null,
|
||||||
MAP_DATABASE_ATTRIBUTE_NAME);
|
MAP_DATABASE_ATTRIBUTE_NAME);
|
||||||
if (mapDatabaseName == null) {
|
if (mapDatabaseName == null) {
|
||||||
return MapDatabases.POSTGIS_READER;
|
return MapDatabases.PBMAP_READER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MapDatabases.valueOf(mapDatabaseName);
|
return MapDatabases.valueOf(mapDatabaseName);
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.mapgenerator;
|
|
||||||
|
|
||||||
import org.mapsforge.android.utils.PausableThread;
|
|
||||||
|
|
||||||
public class MapDownloader extends PausableThread {
|
|
||||||
private static final String THREAD_NAME = "MapDownloader";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doWork() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasWork() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getThreadName() {
|
|
||||||
return THREAD_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getThreadPriority() {
|
|
||||||
return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.mapgenerator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.mapsforge.android.DebugSettings;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A MapGeneratorJob holds all immutable rendering parameters for a single map image together with a mutable priority
|
|
||||||
* field, which indicates the importance of this job.
|
|
||||||
*/
|
|
||||||
public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The debug settings for this job.
|
|
||||||
*/
|
|
||||||
public final DebugSettings debugSettings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The rendering parameters for this job.
|
|
||||||
*/
|
|
||||||
// public final JobParameters jobParameters;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tile which should be generated.
|
|
||||||
*/
|
|
||||||
public final MapTile tile;
|
|
||||||
|
|
||||||
private transient int mHashCodeValue;
|
|
||||||
private transient double mPriority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bitmap passed to renderer
|
|
||||||
*/
|
|
||||||
private Bitmap mBitmap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public Bitmap getBitmap() {
|
|
||||||
return mBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bitmap
|
|
||||||
* ..
|
|
||||||
*/
|
|
||||||
public void setBitmap(Bitmap bitmap) {
|
|
||||||
mBitmap = bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float mScale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return scale the tile is rendered with
|
|
||||||
*/
|
|
||||||
public float getScale() {
|
|
||||||
return mScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param _scale
|
|
||||||
* for the tile to be rendered
|
|
||||||
*/
|
|
||||||
public void setScale(float _scale) {
|
|
||||||
mScale = _scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new job for a MapGenerator with the given parameters.
|
|
||||||
*
|
|
||||||
* @param _tile
|
|
||||||
* the tile which should be generated.
|
|
||||||
* @param _jobParameters
|
|
||||||
* the rendering parameters for this job.
|
|
||||||
* @param _debugSettings
|
|
||||||
* the debug settings for this job.
|
|
||||||
*/
|
|
||||||
public MapGeneratorJob(MapTile _tile, JobParameters _jobParameters,
|
|
||||||
DebugSettings _debugSettings) {
|
|
||||||
tile = _tile;
|
|
||||||
// jobParameters = _jobParameters;
|
|
||||||
debugSettings = _debugSettings;
|
|
||||||
calculateTransientValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(MapGeneratorJob o) {
|
|
||||||
if (mPriority < o.mPriority) {
|
|
||||||
return -1;
|
|
||||||
} else if (mPriority > o.mPriority) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(obj instanceof MapGeneratorJob)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
MapGeneratorJob other = (MapGeneratorJob) obj;
|
|
||||||
|
|
||||||
if (debugSettings == null) {
|
|
||||||
if (other.debugSettings != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!debugSettings.equals(other.debugSettings)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// if (jobParameters == null) {
|
|
||||||
// if (other.jobParameters != null) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// } else if (!jobParameters.equals(other.jobParameters)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (tile == null) {
|
|
||||||
if (other.tile != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!tile.equals(other.tile)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return mHashCodeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hash code of this object.
|
|
||||||
*/
|
|
||||||
private int calculateHashCode() {
|
|
||||||
int result = 1;
|
|
||||||
result = 31 * result + ((debugSettings == null) ? 0 : debugSettings.hashCode());
|
|
||||||
// result = 31 * result + ((jobParameters == null) ? 0 : jobParameters.hashCode());
|
|
||||||
result = 31 * result + ((tile == null) ? 0 : tile.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the values of some transient variables.
|
|
||||||
*/
|
|
||||||
private void calculateTransientValues() {
|
|
||||||
mHashCodeValue = calculateHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readObject(ObjectInputStream objectInputStream) throws IOException,
|
|
||||||
ClassNotFoundException {
|
|
||||||
objectInputStream.defaultReadObject();
|
|
||||||
calculateTransientValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPriority(double priority) {
|
|
||||||
mPriority = priority;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,7 +19,7 @@ import org.mapsforge.core.Tile;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MapTile extends Tile {
|
public class MapTile extends Tile implements Comparable<MapTile> {
|
||||||
/**
|
/**
|
||||||
* tile is loaded and ready for drawing. (set and used by render thread after uploading data to gl).
|
* tile is loaded and ready for drawing. (set and used by render thread after uploading data to gl).
|
||||||
*/
|
*/
|
||||||
@ -53,7 +53,17 @@ public class MapTile extends Tile {
|
|||||||
* @param zoomLevel
|
* @param zoomLevel
|
||||||
* ..
|
* ..
|
||||||
*/
|
*/
|
||||||
public MapTile(long tileX, long tileY, byte zoomLevel) {
|
public MapTile(int tileX, int tileY, byte zoomLevel) {
|
||||||
super(tileX, tileY, zoomLevel);
|
super(tileX, tileY, zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(MapTile o) {
|
||||||
|
if (this.distance < o.distance) {
|
||||||
|
return -1;
|
||||||
|
} else if (this.distance > o.distance) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,15 +62,15 @@ public class MapWorker extends PausableThread {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doWork() {
|
protected void doWork() {
|
||||||
MapGeneratorJob mapGeneratorJob = mJobQueue.poll();
|
MapTile tile = mJobQueue.poll();
|
||||||
|
|
||||||
if (mMapGenerator == null || mapGeneratorJob == null)
|
if (mMapGenerator == null || tile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean success = mMapGenerator.executeJob(mapGeneratorJob);
|
boolean success = mMapGenerator.executeJob(tile);
|
||||||
|
|
||||||
if (!isInterrupted() && success) {
|
if (!isInterrupted() && success) {
|
||||||
mMapRenderer.passTile(mapGeneratorJob);
|
mMapRenderer.passTile(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,9 +18,6 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
|
||||||
* A JobTheme defines the render theme which is used for a {@link MapGeneratorJob}.
|
|
||||||
*/
|
|
||||||
public interface Theme extends Serializable {
|
public interface Theme extends Serializable {
|
||||||
/**
|
/**
|
||||||
* @return an InputStream to read the render theme data from.
|
* @return an InputStream to read the render theme data from.
|
||||||
|
|||||||
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.mapgenerator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jeff
|
|
||||||
*/
|
|
||||||
public class TileCacheKey {
|
|
||||||
long x, y;
|
|
||||||
byte z;
|
|
||||||
int hash;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public TileCacheKey() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param key
|
|
||||||
* create new TileCacheKey for key
|
|
||||||
*/
|
|
||||||
public TileCacheKey(TileCacheKey key) {
|
|
||||||
this.x = key.x;
|
|
||||||
this.y = key.y;
|
|
||||||
this.z = key.z;
|
|
||||||
this.hash = key.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param x
|
|
||||||
* Position
|
|
||||||
* @param y
|
|
||||||
* Position
|
|
||||||
* @param z
|
|
||||||
* Position
|
|
||||||
*/
|
|
||||||
public TileCacheKey(long x, long y, byte z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
hash = 7 * z + 31 * ((int) (x ^ (x >>> 32)) + 31 * (int) (y ^ (y >>> 32)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param x
|
|
||||||
* Position
|
|
||||||
* @param y
|
|
||||||
* Position
|
|
||||||
* @param z
|
|
||||||
* Position
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public TileCacheKey set(long x, long y, byte z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
hash = 7 * z + 31 * ((int) (x ^ (x >>> 32)) + 31 * (int) (y ^ (y >>> 32)));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
TileCacheKey other = (TileCacheKey) obj;
|
|
||||||
return (x == other.x && y == other.y && z == other.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.mapgenerator;
|
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.core.MapPosition;
|
|
||||||
|
|
||||||
final class TileScheduler {
|
|
||||||
|
|
||||||
static long time;
|
|
||||||
static MapPosition mapPosition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the priority for the given tile based on the current position and zoom level of the supplied MapView.
|
|
||||||
* The smaller the distance from the tile center to the MapView center, the higher its priority. If the zoom level
|
|
||||||
* of a tile differs from the zoom level of the MapView, its priority decreases.
|
|
||||||
*
|
|
||||||
* @param mapGeneratorJob
|
|
||||||
* the tile whose priority should be calculated.
|
|
||||||
* @param mapView
|
|
||||||
* the MapView whose current position and zoom level define the priority of the tile.
|
|
||||||
* @return the current priority of the tile. A smaller number means a higher priority.
|
|
||||||
*/
|
|
||||||
static double getPriority(MapGeneratorJob mapGeneratorJob, MapView mapView) {
|
|
||||||
MapTile tile = mapGeneratorJob.tile;
|
|
||||||
|
|
||||||
// if (tile.isDrawn) {
|
|
||||||
// long diff = time - tile.loadTime;
|
|
||||||
//
|
|
||||||
// // check.. just in case
|
|
||||||
// if (diff > 0.0) {
|
|
||||||
// return (10000.0f / diff) * (tile.isVisible ? 1 : 5); // * tile.distance;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // calculate the center coordinates of the tile
|
|
||||||
// double tileCenterLongitude = MercatorProjection.pixelXToLongitude(tile.getCenterX(), tileZoomLevel);
|
|
||||||
// double tileCenterLatitude = MercatorProjection.pixelYToLatitude(tile.getCenterY(), tileZoomLevel);
|
|
||||||
//
|
|
||||||
// // calculate the Euclidian distance from the MapView center to the tile
|
|
||||||
// // center
|
|
||||||
// GeoPoint geoPoint = mapPosition.geoPoint;
|
|
||||||
// double longitudeDiff = geoPoint.getLongitude() - tileCenterLongitude;
|
|
||||||
// double latitudeDiff = geoPoint.getLatitude() - tileCenterLatitude;
|
|
||||||
//
|
|
||||||
// return Math.sqrt(longitudeDiff * longitudeDiff + latitudeDiff * latitudeDiff)
|
|
||||||
// * (tile.visible ? 1.0 : 1000.0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return tile.distance / 1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TileScheduler() {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -31,6 +31,8 @@ public interface IRenderCallback {
|
|||||||
*
|
*
|
||||||
* @param area
|
* @param area
|
||||||
* ...
|
* ...
|
||||||
|
* @param level
|
||||||
|
* ...
|
||||||
*/
|
*/
|
||||||
void renderArea(Area area, int level);
|
void renderArea(Area area, int level);
|
||||||
|
|
||||||
@ -83,6 +85,8 @@ public interface IRenderCallback {
|
|||||||
*
|
*
|
||||||
* @param line
|
* @param line
|
||||||
* ...
|
* ...
|
||||||
|
* @param level
|
||||||
|
* ...
|
||||||
*/
|
*/
|
||||||
void renderWay(Line line, int level);
|
void renderWay(Line line, int level);
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,9 @@ public enum InternalRenderTheme implements Theme {
|
|||||||
*
|
*
|
||||||
* @see <a href="http://wiki.openstreetmap.org/wiki/Osmarender">Osmarender</a>
|
* @see <a href="http://wiki.openstreetmap.org/wiki/Osmarender">Osmarender</a>
|
||||||
*/
|
*/
|
||||||
OSMARENDER("/org/mapsforge/android/rendertheme/osmarender/osmarender.xml");
|
OSMARENDER("/org/mapsforge/android/rendertheme/osmarender/osmarender.xml"),
|
||||||
|
|
||||||
|
TRONRENDER("/org/mapsforge/android/rendertheme/osmarender/tronrender.xml");
|
||||||
|
|
||||||
private final String mPath;
|
private final String mPath;
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,8 @@ class PositiveRule extends Rule {
|
|||||||
@Override
|
@Override
|
||||||
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
||||||
return (mElement != Element.WAY)
|
return (mElement != Element.WAY)
|
||||||
&& mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
&& mZoomMin <= zoomLevel
|
||||||
|
&& mZoomMax >= zoomLevel
|
||||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||||
}
|
}
|
||||||
@ -46,7 +47,8 @@ class PositiveRule extends Rule {
|
|||||||
@Override
|
@Override
|
||||||
boolean matchesWay(Tag[] tags, byte zoomLevel, int closed) {
|
boolean matchesWay(Tag[] tags, byte zoomLevel, int closed) {
|
||||||
return (mElement != Element.NODE)
|
return (mElement != Element.NODE)
|
||||||
&& mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
&& mZoomMin <= zoomLevel
|
||||||
|
&& mZoomMax >= zoomLevel
|
||||||
&& (mClosed == closed || mClosed == Closed.ANY)
|
&& (mClosed == closed || mClosed == Closed.ANY)
|
||||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||||
|
|||||||
@ -138,8 +138,7 @@ public class RenderTheme {
|
|||||||
* @return ...
|
* @return ...
|
||||||
*/
|
*/
|
||||||
public synchronized RenderInstruction[] matchNode(IRenderCallback renderCallback,
|
public synchronized RenderInstruction[] matchNode(IRenderCallback renderCallback,
|
||||||
Tag[] tags,
|
Tag[] tags, byte zoomLevel) {
|
||||||
byte zoomLevel) {
|
|
||||||
|
|
||||||
RenderInstruction[] renderInstructions = null;
|
RenderInstruction[] renderInstructions = null;
|
||||||
|
|
||||||
@ -189,9 +188,8 @@ public class RenderTheme {
|
|||||||
* @return currently processed render instructions
|
* @return currently processed render instructions
|
||||||
*/
|
*/
|
||||||
public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
|
public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
|
||||||
Tag[] tags,
|
Tag[] tags, byte zoomLevel, boolean closed, boolean render) {
|
||||||
byte zoomLevel,
|
|
||||||
boolean closed, boolean render) {
|
|
||||||
RenderInstruction[] renderInstructions = null;
|
RenderInstruction[] renderInstructions = null;
|
||||||
|
|
||||||
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
||||||
@ -205,6 +203,7 @@ public class RenderTheme {
|
|||||||
|
|
||||||
matchingCacheKey = new MatchingCacheKey(tags, zoomLevel);
|
matchingCacheKey = new MatchingCacheKey(tags, zoomLevel);
|
||||||
boolean found = matchingCache.containsKey(matchingCacheKey);
|
boolean found = matchingCache.containsKey(matchingCacheKey);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
renderInstructions = matchingCache.get(matchingCacheKey);
|
renderInstructions = matchingCache.get(matchingCacheKey);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -25,9 +25,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||||
|
import org.mapsforge.android.rendertheme.renderinstruction.AreaLevel;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Circle;
|
import org.mapsforge.android.rendertheme.renderinstruction.Circle;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.AreaLevel;
|
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.LineSymbol;
|
import org.mapsforge.android.rendertheme.renderinstruction.LineSymbol;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.PathText;
|
import org.mapsforge.android.rendertheme.renderinstruction.PathText;
|
||||||
@ -40,6 +40,8 @@ import org.xml.sax.SAXParseException;
|
|||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SAX2 handler to parse XML render theme files.
|
* SAX2 handler to parse XML render theme files.
|
||||||
*/
|
*/
|
||||||
@ -195,7 +197,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
// System.out.println("add style: " + line.style + " from " + style);
|
// System.out.println("add style: " + line.style + " from " + style);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// System.out.println("couldnt check the style yo! " + style);
|
Log.d("...", "this aint no style! " + style);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Line line = Line.create(null, localName, attributes, 0, false);
|
Line line = Line.create(null, localName, attributes, 0, false);
|
||||||
@ -266,6 +268,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
mCurrentRule.addRenderingInstruction(newLine);
|
mCurrentRule.addRenderingInstruction(newLine);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Log.d("...", "styles not a line! " + style);
|
||||||
}
|
}
|
||||||
} else if (ELEMENT_NAME_USE_STYLE_OUTLINE.equals(localName)) {
|
} else if (ELEMENT_NAME_USE_STYLE_OUTLINE.equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@ -274,6 +278,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
Line line = (Line) tmpStyleHash.get("o" + style);
|
Line line = (Line) tmpStyleHash.get("o" + style);
|
||||||
if (line != null && line.outline)
|
if (line != null && line.outline)
|
||||||
mCurrentRule.addRenderingInstruction(line);
|
mCurrentRule.addRenderingInstruction(line);
|
||||||
|
else
|
||||||
|
Log.d("...", "styles not bad, but this aint no outline! " + style);
|
||||||
}
|
}
|
||||||
} else if (ELEMENT_NAME_USE_STYLE_AREA.equals(localName)) {
|
} else if (ELEMENT_NAME_USE_STYLE_AREA.equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@ -283,6 +289,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
if (area != null)
|
if (area != null)
|
||||||
mCurrentRule.addRenderingInstruction(new AreaLevel(area,
|
mCurrentRule.addRenderingInstruction(new AreaLevel(area,
|
||||||
mLevel++));
|
mLevel++));
|
||||||
|
else
|
||||||
|
Log.d("...", "this aint no style inna di area! " + style);
|
||||||
}
|
}
|
||||||
} else if (ELEMENT_NAME_USE_STYLE_PATH_TEXT.equals(localName)) {
|
} else if (ELEMENT_NAME_USE_STYLE_PATH_TEXT.equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@ -291,6 +299,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
PathText pt = (PathText) tmpStyleHash.get("t" + style);
|
PathText pt = (PathText) tmpStyleHash.get("t" + style);
|
||||||
if (pt != null)
|
if (pt != null)
|
||||||
mCurrentRule.addRenderingInstruction(pt);
|
mCurrentRule.addRenderingInstruction(pt);
|
||||||
|
else
|
||||||
|
Log.d("...", "this aint no path text style! " + style);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new SAXException("unknown element: " + localName);
|
throw new SAXException("unknown element: " + localName);
|
||||||
|
|||||||
@ -485,7 +485,7 @@
|
|||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<!-- outline 1 - 4 -->
|
<!-- outline 1 - 4 -->
|
||||||
<style-outline name="1" stroke="#404040" width="0.025"/>
|
<style-outline name="1" stroke="#ee605020" width="0.02"/>
|
||||||
<!-- <style-outline name="1" stroke="#404030"/> -->
|
<!-- <style-outline name="1" stroke="#404030"/> -->
|
||||||
<style-outline name="2" stroke="#c0c0c0" />
|
<style-outline name="2" stroke="#c0c0c0" />
|
||||||
<style-outline name="primary" stroke="#7f7700" width="0.025"/>
|
<style-outline name="primary" stroke="#7f7700" width="0.025"/>
|
||||||
|
|||||||
992
src/org/mapsforge/android/rendertheme/osmarender/tronrender.xml
Normal file
992
src/org/mapsforge/android/rendertheme/osmarender/tronrender.xml
Normal file
@ -0,0 +1,992 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rendertheme xmlns="http://mapsforge.org/renderTheme"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://mapsforge.org/renderTheme ../renderTheme.xsd"
|
||||||
|
version="1" map-background="#050508">
|
||||||
|
|
||||||
|
<style-pathtext name="road" k="name" font-style="bold" font-size="18" stroke="#606050" fill="#eeffee" stroke-width="2.5" />
|
||||||
|
<style-pathtext name="major-road" k="name" font-style="bold" font-size="19" fill="#e2cf5d" stroke="#101010" stroke-width="2.5" />
|
||||||
|
|
||||||
|
<style-area name="residential" fill="#ff0000" fade="10"/>
|
||||||
|
|
||||||
|
<style-area name="railway|industrial" fill="#f2eeef" fade="10"/>
|
||||||
|
<!-- "#f0fae7" mint green -->
|
||||||
|
<style-area name="farmland" fill="#fff8bf" fade="11" />
|
||||||
|
|
||||||
|
<!-- fade out at z=7, blend over to 'blend-fill' in z=11 -->
|
||||||
|
<style-area name="forest|wood" fill="#151806" fade="7" blend="11" blend-fill="#1e2205"/>
|
||||||
|
|
||||||
|
<!-- grass|meadow|garden|grassland|scrub -->
|
||||||
|
<style-area name="greens" fill="#33390c" fade="10" />
|
||||||
|
|
||||||
|
<!-- marsh|wetland|nature_reserve -->
|
||||||
|
<style-area name="greens2" fill="#627100" fade="12" />
|
||||||
|
|
||||||
|
<!-- park|common|green|cemetery|golf_course|dog_park -->
|
||||||
|
<style-area name="park" fill="#627100" fade="11" />
|
||||||
|
|
||||||
|
<!-- de:Kleingartengebiet -->
|
||||||
|
<style-area name="allotments" fill="#efeae0" fade="12" />
|
||||||
|
|
||||||
|
<!-- de:Steinbruch, Schotter-, Kies-, Sand- und Tongrube -->
|
||||||
|
<style-area name="quarry" fill="#ddddcc" fade="10" />
|
||||||
|
|
||||||
|
<style-area name="military" fill="#eeedea" fade="10"/>
|
||||||
|
|
||||||
|
|
||||||
|
<style-line name="residential" stroke="#ffffff" width="1.0" blur="1.0" fade="13"/>
|
||||||
|
<style-line name="residential:bridge" from="residential" cap="square"/>
|
||||||
|
|
||||||
|
<!-- when inheriting another style with 'from' then 'witdth' is meant relative to the parent -->
|
||||||
|
<style-line name="pedestrian" from="residential" width="-0.4"/>
|
||||||
|
<style-line name="pedestrian:bridge" from="pedestrian" cap="square"/>
|
||||||
|
|
||||||
|
<style-line name="highway:z11" stroke="#fcba5a" width="1.8" blur="0.9"/>
|
||||||
|
<!-- <style-line name="highway:z11:bridge" from="highway:z11" cap="butt" /> -->
|
||||||
|
|
||||||
|
<style-line name="trunk_link" stroke="#fee16e" width="1.3" cap="butt" blur="0.9"/>
|
||||||
|
<style-line name="trunk" stroke="#fedb52" width="1.6" blur="0.9"/>
|
||||||
|
<style-line name="primary:z11" stroke="#f2df6d" width="1.5" blur="0.9"/>
|
||||||
|
<style-line name="secondary:z11" from="primary:z11" width="-0.1"/>
|
||||||
|
|
||||||
|
<style-line name="tertiary" from="residential" width="0.2" fade="11"/>
|
||||||
|
<style-line name="construction" stroke="#e0e0e0" width="1.2" />
|
||||||
|
|
||||||
|
<style-line name="highway-service" from="residential" width="-0.6" />
|
||||||
|
|
||||||
|
<!-- track|footway|path|cycleway -->
|
||||||
|
<style-line name="footway" stroke="#c1bcb6" width="1.2" cap="butt" fixed="true"/>
|
||||||
|
<style-line name="footway:z16" from="footway" width="-1.0" fixed="false" fade="-1"/>
|
||||||
|
<style-line name="footway:z17" stroke="#faf8f5" width="0.3"/>
|
||||||
|
|
||||||
|
<!-- de: ein Weg der für Reiter vorgeshen ist.. -->
|
||||||
|
<style-line name="bridleway" stroke="#d3cb98" width="0.4" cap="butt"/>
|
||||||
|
|
||||||
|
<style-line name="steps" stroke="#f1f0f4" width="0.25" cap="butt" />
|
||||||
|
|
||||||
|
<style-line name="water:outline" stroke="#a4bbcc" width="1.0" cap="butt" />
|
||||||
|
<style-line name="water" stroke="#cca4bbcc" width="0.6" cap="butt" />
|
||||||
|
<style-area name="water" fill="#001223" />
|
||||||
|
<!-- no-go area boundary -->
|
||||||
|
<style-line name="fence" stroke="#444444" width="1.2" fixed="true" cap="butt"/>
|
||||||
|
|
||||||
|
<style-line name="aeroway:runway" stroke="#008888" width="1.8" cap="butt" blur="0.7" />
|
||||||
|
|
||||||
|
<style-line name="building" stroke="#dd999999" width="1.8" fixed="true" cap="butt"/>
|
||||||
|
<style-area name="building" fill="#ee202020" fade="15"/>
|
||||||
|
|
||||||
|
<!-- ways -->
|
||||||
|
<rule e="way" k="*" v="*" >
|
||||||
|
|
||||||
|
<rule e="way" k="natural" v="grassland|scrub" zoom-min="10">
|
||||||
|
<use-area name="greens"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- landuse base -->
|
||||||
|
<rule e="way" k="landuse" v="*">
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" zoom-min="10" v="farmland|farm|orchard|vineyard|greenhouse_horticulture|plant_nursery">
|
||||||
|
<use-area name="farmland"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="quarry">
|
||||||
|
<use-area name="quarry"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="residential|farmyard|retail|commercial|industrial;retail">
|
||||||
|
<use-area name="residential" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="industrial|railway">
|
||||||
|
<use-area name ="railway|industrial"/>
|
||||||
|
</rule>
|
||||||
|
-->
|
||||||
|
<!-- <rule e="way" k="*" v="military">
|
||||||
|
<use-area name="military"/>
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
<!--<rule e="way" k="landuse" v="construction|greenfield"> <area fill="#a47c41"
|
||||||
|
stroke="#e4e4e4" width="0.2" /> </rule> -->
|
||||||
|
<!-- <rule e="way" k="landuse" v="garages"> <area fill="#d6d6e4" /> </rule> -->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="landuse|natural|leisure||amenity" v="*">
|
||||||
|
<!-- kind of more like landuse imho -->
|
||||||
|
<rule e="way" k="leisure|landuse" v="nature_reserve">
|
||||||
|
<use-area name="greens2" />
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
|
<line stroke="#abe29c" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- landuse -->
|
||||||
|
<rule e="way" k="landuse" v="*" zoom-min="11">
|
||||||
|
<!-- how about 'leisure' for this one? -->
|
||||||
|
<rule e="way" k="*" v="cemetery">
|
||||||
|
<use-area name="park"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="reservoir|basin">
|
||||||
|
<use-area name="water" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="landuse" v="village_green|recreation_ground" >
|
||||||
|
<use-area name="greens" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="landuse" v="allotments" zoom-min="12">
|
||||||
|
<use-area name="allotments"/>
|
||||||
|
</rule>-->
|
||||||
|
|
||||||
|
<rule e="way" k="leisure" v="park|common|green|golf_course|dog_park" zoom-min="11">
|
||||||
|
<use-area name="park"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Heideland, keep below forest -->
|
||||||
|
<rule e="way" k="*" zoom-min="11" v="heath|sand">
|
||||||
|
<area fill="#0f0f0c" fade="11" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="landuse" v="forest">
|
||||||
|
<use-area name="forest|wood"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="natural" v="wood">
|
||||||
|
<use-area name="forest|wood"/>
|
||||||
|
<!-- <line stroke="#abcfab" width="1.5" fixed="true" cap="butt"/> -->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- keep grass above forest:wood and leisure:park! -->
|
||||||
|
<rule e="way" k="landuse" v="grass|meadow">
|
||||||
|
<use-area name="greens"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="leisure" v="garden">
|
||||||
|
<use-area name="greens"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="leisure" v="track">
|
||||||
|
<line stroke="#c1bcb6" width="1.3" cap="butt" fixed="true" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- amenity -->
|
||||||
|
<rule e="way" k="amenity" v="*">
|
||||||
|
<rule e="way" k="*" v="kindergarten|school|college|university" zoom-min="14">
|
||||||
|
<area fill="#cdabde" stroke="#b094bf" stroke-width="0.2" /> </rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="parking" zoom-min="14">
|
||||||
|
<area fill="#f4f4f4" stroke="#d4d4d4" stroke-width="0.2" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="fountain" closed="yes">
|
||||||
|
<area fill="#b4cbdc" stroke="#000080" stroke-width="0.15" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="natural" v="coastline">
|
||||||
|
<line stroke="#a4bbcc" width="1.2" fixed="true" />
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
<!-- natural -->
|
||||||
|
<rule e="way" k="natural" v="*" zoom-min="10">
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="glacier">
|
||||||
|
<area fill="#fafaff" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="land">
|
||||||
|
<area fill="#080808" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" v="beach">
|
||||||
|
<area fill="#aaedd400"/>
|
||||||
|
<line stroke="#fce94f" fixed="true" width="2.8" />
|
||||||
|
</rule>-->
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="marsh|wetland|mud">
|
||||||
|
<use-area name="greens2" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- leisure -->
|
||||||
|
<rule e="way" k="leisure" v="*" zoom-min="13">
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="stadium" >
|
||||||
|
<area fill="#404040" />
|
||||||
|
<line stroke="#cccccc" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!--should be under playing field -->
|
||||||
|
<!-- <rule e="way" k="*" zoom-min="14" v="sports_centre|water_park">
|
||||||
|
<area fill="#daefdb" fade="12" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" zoom-min="15" v="playground|miniature_golf">
|
||||||
|
<area fill="#f4f4de" />
|
||||||
|
<line stroke="#fbdbc8" width="0.6" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="playing_fields|pitch">
|
||||||
|
<area fill="#f4f4de" />
|
||||||
|
<line stroke="#dbdbc8" width="0.6" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
-->
|
||||||
|
<rule e="way" k="*" v="swimming_pool">
|
||||||
|
<area fill="#b4cbdc" stroke="#6060ff" width="0.2" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" v="track"> <rule e="way" k="area" v="yes|true">
|
||||||
|
<area fill="#c9d8a2" stroke="#b7c690" width="0.025" /> </rule> <rule
|
||||||
|
e="way" k="area" v="~|no|false"> <line stroke="#b7c690" width="0.75"
|
||||||
|
/> </rule> </rule> -->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- area outlines need to be above to avoid uggly pixelation where
|
||||||
|
not aliased polygon overlaps the lines... -->
|
||||||
|
|
||||||
|
<rule e="way" k="leisure|landuse" v="*" zoom-min="14">
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="nature_reserve">
|
||||||
|
<line stroke="#abe29c" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="military">
|
||||||
|
<use-line name="fence" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- waterways -->
|
||||||
|
<rule e="way" k="waterway" v="*">
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="ditch|drain" zoom-min="14">
|
||||||
|
<use-line name="water" width="0.1" fixed="true"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="canal">
|
||||||
|
<use-line name="water" width="-0.2"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="stream" zoom-min="14">
|
||||||
|
<use-line name="water" width="-0.1"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<style-outline name="river" width="1.0" stroke="#456799" blur="1.0"/>
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="river" closed="no">
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="12">
|
||||||
|
<use-line name="water" width="0.5"/>
|
||||||
|
<use-outline name="river"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="*" zoom-max="12">
|
||||||
|
<use-line name="water" width="1.0" fixed="true" fade="9"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="riverbank|dock">
|
||||||
|
<use-area name="water"/>
|
||||||
|
<use-line name="water" width="1.0" fixed="true"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="river" closed="yes">
|
||||||
|
<use-area name="water"/>
|
||||||
|
<use-line name="water" width="1.0" fixed="true"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="weir">
|
||||||
|
<line stroke="#000044" width="0.375" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="waterway" v="dam" zoom-min="12">
|
||||||
|
<!-- sehr seltsam was in deutschland so als Damm gekenzeichnet wird.. -->
|
||||||
|
<line stroke="#ababab" width="1.2" cap="butt" fixed="true" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="lock" v="yes|true">
|
||||||
|
<line stroke="#f8f8f8" width="1.5" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="natural" v="water">
|
||||||
|
<use-area name="water"/>
|
||||||
|
<use-line name="water:outline" width="0.5" fixed="true"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- sport -->
|
||||||
|
<!-- <rule e="way" k="sport" v="*"> <rule e="way" k="sport" v="soccer"
|
||||||
|
zoom-min="17"> <rule e="way" k="sport" v="swimming|canoe|diving|scuba_diving">
|
||||||
|
<area fill="#b4cbdc" stroke="#6060ff" width="0.2" /> </rule> <rule
|
||||||
|
e="way" k="sport" v="tennis"> <area fill="#d18a6a" stroke="#b36c4c" width="0.2"
|
||||||
|
/> </rule> </rule> -->
|
||||||
|
|
||||||
|
<!-- tourism areas -->
|
||||||
|
<rule e="way" k="tourism" v="*">
|
||||||
|
<!-- <rule e="way" k="tourism" v="attraction"> <area fill="#f2caea" /> </rule> -->
|
||||||
|
|
||||||
|
<rule e="way" k="tourism" v="zoo|picnic_site|caravan_site|camp_site">
|
||||||
|
<area fill="#d7e6b0" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- outline 0 -->
|
||||||
|
|
||||||
|
<style-outline name="0" stroke="#44000000" width="0.1" />
|
||||||
|
<!-- tunnel -->
|
||||||
|
<rule e="way" k="tunnel" v="yes|true" zoom-min="11">
|
||||||
|
<!-- highway tunnels -->
|
||||||
|
<rule e="way" k="highway" v="*">
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="15">
|
||||||
|
<rule e="way" k="*" v="steps">
|
||||||
|
<use-line name="steps"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="16">
|
||||||
|
<use-line name="footway:z16"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-max="15">
|
||||||
|
<use-line name="footway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="bridleway">
|
||||||
|
<use-line name="bridleway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="construction">
|
||||||
|
<use-line name="construction"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="service">
|
||||||
|
<rule e="way" k="service" v="-|parking_aisle">
|
||||||
|
<use-line name="highway-service"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk_link|motorway_link">
|
||||||
|
<use-line name="trunk_link"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="13">
|
||||||
|
<rule e="way" k="*" v="byway|pedestrian">
|
||||||
|
<use-line name="pedestrian"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="residential|road|unclassified|living_street">
|
||||||
|
<use-line name="residential"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="tertiary|secondary_link">
|
||||||
|
<use-line name="tertiary"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="secondary|primary_link">
|
||||||
|
<use-line name="secondary:z11"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="primary">
|
||||||
|
<use-line name="primary:z11"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk">
|
||||||
|
<use-line name="trunk" blur="0.3"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<!-- <use-outline name="glow"/> -->
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="motorway">
|
||||||
|
<use-line name="highway:z11" blur="0.3"/>
|
||||||
|
<use-outline name="0"/>
|
||||||
|
<!-- <use-outline name="glow"/> -->
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- railway tunnel -->
|
||||||
|
<rule e="way" k="railway" v="*">
|
||||||
|
<!-- <rule e="way" k="railway" v="tram|subway|light_rail|narrow_gauge">
|
||||||
|
<line stroke="#a0a0a0" width="0.8" cap="butt" fixed="true"/>
|
||||||
|
</rule> -->
|
||||||
|
<rule e="way" k="railway" v="rail">
|
||||||
|
<line stroke="#aaaaaa" width="0.9" cap="butt" fixed="true" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule> <!-- end tunnel -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- platform cores -->
|
||||||
|
<rule e="way" k="highway|railway|public_transport" v="platform">
|
||||||
|
<rule e="way" k="*" v="*" closed="yes">
|
||||||
|
<area fill="#999999" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="*" closed="no">
|
||||||
|
<line stroke="#cccccc" width="0.3" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- runways areas -->
|
||||||
|
<rule e="way" k="aeroway" v="*">
|
||||||
|
<!-- <rule e="way" k="*" v="aerodrome" closed="yes">
|
||||||
|
<area fill="#050008" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="apron">
|
||||||
|
<area fill="#050008" />
|
||||||
|
</rule>-->
|
||||||
|
<!-- Airport passenger building -->
|
||||||
|
<rule e="way" k="*" v="terminal|hangar">
|
||||||
|
<use-area name="building" />
|
||||||
|
<use-line name="building" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- turning circles -->
|
||||||
|
<!-- <rule e="node" k="highway" v="turning_circle"> <circle r="1.5" scale-radius="true"
|
||||||
|
fill="#707070" />
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
<!-- building -->
|
||||||
|
<rule e="way" k="building" v="*">
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="15">
|
||||||
|
<use-area name="building" fade="15"/>
|
||||||
|
<use-line name="building" fade="15"/>
|
||||||
|
<!-- <line stroke="#c9c3c1" width="1.0" fixed="true" cap="butt" fade="15"/>
|
||||||
|
<area fill="#e9e6e3" fade="15" /> -->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" v="*" zoom-min="17">
|
||||||
|
<caption k="name" font-style="bold" font-size="10" fill="#4040ff"
|
||||||
|
stroke="#ffffff" stroke-width="2.0" />
|
||||||
|
<caption k="addr:housenumber" font-style="bold" font-size="10" fill="#606060"
|
||||||
|
stroke="#ffffff" stroke-width="2.0" />
|
||||||
|
</rule> -->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- outline 1 - 4 -->
|
||||||
|
<style-outline name="glow3" stroke="#ddffffff" width="0.8" blur="0.5" fade="13"/>
|
||||||
|
<!-- > <style-outline name="glow" stroke="#ee909090" width="0.8" blur="0.5" fade="14"/>-->
|
||||||
|
<style-outline name="glow2" width="1.0" stroke="#ffffff" blur="1.0" fade="13"/>
|
||||||
|
<style-outline name="1" stroke="#dd000000" width="-0.3" fade="14"/>
|
||||||
|
<!-- <style-outline name="1" stroke="#404030"/> -->
|
||||||
|
<style-outline name="2" stroke="#c0c0c0" />
|
||||||
|
<style-outline name="primary" stroke="#7f7700" width="0.025"/>
|
||||||
|
<style-outline name="motorway" stroke="#805f2e" width="0.025"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- highway -->
|
||||||
|
<rule e="way" k="highway" v="*">
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="5" zoom-max="10">
|
||||||
|
<rule e="way" k="area" v="~|no|false">
|
||||||
|
<rule e="way" k="*" v="secondary|primary_link" zoom-min="9">
|
||||||
|
<line stroke="#ddf2df6d" width="1.8" cap="butt" fixed="true" fade="9"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk_link|motorway_link" zoom-min="8">
|
||||||
|
<line stroke="#ddfed6a3" width="1.8" cap="butt" fixed="true" fade="8"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="primary" zoom-min="5">
|
||||||
|
<line stroke="#ddf2df6d" cap="butt" fixed="true" width="1.8" fade="5"/> <!-- stroke="#f2df6d" width="1.8" cap="butt" fixed="true" fade="5"/>-->
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk" zoom-min="5">
|
||||||
|
<line stroke="#ddfed6a3" width="2.0" cap="butt" fixed="true" fade="5"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="motorway">
|
||||||
|
<line stroke="#ddeec693" width="2.2" cap="butt" fixed="true" fade="5"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="11">
|
||||||
|
<rule e="way" k="tunnel|bridge" v="~|no|false">
|
||||||
|
<!-- highway area -->
|
||||||
|
<rule e="way" k="area" v="yes|true">
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="footway" zoom-min="15">
|
||||||
|
<area fill="#44ffffff" />
|
||||||
|
<line stroke="#888888" width="0.15" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" zoom-min="13" v="pedestrian|unclassified|residential|road|living_street">
|
||||||
|
<area fill="#44ffffff" />
|
||||||
|
<line stroke="#888888" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" v="path" zoom-min="14">
|
||||||
|
<area fill="#d0d0d0" />
|
||||||
|
</rule>-->
|
||||||
|
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="area" v="~|no|false">
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="15">
|
||||||
|
<rule e="way" k="*" v="steps">
|
||||||
|
<use-line name="steps"/>
|
||||||
|
<use-outline name="2"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="16" zoom-max="16">
|
||||||
|
<use-line name="footway:z16"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="17">
|
||||||
|
<use-line name="footway:z17"/>
|
||||||
|
<!-- <use-outline name="1"/> -->
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-max="15">
|
||||||
|
<use-line name="footway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="bridleway">
|
||||||
|
<use-line name="bridleway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="construction">
|
||||||
|
<use-line name="construction"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="service">
|
||||||
|
<rule e="way" k="service" v="-|parking_aisle">
|
||||||
|
<use-line name="highway-service"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
</rule>
|
||||||
|
<!-- <rule e="way" k="service" v="parking_aisle" zoom-min="16">
|
||||||
|
<use-line name="highway-service" width="-0.4"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
</rule> -->
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk_link|motorway_link">
|
||||||
|
<use-line name="trunk_link"/>
|
||||||
|
<use-outline name="motorway"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="13">
|
||||||
|
<rule e="way" k="*" v="byway|pedestrian">
|
||||||
|
<use-line name="residential" width="-0.4"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="residential|road|unclassified|living_street">
|
||||||
|
<use-line name="residential"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
|
||||||
|
<use-outline name="glow"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="tertiary|secondary_link">
|
||||||
|
<use-line name="tertiary"/>
|
||||||
|
<use-outline name="1"/>
|
||||||
|
|
||||||
|
<use-outline name="glow"/>
|
||||||
|
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="secondary|primary_link">
|
||||||
|
<!-- <line stroke="#fff939" width="1.6" /> -->
|
||||||
|
<use-line name="secondary:z11"/>
|
||||||
|
<use-outline name="primary"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="primary">
|
||||||
|
<use-line name="primary:z11"/>
|
||||||
|
<use-outline name="primary"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk">
|
||||||
|
<use-line name="trunk"/>
|
||||||
|
<use-outline name="motorway"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="motorway">
|
||||||
|
<use-line name="highway:z11"/>
|
||||||
|
<use-outline name="motorway"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
</rule> <!-- end area=~|no|false -->
|
||||||
|
</rule> <!-- end tunnel|bridge=~|no|false -->
|
||||||
|
|
||||||
|
|
||||||
|
<rule e="way" k="bridge" v="yes|true|viaduct|suspension">
|
||||||
|
<rule e="way" k="area" v="~|no|false">
|
||||||
|
|
||||||
|
<style-outline name="bridge" stroke="#aa202020" width="0.08"/>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="15">
|
||||||
|
<rule e="way" k="*" v="steps">
|
||||||
|
<use-line name="steps"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="16" zoom-max="16">
|
||||||
|
<use-line name="footway:z16"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="17">
|
||||||
|
<use-line name="footway:z17" cap="butt"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
|
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-max="15">
|
||||||
|
<use-line name="footway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="bridleway">
|
||||||
|
<use-line name="bridleway"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="construction">
|
||||||
|
<use-line name="construction" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="service">
|
||||||
|
<use-line name="highway-service" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="13">
|
||||||
|
<rule e="way" k="*" v="byway|pedestrian">
|
||||||
|
<use-line name="pedestrian:bridge"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="residential|road|unclassified|living_street">
|
||||||
|
<use-line name="residential:bridge"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="tertiary|secondary_link">
|
||||||
|
<use-line name="tertiary" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk_link|motorway_link">
|
||||||
|
<use-line name="trunk_link" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="secondary|primary_link">
|
||||||
|
<!-- <line stroke="#fff939" width="1.6" cap="butt" /> -->
|
||||||
|
<use-line name="secondary:z11" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="primary">
|
||||||
|
<use-line name="primary:z11" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="trunk">
|
||||||
|
<use-line name="trunk" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="motorway">
|
||||||
|
<use-line name="highway:z11" cap="square"/>
|
||||||
|
<use-outline name="bridge"/>
|
||||||
|
<use-text name="major-road"/>
|
||||||
|
</rule>
|
||||||
|
</rule> <!-- end area=~|no|false -->
|
||||||
|
|
||||||
|
<rule e="way" k="area" v="yes|true">
|
||||||
|
<rule e="way" k="*" v="footway" zoom-min="15">
|
||||||
|
<area fill="#fefefe" />
|
||||||
|
<line stroke="#c0c0c0" width="0.15" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" zoom-min="13" v="pedestrian|service|unclassified|residential|road|living_street">
|
||||||
|
<area fill="#ffffff" />
|
||||||
|
<line stroke="#d0d0d0" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- <rule e="way" k="*" v="path" zoom-min="14">
|
||||||
|
<area fill="#d0d0d0" />
|
||||||
|
</rule>-->
|
||||||
|
</rule> <!-- end area=yes|true -->
|
||||||
|
</rule> <!-- end bridge=yes -->
|
||||||
|
</rule> <!-- end zoom-min=11 -->
|
||||||
|
</rule> <!-- end highway -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- runways cores -->
|
||||||
|
<rule e="way" k="aeroway" v="*">
|
||||||
|
<rule e="way" k="*" v="runway">
|
||||||
|
<use-line name="aeroway:runway"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="taxiway">
|
||||||
|
<use-line name="aeroway:runway" width="-0.8"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- man_made features -->
|
||||||
|
<!-- <rule e="way" k="man_made" v="pier">
|
||||||
|
<rule e="way" k="*" v="*" closed="no">
|
||||||
|
<line stroke="#d0d0d0" width="0.4" cap="butt" />
|
||||||
|
<line stroke="#e4e4e4" width="0.3" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="*" v="*" closed="yes">
|
||||||
|
<area fill="#e4e4e4" stroke="#d0d0d0" stroke-width="0.05" />
|
||||||
|
</rule>
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- barriers -->
|
||||||
|
<rule e="way" k="barrier" v="*">
|
||||||
|
<!-- <rule e="way" k="*" v="fence|wall|city_wall" zoom-min="15"> <line
|
||||||
|
stroke="#909090" width="0.1" cap="butt" /> </rule> -->
|
||||||
|
<rule e="way" k="*" v="retaining_wall" zoom-min="15">
|
||||||
|
<line stroke="#888888" width="0.1" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- non-physical routes -->
|
||||||
|
<!-- <rule e="way" k="route" v="ferry"> <line stroke="#707070" width="0.3"
|
||||||
|
stroke-dasharray="15,10" cap="butt" /> </rule> -->
|
||||||
|
|
||||||
|
<!-- aerial ways -->
|
||||||
|
<!-- <rule e="way" k="aerialway" v="*"> <line stroke="#202020" width="0.4"
|
||||||
|
cap="butt" /> <rule e="way" k="aerialway" v="cable_car"> <lineSymbol
|
||||||
|
src="jar:/org/mapsforge/android/maps/rendertheme/osmarender/symbols/cable_car.png"
|
||||||
|
/> </rule> <rule e="way" k="aerialway" v="chair_lift"> <lineSymbol src="jar:/org/mapsforge/android/maps/rendertheme/osmarender/symbols/chair_lift_2.png"
|
||||||
|
/> </rule> <rule e="way" k="aerialway" v="gondola"> <lineSymbol src="jar:/org/mapsforge/android/maps/rendertheme/osmarender/symbols/gondola.png"
|
||||||
|
/> </rule> <rule e="way" k="*" v="*" zoom-min="14"> <pathText k="name" font-style="bold"
|
||||||
|
font-size="10" fill="#606060" stroke="#ffffff" width="2.0" /> </rule>
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- railway (no tunnel) -->
|
||||||
|
<rule e="way" k="railway" v="*" zoom-min="12">
|
||||||
|
<rule e="way" k="tunnel" v="~|false|no">
|
||||||
|
|
||||||
|
<rule e="way" k="railway" v="station">
|
||||||
|
<area fill="#aa000000" />
|
||||||
|
<line stroke="#cccccc" width="1.0" fixed="true"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- railway bridge casings -->
|
||||||
|
<rule e="way" k="*" v="*" zoom-min="14">
|
||||||
|
<rule e="way" k="bridge" v="yes|true">
|
||||||
|
<rule e="way" k="railway" v="tram">
|
||||||
|
<line stroke="#777777" width="0.9" cap="butt"
|
||||||
|
fixed="true" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="railway" v="subway|light_rail|narrow_gauge">
|
||||||
|
<line stroke="#777777" width="0.9" cap="butt"
|
||||||
|
fixed="true" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="railway" v="rail">
|
||||||
|
<line stroke="#777777" width="0.9" cap="butt"
|
||||||
|
fixed="true" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- railway casings and cores -->
|
||||||
|
<rule e="way" k="railway" v="tram" zoom-min="15">
|
||||||
|
<line stroke="#887766" width="1.0" fixed="true" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="railway" v="light_rail|subway|narrow_gauge" zoom-min="14">
|
||||||
|
<line stroke="#a0a0a0" width="0.9" cap="butt" fixed="true" />
|
||||||
|
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="railway" v="rail|turntable" >
|
||||||
|
<line stroke="#aaaaaa" width="1.0" cap="butt" fixed="true" fade="12"/>
|
||||||
|
</rule>
|
||||||
|
<!-- <rule e="way" k="railway" v="rail" zoom-max="14" zoom-min="13">
|
||||||
|
<line stroke="#8888aa" width="0.6" cap="butt"
|
||||||
|
fixed="true" />
|
||||||
|
</rule> -->
|
||||||
|
<!-- <rule e="way" k="railway" v="rail" zoom-max="13" zoom-min="11">
|
||||||
|
<line stroke="#bbbbcc" width="0.8" cap="butt" fixed="true" />
|
||||||
|
</rule> -->
|
||||||
|
<!-- whatever railway:spur means ... -->
|
||||||
|
<rule e="way" k="railway" v="disused|spur|abandoned|preserved" >
|
||||||
|
<line stroke="#cccccc" width="0.8" cap="butt" fixed="true" fade="12"/>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- non-physical boundaries -->
|
||||||
|
<!-- <rule e="way" k="boundary" v="*"> <rule e="way" k="boundary" v="national_park">
|
||||||
|
<line stroke="#4ef94b" width="0.25" stroke-dasharray="15, 5, 5, 5"
|
||||||
|
/> -->
|
||||||
|
|
||||||
|
<!--<rule e="way" k="boundary" v="administrative"> -->
|
||||||
|
<rule e="way" k="admin_level" v="*">
|
||||||
|
<!-- <rule e="way" k="admin_level" v="11"> <line stroke="#f9574b" width="0.1"
|
||||||
|
fixed="true" cap="butt" /> </rule> <rule e="way" k="admin_level"
|
||||||
|
v="10"> <line stroke="#f9574b" width="0.1" fixed="true" cap="butt"
|
||||||
|
/> </rule> <rule e="way" k="admin_level" v="9"> <line stroke="#f9574b" width="0.1"
|
||||||
|
fixed="true" cap="butt" /> </rule> <rule e="way" k="admin_level"
|
||||||
|
v="8"> <line stroke="#f9574b" width="0.3" fixed="true" cap="butt"
|
||||||
|
/> </rule> <rule e="way" k="admin_level" v="7"> <line stroke="#f9574b" width="0.1"
|
||||||
|
fixed="true" cap="butt" /> </rule> <rule e="way" k="admin_level"
|
||||||
|
v="6"> <line stroke="#f9574b" width="0.15" fixed="true" cap="butt"
|
||||||
|
/> </rule> <rule e="way" k="admin_level" v="5"> <line stroke="#f9574b" width="0.15"
|
||||||
|
fixed="true" cap="butt" /> </rule> -->
|
||||||
|
<rule e="way" k="admin_level" v="4">
|
||||||
|
<line stroke="#8f80dd" width="0.9" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="admin_level" v="3">
|
||||||
|
<line stroke="#0000ff" width="1.0" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="admin_level" v="2">
|
||||||
|
<line stroke="#dddddd" width="1.0" fixed="true" cap="butt" blur="0.3"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="admin_level" v="1">
|
||||||
|
<line stroke="#ff0000" width="0.95" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
</rule>
|
||||||
|
<!-- </rule> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- historic -->
|
||||||
|
<!-- <rule e="way" k="historic" v="ruins" zoom-min="17">
|
||||||
|
<caption k="name" font-style="bold" font-size="10" fill="#4040ff" stroke="#ffffff" stroke-width="2.0" />
|
||||||
|
</rule> -->
|
||||||
|
|
||||||
|
<!-- place -->
|
||||||
|
<rule e="way" k="place" v="locality" zoom-min="17">
|
||||||
|
<caption k="name" font-style="bold" font-size="10" fill="#000000" stroke="#ffffff" stroke-width="2.0" />
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="debug" v="area">
|
||||||
|
<line stroke="#ff0000" width="1.2" fixed="true" cap="butt" />
|
||||||
|
<area fill="#880000ff"/>
|
||||||
|
<caption k="name" font-size="15" fill="#ff0000" stroke="#444444" stroke-width="2.0"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="debug" v="way">
|
||||||
|
<line stroke="#00ffff" width="1.5" fixed="true" cap="butt" />
|
||||||
|
<caption k="name" font-size="15" fill="#00ffff" stroke="#444444" stroke-width="2.0"/>
|
||||||
|
</rule>
|
||||||
|
<rule e="way" k="debug" v="box">
|
||||||
|
<line stroke="#dedeae" width="1.5" fixed="true" cap="butt" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="node" k="*" v="*">
|
||||||
|
<!-- barrier -->
|
||||||
|
<rule e="node" k="barrier" v="bollard">
|
||||||
|
<circle r="1.5" fill="#909090" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="node" k="debug" v="*" >
|
||||||
|
<caption k="name" font-size="16" fill="#fefece"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- highway -->
|
||||||
|
<!-- <rule e="node" k="highway" v="*"> <rule e="node" k="highway" v="turning_circle">
|
||||||
|
<circle r="1.4" scale-radius="true" fill="#ffffff" /> </rule> </rule> -->
|
||||||
|
|
||||||
|
<!-- historic -->
|
||||||
|
<!-- <rule e="node" k="historic" v="*"> <circle r="3" fill="#4040ff" stroke="#606060"
|
||||||
|
width="1.5" /> <rule e="node" k="*" v="*" zoom-min="17"> <caption
|
||||||
|
k="name" dy="-10" font-style="bold" font-size="10" fill="#4040ff" stroke="#ffffff"
|
||||||
|
width="2.0" /> </rule> </rule> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- house numbers -->
|
||||||
|
<!-- <rule e="node" k="addr:housenumber" v="*" zoom-min="18"> <caption
|
||||||
|
k="addr:housenumber" font-style="bold" font-size="10" fill="#606060" stroke="#ffffff"
|
||||||
|
width="2.0" /> </rule> -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- place -->
|
||||||
|
<rule e="node" k="place" v="*">
|
||||||
|
<rule e="node" k="*" v="suburb|town|village">
|
||||||
|
<caption k="name" font-size="20" fill="#eeeeee"
|
||||||
|
stroke="#000020" stroke-width="4.0" />
|
||||||
|
</rule>
|
||||||
|
<rule e="node" k="*" v="island" zoom-min="10">
|
||||||
|
<caption k="name" font-style="bold" font-size="20" fill="#ffffff"
|
||||||
|
stroke="#ffffff" stroke-width="1.0" />
|
||||||
|
</rule>
|
||||||
|
<rule e="node" k="*" v="city">
|
||||||
|
<caption k="name" font-style="bold" font-size="22" fill="#ffffff"
|
||||||
|
stroke="#002020" stroke-width="4.0" />
|
||||||
|
</rule>
|
||||||
|
<rule e="node" k="*" v="country">
|
||||||
|
<caption k="name" font-size="22" fill="#ffffff"
|
||||||
|
stroke="#000000" stroke-width="2.0" />
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- railway -->
|
||||||
|
<rule e="node" k="railway" v="*">
|
||||||
|
<rule e="node" k="*" v="station" zoom-min="14">
|
||||||
|
<circle r="6" fill="#ec2d2d" stroke="#606060" width="1.5" />
|
||||||
|
<!-- <caption k="name" dy="-10" font-style="bold" font-size="13" fill="#ec2d2d"
|
||||||
|
stroke="#ffffff" stroke-width="2.0" /> -->
|
||||||
|
</rule>
|
||||||
|
<rule e="node" k="*" v="halt|tram_stop" zoom-min="17">
|
||||||
|
<circle r="4" fill="#ec2d2d" stroke="#606060" width="1.5" />
|
||||||
|
<!-- <caption k="name" dy="-15" font-style="bold" font-size="11" fill="#ec2d2d"
|
||||||
|
stroke="#ffffff" stroke-width="2.0" /> -->
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
</rendertheme>
|
||||||
@ -36,7 +36,7 @@ public class GLMapTile extends MapTile {
|
|||||||
* @param zoomLevel
|
* @param zoomLevel
|
||||||
* ..
|
* ..
|
||||||
*/
|
*/
|
||||||
public GLMapTile(long tileX, long tileY, byte zoomLevel) {
|
public GLMapTile(int tileX, int tileY, byte zoomLevel) {
|
||||||
super(tileX, tileY, zoomLevel);
|
super(tileX, tileY, zoomLevel);
|
||||||
mScale = 1;
|
mScale = 1;
|
||||||
mTextureID = -1;
|
mTextureID = -1;
|
||||||
|
|||||||
@ -17,8 +17,10 @@ package org.mapsforge.android.swrenderer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mapsforge.android.DebugSettings;
|
||||||
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||||
@ -98,11 +100,16 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
|||||||
|
|
||||||
// private long _renderTime;
|
// private long _renderTime;
|
||||||
private int _nodes, _nodesDropped;
|
private int _nodes, _nodesDropped;
|
||||||
|
private MapView mMapView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DatabaseRenderer.
|
* Constructs a new DatabaseRenderer.
|
||||||
|
*
|
||||||
|
* @param mapView
|
||||||
|
* the MapView
|
||||||
*/
|
*/
|
||||||
public MapGenerator() {
|
public MapGenerator(MapView mapView) {
|
||||||
|
mMapView = mapView;
|
||||||
mCanvasRasterer = new CanvasRasterer();
|
mCanvasRasterer = new CanvasRasterer();
|
||||||
mLabelPlacement = new LabelPlacement();
|
mLabelPlacement = new LabelPlacement();
|
||||||
|
|
||||||
@ -131,13 +138,13 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
|
public boolean executeJob(MapTile mapTile) {
|
||||||
long time_load = System.currentTimeMillis();
|
long time_load = System.currentTimeMillis();
|
||||||
_nodes = 0;
|
_nodes = 0;
|
||||||
_nodesDropped = 0;
|
_nodesDropped = 0;
|
||||||
// _renderTime = 0;
|
// _renderTime = 0;
|
||||||
|
|
||||||
mCurrentTile = mapGeneratorJob.tile;
|
mCurrentTile = mapTile;
|
||||||
mCurrentTileZoom = ((long) Tile.TILE_SIZE << mCurrentTile.zoomLevel);
|
mCurrentTileZoom = ((long) Tile.TILE_SIZE << mCurrentTile.zoomLevel);
|
||||||
mCurrentTileX = mCurrentTile.pixelX;
|
mCurrentTileX = mCurrentTile.pixelX;
|
||||||
mCurrentTileY = mCurrentTile.pixelY;
|
mCurrentTileY = mCurrentTile.pixelY;
|
||||||
@ -151,7 +158,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
|||||||
//
|
//
|
||||||
// mTileWidth = mLon2 - mLon1;
|
// mTileWidth = mLon2 - mLon1;
|
||||||
// mTileHeight = mLat1 - mLat2;
|
// mTileHeight = mLat1 - mLat2;
|
||||||
mScale = mapGeneratorJob.getScale();
|
// mScale = mapGeneratorJob.getScale();
|
||||||
|
|
||||||
// Theme theme = mapGeneratorJob.jobParameters.theme;
|
// Theme theme = mapGeneratorJob.jobParameters.theme;
|
||||||
// if (!theme.equals(mPreviousJobTheme)) {
|
// if (!theme.equals(mPreviousJobTheme)) {
|
||||||
@ -203,18 +210,20 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
|||||||
mCanvasRasterer.drawNodes(mAreaLabels);
|
mCanvasRasterer.drawNodes(mAreaLabels);
|
||||||
time_draw = System.currentTimeMillis() - time_draw;
|
time_draw = System.currentTimeMillis() - time_draw;
|
||||||
|
|
||||||
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
DebugSettings debugSettings = mMapView.getDebugSettings();
|
||||||
|
|
||||||
|
if (debugSettings.mDrawTileFrames) {
|
||||||
mCanvasRasterer.drawTileFrame();
|
mCanvasRasterer.drawTileFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapGeneratorJob.debugSettings.mDrawTileCoordinates) {
|
if (debugSettings.mDrawTileCoordinates) {
|
||||||
mCanvasRasterer.drawTileCoordinates(mCurrentTile, time_load, time_draw,
|
mCanvasRasterer.drawTileCoordinates(mCurrentTile, time_load, time_draw,
|
||||||
_nodes, _nodesDropped);
|
_nodes, _nodesDropped);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearLists();
|
clearLists();
|
||||||
|
|
||||||
mapGeneratorJob.setBitmap(mTileBitmap);
|
// mapGeneratorJob.setBitmap(mTileBitmap);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -411,8 +420,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
|||||||
// mPrevLayer = layer;
|
// mPrevLayer = layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ShapeContainer> mCurLevelContainer1;
|
// private List<ShapeContainer> mCurLevelContainer1;
|
||||||
private List<ShapeContainer> mCurLevelContainer2;
|
// private List<ShapeContainer> mCurLevelContainer2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(Line line, int level) {
|
public void renderWay(Line line, int level) {
|
||||||
|
|||||||
@ -21,17 +21,13 @@ import java.nio.ByteOrder;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
import org.mapsforge.android.DebugSettings;
|
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
import org.mapsforge.android.mapgenerator.MapTile;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
|
||||||
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
|
||||||
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.utils.GlUtils;
|
import org.mapsforge.android.utils.GlUtils;
|
||||||
@ -40,7 +36,6 @@ import org.mapsforge.core.MercatorProjection;
|
|||||||
import org.mapsforge.core.Tile;
|
import org.mapsforge.core.Tile;
|
||||||
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.opengl.GLUtils;
|
|
||||||
import android.opengl.Matrix;
|
import android.opengl.Matrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,11 +60,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
private double mDrawX, mDrawY;
|
private double mDrawX, mDrawY;
|
||||||
private long mTileX, mTileY;
|
private long mTileX, mTileY;
|
||||||
private float mMapScale;
|
private float mMapScale;
|
||||||
private DebugSettings mDebugSettings;
|
// private DebugSettings mDebugSettings;
|
||||||
private JobParameters mJobParameter;
|
// private JobParameters mJobParameter;
|
||||||
private MapPosition mMapPosition, mPrevMapPosition;
|
private MapPosition mMapPosition, mPrevMapPosition;
|
||||||
|
|
||||||
private ArrayList<MapGeneratorJob> mJobList;
|
private ArrayList<MapTile> mJobList;
|
||||||
|
|
||||||
ArrayList<Integer> mTextures;
|
ArrayList<Integer> mTextures;
|
||||||
MapView mMapView;
|
MapView mMapView;
|
||||||
@ -78,8 +73,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
GLMapTile[] newTiles;
|
GLMapTile[] newTiles;
|
||||||
int currentTileCnt = 0;
|
int currentTileCnt = 0;
|
||||||
|
|
||||||
private TileCacheKey mTileCacheKey;
|
// private TileCacheKey mTileCacheKey;
|
||||||
private LinkedHashMap<TileCacheKey, GLMapTile> mTiles;
|
// private LinkedHashMap<TileCacheKey, GLMapTile> mTiles;
|
||||||
private ArrayList<GLMapTile> mTileList;
|
private ArrayList<GLMapTile> mTileList;
|
||||||
|
|
||||||
private boolean processedTile = true;
|
private boolean processedTile = true;
|
||||||
@ -96,7 +91,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
*/
|
*/
|
||||||
public MapRenderer(MapView mapView) {
|
public MapRenderer(MapView mapView) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
mDebugSettings = mapView.getDebugSettings();
|
// mDebugSettings = mapView.getDebugSettings();
|
||||||
mMapScale = 1;
|
mMapScale = 1;
|
||||||
|
|
||||||
float[] vertices = {
|
float[] vertices = {
|
||||||
@ -110,12 +105,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
mVertices.put(vertices);
|
mVertices.put(vertices);
|
||||||
|
|
||||||
mTextures = new ArrayList<Integer>();
|
mTextures = new ArrayList<Integer>();
|
||||||
mJobList = new ArrayList<MapGeneratorJob>();
|
mJobList = new ArrayList<MapTile>();
|
||||||
|
|
||||||
mTiles = new LinkedHashMap<TileCacheKey, GLMapTile>(100);
|
// mTiles = new LinkedHashMap<TileCacheKey, GLMapTile>(100);
|
||||||
mTileList = new ArrayList<GLMapTile>();
|
mTileList = new ArrayList<GLMapTile>();
|
||||||
|
|
||||||
mTileCacheKey = new TileCacheKey();
|
// mTileCacheKey = new TileCacheKey();
|
||||||
mInitial = true;
|
mInitial = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,8 +139,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
for (int j = mTileList.size() - 1, cnt = 0; cnt < remove; j--, cnt++) {
|
for (int j = mTileList.size() - 1, cnt = 0; cnt < remove; j--, cnt++) {
|
||||||
GLMapTile t = mTileList.remove(j);
|
GLMapTile t = mTileList.remove(j);
|
||||||
|
|
||||||
mTileCacheKey.set(t.tileX, t.tileY, t.zoomLevel);
|
// mTileCacheKey.set(t.tileX, t.tileY, t.zoomLevel);
|
||||||
mTiles.remove(mTileCacheKey);
|
// mTiles.remove(mTileCacheKey);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (t.child[i] != null)
|
if (t.child[i] != null)
|
||||||
@ -176,63 +171,63 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
long pixelLeft = x - offsetX;
|
long pixelLeft = x - offsetX;
|
||||||
long pixelTop = y - offsetY;
|
long pixelTop = y - offsetY;
|
||||||
|
|
||||||
long tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel);
|
int tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel);
|
||||||
long tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel);
|
int tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel);
|
||||||
long tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel);
|
int tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel);
|
||||||
long tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel);
|
int tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel);
|
||||||
|
|
||||||
mJobList.clear();
|
mJobList.clear();
|
||||||
|
|
||||||
// IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
// IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
||||||
|
|
||||||
int tiles = 0;
|
int tiles = 0;
|
||||||
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
for (int tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
||||||
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
|
for (int tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
|
||||||
|
|
||||||
GLMapTile tile = mTiles.get(mTileCacheKey.set(tileX, tileY, zoomLevel));
|
// GLMapTile tile = mTiles.get(mTileCacheKey.set(tileX, tileY, zoomLevel));
|
||||||
|
//
|
||||||
|
// if (tile == null) {
|
||||||
|
// tile = new GLMapTile(tileX, tileY, zoomLevel);
|
||||||
|
// TileCacheKey key = new TileCacheKey(mTileCacheKey);
|
||||||
|
// mTiles.put(key, tile);
|
||||||
|
//
|
||||||
|
// mTileCacheKey.set((tileX >> 1), (tileY >> 1), (byte) (zoomLevel - 1));
|
||||||
|
// tile.parent = mTiles.get(mTileCacheKey);
|
||||||
|
//
|
||||||
|
// long xx = tileX << 1;
|
||||||
|
// long yy = tileY << 1;
|
||||||
|
// byte z = (byte) (zoomLevel + 1);
|
||||||
|
//
|
||||||
|
// tile.child[0] = mTiles.get(mTileCacheKey.set(xx, yy, z));
|
||||||
|
// tile.child[1] = mTiles.get(mTileCacheKey.set(xx + 1, yy, z));
|
||||||
|
// tile.child[2] = mTiles.get(mTileCacheKey.set(xx, yy + 1, z));
|
||||||
|
// tile.child[3] = mTiles.get(mTileCacheKey.set(xx + 1, yy + 1, z));
|
||||||
|
//
|
||||||
|
// mTileList.add(tile);
|
||||||
|
// }
|
||||||
|
|
||||||
if (tile == null) {
|
// newTiles[tiles++] = tile;
|
||||||
tile = new GLMapTile(tileX, tileY, zoomLevel);
|
//
|
||||||
TileCacheKey key = new TileCacheKey(mTileCacheKey);
|
// if (!tile.isReady || (tile.getScale() != scale)) {
|
||||||
mTiles.put(key, tile);
|
// // tile.isLoading = true;
|
||||||
|
// // approximation for TileScheduler
|
||||||
mTileCacheKey.set((tileX >> 1), (tileY >> 1), (byte) (zoomLevel - 1));
|
// if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft
|
||||||
tile.parent = mTiles.get(mTileCacheKey);
|
// || tileX > tileRight)
|
||||||
|
// tile.isVisible = false;
|
||||||
long xx = tileX << 1;
|
// else
|
||||||
long yy = tileY << 1;
|
// tile.isVisible = true;
|
||||||
byte z = (byte) (zoomLevel + 1);
|
//
|
||||||
|
// MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
|
||||||
tile.child[0] = mTiles.get(mTileCacheKey.set(xx, yy, z));
|
// mDebugSettings);
|
||||||
tile.child[1] = mTiles.get(mTileCacheKey.set(xx + 1, yy, z));
|
// job.setScale(scale);
|
||||||
tile.child[2] = mTiles.get(mTileCacheKey.set(xx, yy + 1, z));
|
// mJobList.add(job);
|
||||||
tile.child[3] = mTiles.get(mTileCacheKey.set(xx + 1, yy + 1, z));
|
// }
|
||||||
|
|
||||||
mTileList.add(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
newTiles[tiles++] = tile;
|
|
||||||
|
|
||||||
if (!tile.isReady || (tile.getScale() != scale)) {
|
|
||||||
// tile.isLoading = true;
|
|
||||||
// approximation for TileScheduler
|
|
||||||
if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft
|
|
||||||
|| tileX > tileRight)
|
|
||||||
tile.isVisible = false;
|
|
||||||
else
|
|
||||||
tile.isVisible = true;
|
|
||||||
|
|
||||||
MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
|
|
||||||
mDebugSettings);
|
|
||||||
job.setScale(scale);
|
|
||||||
mJobList.add(job);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|
||||||
limitCache(zoomLevel, (mTiles.size() - 200));
|
limitCache(zoomLevel, (mTileList.size() - 200));
|
||||||
|
|
||||||
for (int i = 0; i < tiles; i++)
|
for (int i = 0; i < tiles; i++)
|
||||||
currentTiles[i] = newTiles[i];
|
currentTiles[i] = newTiles[i];
|
||||||
@ -243,9 +238,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
mMapScale = scale;
|
mMapScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mJobList.size() > 0) {
|
// if (mJobList.size() > 0) {
|
||||||
mMapView.addJobs(mJobList);
|
// mMapView.addJobs(mJobList);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -260,12 +255,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
|
|
||||||
long x = (long) MercatorProjection.longitudeToPixelX(
|
long x = (long) MercatorProjection.longitudeToPixelX(mMapPosition);
|
||||||
mMapPosition.geoPoint.getLongitude(),
|
long y = (long) MercatorProjection.latitudeToPixelY(mMapPosition);
|
||||||
mMapPosition.zoomLevel);
|
|
||||||
long y = (long) MercatorProjection
|
|
||||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(),
|
|
||||||
mMapPosition.zoomLevel);
|
|
||||||
|
|
||||||
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
|
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
|
||||||
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
|
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
|
||||||
@ -304,12 +295,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
mMapView.requestRender();
|
mMapView.requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapGeneratorJob mMapGeneratorJob = null;
|
// private MapGeneratorJob mMapGeneratorJob = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean passTile(MapGeneratorJob mapGeneratorJob) {
|
public boolean passTile(MapTile mapTile) {
|
||||||
|
|
||||||
mMapGeneratorJob = mapGeneratorJob;
|
// mMapGeneratorJob = mapGeneratorJob;
|
||||||
processedTile = false;
|
processedTile = false;
|
||||||
mMapView.requestRender();
|
mMapView.requestRender();
|
||||||
|
|
||||||
@ -344,11 +335,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
} else {
|
} else {
|
||||||
z = 1.0f / (1 << -diff);
|
z = 1.0f / (1 << -diff);
|
||||||
}
|
}
|
||||||
drawX = MercatorProjection
|
// drawX = MercatorProjection
|
||||||
.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
// .longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
||||||
tile.zoomLevel);
|
// tile.zoomLevel);
|
||||||
drawY = MercatorProjection
|
// drawY = MercatorProjection
|
||||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
// .latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,71 +421,71 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||||
|
|
||||||
// lock position and currentTiles while drawing
|
// lock position and currentTiles while drawing
|
||||||
synchronized (this) {
|
// synchronized (this) {
|
||||||
if (mMapGeneratorJob != null) {
|
// if (mMapGeneratorJob != null) {
|
||||||
|
//
|
||||||
tile = (GLMapTile) mMapGeneratorJob.tile;
|
// tile = (GLMapTile) mMapGeneratorJob.tile;
|
||||||
// TODO tile bitmaps texture to smaller parts avoiding uploading full
|
// // TODO tile bitmaps texture to smaller parts avoiding uploading full
|
||||||
// bitmap when not necessary
|
// // bitmap when not necessary
|
||||||
if (tile.getTexture() >= 0) {
|
// if (tile.getTexture() >= 0) {
|
||||||
// reuse tile texture
|
// // reuse tile texture
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
// GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||||
mMapGeneratorJob.getBitmap());
|
// mMapGeneratorJob.getBitmap());
|
||||||
} else if (mTextures.size() > 0) {
|
// } else if (mTextures.size() > 0) {
|
||||||
// reuse texture from previous tiles
|
// // reuse texture from previous tiles
|
||||||
Integer texture;
|
// Integer texture;
|
||||||
texture = mTextures.remove(mTextures.size() - 1);
|
// texture = mTextures.remove(mTextures.size() - 1);
|
||||||
|
//
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
// GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||||
mMapGeneratorJob.getBitmap());
|
// mMapGeneratorJob.getBitmap());
|
||||||
tile.setTexture(texture.intValue());
|
// tile.setTexture(texture.intValue());
|
||||||
} else {
|
// } else {
|
||||||
// create texture
|
// // create texture
|
||||||
tile.setTexture(GlUtils.loadTextures(mMapGeneratorJob.getBitmap()));
|
// tile.setTexture(GlUtils.loadTextures(mMapGeneratorJob.getBitmap()));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
tile.setScale(mMapGeneratorJob.getScale());
|
// tile.setScale(mMapGeneratorJob.getScale());
|
||||||
tile.isReady = true;
|
// tile.isReady = true;
|
||||||
tile.isLoading = false;
|
// tile.isLoading = false;
|
||||||
|
//
|
||||||
mMapGeneratorJob = null;
|
// mMapGeneratorJob = null;
|
||||||
processedTile = true;
|
// processedTile = true;
|
||||||
// loadedTexture = true;
|
// // loadedTexture = true;
|
||||||
}
|
// }
|
||||||
int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
// int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
||||||
int hWidth = mWidth >> 1;
|
// int hWidth = mWidth >> 1;
|
||||||
int hHeight = mHeight >> 1;
|
// int hHeight = mHeight >> 1;
|
||||||
for (int i = 0, n = currentTileCnt; i < n; i++) {
|
// for (int i = 0, n = currentTileCnt; i < n; i++) {
|
||||||
tile = currentTiles[i];
|
// tile = currentTiles[i];
|
||||||
|
//
|
||||||
float x = (float) (tile.pixelX - mDrawX);
|
// float x = (float) (tile.pixelX - mDrawX);
|
||||||
float y = (float) (tile.pixelY - mDrawY);
|
// float y = (float) (tile.pixelY - mDrawY);
|
||||||
|
//
|
||||||
// clip rendering to tile boundaries
|
// // clip rendering to tile boundaries
|
||||||
GLES20.glScissor(
|
// GLES20.glScissor(
|
||||||
hWidth + (int) (x * mMapScale) - 2,
|
// hWidth + (int) (x * mMapScale) - 2,
|
||||||
hHeight - (int) (y * mMapScale) - tileSize - 2,
|
// hHeight - (int) (y * mMapScale) - tileSize - 2,
|
||||||
tileSize + 4, tileSize + 4);
|
// tileSize + 4, tileSize + 4);
|
||||||
|
//
|
||||||
if (drawTile(tile, 0, 0.0f))
|
// if (drawTile(tile, 0, 0.0f))
|
||||||
continue;
|
// continue;
|
||||||
|
//
|
||||||
// or two zoom level above
|
// // or two zoom level above
|
||||||
for (int k = 0; k < 4; k++) {
|
// for (int k = 0; k < 4; k++) {
|
||||||
if (((child = tile.child[k]) != null)) {
|
// if (((child = tile.child[k]) != null)) {
|
||||||
|
//
|
||||||
if (drawTile(child, 2, 0.1f))
|
// if (drawTile(child, 2, 0.1f))
|
||||||
continue;
|
// continue;
|
||||||
|
//
|
||||||
for (int j = 0; j < 4; j++)
|
// for (int j = 0; j < 4; j++)
|
||||||
if ((child2 = child.child[j]) != null)
|
// if ((child2 = child.child[j]) != null)
|
||||||
drawTile(child2, 2, 0.1f);
|
// drawTile(child2, 2, 0.1f);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -508,10 +499,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
GLES20.glViewport(0, 0, width, height);
|
GLES20.glViewport(0, 0, width, height);
|
||||||
|
|
||||||
mDebugSettings = mMapView.getDebugSettings();
|
// mDebugSettings = mMapView.getDebugSettings();
|
||||||
mJobParameter = mMapView.getJobParameters();
|
// mJobParameter = mMapView.getJobParameters();
|
||||||
|
|
||||||
mTiles.clear();
|
// mTiles.clear();
|
||||||
mTileList.clear();
|
mTileList.clear();
|
||||||
mTextures.clear();
|
mTextures.clear();
|
||||||
mInitial = true;
|
mInitial = true;
|
||||||
@ -581,7 +572,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IMapGenerator createMapGenerator() {
|
public IMapGenerator createMapGenerator() {
|
||||||
return new MapGenerator();
|
return new MapGenerator(mMapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import org.mapsforge.database.MapFileInfo;
|
|||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -43,7 +44,6 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@ -51,14 +51,14 @@ import android.widget.SeekBar;
|
|||||||
import android.widget.SpinnerAdapter;
|
import android.widget.SpinnerAdapter;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.ToggleButton;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map application which uses the features from the mapsforge map library. The map can be centered to the current
|
* A map application which uses the features from the mapsforge map library. The map can be centered to the current
|
||||||
* location. A simple file browser for selecting the map file is also included. Some preferences can be adjusted via the
|
* location. A simple file browser for selecting the map file is also included. Some preferences can be adjusted via the
|
||||||
* {@link EditPreferences} activity.
|
* {@link EditPreferences} activity.
|
||||||
*/
|
*/
|
||||||
public class TileMap extends MapActivity { // implements ActionBar.OnNavigationListener {
|
public class TileMap extends MapActivity {
|
||||||
|
// implements ActionBar.OnNavigationListener {
|
||||||
private static final String BUNDLE_CENTER_AT_FIRST_FIX = "centerAtFirstFix";
|
private static final String BUNDLE_CENTER_AT_FIRST_FIX = "centerAtFirstFix";
|
||||||
private static final String BUNDLE_SHOW_MY_LOCATION = "showMyLocation";
|
private static final String BUNDLE_SHOW_MY_LOCATION = "showMyLocation";
|
||||||
private static final String BUNDLE_SNAP_TO_LOCATION = "snapToLocation";
|
private static final String BUNDLE_SNAP_TO_LOCATION = "snapToLocation";
|
||||||
@ -76,7 +76,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
private MyLocationListener mMyLocationListener;
|
private MyLocationListener mMyLocationListener;
|
||||||
private boolean mShowMyLocation;
|
private boolean mShowMyLocation;
|
||||||
private boolean mSnapToLocation;
|
private boolean mSnapToLocation;
|
||||||
private ToggleButton mSnapToLocationView;
|
// private ToggleButton mSnapToLocationView;
|
||||||
private WakeLock mWakeLock;
|
private WakeLock mWakeLock;
|
||||||
MapController mMapController;
|
MapController mMapController;
|
||||||
MapView mMapView;
|
MapView mMapView;
|
||||||
@ -86,12 +86,12 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||||
getMenuInflater().inflate(R.menu.options_menu, menu);
|
getMenuInflater().inflate(R.menu.options_menu, menu);
|
||||||
else
|
else
|
||||||
getMenuInflater().inflate(R.menu.options_menu_pre_honeycomb, menu);
|
getMenuInflater().inflate(R.menu.options_menu_pre_honeycomb, menu);
|
||||||
mMenu = menu;
|
mMenu = menu;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,9 +99,9 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
|
|
||||||
// case R.id.menu_info_map_file:
|
case R.id.menu_info_about:
|
||||||
// showDialog(DIALOG_INFO_MAP_FILE);
|
startActivity(new Intent(this, InfoView.class));
|
||||||
// return true;
|
return true;
|
||||||
|
|
||||||
case R.id.menu_position:
|
case R.id.menu_position:
|
||||||
return true;
|
return true;
|
||||||
@ -161,6 +161,10 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
mMapView.setRenderTheme(InternalRenderTheme.OSMARENDER);
|
mMapView.setRenderTheme(InternalRenderTheme.OSMARENDER);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case R.id.menu_render_theme_tronrender:
|
||||||
|
mMapView.setRenderTheme(InternalRenderTheme.TRONRENDER);
|
||||||
|
return true;
|
||||||
|
|
||||||
case R.id.menu_render_theme_select_file:
|
case R.id.menu_render_theme_select_file:
|
||||||
startRenderThemePicker();
|
startRenderThemePicker();
|
||||||
return true;
|
return true;
|
||||||
@ -176,6 +180,10 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
menu.clear();
|
||||||
|
onCreateOptionsMenu(menu);
|
||||||
|
|
||||||
|
Log.d("TileMap", "prepare options...");
|
||||||
|
|
||||||
// menu.findItem(R.id.menu_info_map_file).setEnabled(true);
|
// menu.findItem(R.id.menu_info_map_file).setEnabled(true);
|
||||||
|
|
||||||
@ -193,9 +201,15 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
menu.findItem(R.id.menu_position_map_center).setEnabled(true);
|
menu.findItem(R.id.menu_position_map_center).setEnabled(true);
|
||||||
menu.findItem(R.id.menu_render_theme).setEnabled(true);
|
menu.findItem(R.id.menu_render_theme).setEnabled(true);
|
||||||
menu.findItem(R.id.menu_mapfile).setEnabled(true);
|
// menu.findItem(R.id.menu_mapfile).setEnabled(true);
|
||||||
|
|
||||||
return true;
|
if (mMapDatabase == MapDatabases.MAP_READER)
|
||||||
|
menu.findItem(R.id.menu_mapfile).setVisible(true);
|
||||||
|
else
|
||||||
|
menu.findItem(R.id.menu_mapfile).setVisible(false);
|
||||||
|
|
||||||
|
return super.onPrepareOptionsMenu(menu);
|
||||||
|
// return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -227,7 +241,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
mMyLocationListener.setCenterAtFirstFix(centerAtFirstFix);
|
mMyLocationListener.setCenterAtFirstFix(centerAtFirstFix);
|
||||||
mLocationManager.requestLocationUpdates(bestProvider, 1000, 0,
|
mLocationManager.requestLocationUpdates(bestProvider, 1000, 0,
|
||||||
mMyLocationListener);
|
mMyLocationListener);
|
||||||
mSnapToLocationView.setVisibility(View.VISIBLE);
|
// mSnapToLocationView.setVisibility(View.VISIBLE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -323,17 +337,18 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
mMapView = (MapView) findViewById(R.id.mapView);
|
mMapView = (MapView) findViewById(R.id.mapView);
|
||||||
configureMapView();
|
configureMapView();
|
||||||
|
|
||||||
mSnapToLocationView = (ToggleButton) findViewById(R.id.snapToLocationView);
|
// mSnapToLocationView = (ToggleButton) findViewById(R.id.snapToLocationView);
|
||||||
mSnapToLocationView.setOnClickListener(new OnClickListener() {
|
//
|
||||||
@Override
|
// mSnapToLocationView.setOnClickListener(new OnClickListener() {
|
||||||
public void onClick(View view) {
|
// @Override
|
||||||
if (isSnapToLocationEnabled()) {
|
// public void onClick(View view) {
|
||||||
disableSnapToLocation(true);
|
// if (isSnapToLocationEnabled()) {
|
||||||
} else {
|
// disableSnapToLocation(true);
|
||||||
enableSnapToLocation(true);
|
// } else {
|
||||||
}
|
// enableSnapToLocation(true);
|
||||||
}
|
// }
|
||||||
});
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
// get the pointers to different system services
|
// get the pointers to different system services
|
||||||
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||||
@ -404,7 +419,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
builder.setPositiveButton(R.string.ok, null);
|
builder.setPositiveButton(R.string.ok, null);
|
||||||
return builder.create();
|
return builder.create();
|
||||||
} else {
|
} else {
|
||||||
// do dialog will be created
|
// no dialog will be created
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,40 +548,31 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
if (preferences.contains("mapDatabase")) {
|
if (preferences.contains("mapDatabase")) {
|
||||||
String name = preferences.getString("mapDatabase",
|
String name = preferences.getString("mapDatabase",
|
||||||
MapDatabases.POSTGIS_READER.name());
|
MapDatabases.PBMAP_READER.name());
|
||||||
|
|
||||||
MapDatabases mapDatabaseNew;
|
MapDatabases mapDatabaseNew;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mapDatabaseNew = MapDatabases.valueOf(name);
|
mapDatabaseNew = MapDatabases.valueOf(name);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
mapDatabaseNew = MapDatabases.POSTGIS_READER;
|
mapDatabaseNew = MapDatabases.PBMAP_READER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapDatabaseInternalNew = MapDatabaseInternal.PBMAP_READER;
|
|
||||||
Log.d("VectorTileMap", "set map database " + mapDatabaseNew);
|
Log.d("VectorTileMap", "set map database " + mapDatabaseNew);
|
||||||
|
|
||||||
if (mapDatabaseNew != mMapDatabase) {
|
if (mapDatabaseNew != mMapDatabase) {
|
||||||
mMapView.setMapDatabase(mapDatabaseNew);
|
mMapView.setMapDatabase(mapDatabaseNew);
|
||||||
mMapDatabase = mapDatabaseNew;
|
mMapDatabase = mapDatabaseNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (mapDatabaseNew != mMapDatabase) {
|
|
||||||
// IMapDatabase mapDatabase = MapDatabaseFactory
|
|
||||||
// .createMapDatabase(mapDatabaseNew);
|
|
||||||
//
|
|
||||||
// mMapView.setMapDatabase(mapDatabase);
|
|
||||||
// mMapDatabase = mapDatabaseNew;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
String textScaleDefault = getString(R.string.preferences_text_scale_default);
|
// String textScaleDefault = getString(R.string.preferences_text_scale_default);
|
||||||
mMapView.setTextScale(Float.parseFloat(preferences.getString("textScale",
|
// mMapView.setTextScale(Float.parseFloat(preferences.getString("textScale",
|
||||||
textScaleDefault)));
|
// textScaleDefault)));
|
||||||
} catch (NumberFormatException e) {
|
// } catch (NumberFormatException e) {
|
||||||
mMapView.setTextScale(1);
|
// mMapView.setTextScale(1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (preferences.getBoolean("fullscreen", false)) {
|
if (preferences.getBoolean("fullscreen", false)) {
|
||||||
Log.i("mapviewer", "FULLSCREEN");
|
Log.i("mapviewer", "FULLSCREEN");
|
||||||
@ -601,6 +607,18 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
} else {
|
} else {
|
||||||
mMapView.setMapFile(mMapView.getMapFile());
|
mMapView.setMapFile(mMapView.getMapFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
|
VersionHelper.refreshActionBarMenu(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class VersionHelper {
|
||||||
|
@TargetApi(11)
|
||||||
|
static void refreshActionBarMenu(Activity activity) {
|
||||||
|
activity.invalidateOptionsMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -628,7 +646,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
// circleOverlay = null;
|
// circleOverlay = null;
|
||||||
// itemizedOverlay = null;
|
// itemizedOverlay = null;
|
||||||
// }
|
// }
|
||||||
mSnapToLocationView.setVisibility(View.GONE);
|
// mSnapToLocationView.setVisibility(View.GONE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -643,7 +661,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
void disableSnapToLocation(boolean showToast) {
|
void disableSnapToLocation(boolean showToast) {
|
||||||
if (mSnapToLocation) {
|
if (mSnapToLocation) {
|
||||||
mSnapToLocation = false;
|
mSnapToLocation = false;
|
||||||
mSnapToLocationView.setChecked(false);
|
// mSnapToLocationView.setChecked(false);
|
||||||
mMapView.setClickable(true);
|
mMapView.setClickable(true);
|
||||||
if (showToast) {
|
if (showToast) {
|
||||||
showToastOnUiThread(getString(R.string.snap_to_location_disabled));
|
showToastOnUiThread(getString(R.string.snap_to_location_disabled));
|
||||||
|
|||||||
@ -22,12 +22,14 @@ import java.util.Comparator;
|
|||||||
import org.mapsforge.app.R;
|
import org.mapsforge.app.R;
|
||||||
import org.mapsforge.app.filefilter.ValidFileFilter;
|
import org.mapsforge.app.filefilter.ValidFileFilter;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
@ -223,13 +225,16 @@ public class FilePicker extends Activity implements AdapterView.OnItemClickListe
|
|||||||
editor.commit();
|
editor.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(11)
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
// getActionBar().hide();
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||||
|
getActionBar().hide();
|
||||||
|
|
||||||
// check if the full screen mode should be activated
|
// check if the full screen mode should be activated
|
||||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
|
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
||||||
|
// false)) {
|
||||||
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||||
// } else {
|
// } else {
|
||||||
|
|||||||
@ -16,6 +16,8 @@ package org.mapsforge.app.preferences;
|
|||||||
|
|
||||||
import org.mapsforge.app.R;
|
import org.mapsforge.app.R;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
|
|
||||||
@ -29,10 +31,13 @@ public class EditPreferences extends PreferenceActivity {
|
|||||||
addPreferencesFromResource(R.xml.preferences);
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(11)
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
// getActionBar().hide();
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||||
|
getActionBar().hide();
|
||||||
|
|
||||||
// check if the full screen mode should be activated
|
// check if the full screen mode should be activated
|
||||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
||||||
|
|||||||
@ -14,21 +14,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.core;
|
package org.mapsforge.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GeoPoint represents an immutable pair of latitude and longitude coordinates.
|
* A GeoPoint represents an immutable pair of latitude and longitude coordinates.
|
||||||
*/
|
*/
|
||||||
public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
public class GeoPoint implements Comparable<GeoPoint> {
|
||||||
/**
|
/**
|
||||||
* Conversion factor from degrees to microdegrees.
|
* Conversion factor from degrees to microdegrees.
|
||||||
*/
|
*/
|
||||||
private static final double CONVERSION_FACTOR = 1000000d;
|
private static final double CONVERSION_FACTOR = 1000000d;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The latitude value of this GeoPoint in microdegrees (degrees * 10^6).
|
* The latitude value of this GeoPoint in microdegrees (degrees * 10^6).
|
||||||
*/
|
*/
|
||||||
@ -42,7 +37,7 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
|||||||
/**
|
/**
|
||||||
* The hash code of this object.
|
* The hash code of this object.
|
||||||
*/
|
*/
|
||||||
private transient int hashCodeValue;
|
private int hashCodeValue = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param latitude
|
* @param latitude
|
||||||
@ -57,7 +52,6 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
|||||||
double limitLongitude = MercatorProjection.limitLongitude(longitude);
|
double limitLongitude = MercatorProjection.limitLongitude(longitude);
|
||||||
this.longitudeE6 = (int) (limitLongitude * CONVERSION_FACTOR);
|
this.longitudeE6 = (int) (limitLongitude * CONVERSION_FACTOR);
|
||||||
|
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,6 +110,9 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
if (this.hashCodeValue == 0)
|
||||||
|
this.hashCodeValue = calculateHashCode();
|
||||||
|
|
||||||
return this.hashCodeValue;
|
return this.hashCodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +136,4 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
|||||||
result = 31 * result + this.longitudeE6;
|
result = 31 * result + this.longitudeE6;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
|
||||||
objectInputStream.defaultReadObject();
|
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,20 +14,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.core;
|
package org.mapsforge.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MapPosition represents an immutable pair of {@link GeoPoint} and zoom level.
|
* A MapPosition represents an immutable pair of {@link GeoPoint} and zoom level.
|
||||||
*/
|
*/
|
||||||
public class MapPosition implements Serializable {
|
public class MapPosition {
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The map position.
|
* The map position.
|
||||||
*/
|
*/
|
||||||
public final GeoPoint geoPoint;
|
// public final GeoPoint geoPoint;
|
||||||
|
public final double lon;
|
||||||
|
public final double lat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The zoom level.
|
* The zoom level.
|
||||||
@ -38,10 +35,11 @@ public class MapPosition implements Serializable {
|
|||||||
* 1.0 - 2.0 scale of current zoomlevel
|
* 1.0 - 2.0 scale of current zoomlevel
|
||||||
*/
|
*/
|
||||||
public final float scale;
|
public final float scale;
|
||||||
/**
|
|
||||||
* The hash code of this object.
|
public final float angle;
|
||||||
*/
|
|
||||||
private transient int hashCodeValue;
|
public final double x;
|
||||||
|
public final double y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param geoPoint
|
* @param geoPoint
|
||||||
@ -51,62 +49,40 @@ public class MapPosition implements Serializable {
|
|||||||
* @param scale
|
* @param scale
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public MapPosition(GeoPoint geoPoint, byte zoomLevel, float scale) {
|
public MapPosition(GeoPoint geoPoint, byte zoomLevel, float scale) {
|
||||||
this.geoPoint = geoPoint;
|
// this.geoPoint = geoPoint;
|
||||||
this.zoomLevel = zoomLevel;
|
this.zoomLevel = zoomLevel;
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
this.hashCodeValue = calculateHashCode();
|
this.lat = geoPoint.getLatitude();
|
||||||
|
this.lon = geoPoint.getLongitude();
|
||||||
|
this.angle = 0;
|
||||||
|
this.x = MercatorProjection.longitudeToPixelX(this.lon, zoomLevel);
|
||||||
|
this.y = MercatorProjection.latitudeToPixelY(this.lat, zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public MapPosition(double latitude, double longitude, byte zoomLevel, float scale,
|
||||||
public boolean equals(Object obj) {
|
float angle) {
|
||||||
if (this == obj) {
|
this.zoomLevel = zoomLevel;
|
||||||
return true;
|
this.scale = scale;
|
||||||
} else if (!(obj instanceof MapPosition)) {
|
this.lat = latitude;
|
||||||
return false;
|
this.lon = longitude;
|
||||||
}
|
this.angle = angle;
|
||||||
MapPosition other = (MapPosition) obj;
|
this.x = MercatorProjection.longitudeToPixelX(longitude, zoomLevel);
|
||||||
if (this.geoPoint == null) {
|
this.y = MercatorProjection.latitudeToPixelY(latitude, zoomLevel);
|
||||||
if (other.geoPoint != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!this.geoPoint.equals(other.geoPoint)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (this.zoomLevel != other.zoomLevel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.hashCodeValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("MapPosition [geoPoint=");
|
builder.append("MapPosition [geoPoint=");
|
||||||
builder.append(this.geoPoint);
|
builder.append("lat");
|
||||||
|
builder.append(this.lat);
|
||||||
|
builder.append("lon");
|
||||||
|
builder.append(this.lon);
|
||||||
builder.append(", zoomLevel=");
|
builder.append(", zoomLevel=");
|
||||||
builder.append(this.zoomLevel);
|
builder.append(this.zoomLevel);
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hash code of this object.
|
|
||||||
*/
|
|
||||||
private int calculateHashCode() {
|
|
||||||
int result = 7;
|
|
||||||
result = 31 * result + ((this.geoPoint == null) ? 0 : this.geoPoint.hashCode());
|
|
||||||
result = 31 * result + this.zoomLevel;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
|
||||||
objectInputStream.defaultReadObject();
|
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,8 @@ public final class MercatorProjection {
|
|||||||
* @return the ground resolution at the given latitude and zoom level.
|
* @return the ground resolution at the given latitude and zoom level.
|
||||||
*/
|
*/
|
||||||
public static double calculateGroundResolution(double latitude, byte zoomLevel) {
|
public static double calculateGroundResolution(double latitude, byte zoomLevel) {
|
||||||
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE / ((long) Tile.TILE_SIZE << zoomLevel);
|
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE
|
||||||
|
/ ((long) Tile.TILE_SIZE << zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,6 +72,12 @@ public final class MercatorProjection {
|
|||||||
* ((long) Tile.TILE_SIZE << zoomLevel);
|
* ((long) Tile.TILE_SIZE << zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double latitudeToPixelY(MapPosition mapPosition) {
|
||||||
|
double sinLatitude = Math.sin(mapPosition.lat * (Math.PI / 180));
|
||||||
|
return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
|
||||||
|
* ((long) Tile.TILE_SIZE << mapPosition.zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a latitude coordinate (in degrees) to a tile Y number at a certain zoom level.
|
* Converts a latitude coordinate (in degrees) to a tile Y number at a certain zoom level.
|
||||||
*
|
*
|
||||||
@ -102,6 +109,16 @@ public final class MercatorProjection {
|
|||||||
return Math.max(Math.min(longitude, LONGITUDE_MAX), LONGITUDE_MIN);
|
return Math.max(Math.min(longitude, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double wrapLongitude(double longitude) {
|
||||||
|
if (longitude < -180)
|
||||||
|
return Math.max(Math.min(360 + longitude, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||||
|
else if (longitude > 180)
|
||||||
|
return Math.max(Math.min(longitude - 360, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||||
|
|
||||||
|
return longitude;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a longitude coordinate (in degrees) to a pixel X coordinate at a certain zoom level.
|
* Converts a longitude coordinate (in degrees) to a pixel X coordinate at a certain zoom level.
|
||||||
*
|
*
|
||||||
@ -115,6 +132,11 @@ public final class MercatorProjection {
|
|||||||
return (longitude + 180) / 360 * ((long) Tile.TILE_SIZE << zoomLevel);
|
return (longitude + 180) / 360 * ((long) Tile.TILE_SIZE << zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double longitudeToPixelX(MapPosition mapPosition) {
|
||||||
|
return (mapPosition.lon + 180) / 360
|
||||||
|
* ((long) Tile.TILE_SIZE << mapPosition.zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a longitude coordinate (in degrees) to the tile X number at a certain zoom level.
|
* Converts a longitude coordinate (in degrees) to the tile X number at a certain zoom level.
|
||||||
*
|
*
|
||||||
@ -150,8 +172,9 @@ public final class MercatorProjection {
|
|||||||
* the zoom level at which the coordinate should be converted.
|
* the zoom level at which the coordinate should be converted.
|
||||||
* @return the tile X number.
|
* @return the tile X number.
|
||||||
*/
|
*/
|
||||||
public static long pixelXToTileX(double pixelX, byte zoomLevel) {
|
public static int pixelXToTileX(double pixelX, byte zoomLevel) {
|
||||||
return (long) Math.min(Math.max(pixelX / Tile.TILE_SIZE, 0), Math.pow(2, zoomLevel) - 1);
|
return (int) Math.min(Math.max(pixelX / Tile.TILE_SIZE, 0),
|
||||||
|
Math.pow(2, zoomLevel) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,8 +200,9 @@ public final class MercatorProjection {
|
|||||||
* the zoom level at which the coordinate should be converted.
|
* the zoom level at which the coordinate should be converted.
|
||||||
* @return the tile Y number.
|
* @return the tile Y number.
|
||||||
*/
|
*/
|
||||||
public static long pixelYToTileY(double pixelY, byte zoomLevel) {
|
public static int pixelYToTileY(double pixelY, byte zoomLevel) {
|
||||||
return (long) Math.min(Math.max(pixelY / Tile.TILE_SIZE, 0), Math.pow(2, zoomLevel) - 1);
|
return (int) Math.min(Math.max(pixelY / Tile.TILE_SIZE, 0),
|
||||||
|
Math.pow(2, zoomLevel) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -49,7 +49,7 @@ public class Tag {
|
|||||||
*/
|
*/
|
||||||
public String value;
|
public String value;
|
||||||
|
|
||||||
private transient int hashCodeValue;
|
private transient int hashCodeValue = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tag
|
* @param tag
|
||||||
@ -63,7 +63,6 @@ public class Tag {
|
|||||||
}
|
}
|
||||||
this.key = tag.substring(0, splitPosition).intern();
|
this.key = tag.substring(0, splitPosition).intern();
|
||||||
this.value = tag.substring(splitPosition + 1).intern();
|
this.value = tag.substring(splitPosition + 1).intern();
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tag(String tag, boolean hashValue) {
|
public Tag(String tag, boolean hashValue) {
|
||||||
@ -76,8 +75,6 @@ public class Tag {
|
|||||||
this.value = tag.substring(splitPosition + 1);
|
this.value = tag.substring(splitPosition + 1);
|
||||||
else
|
else
|
||||||
this.value = tag.substring(splitPosition + 1).intern();
|
this.value = tag.substring(splitPosition + 1).intern();
|
||||||
|
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,7 +86,6 @@ public class Tag {
|
|||||||
public Tag(String key, String value) {
|
public Tag(String key, String value) {
|
||||||
this.key = (key == null ? null : key.intern());
|
this.key = (key == null ? null : key.intern());
|
||||||
this.value = (value == null ? null : value.intern());
|
this.value = (value == null ? null : value.intern());
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,7 +105,6 @@ public class Tag {
|
|||||||
this.key = (key == null ? null : key);
|
this.key = (key == null ? null : key);
|
||||||
this.value = (value == null ? null : value);
|
this.value = (value == null ? null : value);
|
||||||
}
|
}
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -121,14 +116,17 @@ public class Tag {
|
|||||||
}
|
}
|
||||||
Tag other = (Tag) obj;
|
Tag other = (Tag) obj;
|
||||||
|
|
||||||
if ((this.key != other.key) || (this.value != other.value))
|
if ((this.key == other.key) && (this.value == other.value))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
if (this.hashCodeValue == 0)
|
||||||
|
this.hashCodeValue = calculateHashCode();
|
||||||
|
|
||||||
return this.hashCodeValue;
|
return this.hashCodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,38 +19,27 @@ package org.mapsforge.core;
|
|||||||
* with their zoom level. The actual area that a tile covers on a map depends on the underlying map projection.
|
* with their zoom level. The actual area that a tile covers on a map depends on the underlying map projection.
|
||||||
*/
|
*/
|
||||||
public class Tile {
|
public class Tile {
|
||||||
/**
|
|
||||||
* Bytes per pixel required in a map tile bitmap.
|
|
||||||
*/
|
|
||||||
public static final byte TILE_BYTES_PER_PIXEL = 2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Width and height of a map tile in pixel.
|
* Width and height of a map tile in pixel.
|
||||||
*/
|
*/
|
||||||
public static int TILE_SIZE = 256;
|
public static int TILE_SIZE = 256;
|
||||||
|
|
||||||
/**
|
|
||||||
* Size of a single uncompressed map tile bitmap in bytes.
|
|
||||||
*/
|
|
||||||
public static final int TILE_SIZE_IN_BYTES = TILE_SIZE * TILE_SIZE
|
|
||||||
* TILE_BYTES_PER_PIXEL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The X number of this tile.
|
* The X number of this tile.
|
||||||
*/
|
*/
|
||||||
public final long tileX;
|
public final int tileX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Y number of this tile.
|
* The Y number of this tile.
|
||||||
*/
|
*/
|
||||||
public final long tileY;
|
public final int tileY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Zoom level of this tile.
|
* The Zoom level of this tile.
|
||||||
*/
|
*/
|
||||||
public final byte zoomLevel;
|
public final byte zoomLevel;
|
||||||
|
|
||||||
private transient int hashCodeValue;
|
|
||||||
/**
|
/**
|
||||||
* the pixel X coordinate of the upper left corner of this tile.
|
* the pixel X coordinate of the upper left corner of this tile.
|
||||||
*/
|
*/
|
||||||
@ -70,51 +59,12 @@ public class Tile {
|
|||||||
* @param zoomLevel
|
* @param zoomLevel
|
||||||
* the zoom level of the tile.
|
* the zoom level of the tile.
|
||||||
*/
|
*/
|
||||||
public Tile(long tileX, long tileY, byte zoomLevel) {
|
public Tile(int tileX, int tileY, byte zoomLevel) {
|
||||||
this.tileX = tileX;
|
this.tileX = tileX;
|
||||||
this.tileY = tileY;
|
this.tileY = tileY;
|
||||||
this.pixelX = this.tileX * TILE_SIZE;
|
this.pixelX = this.tileX * TILE_SIZE;
|
||||||
this.pixelY = this.tileY * TILE_SIZE;
|
this.pixelY = this.tileY * TILE_SIZE;
|
||||||
this.zoomLevel = zoomLevel;
|
this.zoomLevel = zoomLevel;
|
||||||
this.hashCodeValue = calculateHashCode();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
} else if (!(obj instanceof Tile)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Tile other = (Tile) obj;
|
|
||||||
if (this.tileX != other.tileX) {
|
|
||||||
return false;
|
|
||||||
} else if (this.tileY != other.tileY) {
|
|
||||||
return false;
|
|
||||||
} else if (this.zoomLevel != other.zoomLevel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the pixel X coordinate of the upper left corner of this tile.
|
|
||||||
*/
|
|
||||||
// public long getPixelX() {
|
|
||||||
// return this.pixelX;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the pixel Y coordinate of the upper left corner of this tile.
|
|
||||||
*/
|
|
||||||
// public long getPixelY() {
|
|
||||||
// return this.pixelY;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.hashCodeValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,14 +80,34 @@ public class Tile {
|
|||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the hash code of this object.
|
public boolean equals(Object obj) {
|
||||||
*/
|
if (this == obj)
|
||||||
private int calculateHashCode() {
|
return true;
|
||||||
int result = 7;
|
|
||||||
result = 31 * result + (int) (this.tileX ^ (this.tileX >>> 32));
|
if (!(obj instanceof Tile))
|
||||||
result = 31 * result + (int) (this.tileY ^ (this.tileY >>> 32));
|
return false;
|
||||||
result = 31 * result + this.zoomLevel;
|
|
||||||
return result;
|
Tile o = (Tile) obj;
|
||||||
|
|
||||||
|
if (o.tileX == this.tileX && o.tileY == this.tileY
|
||||||
|
&& o.zoomLevel == this.zoomLevel)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mHash = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (mHash == 0) {
|
||||||
|
int result = 7;
|
||||||
|
result = 31 * result + this.tileX;
|
||||||
|
result = 31 * result + this.tileY;
|
||||||
|
result = 31 * result + this.zoomLevel;
|
||||||
|
mHash = result;
|
||||||
|
}
|
||||||
|
return mHash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,10 +15,14 @@
|
|||||||
package org.mapsforge.database.pbmap;
|
package org.mapsforge.database.pbmap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -46,6 +50,7 @@ import org.mapsforge.database.IMapDatabaseCallback;
|
|||||||
import org.mapsforge.database.MapFileInfo;
|
import org.mapsforge.database.MapFileInfo;
|
||||||
import org.mapsforge.database.QueryResult;
|
import org.mapsforge.database.QueryResult;
|
||||||
|
|
||||||
|
import android.os.Environment;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +67,11 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
private boolean mOpenFile = false;
|
private boolean mOpenFile = false;
|
||||||
|
|
||||||
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
|
private static final String CACHE_DIRECTORY = "/Android/data/org.mapsforge.app/cache/";
|
||||||
|
private static final String CACHE_FILE = "%d-%d-%d.tile";
|
||||||
|
|
||||||
// private static final String URL = "http://city.informatik.uni-bremen.de:8020/test/%d/%d/%d.osmtile";
|
// private static final String URL = "http://city.informatik.uni-bremen.de:8020/test/%d/%d/%d.osmtile";
|
||||||
private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/test/%d/%d/%d.osmtile";
|
private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/test/%d/%d/%d.osmtile";
|
||||||
// private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/gis2/%d/%d/%d.osmtile";
|
// private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/gis2/%d/%d/%d.osmtile";
|
||||||
@ -69,6 +79,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
// new BasicHeader("Accept-Encoding", "gzip");
|
// new BasicHeader("Accept-Encoding", "gzip");
|
||||||
|
|
||||||
private static final int MAX_TAGS_CACHE = 100;
|
private static final int MAX_TAGS_CACHE = 100;
|
||||||
|
|
||||||
private static Map<String, Tag> tagHash = Collections
|
private static Map<String, Tag> tagHash = Collections
|
||||||
.synchronizedMap(new LinkedHashMap<String, Tag>(
|
.synchronizedMap(new LinkedHashMap<String, Tag>(
|
||||||
MAX_TAGS_CACHE, 0.75f, true) {
|
MAX_TAGS_CACHE, 0.75f, true) {
|
||||||
@ -79,8 +90,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
protected boolean removeEldestEntry(Entry<String, Tag> e) {
|
protected boolean removeEldestEntry(Entry<String, Tag> e) {
|
||||||
if (size() < MAX_TAGS_CACHE)
|
if (size() < MAX_TAGS_CACHE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Log.d(TAG, "cache: drop " + e.getValue());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -92,30 +101,72 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
private int mCurTagCnt;
|
private int mCurTagCnt;
|
||||||
|
|
||||||
private HttpClient mClient;
|
private HttpClient mClient;
|
||||||
|
private HttpGet mRequest = null;
|
||||||
|
|
||||||
private IMapDatabaseCallback mMapGenerator;
|
private IMapDatabaseCallback mMapGenerator;
|
||||||
private float mScaleFactor;
|
private float mScaleFactor;
|
||||||
private HttpGet mRequest = null;
|
|
||||||
private Tile mTile;
|
private Tile mTile;
|
||||||
|
|
||||||
|
private FileOutputStream mCacheFile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||||
mCanceled = false;
|
// mCanceled = false;
|
||||||
|
mCacheFile = null;
|
||||||
|
|
||||||
// just used for debugging ....
|
// just used for debugging ....
|
||||||
mTile = tile;
|
mTile = tile;
|
||||||
|
|
||||||
// Log.d(TAG, "get tile >> : " + tile);
|
// Log.d(TAG, "get tile >> : " + tile);
|
||||||
|
|
||||||
String url = String.format(URL, Integer.valueOf(tile.zoomLevel),
|
|
||||||
Long.valueOf(tile.tileX), Long.valueOf(tile.tileY));
|
|
||||||
|
|
||||||
HttpGet getRequest = new HttpGet(url);
|
|
||||||
|
|
||||||
mRequest = getRequest;
|
|
||||||
mMapGenerator = mapDatabaseCallback;
|
mMapGenerator = mapDatabaseCallback;
|
||||||
mCurTagCnt = 0;
|
mCurTagCnt = 0;
|
||||||
|
|
||||||
mScaleFactor = REF_TILE_SIZE / Tile.TILE_SIZE;
|
mScaleFactor = REF_TILE_SIZE / Tile.TILE_SIZE;
|
||||||
|
File f;
|
||||||
|
|
||||||
|
if (USE_CACHE) {
|
||||||
|
f = new File(cacheDir, String.format(CACHE_FILE,
|
||||||
|
Integer.valueOf(tile.zoomLevel),
|
||||||
|
Long.valueOf(tile.tileX),
|
||||||
|
Long.valueOf(tile.tileY)));
|
||||||
|
|
||||||
|
if (f.exists()) {
|
||||||
|
FileInputStream in;
|
||||||
|
Log.d(TAG, "using cache: " + tile);
|
||||||
|
|
||||||
|
try {
|
||||||
|
in = new FileInputStream(f);
|
||||||
|
decode(in);
|
||||||
|
in.close();
|
||||||
|
return QueryResult.SUCCESS;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = String.format(URL,
|
||||||
|
Integer.valueOf(tile.zoomLevel),
|
||||||
|
Long.valueOf(tile.tileX),
|
||||||
|
Long.valueOf(tile.tileY));
|
||||||
|
|
||||||
|
HttpGet getRequest = new HttpGet(url);
|
||||||
|
mRequest = getRequest;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// HttpURLConnection urlConn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
// // urlConn.setUseCaches(false);
|
||||||
|
//
|
||||||
|
// InputStream in = urlConn.getInputStream();
|
||||||
|
// try {
|
||||||
|
// decode(in);
|
||||||
|
// } finally {
|
||||||
|
// urlConn.disconnect();
|
||||||
|
// }
|
||||||
|
|
||||||
HttpResponse response = mClient.execute(getRequest);
|
HttpResponse response = mClient.execute(getRequest);
|
||||||
final int statusCode = response.getStatusLine().getStatusCode();
|
final int statusCode = response.getStatusLine().getStatusCode();
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
@ -125,10 +176,10 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
entity.consumeContent();
|
entity.consumeContent();
|
||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTile.isCanceled) {
|
if (mTile.isCanceled) {
|
||||||
Log.d(TAG, "1 loading canceled " + mTile);
|
Log.d(TAG, "1 loading canceled " + mTile);
|
||||||
entity.consumeContent();
|
entity.consumeContent();
|
||||||
|
|
||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +187,16 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
// GZIPInputStream zis = null;
|
// GZIPInputStream zis = null;
|
||||||
try {
|
try {
|
||||||
is = entity.getContent();
|
is = entity.getContent();
|
||||||
|
|
||||||
|
if (USE_CACHE) {
|
||||||
|
try {
|
||||||
|
Log.d(TAG, "writing cache: " + tile);
|
||||||
|
mCacheFile = new FileOutputStream(f);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// zis = new GZIPInputStream(is);
|
// zis = new GZIPInputStream(is);
|
||||||
|
|
||||||
decode(is);
|
decode(is);
|
||||||
@ -149,15 +210,22 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
}
|
}
|
||||||
} catch (SocketException ex) {
|
} catch (SocketException ex) {
|
||||||
Log.d(TAG, "Socket exception: " + ex.getMessage());
|
Log.d(TAG, "Socket exception: " + ex.getMessage());
|
||||||
|
// f.delete();
|
||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
} catch (SocketTimeoutException ex) {
|
} catch (SocketTimeoutException ex) {
|
||||||
Log.d(TAG, "Socket Timeout exception: " + ex.getMessage());
|
Log.d(TAG, "Socket Timeout exception: " + ex.getMessage());
|
||||||
|
// f.delete();
|
||||||
|
return QueryResult.FAILED;
|
||||||
|
} catch (UnknownHostException ex) {
|
||||||
|
Log.d(TAG, "no network");
|
||||||
|
// f.delete();
|
||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
getRequest.abort();
|
// f.delete();
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRequest = null;
|
mRequest = null;
|
||||||
|
|
||||||
if (mTile.isCanceled) {
|
if (mTile.isCanceled) {
|
||||||
@ -165,11 +233,21 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
return QueryResult.FAILED;
|
return QueryResult.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log.d(TAG, "get tile << : " + tile);
|
if (USE_CACHE) {
|
||||||
|
try {
|
||||||
|
mCacheFile.flush();
|
||||||
|
mCacheFile.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
mCacheFile = null;
|
||||||
|
}
|
||||||
|
|
||||||
return QueryResult.SUCCESS;
|
return QueryResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static File cacheDir;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMapProjection() {
|
public String getMapProjection() {
|
||||||
return null;
|
return null;
|
||||||
@ -190,11 +268,14 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
HttpParams params = new BasicHttpParams();
|
HttpParams params = new BasicHttpParams();
|
||||||
HttpConnectionParams.setStaleCheckingEnabled(params, false);
|
HttpConnectionParams.setStaleCheckingEnabled(params, false);
|
||||||
|
|
||||||
HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
|
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
|
||||||
HttpConnectionParams.setSoTimeout(params, 60 * 1000);
|
HttpConnectionParams.setSoTimeout(params, 60 * 1000);
|
||||||
HttpConnectionParams.setSocketBufferSize(params, 16384);
|
HttpConnectionParams.setSocketBufferSize(params, 32768);
|
||||||
mClient = new DefaultHttpClient(params);
|
|
||||||
HttpClientParams.setRedirecting(params, false);
|
HttpClientParams.setRedirecting(params, false);
|
||||||
|
// HttpClientParams.setCookiePolicy(params, CookiePolicy.ACCEPT_NONE);
|
||||||
|
|
||||||
|
mClient = new DefaultHttpClient(params);
|
||||||
|
|
||||||
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
||||||
schemeRegistry.register(new Scheme("http",
|
schemeRegistry.register(new Scheme("http",
|
||||||
PlainSocketFactory.getSocketFactory(), 80));
|
PlainSocketFactory.getSocketFactory(), 80));
|
||||||
@ -202,16 +283,33 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileOpenResult openFile(File mapFile) {
|
public FileOpenResult openFile(File mapFile) {
|
||||||
|
|
||||||
createClient();
|
createClient();
|
||||||
|
|
||||||
|
if (USE_CACHE) {
|
||||||
|
if (cacheDir == null) {
|
||||||
|
// cacheDir = mapFile;
|
||||||
|
|
||||||
|
String externalStorageDirectory = Environment
|
||||||
|
.getExternalStorageDirectory()
|
||||||
|
.getAbsolutePath();
|
||||||
|
String cacheDirectoryPath = externalStorageDirectory + CACHE_DIRECTORY;
|
||||||
|
cacheDir = createDirectory(cacheDirectoryPath);
|
||||||
|
|
||||||
|
Log.d(TAG, "cache dir: " + cacheDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new FileOpenResult();
|
return new FileOpenResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeFile() {
|
public void closeFile() {
|
||||||
mOpenFile = false;
|
mOpenFile = false;
|
||||||
if (mClient != null)
|
if (mClient != null) {
|
||||||
mClient.getConnectionManager().shutdown();
|
mClient.getConnectionManager().shutdown();
|
||||||
|
mClient = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -219,12 +317,31 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static File createDirectory(String pathName) {
|
||||||
|
File file = new File(pathName);
|
||||||
|
if (!file.exists() && !file.mkdirs()) {
|
||||||
|
throw new IllegalArgumentException("could not create directory: " + file);
|
||||||
|
} else if (!file.isDirectory()) {
|
||||||
|
throw new IllegalArgumentException("not a directory: " + file);
|
||||||
|
} else if (!file.canRead()) {
|
||||||
|
throw new IllegalArgumentException("cannot read directory: " + file);
|
||||||
|
} else if (!file.canWrite()) {
|
||||||
|
throw new IllegalArgumentException("cannot write directory: " + file);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
// // // hand sewed tile protocol buffers decoder // // //
|
// // // hand sewed tile protocol buffers decoder // // //
|
||||||
private static final int BUFFER_SIZE = 65536;
|
private static final int BUFFER_SIZE = 65536;
|
||||||
|
|
||||||
private final byte[] buffer = new byte[BUFFER_SIZE];
|
private final byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
// position in read buffer
|
||||||
private int bufferPos;
|
private int bufferPos;
|
||||||
|
// bytes available in read buffer
|
||||||
private int bufferSize;
|
private int bufferSize;
|
||||||
|
// (bytesRead - bufferPos) + bufferSize
|
||||||
|
// private int bufferLimit;
|
||||||
|
// bytes processed
|
||||||
private int bytesRead;
|
private int bytesRead;
|
||||||
private InputStream inputStream;
|
private InputStream inputStream;
|
||||||
|
|
||||||
@ -256,8 +373,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
while ((val = decodeVarint32()) > 0) {
|
while ((val = decodeVarint32()) > 0) {
|
||||||
// read tag and wire type
|
// read tag and wire type
|
||||||
int tag = (val >> 3);
|
int tag = (val >> 3);
|
||||||
// int wireType = (val & 7);
|
|
||||||
// Log.d(TAG, "tile " + tag + " " + wireType);
|
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case TAG_TILE_TAGS:
|
case TAG_TILE_TAGS:
|
||||||
@ -286,7 +401,13 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
private boolean decodeTileTags() throws IOException {
|
private boolean decodeTileTags() throws IOException {
|
||||||
String tagString = decodeString();
|
String tagString = decodeString();
|
||||||
|
// Log.d(TAG, "tag>" + tagString + "<");
|
||||||
|
|
||||||
|
if (tagString == null || tagString.length() == 0) {
|
||||||
|
|
||||||
|
curTags[mCurTagCnt++] = new Tag(Tag.TAG_KEY_NAME, "...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Tag tag = tagHash.get(tagString);
|
Tag tag = tagHash.get(tagString);
|
||||||
|
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
@ -298,7 +419,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tagHash.put(tagString, tag);
|
tagHash.put(tagString, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME ...
|
|
||||||
if (mCurTagCnt >= MAX_TILE_TAGS) {
|
if (mCurTagCnt >= MAX_TILE_TAGS) {
|
||||||
MAX_TILE_TAGS = mCurTagCnt + 10;
|
MAX_TILE_TAGS = mCurTagCnt + 10;
|
||||||
Tag[] tmp = new Tag[MAX_TILE_TAGS];
|
Tag[] tmp = new Tag[MAX_TILE_TAGS];
|
||||||
@ -331,9 +451,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
int tag = (val >> 3);
|
int tag = (val >> 3);
|
||||||
// int wireType = val & 7;
|
|
||||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case TAG_WAY_TAGS:
|
case TAG_WAY_TAGS:
|
||||||
@ -345,9 +462,9 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_WAY_COORDS:
|
case TAG_WAY_COORDS:
|
||||||
cnt = decodeWayCoordinates(skip);
|
int cnt = decodeWayCoordinates(skip);
|
||||||
if (cnt != coordCnt) {
|
if (cnt != coordCnt) {
|
||||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
Log.d(TAG, "X wrong number of coordintes");
|
||||||
fail = true;
|
fail = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -369,20 +486,20 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "invalid type for way: " + tag);
|
Log.d(TAG, "X invalid type for way: " + tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fail || index == null || tags == null || indexCnt == 0 || tagCnt == 0) {
|
if (fail || index == null || tags == null || indexCnt == 0 || tagCnt == 0) {
|
||||||
Log.d(TAG, "..." + index + " " + (tags != null ? tags[0] : "...") + " "
|
Log.d(TAG, "failed reading way: bytes:" + bytes + " index:" + index + " tag:"
|
||||||
+ indexCnt + " " + coordCnt + " "
|
+ (tags != null ? tags[0] : "...") + " "
|
||||||
+ tagCnt);
|
+ indexCnt + " " + coordCnt + " " + tagCnt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] coords = tmpCoords;
|
float[] coords = tmpCoords;
|
||||||
|
|
||||||
// FIXME !!!!!
|
// FIXME, remove all tiles from cache then remove this below
|
||||||
if (layer == 0)
|
if (layer == 0)
|
||||||
layer = 5;
|
layer = 5;
|
||||||
|
|
||||||
@ -393,8 +510,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
private boolean decodeTileNodes() throws IOException {
|
private boolean decodeTileNodes() throws IOException {
|
||||||
int bytes = decodeVarint32();
|
int bytes = decodeVarint32();
|
||||||
|
|
||||||
// Log.d(TAG, "decode nodes " + bytes);
|
|
||||||
|
|
||||||
int end = bytesRead + bytes;
|
int end = bytesRead + bytes;
|
||||||
int tagCnt = 0;
|
int tagCnt = 0;
|
||||||
int coordCnt = 0;
|
int coordCnt = 0;
|
||||||
@ -408,9 +523,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
int tag = (val >> 3);
|
int tag = (val >> 3);
|
||||||
// int wireType = val & 7;
|
|
||||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case TAG_NODE_TAGS:
|
case TAG_NODE_TAGS:
|
||||||
@ -418,9 +530,9 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_NODE_COORDS:
|
case TAG_NODE_COORDS:
|
||||||
cnt = decodeNodeCoordinates(coordCnt, layer, tags);
|
int cnt = decodeNodeCoordinates(coordCnt, layer, tags);
|
||||||
if (cnt != coordCnt) {
|
if (cnt != coordCnt) {
|
||||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
Log.d(TAG, "X wrong number of coordintes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -438,7 +550,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "invalid type for node: " + tag);
|
Log.d(TAG, "X invalid type for node: " + tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,15 +569,13 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
int lastX = 0;
|
int lastX = 0;
|
||||||
int lastY = 0;
|
int lastY = 0;
|
||||||
while (bufferPos < end && cnt < numNodes) {
|
while (bufferPos < end && cnt < numNodes) {
|
||||||
int lon = decodeZigZag32(decodeVarint32()); // * mScaleFactor;
|
int lon = decodeZigZag32(decodeVarint32());
|
||||||
int lat = decodeZigZag32(decodeVarint32()); // * mScaleFactor;
|
int lat = decodeZigZag32(decodeVarint32());
|
||||||
lastX = lon + lastX;
|
lastX = lon + lastX;
|
||||||
lastY = lat + lastY;
|
lastY = lat + lastY;
|
||||||
|
|
||||||
mMapGenerator.renderPointOfInterest(layer,
|
mMapGenerator.renderPointOfInterest(layer,
|
||||||
lastY / scale,
|
lastY / scale, lastX / scale, tags);
|
||||||
lastX / scale,
|
|
||||||
tags);
|
|
||||||
cnt += 2;
|
cnt += 2;
|
||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
@ -500,8 +610,8 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
|
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
|
||||||
tags[cnt++] = curTags[tagNum];
|
tags[cnt++] = curTags[tagNum];
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "NULL TAG: " + mTile + " could find tag:" + tagNum + " "
|
Log.d(TAG, "NULL TAG: " + mTile + " could find tag:"
|
||||||
+ tagCnt + "/" + cnt);
|
+ tagNum + " " + tagCnt + "/" + cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,41 +683,38 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
if (buf[pos] >= 0) {
|
if (buf[pos] >= 0) {
|
||||||
result = buf[pos++];
|
result = buf[pos++];
|
||||||
} else if (buf[pos + 1] >= 0) {
|
} else if (buf[pos + 1] >= 0) {
|
||||||
result = buf[pos] & 0x7f
|
result = (buf[pos] & 0x7f)
|
||||||
| buf[pos + 1] << 7;
|
| buf[pos + 1] << 7;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
} else if (buf[pos + 2] >= 0) {
|
} else if (buf[pos + 2] >= 0) {
|
||||||
result = buf[pos] & 0x7f
|
result = (buf[pos] & 0x7f)
|
||||||
| buf[pos + 1] << 7
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
| buf[pos + 2] << 14;
|
| (buf[pos + 2]) << 14;
|
||||||
pos += 3;
|
pos += 3;
|
||||||
} else if (buf[pos + 3] >= 0) {
|
} else if (buf[pos + 3] >= 0) {
|
||||||
result = buf[pos] & 0x7f
|
result = (buf[pos] & 0x7f)
|
||||||
| buf[pos + 1] << 7
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
| buf[pos + 2] << 14
|
| (buf[pos + 2] & 0x7f) << 14
|
||||||
| buf[pos + 3] << 21;
|
| (buf[pos + 3]) << 21;
|
||||||
pos += 4;
|
pos += 4;
|
||||||
Log.d(TAG, "4 Stuffs too large " + mTile);
|
|
||||||
} else {
|
} else {
|
||||||
result = buf[pos] & 0x7f
|
result = (buf[pos] & 0x7f)
|
||||||
| buf[pos + 1] << 7
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
| buf[pos + 2] << 14
|
| (buf[pos + 2] & 0x7f) << 14
|
||||||
| buf[pos + 3] << 21
|
| (buf[pos + 3] & 0x7f) << 21
|
||||||
| buf[pos + 4] << 28;
|
| (buf[pos + 4]) << 28;
|
||||||
pos += 5;
|
|
||||||
|
|
||||||
Log.d(TAG, "5 Stuffs too large " + mTile);
|
Log.d(TAG, "Stuffs too large " + mTile);
|
||||||
|
|
||||||
|
pos += 4;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (buf[pos++] < 0 && i < 10)
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i == 10)
|
||||||
|
throw new IOException("X malformed VarInt32");
|
||||||
|
|
||||||
if (buf[pos + 4] < 0) {
|
|
||||||
Log.d(TAG, "Stuffs too large ...");
|
|
||||||
int i = 0;
|
|
||||||
while (i++ < 5) {
|
|
||||||
if (buf[pos++] >= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == 5)
|
|
||||||
throw new IOException("EEEK malformed varInt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (even) {
|
if (even) {
|
||||||
x = ((result >>> 1) ^ -(result & 1));
|
x = ((result >>> 1) ^ -(result & 1));
|
||||||
@ -628,70 +735,120 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readBuffer() throws IOException {
|
private int readBuffer(int size) throws IOException {
|
||||||
|
int read = 0;
|
||||||
|
|
||||||
int len = inputStream.read(buffer, 0, BUFFER_SIZE);
|
if (bufferPos + size < bufferSize)
|
||||||
if (len < 0) {
|
return 0;
|
||||||
buffer[bufferPos] = 0;
|
|
||||||
// Log.d(TAG, " nothing to read... pos " + bufferPos + ", size "
|
|
||||||
// + bufferSize + ", read " + bytesRead);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bufferSize = len;
|
|
||||||
bufferPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readBuffer(int size) throws IOException {
|
|
||||||
if (size < (bufferSize - bufferPos))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (size > BUFFER_SIZE) {
|
if (size > BUFFER_SIZE) {
|
||||||
// FIXME throw exception for now, but frankly better
|
// FIXME throw exception for now, but frankly better
|
||||||
// sanitize tile data on compilation.
|
// sanitize tile data on compilation.
|
||||||
// this only happen with strings or coordinates larger than 64kb
|
// this only happen with strings or coordinates larger than 64kb
|
||||||
throw new IOException("EEEK requested size too large");
|
throw new IOException("X requested size too large");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size - bufferSize) + bufferPos > BUFFER_SIZE) {
|
if (bufferSize == bufferPos) {
|
||||||
// copy bytes left to read from buffer to the beginning of buffer
|
bufferPos = 0;
|
||||||
System.arraycopy(buffer, bufferPos, buffer, 0, bufferSize - bufferPos);
|
bufferSize = 0;
|
||||||
|
} else if (bufferPos + (size - bufferSize) > BUFFER_SIZE) {
|
||||||
|
Log.d(TAG, "wrap buffer" + (size - bufferSize) + " " + bufferPos);
|
||||||
|
// copy bytes left to read to the beginning of buffer
|
||||||
|
bufferSize -= bufferPos;
|
||||||
|
System.arraycopy(buffer, bufferPos, buffer, 0, bufferSize);
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((bufferSize - bufferPos) < size) {
|
while ((bufferSize - bufferPos) < size) {
|
||||||
if (mTile.isCanceled) {
|
|
||||||
throw new IOException("canceled " + mTile);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read until requested size is available in buffer
|
// read until requested size is available in buffer
|
||||||
int len = inputStream.read(buffer, bufferSize, BUFFER_SIZE - bufferSize);
|
int len = inputStream.read(buffer, bufferSize, BUFFER_SIZE - bufferSize);
|
||||||
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
buffer[bufferSize - 1] = 0; // FIXME is this needed?
|
// finished reading, mark end
|
||||||
|
buffer[bufferSize] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read += len;
|
||||||
|
|
||||||
|
if (mCacheFile != null)
|
||||||
|
mCacheFile.write(buffer, bufferSize, len);
|
||||||
|
|
||||||
bufferSize += len;
|
bufferSize += len;
|
||||||
|
|
||||||
if (mCanceled)
|
|
||||||
throw new IOException("... canceld?");
|
|
||||||
}
|
}
|
||||||
|
return read;
|
||||||
// Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
|
|
||||||
// + bufferSize
|
|
||||||
// + ", read " + bytesRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mCanceled;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
mCanceled = true;
|
|
||||||
if (mRequest != null) {
|
if (mRequest != null) {
|
||||||
mRequest.abort();
|
mRequest.abort();
|
||||||
mRequest = null;
|
mRequest = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int decodeVarint32() throws IOException {
|
||||||
|
int pos = bufferPos;
|
||||||
|
|
||||||
|
if (pos + 10 > bufferSize) {
|
||||||
|
readBuffer(8192);
|
||||||
|
pos = bufferPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] buf = buffer;
|
||||||
|
|
||||||
|
if (buf[pos] >= 0) {
|
||||||
|
bufferPos += 1;
|
||||||
|
bytesRead += 1;
|
||||||
|
return buf[pos];
|
||||||
|
} else if (buf[pos + 1] >= 0) {
|
||||||
|
bufferPos += 2;
|
||||||
|
bytesRead += 2;
|
||||||
|
return (buf[pos] & 0x7f)
|
||||||
|
| (buf[pos + 1]) << 7;
|
||||||
|
|
||||||
|
} else if (buf[pos + 2] >= 0) {
|
||||||
|
bufferPos += 3;
|
||||||
|
bytesRead += 3;
|
||||||
|
return (buf[pos] & 0x7f)
|
||||||
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
|
| (buf[pos + 2]) << 14;
|
||||||
|
} else if (buf[pos + 3] >= 0) {
|
||||||
|
bufferPos += 4;
|
||||||
|
bytesRead += 4;
|
||||||
|
return (buf[pos] & 0x7f)
|
||||||
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
|
| (buf[pos + 2] & 0x7f) << 14
|
||||||
|
| (buf[pos + 3]) << 21;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = (buf[pos] & 0x7f)
|
||||||
|
| (buf[pos + 1] & 0x7f) << 7
|
||||||
|
| (buf[pos + 2] & 0x7f) << 14
|
||||||
|
| (buf[pos + 3] & 0x7f) << 21
|
||||||
|
| (buf[pos + 4]) << 28;
|
||||||
|
|
||||||
|
Log.d(TAG, "got a big number, eh?");
|
||||||
|
|
||||||
|
int read = 5;
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
|
// 'Discard upper 32 bits' - the original comment.
|
||||||
|
// havent found this in any document but the code provided by google.
|
||||||
|
// no idea what this is for, just seems fsckin stupid...
|
||||||
|
while (buf[pos++] < 0 && read < 10)
|
||||||
|
read++;
|
||||||
|
|
||||||
|
if (read == 10)
|
||||||
|
throw new IOException("X malformed VarInt32");
|
||||||
|
|
||||||
|
bufferPos += read;
|
||||||
|
bytesRead += read;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* All code below is taken from or based on Google's Protocol Buffers implementation: */
|
/* All code below is taken from or based on Google's Protocol Buffers implementation: */
|
||||||
|
|
||||||
// Protocol Buffers - Google's data interchange format
|
// Protocol Buffers - Google's data interchange format
|
||||||
@ -724,61 +881,21 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
private byte readRawByte() throws IOException {
|
|
||||||
if (bufferPos == bufferSize) {
|
|
||||||
readBuffer();
|
|
||||||
}
|
|
||||||
bytesRead++;
|
|
||||||
return buffer[bufferPos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decodeVarint32() throws IOException {
|
|
||||||
byte tmp = readRawByte();
|
|
||||||
if (tmp >= 0) {
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
int result = tmp & 0x7f;
|
|
||||||
if ((tmp = readRawByte()) >= 0) {
|
|
||||||
return result | tmp << 7;
|
|
||||||
}
|
|
||||||
result |= (tmp & 0x7f) << 7;
|
|
||||||
if ((tmp = readRawByte()) >= 0) {
|
|
||||||
return result | tmp << 14;
|
|
||||||
}
|
|
||||||
result |= (tmp & 0x7f) << 14;
|
|
||||||
if ((tmp = readRawByte()) >= 0) {
|
|
||||||
return result | tmp << 21;
|
|
||||||
}
|
|
||||||
result |= (tmp & 0x7f) << 21;
|
|
||||||
result |= (tmp = readRawByte()) << 28;
|
|
||||||
|
|
||||||
if (tmp < 0) {
|
|
||||||
// Discard upper 32 bits.
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
if (readRawByte() >= 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.d(TAG, "EEK malformedVarint");
|
|
||||||
// FIXME throw some poo
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String decodeString() throws IOException {
|
private String decodeString() throws IOException {
|
||||||
final int size = decodeVarint32();
|
final int size = decodeVarint32();
|
||||||
|
|
||||||
readBuffer(size);
|
readBuffer(size);
|
||||||
|
|
||||||
final String result = new String(buffer, bufferPos, size, "UTF-8");
|
final String result = new String(buffer, bufferPos, size, "UTF-8");
|
||||||
|
// Log.d(TAG, "read string " + read + " " + size + " " + bufferPos + " " + result);
|
||||||
|
|
||||||
bufferPos += size;
|
bufferPos += size;
|
||||||
bytesRead += size;
|
bytesRead += size;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int decodeZigZag32(final int n) {
|
private static int decodeZigZag32(final int n) {
|
||||||
return (n >>> 1) ^ -(n & 1);
|
return (n >>> 1) ^ -(n & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user