- adding MapDatabase backend for our TileStache provider
- fixing some renering bugs on nexus phone and some refactoring and cleanup
This commit is contained in:
parent
c5c952bf14
commit
124624785d
@ -12,14 +12,15 @@
|
|||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="10"
|
android:minSdkVersion="10"
|
||||||
android:targetSdkVersion="15" />
|
android:targetSdkVersion="16" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/globe2"
|
android:icon="@drawable/globe2"
|
||||||
android:label="@string/application_name"
|
android:label="@string/application_name"
|
||||||
android:theme="@style/Theme.TileMap" >
|
android:theme="@style/Theme.TileMap" >
|
||||||
|
<activity
|
||||||
<activity android:name="org.mapsforge.app.TileMap" >
|
android:name="org.mapsforge.app.TileMap"
|
||||||
|
android:configChanges="orientation|screenSize" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
@ -28,6 +29,6 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".preferences.EditPreferences" />
|
<activity android:name=".preferences.EditPreferences" />
|
||||||
<activity android:name=".filepicker.FilePicker" />
|
<activity android:name=".filepicker.FilePicker" />
|
||||||
|
</application>
|
||||||
|
|
||||||
</application>
|
</manifest>
|
||||||
</manifest>
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/mainView"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<org.mapsforge.android.MapView
|
|
||||||
android:id="@+id/mapView"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent" />
|
|
||||||
|
|
||||||
<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_marginRight="10dip"
|
|
||||||
android:layout_marginTop="10dip"
|
|
||||||
android:background="@drawable/snap_to_position"
|
|
||||||
android:textOff=""
|
|
||||||
android:textOn=""
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
71
res/menu/options_menu_pre_honeycomb.xml
Normal file
71
res/menu/options_menu_pre_honeycomb.xml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position"
|
||||||
|
android:icon="@drawable/ic_menu_mylocation"
|
||||||
|
android:showAsAction="always"
|
||||||
|
android:title="@string/menu_position">
|
||||||
|
<menu>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position_my_location_enable"
|
||||||
|
android:title="@string/menu_position_my_location_enable"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position_my_location_disable"
|
||||||
|
android:title="@string/menu_position_my_location_disable"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position_last_known"
|
||||||
|
android:title="@string/menu_position_last_known"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position_enter_coordinates"
|
||||||
|
android:title="@string/menu_position_enter_coordinates"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_position_map_center"
|
||||||
|
android:title="@string/menu_position_map_file_center"/>
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_options"
|
||||||
|
android:icon="@drawable/ic_menu_options"
|
||||||
|
android:showAsAction="always"
|
||||||
|
android:title="@string/menu_options">
|
||||||
|
|
||||||
|
<menu>
|
||||||
|
<!-- android:icon="@drawable/ic_menu_preferences" -->
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_preferences"
|
||||||
|
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/menu_preferences"/>
|
||||||
|
<!-- android:icon="@drawable/ic_menu_mapmode" -->
|
||||||
|
|
||||||
|
<!-- android:icon="@drawable/ic_menu_archive" -->
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_mapfile"
|
||||||
|
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/menu_mapfile"/>
|
||||||
|
<!-- <item
|
||||||
|
android:id="@+id/menu_info_map_file"
|
||||||
|
android:title="@string/menu_info_map_file"/> -->
|
||||||
|
</menu>
|
||||||
|
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_render_theme"
|
||||||
|
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/menu_render_theme">
|
||||||
|
<menu>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_render_theme_osmarender"
|
||||||
|
android:title="@string/menu_render_theme_osmarender"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_render_theme_select_file"
|
||||||
|
android:title="@string/menu_render_theme_select_file"/>
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
|
||||||
|
</menu>
|
||||||
@ -3,6 +3,7 @@
|
|||||||
<string-array name="preferences_map_generator_values">
|
<string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="preferences_scale_bar_unit_values">
|
<string-array name="preferences_scale_bar_unit_values">
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<string-array name="preferences_map_generator_values">
|
<string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="preferences_text_scale_values">
|
<string-array name="preferences_text_scale_values">
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<string-array name="preferences_map_generator_values">
|
<string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="preferences_text_scale_values">
|
<string-array name="preferences_text_scale_values">
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<string-array name="preferences_map_database_keys">
|
<string-array name="preferences_map_database_keys">
|
||||||
<item>MAP_READER</item>
|
<item>MAP_READER</item>
|
||||||
<item>POSTGIS_READER</item>
|
<item>POSTGIS_READER</item>
|
||||||
|
<item>PBMAP_READER</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="preferences_map_database_default">POSTGIS_READER</string>
|
<string name="preferences_map_database_default">POSTGIS_READER</string>
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<string-array name="preferences_map_generator_values">
|
<string-array name="preferences_map_generator_values">
|
||||||
<item>Mapfile</item>
|
<item>Mapfile</item>
|
||||||
<item>PostGIS</item>
|
<item>PostGIS</item>
|
||||||
|
<item>OpenScienceMap</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="preferences_scale_bar_unit_values">
|
<string-array name="preferences_scale_bar_unit_values">
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android;
|
package org.mapsforge.android;
|
||||||
|
|
||||||
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
|
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
@ -21,7 +22,7 @@ import android.opengl.GLSurfaceView;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface MapRenderer extends GLSurfaceView.Renderer {
|
public interface IMapRenderer extends GLSurfaceView.Renderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapGeneratorJob
|
* @param mapGeneratorJob
|
||||||
@ -31,9 +32,8 @@ public interface MapRenderer extends GLSurfaceView.Renderer {
|
|||||||
public boolean passTile(MapGeneratorJob mapGeneratorJob);
|
public boolean passTile(MapGeneratorJob mapGeneratorJob);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true when tile passed to renderer is processed false otherwise.
|
* @return true when tile passed to renderer is processed false otherwise. used to lock overwriting resources passed
|
||||||
* used to lock overwriting resources passed with the tile
|
* with the tile (e.g. lock until bitmap is loaded to texture)
|
||||||
* (e.g. lock until bitmap is loaded to texture)
|
|
||||||
*/
|
*/
|
||||||
public boolean processedTile();
|
public boolean processedTile();
|
||||||
|
|
||||||
@ -44,4 +44,6 @@ public interface MapRenderer extends GLSurfaceView.Renderer {
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
public void redrawTiles(boolean clear);
|
public void redrawTiles(boolean clear);
|
||||||
|
|
||||||
|
public IMapGenerator createMapGenerator();
|
||||||
}
|
}
|
||||||
@ -16,25 +16,35 @@ package org.mapsforge.android;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.mapsforge.android.input.TouchHandler;
|
import org.mapsforge.android.input.TouchHandler;
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
import org.mapsforge.android.mapgenerator.JobParameters;
|
||||||
import org.mapsforge.android.mapgenerator.JobQueue;
|
import org.mapsforge.android.mapgenerator.JobQueue;
|
||||||
import org.mapsforge.android.mapgenerator.JobTheme;
|
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabaseInternal;
|
import org.mapsforge.android.mapgenerator.MapDatabases;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorFactory;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorInternal;
|
import org.mapsforge.android.mapgenerator.MapRendererFactory;
|
||||||
|
import org.mapsforge.android.mapgenerator.MapRenderers;
|
||||||
import org.mapsforge.android.mapgenerator.MapWorker;
|
import org.mapsforge.android.mapgenerator.MapWorker;
|
||||||
|
import org.mapsforge.android.mapgenerator.Theme;
|
||||||
import org.mapsforge.android.rendertheme.ExternalRenderTheme;
|
import org.mapsforge.android.rendertheme.ExternalRenderTheme;
|
||||||
import org.mapsforge.android.rendertheme.InternalRenderTheme;
|
import org.mapsforge.android.rendertheme.InternalRenderTheme;
|
||||||
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
|
import org.mapsforge.android.rendertheme.RenderThemeHandler;
|
||||||
import org.mapsforge.android.utils.GlConfigChooser;
|
import org.mapsforge.android.utils.GlConfigChooser;
|
||||||
import org.mapsforge.core.GeoPoint;
|
import org.mapsforge.core.GeoPoint;
|
||||||
import org.mapsforge.core.MapPosition;
|
import org.mapsforge.core.MapPosition;
|
||||||
import org.mapsforge.database.FileOpenResult;
|
import org.mapsforge.database.FileOpenResult;
|
||||||
import org.mapsforge.database.IMapDatabase;
|
import org.mapsforge.database.IMapDatabase;
|
||||||
|
import org.mapsforge.database.MapFileInfo;
|
||||||
import org.mapsforge.database.mapfile.MapDatabase;
|
import org.mapsforge.database.mapfile.MapDatabase;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
@ -49,8 +59,7 @@ import android.view.MotionEvent;
|
|||||||
* <p>
|
* <p>
|
||||||
* This implementation supports offline map rendering as well as downloading map images (tiles) over an Internet
|
* This implementation supports offline map rendering as well as downloading map images (tiles) over an Internet
|
||||||
* connection. The operation mode of a MapView can be set in the constructor and changed at runtime with the
|
* connection. The operation mode of a MapView can be set in the constructor and changed at runtime with the
|
||||||
* {@link #setMapGeneratorInternal(IMapGenerator)} method. Some MapView parameters depend on the selected operation
|
* {@link #setMapDatabase(MapDatabases)} method. Some MapView parameters depend on the selected operation mode.
|
||||||
* mode.
|
|
||||||
* <p>
|
* <p>
|
||||||
* In offline rendering mode a special database file is required which contains the map data. Map files can be stored in
|
* In offline rendering mode a special database file is required which contains the map data. Map files can be stored in
|
||||||
* any folder. The current map file is set by calling {@link #setMapFile(String)}. To retrieve the current
|
* any folder. The current map file is set by calling {@link #setMapFile(String)}. To retrieve the current
|
||||||
@ -67,12 +76,12 @@ public class MapView extends GLSurfaceView {
|
|||||||
public static final InternalRenderTheme DEFAULT_RENDER_THEME = InternalRenderTheme.OSMARENDER;
|
public static final InternalRenderTheme DEFAULT_RENDER_THEME = InternalRenderTheme.OSMARENDER;
|
||||||
|
|
||||||
private static final float DEFAULT_TEXT_SCALE = 1;
|
private static final float DEFAULT_TEXT_SCALE = 1;
|
||||||
|
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
||||||
|
|
||||||
private final MapController mMapController;
|
private final MapController mMapController;
|
||||||
// private final MapMover mMapMover;
|
// private final MapMover mMapMover;
|
||||||
// private final ZoomAnimator mZoomAnimator;
|
// private final ZoomAnimator mZoomAnimator;
|
||||||
|
// private final MapScaleBar mMapScaleBar;
|
||||||
private final MapScaleBar mMapScaleBar;
|
|
||||||
private final MapViewPosition mMapViewPosition;
|
private final MapViewPosition mMapViewPosition;
|
||||||
|
|
||||||
private final MapZoomControls mMapZoomControls;
|
private final MapZoomControls mMapZoomControls;
|
||||||
@ -80,10 +89,11 @@ public class MapView extends GLSurfaceView {
|
|||||||
private final TouchHandler mTouchEventHandler;
|
private final TouchHandler mTouchEventHandler;
|
||||||
|
|
||||||
private IMapDatabase mMapDatabase;
|
private IMapDatabase mMapDatabase;
|
||||||
private IMapGenerator mMapGenerator;
|
private MapDatabases mMapDatabaseType;
|
||||||
private MapRenderer mMapRenderer;
|
private IMapRenderer mMapRenderer;
|
||||||
private JobQueue mJobQueue;
|
private JobQueue mJobQueue;
|
||||||
private MapWorker mMapWorker;
|
private MapWorker mMapWorkers[];
|
||||||
|
private int mNumMapWorkers = 6;
|
||||||
private JobParameters mJobParameters;
|
private JobParameters mJobParameters;
|
||||||
private DebugSettings mDebugSettings;
|
private DebugSettings mDebugSettings;
|
||||||
private String mMapFile;
|
private String mMapFile;
|
||||||
@ -95,9 +105,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
* if the context object is not an instance of {@link MapActivity} .
|
* if the context object is not an instance of {@link MapActivity} .
|
||||||
*/
|
*/
|
||||||
public MapView(Context context) {
|
public MapView(Context context) {
|
||||||
this(context, null,
|
this(context, null, MapRenderers.GL_RENDERER, MapDatabases.MAP_READER);
|
||||||
MapGeneratorFactory.createMapGenerator(MapGeneratorInternal.GL_RENDERER),
|
|
||||||
MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.MAP_READER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,25 +118,12 @@ public class MapView extends GLSurfaceView {
|
|||||||
*/
|
*/
|
||||||
public MapView(Context context, AttributeSet attributeSet) {
|
public MapView(Context context, AttributeSet attributeSet) {
|
||||||
this(context, attributeSet,
|
this(context, attributeSet,
|
||||||
MapGeneratorFactory.createMapGenerator(attributeSet),
|
MapRendererFactory.getMapGenerator(attributeSet),
|
||||||
MapDatabaseFactory.createMapDatabase(attributeSet));
|
MapDatabaseFactory.getMapDatabase(attributeSet));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param context
|
|
||||||
* the enclosing MapActivity instance.
|
|
||||||
* @param mapGenerator
|
|
||||||
* the MapGenerator for this MapView.
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the context object is not an instance of {@link MapActivity} .
|
|
||||||
*/
|
|
||||||
public MapView(Context context, IMapGenerator mapGenerator) {
|
|
||||||
this(context, null, mapGenerator, MapDatabaseFactory
|
|
||||||
.createMapDatabase(MapDatabaseInternal.MAP_READER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapView(Context context, AttributeSet attributeSet,
|
private MapView(Context context, AttributeSet attributeSet,
|
||||||
IMapGenerator mapGenerator, IMapDatabase mapDatabase) {
|
MapRenderers mapGeneratorType, MapDatabases mapDatabaseType) {
|
||||||
|
|
||||||
super(context, attributeSet);
|
super(context, attributeSet);
|
||||||
|
|
||||||
@ -147,46 +142,63 @@ public class MapView extends GLSurfaceView {
|
|||||||
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
|
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
|
||||||
mMapController = new MapController(this);
|
mMapController = new MapController(this);
|
||||||
|
|
||||||
// mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.POSTGIS_READER);
|
mMapDatabaseType = mapDatabaseType;
|
||||||
// mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.JSON_READER);
|
|
||||||
mMapDatabase = mapDatabase;
|
|
||||||
|
|
||||||
mMapViewPosition = new MapViewPosition(this);
|
mMapViewPosition = new MapViewPosition(this);
|
||||||
mMapScaleBar = new MapScaleBar(this);
|
// mMapScaleBar = new MapScaleBar(this);
|
||||||
mMapZoomControls = new MapZoomControls(mapActivity, this);
|
mMapZoomControls = new MapZoomControls(mapActivity, this);
|
||||||
mProjection = new MapViewProjection(this);
|
mProjection = new MapViewProjection(this);
|
||||||
mTouchEventHandler = new TouchHandler(mapActivity, this);
|
mTouchEventHandler = new TouchHandler(mapActivity, this);
|
||||||
|
|
||||||
mJobQueue = new JobQueue(this);
|
mJobQueue = new JobQueue(this);
|
||||||
mMapWorker = new MapWorker(this);
|
|
||||||
mMapWorker.start();
|
|
||||||
// mMapMover = new MapMover(this);
|
// mMapMover = new MapMover(this);
|
||||||
// mMapMover.start();
|
// mMapMover.start();
|
||||||
// mZoomAnimator = new ZoomAnimator(this);
|
// mZoomAnimator = new ZoomAnimator(this);
|
||||||
// mZoomAnimator.start();
|
// mZoomAnimator.start();
|
||||||
|
|
||||||
setMapGeneratorInternal(mapGenerator);
|
mMapRenderer = MapRendererFactory.createMapRenderer(this, mapGeneratorType);
|
||||||
|
mMapWorkers = new MapWorker[mNumMapWorkers];
|
||||||
|
|
||||||
GeoPoint startPoint = mMapGenerator.getStartPoint();
|
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||||
if (startPoint != null) {
|
IMapDatabase mapDatabase = MapDatabaseFactory
|
||||||
mMapViewPosition.setMapCenter(startPoint);
|
.createMapDatabase(mapDatabaseType);
|
||||||
|
|
||||||
|
IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
|
||||||
|
mapGenerator.setMapDatabase(mapDatabase);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
mMapDatabase = mapDatabase;
|
||||||
|
initMapStartPosition();
|
||||||
|
|
||||||
|
// mapGenerator.setRendertheme(DEFAULT_RENDER_THEME);
|
||||||
|
}
|
||||||
|
mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
|
||||||
|
mMapWorkers[i].start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte startZoomLevel = mMapGenerator.getStartZoomLevel();
|
setRenderTheme(InternalRenderTheme.OSMARENDER);
|
||||||
if (startZoomLevel != null) {
|
|
||||||
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
mapActivity.registerMapView(this);
|
mapActivity.registerMapView(this);
|
||||||
|
|
||||||
setEGLConfigChooser(new GlConfigChooser());
|
setEGLConfigChooser(new GlConfigChooser());
|
||||||
setEGLContextClientVersion(2);
|
setEGLContextClientVersion(2);
|
||||||
|
|
||||||
mMapRenderer = mMapGenerator.getMapRenderer(this);
|
|
||||||
setRenderer(mMapRenderer);
|
setRenderer(mMapRenderer);
|
||||||
|
|
||||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||||
mMapWorker.setMapRenderer(mMapRenderer);
|
}
|
||||||
|
|
||||||
|
private void initMapStartPosition() {
|
||||||
|
GeoPoint startPoint = getStartPoint();
|
||||||
|
if (startPoint != null) {
|
||||||
|
mMapViewPosition.setMapCenter(startPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte startZoomLevel = getStartZoomLevel();
|
||||||
|
if (startZoomLevel != null) {
|
||||||
|
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,13 +236,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mMapFile;
|
return mMapFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the currently used MapGenerator (may be null).
|
|
||||||
*/
|
|
||||||
public IMapGenerator getMapGenerator() {
|
|
||||||
return mMapGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * @return the MapMover which is used by this MapView.
|
// * @return the MapMover which is used by this MapView.
|
||||||
// */
|
// */
|
||||||
@ -245,19 +250,19 @@ public class MapView extends GLSurfaceView {
|
|||||||
return mMapViewPosition;
|
return mMapViewPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* @return the scale bar which is used in this MapView.
|
// * @return the scale bar which is used in this MapView.
|
||||||
*/
|
// */
|
||||||
public MapScaleBar getMapScaleBar() {
|
// public MapScaleBar getMapScaleBar() {
|
||||||
return mMapScaleBar;
|
// return mMapScaleBar;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* @return the zoom controls instance which is used in this MapView.
|
// * @return the zoom controls instance which is used in this MapView.
|
||||||
*/
|
// */
|
||||||
public MapZoomControls getMapZoomControls() {
|
// public MapZoomControls getMapZoomControls() {
|
||||||
return mMapZoomControls;
|
// return mMapZoomControls;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the currently used projection of the map. Do not keep this object for a longer time.
|
* @return the currently used projection of the map. Do not keep this object for a longer time.
|
||||||
@ -362,37 +367,41 @@ public class MapView extends GLSurfaceView {
|
|||||||
|
|
||||||
// mZoomAnimator.pause();
|
// mZoomAnimator.pause();
|
||||||
// mMapMover.pause();
|
// mMapMover.pause();
|
||||||
mMapWorker.pause();
|
|
||||||
// mZoomAnimator.awaitPausing();
|
// mZoomAnimator.awaitPausing();
|
||||||
// mMapMover.awaitPausing();
|
// mMapMover.awaitPausing();
|
||||||
mMapWorker.awaitPausing();
|
|
||||||
// mZoomAnimator.proceed();
|
// mZoomAnimator.proceed();
|
||||||
// mMapMover.stopMove();
|
// mMapMover.stopMove();
|
||||||
// mMapMover.proceed();
|
// mMapMover.proceed();
|
||||||
mMapWorker.proceed();
|
|
||||||
|
|
||||||
mMapDatabase.closeFile();
|
boolean initialized = false;
|
||||||
|
|
||||||
if (mapFile != null)
|
mJobQueue.clear();
|
||||||
fileOpenResult = mMapDatabase.openFile(new File(mapFile));
|
|
||||||
else
|
|
||||||
fileOpenResult = mMapDatabase.openFile(null);
|
|
||||||
|
|
||||||
if (fileOpenResult != null && fileOpenResult.isSuccess()) {
|
mapWorkersPause();
|
||||||
mMapFile = mapFile;
|
|
||||||
|
|
||||||
GeoPoint startPoint = mMapGenerator.getStartPoint();
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
if (startPoint != null) {
|
|
||||||
Log.d(TAG, "mapfile got startpoint");
|
IMapGenerator mapGenerator = mapWorker.getMapGenerator();
|
||||||
mMapViewPosition.setMapCenter(startPoint);
|
IMapDatabase mapDatabase = mapGenerator.getMapDatabase();
|
||||||
|
|
||||||
|
mapDatabase.closeFile();
|
||||||
|
|
||||||
|
if (mapFile != null)
|
||||||
|
fileOpenResult = mapDatabase.openFile(new File(mapFile));
|
||||||
|
else
|
||||||
|
fileOpenResult = mapDatabase.openFile(null);
|
||||||
|
|
||||||
|
if (fileOpenResult != null && fileOpenResult.isSuccess()) {
|
||||||
|
mMapFile = mapFile;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Byte startZoomLevel = mMapGenerator.getStartZoomLevel();
|
mapWorkersProceed();
|
||||||
if (startZoomLevel != null) {
|
|
||||||
Log.d(TAG, "mapfile got start zoomlevel");
|
|
||||||
mMapViewPosition.setZoomLevel(startZoomLevel.byteValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (initialized) {
|
||||||
clearAndRedrawMapView();
|
clearAndRedrawMapView();
|
||||||
Log.d(TAG, "mapfile set");
|
Log.d(TAG, "mapfile set");
|
||||||
return true;
|
return true;
|
||||||
@ -404,76 +413,61 @@ public class MapView extends GLSurfaceView {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private GeoPoint getStartPoint() {
|
||||||
* Sets the MapGenerator for this MapView.
|
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||||
*
|
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||||
* @param mapGenerator
|
if (mapFileInfo.startPosition != null) {
|
||||||
* the new MapGenerator.
|
return mapFileInfo.startPosition;
|
||||||
*/
|
} else if (mapFileInfo.mapCenter != null) {
|
||||||
public void setMapGenerator(IMapGenerator mapGenerator) {
|
return mapFileInfo.mapCenter;
|
||||||
|
}
|
||||||
if (mMapGenerator != mapGenerator) {
|
|
||||||
setMapGeneratorInternal(mapGenerator);
|
|
||||||
|
|
||||||
clearAndRedrawMapView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMapGeneratorInternal(IMapGenerator mapGenerator) {
|
private Byte getStartZoomLevel() {
|
||||||
if (mapGenerator == null) {
|
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
||||||
throw new IllegalArgumentException("mapGenerator must not be null");
|
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
||||||
|
if (mapFileInfo.startZoomLevel != null) {
|
||||||
|
return mapFileInfo.startZoomLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapGenerator.setMapDatabase(mMapDatabase);
|
return DEFAULT_START_ZOOM_LEVEL;
|
||||||
|
|
||||||
mMapGenerator = mapGenerator;
|
|
||||||
mMapWorker.setMapGenerator(mMapGenerator);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the MapDatabase for this MapView.
|
* Sets the MapDatabase for this MapView.
|
||||||
*
|
*
|
||||||
* @param mapDatabase
|
* @param mapDatabaseType
|
||||||
* the new MapDatabase.
|
* the new MapDatabase.
|
||||||
*/
|
*/
|
||||||
public void setMapDatabase(IMapDatabase mapDatabase) {
|
|
||||||
Log.d(TAG, "setMapDatabase " + mapDatabase.getClass());
|
|
||||||
if (mMapDatabase != mapDatabase) {
|
|
||||||
|
|
||||||
if (mMapDatabase != null)
|
public void setMapDatabase(MapDatabases mapDatabaseType) {
|
||||||
mMapDatabase.closeFile();
|
IMapGenerator mapGenerator;
|
||||||
|
|
||||||
setMapDatabaseInternal(mapDatabase);
|
Log.d(TAG, "setMapDatabase " + mapDatabaseType.name());
|
||||||
|
|
||||||
// clearAndRedrawMapView();
|
if (mMapDatabaseType == mapDatabaseType)
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
private void setMapDatabaseInternal(IMapDatabase mapDatabase) {
|
mapWorkersPause();
|
||||||
if (mapDatabase == null) {
|
|
||||||
throw new IllegalArgumentException("MapDatabase must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mMapWorker.isPausing()) {
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
mMapWorker.pause();
|
mapGenerator = mapWorker.getMapGenerator();
|
||||||
mMapWorker.awaitPausing();
|
|
||||||
|
mapGenerator.setMapDatabase(MapDatabaseFactory
|
||||||
|
.createMapDatabase(mapDatabaseType));
|
||||||
}
|
}
|
||||||
|
|
||||||
mJobQueue.clear();
|
mJobQueue.clear();
|
||||||
mMapDatabase = mapDatabase;
|
|
||||||
mMapGenerator.setMapDatabase(mMapDatabase);
|
|
||||||
|
|
||||||
Log.d(TAG, "setMapDatabaseInternal " + mapDatabase.getClass());
|
|
||||||
|
|
||||||
String mapFile = mMapFile;
|
String mapFile = mMapFile;
|
||||||
mMapFile = null;
|
mMapFile = null;
|
||||||
setMapFile(mapFile);
|
setMapFile(mapFile);
|
||||||
|
|
||||||
mMapWorker.proceed();
|
mapWorkersProceed();
|
||||||
|
|
||||||
// mMapWorker.setMapDatabase(mMapDatabase);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -489,8 +483,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
throw new IllegalArgumentException("render theme must not be null");
|
throw new IllegalArgumentException("render theme must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "set rendertheme " + internalRenderTheme);
|
setRenderTheme((Theme) internalRenderTheme);
|
||||||
mJobParameters = new JobParameters(internalRenderTheme, mJobParameters.textScale);
|
|
||||||
|
|
||||||
clearAndRedrawMapView();
|
clearAndRedrawMapView();
|
||||||
}
|
}
|
||||||
@ -510,12 +503,40 @@ public class MapView extends GLSurfaceView {
|
|||||||
throw new IllegalArgumentException("render theme path must not be null");
|
throw new IllegalArgumentException("render theme path must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
JobTheme jobTheme = new ExternalRenderTheme(renderThemePath);
|
setRenderTheme(new ExternalRenderTheme(renderThemePath));
|
||||||
mJobParameters = new JobParameters(jobTheme, mJobParameters.textScale);
|
|
||||||
|
|
||||||
clearAndRedrawMapView();
|
clearAndRedrawMapView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean setRenderTheme(Theme theme) {
|
||||||
|
|
||||||
|
mapWorkersPause();
|
||||||
|
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
RenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
|
||||||
|
mMapWorkers[0].getMapGenerator().setRenderTheme(t);
|
||||||
|
return true;
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} catch (SAXException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
mapWorkersProceed();
|
||||||
|
try {
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the text scale for the map rendering. Has no effect in downloading mode.
|
* Sets the text scale for the map rendering. Has no effect in downloading mode.
|
||||||
*
|
*
|
||||||
@ -523,7 +544,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
* the new text scale for the map rendering.
|
* the new text scale for the map rendering.
|
||||||
*/
|
*/
|
||||||
public void setTextScale(float textScale) {
|
public void setTextScale(float textScale) {
|
||||||
mJobParameters = new JobParameters(mJobParameters.jobTheme, textScale);
|
mJobParameters = new JobParameters(mJobParameters.theme, textScale);
|
||||||
clearAndRedrawMapView();
|
clearAndRedrawMapView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,28 +604,33 @@ public class MapView extends GLSurfaceView {
|
|||||||
@Override
|
@Override
|
||||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
||||||
int oldHeight) {
|
int oldHeight) {
|
||||||
mMapWorker.pause();
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
mMapWorker.awaitPausing();
|
mapWorker.pause();
|
||||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
mapWorker.awaitPausing();
|
||||||
mMapWorker.proceed();
|
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||||
|
mapWorker.proceed();
|
||||||
|
}
|
||||||
// redrawTiles();
|
// redrawTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
// mMapMover.interrupt();
|
// mMapMover.interrupt();
|
||||||
mMapWorker.interrupt();
|
|
||||||
// mZoomAnimator.interrupt();
|
// mZoomAnimator.interrupt();
|
||||||
|
|
||||||
try {
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
mMapWorker.join();
|
mapWorker.interrupt();
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// restore the interrupted status
|
try {
|
||||||
Thread.currentThread().interrupt();
|
mapWorker.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// restore the interrupted status
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
IMapDatabase mapDatabase = mapWorker.getMapGenerator().getMapDatabase();
|
||||||
|
mapDatabase.closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
mMapScaleBar.destroy();
|
// mMapScaleBar.destroy();
|
||||||
mMapDatabase.closeFile();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,8 +638,9 @@ public class MapView extends GLSurfaceView {
|
|||||||
* @return the maximum possible zoom level.
|
* @return the maximum possible zoom level.
|
||||||
*/
|
*/
|
||||||
byte getMaximumPossibleZoomLevel() {
|
byte getMaximumPossibleZoomLevel() {
|
||||||
return (byte) Math.min(mMapZoomControls.getZoomLevelMax(),
|
return (byte) 20;
|
||||||
mMapGenerator.getZoomLevelMax());
|
// FIXME Math.min(mMapZoomControls.getZoomLevelMax(),
|
||||||
|
// mMapGenerator.getZoomLevelMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -639,7 +666,9 @@ public class MapView extends GLSurfaceView {
|
|||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
mMapWorker.pause();
|
for (MapWorker mapWorker : mMapWorkers)
|
||||||
|
mapWorker.pause();
|
||||||
|
|
||||||
// mMapMover.pause();
|
// mMapMover.pause();
|
||||||
// mZoomAnimator.pause();
|
// mZoomAnimator.pause();
|
||||||
}
|
}
|
||||||
@ -647,7 +676,9 @@ public class MapView extends GLSurfaceView {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
mMapWorker.proceed();
|
for (MapWorker mapWorker : mMapWorkers)
|
||||||
|
mapWorker.proceed();
|
||||||
|
|
||||||
// mMapMover.proceed();
|
// mMapMover.proceed();
|
||||||
// mZoomAnimator.proceed();
|
// mZoomAnimator.proceed();
|
||||||
}
|
}
|
||||||
@ -706,9 +737,33 @@ public class MapView extends GLSurfaceView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MapWorker
|
* add jobs and remember MapWorkers that stuff needs to be done
|
||||||
|
*
|
||||||
|
* @param jobs
|
||||||
|
* tile jobs
|
||||||
*/
|
*/
|
||||||
public MapWorker getMapWorker() {
|
public void addJobs(ArrayList<MapGeneratorJob> jobs) {
|
||||||
return mMapWorker;
|
mJobQueue.setJobs(jobs);
|
||||||
|
|
||||||
|
for (MapWorker m : mMapWorkers) {
|
||||||
|
synchronized (m) {
|
||||||
|
m.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mapWorkersPause() {
|
||||||
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
|
if (!mapWorker.isPausing()) {
|
||||||
|
mapWorker.pause();
|
||||||
|
mapWorker.awaitPausing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapWorkersProceed() {
|
||||||
|
for (MapWorker mapWorker : mMapWorkers)
|
||||||
|
mapWorker.proceed();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import android.util.FloatMath;
|
|||||||
public class MapViewPosition {
|
public class MapViewPosition {
|
||||||
private static float MAX_SCALE = 2.0f;
|
private static float MAX_SCALE = 2.0f;
|
||||||
private static float MIN_SCALE = 1.0f;
|
private static float MIN_SCALE = 1.0f;
|
||||||
|
private static int MAX_ZOOMLEVEL = 16;
|
||||||
|
|
||||||
private double mLatitude;
|
private double mLatitude;
|
||||||
private double mLongitude;
|
private double mLongitude;
|
||||||
@ -162,12 +163,14 @@ public class MapViewPosition {
|
|||||||
float s = mScale * scale;
|
float s = mScale * scale;
|
||||||
|
|
||||||
if (s >= MAX_SCALE) {
|
if (s >= MAX_SCALE) {
|
||||||
|
if (s > 8)
|
||||||
byte z = (byte) FloatMath.sqrt(s);
|
|
||||||
if (z != 0 && mZoomLevel == 20)
|
|
||||||
return;
|
return;
|
||||||
mZoomLevel += z;
|
|
||||||
s *= 1.0f / (1 << z);
|
if (mZoomLevel <= MAX_ZOOMLEVEL) {
|
||||||
|
byte z = (byte) FloatMath.sqrt(s);
|
||||||
|
mZoomLevel += z;
|
||||||
|
s *= 1.0f / (1 << z);
|
||||||
|
}
|
||||||
} else if (s < MIN_SCALE) {
|
} else if (s < MIN_SCALE) {
|
||||||
byte z = (byte) FloatMath.sqrt(1 / s);
|
byte z = (byte) FloatMath.sqrt(1 / s);
|
||||||
if (z != 0 && mZoomLevel == 1)
|
if (z != 0 && mZoomLevel == 1)
|
||||||
|
|||||||
@ -18,31 +18,33 @@ package org.mapsforge.android.glrenderer;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
class LayerPool {
|
class LayerPool {
|
||||||
static private LinkedList<PoolItem> pool;
|
static private LinkedList<PoolItem> pool = null;
|
||||||
static private int count;
|
static private int count;
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
pool = new LinkedList<PoolItem>();
|
if (pool == null) {
|
||||||
count = 0;
|
pool = new LinkedList<PoolItem>();
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PoolItem get() {
|
static PoolItem get() {
|
||||||
if (count == 0)
|
|
||||||
return new PoolItem();
|
|
||||||
|
|
||||||
PoolItem it;
|
|
||||||
synchronized (pool) {
|
synchronized (pool) {
|
||||||
count--;
|
|
||||||
it = pool.pop();
|
|
||||||
it.used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return it;
|
if (count == 0)
|
||||||
|
return new PoolItem();
|
||||||
|
|
||||||
|
count--;
|
||||||
|
PoolItem it = pool.pop();
|
||||||
|
it.used = 0;
|
||||||
|
return it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add(LinkedList<PoolItem> items) {
|
static void add(LinkedList<PoolItem> items) {
|
||||||
int size = items.size();
|
|
||||||
synchronized (pool) {
|
synchronized (pool) {
|
||||||
|
int size = items.size();
|
||||||
|
|
||||||
while (count < 4096 && size-- > 0) {
|
while (count < 4096 && size-- > 0) {
|
||||||
count++;
|
count++;
|
||||||
pool.add(items.pop());
|
pool.add(items.pop());
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class LineLayers {
|
|||||||
ByteOrder.nativeOrder());
|
ByteOrder.nativeOrder());
|
||||||
fbuf = bbuf.asFloatBuffer();
|
fbuf = bbuf.asFloatBuffer();
|
||||||
} else {
|
} else {
|
||||||
fbuf.position(0);
|
fbuf.clear();
|
||||||
}
|
}
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class LineLayers {
|
|||||||
l.pool = null;
|
l.pool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbuf.position(0);
|
fbuf.flip();
|
||||||
|
|
||||||
// not needed for drawing
|
// not needed for drawing
|
||||||
layers = null;
|
layers = null;
|
||||||
@ -105,7 +105,7 @@ class LineLayers {
|
|||||||
ByteOrder.nativeOrder());
|
ByteOrder.nativeOrder());
|
||||||
sbuf = bbuf.asShortBuffer();
|
sbuf = bbuf.asShortBuffer();
|
||||||
} else {
|
} else {
|
||||||
sbuf.position(0);
|
sbuf.clear();
|
||||||
}
|
}
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ class LineLayers {
|
|||||||
l.pool = null;
|
l.pool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
sbuf.position(0);
|
sbuf.flip();
|
||||||
|
|
||||||
// not needed for drawing
|
// not needed for drawing
|
||||||
layers = null;
|
layers = null;
|
||||||
|
|||||||
@ -14,29 +14,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.glrenderer;
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.JobTheme;
|
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.rendertheme.RenderThemeHandler;
|
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||||
import org.mapsforge.core.GeoPoint;
|
import org.mapsforge.android.rendertheme.renderinstruction.RenderInstruction;
|
||||||
import org.mapsforge.core.WebMercator;
|
import org.mapsforge.core.MercatorProjection;
|
||||||
import org.mapsforge.core.Tag;
|
import org.mapsforge.core.Tag;
|
||||||
import org.mapsforge.core.Tile;
|
import org.mapsforge.core.Tile;
|
||||||
|
import org.mapsforge.core.WebMercator;
|
||||||
import org.mapsforge.database.IMapDatabase;
|
import org.mapsforge.database.IMapDatabase;
|
||||||
import org.mapsforge.database.IMapDatabaseCallback;
|
import org.mapsforge.database.IMapDatabaseCallback;
|
||||||
import org.mapsforge.database.MapFileInfo;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
@ -46,33 +36,26 @@ import android.util.Log;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabaseCallback {
|
||||||
IMapDatabaseCallback {
|
|
||||||
private static String TAG = DatabaseRenderer.class.getName();
|
private static String TAG = MapGenerator.class.getName();
|
||||||
|
|
||||||
private static final byte ZOOM_MAX = 22;
|
|
||||||
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
|
||||||
private static final double PI180 = (Math.PI / 180) / 1000000.0;
|
private static final double PI180 = (Math.PI / 180) / 1000000.0;
|
||||||
private static final double PIx4 = Math.PI * 4;
|
private static final double PIx4 = Math.PI * 4;
|
||||||
private static final double STROKE_INCREASE = Math.sqrt(2);
|
private static final double STROKE_INCREASE = Math.sqrt(2);
|
||||||
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
|
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
|
||||||
private static final byte LAYERS = 11;
|
private static final byte LAYERS = 11;
|
||||||
|
private static final double f900913 = 20037508.342789244;
|
||||||
|
|
||||||
private static RenderTheme renderTheme;
|
private static RenderTheme renderTheme;
|
||||||
|
|
||||||
private IMapDatabase mMapDatabase;
|
private IMapDatabase mMapDatabase;
|
||||||
|
|
||||||
private JobTheme mPreviousJobTheme;
|
|
||||||
// private float mPreviousTextScale;
|
|
||||||
private byte mPreviousZoomLevel;
|
|
||||||
|
|
||||||
private GLMapTile mCurrentTile;
|
private GLMapTile mCurrentTile;
|
||||||
|
|
||||||
private float[] mWayNodes;
|
private float[] mWayNodes;
|
||||||
private int[] mWays;
|
private int[] mWays;
|
||||||
|
|
||||||
private ArrayList<float[]> mCurrentLines;
|
|
||||||
|
|
||||||
private LineLayers mLineLayers;
|
private LineLayers mLineLayers;
|
||||||
private PolygonLayers mPolyLayers;
|
private PolygonLayers mPolyLayers;
|
||||||
private MeshLayers mMeshLayers;
|
private MeshLayers mMeshLayers;
|
||||||
@ -81,14 +64,13 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
private int mLevels;
|
private int mLevels;
|
||||||
|
|
||||||
private boolean useSphericalMercator = false;
|
private boolean useSphericalMercator = false;
|
||||||
|
private float mStrokeScale = 1.0f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public DatabaseRenderer() {
|
public MapGenerator() {
|
||||||
Log.d(TAG, "init DatabaseRenderer");
|
Log.d(TAG, "init DatabaseRenderer");
|
||||||
mCurrentLines = new ArrayList<float[]>();
|
|
||||||
|
|
||||||
LayerPool.init();
|
LayerPool.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +89,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
private boolean mProjected;
|
private boolean mProjected;
|
||||||
private boolean mProjectedResult;
|
private boolean mProjectedResult;
|
||||||
private float mSimplify;
|
private float mSimplify;
|
||||||
private static final double f900913 = 20037508.342789244;
|
|
||||||
|
|
||||||
private boolean projectToTile(boolean area) {
|
private boolean projectToTile(boolean area) {
|
||||||
if (mProjected)
|
if (mProjected)
|
||||||
@ -136,6 +117,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
|
|
||||||
for (int pos = 0, outPos = 0, i = 0, m = mWays.length; i < m; i++) {
|
for (int pos = 0, outPos = 0, i = 0, m = mWays.length; i < m; i++) {
|
||||||
int len = mWays[i];
|
int len = mWays[i];
|
||||||
|
if (len == 0)
|
||||||
|
continue;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
float lat, lon, prevLon = 0, prevLat = 0;
|
float lat, lon, prevLon = 0, prevLat = 0;
|
||||||
|
|
||||||
@ -197,6 +180,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
private boolean firstMatch;
|
private boolean firstMatch;
|
||||||
private boolean prevClosed;
|
private boolean prevClosed;
|
||||||
|
|
||||||
|
private RenderInstruction[] mRenderInstructions = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLength,
|
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLength,
|
||||||
boolean changed) {
|
boolean changed) {
|
||||||
@ -220,17 +205,20 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
mSimplify = 0;
|
mSimplify = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentLines.clear();
|
|
||||||
mWayNodes = wayNodes;
|
mWayNodes = wayNodes;
|
||||||
mWays = wayLength;
|
mWays = wayLength;
|
||||||
|
|
||||||
if (!firstMatch && prevClosed == closed && !changed) {
|
if (!firstMatch && prevClosed == closed && !changed) {
|
||||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
if (mRenderInstructions != null) {
|
||||||
(byte) (mCurrentTile.zoomLevel + 0),
|
for (int i = 0, n = mRenderInstructions.length; i < n; i++)
|
||||||
closed, false);
|
mRenderInstructions[i].renderWay(this, tags);
|
||||||
|
}
|
||||||
|
// MapGenerator.renderTheme.matchWay(this, tags,
|
||||||
|
// (byte) (mCurrentTile.zoomLevel + 0),
|
||||||
|
// closed, false);
|
||||||
} else {
|
} else {
|
||||||
prevClosed = closed;
|
prevClosed = closed;
|
||||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
|
||||||
(byte) (mCurrentTile.zoomLevel + 0),
|
(byte) (mCurrentTile.zoomLevel + 0),
|
||||||
closed, true);
|
closed, true);
|
||||||
}
|
}
|
||||||
@ -273,9 +261,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
@Override
|
@Override
|
||||||
public void renderWay(Line line) {
|
public void renderWay(Line line) {
|
||||||
|
|
||||||
// if (prevClosed && !mProjected)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
projectToTile(false);
|
projectToTile(false);
|
||||||
|
|
||||||
LineLayer outlineLayer = null;
|
LineLayer outlineLayer = null;
|
||||||
@ -284,11 +269,12 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
|
|
||||||
float w = line.strokeWidth;
|
float w = line.strokeWidth;
|
||||||
|
|
||||||
if (!line.fixed)
|
if (!line.fixed) {
|
||||||
w *= mStrokeScale / 1.5f;
|
w *= mStrokeScale;
|
||||||
|
w *= mProjectionScaleFactor;
|
||||||
|
}
|
||||||
if (line.outline != -1) {
|
if (line.outline != -1) {
|
||||||
Line outline = DatabaseRenderer.renderTheme.getOutline(line.outline);
|
Line outline = MapGenerator.renderTheme.getOutline(line.outline);
|
||||||
if (outline != null) {
|
if (outline != null) {
|
||||||
outlineLayer = mLineLayers.getLayer(mDrawingLayer + outline.level,
|
outlineLayer = mLineLayers.getLayer(mDrawingLayer + outline.level,
|
||||||
outline.color, true, false);
|
outline.color, true, false);
|
||||||
@ -363,33 +349,19 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
if (mMapDatabase == null)
|
if (mMapDatabase == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
useSphericalMercator = WebMercator.NAME.equals(mMapDatabase.getMapProjection());
|
||||||
|
|
||||||
mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
|
mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
|
||||||
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
|
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
|
||||||
|
|
||||||
// FIXME still chance of concurrency with maprenderer updateVisibleList ?
|
|
||||||
if (mCurrentTile.isLoading || mCurrentTile.isDrawn)
|
if (mCurrentTile.isLoading || mCurrentTile.isDrawn)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mCurrentTile.isLoading = true;
|
mCurrentTile.isLoading = true;
|
||||||
|
|
||||||
JobTheme jobTheme = mapGeneratorJob.jobParameters.jobTheme;
|
mLevels = MapGenerator.renderTheme.getLevels();
|
||||||
|
|
||||||
if (jobTheme != mPreviousJobTheme) {
|
setScaleStrokeWidth(mCurrentTile.zoomLevel);
|
||||||
if (!setRenderTheme(jobTheme)) {
|
|
||||||
mPreviousJobTheme = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPreviousJobTheme = jobTheme;
|
|
||||||
mPreviousZoomLevel = Byte.MIN_VALUE;
|
|
||||||
mLevels = DatabaseRenderer.renderTheme.getLevels();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte zoomLevel = mCurrentTile.zoomLevel;
|
|
||||||
if (zoomLevel != mPreviousZoomLevel) {
|
|
||||||
setScaleStrokeWidth(zoomLevel);
|
|
||||||
mPreviousZoomLevel = zoomLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
mLineLayers = new LineLayers();
|
mLineLayers = new LineLayers();
|
||||||
mPolyLayers = new PolygonLayers();
|
mPolyLayers = new PolygonLayers();
|
||||||
@ -399,81 +371,32 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
mCurrentTile.meshLayers = mMeshLayers;
|
mCurrentTile.meshLayers = mMeshLayers;
|
||||||
|
|
||||||
firstMatch = true;
|
firstMatch = true;
|
||||||
mMapDatabase.executeQuery(mCurrentTile, this);
|
|
||||||
|
|
||||||
// Log.d(TAG, "loaded " + mCurrentTile);
|
mProjectionScaleFactor = (float) (1.0 / Math.cos(MercatorProjection
|
||||||
|
.pixelYToLatitude(mCurrentTile.pixelY, mCurrentTile.zoomLevel)
|
||||||
|
* (Math.PI / 180))) / 1.5f;
|
||||||
|
mMapDatabase.executeQuery(mCurrentTile, this);
|
||||||
|
|
||||||
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
||||||
float[] coords = { 0, 0, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE,
|
float[] coords = { 0, 0, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE,
|
||||||
Tile.TILE_SIZE, 0, 0, 0 };
|
Tile.TILE_SIZE, 0, 0, 0 };
|
||||||
LineLayer ll = mLineLayers.getLayer(Integer.MAX_VALUE, Color.BLACK, false,
|
LineLayer ll = mLineLayers.getLayer(Integer.MAX_VALUE, Color.BLACK, false,
|
||||||
true);
|
true);
|
||||||
ll.addLine(coords, 0, coords.length, 1.0f, false);
|
ll.addLine(coords, 0, coords.length, 2.0f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentTile.newData = true;
|
mCurrentTile.newData = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private float mProjectionScaleFactor;
|
||||||
public GeoPoint getStartPoint() {
|
|
||||||
useSphericalMercator = false;
|
|
||||||
|
|
||||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
|
||||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
|
||||||
|
|
||||||
if (WebMercator.NAME.equals(mapFileInfo.projectionName)) {
|
|
||||||
Log.d(TAG, "using Spherical Mercator");
|
|
||||||
|
|
||||||
useSphericalMercator = true;
|
|
||||||
}
|
|
||||||
if (mapFileInfo.startPosition != null) {
|
|
||||||
return mapFileInfo.startPosition;
|
|
||||||
} else if (mapFileInfo.mapCenter != null) {
|
|
||||||
return mapFileInfo.mapCenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Byte getStartZoomLevel() {
|
|
||||||
return DEFAULT_START_ZOOM_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte getZoomLevelMax() {
|
|
||||||
return ZOOM_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean setRenderTheme(JobTheme jobTheme) {
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = jobTheme.getRenderThemeAsStream();
|
|
||||||
DatabaseRenderer.renderTheme = RenderThemeHandler.getRenderTheme(inputStream);
|
|
||||||
return true;
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (SAXException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (inputStream != null) {
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte getValidLayer(byte layer) {
|
private static byte getValidLayer(byte layer) {
|
||||||
if (layer < 0) {
|
if (layer < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
/**
|
||||||
|
* return instances of MapRenderer
|
||||||
|
*/
|
||||||
} else if (layer >= LAYERS) {
|
} else if (layer >= LAYERS) {
|
||||||
return LAYERS - 1;
|
return LAYERS - 1;
|
||||||
} else {
|
} else {
|
||||||
@ -481,9 +404,17 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public MapRenderer getMapRenderer(MapView mapView) {
|
* Sets the scale stroke factor for the given zoom level.
|
||||||
return new MapRenderer(mapView);
|
*
|
||||||
|
* @param zoomLevel
|
||||||
|
* the zoom level for which the scale stroke factor should be set.
|
||||||
|
*/
|
||||||
|
private void setScaleStrokeWidth(byte zoomLevel) {
|
||||||
|
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
||||||
|
mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
|
||||||
|
if (mStrokeScale < 1)
|
||||||
|
mStrokeScale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -491,19 +422,13 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
mMapDatabase = mapDatabase;
|
mMapDatabase = mapDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float mStrokeScale = 1.0f;
|
@Override
|
||||||
|
public IMapDatabase getMapDatabase() {
|
||||||
|
return mMapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Sets the scale stroke factor for the given zoom level.
|
public void setRenderTheme(RenderTheme theme) {
|
||||||
*
|
MapGenerator.renderTheme = theme;
|
||||||
* @param zoomLevel
|
|
||||||
* the zoom level for which the scale stroke factor should be set.
|
|
||||||
*/
|
|
||||||
private static void setScaleStrokeWidth(byte zoomLevel) {
|
|
||||||
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
|
||||||
mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
|
|
||||||
if (mStrokeScale < 1)
|
|
||||||
mStrokeScale = 1;
|
|
||||||
// DatabaseRenderer.renderTheme.scaleStrokeWidth(mStrokeScale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14,6 +14,57 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.glrenderer;
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
|
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
|
||||||
|
import static android.opengl.GLES20.GL_DEPTH_TEST;
|
||||||
|
import static android.opengl.GLES20.GL_DITHER;
|
||||||
|
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
||||||
|
import static android.opengl.GLES20.GL_EQUAL;
|
||||||
|
import static android.opengl.GLES20.GL_EXTENSIONS;
|
||||||
|
import static android.opengl.GLES20.GL_FLOAT;
|
||||||
|
import static android.opengl.GLES20.GL_INVERT;
|
||||||
|
import static android.opengl.GLES20.GL_NEVER;
|
||||||
|
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
import static android.opengl.GLES20.GL_SCISSOR_TEST;
|
||||||
|
import static android.opengl.GLES20.GL_SRC_ALPHA;
|
||||||
|
import static android.opengl.GLES20.GL_STENCIL_BUFFER_BIT;
|
||||||
|
import static android.opengl.GLES20.GL_STENCIL_TEST;
|
||||||
|
import static android.opengl.GLES20.GL_TRIANGLES;
|
||||||
|
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
|
||||||
|
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
|
||||||
|
import static android.opengl.GLES20.GL_ZERO;
|
||||||
|
import static android.opengl.GLES20.glBindBuffer;
|
||||||
|
import static android.opengl.GLES20.glBlendFunc;
|
||||||
|
import static android.opengl.GLES20.glBufferData;
|
||||||
|
import static android.opengl.GLES20.glClear;
|
||||||
|
import static android.opengl.GLES20.glClearColor;
|
||||||
|
import static android.opengl.GLES20.glClearStencil;
|
||||||
|
import static android.opengl.GLES20.glColorMask;
|
||||||
|
import static android.opengl.GLES20.glDepthMask;
|
||||||
|
import static android.opengl.GLES20.glDisable;
|
||||||
|
import static android.opengl.GLES20.glDisableVertexAttribArray;
|
||||||
|
import static android.opengl.GLES20.glDrawArrays;
|
||||||
|
import static android.opengl.GLES20.glEnable;
|
||||||
|
import static android.opengl.GLES20.glEnableVertexAttribArray;
|
||||||
|
import static android.opengl.GLES20.glFinish;
|
||||||
|
import static android.opengl.GLES20.glGenBuffers;
|
||||||
|
import static android.opengl.GLES20.glGetAttribLocation;
|
||||||
|
import static android.opengl.GLES20.glGetString;
|
||||||
|
import static android.opengl.GLES20.glGetUniformLocation;
|
||||||
|
import static android.opengl.GLES20.glScissor;
|
||||||
|
import static android.opengl.GLES20.glStencilFunc;
|
||||||
|
import static android.opengl.GLES20.glStencilMask;
|
||||||
|
import static android.opengl.GLES20.glStencilOp;
|
||||||
|
import static android.opengl.GLES20.glUniform1f;
|
||||||
|
import static android.opengl.GLES20.glUniform2f;
|
||||||
|
import static android.opengl.GLES20.glUniform4f;
|
||||||
|
import static android.opengl.GLES20.glUniform4fv;
|
||||||
|
import static android.opengl.GLES20.glUniformMatrix4fv;
|
||||||
|
import static android.opengl.GLES20.glUseProgram;
|
||||||
|
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||||
|
import static android.opengl.GLES20.glViewport;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -25,10 +76,9 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
|
|
||||||
import org.mapsforge.android.DebugSettings;
|
import org.mapsforge.android.DebugSettings;
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
|
import org.mapsforge.android.mapgenerator.JobParameters;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
import org.mapsforge.android.mapgenerator.MapWorker;
|
|
||||||
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
||||||
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
||||||
import org.mapsforge.android.utils.GlConfigChooser;
|
import org.mapsforge.android.utils.GlConfigChooser;
|
||||||
@ -47,12 +97,15 @@ import android.util.Log;
|
|||||||
* TODO - use proxy child/parent tile nearer to current tile (currently it is always parent first) - use stencil instead
|
* TODO - use proxy child/parent tile nearer to current tile (currently it is always parent first) - use stencil instead
|
||||||
* of scissor mask for rotation - draw up to two parents above current tile, maybe prefetch parent
|
* of scissor mask for rotation - draw up to two parents above current tile, maybe prefetch parent
|
||||||
*/
|
*/
|
||||||
public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||||
private static final String TAG = "MapRenderer";
|
private static final String TAG = "MapRenderer";
|
||||||
|
private static final int MB = 1024 * 1024;
|
||||||
|
|
||||||
|
private boolean mTriangulate = false;
|
||||||
|
|
||||||
private static int CACHE_TILES_MAX = 400;
|
private static int CACHE_TILES_MAX = 400;
|
||||||
private static int CACHE_TILES = CACHE_TILES_MAX;
|
private static int CACHE_TILES = CACHE_TILES_MAX;
|
||||||
private static final int LIMIT_BUFFERS = 32 * (1024 * 1024);
|
private static int LIMIT_BUFFERS = 20 * MB;
|
||||||
|
|
||||||
private static final int OES_HALF_FLOAT = 0x8D61;
|
private static final int OES_HALF_FLOAT = 0x8D61;
|
||||||
private static final int FLOAT_BYTES = 4;
|
private static final int FLOAT_BYTES = 4;
|
||||||
@ -64,8 +117,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
private static int STENCIL_BITS = 8;
|
private static int STENCIL_BITS = 8;
|
||||||
|
|
||||||
private final MapView mMapView;
|
private final MapView mMapView;
|
||||||
private final MapWorker mMapWorker;
|
|
||||||
|
|
||||||
private final ArrayList<MapGeneratorJob> mJobList;
|
private final ArrayList<MapGeneratorJob> mJobList;
|
||||||
private final ArrayList<VertexBufferObject> mVBOs;
|
private final ArrayList<VertexBufferObject> mVBOs;
|
||||||
private final TileCacheKey mTileCacheKey;
|
private final TileCacheKey mTileCacheKey;
|
||||||
@ -88,9 +139,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
// current center tile
|
// current center tile
|
||||||
private long mTileX, mTileY;
|
private long mTileX, mTileY;
|
||||||
|
|
||||||
private FloatBuffer floatBuffer = null;
|
private FloatBuffer floatBuffer[];
|
||||||
// private ByteBuffer byteBuffer = null;
|
private ShortBuffer shortBuffer[];
|
||||||
private ShortBuffer shortBuffer = null;
|
|
||||||
|
|
||||||
boolean useHalfFloat = false;
|
boolean useHalfFloat = false;
|
||||||
|
|
||||||
@ -147,7 +197,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
public MapRenderer(MapView mapView) {
|
public MapRenderer(MapView mapView) {
|
||||||
Log.d(TAG, "init MapRenderer");
|
Log.d(TAG, "init MapRenderer");
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
mMapWorker = mapView.getMapWorker();
|
|
||||||
mDebugSettings = mapView.getDebugSettings();
|
mDebugSettings = mapView.getDebugSettings();
|
||||||
|
|
||||||
mVBOs = new ArrayList<VertexBufferObject>();
|
mVBOs = new ArrayList<VertexBufferObject>();
|
||||||
@ -316,7 +365,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
mJobList.clear();
|
mJobList.clear();
|
||||||
mJobParameter = mMapView.getJobParameters();
|
mJobParameter = mMapView.getJobParameters();
|
||||||
|
|
||||||
IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
|
||||||
int tiles = 0;
|
int tiles = 0;
|
||||||
if (newTiles == null)
|
if (newTiles == null)
|
||||||
return false;
|
return false;
|
||||||
@ -376,19 +424,19 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
newTiles.tiles[tiles++] = tile;
|
newTiles.tiles[tiles++] = tile;
|
||||||
|
|
||||||
if (!tile.isDrawn && !tile.newData && !tile.isLoading) {
|
if (!tile.isDrawn && !tile.newData && !tile.isLoading) {
|
||||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
|
MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
|
||||||
mJobParameter, mDebugSettings);
|
mDebugSettings);
|
||||||
mJobList.add(job);
|
mJobList.add(job);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefetch parent
|
// prefetch parent
|
||||||
if (tile.parent != null && !tile.parent.isDrawn && !tile.parent.newData
|
// if (tile.parent != null && !tile.parent.isDrawn && !tile.parent.newData
|
||||||
&& !tile.parent.isLoading) {
|
// && !tile.parent.isLoading) {
|
||||||
MapGeneratorJob job = new MapGeneratorJob(tile.parent, mapGenerator,
|
// MapGeneratorJob job = new MapGeneratorJob(tile.parent, mJobParameter,
|
||||||
mJobParameter, mDebugSettings);
|
// mDebugSettings);
|
||||||
if (!mJobList.contains(job))
|
// if (!mJobList.contains(job))
|
||||||
mJobList.add(job);
|
// mJobList.add(job);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,12 +467,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
limitCache(removes);
|
limitCache(removes);
|
||||||
|
|
||||||
if (mJobList.size() > 0) {
|
if (mJobList.size() > 0)
|
||||||
mMapView.getJobQueue().setJobs(mJobList);
|
mMapView.addJobs(mJobList);
|
||||||
synchronized (mMapWorker) {
|
|
||||||
mMapWorker.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -513,7 +557,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean passTile(MapGeneratorJob mapGeneratorJob) {
|
public boolean passTile(MapGeneratorJob mapGeneratorJob) {
|
||||||
if (!timing)
|
if (!timing && mapGeneratorJob.tile.isVisible)
|
||||||
mMapView.requestRender();
|
mMapView.requestRender();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -524,10 +568,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
boolean blend = false;
|
boolean blend = false;
|
||||||
|
|
||||||
// draw to framebuffer
|
// draw to framebuffer
|
||||||
GLES20.glColorMask(true, true, true, true);
|
glColorMask(true, true, true, true);
|
||||||
|
|
||||||
// do not modify stencil buffer
|
// do not modify stencil buffer
|
||||||
GLES20.glStencilMask(0);
|
glStencilMask(0);
|
||||||
|
|
||||||
for (int c = 0; c < count; c++) {
|
for (int c = 0; c < count; c++) {
|
||||||
PolygonLayer l = mFillPolys[c];
|
PolygonLayer l = mFillPolys[c];
|
||||||
@ -541,26 +585,26 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
alpha = 1.0f;
|
alpha = 1.0f;
|
||||||
|
|
||||||
if (!blend) {
|
if (!blend) {
|
||||||
GLES20.glEnable(GLES20.GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
blend = true;
|
blend = true;
|
||||||
}
|
}
|
||||||
} else if (blend) {
|
} else if (blend) {
|
||||||
GLES20.glDisable(GLES20.GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
blend = false;
|
blend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glUniform4f(gPolygonColorHandle,
|
glUniform4f(gPolygonColorHandle,
|
||||||
l.colors[0], l.colors[1], l.colors[2], alpha);
|
l.colors[0], l.colors[1], l.colors[2], alpha);
|
||||||
|
|
||||||
// set stencil buffer mask used to draw this layer
|
// set stencil buffer mask used to draw this layer
|
||||||
GLES20.glStencilFunc(GLES20.GL_EQUAL, 0xff, 1 << c);
|
glStencilFunc(GL_EQUAL, 0xff, 1 << c);
|
||||||
|
|
||||||
// draw tile fill coordinates
|
// draw tile fill coordinates
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend)
|
if (blend)
|
||||||
GLES20.glDisable(GLES20.GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean drawPolygons(GLMapTile tile, int diff) {
|
private boolean drawPolygons(GLMapTile tile, int diff) {
|
||||||
@ -569,63 +613,68 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (tile.polygonLayers == null || tile.polygonLayers.array == null)
|
if (tile.polygonLayers == null || tile.polygonLayers.array == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
if (mLastBoundVBO != tile.polygonVBO.id) {
|
||||||
|
mLastBoundVBO = tile.polygonVBO.id;
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||||
OES_HALF_FLOAT, false, 0,
|
OES_HALF_FLOAT, false, 0,
|
||||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
} else {
|
} else {
|
||||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||||
GLES20.GL_FLOAT, false, 0,
|
GL_FLOAT, false, 0,
|
||||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
setMatrix(tile, diff);
|
setMatrix(tile, diff);
|
||||||
GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||||
|
|
||||||
boolean firstPass = true;
|
boolean firstPass = true;
|
||||||
|
|
||||||
for (int i = 0, n = tile.polygonLayers.array.length; i < n; i++) {
|
for (int i = 0, n = tile.polygonLayers.array.length; i < n; i++) {
|
||||||
PolygonLayer l = tile.polygonLayers.array[i];
|
PolygonLayer l = tile.polygonLayers.array[i];
|
||||||
|
|
||||||
if (cnt == 0) {
|
|
||||||
// disable drawing to framebuffer
|
|
||||||
GLES20.glColorMask(false, false, false, false);
|
|
||||||
|
|
||||||
// never pass the test, i.e. always apply first stencil op (sfail)
|
|
||||||
GLES20.glStencilFunc(GLES20.GL_NEVER, 0, 0xff);
|
|
||||||
|
|
||||||
if (firstPass)
|
|
||||||
firstPass = false;
|
|
||||||
else {
|
|
||||||
// clear stencilbuffer
|
|
||||||
GLES20.glStencilMask(0xFF);
|
|
||||||
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
// clear stencilbuffer (tile region)
|
|
||||||
// GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
|
|
||||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// stencil op for stencil method polygon drawing
|
|
||||||
GLES20.glStencilOp(GLES20.GL_INVERT, GLES20.GL_INVERT, GLES20.GL_INVERT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fade out polygon layers (set in RederTheme)
|
// fade out polygon layers (set in RederTheme)
|
||||||
if (l.fadeLevel > 0 && l.fadeLevel > mDrawZ)
|
if (l.fadeLevel > 0 && l.fadeLevel > mDrawZ)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (cnt == 0) {
|
||||||
|
// disable drawing to framebuffer
|
||||||
|
glColorMask(false, false, false, false);
|
||||||
|
|
||||||
|
// never pass the test, i.e. always apply first stencil op (sfail)
|
||||||
|
glStencilFunc(GL_NEVER, 0, 0xff);
|
||||||
|
|
||||||
|
if (firstPass)
|
||||||
|
firstPass = false;
|
||||||
|
else {
|
||||||
|
// eeek, nexus! - cant do old-school polygons
|
||||||
|
// glFinish();
|
||||||
|
|
||||||
|
// clear stencilbuffer
|
||||||
|
glStencilMask(0xFF);
|
||||||
|
// glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
// clear stencilbuffer (tile region)
|
||||||
|
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stencil op for stencil method polygon drawing
|
||||||
|
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||||
|
}
|
||||||
|
|
||||||
mFillPolys[cnt] = l;
|
mFillPolys[cnt] = l;
|
||||||
|
|
||||||
// set stencil mask to draw to
|
// set stencil mask to draw to
|
||||||
GLES20.glStencilMask(1 << cnt++);
|
glStencilMask(1 << cnt++);
|
||||||
|
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
||||||
|
|
||||||
// draw up to 8 layers into stencil buffer
|
// draw up to 8 layers into stencil buffer
|
||||||
if (cnt == STENCIL_BITS) {
|
if (cnt == STENCIL_BITS) {
|
||||||
@ -634,47 +683,54 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt > 0)
|
if (cnt > 0) {
|
||||||
fillPolygons(cnt);
|
fillPolygons(cnt);
|
||||||
|
// eeek, nexus! - cant do old-school polygons
|
||||||
|
// glFinish();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int mLastBoundVBO;
|
||||||
|
|
||||||
private boolean drawTriangles(GLMapTile tile, int diff) {
|
private boolean drawTriangles(GLMapTile tile, int diff) {
|
||||||
|
|
||||||
if (tile.meshLayers == null || tile.meshLayers.array == null)
|
if (tile.meshLayers == null || tile.meshLayers.array == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
if (mLastBoundVBO != tile.polygonVBO.id) {
|
||||||
|
mLastBoundVBO = tile.polygonVBO.id;
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||||
OES_HALF_FLOAT, false, 0,
|
OES_HALF_FLOAT, false, 0,
|
||||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
} else {
|
} else {
|
||||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||||
GLES20.GL_FLOAT, false, 0,
|
GL_FLOAT, false, 0,
|
||||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
setMatrix(tile, diff);
|
setMatrix(tile, diff);
|
||||||
GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||||
|
|
||||||
MeshLayer[] layers = tile.meshLayers.array;
|
MeshLayer[] layers = tile.meshLayers.array;
|
||||||
|
|
||||||
for (int i = 0, n = layers.length; i < n; i++) {
|
for (int i = 0, n = layers.length; i < n; i++) {
|
||||||
MeshLayer l = layers[i];
|
MeshLayer l = layers[i];
|
||||||
GLES20.glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
|
glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
|
||||||
|
|
||||||
// GLES20.glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
|
// glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
|
||||||
|
|
||||||
// System.out.println("draw: " + l.offset + " " + l.verticesCnt);
|
// System.out.println("draw: " + l.offset + " " + l.verticesCnt);
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, l.offset, l.verticesCnt);
|
glDrawArrays(GL_TRIANGLES, l.offset, l.verticesCnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,30 +740,32 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (tile.lineLayers == null || tile.lineLayers.array == null)
|
if (tile.lineLayers == null || tile.lineLayers.array == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
|
if (mLastBoundVBO != tile.lineVBO.id) {
|
||||||
|
mLastBoundVBO = tile.lineVBO.id;
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
|
glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
|
||||||
false, 8, LINE_VERTICES_DATA_POS_OFFSET);
|
false, 8, LINE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
|
glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
|
||||||
false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
||||||
} else {
|
} else {
|
||||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT,
|
glVertexAttribPointer(gLineVertexPositionHandle, 2, GL_FLOAT,
|
||||||
false, 16, LINE_VERTICES_DATA_POS_OFFSET);
|
false, 16, LINE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT,
|
glVertexAttribPointer(gLineTexturePositionHandle, 2, GL_FLOAT,
|
||||||
false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
|
false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
|
||||||
|
}
|
||||||
|
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
if (diff != 0)
|
if (diff != 0)
|
||||||
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
|
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
|
||||||
|
|
||||||
setMatrix(tile, diff);
|
setMatrix(tile, diff);
|
||||||
GLES20.glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
|
glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||||
|
|
||||||
LineLayer[] layers = tile.lineLayers.array;
|
LineLayer[] layers = tile.lineLayers.array;
|
||||||
|
|
||||||
@ -729,42 +787,37 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
drawFixed = l.isFixed;
|
drawFixed = l.isFixed;
|
||||||
|
|
||||||
if (drawOutlines) {
|
if (drawOutlines) {
|
||||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
glUniform2f(gLineModeHandle, 0, wdiv);
|
||||||
} else if (!drawFixed) {
|
} else if (!drawFixed) {
|
||||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv * 0.98f);
|
glUniform2f(gLineModeHandle, 0, wdiv * 0.98f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawFixed) {
|
if (drawFixed) {
|
||||||
if (l.width < 1.0)
|
if (l.width < 1.0)
|
||||||
GLES20.glUniform2f(gLineModeHandle, 0.4f, fdiv);
|
glUniform2f(gLineModeHandle, 0.4f, fdiv);
|
||||||
else
|
else
|
||||||
GLES20.glUniform2f(gLineModeHandle, 0, fdiv);
|
glUniform2f(gLineModeHandle, 0, fdiv);
|
||||||
}
|
}
|
||||||
GLES20.glUniform4fv(gLineColorHandle, 1, l.colors, 0);
|
glUniform4fv(gLineColorHandle, 1, l.colors, 0);
|
||||||
|
|
||||||
if (drawOutlines) {
|
if (drawOutlines) {
|
||||||
for (int j = 0, m = l.outlines.size(); j < m; j++) {
|
for (int j = 0, m = l.outlines.size(); j < m; j++) {
|
||||||
LineLayer o = l.outlines.get(j);
|
LineLayer o = l.outlines.get(j);
|
||||||
|
|
||||||
if (mSimpleLines)
|
if (mSimpleLines)
|
||||||
GLES20.glUniform1f(gLineWidthHandle, o.width);
|
glUniform1f(gLineWidthHandle, o.width);
|
||||||
|
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mSimpleLines)
|
if (mSimpleLines)
|
||||||
GLES20.glUniform1f(gLineWidthHandle, l.width);
|
glUniform1f(gLineWidthHandle, l.width);
|
||||||
|
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||||
}
|
}
|
||||||
// cnt += l.verticesCnt;
|
|
||||||
}
|
}
|
||||||
// GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
|
||||||
// float[] c = { 1, 0, 0, 1 };
|
|
||||||
// GLES20.glUniform4fv(gLineColorHandle, 1, c, 0);
|
|
||||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, cnt);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -940,47 +993,53 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mTriangulate = false;
|
|
||||||
|
|
||||||
private int uploadCnt = 0;
|
private int uploadCnt = 0;
|
||||||
|
|
||||||
private boolean uploadTileData(GLMapTile tile) {
|
private boolean uploadTileData(GLMapTile tile) {
|
||||||
// not sure about this, but seems it fixes some flickering when
|
|
||||||
// multiple tiles are uploaded in one go. but if this is really
|
|
||||||
// the issue tiles should stay corrupted..
|
|
||||||
|
|
||||||
if (uploadCnt++ > 0)
|
// double start = SystemClock.uptimeMillis();
|
||||||
GLES20.glFinish();
|
|
||||||
|
|
||||||
|
// use multiple buffers to avoid overwriting buffer while current data is uploaded
|
||||||
|
// (or rather the blocking which is required to avoid this)
|
||||||
|
if (uploadCnt >= 10) {
|
||||||
|
// mMapView.requestRender();
|
||||||
|
// return false;
|
||||||
|
uploadCnt = 0;
|
||||||
|
glFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload line data to vertex buffer object
|
||||||
if (tile.lineVBO == null) {
|
if (tile.lineVBO == null) {
|
||||||
// Upload line data to vertex buffer object
|
|
||||||
synchronized (mVBOs) {
|
synchronized (mVBOs) {
|
||||||
if (mVBOs.size() < 2)
|
if (mVBOs.size() < 2) {
|
||||||
|
Log.d(TAG, "uploadTileData, no VBOs left");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
tile.lineVBO = mVBOs.remove(mVBOs.size() - 1);
|
tile.lineVBO = mVBOs.remove(mVBOs.size() - 1);
|
||||||
tile.polygonVBO = mVBOs.remove(mVBOs.size() - 1);
|
tile.polygonVBO = mVBOs.remove(mVBOs.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useHalfFloat)
|
if (useHalfFloat)
|
||||||
shortBuffer = tile.lineLayers.compileLayerData(shortBuffer);
|
shortBuffer[uploadCnt * 2] = tile.lineLayers
|
||||||
|
.compileLayerData(shortBuffer[uploadCnt * 2]);
|
||||||
else
|
else
|
||||||
floatBuffer = tile.lineLayers.compileLayerData(floatBuffer);
|
floatBuffer[uploadCnt * 2] = tile.lineLayers
|
||||||
|
.compileLayerData(floatBuffer[uploadCnt * 2]);
|
||||||
|
|
||||||
if (tile.lineLayers.size > 0) {
|
if (tile.lineLayers.size > 0) {
|
||||||
mBufferMemoryUsage -= tile.lineVBO.size;
|
mBufferMemoryUsage -= tile.lineVBO.size;
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
|
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
|
// glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
|
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
shortBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
|
||||||
} else {
|
} else {
|
||||||
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
|
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
floatBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
mBufferMemoryUsage += tile.lineVBO.size;
|
mBufferMemoryUsage += tile.lineVBO.size;
|
||||||
@ -991,26 +1050,28 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
if (!mTriangulate) {
|
if (!mTriangulate) {
|
||||||
if (useHalfFloat)
|
if (useHalfFloat)
|
||||||
shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
|
shortBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
|
||||||
|
.compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
|
||||||
else
|
else
|
||||||
floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
|
floatBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
|
||||||
|
.compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
|
||||||
|
|
||||||
// Upload polygon data to vertex buffer object
|
// Upload polygon data to vertex buffer object
|
||||||
if (tile.polygonLayers.size > 0) {
|
if (tile.polygonLayers.size > 0) {
|
||||||
mBufferMemoryUsage -= tile.polygonVBO.size;
|
mBufferMemoryUsage -= tile.polygonVBO.size;
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
|
// glBufferData(GL_ARRAY_BUFFER, 0, null,
|
||||||
GLES20.GL_STATIC_DRAW);
|
// GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
|
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||||
} else {
|
} else {
|
||||||
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
|
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
mBufferMemoryUsage += tile.polygonVBO.size;
|
mBufferMemoryUsage += tile.polygonVBO.size;
|
||||||
|
|
||||||
@ -1020,26 +1081,28 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (useHalfFloat)
|
if (useHalfFloat)
|
||||||
shortBuffer = tile.meshLayers.compileLayerData(shortBuffer);
|
shortBuffer[uploadCnt * 2 + 1] = tile.meshLayers
|
||||||
|
.compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
|
||||||
else
|
else
|
||||||
floatBuffer = tile.meshLayers.compileLayerData(floatBuffer);
|
floatBuffer[uploadCnt * 2 + 1] = tile.meshLayers
|
||||||
|
.compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
|
||||||
|
|
||||||
// Upload triangle data to vertex buffer object
|
// Upload triangle data to vertex buffer object
|
||||||
if (tile.meshLayers.size > 0) {
|
if (tile.meshLayers.size > 0) {
|
||||||
mBufferMemoryUsage -= tile.polygonVBO.size;
|
mBufferMemoryUsage -= tile.polygonVBO.size;
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
|
// glBufferData(GL_ARRAY_BUFFER, 0, null,
|
||||||
GLES20.GL_STATIC_DRAW);
|
// GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
if (useHalfFloat) {
|
if (useHalfFloat) {
|
||||||
tile.polygonVBO.size = tile.meshLayers.size * SHORT_BYTES;
|
tile.polygonVBO.size = tile.meshLayers.size * SHORT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||||
} else {
|
} else {
|
||||||
tile.polygonVBO.size = tile.meshLayers.size * FLOAT_BYTES;
|
tile.polygonVBO.size = tile.meshLayers.size * FLOAT_BYTES;
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
mBufferMemoryUsage += tile.polygonVBO.size;
|
mBufferMemoryUsage += tile.polygonVBO.size;
|
||||||
|
|
||||||
@ -1050,6 +1113,13 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
tile.newData = false;
|
tile.newData = false;
|
||||||
tile.isDrawn = true;
|
tile.isDrawn = true;
|
||||||
tile.isLoading = false;
|
tile.isLoading = false;
|
||||||
|
// double compile = SystemClock.uptimeMillis();
|
||||||
|
// glFinish();
|
||||||
|
// double now = SystemClock.uptimeMillis();
|
||||||
|
// Log.d(TAG, tile + " - upload took: " + (now - start) + " "
|
||||||
|
// + (mBufferMemoryUsage / 1024) + "kb");
|
||||||
|
|
||||||
|
uploadCnt++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1066,10 +1136,9 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (timing)
|
if (timing)
|
||||||
start = SystemClock.uptimeMillis();
|
start = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
GLES20.glStencilMask(0xFF);
|
glStencilMask(0xFF);
|
||||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
// GLES20.glFlush();
|
|
||||||
|
|
||||||
// long endTime = SystemClock.uptimeMillis();
|
// long endTime = SystemClock.uptimeMillis();
|
||||||
// long dt = endTime - startTime;
|
// long dt = endTime - startTime;
|
||||||
@ -1100,22 +1169,21 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
GLMapTile[] tiles = curTiles.tiles;
|
GLMapTile[] tiles = curTiles.tiles;
|
||||||
|
|
||||||
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
||||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024)
|
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
|
||||||
+ "MB");
|
|
||||||
synchronized (mVBOs) {
|
synchronized (mVBOs) {
|
||||||
for (VertexBufferObject vbo : mVBOs) {
|
for (VertexBufferObject vbo : mVBOs) {
|
||||||
if (vbo.size == 0)
|
if (vbo.size == 0)
|
||||||
continue;
|
continue;
|
||||||
mBufferMemoryUsage -= vbo.size;
|
mBufferMemoryUsage -= vbo.size;
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
|
glBufferData(GL_ARRAY_BUFFER, 0, null,
|
||||||
GLES20.GL_STATIC_DRAW);
|
GL_DYNAMIC_DRAW);
|
||||||
vbo.size = 0;
|
vbo.size = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
Log.d(TAG, " > " + mBufferMemoryUsage / (1024 * 1024) + "MB");
|
Log.d(TAG, " > " + mBufferMemoryUsage / MB + "MB");
|
||||||
|
|
||||||
if (CACHE_TILES > 50)
|
if (CACHE_TILES > 50)
|
||||||
CACHE_TILES -= 50;
|
CACHE_TILES -= 50;
|
||||||
@ -1124,6 +1192,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uploadCnt = 0;
|
uploadCnt = 0;
|
||||||
|
mLastBoundVBO = -1;
|
||||||
|
|
||||||
// check visible tiles, set tile clip scissors, upload new vertex data
|
// check visible tiles, set tile clip scissors, upload new vertex data
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
@ -1134,11 +1203,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
if (tile.newData) {
|
if (tile.newData) {
|
||||||
uploadTileData(tile);
|
uploadTileData(tile);
|
||||||
|
|
||||||
if (timing)
|
|
||||||
Log.d(TAG, "buffer upload took: "
|
|
||||||
+ (SystemClock.uptimeMillis() - start));
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,23 +1222,25 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// GLES20.glFinish();
|
|
||||||
GlUtils.checkGlError("upload");
|
if (GlUtils.checkGlOutOfMemory("upload: " + mBufferMemoryUsage)
|
||||||
|
&& LIMIT_BUFFERS > MB)
|
||||||
|
LIMIT_BUFFERS -= MB;
|
||||||
|
|
||||||
if (timing)
|
if (timing)
|
||||||
clear_time = (SystemClock.uptimeMillis() - start);
|
clear_time = (SystemClock.uptimeMillis() - start);
|
||||||
|
|
||||||
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
GLES20.glUseProgram(gPolygonProgram);
|
glUseProgram(gPolygonProgram);
|
||||||
// GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||||
|
|
||||||
if (!mTriangulate) {
|
if (!mTriangulate) {
|
||||||
GLES20.glDisable(GLES20.GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
// Draw Polygons
|
// Draw Polygons
|
||||||
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
// GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
// glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
if (tiles[i].isVisible) {
|
if (tiles[i].isVisible) {
|
||||||
@ -1186,8 +1252,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
drawProxyPolygons(tile);
|
drawProxyPolygons(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlUtils.checkGlError("polygons");
|
// GlUtils.checkGlError("polygons");
|
||||||
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
} else {
|
} else {
|
||||||
// Draw Triangles
|
// Draw Triangles
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
@ -1200,23 +1266,22 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
drawProxyTriangles(tile);
|
drawProxyTriangles(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlUtils.checkGlError("triangles");
|
// GlUtils.checkGlError("triangles");
|
||||||
}
|
}
|
||||||
// required on GalaxyII, Android 2.3.3
|
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
||||||
// GLES20.glDisableVertexAttribArray(gPolygonVertexPositionHandle);
|
glDisableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||||
|
|
||||||
if (timing) {
|
if (timing) {
|
||||||
GLES20.glFinish();
|
glFinish();
|
||||||
poly_time = (SystemClock.uptimeMillis() - start);
|
poly_time = (SystemClock.uptimeMillis() - start);
|
||||||
}
|
}
|
||||||
GLES20.glFlush();
|
|
||||||
|
|
||||||
// Draw lines
|
// Draw lines
|
||||||
GLES20.glEnable(GLES20.GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
GLES20.glUseProgram(gLineProgram);
|
glUseProgram(gLineProgram);
|
||||||
|
|
||||||
// GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
|
glEnableVertexAttribArray(gLineVertexPositionHandle);
|
||||||
// GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
|
glEnableVertexAttribArray(gLineTexturePositionHandle);
|
||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
if (tiles[i].isVisible) {
|
if (tiles[i].isVisible) {
|
||||||
@ -1230,14 +1295,13 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (timing) {
|
if (timing) {
|
||||||
GLES20.glFinish();
|
glFinish();
|
||||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
|
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
|
||||||
+ clear_time + " " + poly_time);
|
+ clear_time + " " + poly_time);
|
||||||
}
|
}
|
||||||
// GLES20.glDisableVertexAttribArray(gLineVertexPositionHandle);
|
glDisableVertexAttribArray(gLineVertexPositionHandle);
|
||||||
// GLES20.glDisableVertexAttribArray(gLineTexturePositionHandle);
|
glDisableVertexAttribArray(gLineTexturePositionHandle);
|
||||||
GlUtils.checkGlError("lines");
|
// GlUtils.checkGlError("lines");
|
||||||
GLES20.glFinish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] mVboIds;
|
private int[] mVboIds;
|
||||||
@ -1261,7 +1325,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
mHeight = height;
|
mHeight = height;
|
||||||
mAspect = (float) height / width;
|
mAspect = (float) height / width;
|
||||||
|
|
||||||
GLES20.glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
|
||||||
int tiles = (mWidth / Tile.TILE_SIZE + 4) * (mHeight / Tile.TILE_SIZE + 4);
|
int tiles = (mWidth / Tile.TILE_SIZE + 4) * (mHeight / Tile.TILE_SIZE + 4);
|
||||||
curTiles = new TilesData(tiles);
|
curTiles = new TilesData(tiles);
|
||||||
@ -1271,7 +1335,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
// Set up vertex buffer objects
|
// Set up vertex buffer objects
|
||||||
int numVBO = (CACHE_TILES + tiles) * 2;
|
int numVBO = (CACHE_TILES + tiles) * 2;
|
||||||
mVboIds = new int[numVBO];
|
mVboIds = new int[numVBO];
|
||||||
GLES20.glGenBuffers(numVBO, mVboIds, 0);
|
glGenBuffers(numVBO, mVboIds, 0);
|
||||||
|
|
||||||
for (int i = 0; i < numVBO; i++)
|
for (int i = 0; i < numVBO; i++)
|
||||||
mVBOs.add(new VertexBufferObject(mVboIds[i]));
|
mVBOs.add(new VertexBufferObject(mVboIds[i]));
|
||||||
@ -1302,21 +1366,25 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
|
String ext = glGetString(GL_EXTENSIONS);
|
||||||
|
|
||||||
if (ext.indexOf("GL_OES_vertex_half_float") >= 0)
|
if (ext.indexOf("GL_OES_vertex_half_float") >= 0) {
|
||||||
useHalfFloat = true;
|
useHalfFloat = true;
|
||||||
|
shortBuffer = new ShortBuffer[20];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
floatBuffer = new FloatBuffer[20];
|
||||||
|
}
|
||||||
Log.d(TAG, "Extensions: " + ext);
|
Log.d(TAG, "Extensions: " + ext);
|
||||||
|
|
||||||
gLineMatrixHandle = GLES20.glGetUniformLocation(gLineProgram, "u_center");
|
gLineMatrixHandle = glGetUniformLocation(gLineProgram, "u_center");
|
||||||
gLineModeHandle = GLES20.glGetUniformLocation(gLineProgram, "u_mode");
|
gLineModeHandle = glGetUniformLocation(gLineProgram, "u_mode");
|
||||||
gLineColorHandle = GLES20.glGetUniformLocation(gLineProgram, "u_color");
|
gLineColorHandle = glGetUniformLocation(gLineProgram, "u_color");
|
||||||
gLineVertexPositionHandle = GLES20
|
gLineVertexPositionHandle = GLES20
|
||||||
.glGetAttribLocation(gLineProgram, "a_position");
|
.glGetAttribLocation(gLineProgram, "a_position");
|
||||||
gLineTexturePositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_st");
|
gLineTexturePositionHandle = glGetAttribLocation(gLineProgram, "a_st");
|
||||||
if (mSimpleLines)
|
if (mSimpleLines)
|
||||||
gLineWidthHandle = GLES20.glGetUniformLocation(gLineProgram, "u_width");
|
gLineWidthHandle = glGetUniformLocation(gLineProgram, "u_width");
|
||||||
|
|
||||||
// Set up the program for rendering polygons
|
// Set up the program for rendering polygons
|
||||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
||||||
@ -1325,31 +1393,39 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
Log.e(TAG, "Could not create polygon program.");
|
Log.e(TAG, "Could not create polygon program.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gPolygonMatrixHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_center");
|
gPolygonMatrixHandle = glGetUniformLocation(gPolygonProgram, "u_center");
|
||||||
gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram,
|
gPolygonVertexPositionHandle = glGetAttribLocation(gPolygonProgram,
|
||||||
"a_position");
|
"a_position");
|
||||||
gPolygonColorHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_color");
|
gPolygonColorHandle = glGetUniformLocation(gPolygonProgram, "u_color");
|
||||||
|
|
||||||
GLES20.glUseProgram(gPolygonProgram);
|
// glUseProgram(gPolygonProgram);
|
||||||
GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
// glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||||
|
//
|
||||||
|
// glUseProgram(gLineProgram);
|
||||||
|
// glEnableVertexAttribArray(gLineVertexPositionHandle);
|
||||||
|
// glEnableVertexAttribArray(gLineTexturePositionHandle);
|
||||||
|
|
||||||
GLES20.glUseProgram(gLineProgram);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
|
|
||||||
GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
|
|
||||||
|
|
||||||
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(false);
|
||||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
glDisable(GL_DITHER);
|
||||||
GLES20.glDepthMask(false);
|
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
|
||||||
GLES20.glDisable(GLES20.GL_DITHER);
|
glClearStencil(0);
|
||||||
GLES20.glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
|
|
||||||
GLES20.glClearStencil(0);
|
|
||||||
|
|
||||||
// GLES20.glFrontFace(GLES20.GL_CCW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processedTile() {
|
public boolean processedTile() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IMapGenerator getMapGenerator() {
|
||||||
|
return new MapGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMapGenerator createMapGenerator() {
|
||||||
|
return new MapGenerator();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class PolygonLayers {
|
|||||||
// Log.d("GLMap", "allocate buffer " + size);
|
// Log.d("GLMap", "allocate buffer " + size);
|
||||||
fbuf = bbuf.asFloatBuffer();
|
fbuf = bbuf.asFloatBuffer();
|
||||||
} else {
|
} else {
|
||||||
fbuf.position(0);
|
fbuf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fbuf.put(mFillCoords, 0, 8);
|
fbuf.put(mFillCoords, 0, 8);
|
||||||
@ -95,7 +95,7 @@ class PolygonLayers {
|
|||||||
l.pool = null;
|
l.pool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbuf.position(0);
|
fbuf.flip();
|
||||||
|
|
||||||
// not needed for drawing
|
// not needed for drawing
|
||||||
layers = null;
|
layers = null;
|
||||||
@ -121,7 +121,7 @@ class PolygonLayers {
|
|||||||
ByteOrder.nativeOrder());
|
ByteOrder.nativeOrder());
|
||||||
sbuf = bbuf.asShortBuffer();
|
sbuf = bbuf.asShortBuffer();
|
||||||
} else {
|
} else {
|
||||||
sbuf.position(0);
|
sbuf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
short[] data = new short[PoolItem.SIZE];
|
short[] data = new short[PoolItem.SIZE];
|
||||||
@ -157,7 +157,7 @@ class PolygonLayers {
|
|||||||
l.pool = null;
|
l.pool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
sbuf.position(0);
|
sbuf.flip();
|
||||||
|
|
||||||
// not needed for drawing
|
// not needed for drawing
|
||||||
layers = null;
|
layers = null;
|
||||||
|
|||||||
@ -14,9 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.mapgenerator;
|
package org.mapsforge.android.mapgenerator;
|
||||||
|
|
||||||
import org.mapsforge.android.MapRenderer;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.core.GeoPoint;
|
|
||||||
import org.mapsforge.database.IMapDatabase;
|
import org.mapsforge.database.IMapDatabase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,31 +35,13 @@ public interface IMapGenerator {
|
|||||||
*/
|
*/
|
||||||
boolean executeJob(MapGeneratorJob mapGeneratorJob);
|
boolean executeJob(MapGeneratorJob mapGeneratorJob);
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the start point of this MapGenerator (may be null).
|
|
||||||
*/
|
|
||||||
GeoPoint getStartPoint();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the start zoom level of this MapGenerator (may be null).
|
|
||||||
*/
|
|
||||||
Byte getStartZoomLevel();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the maximum zoom level that this MapGenerator supports.
|
|
||||||
*/
|
|
||||||
byte getZoomLevelMax();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mapView
|
|
||||||
* the MapView
|
|
||||||
* @return GLSurfaceView Renderer
|
|
||||||
*/
|
|
||||||
MapRenderer getMapRenderer(MapView mapView);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapDatabase
|
* @param mapDatabase
|
||||||
* the MapDatabase from which the map data will be read.
|
* the MapDatabase from which the map data will be read.
|
||||||
*/
|
*/
|
||||||
void setMapDatabase(IMapDatabase mapDatabase);
|
void setMapDatabase(IMapDatabase mapDatabase);
|
||||||
|
|
||||||
|
IMapDatabase getMapDatabase();
|
||||||
|
|
||||||
|
void setRenderTheme(RenderTheme theme);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public class JobParameters {
|
|||||||
/**
|
/**
|
||||||
* The render theme which should be used.
|
* The render theme which should be used.
|
||||||
*/
|
*/
|
||||||
public final JobTheme jobTheme;
|
public final Theme theme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text scale factor which should applied to the render theme.
|
* The text scale factor which should applied to the render theme.
|
||||||
@ -32,13 +32,13 @@ public class JobParameters {
|
|||||||
private final int mHashCodeValue;
|
private final int mHashCodeValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param jobTheme
|
* @param theme
|
||||||
* render theme which should be used.
|
* render theme which should be used.
|
||||||
* @param textScale
|
* @param textScale
|
||||||
* the text scale factor which should applied to the render theme.
|
* the text scale factor which should applied to the render theme.
|
||||||
*/
|
*/
|
||||||
public JobParameters(JobTheme jobTheme, float textScale) {
|
public JobParameters(Theme theme, float textScale) {
|
||||||
this.jobTheme = jobTheme;
|
this.theme = theme;
|
||||||
this.textScale = textScale;
|
this.textScale = textScale;
|
||||||
mHashCodeValue = calculateHashCode();
|
mHashCodeValue = calculateHashCode();
|
||||||
}
|
}
|
||||||
@ -52,11 +52,11 @@ public class JobParameters {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
JobParameters other = (JobParameters) obj;
|
JobParameters other = (JobParameters) obj;
|
||||||
if (jobTheme == null) {
|
if (theme == null) {
|
||||||
if (other.jobTheme != null) {
|
if (other.theme != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!jobTheme.equals(other.jobTheme)) {
|
} else if (!theme.equals(other.theme)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Float.floatToIntBits(textScale) != Float.floatToIntBits(other.textScale)) {
|
if (Float.floatToIntBits(textScale) != Float.floatToIntBits(other.textScale)) {
|
||||||
@ -75,7 +75,7 @@ public class JobParameters {
|
|||||||
*/
|
*/
|
||||||
private int calculateHashCode() {
|
private int calculateHashCode() {
|
||||||
int result = 7;
|
int result = 7;
|
||||||
result = 31 * result + ((jobTheme == null) ? 0 : jobTheme.hashCode());
|
result = 31 * result + ((theme == null) ? 0 : theme.hashCode());
|
||||||
result = 31 * result + Float.floatToIntBits(textScale);
|
result = 31 * result + Float.floatToIntBits(textScale);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,7 +103,8 @@ public class JobQueue {
|
|||||||
* Schedules all jobs in this queue.
|
* Schedules all jobs in this queue.
|
||||||
*/
|
*/
|
||||||
private void schedule() {
|
private void schedule() {
|
||||||
PriorityQueue<MapGeneratorJob> tempJobQueue = new PriorityQueue<MapGeneratorJob>(INITIAL_CAPACITY);
|
PriorityQueue<MapGeneratorJob> tempJobQueue = new PriorityQueue<MapGeneratorJob>(
|
||||||
|
INITIAL_CAPACITY);
|
||||||
|
|
||||||
TileScheduler.time = SystemClock.uptimeMillis();
|
TileScheduler.time = SystemClock.uptimeMillis();
|
||||||
TileScheduler.mapPosition = mMapView.getMapPosition().getMapPosition();
|
TileScheduler.mapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
|
|||||||
@ -37,29 +37,40 @@ public final class MapDatabaseFactory {
|
|||||||
return new org.mapsforge.database.postgis.MapDatabase();
|
return new org.mapsforge.database.postgis.MapDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
MapDatabaseInternal mapDatabaseInternal = MapDatabaseInternal
|
MapDatabases mapDatabaseInternal = MapDatabases.valueOf(mapDatabaseName);
|
||||||
.valueOf(mapDatabaseName);
|
|
||||||
|
|
||||||
return MapDatabaseFactory.createMapDatabase(mapDatabaseInternal);
|
return MapDatabaseFactory.createMapDatabase(mapDatabaseInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MapDatabases getMapDatabase(AttributeSet attributeSet) {
|
||||||
|
String mapDatabaseName = attributeSet.getAttributeValue(null,
|
||||||
|
MAP_DATABASE_ATTRIBUTE_NAME);
|
||||||
|
if (mapDatabaseName == null) {
|
||||||
|
return MapDatabases.POSTGIS_READER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MapDatabases.valueOf(mapDatabaseName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapDatabaseInternal
|
* @param mapDatabase
|
||||||
* the internal MapDatabase implementation.
|
* the internal MapDatabase implementation.
|
||||||
* @return a new MapGenerator instance.
|
* @return a new MapGenerator instance.
|
||||||
*/
|
*/
|
||||||
public static IMapDatabase createMapDatabase(MapDatabaseInternal mapDatabaseInternal) {
|
public static IMapDatabase createMapDatabase(MapDatabases mapDatabase) {
|
||||||
switch (mapDatabaseInternal) {
|
switch (mapDatabase) {
|
||||||
case MAP_READER:
|
case MAP_READER:
|
||||||
return new org.mapsforge.database.mapfile.MapDatabase();
|
return new org.mapsforge.database.mapfile.MapDatabase();
|
||||||
case JSON_READER:
|
case JSON_READER:
|
||||||
return new org.mapsforge.database.json.MapDatabase();
|
return new org.mapsforge.database.json.MapDatabase();
|
||||||
case POSTGIS_READER:
|
case POSTGIS_READER:
|
||||||
return new org.mapsforge.database.postgis.MapDatabase();
|
return new org.mapsforge.database.postgis.MapDatabase();
|
||||||
|
case PBMAP_READER:
|
||||||
|
return new org.mapsforge.database.pbmap.MapDatabase();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("unknown enum value: " + mapDatabaseInternal);
|
throw new IllegalArgumentException("unknown enum value: " + mapDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapDatabaseFactory() {
|
private MapDatabaseFactory() {
|
||||||
|
|||||||
@ -17,7 +17,7 @@ package org.mapsforge.android.mapgenerator;
|
|||||||
/**
|
/**
|
||||||
* MapDatabase Implementations
|
* MapDatabase Implementations
|
||||||
*/
|
*/
|
||||||
public enum MapDatabaseInternal {
|
public enum MapDatabases {
|
||||||
/**
|
/**
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
@ -33,4 +33,8 @@ public enum MapDatabaseInternal {
|
|||||||
*/
|
*/
|
||||||
POSTGIS_READER,
|
POSTGIS_READER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
PBMAP_READER,
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
/**
|
/**
|
||||||
* The rendering parameters for this job.
|
* The rendering parameters for this job.
|
||||||
*/
|
*/
|
||||||
public final JobParameters jobParameters;
|
// public final JobParameters jobParameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tile which should be generated.
|
* The tile which should be generated.
|
||||||
@ -45,7 +45,6 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
public final MapTile tile;
|
public final MapTile tile;
|
||||||
|
|
||||||
private transient int mHashCodeValue;
|
private transient int mHashCodeValue;
|
||||||
private final IMapGenerator mMapGenerator;
|
|
||||||
private transient double mPriority;
|
private transient double mPriority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,18 +89,15 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
*
|
*
|
||||||
* @param _tile
|
* @param _tile
|
||||||
* the tile which should be generated.
|
* the tile which should be generated.
|
||||||
* @param mapGenerator
|
|
||||||
* the MapGenerator for this job.
|
|
||||||
* @param _jobParameters
|
* @param _jobParameters
|
||||||
* the rendering parameters for this job.
|
* the rendering parameters for this job.
|
||||||
* @param _debugSettings
|
* @param _debugSettings
|
||||||
* the debug settings for this job.
|
* the debug settings for this job.
|
||||||
*/
|
*/
|
||||||
public MapGeneratorJob(MapTile _tile, IMapGenerator mapGenerator,
|
public MapGeneratorJob(MapTile _tile, JobParameters _jobParameters,
|
||||||
JobParameters _jobParameters, DebugSettings _debugSettings) {
|
DebugSettings _debugSettings) {
|
||||||
tile = _tile;
|
tile = _tile;
|
||||||
mMapGenerator = mapGenerator;
|
// jobParameters = _jobParameters;
|
||||||
jobParameters = _jobParameters;
|
|
||||||
debugSettings = _debugSettings;
|
debugSettings = _debugSettings;
|
||||||
calculateTransientValues();
|
calculateTransientValues();
|
||||||
}
|
}
|
||||||
@ -133,16 +129,14 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
} else if (!debugSettings.equals(other.debugSettings)) {
|
} else if (!debugSettings.equals(other.debugSettings)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (jobParameters == null) {
|
// if (jobParameters == null) {
|
||||||
if (other.jobParameters != null) {
|
// if (other.jobParameters != null) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
} else if (!jobParameters.equals(other.jobParameters)) {
|
// } else if (!jobParameters.equals(other.jobParameters)) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
if (mMapGenerator != other.mMapGenerator) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
if (other.tile != null) {
|
if (other.tile != null) {
|
||||||
return false;
|
return false;
|
||||||
@ -164,8 +158,7 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
private int calculateHashCode() {
|
private int calculateHashCode() {
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = 31 * result + ((debugSettings == null) ? 0 : debugSettings.hashCode());
|
result = 31 * result + ((debugSettings == null) ? 0 : debugSettings.hashCode());
|
||||||
result = 31 * result + ((jobParameters == null) ? 0 : jobParameters.hashCode());
|
// result = 31 * result + ((jobParameters == null) ? 0 : jobParameters.hashCode());
|
||||||
result = 31 * result + ((mMapGenerator == null) ? 0 : mMapGenerator.hashCode());
|
|
||||||
result = 31 * result + ((tile == null) ? 0 : tile.hashCode());
|
result = 31 * result + ((tile == null) ? 0 : tile.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -177,7 +170,8 @@ public class MapGeneratorJob implements Comparable<MapGeneratorJob>, Serializabl
|
|||||||
mHashCodeValue = calculateHashCode();
|
mHashCodeValue = calculateHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream objectInputStream) throws IOException,
|
||||||
|
ClassNotFoundException {
|
||||||
objectInputStream.defaultReadObject();
|
objectInputStream.defaultReadObject();
|
||||||
calculateTransientValues();
|
calculateTransientValues();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,46 +14,66 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.mapgenerator;
|
package org.mapsforge.android.mapgenerator;
|
||||||
|
|
||||||
|
import org.mapsforge.android.IMapRenderer;
|
||||||
|
import org.mapsforge.android.MapView;
|
||||||
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for the internal MapGenerator implementations.
|
* A factory for the internal MapGenerator implementations.
|
||||||
*/
|
*/
|
||||||
public final class MapGeneratorFactory {
|
public final class MapRendererFactory {
|
||||||
private static final String MAP_GENERATOR_ATTRIBUTE_NAME = "mapGenerator";
|
private static final String MAP_GENERATOR_ATTRIBUTE_NAME = "mapGenerator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param mapView
|
||||||
|
* ...
|
||||||
* @param attributeSet
|
* @param attributeSet
|
||||||
* A collection of attributes which includes the desired MapGenerator.
|
* A collection of attributes which includes the desired MapGenerator.
|
||||||
* @return a new MapGenerator instance.
|
* @return a new MapGenerator instance.
|
||||||
*/
|
*/
|
||||||
public static IMapGenerator createMapGenerator(AttributeSet attributeSet) {
|
public static IMapRenderer createMapRenderer(MapView mapView,
|
||||||
String mapGeneratorName = attributeSet.getAttributeValue(null, MAP_GENERATOR_ATTRIBUTE_NAME);
|
AttributeSet attributeSet) {
|
||||||
|
String mapGeneratorName = attributeSet.getAttributeValue(null,
|
||||||
|
MAP_GENERATOR_ATTRIBUTE_NAME);
|
||||||
if (mapGeneratorName == null) {
|
if (mapGeneratorName == null) {
|
||||||
return new org.mapsforge.android.glrenderer.DatabaseRenderer();
|
return new org.mapsforge.android.glrenderer.MapRenderer(mapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
MapGeneratorInternal mapGeneratorInternal = MapGeneratorInternal.valueOf(mapGeneratorName);
|
MapRenderers mapGeneratorInternal = MapRenderers.valueOf(mapGeneratorName);
|
||||||
return MapGeneratorFactory.createMapGenerator(mapGeneratorInternal);
|
return MapRendererFactory.createMapRenderer(mapView, mapGeneratorInternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MapRenderers getMapGenerator(AttributeSet attributeSet) {
|
||||||
|
String mapGeneratorName = attributeSet.getAttributeValue(null,
|
||||||
|
MAP_GENERATOR_ATTRIBUTE_NAME);
|
||||||
|
if (mapGeneratorName == null) {
|
||||||
|
return MapRenderers.GL_RENDERER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MapRenderers.valueOf(mapGeneratorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param mapView
|
||||||
|
* ...
|
||||||
* @param mapGeneratorInternal
|
* @param mapGeneratorInternal
|
||||||
* the internal MapGenerator implementation.
|
* the internal MapGenerator implementation.
|
||||||
* @return a new MapGenerator instance.
|
* @return a new MapGenerator instance.
|
||||||
*/
|
*/
|
||||||
public static IMapGenerator createMapGenerator(MapGeneratorInternal mapGeneratorInternal) {
|
public static IMapRenderer createMapRenderer(MapView mapView,
|
||||||
|
MapRenderers mapGeneratorInternal) {
|
||||||
switch (mapGeneratorInternal) {
|
switch (mapGeneratorInternal) {
|
||||||
case SW_RENDERER:
|
case SW_RENDERER:
|
||||||
return new org.mapsforge.android.swrenderer.DatabaseRenderer();
|
return new org.mapsforge.android.swrenderer.MapRenderer(mapView);
|
||||||
case GL_RENDERER:
|
case GL_RENDERER:
|
||||||
return new org.mapsforge.android.glrenderer.DatabaseRenderer();
|
return new org.mapsforge.android.glrenderer.MapRenderer(mapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("unknown enum value: " + mapGeneratorInternal);
|
throw new IllegalArgumentException("unknown enum value: " + mapGeneratorInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapGeneratorFactory() {
|
private MapRendererFactory() {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ package org.mapsforge.android.mapgenerator;
|
|||||||
/**
|
/**
|
||||||
* Enumeration of all internal MapGenerator implementations.
|
* Enumeration of all internal MapGenerator implementations.
|
||||||
*/
|
*/
|
||||||
public enum MapGeneratorInternal {
|
public enum MapRenderers {
|
||||||
/**
|
/**
|
||||||
* texture renderer.
|
* texture renderer.
|
||||||
*/
|
*/
|
||||||
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.mapgenerator;
|
package org.mapsforge.android.mapgenerator;
|
||||||
|
|
||||||
import org.mapsforge.android.MapRenderer;
|
import org.mapsforge.android.IMapRenderer;
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.utils.PausableThread;
|
import org.mapsforge.android.utils.PausableThread;
|
||||||
|
|
||||||
@ -23,35 +23,33 @@ import org.mapsforge.android.utils.PausableThread;
|
|||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
public class MapWorker extends PausableThread {
|
public class MapWorker extends PausableThread {
|
||||||
private static final String THREAD_NAME = "MapWorker";
|
private final String THREAD_NAME;
|
||||||
|
|
||||||
private final JobQueue mJobQueue;
|
private final JobQueue mJobQueue;
|
||||||
private IMapGenerator mMapGenerator;
|
private final IMapGenerator mMapGenerator;
|
||||||
private MapRenderer mMapRenderer;
|
private final IMapRenderer mMapRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param id
|
||||||
|
* thread id
|
||||||
* @param mapView
|
* @param mapView
|
||||||
* the MapView for which this MapWorker generates map tiles.
|
* the MapView for which this MapWorker generates map tiles.
|
||||||
|
* @param mapGenerator
|
||||||
|
* ...
|
||||||
|
* @param mapRenderer
|
||||||
|
* ...
|
||||||
*/
|
*/
|
||||||
public MapWorker(MapView mapView) {
|
public MapWorker(int id, MapView mapView, IMapGenerator mapGenerator,
|
||||||
|
IMapRenderer mapRenderer) {
|
||||||
super();
|
super();
|
||||||
mJobQueue = mapView.getJobQueue();
|
mJobQueue = mapView.getJobQueue();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mapGenerator
|
|
||||||
* the MapGenerator which this MapWorker should use.
|
|
||||||
*/
|
|
||||||
public void setMapGenerator(IMapGenerator mapGenerator) {
|
|
||||||
mMapGenerator = mapGenerator;
|
mMapGenerator = mapGenerator;
|
||||||
|
mMapRenderer = mapRenderer;
|
||||||
|
|
||||||
|
THREAD_NAME = "MapWorker" + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public IMapGenerator getMapGenerator() {
|
||||||
* @param mapRenderer
|
return mMapGenerator;
|
||||||
* the MapRenderer
|
|
||||||
*/
|
|
||||||
public void setMapRenderer(MapRenderer mapRenderer) {
|
|
||||||
mMapRenderer = mapRenderer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,6 +63,7 @@ public class MapWorker extends PausableThread {
|
|||||||
|
|
||||||
if (mMapGenerator == null || mapGeneratorJob == null)
|
if (mMapGenerator == null || mapGeneratorJob == null)
|
||||||
return;
|
return;
|
||||||
|
// Log.d(THREAD_NAME, "processing: " + mapGeneratorJob.tile);
|
||||||
|
|
||||||
boolean success = mMapGenerator.executeJob(mapGeneratorJob);
|
boolean success = mMapGenerator.executeJob(mapGeneratorJob);
|
||||||
|
|
||||||
@ -80,7 +79,8 @@ public class MapWorker extends PausableThread {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getThreadPriority() {
|
protected int getThreadPriority() {
|
||||||
return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
|
// return (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2;
|
||||||
|
return Thread.MIN_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import java.io.Serializable;
|
|||||||
/**
|
/**
|
||||||
* A JobTheme defines the render theme which is used for a {@link MapGeneratorJob}.
|
* A JobTheme defines the render theme which is used for a {@link MapGeneratorJob}.
|
||||||
*/
|
*/
|
||||||
public interface JobTheme extends Serializable {
|
public interface Theme extends Serializable {
|
||||||
/**
|
/**
|
||||||
* @return an InputStream to read the render theme data from.
|
* @return an InputStream to read the render theme data from.
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
@ -21,12 +21,12 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
|
|
||||||
import org.mapsforge.android.mapgenerator.JobTheme;
|
import org.mapsforge.android.mapgenerator.Theme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ExternalRenderTheme allows for customizing the rendering style of the map via an XML file.
|
* An ExternalRenderTheme allows for customizing the rendering style of the map via an XML file.
|
||||||
*/
|
*/
|
||||||
public class ExternalRenderTheme implements JobTheme {
|
public class ExternalRenderTheme implements Theme {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final long mFileModificationDate;
|
private final long mFileModificationDate;
|
||||||
|
|||||||
@ -16,12 +16,12 @@ package org.mapsforge.android.rendertheme;
|
|||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.mapsforge.android.mapgenerator.JobTheme;
|
import org.mapsforge.android.mapgenerator.Theme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of all internal rendering themes.
|
* Enumeration of all internal rendering themes.
|
||||||
*/
|
*/
|
||||||
public enum InternalRenderTheme implements JobTheme {
|
public enum InternalRenderTheme implements Theme {
|
||||||
/**
|
/**
|
||||||
* A rendering theme similar to the OpenStreetMap Osmarender style.
|
* A rendering theme similar to the OpenStreetMap Osmarender style.
|
||||||
*
|
*
|
||||||
@ -37,6 +37,9 @@ public enum InternalRenderTheme implements JobTheme {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getRenderThemeAsStream() {
|
public InputStream getRenderThemeAsStream() {
|
||||||
return Thread.currentThread().getClass().getResourceAsStream(mPath);
|
// getResourceAsStream(mPath);
|
||||||
|
return InternalRenderTheme.class.getResourceAsStream(mPath);
|
||||||
|
// return Thread.currentThread().getClass().getResourceAsStream(mPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,10 +87,6 @@ public class RenderTheme {
|
|||||||
private final LRUCache<MatchingCacheKey, RenderInstruction[]> mMatchingCacheWay;
|
private final LRUCache<MatchingCacheKey, RenderInstruction[]> mMatchingCacheWay;
|
||||||
private final LRUCache<MatchingCacheKey, RenderInstruction[]> mMatchingCacheArea;
|
private final LRUCache<MatchingCacheKey, RenderInstruction[]> mMatchingCacheArea;
|
||||||
|
|
||||||
// private List<RenderInstruction> mMatchingListWay;
|
|
||||||
// private List<RenderInstruction> mMatchingListArea;
|
|
||||||
// private List<RenderInstruction> mMatchingListNode;
|
|
||||||
|
|
||||||
RenderTheme(int mapBackground, float baseStrokeWidth, float baseTextSize) {
|
RenderTheme(int mapBackground, float baseStrokeWidth, float baseTextSize) {
|
||||||
mMapBackground = mapBackground;
|
mMapBackground = mapBackground;
|
||||||
mBaseStrokeWidth = baseStrokeWidth;
|
mBaseStrokeWidth = baseStrokeWidth;
|
||||||
@ -198,7 +194,7 @@ public class RenderTheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderInstruction[] mRenderInstructions = null;
|
// private RenderInstruction[] mRenderInstructions = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches a way with the given parameters against this RenderTheme.
|
* Matches a way with the given parameters against this RenderTheme.
|
||||||
@ -213,23 +209,26 @@ public class RenderTheme {
|
|||||||
* way is Closed
|
* way is Closed
|
||||||
* @param changed
|
* @param changed
|
||||||
* ...
|
* ...
|
||||||
|
* @return currently processed render instructions
|
||||||
*/
|
*/
|
||||||
public void matchWay(IRenderCallback renderCallback, Tag[] tags, byte zoomLevel,
|
public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
|
||||||
|
Tag[] tags,
|
||||||
|
byte zoomLevel,
|
||||||
boolean closed, boolean changed) {
|
boolean closed, boolean changed) {
|
||||||
RenderInstruction[] renderInstructions = null;
|
RenderInstruction[] renderInstructions = null;
|
||||||
|
|
||||||
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
||||||
MatchingCacheKey matchingCacheKey;
|
MatchingCacheKey matchingCacheKey;
|
||||||
|
|
||||||
if (!changed) {
|
// if (!changed) {
|
||||||
renderInstructions = mRenderInstructions;
|
// renderInstructions = mRenderInstructions;
|
||||||
|
//
|
||||||
if (renderInstructions != null) {
|
// if (renderInstructions != null) {
|
||||||
for (int i = 0, n = renderInstructions.length; i < n; i++)
|
// for (int i = 0, n = renderInstructions.length; i < n; i++)
|
||||||
renderInstructions[i].renderWay(renderCallback, tags);
|
// renderInstructions[i].renderWay(renderCallback, tags);
|
||||||
}
|
// }
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
matchingCache = mMatchingCacheArea;
|
matchingCache = mMatchingCacheArea;
|
||||||
@ -267,90 +266,8 @@ public class RenderTheme {
|
|||||||
matchingCache.put(matchingCacheKey, renderInstructions);
|
matchingCache.put(matchingCacheKey, renderInstructions);
|
||||||
}
|
}
|
||||||
|
|
||||||
mRenderInstructions = renderInstructions;
|
// mRenderInstructions = renderInstructions;
|
||||||
|
return renderInstructions;
|
||||||
// if (matchingList != null) {
|
|
||||||
// for (int i = 0, n = matchingList.size(); i < n; ++i) {
|
|
||||||
// matchingList.get(i).renderWay(renderCallback, tags);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return renderInstructions;
|
|
||||||
|
|
||||||
// if (closed) {
|
|
||||||
// mMatchingListArea = matchingList;
|
|
||||||
// } else {
|
|
||||||
// mMatchingListWay = matchingList;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (mCompareKey.set(tags, zoomLevel, closed)) {
|
|
||||||
// // Log.d("mapsforge", "SAME AS BAFORE!!!" + tags);
|
|
||||||
// for (int i = 0, n = mInstructionList.length; i < n; ++i) {
|
|
||||||
// mInstructionList[i].renderWay(renderCallback, tags);
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// SparseArray<RenderInstruction[]> matchingList = mMatchingCache.get(mCompareKey);
|
|
||||||
//
|
|
||||||
// if (matchingList != null) {
|
|
||||||
// mInstructionList = matchingList.get(zoomLevel);
|
|
||||||
// if (mInstructionList != null) {
|
|
||||||
// // cache hit
|
|
||||||
// // Log.d("mapsforge", "CCACHE HIT !!!" + tags);
|
|
||||||
// for (int i = 0, n = mInstructionList.length; i < n; ++i) {
|
|
||||||
// mInstructionList[i].renderWay(renderCallback, tags);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // Log.d("mapsforge", "CACHE MISS !!!" + tags);
|
|
||||||
// // cache miss
|
|
||||||
// ArrayList<RenderInstruction> instructionList = new ArrayList<RenderInstruction>();
|
|
||||||
//
|
|
||||||
// for (int i = 0, n = mRulesList.size(); i < n; ++i) {
|
|
||||||
// mRulesList.get(i).matchWay(renderCallback, mCompareKey.getTags(), zoomLevel, closed, instructionList);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// boolean found = false;
|
|
||||||
// int size = instructionList.size();
|
|
||||||
//
|
|
||||||
// if (matchingList == null) {
|
|
||||||
// matchingList = new SparseArray<RenderInstruction[]>(25);
|
|
||||||
// MatchingCacheKey matchingCacheKey = new MatchingCacheKey(mCompareKey);
|
|
||||||
// mMatchingCache.put(matchingCacheKey, matchingList);
|
|
||||||
// } else {
|
|
||||||
// // check if another zoomLevel uses the same instructionList
|
|
||||||
// for (int i = 0, n = matchingList.size(); i < n; i++) {
|
|
||||||
// int key = matchingList.keyAt(i);
|
|
||||||
//
|
|
||||||
// RenderInstruction[] list2 = matchingList.get(key);
|
|
||||||
// if (list2.length != size)
|
|
||||||
// continue;
|
|
||||||
//
|
|
||||||
// int j = 0;
|
|
||||||
// while (j < size && (list2[j] == instructionList.get(j)))
|
|
||||||
// j++;
|
|
||||||
//
|
|
||||||
// if (j == size) {
|
|
||||||
// instructionList.clear();
|
|
||||||
// mInstructionList = list2;
|
|
||||||
// found = true;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (!found) {
|
|
||||||
// mInstructionList = new RenderInstruction[size];
|
|
||||||
// for (int i = 0; i < size; i++)
|
|
||||||
// mInstructionList[i] = instructionList.get(i);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (int i = 0, n = mInstructionList.length; i < n; ++i)
|
|
||||||
// mInstructionList[i].renderWay(renderCallback, tags);
|
|
||||||
//
|
|
||||||
// matchingList.put(zoomLevel, mInstructionList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addRule(Rule rule) {
|
void addRule(Rule rule) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -14,77 +14,39 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.swrenderer;
|
package org.mapsforge.android.swrenderer;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
import org.mapsforge.android.mapgenerator.JobTheme;
|
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
|
import org.mapsforge.android.mapgenerator.Theme;
|
||||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||||
import org.mapsforge.android.rendertheme.RenderThemeHandler;
|
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||||
import org.mapsforge.core.GeoPoint;
|
|
||||||
import org.mapsforge.core.Tag;
|
import org.mapsforge.core.Tag;
|
||||||
import org.mapsforge.core.Tile;
|
import org.mapsforge.core.Tile;
|
||||||
import org.mapsforge.database.IMapDatabase;
|
import org.mapsforge.database.IMapDatabase;
|
||||||
import org.mapsforge.database.IMapDatabaseCallback;
|
import org.mapsforge.database.IMapDatabaseCallback;
|
||||||
import org.mapsforge.database.MapFileInfo;
|
|
||||||
import org.mapsforge.database.mapfile.MapDatabase;
|
import org.mapsforge.database.mapfile.MapDatabase;
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A DatabaseRenderer renders map tiles by reading from a {@link MapDatabase}.
|
* A DatabaseRenderer renders map tiles by reading from a {@link MapDatabase}.
|
||||||
*/
|
*/
|
||||||
public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||||
IMapDatabaseCallback {
|
IMapDatabaseCallback {
|
||||||
private static String TAG = DatabaseRenderer.class.getName();
|
// private static String TAG = MapGenerator.class.getName();
|
||||||
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 12);
|
|
||||||
private static final byte LAYERS = 11;
|
private static final byte LAYERS = 11;
|
||||||
private static final Paint PAINT_WATER_TILE_HIGHTLIGHT = new Paint(
|
private static final Paint PAINT_WATER_TILE_HIGHTLIGHT = new Paint(
|
||||||
Paint.ANTI_ALIAS_FLAG);
|
Paint.ANTI_ALIAS_FLAG);
|
||||||
private static final double STROKE_INCREASE = 1.5;
|
private static final double STROKE_INCREASE = 1.5;
|
||||||
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
|
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
|
||||||
|
|
||||||
private static final byte ZOOM_MAX = 22;
|
|
||||||
|
|
||||||
// private static MapRenderer mMapRenderer;
|
|
||||||
|
|
||||||
private static RenderTheme getRenderTheme(JobTheme jobTheme) {
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = jobTheme.getRenderThemeAsStream();
|
|
||||||
return RenderThemeHandler.getRenderTheme(inputStream);
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (SAXException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (inputStream != null) {
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte getValidLayer(byte layer) {
|
private static byte getValidLayer(byte layer) {
|
||||||
if (layer < 0) {
|
if (layer < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -103,7 +65,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
private List<PointTextContainer> mNodes;
|
private List<PointTextContainer> mNodes;
|
||||||
private float mPoiX;
|
private float mPoiX;
|
||||||
private float mPoiY;
|
private float mPoiY;
|
||||||
private JobTheme mPreviousJobTheme;
|
private Theme mPreviousJobTheme;
|
||||||
private float mPreviousTextScale;
|
private float mPreviousTextScale;
|
||||||
private byte mPreviousZoomLevel;
|
private byte mPreviousZoomLevel;
|
||||||
private static RenderTheme renderTheme;
|
private static RenderTheme renderTheme;
|
||||||
@ -138,7 +100,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
/**
|
/**
|
||||||
* Constructs a new DatabaseRenderer.
|
* Constructs a new DatabaseRenderer.
|
||||||
*/
|
*/
|
||||||
public DatabaseRenderer() {
|
public MapGenerator() {
|
||||||
mCanvasRasterer = new CanvasRasterer();
|
mCanvasRasterer = new CanvasRasterer();
|
||||||
mLabelPlacement = new LabelPlacement();
|
mLabelPlacement = new LabelPlacement();
|
||||||
|
|
||||||
@ -161,8 +123,8 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
@Override
|
@Override
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
mTileBitmap.recycle();
|
mTileBitmap.recycle();
|
||||||
if (DatabaseRenderer.renderTheme != null) {
|
if (MapGenerator.renderTheme != null) {
|
||||||
DatabaseRenderer.renderTheme.destroy();
|
MapGenerator.renderTheme.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,30 +151,30 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
// mTileHeight = mLat1 - mLat2;
|
// mTileHeight = mLat1 - mLat2;
|
||||||
mScale = mapGeneratorJob.getScale();
|
mScale = mapGeneratorJob.getScale();
|
||||||
|
|
||||||
JobTheme jobTheme = mapGeneratorJob.jobParameters.jobTheme;
|
// Theme theme = mapGeneratorJob.jobParameters.theme;
|
||||||
if (!jobTheme.equals(mPreviousJobTheme)) {
|
// if (!theme.equals(mPreviousJobTheme)) {
|
||||||
if (DatabaseRenderer.renderTheme == null)
|
// // if (MapGenerator.renderTheme == null)
|
||||||
DatabaseRenderer.renderTheme = getRenderTheme(jobTheme);
|
// // MapGenerator.renderTheme = getRenderTheme(theme);
|
||||||
if (DatabaseRenderer.renderTheme == null) {
|
// // if (MapGenerator.renderTheme == null) {
|
||||||
mPreviousJobTheme = null;
|
// // mPreviousJobTheme = null;
|
||||||
return false;
|
// // return false;
|
||||||
}
|
// // }
|
||||||
createWayLists();
|
// createWayLists();
|
||||||
mPreviousJobTheme = jobTheme;
|
// mPreviousJobTheme = theme;
|
||||||
mPreviousZoomLevel = Byte.MIN_VALUE;
|
// mPreviousZoomLevel = Byte.MIN_VALUE;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
byte zoomLevel = mCurrentTile.zoomLevel;
|
// byte zoomLevel = mCurrentTile.zoomLevel;
|
||||||
if (zoomLevel != mPreviousZoomLevel) {
|
// if (zoomLevel != mPreviousZoomLevel) {
|
||||||
setScaleStrokeWidth(zoomLevel);
|
// setScaleStrokeWidth(zoomLevel);
|
||||||
mPreviousZoomLevel = zoomLevel;
|
// mPreviousZoomLevel = zoomLevel;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
float textScale = mapGeneratorJob.jobParameters.textScale;
|
// float textScale = mapGeneratorJob.jobParameters.textScale;
|
||||||
if (textScale != mPreviousTextScale) {
|
// if (textScale != mPreviousTextScale) {
|
||||||
DatabaseRenderer.renderTheme.scaleTextSize(textScale);
|
// MapGenerator.renderTheme.scaleTextSize(textScale);
|
||||||
mPreviousTextScale = textScale;
|
// mPreviousTextScale = textScale;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (mMapDatabase != null) {
|
if (mMapDatabase != null) {
|
||||||
mMapDatabase.executeQuery(mCurrentTile, this);
|
mMapDatabase.executeQuery(mCurrentTile, this);
|
||||||
@ -230,7 +192,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
// FIXME mCoords = mMapDatabase.getCoordinates();
|
// FIXME mCoords = mMapDatabase.getCoordinates();
|
||||||
|
|
||||||
mCanvasRasterer.setCanvasBitmap(mTileBitmap, mScale);
|
mCanvasRasterer.setCanvasBitmap(mTileBitmap, mScale);
|
||||||
mCanvasRasterer.fill(DatabaseRenderer.renderTheme.getMapBackground());
|
mCanvasRasterer.fill(MapGenerator.renderTheme.getMapBackground());
|
||||||
mCanvasRasterer.drawWays(mCoords, mWays);
|
mCanvasRasterer.drawWays(mCoords, mWays);
|
||||||
mCanvasRasterer.drawSymbols(mWaySymbols);
|
mCanvasRasterer.drawSymbols(mWaySymbols);
|
||||||
mCanvasRasterer.drawSymbols(mPointSymbols);
|
mCanvasRasterer.drawSymbols(mPointSymbols);
|
||||||
@ -255,37 +217,6 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public GeoPoint getStartPoint() {
|
|
||||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
|
||||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
|
||||||
if (mapFileInfo.startPosition != null) {
|
|
||||||
return mapFileInfo.startPosition;
|
|
||||||
} else if (mapFileInfo.mapCenter != null) {
|
|
||||||
return mapFileInfo.mapCenter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Byte getStartZoomLevel() {
|
|
||||||
if (mMapDatabase != null && mMapDatabase.hasOpenFile()) {
|
|
||||||
MapFileInfo mapFileInfo = mMapDatabase.getMapFileInfo();
|
|
||||||
if (mapFileInfo.startZoomLevel != null) {
|
|
||||||
return mapFileInfo.startZoomLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DEFAULT_START_ZOOM_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte getZoomLevelMax() {
|
|
||||||
return ZOOM_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAreaCaption(String textKey, float verticalOffset, Paint paint,
|
public void renderAreaCaption(String textKey, float verticalOffset, Paint paint,
|
||||||
Paint stroke) {
|
Paint stroke) {
|
||||||
@ -314,7 +245,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
mDrawingLayer = mWays[getValidLayer(layer)];
|
mDrawingLayer = mWays[getValidLayer(layer)];
|
||||||
mPoiX = scaleLongitude(longitude);
|
mPoiX = scaleLongitude(longitude);
|
||||||
mPoiY = scaleLatitude(latitude);
|
mPoiY = scaleLatitude(latitude);
|
||||||
DatabaseRenderer.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
|
MapGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -539,7 +470,7 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createWayLists() {
|
private void createWayLists() {
|
||||||
int levels = DatabaseRenderer.renderTheme.getLevels();
|
int levels = MapGenerator.renderTheme.getLevels();
|
||||||
for (byte i = LAYERS - 1; i >= 0; --i) {
|
for (byte i = LAYERS - 1; i >= 0; --i) {
|
||||||
mWays[i] = new LayerContainer(levels);
|
mWays[i] = new LayerContainer(levels);
|
||||||
}
|
}
|
||||||
@ -581,12 +512,18 @@ public class DatabaseRenderer implements IMapGenerator, IRenderCallback,
|
|||||||
*/
|
*/
|
||||||
private static void setScaleStrokeWidth(byte zoomLevel) {
|
private static void setScaleStrokeWidth(byte zoomLevel) {
|
||||||
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
||||||
DatabaseRenderer.renderTheme.scaleStrokeWidth((float) Math.pow(STROKE_INCREASE,
|
MapGenerator.renderTheme.scaleStrokeWidth((float) Math.pow(STROKE_INCREASE,
|
||||||
zoomLevelDiff));
|
zoomLevelDiff));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MapRenderer getMapRenderer(MapView mapView) {
|
public IMapDatabase getMapDatabase() {
|
||||||
return new MapRenderer(mapView);
|
return mMapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRenderTheme(RenderTheme theme) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,10 +28,9 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
|
|
||||||
import org.mapsforge.android.DebugSettings;
|
import org.mapsforge.android.DebugSettings;
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.JobParameters;
|
|
||||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||||
|
import org.mapsforge.android.mapgenerator.JobParameters;
|
||||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||||
import org.mapsforge.android.mapgenerator.MapWorker;
|
|
||||||
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
||||||
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
||||||
import org.mapsforge.android.utils.GlUtils;
|
import org.mapsforge.android.utils.GlUtils;
|
||||||
@ -46,7 +45,7 @@ import android.opengl.Matrix;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||||
// private static String TAG = "MapRenderer";
|
// private static String TAG = "MapRenderer";
|
||||||
|
|
||||||
private static final int FLOAT_SIZE_BYTES = 4;
|
private static final int FLOAT_SIZE_BYTES = 4;
|
||||||
@ -72,7 +71,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
private ArrayList<MapGeneratorJob> mJobList;
|
private ArrayList<MapGeneratorJob> mJobList;
|
||||||
|
|
||||||
ArrayList<Integer> mTextures;
|
ArrayList<Integer> mTextures;
|
||||||
MapWorker mMapWorker;
|
|
||||||
MapView mMapView;
|
MapView mMapView;
|
||||||
|
|
||||||
GLMapTile[] currentTiles;
|
GLMapTile[] currentTiles;
|
||||||
@ -97,7 +95,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
*/
|
*/
|
||||||
public MapRenderer(MapView mapView) {
|
public MapRenderer(MapView mapView) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
mMapWorker = mapView.getMapWorker();
|
|
||||||
mDebugSettings = mapView.getDebugSettings();
|
mDebugSettings = mapView.getDebugSettings();
|
||||||
mMapScale = 1;
|
mMapScale = 1;
|
||||||
|
|
||||||
@ -133,7 +130,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (diff != 0)
|
if (diff != 0)
|
||||||
{
|
{
|
||||||
float z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
|
float z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
|
||||||
t.distance = (long) (Math.abs((t.tileX) * z - x) + Math.abs((t.tileY) * z - y));
|
t.distance = (long) (Math.abs((t.tileX) * z - x) + Math.abs((t.tileY) * z
|
||||||
|
- y));
|
||||||
t.distance *= 2 * diff * diff;
|
t.distance *= 2 * diff * diff;
|
||||||
} else {
|
} else {
|
||||||
t.distance = (Math.abs(t.tileX - x) + Math.abs(t.tileY - y));
|
t.distance = (Math.abs(t.tileX - x) + Math.abs(t.tileY - y));
|
||||||
@ -160,7 +158,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
if (t.hasTexture()) {
|
if (t.hasTexture()) {
|
||||||
synchronized (mTextures) {
|
synchronized (mTextures) {
|
||||||
mTextures.add(new Integer(t.getTexture()));
|
mTextures.add(Integer.valueOf(t.getTexture()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,7 +182,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
mJobList.clear();
|
mJobList.clear();
|
||||||
|
|
||||||
IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
// IMapGenerator mapGenerator = mMapView.getMapGenerator();
|
||||||
|
|
||||||
int tiles = 0;
|
int tiles = 0;
|
||||||
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
|
||||||
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
|
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
|
||||||
@ -216,13 +215,14 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (!tile.isDrawn || (tile.getScale() != scale)) {
|
if (!tile.isDrawn || (tile.getScale() != scale)) {
|
||||||
tile.isLoading = true;
|
tile.isLoading = true;
|
||||||
// approximation for TileScheduler
|
// approximation for TileScheduler
|
||||||
if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft || tileX > tileRight)
|
if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft
|
||||||
|
|| tileX > tileRight)
|
||||||
tile.isVisible = false;
|
tile.isVisible = false;
|
||||||
else
|
else
|
||||||
tile.isVisible = true;
|
tile.isVisible = true;
|
||||||
|
|
||||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
|
MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
|
||||||
mJobParameter, mDebugSettings);
|
mDebugSettings);
|
||||||
job.setScale(scale);
|
job.setScale(scale);
|
||||||
mJobList.add(job);
|
mJobList.add(job);
|
||||||
}
|
}
|
||||||
@ -243,10 +243,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mJobList.size() > 0) {
|
if (mJobList.size() > 0) {
|
||||||
mMapView.getJobQueue().setJobs(mJobList);
|
mMapView.addJobs(mJobList);
|
||||||
synchronized (mMapWorker) {
|
|
||||||
mMapWorker.notify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -262,10 +259,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
mMapPosition = mMapView.getMapPosition().getMapPosition();
|
||||||
|
|
||||||
long x = (long) MercatorProjection.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
long x = (long) MercatorProjection.longitudeToPixelX(
|
||||||
|
mMapPosition.geoPoint.getLongitude(),
|
||||||
mMapPosition.zoomLevel);
|
mMapPosition.zoomLevel);
|
||||||
long y = (long) MercatorProjection
|
long y = (long) MercatorProjection
|
||||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), mMapPosition.zoomLevel);
|
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(),
|
||||||
|
mMapPosition.zoomLevel);
|
||||||
|
|
||||||
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
|
long tileX = MercatorProjection.pixelXToTileX(x, mMapPosition.zoomLevel);
|
||||||
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
|
long tileY = MercatorProjection.pixelYToTileY(y, mMapPosition.zoomLevel);
|
||||||
@ -345,7 +344,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
z = 1.0f / (1 << -diff);
|
z = 1.0f / (1 << -diff);
|
||||||
}
|
}
|
||||||
drawX = MercatorProjection
|
drawX = MercatorProjection
|
||||||
.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(), tile.zoomLevel);
|
.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(),
|
||||||
|
tile.zoomLevel);
|
||||||
drawY = MercatorProjection
|
drawY = MercatorProjection
|
||||||
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), tile.zoomLevel);
|
||||||
|
|
||||||
@ -377,7 +377,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
Matrix.setIdentityM(mMatrix, 0);
|
Matrix.setIdentityM(mMatrix, 0);
|
||||||
// map tile GL coordinates to screen coordinates
|
// map tile GL coordinates to screen coordinates
|
||||||
Matrix.scaleM(mMatrix, 0, 2.0f * (tileSize * z) / mWidth, 2.0f * (tileSize * z) / mHeight, 1);
|
Matrix.scaleM(mMatrix, 0, 2.0f * (tileSize * z) / mWidth, 2.0f * (tileSize * z)
|
||||||
|
/ mHeight, 1);
|
||||||
|
|
||||||
// scale tile
|
// scale tile
|
||||||
Matrix.scaleM(mMatrix, 0, mapScale / z, mapScale / z, 1);
|
Matrix.scaleM(mMatrix, 0, mapScale / z, mapScale / z, 1);
|
||||||
@ -396,7 +397,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDrawFrame(GL10 glUnused) {
|
public void onDrawFrame(GL10 glUnused) {
|
||||||
boolean loadedTexture = false;
|
// boolean loadedTexture = false;
|
||||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||||
GLES20.glClearColor(0.95f, 0.95f, 0.94f, 1.0f);
|
GLES20.glClearColor(0.95f, 0.95f, 0.94f, 1.0f);
|
||||||
// GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
|
// GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
|
||||||
@ -437,14 +438,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
if (tile.getTexture() >= 0) {
|
if (tile.getTexture() >= 0) {
|
||||||
// reuse tile texture
|
// reuse tile texture
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.getTexture());
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mMapGeneratorJob.getBitmap());
|
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||||
|
mMapGeneratorJob.getBitmap());
|
||||||
} else if (mTextures.size() > 0) {
|
} else if (mTextures.size() > 0) {
|
||||||
// reuse texture from previous tiles
|
// reuse texture from previous tiles
|
||||||
Integer texture;
|
Integer texture;
|
||||||
texture = mTextures.remove(mTextures.size() - 1);
|
texture = mTextures.remove(mTextures.size() - 1);
|
||||||
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.intValue());
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mMapGeneratorJob.getBitmap());
|
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0,
|
||||||
|
mMapGeneratorJob.getBitmap());
|
||||||
tile.setTexture(texture.intValue());
|
tile.setTexture(texture.intValue());
|
||||||
} else {
|
} else {
|
||||||
// create texture
|
// create texture
|
||||||
@ -457,7 +460,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
|
|
||||||
mMapGeneratorJob = null;
|
mMapGeneratorJob = null;
|
||||||
processedTile = true;
|
processedTile = true;
|
||||||
loadedTexture = true;
|
// loadedTexture = true;
|
||||||
}
|
}
|
||||||
int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
int tileSize = (int) (Tile.TILE_SIZE * mMapScale);
|
||||||
int hWidth = mWidth >> 1;
|
int hWidth = mWidth >> 1;
|
||||||
@ -491,11 +494,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loadedTexture) {
|
// FIXME
|
||||||
synchronized (mMapWorker) {
|
// if (loadedTexture) {
|
||||||
mMapWorker.notify();
|
// synchronized (mMapWorker) {
|
||||||
}
|
// mMapWorker.notify();
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -579,65 +583,9 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
|||||||
public boolean processedTile() {
|
public boolean processedTile() {
|
||||||
return processedTile;
|
return processedTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMapGenerator createMapGenerator() {
|
||||||
|
return new MapGenerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void limitCache(long top, long bottom, long left, long right, byte zoom, int remove) {
|
|
||||||
// int cnt = 0;
|
|
||||||
// TileCacheKey[] keys = new TileCacheKey[remove];
|
|
||||||
//
|
|
||||||
// for (Entry<TileCacheKey, GLMapTile> e : mTiles.entrySet()) {
|
|
||||||
// GLMapTile t = e.getValue();
|
|
||||||
// if (t.zoomLevel == zoom && t.tileX >= left && t.tileX <= right &&
|
|
||||||
// t.tileY >= top && t.tileY <= bottom)
|
|
||||||
// continue;
|
|
||||||
//
|
|
||||||
// if (t.zoomLevel + 1 == zoom) {
|
|
||||||
// boolean found = false;
|
|
||||||
// for (int i = 0; i < 4; i++) {
|
|
||||||
// GLMapTile c = t.child[i];
|
|
||||||
// if (c != null && !c.hasTexture() && c.tileX >= left && c.tileX <= right &&
|
|
||||||
// c.tileY >= top && c.tileY <= bottom) {
|
|
||||||
// found = true;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (found)
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// if (t.zoomLevel - 1 == zoom) {
|
|
||||||
// GLMapTile p = t.parent;
|
|
||||||
// if (p != null && !p.hasTexture() && p.tileX >= left && p.tileX <= right &&
|
|
||||||
// p.tileY >= top && p.tileY <= bottom) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// keys[cnt++] = e.getKey();
|
|
||||||
//
|
|
||||||
// if (cnt == remove)
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (TileCacheKey key : keys) {
|
|
||||||
// GLMapTile t = mTiles.remove(key);
|
|
||||||
// if (t == null)
|
|
||||||
// continue;
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < 4; i++) {
|
|
||||||
// if (t.child[i] != null)
|
|
||||||
// t.child[i].parent = null;
|
|
||||||
// }
|
|
||||||
// if (t.parent != null) {
|
|
||||||
// for (int i = 0; i < 4; i++) {
|
|
||||||
// if (t.parent.child[i] == t)
|
|
||||||
// t.parent.child[i] = null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (t.hasTexture()) {
|
|
||||||
// synchronized (mTextures) {
|
|
||||||
// mTextures.add(new Integer(t.getTexture()));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,7 @@ final class WayDecorator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void renderText(DatabaseRenderer databaseRenderer, Paint paint, Paint outline,
|
static void renderText(MapGenerator mapGenerator, Paint paint, Paint outline,
|
||||||
float[] coordinates, WayDataContainer wayDataContainer,
|
float[] coordinates, WayDataContainer wayDataContainer,
|
||||||
List<WayTextContainer> wayNames) {
|
List<WayTextContainer> wayNames) {
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ final class WayDecorator {
|
|||||||
|
|
||||||
if (wayNameWidth < 0) {
|
if (wayNameWidth < 0) {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
text = databaseRenderer.getWayName();
|
text = mapGenerator.getWayName();
|
||||||
if (text == null)
|
if (text == null)
|
||||||
text = "blub";
|
text = "blub";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,13 +40,17 @@ public class GlUtils {
|
|||||||
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
|
||||||
|
|
||||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
|
||||||
|
GLES20.GL_LINEAR);
|
||||||
|
|
||||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
|
||||||
|
GLES20.GL_LINEAR);
|
||||||
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
|
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
|
||||||
|
GLES20.GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
|
||||||
|
GLES20.GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||||
|
|
||||||
@ -125,4 +129,16 @@ public class GlUtils {
|
|||||||
// throw new RuntimeException(op + ": glError " + error);
|
// throw new RuntimeException(op + ": glError " + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkGlOutOfMemory(String op) {
|
||||||
|
int error;
|
||||||
|
boolean oom = false;
|
||||||
|
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
|
||||||
|
Log.e(TAG, op + ": glError " + error);
|
||||||
|
// throw new RuntimeException(op + ": glError " + error);
|
||||||
|
if (error == 1285)
|
||||||
|
oom = true;
|
||||||
|
}
|
||||||
|
return oom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,14 @@ public abstract class PausableThread extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void interrupt() {
|
||||||
|
// first acquire the monitor which is used to call wait()
|
||||||
|
synchronized (this) {
|
||||||
|
super.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this thread is currently pausing, false otherwise.
|
* @return true if this thread is currently pausing, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -9,8 +9,7 @@ import org.mapsforge.android.DebugSettings;
|
|||||||
import org.mapsforge.android.MapActivity;
|
import org.mapsforge.android.MapActivity;
|
||||||
import org.mapsforge.android.MapController;
|
import org.mapsforge.android.MapController;
|
||||||
import org.mapsforge.android.MapView;
|
import org.mapsforge.android.MapView;
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabaseFactory;
|
import org.mapsforge.android.mapgenerator.MapDatabases;
|
||||||
import org.mapsforge.android.mapgenerator.MapDatabaseInternal;
|
|
||||||
import org.mapsforge.android.rendertheme.InternalRenderTheme;
|
import org.mapsforge.android.rendertheme.InternalRenderTheme;
|
||||||
import org.mapsforge.android.utils.AndroidUtils;
|
import org.mapsforge.android.utils.AndroidUtils;
|
||||||
import org.mapsforge.app.filefilter.FilterByFileExtension;
|
import org.mapsforge.app.filefilter.FilterByFileExtension;
|
||||||
@ -20,7 +19,6 @@ import org.mapsforge.app.filepicker.FilePicker;
|
|||||||
import org.mapsforge.app.preferences.EditPreferences;
|
import org.mapsforge.app.preferences.EditPreferences;
|
||||||
import org.mapsforge.core.BoundingBox;
|
import org.mapsforge.core.BoundingBox;
|
||||||
import org.mapsforge.core.GeoPoint;
|
import org.mapsforge.core.GeoPoint;
|
||||||
import org.mapsforge.database.IMapDatabase;
|
|
||||||
import org.mapsforge.database.MapFileInfo;
|
import org.mapsforge.database.MapFileInfo;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
@ -74,7 +72,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
private static final int SELECT_MAP_FILE = 0;
|
private static final int SELECT_MAP_FILE = 0;
|
||||||
private static final int SELECT_RENDER_THEME_FILE = 1;
|
private static final int SELECT_RENDER_THEME_FILE = 1;
|
||||||
private LocationManager mLocationManager;
|
private LocationManager mLocationManager;
|
||||||
private MapDatabaseInternal mMapDatabaseInternal;
|
private MapDatabases mMapDatabase;
|
||||||
private MyLocationListener mMyLocationListener;
|
private MyLocationListener mMyLocationListener;
|
||||||
private boolean mShowMyLocation;
|
private boolean mShowMyLocation;
|
||||||
private boolean mSnapToLocation;
|
private boolean mSnapToLocation;
|
||||||
@ -88,8 +86,11 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.options_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;
|
mMenu = menu;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -434,7 +435,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
editText.setText(Double.toString(mapCenter.getLongitude()));
|
editText.setText(Double.toString(mapCenter.getLongitude()));
|
||||||
|
|
||||||
SeekBar zoomlevel = (SeekBar) dialog.findViewById(R.id.zoomLevel);
|
SeekBar zoomlevel = (SeekBar) dialog.findViewById(R.id.zoomLevel);
|
||||||
zoomlevel.setMax(mMapView.getMapGenerator().getZoomLevelMax());
|
zoomlevel.setMax(20); // FIXME mMapView.getMapGenerator().getZoomLevelMax());
|
||||||
zoomlevel.setProgress(mMapView.getMapPosition().getZoomLevel());
|
zoomlevel.setProgress(mMapView.getMapPosition().getZoomLevel());
|
||||||
|
|
||||||
final TextView textView = (TextView) dialog.findViewById(R.id.zoomlevelValue);
|
final TextView textView = (TextView) dialog.findViewById(R.id.zoomlevelValue);
|
||||||
@ -532,25 +533,31 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
if (preferences.contains("mapDatabase")) {
|
if (preferences.contains("mapDatabase")) {
|
||||||
String name = preferences.getString("mapDatabase",
|
String name = preferences.getString("mapDatabase",
|
||||||
MapDatabaseInternal.POSTGIS_READER.name());
|
MapDatabases.POSTGIS_READER.name());
|
||||||
|
|
||||||
MapDatabaseInternal mapDatabaseInternalNew;
|
MapDatabases mapDatabaseNew;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mapDatabaseInternalNew = MapDatabaseInternal.valueOf(name);
|
mapDatabaseNew = MapDatabases.valueOf(name);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
mapDatabaseInternalNew = MapDatabaseInternal.POSTGIS_READER;
|
mapDatabaseNew = MapDatabases.POSTGIS_READER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapDatabaseInternalNew = MapDatabaseInternal.JSON_READER;
|
// mapDatabaseInternalNew = MapDatabaseInternal.PBMAP_READER;
|
||||||
Log.d("VectorTileMap", "set map database " + mapDatabaseInternalNew);
|
Log.d("VectorTileMap", "set map database " + mapDatabaseNew);
|
||||||
|
|
||||||
if (mapDatabaseInternalNew != mMapDatabaseInternal) {
|
if (mapDatabaseNew != mMapDatabase) {
|
||||||
IMapDatabase mapDatabase = MapDatabaseFactory
|
mMapView.setMapDatabase(mapDatabaseNew);
|
||||||
.createMapDatabase(mapDatabaseInternalNew);
|
mMapDatabase = mapDatabaseNew;
|
||||||
mMapView.setMapDatabase(mapDatabase);
|
|
||||||
mMapDatabaseInternal = mapDatabaseInternalNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (mapDatabaseNew != mMapDatabase) {
|
||||||
|
// IMapDatabase mapDatabase = MapDatabaseFactory
|
||||||
|
// .createMapDatabase(mapDatabaseNew);
|
||||||
|
//
|
||||||
|
// mMapView.setMapDatabase(mapDatabase);
|
||||||
|
// mMapDatabase = mapDatabaseNew;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -586,7 +593,7 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
|||||||
|
|
||||||
mMapView.setDebugSettings(debugSettings);
|
mMapView.setDebugSettings(debugSettings);
|
||||||
|
|
||||||
if (mMapDatabaseInternal == MapDatabaseInternal.MAP_READER) {
|
if (mMapDatabase == MapDatabases.MAP_READER) {
|
||||||
if (mMapView.getMapFile() == null)
|
if (mMapView.getMapFile() == null)
|
||||||
startMapFilePicker();
|
startMapFilePicker();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -226,7 +226,8 @@ public class FilePicker extends Activity implements AdapterView.OnItemClickListe
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
getActionBar().hide();
|
// getActionBar().hide();
|
||||||
|
|
||||||
// check if the full screen mode should be activated
|
// check if the full screen mode should be activated
|
||||||
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
|
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen", false)) {
|
||||||
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|||||||
@ -18,8 +18,6 @@ import org.mapsforge.app.R;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity to edit the application preferences.
|
* Activity to edit the application preferences.
|
||||||
@ -34,16 +32,16 @@ public class EditPreferences extends PreferenceActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
getActionBar().hide();
|
// getActionBar().hide();
|
||||||
|
|
||||||
// check if the full screen mode should be activated
|
// check if the full screen mode should be activated
|
||||||
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
// if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("fullscreen",
|
||||||
false)) {
|
// false)) {
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||||
} else {
|
// } else {
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
// getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,6 +62,8 @@ public interface IMapDatabase {
|
|||||||
*/
|
*/
|
||||||
public abstract FileOpenResult openFile(File mapFile);
|
public abstract FileOpenResult openFile(File mapFile);
|
||||||
|
|
||||||
|
public abstract String getMapProjection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param position
|
* @param position
|
||||||
* ....
|
* ....
|
||||||
|
|||||||
@ -31,13 +31,14 @@ import org.mapsforge.database.MapFileInfo;
|
|||||||
*/
|
*/
|
||||||
public class MapDatabase implements IMapDatabase {
|
public class MapDatabase implements IMapDatabase {
|
||||||
|
|
||||||
|
private final static String PROJECTION = "Mercator";
|
||||||
private float[] mCoords = new float[20];
|
private float[] mCoords = new float[20];
|
||||||
private int[] mIndex = new int[1];
|
private int[] mIndex = new int[2];
|
||||||
// private Tag[] mTags = { new Tag("boundary", "administrative"), new Tag("admin_level", "2") };
|
// private Tag[] mTags = { new Tag("boundary", "administrative"), new Tag("admin_level", "2") };
|
||||||
private Tag[] mTags = { new Tag("building", "yes") };
|
private Tag[] mTags = { new Tag("natural", "water") };
|
||||||
private final MapFileInfo mMapInfo =
|
private final MapFileInfo mMapInfo =
|
||||||
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
|
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
|
||||||
new Byte((byte) 0), null, "Mercator", 0, 0, 0, "de", "yo!", "by me");
|
new Byte((byte) 0), null, PROJECTION, 0, 0, 0, "de", "yo!", "by me");
|
||||||
|
|
||||||
private boolean mOpenFile = false;
|
private boolean mOpenFile = false;
|
||||||
|
|
||||||
@ -95,10 +96,10 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
//
|
//
|
||||||
// mIndex[0] = 10;
|
// mIndex[0] = 10;
|
||||||
|
|
||||||
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 80, tile.zoomLevel) * 1000000;
|
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 139, tile.zoomLevel) * 1000000;
|
||||||
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 80, tile.zoomLevel) * 1000000;
|
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 139, tile.zoomLevel) * 1000000;
|
||||||
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 80, tile.zoomLevel) * 1000000;
|
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 139, tile.zoomLevel) * 1000000;
|
||||||
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 80, tile.zoomLevel) * 1000000;
|
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 139, tile.zoomLevel) * 1000000;
|
||||||
|
|
||||||
mCoords[0] = lon1;
|
mCoords[0] = lon1;
|
||||||
mCoords[1] = lat1;
|
mCoords[1] = lat1;
|
||||||
@ -117,9 +118,35 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
mIndex[0] = 10;
|
mIndex[0] = 10;
|
||||||
|
|
||||||
|
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 119, tile.zoomLevel) * 1000000;
|
||||||
|
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 119, tile.zoomLevel) * 1000000;
|
||||||
|
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 119, tile.zoomLevel) * 1000000;
|
||||||
|
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 119, tile.zoomLevel) * 1000000;
|
||||||
|
|
||||||
|
mCoords[10] = lon1;
|
||||||
|
mCoords[11] = lat1;
|
||||||
|
|
||||||
|
mCoords[12] = lon2;
|
||||||
|
mCoords[13] = lat1;
|
||||||
|
|
||||||
|
mCoords[14] = lon2;
|
||||||
|
mCoords[15] = lat2;
|
||||||
|
|
||||||
|
mCoords[16] = lon1;
|
||||||
|
mCoords[17] = lat2;
|
||||||
|
|
||||||
|
mCoords[18] = lon1;
|
||||||
|
mCoords[19] = lat1;
|
||||||
|
|
||||||
|
mIndex[1] = 10;
|
||||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
|
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMapProjection() {
|
||||||
|
return PROJECTION;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MapFileInfo getMapFileInfo() {
|
public MapFileInfo getMapFileInfo() {
|
||||||
return mMapInfo;
|
return mMapInfo;
|
||||||
|
|||||||
@ -177,11 +177,13 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
*/
|
*/
|
||||||
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;
|
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;
|
||||||
|
|
||||||
private IndexCache mDatabaseIndexCache;
|
private static IndexCache sDatabaseIndexCache;
|
||||||
|
private static MapFileHeader sMapFileHeader;
|
||||||
|
private static int instances = 0;
|
||||||
|
|
||||||
private long mFileSize;
|
private long mFileSize;
|
||||||
private boolean mDebugFile;
|
private boolean mDebugFile;
|
||||||
private RandomAccessFile mInputFile;
|
private RandomAccessFile mInputFile;
|
||||||
private MapFileHeader mMapFileHeader;
|
|
||||||
private ReadBuffer mReadBuffer;
|
private ReadBuffer mReadBuffer;
|
||||||
private String mSignatureBlock;
|
private String mSignatureBlock;
|
||||||
private String mSignaturePoi;
|
private String mSignaturePoi;
|
||||||
@ -193,31 +195,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
private float[] mWayNodes = new float[100000];
|
private float[] mWayNodes = new float[100000];
|
||||||
private int mWayNodePosition;
|
private int mWayNodePosition;
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see org.mapsforge.map.reader.IMapDatabase#closeFile()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void closeFile() {
|
|
||||||
try {
|
|
||||||
mMapFileHeader = null;
|
|
||||||
|
|
||||||
if (mDatabaseIndexCache != null) {
|
|
||||||
mDatabaseIndexCache.destroy();
|
|
||||||
mDatabaseIndexCache = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mInputFile != null) {
|
|
||||||
mInputFile.close();
|
|
||||||
mInputFile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
mReadBuffer = null;
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.log(Level.SEVERE, null, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int minLat, minLon;
|
private int minLat, minLon;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -227,7 +204,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||||
if (mMapFileHeader == null)
|
if (sMapFileHeader == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mIntBuffer == null)
|
if (mIntBuffer == null)
|
||||||
@ -235,29 +212,13 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
mWayNodePosition = 0;
|
mWayNodePosition = 0;
|
||||||
|
|
||||||
// if (tile.zoomLevel < 10) {
|
|
||||||
// // reduce small nodes with distance smaller min pixel
|
|
||||||
// int min = 1;
|
|
||||||
// long cx = tile.getPixelX() + (Tile.TILE_SIZE >> 1);
|
|
||||||
// long cy = tile.getPixelY() + (Tile.TILE_SIZE >> 1);
|
|
||||||
// double l1 = MercatorProjection.pixelXToLongitude(cx, tile.zoomLevel);
|
|
||||||
// double l2 = MercatorProjection.pixelXToLongitude(cx + min, tile.zoomLevel);
|
|
||||||
// minLon = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
|
|
||||||
// l1 = MercatorProjection.pixelYToLatitude(cy, tile.zoomLevel);
|
|
||||||
// l2 = MercatorProjection.pixelYToLatitude(cy + min, tile.zoomLevel);
|
|
||||||
// minLat = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
|
|
||||||
// } else {
|
|
||||||
minLat = 0;
|
|
||||||
minLon = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
prepareExecution();
|
// prepareExecution();
|
||||||
QueryParameters queryParameters = new QueryParameters();
|
QueryParameters queryParameters = new QueryParameters();
|
||||||
queryParameters.queryZoomLevel = mMapFileHeader
|
queryParameters.queryZoomLevel = sMapFileHeader
|
||||||
.getQueryZoomLevel(tile.zoomLevel);
|
.getQueryZoomLevel(tile.zoomLevel);
|
||||||
// get and check the sub-file for the query zoom level
|
// get and check the sub-file for the query zoom level
|
||||||
SubFileParameter subFileParameter = mMapFileHeader
|
SubFileParameter subFileParameter = sMapFileHeader
|
||||||
.getSubFileParameter(queryParameters.queryZoomLevel);
|
.getSubFileParameter(queryParameters.queryZoomLevel);
|
||||||
if (subFileParameter == null) {
|
if (subFileParameter == null) {
|
||||||
LOG.warning("no sub-file for zoom level: "
|
LOG.warning("no sub-file for zoom level: "
|
||||||
@ -279,10 +240,15 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MapFileInfo getMapFileInfo() {
|
public MapFileInfo getMapFileInfo() {
|
||||||
if (mMapFileHeader == null) {
|
if (sMapFileHeader == null) {
|
||||||
throw new IllegalStateException("no map file is currently opened");
|
throw new IllegalStateException("no map file is currently opened");
|
||||||
}
|
}
|
||||||
return mMapFileHeader.getMapFileInfo();
|
return sMapFileHeader.getMapFileInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMapProjection() {
|
||||||
|
return getMapFileInfo().projectionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -300,6 +266,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public FileOpenResult openFile(File mapFile) {
|
public FileOpenResult openFile(File mapFile) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (mapFile == null) {
|
if (mapFile == null) {
|
||||||
// throw new IllegalArgumentException("mapFile must not be null");
|
// throw new IllegalArgumentException("mapFile must not be null");
|
||||||
@ -323,14 +290,23 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
mFileSize = mInputFile.length();
|
mFileSize = mInputFile.length();
|
||||||
mReadBuffer = new ReadBuffer(mInputFile);
|
mReadBuffer = new ReadBuffer(mInputFile);
|
||||||
|
|
||||||
mMapFileHeader = new MapFileHeader();
|
if (instances > 0) {
|
||||||
FileOpenResult fileOpenResult = mMapFileHeader.readHeader(mReadBuffer,
|
instances++;
|
||||||
|
return FileOpenResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
sMapFileHeader = new MapFileHeader();
|
||||||
|
FileOpenResult fileOpenResult = sMapFileHeader.readHeader(mReadBuffer,
|
||||||
mFileSize);
|
mFileSize);
|
||||||
if (!fileOpenResult.isSuccess()) {
|
if (!fileOpenResult.isSuccess()) {
|
||||||
closeFile();
|
closeFile();
|
||||||
return fileOpenResult;
|
return fileOpenResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareExecution();
|
||||||
|
|
||||||
|
instances++;
|
||||||
|
|
||||||
return FileOpenResult.SUCCESS;
|
return FileOpenResult.SUCCESS;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(Level.SEVERE, null, e);
|
LOG.log(Level.SEVERE, null, e);
|
||||||
@ -340,6 +316,37 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.mapsforge.map.reader.IMapDatabase#closeFile()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void closeFile() {
|
||||||
|
instances--;
|
||||||
|
if (instances > 0) {
|
||||||
|
mReadBuffer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
sMapFileHeader = null;
|
||||||
|
|
||||||
|
if (sDatabaseIndexCache != null) {
|
||||||
|
sDatabaseIndexCache.destroy();
|
||||||
|
sDatabaseIndexCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mInputFile != null) {
|
||||||
|
mInputFile.close();
|
||||||
|
mInputFile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mReadBuffer = null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the debug signatures of the current way and block.
|
* Logs the debug signatures of the current way and block.
|
||||||
*/
|
*/
|
||||||
@ -351,8 +358,8 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void prepareExecution() {
|
private void prepareExecution() {
|
||||||
if (mDatabaseIndexCache == null) {
|
if (sDatabaseIndexCache == null) {
|
||||||
mDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
|
sDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +443,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
long blockNumber = row * subFileParameter.blocksWidth + column;
|
long blockNumber = row * subFileParameter.blocksWidth + column;
|
||||||
|
|
||||||
// get the current index entry
|
// get the current index entry
|
||||||
long currentBlockIndexEntry = mDatabaseIndexCache.getIndexEntry(
|
long currentBlockIndexEntry = sDatabaseIndexCache.getIndexEntry(
|
||||||
subFileParameter, blockNumber);
|
subFileParameter, blockNumber);
|
||||||
|
|
||||||
// check if the current query would still return a water tile
|
// check if the current query would still return a water tile
|
||||||
@ -462,7 +469,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
nextBlockPointer = subFileParameter.subFileSize;
|
nextBlockPointer = subFileParameter.subFileSize;
|
||||||
} else {
|
} else {
|
||||||
// get and check the next block pointer
|
// get and check the next block pointer
|
||||||
nextBlockPointer = mDatabaseIndexCache.getIndexEntry(
|
nextBlockPointer = sDatabaseIndexCache.getIndexEntry(
|
||||||
subFileParameter, blockNumber + 1)
|
subFileParameter, blockNumber + 1)
|
||||||
& BITMASK_INDEX_OFFSET;
|
& BITMASK_INDEX_OFFSET;
|
||||||
if (nextBlockPointer < 1
|
if (nextBlockPointer < 1
|
||||||
@ -559,7 +566,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
* @return true if the POIs could be processed successfully, false otherwise.
|
* @return true if the POIs could be processed successfully, false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean processPOIs(IMapDatabaseCallback mapDatabaseCallback, int numberOfPois) {
|
private boolean processPOIs(IMapDatabaseCallback mapDatabaseCallback, int numberOfPois) {
|
||||||
Tag[] poiTags = mMapFileHeader.getMapFileInfo().poiTags;
|
Tag[] poiTags = sMapFileHeader.getMapFileInfo().poiTags;
|
||||||
Tag[] tags = null;
|
Tag[] tags = null;
|
||||||
|
|
||||||
for (int elementCounter = numberOfPois; elementCounter != 0; --elementCounter) {
|
for (int elementCounter = numberOfPois; elementCounter != 0; --elementCounter) {
|
||||||
@ -778,7 +785,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
int numberOfWays) {
|
int numberOfWays) {
|
||||||
|
|
||||||
Tag[] tags = null;
|
Tag[] tags = null;
|
||||||
Tag[] wayTags = mMapFileHeader.getMapFileInfo().wayTags;
|
Tag[] wayTags = sMapFileHeader.getMapFileInfo().wayTags;
|
||||||
int[] textPos = new int[3];
|
int[] textPos = new int[3];
|
||||||
// float[] labelPosition;
|
// float[] labelPosition;
|
||||||
boolean skippedWays = false;
|
boolean skippedWays = false;
|
||||||
@ -957,7 +964,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
||||||
LOG.warning("invalid cumulated number of ways in row " + row + ' '
|
LOG.warning("invalid cumulated number of ways in row " + row + ' '
|
||||||
+ cumulatedNumberOfWays);
|
+ cumulatedNumberOfWays);
|
||||||
if (mMapFileHeader.getMapFileInfo().debugFile) {
|
if (sMapFileHeader.getMapFileInfo().debugFile) {
|
||||||
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
513
src/org/mapsforge/database/pbmap/MapDatabase.java
Normal file
513
src/org/mapsforge/database/pbmap/MapDatabase.java
Normal file
@ -0,0 +1,513 @@
|
|||||||
|
/*
|
||||||
|
* 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.database.pbmap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.message.BasicHeader;
|
||||||
|
import org.mapsforge.core.BoundingBox;
|
||||||
|
import org.mapsforge.core.GeoPoint;
|
||||||
|
import org.mapsforge.core.Tag;
|
||||||
|
import org.mapsforge.core.Tile;
|
||||||
|
import org.mapsforge.core.WebMercator;
|
||||||
|
import org.mapsforge.database.FileOpenResult;
|
||||||
|
import org.mapsforge.database.IMapDatabase;
|
||||||
|
import org.mapsforge.database.IMapDatabaseCallback;
|
||||||
|
import org.mapsforge.database.MapFileInfo;
|
||||||
|
|
||||||
|
import android.net.http.AndroidHttpClient;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MapDatabase implements IMapDatabase {
|
||||||
|
private static final String TAG = "MapDatabase";
|
||||||
|
|
||||||
|
private static final MapFileInfo mMapInfo =
|
||||||
|
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
|
||||||
|
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
|
||||||
|
WebMercator.NAME, 0, 0, 0, "de", "comment", "author");
|
||||||
|
|
||||||
|
private boolean mOpenFile = false;
|
||||||
|
|
||||||
|
// 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 Header encodingHeader =
|
||||||
|
new BasicHeader("Accept-Encoding", "gzip");
|
||||||
|
|
||||||
|
private static volatile HashMap<String, Tag> tagHash = new HashMap<String, Tag>(100);
|
||||||
|
|
||||||
|
private Tag[] curTags = new Tag[1000];
|
||||||
|
private int mCurTagCnt;
|
||||||
|
|
||||||
|
private AndroidHttpClient mClient;
|
||||||
|
private IMapDatabaseCallback mMapGenerator;
|
||||||
|
private float mScaleFactor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||||
|
|
||||||
|
String url = String.format(URL, Integer.valueOf(tile.zoomLevel),
|
||||||
|
Long.valueOf(tile.tileX), Long.valueOf(tile.tileY));
|
||||||
|
|
||||||
|
HttpGet getRequest = new HttpGet(url);
|
||||||
|
getRequest.addHeader(encodingHeader);
|
||||||
|
mMapGenerator = mapDatabaseCallback;
|
||||||
|
mCurTagCnt = 0;
|
||||||
|
// using variable coordinate scalefactor to take advantage of
|
||||||
|
// variable byte encoded integers
|
||||||
|
mScaleFactor = 1 / 100f;
|
||||||
|
if (tile.zoomLevel < 12)
|
||||||
|
mScaleFactor = (float) Math.pow(2, (12 - tile.zoomLevel)) / 100f;
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpResponse response = mClient.execute(getRequest);
|
||||||
|
final int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if (statusCode != HttpStatus.SC_OK) {
|
||||||
|
Log.d(TAG, "Http response " + statusCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final HttpEntity entity = response.getEntity();
|
||||||
|
if (entity == null) {
|
||||||
|
Log.d(TAG, "Somethings wrong? - no entity " + statusCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream is = null;
|
||||||
|
GZIPInputStream zis = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
is = entity.getContent();
|
||||||
|
zis = new GZIPInputStream(is);
|
||||||
|
|
||||||
|
decode(zis);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (zis != null)
|
||||||
|
zis.close();
|
||||||
|
if (is != null)
|
||||||
|
is.close();
|
||||||
|
entity.consumeContent();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
getRequest.abort();
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMapProjection() {
|
||||||
|
return WebMercator.NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapFileInfo getMapFileInfo() {
|
||||||
|
return mMapInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasOpenFile() {
|
||||||
|
return mOpenFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileOpenResult openFile(File mapFile) {
|
||||||
|
mOpenFile = true;
|
||||||
|
mClient = AndroidHttpClient.newInstance("Android");
|
||||||
|
return new FileOpenResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeFile() {
|
||||||
|
mOpenFile = false;
|
||||||
|
if (mClient != null)
|
||||||
|
mClient.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readString(int position) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int BUFFER_SIZE = 32768;
|
||||||
|
private final byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
private int bufferPos;
|
||||||
|
private int bufferSize;
|
||||||
|
private InputStream inputStream;
|
||||||
|
|
||||||
|
private static final int TAG_TILE_TAGS = 1;
|
||||||
|
private static final int TAG_TILE_WAYS = 2;
|
||||||
|
private static final int TAG_TILE_NODES = 3;
|
||||||
|
private static final int TAG_WAY_TAGS = 1;
|
||||||
|
private static final int TAG_WAY_INDEX = 2;
|
||||||
|
private static final int TAG_WAY_COORDS = 3;
|
||||||
|
// private static final int TAG_NODE_TAGS = 1;
|
||||||
|
// private static final int TAG_NODE_COORDS = 2;
|
||||||
|
|
||||||
|
private int bytesRead;
|
||||||
|
|
||||||
|
private boolean decode(InputStream is) throws IOException {
|
||||||
|
inputStream = is;
|
||||||
|
bytesRead = 0;
|
||||||
|
bufferSize = 0;
|
||||||
|
bufferPos = 0;
|
||||||
|
while (true) {
|
||||||
|
// read tag and wire type
|
||||||
|
int val = decodeVarint32();
|
||||||
|
if (val == 0) {
|
||||||
|
// Log.d(TAG, "EOF, all good");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int tag = (val >> 3);
|
||||||
|
// int wireType = (val & 7);
|
||||||
|
// Log.d(TAG, "tile " + tag + " " + wireType);
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case TAG_TILE_TAGS:
|
||||||
|
decodeTileTags();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_TILE_WAYS:
|
||||||
|
decodeTileWays();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_TILE_NODES:
|
||||||
|
decodeTileNodes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.d(TAG, "invalid type for tile: " + tag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean decodeTileTags() throws IOException {
|
||||||
|
String tagString = decodeString();
|
||||||
|
|
||||||
|
Tag tag = tagHash.get(tagString);
|
||||||
|
if (tag == null) {
|
||||||
|
tag = new Tag(tagString);
|
||||||
|
tagHash.put(tagString, tag);
|
||||||
|
}
|
||||||
|
curTags[mCurTagCnt++] = tag;
|
||||||
|
|
||||||
|
// Log.d(TAG, "tag:" + tag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean decodeTileWays() throws IOException {
|
||||||
|
int bytes = decodeVarint32();
|
||||||
|
|
||||||
|
int end = bytesRead + bytes;
|
||||||
|
int indexCnt = 0;
|
||||||
|
int tagCnt = 0;
|
||||||
|
int coordCnt = 0;
|
||||||
|
while (bytesRead < end) {
|
||||||
|
// read tag and wire type
|
||||||
|
|
||||||
|
int val = decodeVarint32();
|
||||||
|
if (val == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int tag = (val >> 3);
|
||||||
|
// int wireType = val & 7;
|
||||||
|
|
||||||
|
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case TAG_WAY_TAGS:
|
||||||
|
tagCnt = decodeWayTags();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_WAY_INDEX:
|
||||||
|
indexCnt = decodeWayIndices();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_WAY_COORDS:
|
||||||
|
coordCnt = decodeWayCoordinates();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.d(TAG, "invalid type for way: " + tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexCnt == 0 || tagCnt == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int[] index = new int[indexCnt];
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < indexCnt; i++) {
|
||||||
|
index[i] = tmpIndices[i] * 2;
|
||||||
|
sum += index[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag[] tags = new Tag[tagCnt];
|
||||||
|
for (int i = 0; i < tagCnt; i++)
|
||||||
|
tags[i] = curTags[tmpTags[i]];
|
||||||
|
|
||||||
|
float[] coords = tmpCoords;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
if (coordCnt != sum) {
|
||||||
|
Log.d(TAG, "way length is wrong " + coordCnt + " " + sum);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float z = mScaleFactor;
|
||||||
|
for (int j = 0, m = indexCnt; j < m; j++) {
|
||||||
|
float lastX = 0;
|
||||||
|
float lastY = 0;
|
||||||
|
|
||||||
|
for (int n = index[j] + pos; pos < n; pos += 2) {
|
||||||
|
lastX = coords[pos] = (coords[pos] * z) + lastX;
|
||||||
|
lastY = coords[pos + 1] = (coords[pos + 1] * z) + lastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mMapGenerator.renderWay((byte) 0, tags, coords, index, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean decodeTileNodes() throws IOException {
|
||||||
|
int bytes = decodeVarint32();
|
||||||
|
Log.d(TAG, "way nodes " + bytes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int MAX_WAY_COORDS = 32768;
|
||||||
|
private int MAX_WAY_INDICES = 1000;
|
||||||
|
private int[] tmpTags = new int[32];
|
||||||
|
private int[] tmpIndices = new int[MAX_WAY_INDICES];
|
||||||
|
private float[] tmpCoords = new float[MAX_WAY_COORDS];
|
||||||
|
|
||||||
|
// private boolean ensureBufferSize(int size) throws IOException {
|
||||||
|
// if (size > (bufferSize - bufferPos))
|
||||||
|
// readBuffer(size - (bufferSize - bufferPos));
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
private int decodeWayTags() throws IOException {
|
||||||
|
int bytes = decodeVarint32();
|
||||||
|
// Log.d(TAG, "way tags: " + bytes);
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
int end = bytesRead + bytes;
|
||||||
|
|
||||||
|
while (bytesRead < end)
|
||||||
|
tmpTags[cnt++] = decodeVarint32();
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int decodeWayIndices() throws IOException {
|
||||||
|
int bytes = decodeVarint32();
|
||||||
|
// Log.d(TAG, "way indices: " + bytes);
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
int end = bytesRead + bytes;
|
||||||
|
|
||||||
|
while (bytesRead < end) {
|
||||||
|
int val = decodeVarint32();
|
||||||
|
if (cnt >= MAX_WAY_INDICES) {
|
||||||
|
|
||||||
|
MAX_WAY_INDICES += 128;
|
||||||
|
Log.d(TAG, "increase indices array " + MAX_WAY_INDICES);
|
||||||
|
int[] tmp = new int[MAX_WAY_INDICES];
|
||||||
|
System.arraycopy(tmpIndices, 0, tmp, 0, cnt);
|
||||||
|
tmpIndices = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpIndices[cnt++] = val;
|
||||||
|
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int decodeWayCoordinates() throws IOException {
|
||||||
|
int bytes = decodeVarint32();
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
int end = bytesRead + bytes;
|
||||||
|
|
||||||
|
while (bytesRead < end) {
|
||||||
|
int val = decodeZigZag32(decodeVarint32());
|
||||||
|
if (cnt >= MAX_WAY_COORDS) {
|
||||||
|
MAX_WAY_COORDS += 128;
|
||||||
|
Log.d(TAG, "increase coords array " + MAX_WAY_COORDS);
|
||||||
|
float[] tmp = new float[MAX_WAY_COORDS];
|
||||||
|
System.arraycopy(tmpCoords, 0, tmp, 0, cnt);
|
||||||
|
tmpCoords = tmp;
|
||||||
|
}
|
||||||
|
tmpCoords[cnt++] = val;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBuffer() throws IOException {
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Log.d(TAG, "pos " + bufferPos + ", size " + bufferSize + ", read "
|
||||||
|
// + bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBuffer(int size) throws IOException {
|
||||||
|
if (size < (bufferSize - bufferPos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (size > BUFFER_SIZE) {
|
||||||
|
Log.d(TAG, "EEEK too large");
|
||||||
|
// FIXME throw exception, but frankly better sanitize tile data on compilation
|
||||||
|
// this only happen with Strings larger than 32kb
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
bufferPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((bufferSize - bufferPos) < size) {
|
||||||
|
// 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?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bufferSize += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
|
||||||
|
// + bufferSize
|
||||||
|
// + ", read " + bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All code below is taken from or based on Google's Protocol Buffers implementation: */
|
||||||
|
|
||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// http://code.google.com/p/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (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");
|
||||||
|
bufferPos += size;
|
||||||
|
bytesRead += size;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int decodeZigZag32(final int n) {
|
||||||
|
return (n >>> 1) ^ -(n & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -26,9 +26,9 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import org.mapsforge.core.BoundingBox;
|
import org.mapsforge.core.BoundingBox;
|
||||||
import org.mapsforge.core.GeoPoint;
|
import org.mapsforge.core.GeoPoint;
|
||||||
import org.mapsforge.core.WebMercator;
|
|
||||||
import org.mapsforge.core.Tag;
|
import org.mapsforge.core.Tag;
|
||||||
import org.mapsforge.core.Tile;
|
import org.mapsforge.core.Tile;
|
||||||
|
import org.mapsforge.core.WebMercator;
|
||||||
import org.mapsforge.database.FileOpenResult;
|
import org.mapsforge.database.FileOpenResult;
|
||||||
import org.mapsforge.database.IMapDatabase;
|
import org.mapsforge.database.IMapDatabase;
|
||||||
import org.mapsforge.database.IMapDatabaseCallback;
|
import org.mapsforge.database.IMapDatabaseCallback;
|
||||||
@ -40,7 +40,7 @@ import org.postgresql.PGConnection;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MapDatabase implements IMapDatabase {
|
public class MapDatabase implements IMapDatabase {
|
||||||
private static final String QUERY = "SELECT * FROM __get_tile(?,?,?)";
|
private static final String QUERY = "SELECT tags, geom FROM __get_tile(?,?,?)";
|
||||||
|
|
||||||
private final float mScale = 1; // 1000000.0f;
|
private final float mScale = 1; // 1000000.0f;
|
||||||
|
|
||||||
@ -55,16 +55,13 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
new MapFileInfo(new BoundingBox(-180, -85, 180, 85),
|
new MapFileInfo(new BoundingBox(-180, -85, 180, 85),
|
||||||
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
|
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
|
||||||
WebMercator.NAME,
|
WebMercator.NAME,
|
||||||
0, 0, 0, "de", "yo!", "hannes");
|
0, 0, 0, "de", "comment", "author");
|
||||||
// new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
|
|
||||||
// new Byte((byte) 0), null, "Mercator",
|
|
||||||
// 0, 0, 0, "de", "yo!", "by me");
|
|
||||||
|
|
||||||
private boolean mOpenFile = false;
|
private boolean mOpenFile = false;
|
||||||
|
|
||||||
private Connection connection = null;
|
private Connection connection = null;
|
||||||
private static HashMap<Entry<String, String>, Tag> tagHash = new HashMap<Entry<String, String>, Tag>(
|
private static volatile HashMap<Entry<String, String>, Tag> tagHash =
|
||||||
100);
|
new HashMap<Entry<String, String>, Tag>(100);
|
||||||
private PreparedStatement prepQuery = null;
|
private PreparedStatement prepQuery = null;
|
||||||
|
|
||||||
private boolean connect() {
|
private boolean connect() {
|
||||||
@ -123,7 +120,6 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
byte[] b = null;
|
byte[] b = null;
|
||||||
PGHStore h = null;
|
PGHStore h = null;
|
||||||
// long id;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (r != null && r.next()) {
|
while (r != null && r.next()) {
|
||||||
@ -131,9 +127,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
mCoordPos = 0;
|
mCoordPos = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// id = r.getLong(1);
|
Object obj = r.getObject(1);
|
||||||
|
|
||||||
Object obj = r.getObject(2);
|
|
||||||
h = null;
|
h = null;
|
||||||
|
|
||||||
if (obj instanceof PGHStore)
|
if (obj instanceof PGHStore)
|
||||||
@ -141,7 +135,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
b = r.getBytes(3);
|
b = r.getBytes(2);
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -184,6 +178,11 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMapProjection() {
|
||||||
|
return WebMercator.NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MapFileInfo getMapFileInfo() {
|
public MapFileInfo getMapFileInfo() {
|
||||||
return mMapInfo;
|
return mMapInfo;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user