- 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 android:name=".preferences.EditPreferences" />
|
||||
<activity android:name=".filepicker.FilePicker" />
|
||||
<activity android:name=".InfoView" android:theme="@android:style/Theme.NoTitleBar" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -6,9 +6,10 @@
|
||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||
</head>
|
||||
<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>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>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>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 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> <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> This software is based on <a href="https://code.google.com/p/mapsforge">mapsforge</a> library 0.2.4.</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>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB |
@ -11,17 +11,17 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
<ToggleButton
|
||||
<!-- <ToggleButton
|
||||
android:id="@+id/snapToLocationView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_marginTop="10dip"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:background="@drawable/snap_to_position"
|
||||
android:textOff=""
|
||||
android:textOn=""
|
||||
android:visibility="gone" />
|
||||
android:visibility="gone" />-->
|
||||
|
||||
</RelativeLayout>
|
||||
@ -47,6 +47,9 @@
|
||||
<item
|
||||
android:id="@+id/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
|
||||
android:id="@+id/menu_render_theme_select_file"
|
||||
android:title="@string/menu_render_theme_select_file"/>
|
||||
@ -58,9 +61,9 @@
|
||||
|
||||
android:showAsAction="never"
|
||||
android:title="@string/menu_mapfile"/>
|
||||
<!-- <item
|
||||
android:id="@+id/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>
|
||||
|
||||
</item>
|
||||
|
||||
@ -48,6 +48,9 @@
|
||||
<!-- <item
|
||||
android:id="@+id/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>
|
||||
|
||||
</item>
|
||||
@ -61,6 +64,9 @@
|
||||
<item
|
||||
android:id="@+id/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
|
||||
android:id="@+id/menu_render_theme_select_file"
|
||||
android:title="@string/menu_render_theme_select_file"/>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string-array name="preferences_map_generator_values">
|
||||
<!-- <string-array name="preferences_map_generator_values">
|
||||
<item>Mapfile</item>
|
||||
<item>PostGIS</item>
|
||||
<item>OpenScienceMap</item>
|
||||
</string-array>
|
||||
</string-array> -->
|
||||
|
||||
<string-array name="preferences_scale_bar_unit_values">
|
||||
<item>angloamerikanisch</item>
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<item>hyvin pieni</item>
|
||||
<item>pieni</item>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string-array name="preferences_map_generator_values">
|
||||
<!-- <string-array name="preferences_map_generator_values">
|
||||
<item>Mapfile</item>
|
||||
<item>PostGIS</item>
|
||||
<item>OpenScienceMap</item>
|
||||
</string-array>
|
||||
</string-array> -->
|
||||
|
||||
<string-array name="preferences_text_scale_values">
|
||||
<item>minuscola</item>
|
||||
|
||||
@ -1,31 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<item>imperial</item>
|
||||
<item>metric</item>
|
||||
</string-array>
|
||||
<string name="preferences_scale_bar_unit_default">metric</string>
|
||||
<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">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>
|
||||
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string-array name="preferences_map_generator_values">
|
||||
<item>Mapfile</item>
|
||||
<item>PostGIS</item>
|
||||
<!-- <item>Mapfile</item> -->
|
||||
<item>PostGIS</item>
|
||||
<item>OpenScienceMap</item>
|
||||
</string-array>
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
<string name="menu_preferences">Preferences</string>
|
||||
<string name="menu_render_theme">Render 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_screenshot">Screenshot</string>
|
||||
<string name="menu_screenshot_jpeg">JPEG (lossy)</string>
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
|
||||
<style name="MyActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
|
||||
<item name="android:background">@drawable/action_bar</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.TileMap" parent="android:style/Theme.Holo">
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
package org.mapsforge.android;
|
||||
|
||||
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 android.opengl.GLSurfaceView;
|
||||
@ -26,11 +26,11 @@ import android.opengl.GLSurfaceView;
|
||||
public interface IMapRenderer extends GLSurfaceView.Renderer {
|
||||
|
||||
/**
|
||||
* @param mapGeneratorJob
|
||||
* @param tile
|
||||
* the mapGeneratorJob holding Tile data
|
||||
* @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
|
||||
|
||||
@ -96,7 +96,7 @@ public abstract class MapActivity extends Activity {
|
||||
// save the map position and zoom level
|
||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||
if (mapPosition != null) {
|
||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
||||
GeoPoint geoPoint = new GeoPoint(mapPosition.lat, mapPosition.lon);
|
||||
editor.putInt(KEY_LATITUDE, geoPoint.latitudeE6);
|
||||
editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
|
||||
editor.putInt(KEY_ZOOM_LEVEL, mapPosition.zoomLevel);
|
||||
|
||||
@ -65,9 +65,12 @@ public class MapScaleBar {
|
||||
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_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private static final int[] SCALE_BAR_VALUES_IMPERIAL = { 26400000, 10560000, 5280000, 2640000, 1056000, 528000,
|
||||
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,
|
||||
private static final int[] SCALE_BAR_VALUES_IMPERIAL = { 26400000, 10560000, 5280000,
|
||||
2640000, 1056000, 528000,
|
||||
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 };
|
||||
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);
|
||||
@ -101,7 +104,8 @@ public class MapScaleBar {
|
||||
|
||||
MapScaleBar(MapView 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);
|
||||
mTextFields = new HashMap<TextField, String>();
|
||||
setDefaultTexts();
|
||||
@ -173,8 +177,8 @@ public class MapScaleBar {
|
||||
return true;
|
||||
}
|
||||
|
||||
double latitudeDiff = Math.abs(currentMapPosition.geoPoint.getLatitude()
|
||||
- mMapPosition.geoPoint.getLatitude());
|
||||
double latitudeDiff = Math.abs(currentMapPosition.lat
|
||||
- mMapPosition.lat);
|
||||
if (latitudeDiff > LATITUDE_REDRAW_THRESHOLD) {
|
||||
return true;
|
||||
}
|
||||
@ -245,7 +249,8 @@ public class MapScaleBar {
|
||||
}
|
||||
|
||||
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
||||
double groundResolution = MercatorProjection.calculateGroundResolution(mMapPosition.geoPoint.getLatitude(),
|
||||
double groundResolution = MercatorProjection.calculateGroundResolution(
|
||||
mMapPosition.lat,
|
||||
mMapPosition.zoomLevel);
|
||||
|
||||
int[] scaleBarValues;
|
||||
|
||||
@ -24,13 +24,12 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.mapsforge.android.input.TouchHandler;
|
||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
||||
import org.mapsforge.android.mapgenerator.JobQueue;
|
||||
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
||||
import org.mapsforge.android.mapgenerator.MapDatabases;
|
||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||
import org.mapsforge.android.mapgenerator.MapRendererFactory;
|
||||
import org.mapsforge.android.mapgenerator.MapRenderers;
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.android.mapgenerator.MapWorker;
|
||||
import org.mapsforge.android.mapgenerator.Theme;
|
||||
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 final MapController mMapController;
|
||||
// private final MapMover mMapMover;
|
||||
// private final ZoomAnimator mZoomAnimator;
|
||||
// private final MapScaleBar mMapScaleBar;
|
||||
private final MapViewPosition mMapViewPosition;
|
||||
|
||||
private final MapZoomControls mMapZoomControls;
|
||||
@ -95,10 +91,11 @@ public class MapView extends GLSurfaceView {
|
||||
private JobQueue mJobQueue;
|
||||
private MapWorker mMapWorkers[];
|
||||
private int mNumMapWorkers = 4;
|
||||
private JobParameters mJobParameters;
|
||||
public DebugSettings debugSettings;
|
||||
private DebugSettings debugSettings;
|
||||
private String mMapFile;
|
||||
|
||||
private File cacheDir;
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* the enclosing MapActivity instance.
|
||||
@ -139,30 +136,25 @@ public class MapView extends GLSurfaceView {
|
||||
// TODO make this dpi dependent
|
||||
Tile.TILE_SIZE = 400;
|
||||
|
||||
// setWillNotDraw(true);
|
||||
// setWillNotCacheDrawing(true);
|
||||
|
||||
MapActivity mapActivity = (MapActivity) context;
|
||||
|
||||
cacheDir = context.getFilesDir();
|
||||
|
||||
debugSettings = new DebugSettings(false, false, false, false);
|
||||
|
||||
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
|
||||
mMapController = new MapController(this);
|
||||
|
||||
mMapDatabaseType = mapDatabaseType;
|
||||
|
||||
mMapViewPosition = new MapViewPosition(this);
|
||||
// mMapScaleBar = new MapScaleBar(this);
|
||||
|
||||
mMapZoomControls = new MapZoomControls(mapActivity, this);
|
||||
|
||||
mProjection = new MapViewProjection(this);
|
||||
|
||||
mTouchEventHandler = new TouchHandler(mapActivity, this);
|
||||
|
||||
mJobQueue = new JobQueue(this);
|
||||
|
||||
// mMapMover = new MapMover(this);
|
||||
// mMapMover.start();
|
||||
// mZoomAnimator = new ZoomAnimator(this);
|
||||
// mZoomAnimator.start();
|
||||
mJobQueue = new JobQueue();
|
||||
|
||||
mMapRenderer = MapRendererFactory.createMapRenderer(this, mapGeneratorType);
|
||||
mMapWorkers = new MapWorker[mNumMapWorkers];
|
||||
@ -172,7 +164,6 @@ public class MapView extends GLSurfaceView {
|
||||
if (mDebugDatabase) {
|
||||
mapDatabase = MapDatabaseFactory
|
||||
.createMapDatabase(MapDatabases.JSON_READER);
|
||||
|
||||
} else {
|
||||
mapDatabase = MapDatabaseFactory.createMapDatabase(mapDatabaseType);
|
||||
}
|
||||
@ -180,16 +171,18 @@ public class MapView extends GLSurfaceView {
|
||||
IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
|
||||
mapGenerator.setMapDatabase(mapDatabase);
|
||||
|
||||
if (i == 0) {
|
||||
if (i == 0)
|
||||
mMapDatabase = mapDatabase;
|
||||
initMapStartPosition();
|
||||
}
|
||||
|
||||
mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
|
||||
mMapWorkers[i].start();
|
||||
}
|
||||
|
||||
if (!setRenderTheme(InternalRenderTheme.OSMARENDER)) {
|
||||
Log.d(TAG, "EEEK could parse theme");
|
||||
setMapFile("default");
|
||||
initMapStartPosition();
|
||||
|
||||
if (!setRenderTheme(DEFAULT_RENDER_THEME)) {
|
||||
Log.d(TAG, "X could not parse theme");
|
||||
// FIXME show init error dialog
|
||||
}
|
||||
|
||||
@ -197,11 +190,15 @@ public class MapView extends GLSurfaceView {
|
||||
setEGLContextClientVersion(2);
|
||||
|
||||
setRenderer(mMapRenderer);
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
|
||||
if (!debugFrameTime)
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
|
||||
mapActivity.registerMapView(this);
|
||||
}
|
||||
|
||||
public final static boolean debugFrameTime = false;
|
||||
|
||||
private void initMapStartPosition() {
|
||||
GeoPoint startPoint = getStartPoint();
|
||||
if (startPoint != null) {
|
||||
@ -212,7 +209,6 @@ public class MapView extends GLSurfaceView {
|
||||
if (startZoomLevel != null) {
|
||||
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,13 +246,6 @@ public class MapView extends GLSurfaceView {
|
||||
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.
|
||||
*/
|
||||
@ -264,20 +253,6 @@ public class MapView extends GLSurfaceView {
|
||||
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.
|
||||
*/
|
||||
@ -285,33 +260,11 @@ public class MapView extends GLSurfaceView {
|
||||
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
|
||||
public boolean onTouchEvent(MotionEvent motionEvent) {
|
||||
return mTouchEventHandler.handleMotionEvent(motionEvent);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean onTrackballEvent(MotionEvent motionEvent) {
|
||||
// return mMapMover.onTrackballEvent(motionEvent);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Calculates all necessary tiles and adds jobs accordingly.
|
||||
*/
|
||||
@ -372,21 +325,13 @@ public class MapView extends GLSurfaceView {
|
||||
public boolean setMapFile(String mapFile) {
|
||||
FileOpenResult fileOpenResult = null;
|
||||
|
||||
Log.d(TAG, "set mapfile " + mapFile);
|
||||
Log.i(TAG, "set mapfile " + mapFile);
|
||||
|
||||
if (mapFile != null && mapFile.equals(mMapFile)) {
|
||||
// same map file as before
|
||||
return false;
|
||||
}
|
||||
|
||||
// mZoomAnimator.pause();
|
||||
// mMapMover.pause();
|
||||
// mZoomAnimator.awaitPausing();
|
||||
// mMapMover.awaitPausing();
|
||||
// mZoomAnimator.proceed();
|
||||
// mMapMover.stopMove();
|
||||
// mMapMover.proceed();
|
||||
|
||||
boolean initialized = false;
|
||||
|
||||
mJobQueue.clear();
|
||||
@ -403,7 +348,7 @@ public class MapView extends GLSurfaceView {
|
||||
if (mapFile != null)
|
||||
fileOpenResult = mapDatabase.openFile(new File(mapFile));
|
||||
else
|
||||
fileOpenResult = mapDatabase.openFile(null);
|
||||
fileOpenResult = mapDatabase.openFile(cacheDir);
|
||||
|
||||
if (fileOpenResult != null && fileOpenResult.isSuccess()) {
|
||||
mMapFile = mapFile;
|
||||
@ -417,12 +362,12 @@ public class MapView extends GLSurfaceView {
|
||||
|
||||
if (initialized) {
|
||||
clearAndRedrawMapView();
|
||||
Log.d(TAG, "mapfile set");
|
||||
Log.i(TAG, "mapfile set");
|
||||
return true;
|
||||
}
|
||||
|
||||
mMapFile = null;
|
||||
Log.d(TAG, "loading mapfile failed");
|
||||
Log.i(TAG, "loading mapfile failed");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -430,6 +375,7 @@ public class MapView extends GLSurfaceView {
|
||||
private GeoPoint getStartPoint() {
|
||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||
|
||||
if (mapFileInfo.startPosition != null) {
|
||||
return mapFileInfo.startPosition;
|
||||
} else if (mapFileInfo.mapCenter != null) {
|
||||
@ -443,6 +389,7 @@ public class MapView extends GLSurfaceView {
|
||||
private Byte getStartZoomLevel() {
|
||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||
|
||||
if (mapFileInfo.startZoomLevel != null) {
|
||||
return mapFileInfo.startZoomLevel;
|
||||
}
|
||||
@ -464,7 +411,7 @@ public class MapView extends GLSurfaceView {
|
||||
|
||||
IMapGenerator mapGenerator;
|
||||
|
||||
Log.d(TAG, "setMapDatabase " + mapDatabaseType.name());
|
||||
Log.i(TAG, "setMapDatabase " + mapDatabaseType.name());
|
||||
|
||||
if (mMapDatabaseType == mapDatabaseType)
|
||||
return;
|
||||
@ -487,8 +434,6 @@ public class MapView extends GLSurfaceView {
|
||||
setMapFile(mapFile);
|
||||
|
||||
mapWorkersProceed();
|
||||
|
||||
Log.d(TAG, ">>>");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -568,10 +513,10 @@ public class MapView extends GLSurfaceView {
|
||||
* @param textScale
|
||||
* the new text scale for the map rendering.
|
||||
*/
|
||||
public void setTextScale(float textScale) {
|
||||
mJobParameters = new JobParameters(mJobParameters.theme, textScale);
|
||||
clearAndRedrawMapView();
|
||||
}
|
||||
// public void setTextScale(float textScale) {
|
||||
// mJobParameters = new JobParameters(mJobParameters.theme, textScale);
|
||||
// clearAndRedrawMapView();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Zooms in or out by the given amount of zoom levels.
|
||||
@ -603,32 +548,10 @@ public class MapView extends GLSurfaceView {
|
||||
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
|
||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
||||
int oldHeight) {
|
||||
|
||||
mJobQueue.clear();
|
||||
|
||||
mapWorkersPause(true);
|
||||
@ -639,9 +562,6 @@ public class MapView extends GLSurfaceView {
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
// mMapMover.interrupt();
|
||||
// mZoomAnimator.interrupt();
|
||||
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
mapWorker.pause();
|
||||
mapWorker.interrupt();
|
||||
@ -655,9 +575,6 @@ public class MapView extends GLSurfaceView {
|
||||
IMapDatabase mapDatabase = mapWorker.getMapGenerator().getMapDatabase();
|
||||
mapDatabase.closeFile();
|
||||
}
|
||||
|
||||
// mMapScaleBar.destroy();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -693,18 +610,12 @@ public class MapView extends GLSurfaceView {
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapWorkersPause(false);
|
||||
|
||||
// mMapMover.pause();
|
||||
// mZoomAnimator.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapWorkersProceed();
|
||||
|
||||
// mMapMover.proceed();
|
||||
// mZoomAnimator.proceed();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -715,34 +626,7 @@ public class MapView extends GLSurfaceView {
|
||||
*/
|
||||
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);
|
||||
// mapZoomControls.onZoomLevelChange(mapViewPosition.getZoomLevel());
|
||||
redrawTiles();
|
||||
}
|
||||
|
||||
@ -753,20 +637,17 @@ public class MapView extends GLSurfaceView {
|
||||
return mMapViewPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current JobParameters
|
||||
*/
|
||||
public JobParameters getJobParameters() {
|
||||
return mJobParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* add jobs and remember MapWorkers that stuff needs to be done
|
||||
*
|
||||
* @param jobs
|
||||
* tile jobs
|
||||
*/
|
||||
public void addJobs(ArrayList<MapGeneratorJob> jobs) {
|
||||
public void addJobs(ArrayList<MapTile> jobs) {
|
||||
if (jobs == null) {
|
||||
mJobQueue.clear();
|
||||
return;
|
||||
}
|
||||
mJobQueue.setJobs(jobs);
|
||||
|
||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||
@ -795,4 +676,17 @@ public class MapView extends GLSurfaceView {
|
||||
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 android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* 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 byte mZoomLevel;
|
||||
private float mScale;
|
||||
|
||||
// private float mRotation;
|
||||
private float mRotation;
|
||||
|
||||
MapViewPosition(MapView mapView) {
|
||||
mMapView = mapView;
|
||||
@ -43,7 +43,7 @@ public class MapViewPosition {
|
||||
mLongitude = Double.NaN;
|
||||
mZoomLevel = -1;
|
||||
mScale = 1;
|
||||
// mRotation = 0.0f;
|
||||
mRotation = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,8 +61,7 @@ public class MapViewPosition {
|
||||
if (!isValid()) {
|
||||
return null;
|
||||
}
|
||||
GeoPoint geoPoint = new GeoPoint(mLatitude, mLongitude);
|
||||
return new MapPosition(geoPoint, mZoomLevel, mScale);
|
||||
return new MapPosition(mLatitude, mLongitude, mZoomLevel, mScale, mRotation);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,28 +104,50 @@ public class MapViewPosition {
|
||||
/**
|
||||
* Moves this MapViewPosition by the given amount of pixels.
|
||||
*
|
||||
* @param moveHorizontal
|
||||
* @param mx
|
||||
* the amount of pixels to move the map horizontally.
|
||||
* @param moveVertical
|
||||
* @param my
|
||||
* 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 pixelY = MercatorProjection.latitudeToPixelY(mLatitude, mZoomLevel);
|
||||
|
||||
mLatitude = MercatorProjection.pixelYToLatitude(pixelY - moveVertical / mScale,
|
||||
mZoomLevel);
|
||||
// float rad = (float) Math.toRadians(mRotation);
|
||||
// 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);
|
||||
|
||||
mLongitude = MercatorProjection.pixelXToLongitude(pixelX - moveHorizontal
|
||||
/ mScale,
|
||||
mZoomLevel);
|
||||
mLongitude = MercatorProjection.limitLongitude(mLongitude);
|
||||
mLongitude = MercatorProjection.pixelXToLongitude(dx, mZoomLevel);
|
||||
|
||||
//
|
||||
// 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) {
|
||||
// mRotation = angle;
|
||||
// }
|
||||
public synchronized void rotateMap(float angle) {
|
||||
mRotation -= angle;
|
||||
Log.d("...", "angle:" + mRotation);
|
||||
// mRotation %= 360;
|
||||
}
|
||||
|
||||
synchronized void setMapCenter(GeoPoint geoPoint) {
|
||||
mLatitude = MercatorProjection.limitLatitude(geoPoint.getLatitude());
|
||||
@ -134,9 +155,8 @@ public class MapViewPosition {
|
||||
}
|
||||
|
||||
synchronized void setMapCenterAndZoomLevel(MapPosition mapPosition) {
|
||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
||||
mLatitude = MercatorProjection.limitLatitude(geoPoint.getLatitude());
|
||||
mLongitude = MercatorProjection.limitLongitude(geoPoint.getLongitude());
|
||||
mLatitude = MercatorProjection.limitLatitude(mapPosition.lat);
|
||||
mLongitude = MercatorProjection.limitLongitude(mapPosition.lon);
|
||||
mZoomLevel = mMapView.limitZoomLevel(mapPosition.zoomLevel);
|
||||
}
|
||||
|
||||
@ -157,8 +177,9 @@ public class MapViewPosition {
|
||||
* ...
|
||||
*/
|
||||
public synchronized void scaleMap(float scale, float pivotX, float pivotY) {
|
||||
moveMap(pivotX * (1.0f - scale),
|
||||
pivotY * (1.0f - scale));
|
||||
if (pivotY != 0 || pivotY != 0)
|
||||
moveMap(pivotX * (1.0f - scale),
|
||||
pivotY * (1.0f - scale));
|
||||
|
||||
float s = mScale * scale;
|
||||
|
||||
|
||||
@ -38,14 +38,14 @@ class MapViewProjection implements Projection {
|
||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||
|
||||
// calculate the pixel coordinates of the top left corner
|
||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
||||
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
|
||||
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
|
||||
double pixelX = MercatorProjection.longitudeToPixelX(mapPosition);
|
||||
double pixelY = MercatorProjection.latitudeToPixelY(mapPosition);
|
||||
pixelX -= mMapView.getWidth() >> 1;
|
||||
pixelY -= mMapView.getHeight() >> 1;
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
@ -72,7 +72,8 @@ class MapViewProjection implements Projection {
|
||||
@Override
|
||||
public float metersToPixels(float meters, byte zoom) {
|
||||
double latitude = mMapView.getMapPosition().getMapCenter().getLatitude();
|
||||
double groundResolution = MercatorProjection.calculateGroundResolution(latitude, zoom);
|
||||
double groundResolution = MercatorProjection.calculateGroundResolution(latitude,
|
||||
zoom);
|
||||
return (float) (meters * (1 / groundResolution));
|
||||
}
|
||||
|
||||
@ -85,22 +86,25 @@ class MapViewProjection implements Projection {
|
||||
MapPosition mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||
|
||||
// calculate the pixel coordinates of the top left corner
|
||||
GeoPoint geoPoint = mapPosition.geoPoint;
|
||||
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
|
||||
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
|
||||
double pixelX = MercatorProjection.longitudeToPixelX(mapPosition);
|
||||
double pixelY = MercatorProjection.latitudeToPixelY(mapPosition);
|
||||
pixelX -= mMapView.getWidth() >> 1;
|
||||
pixelY -= mMapView.getHeight() >> 1;
|
||||
|
||||
if (out == null) {
|
||||
// create a new point and return it
|
||||
return new Point(
|
||||
(int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX),
|
||||
(int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY));
|
||||
(int) (MercatorProjection.longitudeToPixelX(in.getLongitude(),
|
||||
mapPosition.zoomLevel) - pixelX),
|
||||
(int) (MercatorProjection.latitudeToPixelY(in.getLatitude(),
|
||||
mapPosition.zoomLevel) - pixelY));
|
||||
}
|
||||
|
||||
// reuse the existing point
|
||||
out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX);
|
||||
out.y = (int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY);
|
||||
out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(),
|
||||
mapPosition.zoomLevel) - pixelX);
|
||||
out.y = (int) (MercatorProjection.latitudeToPixelY(in.getLatitude(),
|
||||
mapPosition.zoomLevel) - pixelY);
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -108,7 +112,8 @@ class MapViewProjection implements Projection {
|
||||
public Point toPoint(GeoPoint in, Point out, byte zoom) {
|
||||
if (out == null) {
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
@ -72,7 +72,8 @@ public class MapZoomControls {
|
||||
/**
|
||||
* 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.
|
||||
@ -97,7 +98,8 @@ public class MapZoomControls {
|
||||
/**
|
||||
* 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 mShowMapZoomControls;
|
||||
@ -220,7 +222,8 @@ public class MapZoomControls {
|
||||
return (right - left - zoomControlsWidth) / 2;
|
||||
|
||||
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);
|
||||
@ -251,7 +254,8 @@ public class MapZoomControls {
|
||||
|
||||
private void showZoomControlsWithTimeout() {
|
||||
showZoomControls();
|
||||
mZoomControlsHideHandler.sendEmptyMessageDelayed(MSG_ZOOM_CONTROLS_HIDE, ZOOM_CONTROLS_TIMEOUT);
|
||||
mZoomControlsHideHandler.sendEmptyMessageDelayed(MSG_ZOOM_CONTROLS_HIDE,
|
||||
ZOOM_CONTROLS_TIMEOUT);
|
||||
}
|
||||
|
||||
int getMeasuredHeight() {
|
||||
|
||||
@ -15,38 +15,33 @@
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
class GLMapTile extends MapTile {
|
||||
long lastDraw = 0;
|
||||
|
||||
// VBO layout:
|
||||
// 16 bytes fill coordinates
|
||||
// n bytes polygon vertices
|
||||
// m bytes lines vertices
|
||||
VertexBufferObject vbo;
|
||||
|
||||
// polygonOffset is always 8
|
||||
// polygonOffset in vbo is always 16 bytes,
|
||||
int lineOffset;
|
||||
|
||||
TextTexture texture;
|
||||
|
||||
// Tile data set by MapGenerator:
|
||||
LineLayer lineLayers;
|
||||
PolygonLayer polygonLayers;
|
||||
|
||||
TextItem labels;
|
||||
|
||||
boolean newData;
|
||||
boolean loading;
|
||||
|
||||
// pixel coordinates (y-flipped)
|
||||
final long x;
|
||||
final long y;
|
||||
// pointer in TileTree
|
||||
TreeTile rel;
|
||||
|
||||
final GLMapTile[] child = { null, null, null, null };
|
||||
GLMapTile parent;
|
||||
|
||||
GLMapTile(long tileX, long tileY, byte zoomLevel) {
|
||||
GLMapTile(int tileX, int tileY, byte zoomLevel) {
|
||||
super(tileX, tileY, zoomLevel);
|
||||
|
||||
x = pixelX;
|
||||
y = pixelY + Tile.TILE_SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -67,6 +67,8 @@ class LineLayers {
|
||||
return true;
|
||||
}
|
||||
|
||||
static final boolean mFast = true;
|
||||
|
||||
static LineLayer drawLines(GLMapTile tile, LineLayer layer, int next, float[] matrix,
|
||||
float div, double zoom, float scale) {
|
||||
|
||||
@ -88,18 +90,17 @@ class LineLayers {
|
||||
|
||||
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:
|
||||
// float pixel = 2.0f / (scale * z);
|
||||
// GLES20.glUniform1f(hLineScale, pixel);
|
||||
float pixel = 2.0f / (scale * z);
|
||||
|
||||
if (mFast)
|
||||
GLES20.glUniform1f(hLineScale, pixel);
|
||||
else
|
||||
GLES20.glUniform1f(hLineScale, 0);
|
||||
|
||||
// line scale factor (for non fixed lines)
|
||||
float s = FloatMath.sqrt(scale * z);
|
||||
boolean blur = false;
|
||||
GLES20.glUniform1f(hLineScale, 0);
|
||||
|
||||
LineLayer l = layer;
|
||||
for (; l != null && l.layer < next; l = l.next) {
|
||||
@ -120,11 +121,16 @@ class LineLayers {
|
||||
}
|
||||
|
||||
if (blur) {
|
||||
GLES20.glUniform1f(hLineScale, 0);
|
||||
if (mFast)
|
||||
GLES20.glUniform1f(hLineScale, pixel);
|
||||
else
|
||||
GLES20.glUniform1f(hLineScale, 0);
|
||||
blur = false;
|
||||
}
|
||||
|
||||
if (l.isOutline) {
|
||||
for (LineLayer o = l.outlines; o != null; o = o.outlines) {
|
||||
|
||||
if (line.blur != 0) {
|
||||
GLES20.glUniform1f(hLineScale, (l.width + o.width) / (scale * z)
|
||||
- (line.blur / (scale * z)));
|
||||
|
||||
@ -14,8 +14,10 @@
|
||||
*/
|
||||
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.MapGeneratorJob;
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
@ -81,12 +83,24 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
private RenderInstruction[] mRenderInstructions = null;
|
||||
|
||||
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");
|
||||
mMapView = mapView;
|
||||
}
|
||||
|
||||
private float mPoiX = 256;
|
||||
@ -115,8 +129,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
if (mMapProjection != null)
|
||||
{
|
||||
long x = mCurrentTile.x;
|
||||
long y = mCurrentTile.y;
|
||||
long x = mCurrentTile.pixelX;
|
||||
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||
|
||||
double divx, divy;
|
||||
@ -163,6 +177,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
mTagName = null;
|
||||
mProjected = false;
|
||||
mCurLineLayer = null;
|
||||
|
||||
mDrawingLayer = getValidLayer(layer) * mLevels;
|
||||
mSimplify = 0.5f;
|
||||
@ -325,9 +340,10 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
}
|
||||
}
|
||||
|
||||
if (lineLayer == null)
|
||||
if (lineLayer == null) {
|
||||
mCurLineLayer = null;
|
||||
return;
|
||||
|
||||
}
|
||||
if (line.outline) {
|
||||
lineLayer.addOutline(mCurLineLayer);
|
||||
return;
|
||||
@ -355,45 +371,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
}
|
||||
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
|
||||
@ -469,20 +446,27 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
boolean mDebugDrawUnmatched;
|
||||
|
||||
@Override
|
||||
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
|
||||
public boolean executeJob(MapTile mapTile) {
|
||||
GLMapTile tile;
|
||||
|
||||
if (mMapDatabase == null)
|
||||
return false;
|
||||
|
||||
tile = mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
|
||||
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
|
||||
mDebugDrawUnmatched = mapGeneratorJob.debugSettings.mDrawUnmatchted;
|
||||
tile = mCurrentTile = (GLMapTile) mapTile;
|
||||
DebugSettings debugSettings = mMapView.getDebugSettings();
|
||||
|
||||
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;
|
||||
|
||||
tile.isLoading = true;
|
||||
}
|
||||
|
||||
mLevels = MapGenerator.renderTheme.getLevels();
|
||||
|
||||
@ -492,10 +476,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
else
|
||||
setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
|
||||
|
||||
mLineLayers = null;
|
||||
mPolyLayers = null;
|
||||
mLabels = null;
|
||||
|
||||
// firstMatch = true;
|
||||
countLines = 0;
|
||||
countNodes = 0;
|
||||
@ -516,12 +496,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapGeneratorJob.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 };
|
||||
|
||||
if (debugSettings.mDrawTileFrames) {
|
||||
mTagName = new Tag("name", countLines + " " + countNodes + " "
|
||||
+ tile.toString(), false);
|
||||
mPoiX = Tile.TILE_SIZE >> 1;
|
||||
@ -533,21 +508,20 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
mDrawingLayer = 10 * mLevels;
|
||||
MapGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
|
||||
}
|
||||
|
||||
tile.lineLayers = mLineLayers;
|
||||
tile.polygonLayers = mPolyLayers;
|
||||
tile.labels = mLabels;
|
||||
|
||||
mCurPolyLayer = null;
|
||||
mCurLineLayer = null;
|
||||
mLineLayers = null;
|
||||
mPolyLayers = null;
|
||||
mLabels = null;
|
||||
|
||||
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) {
|
||||
if (layer < 0) {
|
||||
return 0;
|
||||
@ -612,8 +586,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
float[] coords = mWayNodes;
|
||||
|
||||
long x = mCurrentTile.x;
|
||||
long y = mCurrentTile.y;
|
||||
long x = mCurrentTile.pixelX;
|
||||
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||
float min = mSimplify;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -82,9 +82,7 @@ class PolygonLayers {
|
||||
// do not modify stencil buffer
|
||||
glStencilMask(0);
|
||||
|
||||
// clip with depth mask
|
||||
// GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
for (int c = 0; c < count; c++) {
|
||||
PolygonLayer l = mFillPolys[c];
|
||||
@ -139,13 +137,10 @@ class PolygonLayers {
|
||||
|
||||
if (blend)
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// glDisable(GLES20.GL_DEPTH_TEST);
|
||||
// glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
glUseProgram(polygonProgram);
|
||||
@ -182,10 +177,8 @@ class PolygonLayers {
|
||||
// clear stencilbuffer (tile region)
|
||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
|
||||
// draw depth clipper
|
||||
if (first) {
|
||||
// glEnable(GLES20.GL_DEPTH_TEST);
|
||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
GLES20.glPolygonOffset(0, drawCount);
|
||||
GLES20.glDepthMask(true);
|
||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||
}
|
||||
@ -196,13 +189,16 @@ class PolygonLayers {
|
||||
first = false;
|
||||
GLES20.glDepthMask(false);
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
// glDisable(GLES20.GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
// stencil op for stencil method polygon drawing
|
||||
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||
|
||||
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
mFillPolys[cnt] = l;
|
||||
|
||||
// set stencil mask to draw to
|
||||
@ -223,7 +219,7 @@ class PolygonLayers {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
if (clip && first)
|
||||
drawDepthClip(drawCount);
|
||||
drawDepthClip();
|
||||
|
||||
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
||||
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
|
||||
@ -231,53 +227,16 @@ class PolygonLayers {
|
||||
return l;
|
||||
}
|
||||
|
||||
// static void drawStencilClip(byte drawCount) {
|
||||
// // 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) {
|
||||
static void drawDepthClip() {
|
||||
|
||||
glColorMask(false, false, false, false);
|
||||
// glEnable(GLES20.GL_DEPTH_TEST);
|
||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||
GLES20.glPolygonOffset(0, drawCount);
|
||||
|
||||
GLES20.glDepthMask(true);
|
||||
|
||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
GLES20.glDepthMask(false);
|
||||
glColorMask(true, true, true, true);
|
||||
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ package org.mapsforge.android.glrenderer;
|
||||
class Shaders {
|
||||
|
||||
final static String lineVertexShader = ""
|
||||
+ "precision mediump float; \n"
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 mvp;"
|
||||
+ "attribute vec4 a_position;"
|
||||
+ "attribute vec2 a_st;"
|
||||
@ -32,7 +32,26 @@ class Shaders {
|
||||
+ " 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 = ""
|
||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
// + "precision mediump float;\n"
|
||||
// + "uniform float u_wscale;"
|
||||
// + "uniform float u_width;"
|
||||
@ -41,39 +60,18 @@ class Shaders {
|
||||
// + "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);"
|
||||
// + " 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;"
|
||||
// + "}";
|
||||
|
||||
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 = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 mvp;"
|
||||
@ -113,7 +111,7 @@ class Shaders {
|
||||
+ "}";
|
||||
|
||||
// final static String lineVertexZigZagShader = ""
|
||||
// + "precision mediump float; \n"
|
||||
// + "precision mediump float;"
|
||||
// + "uniform mat4 mvp;"
|
||||
// + "attribute vec4 a_pos1;"
|
||||
// + "attribute vec2 a_st1;"
|
||||
@ -135,7 +133,7 @@ class Shaders {
|
||||
|
||||
// final static String lineFragmentShader = ""
|
||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
// + "precision mediump float;\n"
|
||||
// + "precision mediump float;"
|
||||
// + "uniform vec2 u_mode;"
|
||||
// + "uniform vec4 u_color;"
|
||||
// + "varying vec2 v_st;"
|
||||
|
||||
@ -23,7 +23,7 @@ public class ShortPool {
|
||||
static private int count = 0;
|
||||
static private int countAll = 0;
|
||||
|
||||
static synchronized void finish() {
|
||||
static synchronized void init() {
|
||||
count = 0;
|
||||
countAll = 0;
|
||||
pool = null;
|
||||
|
||||
@ -45,7 +45,6 @@ public class TextRenderer {
|
||||
private static int mFontPadY = 1;
|
||||
private static int mBitmapFormat;
|
||||
private static int mBitmapType;
|
||||
private static ByteBuffer mByteBuffer;
|
||||
private static ShortBuffer mShortBuffer;
|
||||
private static TextTexture[] mTextures;
|
||||
|
||||
@ -57,9 +56,8 @@ public class TextRenderer {
|
||||
private static int hTextVertex;
|
||||
private static int hTextScale;
|
||||
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 short[] debugVertices = {
|
||||
@ -79,13 +77,24 @@ public class TextRenderer {
|
||||
};
|
||||
|
||||
static boolean init(int numTextures) {
|
||||
mBitmap = Bitmap
|
||||
.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
||||
int bufferSize = numTextures
|
||||
* 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);
|
||||
|
||||
mBitmapFormat = GLUtils.getInternalFormat(mBitmap);
|
||||
mBitmapType = GLUtils.getType(mBitmap);
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocateDirect(bufferSize)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
mShortBuffer = buf.asShortBuffer();
|
||||
// }
|
||||
|
||||
mTextProgram = GlUtils.createProgram(Shaders.textVertexShader,
|
||||
Shaders.textFragmentShader);
|
||||
|
||||
@ -94,15 +103,6 @@ public class TextRenderer {
|
||||
hTextScale = GLES20.glGetUniformLocation(mTextProgram, "scale");
|
||||
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];
|
||||
TextTexture[] textures = new TextTexture[numTextures];
|
||||
GLES20.glGenTextures(numTextures, textureIds, 0);
|
||||
@ -136,24 +136,23 @@ public class TextRenderer {
|
||||
int len = indices.length;
|
||||
short j = 0;
|
||||
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 + 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);
|
||||
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 + 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();
|
||||
|
||||
tmpIndices.put(indices, 0, len);
|
||||
tmpIndices.flip();
|
||||
mShortBuffer.clear();
|
||||
mShortBuffer.put(indices, 0, len);
|
||||
mShortBuffer.flip();
|
||||
|
||||
int[] mVboIds = new int[2];
|
||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||
@ -162,13 +161,15 @@ public class TextRenderer {
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
|
||||
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);
|
||||
|
||||
mShortBuffer.clear();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, bufferSize,
|
||||
mShortBuffer, GLES20.GL_DYNAMIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -360,10 +361,13 @@ public class TextRenderer {
|
||||
tex.length = pos;
|
||||
tile.texture = tex;
|
||||
tex.tile = tile;
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.id);
|
||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mBitmap,
|
||||
mBitmapFormat, mBitmapType);
|
||||
|
||||
GLES20.glFlush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -388,9 +392,7 @@ public class TextRenderer {
|
||||
}
|
||||
|
||||
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),
|
||||
mShortBuffer);
|
||||
}
|
||||
@ -442,7 +444,7 @@ public class TextRenderer {
|
||||
GLES20.GL_SHORT, false, 12, tile.texture.offset * (Short.SIZE / 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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Minimum distance in pixels before the way name is repeated.
|
||||
*/
|
||||
private static final int DISTANCE_BETWEEN_WAY_NAMES = 500;
|
||||
// /**
|
||||
// * Minimum distance in pixels before the way name is repeated.
|
||||
// */
|
||||
// private static final int DISTANCE_BETWEEN_WAY_NAMES = 500;
|
||||
|
||||
// /**
|
||||
// * 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.MapViewPosition;
|
||||
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.SystemClock;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {
|
||||
private final MapView mMapView;
|
||||
private MapViewPosition mMapPosition;
|
||||
private float mCenterX;
|
||||
private float mCenterY;
|
||||
// private float mFocusX;
|
||||
// private float mFocusY;
|
||||
private float mScale;
|
||||
private boolean mBeginScale;
|
||||
|
||||
// private boolean mScaling;
|
||||
/**
|
||||
* Creates a new ScaleListener for the given MapView.
|
||||
*
|
||||
@ -40,52 +41,104 @@ class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
|
||||
public boolean onScale(ScaleGestureDetector gd) {
|
||||
|
||||
float focusX = scaleGestureDetector.getFocusX();
|
||||
float focusY = scaleGestureDetector.getFocusY();
|
||||
mScale = scaleGestureDetector.getScaleFactor();
|
||||
float focusX = gd.getFocusX();
|
||||
float focusY = gd.getFocusY();
|
||||
mScale = gd.getScaleFactor();
|
||||
|
||||
// mMapPosition.moveMap((focusX - mFocusX), (focusY - mFocusY));
|
||||
// if (mScale > 1.001 || mScale < 0.999) {
|
||||
mSumScale *= mScale;
|
||||
|
||||
mMapPosition.scaleMap(mScale,
|
||||
focusX - mCenterX,
|
||||
focusY - mCenterY);
|
||||
mTimeEnd = SystemClock.elapsedRealtime();
|
||||
|
||||
if (!mBeginScale) {
|
||||
if (mTimeEnd - mTimeStart > 100) {
|
||||
mBeginScale = true;
|
||||
mScale = mSumScale;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
mMapPosition.scaleMap(mScale, focusX - mCenterX, focusY - mCenterY);
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
|
||||
private long mTimeStart;
|
||||
private long mTimeEnd;
|
||||
private float mSumScale;
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector gd) {
|
||||
mTimeEnd = mTimeStart = SystemClock.elapsedRealtime();
|
||||
mSumScale = 1;
|
||||
mBeginScale = false;
|
||||
mCenterX = mMapView.getWidth() >> 1;
|
||||
mCenterY = mMapView.getHeight() >> 1;
|
||||
// mFocusX = scaleGestureDetector.getFocusX();
|
||||
// mFocusY = scaleGestureDetector.getFocusY();
|
||||
mScale = 1;
|
||||
mMapPosition = mMapView.getMapPosition();
|
||||
// mScaling = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
|
||||
// do nothing
|
||||
public void onScaleEnd(ScaleGestureDetector gd) {
|
||||
// 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;
|
||||
|
||||
import org.mapsforge.android.MapView;
|
||||
import org.mapsforge.android.MapViewPosition;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.CountDownTimer;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.Scroller;
|
||||
|
||||
/**
|
||||
@ -33,15 +34,15 @@ import android.widget.Scroller;
|
||||
public class TouchHandler {
|
||||
private static final int INVALID_POINTER_ID = -1;
|
||||
|
||||
/**
|
||||
* is pritected correct? share MapView with inner class
|
||||
*/
|
||||
protected final MapView mMapView;
|
||||
protected final MapViewPosition mMapPosition;
|
||||
|
||||
private final float mMapMoveDelta;
|
||||
private boolean mMoveThresholdReached;
|
||||
private float mPreviousPositionX;
|
||||
private float mPreviousPositionY;
|
||||
private float mPosX;
|
||||
private float mPosY;
|
||||
private float mAngle;
|
||||
|
||||
private int mActivePointerId;
|
||||
|
||||
private final ScaleGestureDetector mScaleGestureDetector;
|
||||
@ -56,11 +57,13 @@ public class TouchHandler {
|
||||
public TouchHandler(Context context, MapView mapView) {
|
||||
ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
|
||||
mMapView = mapView;
|
||||
mMapPosition = mapView.getMapPosition();
|
||||
mMapMoveDelta = viewConfiguration.getScaledTouchSlop();
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener(
|
||||
mMapView));
|
||||
mGestureDetector = new GestureDetector(new MapGestureDetector(mMapView));
|
||||
mGestureDetector = new GestureDetector(context, new MapGestureDetector(mMapView));
|
||||
|
||||
}
|
||||
|
||||
private static int getAction(MotionEvent motionEvent) {
|
||||
@ -72,22 +75,30 @@ public class TouchHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onActionDown(MotionEvent motionEvent) {
|
||||
mPreviousPositionX = motionEvent.getX();
|
||||
mPreviousPositionY = motionEvent.getY();
|
||||
private boolean onActionDown(MotionEvent event) {
|
||||
mPosX = event.getX();
|
||||
mPosY = event.getY();
|
||||
mMoveThresholdReached = false;
|
||||
// save the ID of the pointer
|
||||
mActivePointerId = motionEvent.getPointerId(0);
|
||||
mActivePointerId = event.getPointerId(0);
|
||||
// Log.d("...", "set active pointer" + mActivePointerId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onActionMove(MotionEvent motionEvent) {
|
||||
int pointerIndex = motionEvent.findPointerIndex(mActivePointerId);
|
||||
private boolean mScaling = false;
|
||||
|
||||
private boolean onActionMove(MotionEvent event) {
|
||||
int pointerIndex = event.findPointerIndex(mActivePointerId);
|
||||
|
||||
// calculate the distance between previous and current position
|
||||
float moveX = motionEvent.getX(pointerIndex) - mPreviousPositionX;
|
||||
float moveY = motionEvent.getY(pointerIndex) - mPreviousPositionY;
|
||||
float moveX = event.getX(pointerIndex) - mPosX;
|
||||
float moveY = event.getY(pointerIndex) - mPosY;
|
||||
|
||||
boolean scaling = mScaleGestureDetector.isInProgress();
|
||||
if (!mScaling) {
|
||||
mScaling = scaling;
|
||||
}
|
||||
if (!scaling && !mMoveThresholdReached) {
|
||||
|
||||
if (Math.abs(moveX) > 3 * mMapMoveDelta
|
||||
@ -97,36 +108,57 @@ public class TouchHandler {
|
||||
mMoveThresholdReached = true;
|
||||
|
||||
// save the position of the event
|
||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
||||
mPosX = event.getX(pointerIndex);
|
||||
mPosY = event.getY(pointerIndex);
|
||||
}
|
||||
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
|
||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
||||
mPosX = event.getX(pointerIndex);
|
||||
mPosY = event.getY(pointerIndex);
|
||||
|
||||
if (scaling) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mMapView.getMapPosition().moveMap(moveX, moveY);
|
||||
mMapPosition.moveMap(moveX, moveY);
|
||||
mMapView.redrawTiles();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// private boolean onActionPointerDown(MotionEvent motionEvent) {
|
||||
// longPressDetector.pressStop();
|
||||
// multiTouchDownTime = motionEvent.getEventTime();
|
||||
// return true;
|
||||
// }
|
||||
private int multi = 0;
|
||||
|
||||
private boolean onActionPointerDown(MotionEvent event) {
|
||||
// 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) {
|
||||
|
||||
// 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;
|
||||
|
||||
if (motionEvent.getPointerId(pointerIndex) == mActivePointerId) {
|
||||
// the active pointer has gone up, choose a new one
|
||||
if (pointerIndex == 0) {
|
||||
@ -135,19 +167,12 @@ public class TouchHandler {
|
||||
pointerIndex = 0;
|
||||
}
|
||||
// save the position of the event
|
||||
mPreviousPositionX = motionEvent.getX(pointerIndex);
|
||||
mPreviousPositionY = motionEvent.getY(pointerIndex);
|
||||
mPosX = motionEvent.getX(pointerIndex);
|
||||
mPosY = motionEvent.getY(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;
|
||||
}
|
||||
|
||||
@ -157,83 +182,53 @@ public class TouchHandler {
|
||||
* @return ...
|
||||
*/
|
||||
private boolean onActionUp(MotionEvent motionEvent) {
|
||||
// longPressDetector.pressStop();
|
||||
// int pointerIndex = motionEvent.findPointerIndex(mActivePointerId);
|
||||
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
// if (mMoveThresholdReached // || longPressDetector.isEventHandled()
|
||||
// ) {
|
||||
// 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();
|
||||
//
|
||||
// }
|
||||
mScaling = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private long lastRun = 0;
|
||||
|
||||
/**
|
||||
* @param motionEvent
|
||||
* @param event
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public boolean handleMotionEvent(MotionEvent motionEvent) {
|
||||
public boolean handleMotionEvent(MotionEvent event) {
|
||||
|
||||
// workaround for a bug in the ScaleGestureDetector, see Android issue
|
||||
// #12976
|
||||
if (motionEvent.getAction() != MotionEvent.ACTION_MOVE
|
||||
|| motionEvent.getPointerCount() > 1) {
|
||||
mScaleGestureDetector.onTouchEvent(motionEvent);
|
||||
}
|
||||
|
||||
mGestureDetector.onTouchEvent(motionEvent);
|
||||
// if () {
|
||||
// // mActivePointerId = INVALID_POINTER_ID;
|
||||
// // return true;
|
||||
// if (event.getAction() != MotionEvent.ACTION_MOVE
|
||||
// || event.getPointerCount() > 1) {
|
||||
mScaleGestureDetector.onTouchEvent(event);
|
||||
// }
|
||||
int action = getAction(motionEvent);
|
||||
|
||||
if (!mScaling)
|
||||
mGestureDetector.onTouchEvent(event);
|
||||
|
||||
int action = getAction(event);
|
||||
boolean ret = false;
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
ret = onActionDown(motionEvent);
|
||||
ret = onActionDown(event);
|
||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||
ret = onActionMove(motionEvent);
|
||||
ret = onActionMove(event);
|
||||
} else if (action == MotionEvent.ACTION_UP) {
|
||||
ret = onActionUp(motionEvent);
|
||||
ret = onActionUp(event);
|
||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||
ret = onActionCancel();
|
||||
// } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
// return onActionPointerDown(motionEvent);
|
||||
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
return onActionPointerDown(event);
|
||||
} 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;
|
||||
}
|
||||
|
||||
class MapGestureDetector extends SimpleOnGestureListener {
|
||||
private Scroller mScroller;
|
||||
private float mPrevX, mPrevY;
|
||||
private float mPrevX, mPrevY, mPrevScale;
|
||||
private CountDownTimer mTimer = null;
|
||||
private boolean fling = false;
|
||||
|
||||
public MapGestureDetector(MapView mapView) {
|
||||
mScroller = new Scroller(mapView.getContext(),
|
||||
@ -242,12 +237,17 @@ public class TouchHandler {
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
mScroller.forceFinished(true);
|
||||
if (fling) {
|
||||
mScroller.forceFinished(true);
|
||||
|
||||
if (mTimer != null) {
|
||||
mTimer.cancel();
|
||||
mTimer = null;
|
||||
if (mTimer != null) {
|
||||
mTimer.cancel();
|
||||
mTimer = null;
|
||||
}
|
||||
fling = false;
|
||||
}
|
||||
// Log.d("mapsforge", "onDown");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -256,11 +256,12 @@ public class TouchHandler {
|
||||
return false;
|
||||
}
|
||||
mScroller.computeScrollOffset();
|
||||
|
||||
float moveX = mScroller.getCurrX() - mPrevX;
|
||||
float moveY = mScroller.getCurrY() - mPrevY;
|
||||
|
||||
if (moveX >= 1 || moveY >= 1 || moveX <= -1 || moveY <= -1) {
|
||||
mMapView.getMapPosition().moveMap(moveX, moveY);
|
||||
mMapPosition.moveMap(moveX, moveY);
|
||||
mMapView.redrawTiles();
|
||||
mPrevX = mScroller.getCurrX();
|
||||
mPrevY = mScroller.getCurrY();
|
||||
@ -271,8 +272,8 @@ public class TouchHandler {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||
float velocityY) {
|
||||
int w = Tile.TILE_SIZE * 10;
|
||||
int h = Tile.TILE_SIZE * 10;
|
||||
int w = Tile.TILE_SIZE * 20;
|
||||
int h = Tile.TILE_SIZE * 20;
|
||||
mPrevX = 0;
|
||||
mPrevY = 0;
|
||||
|
||||
@ -283,12 +284,12 @@ public class TouchHandler {
|
||||
|
||||
mScroller.fling(0, 0, Math.round(velocityX) / 2, Math.round(velocityY) / 2,
|
||||
-w, w, -h, h);
|
||||
|
||||
// animate for two seconds
|
||||
mTimer = new CountDownTimer(2000, 40) {
|
||||
mTimer = new CountDownTimer(1500, 50) {
|
||||
@Override
|
||||
public void onTick(long tick) {
|
||||
if (!scroll())
|
||||
cancel();
|
||||
scroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -296,21 +297,61 @@ public class TouchHandler {
|
||||
// do nothing
|
||||
}
|
||||
}.start();
|
||||
|
||||
fling = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private DecelerateInterpolator mBounce = new DecelerateInterpolator();
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
// mMapView.zoom((byte) 1);
|
||||
Log.d("mapsforge", "long press");
|
||||
// return true;
|
||||
// Log.d("mapsforge", "long press");
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,11 +29,11 @@ public interface IMapGenerator {
|
||||
/**
|
||||
* Called when a job needs to be executed.
|
||||
*
|
||||
* @param mapGeneratorJob
|
||||
* @param tile
|
||||
* the job that should be executed.
|
||||
* @return true if the job was executed successfully, false otherwise.
|
||||
*/
|
||||
boolean executeJob(MapGeneratorJob mapGeneratorJob);
|
||||
boolean executeJob(MapTile tile);
|
||||
|
||||
/**
|
||||
* @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.PriorityQueue;
|
||||
|
||||
import org.mapsforge.android.MapView;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
/**
|
||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
||||
*/
|
||||
public class JobQueue {
|
||||
private static final int INITIAL_CAPACITY = 128;
|
||||
private static final int INITIAL_CAPACITY = 64;
|
||||
|
||||
private final MapView mMapView;
|
||||
private PriorityQueue<MapGeneratorJob> mPriorityQueue;
|
||||
private boolean mScheduleNeeded;
|
||||
private PriorityQueue<MapTile> mPriorityQueue;
|
||||
|
||||
/**
|
||||
* @param mapView
|
||||
* the MapView whose jobs should be organized.
|
||||
*/
|
||||
public JobQueue(MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mPriorityQueue = new PriorityQueue<MapGeneratorJob>(INITIAL_CAPACITY);
|
||||
public JobQueue() {
|
||||
mPriorityQueue = new PriorityQueue<MapTile>(INITIAL_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given job to this queue. Does nothing if the given job is already in this queue.
|
||||
*
|
||||
* @param mapGeneratorJob
|
||||
* @param tiles
|
||||
* the job to be added to this queue.
|
||||
*/
|
||||
// public synchronized void addJob(MapGeneratorJob mapGeneratorJob) {
|
||||
// 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) {
|
||||
public synchronized void setJobs(ArrayList<MapTile> tiles) {
|
||||
mPriorityQueue.clear();
|
||||
for (MapGeneratorJob job : jobs)
|
||||
mPriorityQueue.offer(job);
|
||||
// priorityQueue.addAll(jobs);
|
||||
mScheduleNeeded = true;
|
||||
mPriorityQueue.addAll(tiles);
|
||||
// for (int i = 0, n = tiles.size(); i < n; i++)
|
||||
// mPriorityQueue.offer(tiles.get(i));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,39 +59,11 @@ public class JobQueue {
|
||||
/**
|
||||
* @return the most important job from this queue or null, if empty.
|
||||
*/
|
||||
public synchronized MapGeneratorJob poll() {
|
||||
if (mScheduleNeeded) {
|
||||
mScheduleNeeded = false;
|
||||
schedule();
|
||||
}
|
||||
return mPriorityQueue.poll();
|
||||
public synchronized MapTile poll() {
|
||||
MapTile tile = mPriorityQueue.poll();
|
||||
if (tile != null)
|
||||
tile.isLoading = true;
|
||||
|
||||
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,
|
||||
MAP_DATABASE_ATTRIBUTE_NAME);
|
||||
if (mapDatabaseName == null) {
|
||||
return MapDatabases.POSTGIS_READER;
|
||||
return MapDatabases.PBMAP_READER;
|
||||
}
|
||||
|
||||
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).
|
||||
*/
|
||||
@ -53,7 +53,17 @@ public class MapTile extends Tile {
|
||||
* @param zoomLevel
|
||||
* ..
|
||||
*/
|
||||
public MapTile(long tileX, long tileY, byte zoomLevel) {
|
||||
public MapTile(int tileX, int tileY, byte 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
|
||||
protected void doWork() {
|
||||
MapGeneratorJob mapGeneratorJob = mJobQueue.poll();
|
||||
MapTile tile = mJobQueue.poll();
|
||||
|
||||
if (mMapGenerator == null || mapGeneratorJob == null)
|
||||
if (mMapGenerator == null || tile == null)
|
||||
return;
|
||||
|
||||
boolean success = mMapGenerator.executeJob(mapGeneratorJob);
|
||||
boolean success = mMapGenerator.executeJob(tile);
|
||||
|
||||
if (!isInterrupted() && success) {
|
||||
mMapRenderer.passTile(mapGeneratorJob);
|
||||
mMapRenderer.passTile(tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,9 +18,6 @@ import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A JobTheme defines the render theme which is used for a {@link MapGeneratorJob}.
|
||||
*/
|
||||
public interface Theme extends Serializable {
|
||||
/**
|
||||
* @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 level
|
||||
* ...
|
||||
*/
|
||||
void renderArea(Area area, int level);
|
||||
|
||||
@ -83,6 +85,8 @@ public interface IRenderCallback {
|
||||
*
|
||||
* @param line
|
||||
* ...
|
||||
* @param 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>
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
@ -38,7 +38,8 @@ class PositiveRule extends Rule {
|
||||
@Override
|
||||
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
||||
return (mElement != Element.WAY)
|
||||
&& mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||
&& mZoomMin <= zoomLevel
|
||||
&& mZoomMax >= zoomLevel
|
||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||
}
|
||||
@ -46,7 +47,8 @@ class PositiveRule extends Rule {
|
||||
@Override
|
||||
boolean matchesWay(Tag[] tags, byte zoomLevel, int closed) {
|
||||
return (mElement != Element.NODE)
|
||||
&& mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||
&& mZoomMin <= zoomLevel
|
||||
&& mZoomMax >= zoomLevel
|
||||
&& (mClosed == closed || mClosed == Closed.ANY)
|
||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||
|
||||
@ -138,8 +138,7 @@ public class RenderTheme {
|
||||
* @return ...
|
||||
*/
|
||||
public synchronized RenderInstruction[] matchNode(IRenderCallback renderCallback,
|
||||
Tag[] tags,
|
||||
byte zoomLevel) {
|
||||
Tag[] tags, byte zoomLevel) {
|
||||
|
||||
RenderInstruction[] renderInstructions = null;
|
||||
|
||||
@ -189,9 +188,8 @@ public class RenderTheme {
|
||||
* @return currently processed render instructions
|
||||
*/
|
||||
public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
|
||||
Tag[] tags,
|
||||
byte zoomLevel,
|
||||
boolean closed, boolean render) {
|
||||
Tag[] tags, byte zoomLevel, boolean closed, boolean render) {
|
||||
|
||||
RenderInstruction[] renderInstructions = null;
|
||||
|
||||
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
||||
@ -205,6 +203,7 @@ public class RenderTheme {
|
||||
|
||||
matchingCacheKey = new MatchingCacheKey(tags, zoomLevel);
|
||||
boolean found = matchingCache.containsKey(matchingCacheKey);
|
||||
|
||||
if (found) {
|
||||
renderInstructions = matchingCache.get(matchingCacheKey);
|
||||
} else {
|
||||
|
||||
@ -25,9 +25,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
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.Circle;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.AreaLevel;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.LineSymbol;
|
||||
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.helpers.DefaultHandler;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
else {
|
||||
// System.out.println("couldnt check the style yo! " + style);
|
||||
Log.d("...", "this aint no style! " + style);
|
||||
}
|
||||
} else {
|
||||
Line line = Line.create(null, localName, attributes, 0, false);
|
||||
@ -266,6 +268,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
||||
|
||||
mCurrentRule.addRenderingInstruction(newLine);
|
||||
}
|
||||
else
|
||||
Log.d("...", "styles not a line! " + style);
|
||||
}
|
||||
} else if (ELEMENT_NAME_USE_STYLE_OUTLINE.equals(localName)) {
|
||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||
@ -274,6 +278,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
||||
Line line = (Line) tmpStyleHash.get("o" + style);
|
||||
if (line != null && line.outline)
|
||||
mCurrentRule.addRenderingInstruction(line);
|
||||
else
|
||||
Log.d("...", "styles not bad, but this aint no outline! " + style);
|
||||
}
|
||||
} else if (ELEMENT_NAME_USE_STYLE_AREA.equals(localName)) {
|
||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||
@ -283,6 +289,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
||||
if (area != null)
|
||||
mCurrentRule.addRenderingInstruction(new AreaLevel(area,
|
||||
mLevel++));
|
||||
else
|
||||
Log.d("...", "this aint no style inna di area! " + style);
|
||||
}
|
||||
} else if (ELEMENT_NAME_USE_STYLE_PATH_TEXT.equals(localName)) {
|
||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||
@ -291,6 +299,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
||||
PathText pt = (PathText) tmpStyleHash.get("t" + style);
|
||||
if (pt != null)
|
||||
mCurrentRule.addRenderingInstruction(pt);
|
||||
else
|
||||
Log.d("...", "this aint no path text style! " + style);
|
||||
}
|
||||
} else {
|
||||
throw new SAXException("unknown element: " + localName);
|
||||
|
||||
@ -485,7 +485,7 @@
|
||||
</rule>
|
||||
|
||||
<!-- 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="2" stroke="#c0c0c0" />
|
||||
<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
|
||||
* ..
|
||||
*/
|
||||
public GLMapTile(long tileX, long tileY, byte zoomLevel) {
|
||||
public GLMapTile(int tileX, int tileY, byte zoomLevel) {
|
||||
super(tileX, tileY, zoomLevel);
|
||||
mScale = 1;
|
||||
mTextureID = -1;
|
||||
|
||||
@ -17,8 +17,10 @@ package org.mapsforge.android.swrenderer;
|
||||
import java.util.ArrayList;
|
||||
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.MapGeneratorJob;
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
@ -98,11 +100,16 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
|
||||
// private long _renderTime;
|
||||
private int _nodes, _nodesDropped;
|
||||
private MapView mMapView;
|
||||
|
||||
/**
|
||||
* Constructs a new DatabaseRenderer.
|
||||
*
|
||||
* @param mapView
|
||||
* the MapView
|
||||
*/
|
||||
public MapGenerator() {
|
||||
public MapGenerator(MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mCanvasRasterer = new CanvasRasterer();
|
||||
mLabelPlacement = new LabelPlacement();
|
||||
|
||||
@ -131,13 +138,13 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
|
||||
public boolean executeJob(MapTile mapTile) {
|
||||
long time_load = System.currentTimeMillis();
|
||||
_nodes = 0;
|
||||
_nodesDropped = 0;
|
||||
// _renderTime = 0;
|
||||
|
||||
mCurrentTile = mapGeneratorJob.tile;
|
||||
mCurrentTile = mapTile;
|
||||
mCurrentTileZoom = ((long) Tile.TILE_SIZE << mCurrentTile.zoomLevel);
|
||||
mCurrentTileX = mCurrentTile.pixelX;
|
||||
mCurrentTileY = mCurrentTile.pixelY;
|
||||
@ -151,7 +158,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
//
|
||||
// mTileWidth = mLon2 - mLon1;
|
||||
// mTileHeight = mLat1 - mLat2;
|
||||
mScale = mapGeneratorJob.getScale();
|
||||
// mScale = mapGeneratorJob.getScale();
|
||||
|
||||
// Theme theme = mapGeneratorJob.jobParameters.theme;
|
||||
// if (!theme.equals(mPreviousJobTheme)) {
|
||||
@ -203,18 +210,20 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
mCanvasRasterer.drawNodes(mAreaLabels);
|
||||
time_draw = System.currentTimeMillis() - time_draw;
|
||||
|
||||
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
||||
DebugSettings debugSettings = mMapView.getDebugSettings();
|
||||
|
||||
if (debugSettings.mDrawTileFrames) {
|
||||
mCanvasRasterer.drawTileFrame();
|
||||
}
|
||||
|
||||
if (mapGeneratorJob.debugSettings.mDrawTileCoordinates) {
|
||||
if (debugSettings.mDrawTileCoordinates) {
|
||||
mCanvasRasterer.drawTileCoordinates(mCurrentTile, time_load, time_draw,
|
||||
_nodes, _nodesDropped);
|
||||
}
|
||||
|
||||
clearLists();
|
||||
|
||||
mapGeneratorJob.setBitmap(mTileBitmap);
|
||||
// mapGeneratorJob.setBitmap(mTileBitmap);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -411,8 +420,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
// mPrevLayer = layer;
|
||||
}
|
||||
|
||||
private List<ShapeContainer> mCurLevelContainer1;
|
||||
private List<ShapeContainer> mCurLevelContainer2;
|
||||
// private List<ShapeContainer> mCurLevelContainer1;
|
||||
// private List<ShapeContainer> mCurLevelContainer2;
|
||||
|
||||
@Override
|
||||
public void renderWay(Line line, int level) {
|
||||
|
||||
@ -21,17 +21,13 @@ import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import org.mapsforge.android.DebugSettings;
|
||||
import org.mapsforge.android.MapView;
|
||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||
import org.mapsforge.android.utils.GlUtils;
|
||||
@ -40,7 +36,6 @@ import org.mapsforge.core.MercatorProjection;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
import android.opengl.Matrix;
|
||||
|
||||
/**
|
||||
@ -65,11 +60,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
private double mDrawX, mDrawY;
|
||||
private long mTileX, mTileY;
|
||||
private float mMapScale;
|
||||
private DebugSettings mDebugSettings;
|
||||
private JobParameters mJobParameter;
|
||||
// private DebugSettings mDebugSettings;
|
||||
// private JobParameters mJobParameter;
|
||||
private MapPosition mMapPosition, mPrevMapPosition;
|
||||
|
||||
private ArrayList<MapGeneratorJob> mJobList;
|
||||
private ArrayList<MapTile> mJobList;
|
||||
|
||||
ArrayList<Integer> mTextures;
|
||||
MapView mMapView;
|
||||
@ -78,8 +73,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
GLMapTile[] newTiles;
|
||||
int currentTileCnt = 0;
|
||||
|
||||
private TileCacheKey mTileCacheKey;
|
||||
private LinkedHashMap<TileCacheKey, GLMapTile> mTiles;
|
||||
// private TileCacheKey mTileCacheKey;
|
||||
// private LinkedHashMap<TileCacheKey, GLMapTile> mTiles;
|
||||
private ArrayList<GLMapTile> mTileList;
|
||||
|
||||
private boolean processedTile = true;
|
||||
@ -96,7 +91,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
*/
|
||||
public MapRenderer(MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mDebugSettings = mapView.getDebugSettings();
|
||||
// mDebugSettings = mapView.getDebugSettings();
|
||||
mMapScale = 1;
|
||||
|
||||
float[] vertices = {
|
||||
@ -110,12 +105,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mVertices.put(vertices);
|
||||
|
||||
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>();
|
||||
|
||||
mTileCacheKey = new TileCacheKey();
|
||||
// mTileCacheKey = new TileCacheKey();
|
||||
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++) {
|
||||
GLMapTile t = mTileList.remove(j);
|
||||
|
||||
mTileCacheKey.set(t.tileX, t.tileY, t.zoomLevel);
|
||||
mTiles.remove(mTileCacheKey);
|
||||
// mTileCacheKey.set(t.tileX, t.tileY, t.zoomLevel);
|
||||
// mTiles.remove(mTileCacheKey);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (t.child[i] != null)
|
||||
@ -176,63 +171,63 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
long pixelLeft = x - offsetX;
|
||||
long pixelTop = y - offsetY;
|
||||
|
||||
long tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel);
|
||||
long tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel);
|
||||
long tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel);
|
||||
long tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel);
|
||||
int tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel);
|
||||
int tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel);
|
||||
int tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel);
|
||||
int tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel);
|
||||
|
||||
mJobList.clear();
|
||||
|
||||
// IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
||||
|
||||
int tiles = 0;
|
||||
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
||||
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
|
||||
for (int tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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) {
|
||||
|
||||
limitCache(zoomLevel, (mTiles.size() - 200));
|
||||
limitCache(zoomLevel, (mTileList.size() - 200));
|
||||
|
||||
for (int i = 0; i < tiles; i++)
|
||||
currentTiles[i] = newTiles[i];
|
||||
@ -243,9 +238,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mMapScale = scale;
|
||||
}
|
||||
|
||||
if (mJobList.size() > 0) {
|
||||
mMapView.addJobs(mJobList);
|
||||
}
|
||||
// if (mJobList.size() > 0) {
|
||||
// mMapView.addJobs(mJobList);
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -260,12 +255,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
||||
|
||||
long x = (long) MercatorProjection.longitudeToPixelX(
|
||||
mMapPosition.geoPoint.getLongitude(),
|
||||
mMapPosition.zoomLevel);
|
||||
long y = (long) MercatorProjection
|
||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(),
|
||||
mMapPosition.zoomLevel);
|
||||
long x = (long) MercatorProjection.longitudeToPixelX(mMapPosition);
|
||||
long y = (long) MercatorProjection.latitudeToPixelY(mMapPosition);
|
||||
|
||||
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
|
||||
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
|
||||
@ -304,12 +295,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mMapView.requestRender();
|
||||
}
|
||||
|
||||
private MapGeneratorJob mMapGeneratorJob = null;
|
||||
// private MapGeneratorJob mMapGeneratorJob = null;
|
||||
|
||||
@Override
|
||||
public boolean passTile(MapGeneratorJob mapGeneratorJob) {
|
||||
public boolean passTile(MapTile mapTile) {
|
||||
|
||||
mMapGeneratorJob = mapGeneratorJob;
|
||||
// mMapGeneratorJob = mapGeneratorJob;
|
||||
processedTile = false;
|
||||
mMapView.requestRender();
|
||||
|
||||
@ -344,11 +335,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
} else {
|
||||
z = 1.0f / (1 << -diff);
|
||||
}
|
||||
drawX = MercatorProjection
|
||||
.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
||||
tile.zoomLevel);
|
||||
drawY = MercatorProjection
|
||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
||||
// drawX = MercatorProjection
|
||||
// .longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
||||
// tile.zoomLevel);
|
||||
// drawY = MercatorProjection
|
||||
// .latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
||||
|
||||
}
|
||||
|
||||
@ -430,71 +421,71 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
||||
|
||||
// lock position and currentTiles while drawing
|
||||
synchronized (this) {
|
||||
if (mMapGeneratorJob != null) {
|
||||
|
||||
tile = (GLMapTile) mMapGeneratorJob.tile;
|
||||
// TODO tile bitmaps texture to smaller parts avoiding uploading full
|
||||
// bitmap when not necessary
|
||||
if (tile.getTexture() >= 0) {
|
||||
// reuse tile texture
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||
mMapGeneratorJob.getBitmap());
|
||||
} else if (mTextures.size() > 0) {
|
||||
// reuse texture from previous tiles
|
||||
Integer texture;
|
||||
texture = mTextures.remove(mTextures.size() - 1);
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||
mMapGeneratorJob.getBitmap());
|
||||
tile.setTexture(texture.intValue());
|
||||
} else {
|
||||
// create texture
|
||||
tile.setTexture(GlUtils.loadTextures(mMapGeneratorJob.getBitmap()));
|
||||
}
|
||||
|
||||
tile.setScale(mMapGeneratorJob.getScale());
|
||||
tile.isReady = true;
|
||||
tile.isLoading = false;
|
||||
|
||||
mMapGeneratorJob = null;
|
||||
processedTile = true;
|
||||
// loadedTexture = true;
|
||||
}
|
||||
int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
||||
int hWidth = mWidth >> 1;
|
||||
int hHeight = mHeight >> 1;
|
||||
for (int i = 0, n = currentTileCnt; i < n; i++) {
|
||||
tile = currentTiles[i];
|
||||
|
||||
float x = (float) (tile.pixelX - mDrawX);
|
||||
float y = (float) (tile.pixelY - mDrawY);
|
||||
|
||||
// clip rendering to tile boundaries
|
||||
GLES20.glScissor(
|
||||
hWidth + (int) (x * mMapScale) - 2,
|
||||
hHeight - (int) (y * mMapScale) - tileSize - 2,
|
||||
tileSize + 4, tileSize + 4);
|
||||
|
||||
if (drawTile(tile, 0, 0.0f))
|
||||
continue;
|
||||
|
||||
// or two zoom level above
|
||||
for (int k = 0; k < 4; k++) {
|
||||
if (((child = tile.child[k]) != null)) {
|
||||
|
||||
if (drawTile(child, 2, 0.1f))
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
if ((child2 = child.child[j]) != null)
|
||||
drawTile(child2, 2, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// synchronized (this) {
|
||||
// if (mMapGeneratorJob != null) {
|
||||
//
|
||||
// tile = (GLMapTile) mMapGeneratorJob.tile;
|
||||
// // TODO tile bitmaps texture to smaller parts avoiding uploading full
|
||||
// // bitmap when not necessary
|
||||
// if (tile.getTexture() >= 0) {
|
||||
// // reuse tile texture
|
||||
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
||||
// GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||
// mMapGeneratorJob.getBitmap());
|
||||
// } else if (mTextures.size() > 0) {
|
||||
// // reuse texture from previous tiles
|
||||
// Integer texture;
|
||||
// texture = mTextures.remove(mTextures.size() - 1);
|
||||
//
|
||||
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
||||
// GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||
// mMapGeneratorJob.getBitmap());
|
||||
// tile.setTexture(texture.intValue());
|
||||
// } else {
|
||||
// // create texture
|
||||
// tile.setTexture(GlUtils.loadTextures(mMapGeneratorJob.getBitmap()));
|
||||
// }
|
||||
//
|
||||
// tile.setScale(mMapGeneratorJob.getScale());
|
||||
// tile.isReady = true;
|
||||
// tile.isLoading = false;
|
||||
//
|
||||
// mMapGeneratorJob = null;
|
||||
// processedTile = true;
|
||||
// // loadedTexture = true;
|
||||
// }
|
||||
// int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
||||
// int hWidth = mWidth >> 1;
|
||||
// int hHeight = mHeight >> 1;
|
||||
// for (int i = 0, n = currentTileCnt; i < n; i++) {
|
||||
// tile = currentTiles[i];
|
||||
//
|
||||
// float x = (float) (tile.pixelX - mDrawX);
|
||||
// float y = (float) (tile.pixelY - mDrawY);
|
||||
//
|
||||
// // clip rendering to tile boundaries
|
||||
// GLES20.glScissor(
|
||||
// hWidth + (int) (x * mMapScale) - 2,
|
||||
// hHeight - (int) (y * mMapScale) - tileSize - 2,
|
||||
// tileSize + 4, tileSize + 4);
|
||||
//
|
||||
// if (drawTile(tile, 0, 0.0f))
|
||||
// continue;
|
||||
//
|
||||
// // or two zoom level above
|
||||
// for (int k = 0; k < 4; k++) {
|
||||
// if (((child = tile.child[k]) != null)) {
|
||||
//
|
||||
// if (drawTile(child, 2, 0.1f))
|
||||
// continue;
|
||||
//
|
||||
// for (int j = 0; j < 4; j++)
|
||||
// if ((child2 = child.child[j]) != null)
|
||||
// drawTile(child2, 2, 0.1f);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -508,10 +499,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
|
||||
mDebugSettings = mMapView.getDebugSettings();
|
||||
mJobParameter = mMapView.getJobParameters();
|
||||
// mDebugSettings = mMapView.getDebugSettings();
|
||||
// mJobParameter = mMapView.getJobParameters();
|
||||
|
||||
mTiles.clear();
|
||||
// mTiles.clear();
|
||||
mTileList.clear();
|
||||
mTextures.clear();
|
||||
mInitial = true;
|
||||
@ -581,7 +572,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
@Override
|
||||
public IMapGenerator createMapGenerator() {
|
||||
return new MapGenerator();
|
||||
return new MapGenerator(mMapView);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -23,6 +23,7 @@ import org.mapsforge.database.MapFileInfo;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
@ -43,7 +44,6 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
@ -51,14 +51,14 @@ import android.widget.SeekBar;
|
||||
import android.widget.SpinnerAdapter;
|
||||
import android.widget.TextView;
|
||||
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
|
||||
* location. A simple file browser for selecting the map file is also included. Some preferences can be adjusted via the
|
||||
* {@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_SHOW_MY_LOCATION = "showMyLocation";
|
||||
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 boolean mShowMyLocation;
|
||||
private boolean mSnapToLocation;
|
||||
private ToggleButton mSnapToLocationView;
|
||||
// private ToggleButton mSnapToLocationView;
|
||||
private WakeLock mWakeLock;
|
||||
MapController mMapController;
|
||||
MapView mMapView;
|
||||
@ -86,12 +86,12 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
getMenuInflater().inflate(R.menu.options_menu, menu);
|
||||
else
|
||||
getMenuInflater().inflate(R.menu.options_menu_pre_honeycomb, menu);
|
||||
mMenu = menu;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -99,9 +99,9 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
// case R.id.menu_info_map_file:
|
||||
// showDialog(DIALOG_INFO_MAP_FILE);
|
||||
// return true;
|
||||
case R.id.menu_info_about:
|
||||
startActivity(new Intent(this, InfoView.class));
|
||||
return true;
|
||||
|
||||
case R.id.menu_position:
|
||||
return true;
|
||||
@ -161,6 +161,10 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
mMapView.setRenderTheme(InternalRenderTheme.OSMARENDER);
|
||||
return true;
|
||||
|
||||
case R.id.menu_render_theme_tronrender:
|
||||
mMapView.setRenderTheme(InternalRenderTheme.TRONRENDER);
|
||||
return true;
|
||||
|
||||
case R.id.menu_render_theme_select_file:
|
||||
startRenderThemePicker();
|
||||
return true;
|
||||
@ -176,6 +180,10 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.clear();
|
||||
onCreateOptionsMenu(menu);
|
||||
|
||||
Log.d("TileMap", "prepare options...");
|
||||
|
||||
// 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_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
|
||||
@ -227,7 +241,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
mMyLocationListener.setCenterAtFirstFix(centerAtFirstFix);
|
||||
mLocationManager.requestLocationUpdates(bestProvider, 1000, 0,
|
||||
mMyLocationListener);
|
||||
mSnapToLocationView.setVisibility(View.VISIBLE);
|
||||
// mSnapToLocationView.setVisibility(View.VISIBLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -323,17 +337,18 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
mMapView = (MapView) findViewById(R.id.mapView);
|
||||
configureMapView();
|
||||
|
||||
mSnapToLocationView = (ToggleButton) findViewById(R.id.snapToLocationView);
|
||||
mSnapToLocationView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (isSnapToLocationEnabled()) {
|
||||
disableSnapToLocation(true);
|
||||
} else {
|
||||
enableSnapToLocation(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
// mSnapToLocationView = (ToggleButton) findViewById(R.id.snapToLocationView);
|
||||
//
|
||||
// mSnapToLocationView.setOnClickListener(new OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View view) {
|
||||
// if (isSnapToLocationEnabled()) {
|
||||
// disableSnapToLocation(true);
|
||||
// } else {
|
||||
// enableSnapToLocation(true);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// get the pointers to different system services
|
||||
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
@ -404,7 +419,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
builder.setPositiveButton(R.string.ok, null);
|
||||
return builder.create();
|
||||
} else {
|
||||
// do dialog will be created
|
||||
// no dialog will be created
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -533,40 +548,31 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
|
||||
if (preferences.contains("mapDatabase")) {
|
||||
String name = preferences.getString("mapDatabase",
|
||||
MapDatabases.POSTGIS_READER.name());
|
||||
MapDatabases.PBMAP_READER.name());
|
||||
|
||||
MapDatabases mapDatabaseNew;
|
||||
|
||||
try {
|
||||
mapDatabaseNew = MapDatabases.valueOf(name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
mapDatabaseNew = MapDatabases.POSTGIS_READER;
|
||||
mapDatabaseNew = MapDatabases.PBMAP_READER;
|
||||
}
|
||||
|
||||
// mapDatabaseInternalNew = MapDatabaseInternal.PBMAP_READER;
|
||||
Log.d("VectorTileMap", "set map database " + mapDatabaseNew);
|
||||
|
||||
if (mapDatabaseNew != mMapDatabase) {
|
||||
mMapView.setMapDatabase(mapDatabaseNew);
|
||||
mMapDatabase = mapDatabaseNew;
|
||||
}
|
||||
|
||||
// if (mapDatabaseNew != mMapDatabase) {
|
||||
// IMapDatabase mapDatabase = MapDatabaseFactory
|
||||
// .createMapDatabase(mapDatabaseNew);
|
||||
//
|
||||
// mMapView.setMapDatabase(mapDatabase);
|
||||
// mMapDatabase = mapDatabaseNew;
|
||||
// }
|
||||
}
|
||||
|
||||
try {
|
||||
String textScaleDefault = getString(R.string.preferences_text_scale_default);
|
||||
mMapView.setTextScale(Float.parseFloat(preferences.getString("textScale",
|
||||
textScaleDefault)));
|
||||
} catch (NumberFormatException e) {
|
||||
mMapView.setTextScale(1);
|
||||
}
|
||||
// try {
|
||||
// String textScaleDefault = getString(R.string.preferences_text_scale_default);
|
||||
// mMapView.setTextScale(Float.parseFloat(preferences.getString("textScale",
|
||||
// textScaleDefault)));
|
||||
// } catch (NumberFormatException e) {
|
||||
// mMapView.setTextScale(1);
|
||||
// }
|
||||
|
||||
if (preferences.getBoolean("fullscreen", false)) {
|
||||
Log.i("mapviewer", "FULLSCREEN");
|
||||
@ -601,6 +607,18 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
} else {
|
||||
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
|
||||
@ -628,7 +646,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
// circleOverlay = null;
|
||||
// itemizedOverlay = null;
|
||||
// }
|
||||
mSnapToLocationView.setVisibility(View.GONE);
|
||||
// mSnapToLocationView.setVisibility(View.GONE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -643,7 +661,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
void disableSnapToLocation(boolean showToast) {
|
||||
if (mSnapToLocation) {
|
||||
mSnapToLocation = false;
|
||||
mSnapToLocationView.setChecked(false);
|
||||
// mSnapToLocationView.setChecked(false);
|
||||
mMapView.setClickable(true);
|
||||
if (showToast) {
|
||||
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.filefilter.ValidFileFilter;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
@ -223,13 +225,16 @@ public class FilePicker extends Activity implements AdapterView.OnItemClickListe
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
@TargetApi(11)
|
||||
@Override
|
||||
protected void 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
|
||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
|
||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
||||
// false)) {
|
||||
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
// } else {
|
||||
|
||||
@ -16,6 +16,8 @@ package org.mapsforge.app.preferences;
|
||||
|
||||
import org.mapsforge.app.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
@ -29,10 +31,13 @@ public class EditPreferences extends PreferenceActivity {
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
}
|
||||
|
||||
@TargetApi(11)
|
||||
@Override
|
||||
protected void 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
|
||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
||||
|
||||
@ -14,21 +14,16 @@
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
||||
public class GeoPoint implements Comparable<GeoPoint> {
|
||||
/**
|
||||
* Conversion factor from degrees to microdegrees.
|
||||
*/
|
||||
private static final double CONVERSION_FACTOR = 1000000d;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private transient int hashCodeValue;
|
||||
private int hashCodeValue = 0;
|
||||
|
||||
/**
|
||||
* @param latitude
|
||||
@ -57,7 +52,6 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
||||
double limitLongitude = MercatorProjection.limitLongitude(longitude);
|
||||
this.longitudeE6 = (int) (limitLongitude * CONVERSION_FACTOR);
|
||||
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,6 +110,9 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (this.hashCodeValue == 0)
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
|
||||
return this.hashCodeValue;
|
||||
}
|
||||
|
||||
@ -139,9 +136,4 @@ public class GeoPoint implements Comparable<GeoPoint>, Serializable {
|
||||
result = 31 * result + this.longitudeE6;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
||||
objectInputStream.defaultReadObject();
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,20 +14,17 @@
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public class MapPosition implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public class MapPosition {
|
||||
|
||||
/**
|
||||
* The map position.
|
||||
*/
|
||||
public final GeoPoint geoPoint;
|
||||
// public final GeoPoint geoPoint;
|
||||
public final double lon;
|
||||
public final double lat;
|
||||
|
||||
/**
|
||||
* The zoom level.
|
||||
@ -38,10 +35,11 @@ public class MapPosition implements Serializable {
|
||||
* 1.0 - 2.0 scale of current zoomlevel
|
||||
*/
|
||||
public final float scale;
|
||||
/**
|
||||
* The hash code of this object.
|
||||
*/
|
||||
private transient int hashCodeValue;
|
||||
|
||||
public final float angle;
|
||||
|
||||
public final double x;
|
||||
public final double y;
|
||||
|
||||
/**
|
||||
* @param geoPoint
|
||||
@ -51,62 +49,40 @@ public class MapPosition implements Serializable {
|
||||
* @param scale
|
||||
* ...
|
||||
*/
|
||||
|
||||
public MapPosition(GeoPoint geoPoint, byte zoomLevel, float scale) {
|
||||
this.geoPoint = geoPoint;
|
||||
// this.geoPoint = geoPoint;
|
||||
this.zoomLevel = zoomLevel;
|
||||
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 boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
} else if (!(obj instanceof MapPosition)) {
|
||||
return false;
|
||||
}
|
||||
MapPosition other = (MapPosition) obj;
|
||||
if (this.geoPoint == null) {
|
||||
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;
|
||||
public MapPosition(double latitude, double longitude, byte zoomLevel, float scale,
|
||||
float angle) {
|
||||
this.zoomLevel = zoomLevel;
|
||||
this.scale = scale;
|
||||
this.lat = latitude;
|
||||
this.lon = longitude;
|
||||
this.angle = angle;
|
||||
this.x = MercatorProjection.longitudeToPixelX(longitude, zoomLevel);
|
||||
this.y = MercatorProjection.latitudeToPixelY(latitude, zoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
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(this.zoomLevel);
|
||||
builder.append("]");
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
@ -102,6 +109,16 @@ public final class MercatorProjection {
|
||||
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.
|
||||
*
|
||||
@ -115,6 +132,11 @@ public final class MercatorProjection {
|
||||
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.
|
||||
*
|
||||
@ -150,8 +172,9 @@ public final class MercatorProjection {
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the tile X number.
|
||||
*/
|
||||
public static long pixelXToTileX(double pixelX, byte zoomLevel) {
|
||||
return (long) Math.min(Math.max(pixelX / Tile.TILE_SIZE, 0), Math.pow(2, zoomLevel) - 1);
|
||||
public static int pixelXToTileX(double pixelX, byte zoomLevel) {
|
||||
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.
|
||||
* @return the tile Y number.
|
||||
*/
|
||||
public static long pixelYToTileY(double pixelY, byte zoomLevel) {
|
||||
return (long) Math.min(Math.max(pixelY / Tile.TILE_SIZE, 0), Math.pow(2, zoomLevel) - 1);
|
||||
public static int pixelYToTileY(double pixelY, byte zoomLevel) {
|
||||
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;
|
||||
|
||||
private transient int hashCodeValue;
|
||||
private transient int hashCodeValue = 0;
|
||||
|
||||
/**
|
||||
* @param tag
|
||||
@ -63,7 +63,6 @@ public class Tag {
|
||||
}
|
||||
this.key = tag.substring(0, splitPosition).intern();
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
public Tag(String tag, boolean hashValue) {
|
||||
@ -76,8 +75,6 @@ public class Tag {
|
||||
this.value = tag.substring(splitPosition + 1);
|
||||
else
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +86,6 @@ public class Tag {
|
||||
public Tag(String key, String value) {
|
||||
this.key = (key == null ? null : key.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.value = (value == null ? null : value);
|
||||
}
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,14 +116,17 @@ public class Tag {
|
||||
}
|
||||
Tag other = (Tag) obj;
|
||||
|
||||
if ((this.key != other.key) || (this.value != other.value))
|
||||
return false;
|
||||
if ((this.key == other.key) && (this.value == other.value))
|
||||
return true;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (this.hashCodeValue == 0)
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public final long tileX;
|
||||
public final int tileX;
|
||||
|
||||
/**
|
||||
* The Y number of this tile.
|
||||
*/
|
||||
public final long tileY;
|
||||
public final int tileY;
|
||||
|
||||
/**
|
||||
* The Zoom level of this tile.
|
||||
*/
|
||||
public final byte zoomLevel;
|
||||
|
||||
private transient int hashCodeValue;
|
||||
/**
|
||||
* the pixel X coordinate of the upper left corner of this tile.
|
||||
*/
|
||||
@ -70,51 +59,12 @@ public class Tile {
|
||||
* @param zoomLevel
|
||||
* 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.tileY = tileY;
|
||||
this.pixelX = this.tileX * TILE_SIZE;
|
||||
this.pixelY = this.tileY * TILE_SIZE;
|
||||
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
|
||||
@ -130,14 +80,34 @@ public class Tile {
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash code of this object.
|
||||
*/
|
||||
private int calculateHashCode() {
|
||||
int result = 7;
|
||||
result = 31 * result + (int) (this.tileX ^ (this.tileX >>> 32));
|
||||
result = 31 * result + (int) (this.tileY ^ (this.tileY >>> 32));
|
||||
result = 31 * result + this.zoomLevel;
|
||||
return result;
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof Tile))
|
||||
return false;
|
||||
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -46,6 +50,7 @@ import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.MapFileInfo;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
@ -62,6 +67,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
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/osmstache/test/%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");
|
||||
|
||||
private static final int MAX_TAGS_CACHE = 100;
|
||||
|
||||
private static Map<String, Tag> tagHash = Collections
|
||||
.synchronizedMap(new LinkedHashMap<String, Tag>(
|
||||
MAX_TAGS_CACHE, 0.75f, true) {
|
||||
@ -79,8 +90,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
protected boolean removeEldestEntry(Entry<String, Tag> e) {
|
||||
if (size() < MAX_TAGS_CACHE)
|
||||
return false;
|
||||
|
||||
// Log.d(TAG, "cache: drop " + e.getValue());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -92,30 +101,72 @@ public class MapDatabase implements IMapDatabase {
|
||||
private int mCurTagCnt;
|
||||
|
||||
private HttpClient mClient;
|
||||
private HttpGet mRequest = null;
|
||||
|
||||
private IMapDatabaseCallback mMapGenerator;
|
||||
private float mScaleFactor;
|
||||
private HttpGet mRequest = null;
|
||||
private Tile mTile;
|
||||
|
||||
private FileOutputStream mCacheFile;
|
||||
|
||||
@Override
|
||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
mCanceled = false;
|
||||
// mCanceled = false;
|
||||
mCacheFile = null;
|
||||
|
||||
// just used for debugging ....
|
||||
mTile = 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;
|
||||
mCurTagCnt = 0;
|
||||
|
||||
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 {
|
||||
|
||||
// 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);
|
||||
final int statusCode = response.getStatusLine().getStatusCode();
|
||||
final HttpEntity entity = response.getEntity();
|
||||
@ -125,10 +176,10 @@ public class MapDatabase implements IMapDatabase {
|
||||
entity.consumeContent();
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
if (mTile.isCanceled) {
|
||||
Log.d(TAG, "1 loading canceled " + mTile);
|
||||
entity.consumeContent();
|
||||
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
@ -136,6 +187,16 @@ public class MapDatabase implements IMapDatabase {
|
||||
// GZIPInputStream zis = null;
|
||||
try {
|
||||
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);
|
||||
|
||||
decode(is);
|
||||
@ -149,15 +210,22 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
} catch (SocketException ex) {
|
||||
Log.d(TAG, "Socket exception: " + ex.getMessage());
|
||||
// f.delete();
|
||||
return QueryResult.FAILED;
|
||||
} catch (SocketTimeoutException ex) {
|
||||
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;
|
||||
} catch (Exception ex) {
|
||||
getRequest.abort();
|
||||
// f.delete();
|
||||
ex.printStackTrace();
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
mRequest = null;
|
||||
|
||||
if (mTile.isCanceled) {
|
||||
@ -165,11 +233,21 @@ public class MapDatabase implements IMapDatabase {
|
||||
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;
|
||||
}
|
||||
|
||||
private static File cacheDir;
|
||||
|
||||
@Override
|
||||
public String getMapProjection() {
|
||||
return null;
|
||||
@ -190,11 +268,14 @@ public class MapDatabase implements IMapDatabase {
|
||||
HttpParams params = new BasicHttpParams();
|
||||
HttpConnectionParams.setStaleCheckingEnabled(params, false);
|
||||
|
||||
HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
|
||||
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
|
||||
HttpConnectionParams.setSoTimeout(params, 60 * 1000);
|
||||
HttpConnectionParams.setSocketBufferSize(params, 16384);
|
||||
mClient = new DefaultHttpClient(params);
|
||||
HttpConnectionParams.setSocketBufferSize(params, 32768);
|
||||
HttpClientParams.setRedirecting(params, false);
|
||||
// HttpClientParams.setCookiePolicy(params, CookiePolicy.ACCEPT_NONE);
|
||||
|
||||
mClient = new DefaultHttpClient(params);
|
||||
|
||||
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
||||
schemeRegistry.register(new Scheme("http",
|
||||
PlainSocketFactory.getSocketFactory(), 80));
|
||||
@ -202,16 +283,33 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
@Override
|
||||
public FileOpenResult openFile(File mapFile) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeFile() {
|
||||
mOpenFile = false;
|
||||
if (mClient != null)
|
||||
if (mClient != null) {
|
||||
mClient.getConnectionManager().shutdown();
|
||||
mClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -219,12 +317,31 @@ public class MapDatabase implements IMapDatabase {
|
||||
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 // // //
|
||||
private static final int BUFFER_SIZE = 65536;
|
||||
|
||||
private final byte[] buffer = new byte[BUFFER_SIZE];
|
||||
// position in read buffer
|
||||
private int bufferPos;
|
||||
// bytes available in read buffer
|
||||
private int bufferSize;
|
||||
// (bytesRead - bufferPos) + bufferSize
|
||||
// private int bufferLimit;
|
||||
// bytes processed
|
||||
private int bytesRead;
|
||||
private InputStream inputStream;
|
||||
|
||||
@ -256,8 +373,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
while ((val = decodeVarint32()) > 0) {
|
||||
// read tag and wire type
|
||||
int tag = (val >> 3);
|
||||
// int wireType = (val & 7);
|
||||
// Log.d(TAG, "tile " + tag + " " + wireType);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_TILE_TAGS:
|
||||
@ -286,7 +401,13 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
private boolean decodeTileTags() throws IOException {
|
||||
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);
|
||||
|
||||
if (tag == null) {
|
||||
@ -298,7 +419,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
tagHash.put(tagString, tag);
|
||||
}
|
||||
|
||||
// FIXME ...
|
||||
if (mCurTagCnt >= MAX_TILE_TAGS) {
|
||||
MAX_TILE_TAGS = mCurTagCnt + 10;
|
||||
Tag[] tmp = new Tag[MAX_TILE_TAGS];
|
||||
@ -331,9 +451,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
// int wireType = val & 7;
|
||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
||||
int cnt;
|
||||
|
||||
switch (tag) {
|
||||
case TAG_WAY_TAGS:
|
||||
@ -345,9 +462,9 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
case TAG_WAY_COORDS:
|
||||
cnt = decodeWayCoordinates(skip);
|
||||
int cnt = decodeWayCoordinates(skip);
|
||||
if (cnt != coordCnt) {
|
||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
||||
Log.d(TAG, "X wrong number of coordintes");
|
||||
fail = true;
|
||||
}
|
||||
break;
|
||||
@ -369,20 +486,20 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
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) {
|
||||
Log.d(TAG, "..." + index + " " + (tags != null ? tags[0] : "...") + " "
|
||||
+ indexCnt + " " + coordCnt + " "
|
||||
+ tagCnt);
|
||||
Log.d(TAG, "failed reading way: bytes:" + bytes + " index:" + index + " tag:"
|
||||
+ (tags != null ? tags[0] : "...") + " "
|
||||
+ indexCnt + " " + coordCnt + " " + tagCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
float[] coords = tmpCoords;
|
||||
|
||||
// FIXME !!!!!
|
||||
// FIXME, remove all tiles from cache then remove this below
|
||||
if (layer == 0)
|
||||
layer = 5;
|
||||
|
||||
@ -393,8 +510,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
private boolean decodeTileNodes() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
// Log.d(TAG, "decode nodes " + bytes);
|
||||
|
||||
int end = bytesRead + bytes;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
@ -408,9 +523,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
// int wireType = val & 7;
|
||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
||||
int cnt;
|
||||
|
||||
switch (tag) {
|
||||
case TAG_NODE_TAGS:
|
||||
@ -418,9 +530,9 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
case TAG_NODE_COORDS:
|
||||
cnt = decodeNodeCoordinates(coordCnt, layer, tags);
|
||||
int cnt = decodeNodeCoordinates(coordCnt, layer, tags);
|
||||
if (cnt != coordCnt) {
|
||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
||||
Log.d(TAG, "X wrong number of coordintes");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -438,7 +550,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
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 lastY = 0;
|
||||
while (bufferPos < end && cnt < numNodes) {
|
||||
int lon = decodeZigZag32(decodeVarint32()); // * mScaleFactor;
|
||||
int lat = decodeZigZag32(decodeVarint32()); // * mScaleFactor;
|
||||
int lon = decodeZigZag32(decodeVarint32());
|
||||
int lat = decodeZigZag32(decodeVarint32());
|
||||
lastX = lon + lastX;
|
||||
lastY = lat + lastY;
|
||||
|
||||
mMapGenerator.renderPointOfInterest(layer,
|
||||
lastY / scale,
|
||||
lastX / scale,
|
||||
tags);
|
||||
lastY / scale, lastX / scale, tags);
|
||||
cnt += 2;
|
||||
}
|
||||
return cnt;
|
||||
@ -500,8 +610,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
|
||||
tags[cnt++] = curTags[tagNum];
|
||||
} else {
|
||||
Log.d(TAG, "NULL TAG: " + mTile + " could find tag:" + tagNum + " "
|
||||
+ tagCnt + "/" + cnt);
|
||||
Log.d(TAG, "NULL TAG: " + mTile + " could find tag:"
|
||||
+ tagNum + " " + tagCnt + "/" + cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -573,41 +683,38 @@ public class MapDatabase implements IMapDatabase {
|
||||
if (buf[pos] >= 0) {
|
||||
result = buf[pos++];
|
||||
} else if (buf[pos + 1] >= 0) {
|
||||
result = buf[pos] & 0x7f
|
||||
result = (buf[pos] & 0x7f)
|
||||
| buf[pos + 1] << 7;
|
||||
pos += 2;
|
||||
} else if (buf[pos + 2] >= 0) {
|
||||
result = buf[pos] & 0x7f
|
||||
| buf[pos + 1] << 7
|
||||
| buf[pos + 2] << 14;
|
||||
result = (buf[pos] & 0x7f)
|
||||
| (buf[pos + 1] & 0x7f) << 7
|
||||
| (buf[pos + 2]) << 14;
|
||||
pos += 3;
|
||||
} else if (buf[pos + 3] >= 0) {
|
||||
result = buf[pos] & 0x7f
|
||||
| buf[pos + 1] << 7
|
||||
| buf[pos + 2] << 14
|
||||
| buf[pos + 3] << 21;
|
||||
result = (buf[pos] & 0x7f)
|
||||
| (buf[pos + 1] & 0x7f) << 7
|
||||
| (buf[pos + 2] & 0x7f) << 14
|
||||
| (buf[pos + 3]) << 21;
|
||||
pos += 4;
|
||||
Log.d(TAG, "4 Stuffs too large " + mTile);
|
||||
} else {
|
||||
result = buf[pos] & 0x7f
|
||||
| buf[pos + 1] << 7
|
||||
| buf[pos + 2] << 14
|
||||
| buf[pos + 3] << 21
|
||||
| buf[pos + 4] << 28;
|
||||
pos += 5;
|
||||
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, "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) {
|
||||
x = ((result >>> 1) ^ -(result & 1));
|
||||
@ -628,70 +735,120 @@ public class MapDatabase implements IMapDatabase {
|
||||
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 (len < 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 (bufferPos + size < bufferSize)
|
||||
return 0;
|
||||
|
||||
if (size > BUFFER_SIZE) {
|
||||
// FIXME throw exception for now, but frankly better
|
||||
// sanitize tile data on compilation.
|
||||
// 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) {
|
||||
// copy bytes left to read from buffer to the beginning of buffer
|
||||
System.arraycopy(buffer, bufferPos, buffer, 0, bufferSize - bufferPos);
|
||||
if (bufferSize == bufferPos) {
|
||||
bufferPos = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
while ((bufferSize - bufferPos) < size) {
|
||||
if (mTile.isCanceled) {
|
||||
throw new IOException("canceled " + mTile);
|
||||
}
|
||||
|
||||
// read until requested size is available in buffer
|
||||
int len = inputStream.read(buffer, bufferSize, BUFFER_SIZE - bufferSize);
|
||||
|
||||
if (len < 0) {
|
||||
buffer[bufferSize - 1] = 0; // FIXME is this needed?
|
||||
// finished reading, mark end
|
||||
buffer[bufferSize] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
read += len;
|
||||
|
||||
if (mCacheFile != null)
|
||||
mCacheFile.write(buffer, bufferSize, len);
|
||||
|
||||
bufferSize += len;
|
||||
|
||||
if (mCanceled)
|
||||
throw new IOException("... canceld?");
|
||||
}
|
||||
|
||||
// Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
|
||||
// + bufferSize
|
||||
// + ", read " + bytesRead);
|
||||
return read;
|
||||
}
|
||||
|
||||
private boolean mCanceled;
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
mCanceled = true;
|
||||
if (mRequest != null) {
|
||||
mRequest.abort();
|
||||
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: */
|
||||
|
||||
// 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
|
||||
// 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 {
|
||||
final int size = decodeVarint32();
|
||||
|
||||
readBuffer(size);
|
||||
|
||||
final String result = new String(buffer, bufferPos, size, "UTF-8");
|
||||
// Log.d(TAG, "read string " + read + " " + size + " " + bufferPos + " " + result);
|
||||
|
||||
bufferPos += size;
|
||||
bytesRead += size;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public static int decodeZigZag32(final int n) {
|
||||
private static int decodeZigZag32(final int n) {
|
||||
return (n >>> 1) ^ -(n & 1);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user