refactoring of TileLayer, some more

This commit is contained in:
Hannes Janetzek 2013-04-23 01:13:21 +02:00
parent 2bc71090b3
commit 676b994f2d
15 changed files with 409 additions and 378 deletions

View File

@ -15,8 +15,8 @@
package org.oscim.core;
/**
* MapElement is created by MapDatabase(s) and passed to TileGenerator
* via IMapDatabaseCallback.renderElement() TileGenerator processes the
* MapElement is created by MapDatabase(s) and passed to MapTileLoader
* via IMapDatabaseCallback.renderElement() MapTileLoader processes the
* data into MapTile.layers.
* -----
* This is really just a buffer object that belongs to MapDatabase, so

View File

@ -32,7 +32,7 @@ public interface IMapDatabase {
* the callback which handles the extracted map elements.
* @return true if successful
*/
public abstract QueryResult executeQuery(MapTile tile,
abstract QueryResult executeQuery(MapTile tile,
IMapDatabaseCallback mapDatabaseCallback);
/**
@ -40,12 +40,12 @@ public interface IMapDatabase {
* @throws IllegalStateException
* if no map is currently opened.
*/
public abstract MapInfo getMapInfo();
abstract MapInfo getMapInfo();
/**
* @return true if a map database is currently opened, false otherwise.
*/
public abstract boolean isOpen();
abstract boolean isOpen();
/**
* Opens MapDatabase
@ -54,21 +54,21 @@ public interface IMapDatabase {
* the options.
* @return a OpenResult containing an error message in case of a failure.
*/
public abstract OpenResult open(MapOptions options);
abstract OpenResult open(MapOptions options);
/**
* Closes the map file and destroys all internal caches. Has no effect if no
* map file is currently opened. Should also force to close Socket so that
* thread cannot hang in socket.read
*/
public abstract void close();
abstract void close();
public abstract String getMapProjection();
abstract String getMapProjection();
/**
* Cancel loading
*/
public abstract void cancel();
abstract void cancel();
public static enum QueryResult {
SUCCESS,

View File

@ -18,7 +18,7 @@ import org.oscim.core.MapElement;
/**
* MapDatabase callbacks (implemented by TileGenerator)
* MapDatabase callbacks (implemented by MapTileLoader)
* ____
* NOTE: All parameters passed belong to the caller! i.e. dont hold
* references to any arrays after callback function returns.

View File

@ -1,26 +0,0 @@
/*
* Copyright 2013 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.oscim.layers.tile;
public interface ITileGenerator {
/**
* Load data for 'tile' and file tile.layers for rendering.
* (executed on MapWorker threads)
*/
public abstract boolean executeJob(MapTile tile);
public abstract void cleanup();
}

View File

@ -21,7 +21,7 @@ import org.oscim.utils.quadtree.QuadTree;
/**
* Extends Tile class to hold state and data for concurrent use in
* TileManager (Main Thread), TileGenerator (MapWorker Thread) and
* TileManager (Main Thread), TileLoader (Worker Threads) and
* Rendering (GL Thread).
*/
public final class MapTile extends Tile {
@ -30,7 +30,7 @@ public final class MapTile extends Tile {
/**
* STATE_LOADING means the tile is about to be loaded / loading.
* it belongs to MapWorker/TileGenerator thread.
* it belongs to TileLoader thread.
*/
public final static int STATE_LOADING = 1 << 0;
@ -66,7 +66,7 @@ public final class MapTile extends Tile {
public float distance;
/**
* Tile data set by TileGenerator.
* Tile data set by TileLoader.
*/
public TextItem labels;
public Layers layers;

View File

@ -0,0 +1,231 @@
/*
* Copyright 2013 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.oscim.layers.tile;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.oscim.core.GeoPoint;
import org.oscim.core.MapPosition;
import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabase.OpenResult;
import org.oscim.database.MapDatabaseFactory;
import org.oscim.database.MapDatabases;
import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions;
import org.oscim.renderer.GLRenderer;
import org.oscim.theme.ExternalRenderTheme;
import org.oscim.theme.IRenderTheme;
import org.oscim.theme.InternalRenderTheme;
import org.oscim.theme.RenderThemeHandler;
import org.oscim.theme.Theme;
import org.oscim.view.MapView;
import org.xml.sax.SAXException;
import android.util.Log;
public class MapTileLayer extends TileLayer<MapTileLoader> {
private final static String TAG = MapTileLayer.class.getName();
public MapTileLayer(MapView mapView) {
super(mapView, new TileLoader.Factory<MapTileLoader>(){
@Override
public MapTileLoader create(JobQueue q, TileManager tm) {
return new MapTileLoader(q, tm);
}});
}
private MapOptions mMapOptions;
private IMapDatabase mMapDatabase;
private String mRenderTheme;
/**
* Sets the MapDatabase for this MapView.
*
* @param options
* the new MapDatabase options.
* @return true if MapDatabase changed
*/
public boolean setMapDatabase(MapOptions options) {
Log.i(TAG, "setMapDatabase: " + options.db.name());
if (mMapOptions != null && mMapOptions.equals(options))
return true;
pauseLoaders(true);
mJobQueue.clear();
mMapOptions = options;
mMapDatabase = null;
for (int i = 0; i < mNumTileLoader; i++) {
IMapDatabase mapDatabase = MapDatabaseFactory
.createMapDatabase(options.db);
OpenResult result = mapDatabase.open(options);
if (result != OpenResult.SUCCESS) {
Log.d(TAG, "failed open db: " + result.getErrorMessage());
}
mTileLoader.get(i).setMapDatabase(mapDatabase);
// TODO this could be done in a cleaner way..
if (mMapDatabase == null)
mMapDatabase = mapDatabase;
}
if (options.db == MapDatabases.OSCIMAP_READER ||
options.db == MapDatabases.MAP_READER ||
options.db == MapDatabases.TEST_READER)
MapView.enableClosePolygons = true;
else
MapView.enableClosePolygons = false;
clearMap();
resumeLoaders();
return true;
}
public Map<String, String> getMapOptions() {
return mMapOptions;
}
public MapPosition getMapFileCenter() {
if (mMapDatabase == null)
return null;
MapInfo mapInfo = mMapDatabase.getMapInfo();
if (mapInfo == null)
return null;
GeoPoint startPos = mapInfo.startPosition;
if (startPos == null)
startPos = mapInfo.mapCenter;
if (startPos == null)
startPos = new GeoPoint(0, 0);
MapPosition mapPosition = new MapPosition();
mapPosition.setPosition(startPos);
if (mapInfo.startZoomLevel == null)
mapPosition.setZoomLevel(12);
else
mapPosition.setZoomLevel((mapInfo.startZoomLevel).byteValue());
return mapPosition;
}
public String getRenderTheme() {
return mRenderTheme;
}
/**
* Sets the internal theme which is used for rendering the map.
*
* @param internalRenderTheme
* the internal rendering theme.
* @return ...
* @throws IllegalArgumentException
* if the supplied internalRenderTheme is null.
*/
public boolean setRenderTheme(InternalRenderTheme internalRenderTheme) {
if (internalRenderTheme == null) {
throw new IllegalArgumentException("render theme must not be null");
}
if (internalRenderTheme.name() == mRenderTheme)
return true;
boolean ret = setRenderTheme((Theme) internalRenderTheme);
if (ret) {
mRenderTheme = internalRenderTheme.name();
}
clearMap();
return ret;
}
/**
* Sets the theme file which is used for rendering the map.
*
* @param renderThemePath
* the path to the XML file which defines the rendering theme.
* @throws IllegalArgumentException
* if the supplied internalRenderTheme is null.
* @throws FileNotFoundException
* if the supplied file does not exist, is a directory or cannot
* be read.
*/
public void setRenderTheme(String renderThemePath) throws FileNotFoundException {
if (renderThemePath == null) {
throw new IllegalArgumentException("render theme path must not be null");
}
boolean ret = setRenderTheme(new ExternalRenderTheme(renderThemePath));
if (ret) {
mRenderTheme = renderThemePath;
}
clearMap();
}
private boolean setRenderTheme(Theme theme) {
pauseLoaders(true);
InputStream inputStream = null;
try {
inputStream = theme.getRenderThemeAsStream();
IRenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
t.scaleTextSize(1 + (MapView.dpi / 240 - 1) * 0.5f);
// FIXME !!!
GLRenderer.setRenderTheme(t);
for (MapTileLoader g : mTileLoader)
g.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 {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
resumeLoaders();
}
return false;
}
}

View File

@ -50,17 +50,17 @@ import android.util.Log;
/**
* @note
* 1. The MapWorkers call TileGenerator.execute() to load a tile.
* 1. The MapWorkers call MapTileLoader.execute() to load a tile.
* 2. The tile data will be loaded from current MapDatabase
* 3. MapDatabase calls the IMapDatabaseCallback functions
* implemented by TileGenerator for WAY and POI items.
* implemented by MapTileLoader for WAY and POI items.
* 4. these callbacks then call RenderTheme to get the matching style.
* 5. RenderTheme calls IRenderCallback functions with style information
* 6. Styled items become added to MapTile.layers... roughly
*/
public class TileGenerator extends MapWorker implements IRenderCallback, IMapDatabaseCallback, ITileGenerator {
public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDatabaseCallback {
private static final String TAG = TileGenerator.class.getName();
private static final String TAG = MapTileLoader.class.getName();
private static final double STROKE_INCREASE = Math.sqrt(2.2);
private static final byte LAYERS = 11;
@ -83,7 +83,7 @@ public class TileGenerator extends MapWorker implements IRenderCallback, IMapDat
private IRenderTheme renderTheme;
private int renderLevels;
// current MapDatabase used by this TileGenerator
// current MapDatabase used by this MapTileLoader
private IMapDatabase mMapDatabase;
// currently processed tile
@ -117,8 +117,8 @@ public class TileGenerator extends MapWorker implements IRenderCallback, IMapDat
/**
*/
public TileGenerator(int id, JobQueue jobQueue, TileManager tileManager) {
super(id, jobQueue, tileManager);
public MapTileLoader(JobQueue jobQueue, TileManager tileManager) {
super(jobQueue, tileManager);
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
@ -140,7 +140,7 @@ public class TileGenerator extends MapWorker implements IRenderCallback, IMapDat
}
/* (non-Javadoc)
* @see org.oscim.layers.tile.ITileGenerator#cleanup()
* @see org.oscim.layers.tile.TileLoader#cleanup()
*/
@Override
public void cleanup() {
@ -148,7 +148,7 @@ public class TileGenerator extends MapWorker implements IRenderCallback, IMapDat
}
/* (non-Javadoc)
* @see org.oscim.layers.tile.ITileGenerator#executeJob(org.oscim.layers.tile.MapTile)
* @see org.oscim.layers.tile.TileLoader#executeJob(org.oscim.layers.tile.MapTile)
*/
@Override
public boolean executeJob(MapTile mapTile) {

View File

@ -0,0 +1,79 @@
/*
* Copyright 2013 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.oscim.layers.tile;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.Tile;
import org.oscim.graphics.Color;
import org.oscim.graphics.Paint.Cap;
import org.oscim.layers.tile.TestTileLayer.TestTileLoader;
import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.layer.LineLayer;
import org.oscim.theme.renderinstruction.Line;
import org.oscim.view.MapView;
import android.util.Log;
public class TestTileLayer extends TileLayer<TestTileLoader> {
final static String TAG = TestTileLayer.class.getName();
public TestTileLayer(MapView mapView) {
// create an TileLayer instance using TestTileLoader as TileLoader
super(mapView, new TileLoader.Factory<TestTileLoader>(){
@Override
public TestTileLoader create(JobQueue q, TileManager tm) {
return new TestTileLoader(q, tm);
}});
}
static class TestTileLoader extends TileLoader {
public TestTileLoader(JobQueue jobQueue, TileManager tileManager) {
super(jobQueue, tileManager);
}
GeometryBuffer mGeom = new GeometryBuffer(128, 16);
Line mLineStyle = new Line(Color.BLUE, 2f, Cap.ROUND);
@Override
public boolean executeJob(MapTile tile) {
Log.d(TAG, "load tile " + tile);
tile.layers = new Layers();
LineLayer ll = tile.layers.getLineLayer(0);
ll.line = mLineStyle;
ll.width = 2;
int m = 20;
int s = Tile.SIZE - m * 2;
GeometryBuffer g = mGeom;
g.clear();
g.startLine();
g.addPoint(m, m);
g.addPoint(m, s);
g.addPoint(s, s);
g.addPoint(s, m);
g.addPoint(m, m);
ll.addLine(g);
return true;
}
@Override
public void cleanup() {
}
}
}

View File

@ -51,13 +51,11 @@ public class TileDistanceSort {
return 0;
}
private static void binarySort(MapTile[] a, int lo, int hi, int start)
{
private static void binarySort(MapTile[] a, int lo, int hi, int start) {
assert ((lo <= start) && (start <= hi));
if (start == lo)
++start;
for (; start < hi; ++start)
{
for (; start < hi; ++start) {
MapTile pivot = a[start];
int left = lo;
@ -98,8 +96,7 @@ public class TileDistanceSort {
}
}
private static int countRunAndMakeAscending(MapTile[] a, int lo, int hi)
{
private static int countRunAndMakeAscending(MapTile[] a, int lo, int hi) {
assert (lo < hi);
int runHi = lo + 1;
if (runHi == hi) {
@ -118,8 +115,7 @@ public class TileDistanceSort {
return (runHi - lo);
}
private static void reverseRange(MapTile[] a, int lo, int hi)
{
private static void reverseRange(MapTile[] a, int lo, int hi) {
--hi;
while (lo < hi) {
MapTile t = a[lo];
@ -127,4 +123,7 @@ public class TileDistanceSort {
a[(hi--)] = t;
}
}
private TileDistanceSort() {
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2013 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.oscim.layers.tile;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.Tile;
import org.oscim.graphics.Color;
import org.oscim.graphics.Paint.Cap;
import org.oscim.renderer.layer.LineLayer;
import org.oscim.theme.renderinstruction.Line;
public class TileGeneratorExample implements ITileGenerator {
GeometryBuffer mGeom = new GeometryBuffer(128, 16);
Line mLineStyle = new Line(Color.BLUE, 2f, Cap.ROUND);
@Override
public boolean executeJob(MapTile tile) {
LineLayer ll = tile.layers.getLineLayer(0);
ll.line = mLineStyle;
ll.width = 2;
int m = 20;
int s = Tile.SIZE - m * 2;
GeometryBuffer g = mGeom;
g.clear();
g.startPolygon();
g.addPoint(m, m);
g.addPoint(m, s);
g.addPoint(s, s);
g.addPoint(s, m);
ll.addLine(g);
return true;
}
@Override
public void cleanup() {
}
}

View File

@ -14,58 +14,43 @@
*/
package org.oscim.layers.tile;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import org.oscim.core.GeoPoint;
import org.oscim.core.MapPosition;
import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabase.OpenResult;
import org.oscim.database.MapDatabaseFactory;
import org.oscim.database.MapDatabases;
import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions;
import org.oscim.layers.Layer;
import org.oscim.renderer.GLRenderer;
import org.oscim.theme.ExternalRenderTheme;
import org.oscim.theme.IRenderTheme;
import org.oscim.theme.InternalRenderTheme;
import org.oscim.theme.RenderThemeHandler;
import org.oscim.theme.Theme;
import org.oscim.view.MapView;
import org.xml.sax.SAXException;
import android.util.Log;
public class TileLayer extends Layer {
private final static String TAG = TileLayer.class.getName();
public class TileLayer<T extends TileLoader> extends Layer {
//private final static String TAG = TileLayer.class.getName();
private boolean mClearMap = true;
private final TileManager mTileManager;
protected final TileManager mTileManager;
private final JobQueue mJobQueue;
protected final JobQueue mJobQueue;
private final int mNumTileWorker = 4;
private final TileGenerator mTileWorker[];
protected final int mNumTileLoader = 4;
protected final ArrayList<T> mTileLoader;
public TileLayer(MapView mapView) {
public TileLayer(MapView mapView, TileLoader.Factory<T> factory) {
super(mapView);
// TileManager responsible for adding visible tiles
// to load queue and managing in-memory tile cache.
mTileManager = new TileManager(mapView, this);
mJobQueue = new JobQueue();
mTileWorker = new TileGenerator[mNumTileWorker];
TileGenerator.setDebugSettings(mapView.getDebugSettings());
for (int i = 0; i < mNumTileWorker; i++) {
mTileWorker[i] = new TileGenerator(i, mJobQueue, mTileManager);
mTileWorker[i].start();
// Instantiate TileLoader threads
mTileLoader = new ArrayList<T>();
for (int i = 0; i < mNumTileLoader; i++) {
T tileGenerator = factory.create(mJobQueue, mTileManager);
mTileLoader.add(tileGenerator);
tileGenerator.start();
}
// RenderLayer is working in GL Thread and actually
// drawing loaded tiles to screen.
mLayer = new TileRenderLayer(mapView, mTileManager);
}
@ -80,7 +65,6 @@ public class TileLayer extends Layer {
mTileManager.init(mMapView.getWidth(), mMapView.getHeight());
mClearMap = false;
changed = true;
Log.d(TAG, "init TileManager ----- ");
}
if (changed)
mTileManager.update(mapPosition);
@ -91,7 +75,7 @@ public class TileLayer extends Layer {
mTileManager.destroy();
for (TileGenerator tileWorker : mTileWorker) {
for (T tileWorker : mTileLoader) {
tileWorker.pause();
tileWorker.interrupt();
@ -107,192 +91,11 @@ public class TileLayer extends Layer {
}
}
private void clearMap() {
protected void clearMap() {
// clear tile and overlay data before next draw
mClearMap = true;
}
private MapOptions mMapOptions;
private IMapDatabase mMapDatabase;
private String mRenderTheme;
/**
* Sets the MapDatabase for this MapView.
*
* @param options
* the new MapDatabase options.
* @return true if MapDatabase changed
*/
public boolean setMapDatabase(MapOptions options) {
Log.i(TAG, "setMapDatabase: " + options.db.name());
if (mMapOptions != null && mMapOptions.equals(options))
return true;
tileWorkersPause(true);
mJobQueue.clear();
mMapOptions = options;
mMapDatabase = null;
for (int i = 0; i < mNumTileWorker; i++) {
//TileGenerator tileWorker = mTileWorker[i];
IMapDatabase mapDatabase = MapDatabaseFactory
.createMapDatabase(options.db);
OpenResult result = mapDatabase.open(options);
if (result != OpenResult.SUCCESS) {
Log.d(TAG, "failed open db: " + result.getErrorMessage());
}
mTileWorker[i].setMapDatabase(mapDatabase);
//TileGenerator tileGenerator = tileWorker.getTileGenerator();
//tileGenerator.setMapDatabase(mapDatabase);
// TODO this could be done in a cleaner way..
if (mMapDatabase == null)
mMapDatabase = mapDatabase;
}
if (options.db == MapDatabases.OSCIMAP_READER ||
options.db == MapDatabases.MAP_READER ||
options.db == MapDatabases.TEST_READER)
MapView.enableClosePolygons = true;
else
MapView.enableClosePolygons = false;
clearMap();
tileWorkersProceed();
return true;
}
public Map<String, String> getMapOptions() {
return mMapOptions;
}
public MapPosition getMapFileCenter() {
if (mMapDatabase == null)
return null;
MapInfo mapInfo = mMapDatabase.getMapInfo();
if (mapInfo == null)
return null;
GeoPoint startPos = mapInfo.startPosition;
if (startPos == null)
startPos = mapInfo.mapCenter;
if (startPos == null)
startPos = new GeoPoint(0, 0);
MapPosition mapPosition = new MapPosition();
mapPosition.setPosition(startPos);
if (mapInfo.startZoomLevel == null)
mapPosition.setZoomLevel(12);
else
mapPosition.setZoomLevel((mapInfo.startZoomLevel).byteValue());
return mapPosition;
}
public String getRenderTheme() {
return mRenderTheme;
}
/**
* Sets the internal theme which is used for rendering the map.
*
* @param internalRenderTheme
* the internal rendering theme.
* @return ...
* @throws IllegalArgumentException
* if the supplied internalRenderTheme is null.
*/
public boolean setRenderTheme(InternalRenderTheme internalRenderTheme) {
if (internalRenderTheme == null) {
throw new IllegalArgumentException("render theme must not be null");
}
if (internalRenderTheme.name() == mRenderTheme)
return true;
boolean ret = setRenderTheme((Theme) internalRenderTheme);
if (ret) {
mRenderTheme = internalRenderTheme.name();
}
clearMap();
return ret;
}
/**
* Sets the theme file which is used for rendering the map.
*
* @param renderThemePath
* the path to the XML file which defines the rendering theme.
* @throws IllegalArgumentException
* if the supplied internalRenderTheme is null.
* @throws FileNotFoundException
* if the supplied file does not exist, is a directory or cannot
* be read.
*/
public void setRenderTheme(String renderThemePath) throws FileNotFoundException {
if (renderThemePath == null) {
throw new IllegalArgumentException("render theme path must not be null");
}
boolean ret = setRenderTheme(new ExternalRenderTheme(renderThemePath));
if (ret) {
mRenderTheme = renderThemePath;
}
clearMap();
}
private boolean setRenderTheme(Theme theme) {
tileWorkersPause(true);
InputStream inputStream = null;
try {
inputStream = theme.getRenderThemeAsStream();
IRenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
t.scaleTextSize(1 + (MapView.dpi / 240 - 1) * 0.5f);
// FIXME !!!
GLRenderer.setRenderTheme(t);
for (TileGenerator g : mTileWorker)
g.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 {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
tileWorkersProceed();
}
return false;
}
/**
* add jobs and remember TileGenerators that stuff needs to be done
@ -300,36 +103,36 @@ public class TileLayer extends Layer {
* @param jobs
* tile jobs
*/
public void addJobs(MapTile[] jobs) {
public void setJobs(MapTile[] jobs) {
if (jobs == null) {
mJobQueue.clear();
return;
}
mJobQueue.setJobs(jobs);
for (int i = 0; i < mNumTileWorker; i++) {
TileGenerator m = mTileWorker[i];
for (int i = 0; i < mNumTileLoader; i++) {
T m = mTileLoader.get(i);
synchronized (m) {
m.notify();
}
}
}
private void tileWorkersPause(boolean wait) {
for (TileGenerator tileWorker : mTileWorker) {
if (!tileWorker.isPausing())
tileWorker.pause();
protected void pauseLoaders(boolean wait) {
for (T loader : mTileLoader) {
if (!loader.isPausing())
loader.pause();
}
if (wait) {
for (TileGenerator tileWorker : mTileWorker) {
if (!tileWorker.isPausing())
tileWorker.awaitPausing();
for (T loader : mTileLoader) {
if (!loader.isPausing())
loader.awaitPausing();
}
}
}
private void tileWorkersProceed() {
for (TileGenerator tileWorker : mTileWorker)
tileWorker.proceed();
protected void resumeLoaders() {
for (T loader : mTileLoader)
loader.proceed();
}
}

View File

@ -1,6 +1,5 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013 Hannes Hannes Janetzek
* Copyright 2013 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
@ -17,32 +16,34 @@ package org.oscim.layers.tile;
import org.oscim.utils.PausableThread;
/**
* A MapWorker uses a {@link TileGenerator} to generate map tiles. It runs in a
* separate thread to avoid blocking the UI thread.
*/
public abstract class MapWorker extends PausableThread {
public abstract class TileLoader extends PausableThread {
private static int id;
public interface Factory<T extends TileLoader>{
T create(JobQueue jobQueue, TileManager tileManager);
}
private final String THREAD_NAME;
private final JobQueue mJobQueue;
private final TileManager mTileManager;
/**
* @param id
* thread id
* @param jobQueue
* ...
* @param tileManager
* ...
*/
public MapWorker(int id, JobQueue jobQueue, TileManager tileManager) {
public TileLoader(JobQueue jobQueue, TileManager tileManager) {
super();
mJobQueue = jobQueue;
mTileManager = tileManager;
THREAD_NAME = "MapWorker" + id;
THREAD_NAME = "TileLoader" + (id++);
}
public abstract void cleanup();
/**
* Load data for 'tile' and file tile.layers for rendering.
* (executed on MapWorker threads)
*/
protected abstract boolean executeJob(MapTile tile);
@Override
protected void doWork() {
MapTile tile = mJobQueue.poll();
@ -63,7 +64,6 @@ public abstract class MapWorker extends PausableThread {
}
}
protected abstract boolean executeJob(MapTile tile);
@Override
protected String getThreadName() {

View File

@ -114,9 +114,9 @@ public class TileManager {
};
private final float[] mBoxCoords = new float[8];
private final TileLayer mTileLayer;
private final TileLayer<?> mTileLayer;
public TileManager(MapView mapView, TileLayer tileLayer) {
public TileManager(MapView mapView, TileLayer<?> tileLayer) {
mMapView = mapView;
mTileLayer = tileLayer;
@ -197,7 +197,7 @@ public class TileManager {
// start with old jobs while new jobs are calculated, which
// should increase the chance that they are free when new
// jobs come in.
mTileLayer.addJobs(null);
mTileLayer.setJobs(null);
// load some tiles more than currently visible (* 0.75)
double scale = pos.scale * 0.9f;
@ -260,7 +260,7 @@ public class TileManager {
updateTileDistances(jobs, jobs.length, pos);
// sets tiles to state == LOADING
mTileLayer.addJobs(jobs);
mTileLayer.setJobs(jobs);
mJobs.clear();
/* limit cache items */
@ -527,7 +527,7 @@ public class TileManager {
} else if (t.state == STATE_LOADING) {
// NOTE: when set loading to false the tile could be
// added to load queue again while still processed in
// TileGenerator => need tile.cancel flag.
// MapTileLoader => need tile.cancel flag.
// t.isLoading = false;
Log.d(TAG, "limitCache: cancel loading " + t + " " + t.distance);
} else {
@ -560,7 +560,7 @@ public class TileManager {
}
/**
* called from MapWorker Thread when tile is loaded by TileGenerator
* called from MapWorker Thread when tile is loaded by MapTileLoader
*
* @param tile
* Tile ready for upload to GL
@ -570,7 +570,7 @@ public class TileManager {
if (tile.state != STATE_LOADING) {
// - should rather be STATE_FAILED
// no one should be able to use this tile now, TileGenerator passed
// no one should be able to use this tile now, MapTileLoader passed
// it, GL-Thread does nothing until newdata is set.
//Log.d(TAG, "passTile: failed loading " + tile);
return true;

View File

@ -24,8 +24,8 @@ import static android.opengl.GLES20.glVertexAttribPointer;
import org.oscim.core.MapPosition;
import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLRenderer.Matrices;
import org.oscim.renderer.GLState;
import org.oscim.theme.renderinstruction.Line;
import org.oscim.utils.GlUtils;
@ -153,8 +153,6 @@ public final class LineRenderer {
glUniform1f(uLineMode, lineMode);
boolean blur = false;
// dont increase scale when max is reached
//boolean strokeMaxZoom = zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL;
Layer l = curLayer;
for (; l != null && l.type == Layer.LINE; l = l.next) {

View File

@ -23,8 +23,8 @@ import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.database.MapOptions;
import org.oscim.layers.Layer;
import org.oscim.layers.tile.TileGenerator;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.MapTileLayer;
import org.oscim.layers.tile.MapTileLoader;
import org.oscim.overlay.BuildingOverlay;
import org.oscim.overlay.LabelingOverlay;
import org.oscim.overlay.Overlay;
@ -121,7 +121,7 @@ public class MapView extends RelativeLayout {
mDebugSettings = new DebugSettings();
// FIXME
TileGenerator.setDebugSettings(mDebugSettings);
MapTileLoader.setDebugSettings(mDebugSettings);
mapActivity.registerMapView(this);
@ -134,8 +134,8 @@ public class MapView extends RelativeLayout {
redrawMap(false);
}
public TileLayer setBaseMap(MapOptions options) {
TileLayer baseLayer = new TileLayer(this);
public MapTileLayer setBaseMap(MapOptions options) {
MapTileLayer baseLayer = new MapTileLayer(this);
baseLayer.setMapDatabase(options);
@ -266,7 +266,7 @@ public class MapView extends RelativeLayout {
*/
public void setDebugSettings(DebugSettings debugSettings) {
mDebugSettings = debugSettings;
TileGenerator.setDebugSettings(debugSettings);
MapTileLoader.setDebugSettings(debugSettings);
}
/**
@ -351,4 +351,5 @@ public class MapView extends RelativeLayout {
public boolean getRotationEnabled() {
return mRotationEnabled;
}
}