finish first part of database -> tilesource refactoring

- now there is a clean separation between TileSource type
  and TileDataSource(worker instances)
This commit is contained in:
Hannes Janetzek 2013-05-27 03:13:24 +02:00
parent 2be2ab111a
commit 4abec66e39
47 changed files with 666 additions and 643 deletions

View File

@ -15,11 +15,11 @@
package org.oscim.core;
/**
* MapElement is created by MapDatabase(s) and passed to MapTileLoader
* via IMapDataSink.renderElement() MapTileLoader processes the
* MapElement is created by TileDataSource(s) and passed to MapTileLoader
* via ITileDataSink.process() MapTileLoader processes the
* data into MapTile.layers.
* -----
* This is really just a buffer object that belongs to MapDatabase, so
* This is really just a buffer object that belongs to TileDataSource, so
* dont keep a reference to it when passed as parameter.
*/
public class MapElement extends GeometryBuffer {

View File

@ -1,67 +0,0 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.database;
import android.util.AttributeSet;
/**
*
*
*/
public final class MapDatabaseFactory {
private static final String MAP_DATABASE_ATTRIBUTE_NAME = "mapDatabase";
public static MapDatabases getMapDatabase(AttributeSet attributeSet) {
String mapDatabaseName = attributeSet.getAttributeValue(null,
MAP_DATABASE_ATTRIBUTE_NAME);
if (mapDatabaseName == null) {
return MapDatabases.OPENSCIENCEMAP2;
}
return MapDatabases.valueOf(mapDatabaseName);
}
/**
* @param mapDatabase
* the internal MapDatabase implementation.
* @return a new MapDatabase instance.
*/
public static IMapDatabase createMapDatabase(MapDatabases mapDatabase) {
switch (mapDatabase) {
case MAPSFORGE:
return new org.oscim.database.mapfile.MapDatabase();
case TEST:
return new org.oscim.database.test.MapDatabase();
case OPENSCIENCEMAP1:
return new org.oscim.database.oscimap.MapDatabase();
case OPENSCIENCEMAP2:
return new org.oscim.database.oscimap2.MapDatabase();
case OPENSCIENCEMAP4:
return new org.oscim.database.oscimap4.MapDatabase();
case MAPNIK_VECTOR:
return new org.oscim.database.mapnik.MapDatabase();
default:
break;
}
throw new IllegalArgumentException("unknown enum value: " + mapDatabase);
}
private MapDatabaseFactory() {
throw new IllegalStateException();
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright 2013
*
* 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.database.mapnik;
import org.oscim.core.Tile;
import org.oscim.database.common.LwHttp;
import org.oscim.database.common.ProtobufMapDatabase;
public class MapDatabase extends ProtobufMapDatabase {
//private static final String TAG = MapDatabase.class.getName();
public MapDatabase() {
super(new TileDecoder());
mConn = new LwHttp("image/png","vector.pbf", true) {
@Override
protected int formatTilePath(Tile tile, byte[] path, int pos) {
// url formatter for mapbox streets
byte[] hexTable = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
path[pos++] = '/';
path[pos++] = hexTable[(tile.tileX) % 16];
path[pos++] = hexTable[(tile.tileY) % 16];
path[pos++] = '/';
pos = LwHttp.writeInt(tile.zoomLevel, pos, path);
path[pos++] = '/';
pos = LwHttp.writeInt(tile.tileX, pos, path);
path[pos++] = '/';
pos = LwHttp.writeInt(tile.tileY, pos, path);
return pos;
}
};
}
}

View File

@ -17,18 +17,11 @@ package org.oscim.layers.tile.vector;
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.layers.tile.TileLayer;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.GLRenderer;
@ -37,6 +30,11 @@ import org.oscim.theme.IRenderTheme;
import org.oscim.theme.InternalRenderTheme;
import org.oscim.theme.RenderThemeHandler;
import org.oscim.theme.Theme;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.MapInfo;
import org.oscim.tilesource.TileSource;
import org.oscim.tilesource.TileSource.OpenResult;
import org.oscim.tilesource.oscimap.OSciMap1TileSource;
import org.oscim.view.MapView;
import org.xml.sax.SAXException;
@ -54,54 +52,47 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
return new MapTileLoader(tm);
}
private MapOptions mMapOptions;
private IMapDatabase mMapDatabase;
private TileSource mTileSource;
private String mRenderTheme;
/**
* Sets the MapDatabase for this MapView.
* Sets the TileSource for this MapView.
*
* @param options
* the new MapDatabase options.
* @return true if MapDatabase changed
* @param tileSource
* the new TileSource.
* @return true if TileSource changed
*/
public boolean setMapDatabase(MapOptions options) {
Log.i(TAG, "setMapDatabase: " + options.db.name());
if (mMapOptions != null && mMapOptions.equals(options))
return true;
public boolean setTileSource(TileSource tileSource) {
pauseLoaders(true);
mTileManager.clearJobs();
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 (mTileSource != null) {
mTileSource.close();
mTileSource = null;
}
if (options.db == MapDatabases.OPENSCIENCEMAP1)
OpenResult msg = tileSource.open();
if (msg != OpenResult.SUCCESS) {
Log.d(TAG, msg.getErrorMessage());
return false;
}
mTileSource = tileSource;
for (int i = 0; i < mNumTileLoader; i++) {
ITileDataSource tileDataSource = tileSource.getDataSource();
mTileLoader.get(i).setTileDataSource(tileDataSource);
}
if (tileSource instanceof OSciMap1TileSource)
MapView.enableClosePolygons = false;
else
MapView.enableClosePolygons = true;
mTileManager.setZoomTable(mMapDatabase.getMapInfo().zoomLevel);
mTileManager.setZoomTable(mTileSource.getMapInfo().zoomLevel);
mMapView.clearMap();
@ -110,15 +101,11 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
return true;
}
public Map<String, String> getMapOptions() {
return mMapOptions;
}
public MapPosition getMapFileCenter() {
if (mMapDatabase == null)
if (mTileSource == null)
return null;
MapInfo mapInfo = mMapDatabase.getMapInfo();
MapInfo mapInfo = mTileSource.getMapInfo();
if (mapInfo == null)
return null;

View File

@ -23,9 +23,6 @@ import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabase.QueryResult;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
@ -44,6 +41,9 @@ import org.oscim.theme.renderinstruction.LineSymbol;
import org.oscim.theme.renderinstruction.RenderInstruction;
import org.oscim.theme.renderinstruction.Symbol;
import org.oscim.theme.renderinstruction.Text;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.ITileDataSource.QueryResult;
import org.oscim.utils.LineClipper;
import org.oscim.view.DebugSettings;
@ -59,7 +59,7 @@ import android.util.Log;
* 5. RenderTheme calls IRenderCallback functions with style information
* 6. Styled items become added to MapTile.layers... roughly
*/
public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDataSink {
public class MapTileLoader extends TileLoader implements IRenderCallback, ITileDataSink {
private static final String TAG = MapTileLoader.class.getName();
@ -84,8 +84,8 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
private IRenderTheme renderTheme;
private int renderLevels;
// current MapDatabase used by this MapTileLoader
private IMapDatabase mMapDatabase;
// current TileDataSource used by this MapTileLoader
private ITileDataSource mTileDataSource;
// currently processed tile
private MapTile mTile;
@ -145,7 +145,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
*/
@Override
public void cleanup() {
mMapDatabase.close();
mTileDataSource.destroy();
}
/* (non-Javadoc)
@ -154,7 +154,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
@Override
public boolean executeJob(MapTile mapTile) {
if (mMapDatabase == null)
if (mTileDataSource == null)
return false;
mTile = mapTile;
@ -181,7 +181,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
// query database, which calls renderWay and renderPOI
// callbacks while processing map tile data.
if (mMapDatabase.executeQuery(mTile, this) != QueryResult.SUCCESS) {
if (mTileDataSource.executeQuery(mTile, this) != QueryResult.SUCCESS) {
//Log.d(TAG, "Failed loading: " + tile);
mTile.layers.clear();
@ -239,15 +239,15 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, IMapDa
mStrokeScale = 1;
}
public void setMapDatabase(IMapDatabase mapDatabase) {
if (mMapDatabase != null)
mMapDatabase.close();
public void setTileDataSource(ITileDataSource mapDatabase) {
if (mTileDataSource != null)
mTileDataSource.destroy();
mMapDatabase = mapDatabase;
mTileDataSource = mapDatabase;
}
public IMapDatabase getMapDatabase() {
return mMapDatabase;
public ITileDataSource getMapDatabase() {
return mTileDataSource;
}
private boolean mRenderBuildingModel;

View File

@ -24,7 +24,7 @@ class MatchingCacheKey {
}
MatchingCacheKey(MatchingCacheKey key) {
// need to clone tags as they belong to MapDatabase
// need to clone tags as they belong to TileDataSource
mTags = key.mTags.clone();
mHash = key.mHash;
}

View File

@ -228,7 +228,9 @@
<!-- keep grass above forest:wood and leisure:park! -->
<rule e="way" k="landuse" v="grass|meadow">
<!-- http://wiki.openstreetmap.org/wiki/Proposed_features/conservation,
often serves as background for leisure=nature_reserve -->
<rule e="way" k="landuse" v="grass|meadow|conservation">
<use-area name="greens" />
</rule>

View File

@ -12,18 +12,17 @@
* 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.database;
package org.oscim.tilesource;
import org.oscim.core.MapElement;
/**
* MapDatabase callback (implemented by MapTileLoader)
* MapDatabase callback (implemented by MapTileLoader)
* .
* NOTE: MapElement passed belong to the caller! i.e. dont hold
* references to its arrays after callback function returns.
*/
public interface IMapDataSink {
public interface ITileDataSink {
void process(MapElement element);
}

View File

@ -1,4 +1,5 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2012 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
@ -12,18 +13,35 @@
* 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.database.oscimap;
package org.oscim.tilesource;
import org.oscim.database.common.LwHttp;
import org.oscim.database.common.ProtobufMapDatabase;
import org.oscim.layers.tile.MapTile;
/**
* Deprecated
*
*
*/
public class MapDatabase extends ProtobufMapDatabase {
public MapDatabase() {
super(new TileDecoder());
mConn = new LwHttp("application/osmtile", "osmtile", false);
public interface ITileDataSource {
/**
* Starts a database query with the given parameters.
*
* @param tile
* the tile to read.
* @param mapDataSink
* the callback which handles the extracted map elements.
* @return true if successful
*/
abstract QueryResult executeQuery(MapTile tile,
ITileDataSink mapDataSink);
abstract void destroy();
public static enum QueryResult {
SUCCESS,
FAILED,
TILE_NOT_FOUND,
DELAYED,
}
}

View File

@ -12,16 +12,14 @@
* 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.database;
package org.oscim.tilesource;
import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint;
import org.oscim.database.mapfile.MapDatabase;
/**
* Contains the immutable metadata of a map file.
*
* @see MapDatabase#getMapInfo()
*/
public class MapInfo {
/**

View File

@ -12,7 +12,7 @@
* 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.database;
package org.oscim.tilesource;
import java.util.HashMap;
@ -20,9 +20,9 @@ public class MapOptions extends HashMap<String, String> {
private static final long serialVersionUID = 1L;
public final MapDatabases db;
public final TileSources db;
public MapOptions(MapDatabases db) {
public MapOptions(TileSources db) {
this.db = db;
}

View File

@ -1,6 +1,5 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2012 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
@ -13,70 +12,53 @@
* 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.database;
package org.oscim.tilesource;
import org.oscim.layers.tile.MapTile;
import java.util.HashMap;
/**
*
*
*/
public interface IMapDatabase {
public abstract class TileSource {
/**
* Starts a database query with the given parameters.
*
* @param tile
* the tile to read.
* @param mapDataSink
* the callback which handles the extracted map elements.
* @return true if successful
*/
abstract QueryResult executeQuery(MapTile tile,
IMapDataSink mapDataSink);
public abstract ITileDataSource getDataSource();
public abstract OpenResult open();
public abstract void close();
protected final Options options = new Options();
public void setOption(String key, String value){
options.put(key, value);
}
public String getOption(String key){
return options.get(key);
}
/**
* @return the metadata for the current map file.
* @throws IllegalStateException
* if no map is currently opened.
*/
abstract MapInfo getMapInfo();
public abstract MapInfo getMapInfo();
/**
* @return true if a map database is currently opened, false otherwise.
*/
abstract boolean isOpen();
/**
* Opens MapDatabase
*
* @param options
* the options.
* @return a OpenResult containing an error message in case of a failure.
*/
abstract OpenResult open(MapOptions options);
public static class Options extends HashMap<String, String> {
/**
* 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
*/
abstract void close();
private static final long serialVersionUID = 1L;
abstract String getMapProjection();
@Override
public boolean equals(Object other) {
if (!(other instanceof MapOptions))
return false;
/**
* Cancel loading
*/
abstract void cancel();
//if (this.db != ((MapOptions) other).db)
// return false;
public static enum QueryResult {
SUCCESS,
FAILED,
TILE_NOT_FOUND,
DELAYED,
// FIXME test if this is correct!
if (!this.entrySet().equals(((MapOptions) other).entrySet()))
return false;
return true;
}
}
/**
* A FileOpenResult is a simple DTO which is returned by
* IMapDatabase#open().
@ -103,9 +85,6 @@ public interface IMapDatabase {
this.errorMessage = errorMessage;
}
/**
*
*/
public OpenResult() {
this.success = true;
this.errorMessage = null;
@ -137,5 +116,4 @@ public interface IMapDatabase {
return stringBuilder.toString();
}
}
}

View File

@ -12,12 +12,12 @@
* 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.database;
package org.oscim.tilesource;
/**
* MapDatabase Implementations
*/
public enum MapDatabases {
public enum TileSources {
/**
* ...
*/

View File

@ -12,14 +12,13 @@
* 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.database.common;
package org.oscim.tilesource.common;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
@ -43,8 +42,8 @@ public class LwHttp {
private final static int BUFFER_SIZE = 1024;
private final byte[] buffer = new byte[BUFFER_SIZE];
private String mHost;
private int mPort;
private final String mHost;
private final int mPort;
private int mMaxReq = 0;
private Socket mSocket;
@ -53,21 +52,42 @@ public class LwHttp {
private long mLastRequest = 0;
private SocketAddress mSockAddr;
private byte[] REQUEST_GET_START;
private byte[] REQUEST_GET_END;
private byte[] mRequestBuffer;
private final byte[] REQUEST_GET_START;
private final byte[] REQUEST_GET_END;
private final byte[] mRequestBuffer;
private final boolean mInflateContent;
private final byte[] mContentType;
private final String mExtension;
//private final String mExtension;
private int mContentLength = -1;
public LwHttp(String contentType, String extension, boolean deflate) {
mExtension = extension;
public LwHttp(URL url, String contentType, String extension, boolean deflate) {
//mExtension = extension;
mContentType = contentType.getBytes();
mInflateContent = deflate;
int port = url.getPort();
if (port < 0)
port = 80;
String host = url.getHost();
String path = url.getPath();
Log.d(TAG, "open database: " + host + " " + port + " " + path);
REQUEST_GET_START = ("GET " + path).getBytes();
REQUEST_GET_END = ("." + extension + " HTTP/1.1" +
"\nHost: " + host +
"\nConnection: Keep-Alive" +
"\n\n").getBytes();
mHost = host;
mPort = port;
mRequestBuffer = new byte[1024];
System.arraycopy(REQUEST_GET_START, 0,
mRequestBuffer, 0, REQUEST_GET_START.length);
}
static class Buffer extends BufferedInputStream {
@ -86,39 +106,30 @@ public class LwHttp {
}
}
public boolean setServer(String urlString) {
URL url;
try {
url = new URL(urlString);
} catch (MalformedURLException e) {
e.printStackTrace();
return false;
}
int port = url.getPort();
if (port < 0)
port = 80;
String host = url.getHost();
String path = url.getPath();
Log.d(TAG, "open database: " + host + " " + port + " " + path);
REQUEST_GET_START = ("GET " + path).getBytes();
REQUEST_GET_END = ("." + mExtension + " HTTP/1.1" +
"\nHost: " + host +
"\nConnection: Keep-Alive" +
"\n\n").getBytes();
mHost = host;
mPort = port;
mRequestBuffer = new byte[1024];
System.arraycopy(REQUEST_GET_START, 0,
mRequestBuffer, 0, REQUEST_GET_START.length);
return true;
}
// public void setServer(URL url) {
//
// int port = url.getPort();
// if (port < 0)
// port = 80;
//
// String host = url.getHost();
// String path = url.getPath();
// Log.d(TAG, "open database: " + host + " " + port + " " + path);
//
// REQUEST_GET_START = ("GET " + path).getBytes();
//
// REQUEST_GET_END = ("." + mExtension + " HTTP/1.1" +
// "\nHost: " + host +
// "\nConnection: Keep-Alive" +
// "\n\n").getBytes();
//
// mHost = host;
// mPort = port;
//
// mRequestBuffer = new byte[1024];
// System.arraycopy(REQUEST_GET_START, 0,
// mRequestBuffer, 0, REQUEST_GET_START.length);
// }
public void close() {
if (mSocket != null) {

View File

@ -12,19 +12,19 @@
* 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.database.common;
package org.oscim.tilesource.common;
import java.io.IOException;
import java.io.InputStream;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.utils.UTF8Decoder;
import android.util.Log;
public abstract class ProtobufDecoder {
private final static String TAG = ProtobufDecoder.class.getName();
public abstract class PbfDecoder {
private final static String TAG = PbfDecoder.class.getName();
protected static final boolean debug = false;
@ -67,11 +67,11 @@ public abstract class ProtobufDecoder {
private final UTF8Decoder mStringDecoder;
public ProtobufDecoder() {
public PbfDecoder() {
mStringDecoder = new UTF8Decoder();
}
public abstract boolean decode(Tile tile, IMapDataSink sink,
public abstract boolean decode(Tile tile, ITileDataSink sink,
InputStream is, int contentLength) throws IOException;
public void setInputStream(InputStream is, int contentLength) {

View File

@ -12,20 +12,16 @@
* 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.database.common;
package org.oscim.tilesource.common;
import java.io.InputStream;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint;
import org.oscim.database.IMapDataSink;
import org.oscim.database.IMapDatabase;
import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions;
import org.oscim.layers.tile.MapTile;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
import android.util.Log;
@ -33,26 +29,19 @@ import android.util.Log;
*
*
*/
public abstract class ProtobufMapDatabase implements IMapDatabase {
private static final String TAG = ProtobufMapDatabase.class.getName();
public abstract class PbfTileDataSource implements ITileDataSource {
private static final String TAG = PbfTileDataSource.class.getName();
protected LwHttp mConn;
protected final ProtobufDecoder mTileDecoder;
protected final PbfDecoder mTileDecoder;
// 'open' state
private boolean mOpen = false;
public ProtobufMapDatabase(ProtobufDecoder tileDecoder) {
public PbfTileDataSource(PbfDecoder tileDecoder) {
mTileDecoder = tileDecoder;
}
private static final MapInfo mMapInfo =
new MapInfo(new BoundingBox(-180, -90, 180, 90),
new Byte((byte) 4), new GeoPoint(53.11, 8.85),
null, 0, 0, 0, "de", "comment", "author", null);
@Override
public QueryResult executeQuery(MapTile tile, IMapDataSink sink) {
public QueryResult executeQuery(MapTile tile, ITileDataSink sink) {
QueryResult result = QueryResult.SUCCESS;
try {
@ -91,46 +80,7 @@ public abstract class ProtobufMapDatabase implements IMapDatabase {
}
@Override
public String getMapProjection() {
return null;
}
@Override
public MapInfo getMapInfo() {
return mMapInfo;
}
@Override
public boolean isOpen() {
return mOpen;
}
@Override
public OpenResult open(MapOptions options) {
if (mOpen)
return OpenResult.SUCCESS;
if (options == null || !options.containsKey("url"))
return new OpenResult("No URL in MapOptions");
if (!mConn.setServer(options.get("url"))) {
return new OpenResult("invalid url: " + options.get("url"));
}
mOpen = true;
return OpenResult.SUCCESS;
}
@Override
public void close() {
mOpen = false;
public void destroy() {
mConn.close();
}
@Override
public void cancel() {
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.tilesource.common;
import java.net.MalformedURLException;
import java.net.URL;
import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint;
import org.oscim.tilesource.MapInfo;
import org.oscim.tilesource.TileSource;
public abstract class UrlTileSource extends TileSource{
private final static String KEY_URL = "url";
private static final MapInfo mMapInfo =
new MapInfo(new BoundingBox(-180, -90, 180, 90),
new Byte((byte) 4), new GeoPoint(53.11, 8.85),
null, 0, 0, 0, "de", "comment", "author", null);
protected URL mUrl;
@Override
public OpenResult open() {
if (!options.containsKey(KEY_URL))
return new OpenResult("no url set");
String urlString = options.get(KEY_URL);
try {
mUrl = new URL(urlString);
} catch (MalformedURLException e) {
e.printStackTrace();
return new OpenResult("invalid url " + urlString);
}
return OpenResult.SUCCESS;
}
@Override
public void close() {
}
public boolean setUrl(String urlString){
options.put("url", urlString);
return open() == OpenResult.SUCCESS;
}
@Override
public MapInfo getMapInfo() {
return mMapInfo;
}
}

View File

@ -12,7 +12,7 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
/**
* This utility class contains methods to convert byte arrays to numbers.

View File

@ -12,7 +12,7 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import java.io.IOException;
import java.io.RandomAccessFile;
@ -21,7 +21,7 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.oscim.database.mapfile.header.SubFileParameter;
import org.oscim.tilesource.mapfile.header.SubFileParameter;
import org.oscim.utils.LRUCache;
/**

View File

@ -12,9 +12,9 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import org.oscim.database.mapfile.header.SubFileParameter;
import org.oscim.tilesource.mapfile.header.SubFileParameter;
/**
* An immutable container class which is the key for the index cache.

View File

@ -1,5 +1,6 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
* 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
@ -12,9 +13,8 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
@ -22,25 +22,20 @@ import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.IMapDatabase;
import org.oscim.database.MapOptions;
import org.oscim.database.mapfile.header.MapFileHeader;
import org.oscim.database.mapfile.header.MapFileInfo;
import org.oscim.database.mapfile.header.SubFileParameter;
import org.oscim.layers.tile.MapTile;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.mapfile.header.SubFileParameter;
import android.util.Log;
/**
* A class for reading binary map files.
* <p>
* This class is not thread-safe. Each thread should use its own instance.
*
* @see <a
* href="http://code.google.com/p/mapsforge/wiki/SpecificationBinaryMapFile">Specification</a>
*/
public class MapDatabase implements IMapDatabase {
public class MapDatabase implements ITileDataSource {
/**
* Bitmask to extract the block offset from an index entry.
*/
@ -66,11 +61,6 @@ public class MapDatabase implements IMapDatabase {
*/
private static final String DEBUG_SIGNATURE_WAY = "way signature: ";
/**
* Amount of cache blocks that the index cache should store.
*/
private static final int INDEX_CACHE_SIZE = 64;
/**
* Error message for an invalid first way offset.
*/
@ -119,8 +109,6 @@ public class MapDatabase implements IMapDatabase {
*/
private static final int POI_NUMBER_OF_TAGS_BITMASK = 0x0f;
private static final String READ_ONLY_MODE = "r";
/**
* Length of the debug signature at the beginning of each block.
*/
@ -181,9 +169,6 @@ public class MapDatabase implements IMapDatabase {
*/
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;
private static IndexCache sDatabaseIndexCache;
private static MapFileHeader sMapFileHeader;
private static int instances = 0;
private long mFileSize;
private boolean mDebugFile;
@ -196,23 +181,18 @@ public class MapDatabase implements IMapDatabase {
private int mTileLongitude;
private int[] mIntBuffer;
//private final GeometryBuffer mElem = new GeometryBuffer(1 << 14, 1 << 8);
//private final WayData mWay = new WayData();
private final MapElement mElem = new MapElement();
private int minLat, minLon;
private Tile mTile;
private static boolean sMapExperimental;
/*
* (non-Javadoc)
* @see org.oscim.map.reader.IMapDatabase#executeQuery(org.oscim.core.Tile,
* org.oscim.map.reader.MapDatabaseCallback)
*/
private final MapFileTileSource mTileSource;
@Override
public QueryResult executeQuery(MapTile tile, IMapDataSink mapDataSink) {
public QueryResult executeQuery(MapTile tile, ITileDataSink mapDataSink) {
if (sMapFileHeader == null)
if (mTileSource.fileHeader == null)
return QueryResult.FAILED;
if (mIntBuffer == null)
@ -222,10 +202,10 @@ public class MapDatabase implements IMapDatabase {
mTile = tile;
QueryParameters queryParameters = new QueryParameters();
queryParameters.queryZoomLevel = sMapFileHeader
queryParameters.queryZoomLevel = mTileSource.fileHeader
.getQueryZoomLevel(tile.zoomLevel);
// get and check the sub-file for the query zoom level
SubFileParameter subFileParameter = sMapFileHeader
SubFileParameter subFileParameter = mTileSource.fileHeader
.getSubFileParameter(queryParameters.queryZoomLevel);
if (subFileParameter == null) {
Log.w(TAG, "no sub-file for zoom level: "
@ -243,126 +223,35 @@ public class MapDatabase implements IMapDatabase {
return QueryResult.SUCCESS;
}
/*
* (non-Javadoc)
* @see org.oscim.map.reader.IMapDatabase#getMapFileInfo()
*/
@Override
public MapFileInfo getMapInfo() {
if (sMapFileHeader == null) {
throw new IllegalStateException("no map file is currently opened");
}
return sMapFileHeader.getMapFileInfo();
}
public MapDatabase(MapFileTileSource tileSource) throws IOException {
mTileSource = tileSource;
try {
// open the file in read only mode
mInputFile = new RandomAccessFile(tileSource.mapFile, "r");
mFileSize = mInputFile.length();
mReadBuffer = new ReadBuffer(mInputFile);
@Override
public String getMapProjection() {
return "WSG84";
}
/*
* (non-Javadoc)
* @see org.oscim.map.reader.IMapDatabase#hasOpenFile()
*/
@Override
public boolean isOpen() {
return mInputFile != null;
}
/*
* (non-Javadoc)
* @see org.oscim.map.reader.IMapDatabase#openFile(java.io.File)
*/
@Override
public OpenResult open(MapOptions options) {
try {
if (options.get("file") == null) {
throw new IllegalArgumentException("'file' must not be null");
} catch (IOException e) {
Log.e(TAG, e.getMessage());
// make sure that the file is closed
destroy();
throw new IOException();
}
// make sure to close any previously opened file first
//close();
File file = new File(options.get("file"));
Log.d(TAG, file.getAbsolutePath());
// File file = new File(options.get("mapfile"));
// check if the file exists and is readable
if (!file.exists()) {
return new OpenResult("file does not exist: " + file);
} else if (!file.isFile()) {
return new OpenResult("not a file: " + file);
} else if (!file.canRead()) {
return new OpenResult("cannot read file: " + file);
}
// open the file in read only mode
mInputFile = new RandomAccessFile(file, READ_ONLY_MODE);
mFileSize = mInputFile.length();
mReadBuffer = new ReadBuffer(mInputFile);
Log.d(TAG, "open instance " + instances + " " + file.getAbsolutePath());
if (instances++ > 0) {
return OpenResult.SUCCESS;
}
sMapFileHeader = new MapFileHeader();
OpenResult openResult = sMapFileHeader.readHeader(mReadBuffer,
mFileSize);
if (!openResult.isSuccess()) {
close();
return openResult;
}
sDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
sMapExperimental = sMapFileHeader.getMapFileInfo().fileVersion == 4;
Log.d(TAG, "File version: " + sMapFileHeader.getMapFileInfo().fileVersion);
return OpenResult.SUCCESS;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
// make sure that the file is closed
close();
return new OpenResult(e.getMessage());
}
}
/*
* (non-Javadoc)
* @see org.oscim.map.reader.IMapDatabase#closeFile()
*/
@Override
public void close() {
if (instances == 0)
return;
instances--;
Log.d(TAG, "close instance " + instances);
if (instances > 0) {
mReadBuffer = null;
return;
}
try {
sMapFileHeader = null;
@Override
public void destroy() {
mReadBuffer = null;
if (mInputFile != null) {
if (sDatabaseIndexCache != null) {
sDatabaseIndexCache.destroy();
sDatabaseIndexCache = null;
}
if (mInputFile != null) {
try {
mInputFile.close();
mInputFile = null;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
mReadBuffer = null;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
/**
@ -388,7 +277,7 @@ public class MapDatabase implements IMapDatabase {
*/
private void processBlock(QueryParameters queryParameters,
SubFileParameter subFileParameter,
IMapDataSink mapDataSink) {
ITileDataSink mapDataSink) {
if (!processBlockSignature()) {
return;
}
@ -442,7 +331,7 @@ public class MapDatabase implements IMapDatabase {
}
private void processBlocks(IMapDataSink mapDataSink,
private void processBlocks(ITileDataSink mapDataSink,
QueryParameters queryParameters,
SubFileParameter subFileParameter) throws IOException {
boolean queryIsWater = true;
@ -457,7 +346,7 @@ public class MapDatabase implements IMapDatabase {
long blockNumber = row * subFileParameter.blocksWidth + column;
// get the current index entry
long currentBlockIndexEntry = sDatabaseIndexCache.getIndexEntry(
long currentBlockIndexEntry = mTileSource.databaseIndexCache.getIndexEntry(
subFileParameter, blockNumber);
// check if the current query would still return a water tile
@ -484,7 +373,7 @@ public class MapDatabase implements IMapDatabase {
nextBlockPointer = subFileParameter.subFileSize;
} else {
// get and check the next block pointer
nextBlockPointer = sDatabaseIndexCache.getIndexEntry(
nextBlockPointer = mTileSource.databaseIndexCache.getIndexEntry(
subFileParameter, blockNumber + 1)
& BITMASK_INDEX_OFFSET;
if (nextBlockPointer < 1
@ -510,7 +399,7 @@ public class MapDatabase implements IMapDatabase {
Log.w(TAG, "current block size too large: " + currentBlockSize);
continue;
} else if (currentBlockPointer + currentBlockSize > mFileSize) {
Log.w(TAG, "current block largher than file size: "
Log.w(TAG, "current block larger than file size: "
+ currentBlockSize);
return;
}
@ -535,11 +424,7 @@ public class MapDatabase implements IMapDatabase {
mTileLatitude = (int) (tileLatitudeDeg * 1000000);
mTileLongitude = (int) (tileLongitudeDeg * 1000000);
//try {
processBlock(queryParameters, subFileParameter, mapDataSink);
//} catch (ArrayIndexOutOfBoundsException e) {
// Log.e(TAG, e.getMessage());
//}
}
}
@ -584,8 +469,8 @@ public class MapDatabase implements IMapDatabase {
* @return true if the POIs could be processed successfully, false
* otherwise.
*/
private boolean processPOIs(IMapDataSink mapDataSink, int numberOfPois) {
Tag[] poiTags = sMapFileHeader.getMapFileInfo().poiTags;
private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois) {
Tag[] poiTags = mTileSource.fileInfo.poiTags;
Tag[] tags = null;
Tag[] curTags;
@ -827,12 +712,12 @@ public class MapDatabase implements IMapDatabase {
* otherwise.
*/
private boolean processWays(QueryParameters queryParameters,
IMapDataSink mapDataSink,
ITileDataSink mapDataSink,
int numberOfWays) {
Tag[] tags = null;
Tag[] curTags;
Tag[] wayTags = sMapFileHeader.getMapFileInfo().wayTags;
Tag[] wayTags = mTileSource.fileInfo.wayTags;
int wayDataBlocks;
@ -840,7 +725,7 @@ public class MapDatabase implements IMapDatabase {
int stringsSize = 0;
stringOffset = 0;
if (sMapExperimental) {
if (mTileSource.experimental) {
stringsSize = mReadBuffer.readUnsignedInt();
stringOffset = mReadBuffer.getBufferPosition();
mReadBuffer.skipBytes(stringsSize);
@ -867,7 +752,7 @@ public class MapDatabase implements IMapDatabase {
if (elementCounter < 0)
return false;
if (sMapExperimental && mReadBuffer.lastTagPosition > 0) {
if (mTileSource.experimental && mReadBuffer.lastTagPosition > 0) {
int pos = mReadBuffer.getBufferPosition();
mReadBuffer.setBufferPosition(mReadBuffer.lastTagPosition);
@ -928,7 +813,7 @@ public class MapDatabase implements IMapDatabase {
System.arraycopy(tags, 0, curTags, 0, tags.length);
}
if (sMapExperimental) {
if (mTileSource.experimental) {
if (hasName) {
int textPos = mReadBuffer.readUnsignedInt();
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
@ -947,7 +832,6 @@ public class MapDatabase implements IMapDatabase {
} else {
if (hasName) {
String str = mReadBuffer.readUTF8EncodedString();
Log.d(TAG, "way name: " + str);
curTags[addTag++] = new Tag(Tag.TAG_KEY_NAME, str, false);
}
if (hasHouseNr) {
@ -1043,7 +927,7 @@ public class MapDatabase implements IMapDatabase {
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
Log.w(TAG, "invalid cumulated number of ways in row " + row + ' '
+ cumulatedNumberOfWays);
if (sMapFileHeader.getMapFileInfo().debugFile) {
if (mTileSource.fileInfo.debugFile) {
Log.w(TAG, DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
}
return null;
@ -1056,12 +940,6 @@ public class MapDatabase implements IMapDatabase {
return zoomTable;
}
@Override
public void cancel() {
// TODO Auto-generated method stub
}
private static final double PI180 = (Math.PI / 180) / 1000000.0;
private static final double PIx4 = Math.PI * 4;

View File

@ -0,0 +1,137 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2013 mapsforge.org
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.tilesource.mapfile;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.MapInfo;
import org.oscim.tilesource.TileSource;
import org.oscim.tilesource.mapfile.header.MapFileHeader;
import org.oscim.tilesource.mapfile.header.MapFileInfo;
import android.util.Log;
public class MapFileTileSource extends TileSource {
private final static String TAG = MapFileTileSource.class.getName();
/**
* Amount of cache blocks that the index cache should store.
*/
private static final int INDEX_CACHE_SIZE = 64;
private static final String READ_ONLY_MODE = "r";
MapFileHeader fileHeader;
MapFileInfo fileInfo;
IndexCache databaseIndexCache;
boolean experimental;
File mapFile;
public boolean setMapFile(String filename) {
setOption("file", filename);
File file = new File(filename);
if (!file.exists()) {
return false;
} else if (!file.isFile()) {
return false;
} else if (!file.canRead()) {
return false;
}
return true;
}
@Override
public OpenResult open() {
if (!options.containsKey("file"))
return new OpenResult("no map file set");
try {
// make sure to close any previously opened file first
//close();
File file = new File(options.get("file"));
// check if the file exists and is readable
if (!file.exists()) {
return new OpenResult("file does not exist: " + file);
} else if (!file.isFile()) {
return new OpenResult("not a file: " + file);
} else if (!file.canRead()) {
return new OpenResult("cannot read file: " + file);
}
// open the file in read only mode
RandomAccessFile mInputFile = new RandomAccessFile(file, READ_ONLY_MODE);
long mFileSize = mInputFile.length();
ReadBuffer mReadBuffer = new ReadBuffer(mInputFile);
fileHeader = new MapFileHeader();
OpenResult openResult = fileHeader.readHeader(mReadBuffer, mFileSize);
if (!openResult.isSuccess()) {
close();
return openResult;
}
fileInfo = fileHeader.getMapFileInfo();
mapFile = file;
databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
experimental = fileInfo.fileVersion == 4;
Log.d(TAG, "File version: " + fileInfo.fileVersion);
return OpenResult.SUCCESS;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
// make sure that the file is closed
close();
return new OpenResult(e.getMessage());
}
}
@Override
public ITileDataSource getDataSource() {
try {
return new MapDatabase(this);
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
return null;
}
@Override
public void close() {
fileHeader = null;
fileInfo = null;
mapFile = null;
if (databaseIndexCache != null) {
databaseIndexCache.destroy();
databaseIndexCache = null;
}
}
@Override
public MapInfo getMapInfo() {
return fileInfo;
}
}

View File

@ -12,7 +12,7 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import org.oscim.core.Tile;

View File

@ -12,10 +12,10 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import org.oscim.core.Tile;
import org.oscim.database.mapfile.header.SubFileParameter;
import org.oscim.tilesource.mapfile.header.SubFileParameter;
final class QueryCalculations {
private static int getFirstLevelTileBitmask(Tile tile) {

View File

@ -12,7 +12,7 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
class QueryParameters {
long fromBaseTileX;

View File

@ -12,7 +12,7 @@
* 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.database.mapfile;
package org.oscim.tilesource.mapfile;
import java.io.IOException;
import java.io.RandomAccessFile;

View File

@ -12,12 +12,12 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import java.io.IOException;
import org.oscim.database.IMapDatabase.OpenResult;
import org.oscim.database.mapfile.ReadBuffer;
import org.oscim.tilesource.TileSource.OpenResult;
import org.oscim.tilesource.mapfile.ReadBuffer;
/**
* Reads and validates the header data from a binary map file.

View File

@ -12,17 +12,15 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import org.oscim.core.Tag;
import org.oscim.database.mapfile.MapDatabase;
/**
* Contains the immutable metadata of a map file.
*
* @see MapDatabase#getMapInfo()
*/
public class MapFileInfo extends org.oscim.database.MapInfo {
public class MapFileInfo extends org.oscim.tilesource.MapInfo {
/**
* True if the map file includes debug information, false otherwise.

View File

@ -12,7 +12,7 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import org.oscim.core.BoundingBox;
import org.oscim.core.Tag;

View File

@ -12,11 +12,11 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import org.oscim.core.GeoPoint;
import org.oscim.database.IMapDatabase.OpenResult;
import org.oscim.database.mapfile.ReadBuffer;
import org.oscim.tilesource.TileSource.OpenResult;
import org.oscim.tilesource.mapfile.ReadBuffer;
final class OptionalFields {
/**

View File

@ -12,14 +12,14 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import java.io.IOException;
import org.oscim.core.BoundingBox;
import org.oscim.core.Tag;
import org.oscim.database.IMapDatabase.OpenResult;
import org.oscim.database.mapfile.ReadBuffer;
import org.oscim.tilesource.TileSource.OpenResult;
import org.oscim.tilesource.mapfile.ReadBuffer;
final class RequiredFields {
/**

View File

@ -12,9 +12,9 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import org.oscim.database.mapfile.Projection;
import org.oscim.tilesource.mapfile.Projection;
/**
* Holds all parameters of a sub-file.

View File

@ -12,7 +12,7 @@
* 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.database.mapfile.header;
package org.oscim.tilesource.mapfile.header;
import org.oscim.core.BoundingBox;

View File

@ -0,0 +1,62 @@
/*
* 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.tilesource.mapnik;
import java.net.URL;
import org.oscim.core.Tile;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.common.LwHttp;
import org.oscim.tilesource.common.PbfTileDataSource;
import org.oscim.tilesource.common.UrlTileSource;
public class MapnikVectorTileSource extends UrlTileSource {
@Override
public ITileDataSource getDataSource() {
return new TileDataSource(mUrl);
}
static class TileDataSource extends PbfTileDataSource {
public TileDataSource(URL url) {
super(new TileDecoder());
mConn = new LwHttp(url, "image/png", "vector.pbf", true) {
@Override
protected int formatTilePath(Tile tile, byte[] path, int pos) {
// url formatter for mapbox streets
byte[] hexTable = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
path[pos++] = '/';
path[pos++] = hexTable[(tile.tileX) % 16];
path[pos++] = hexTable[(tile.tileY) % 16];
path[pos++] = '/';
pos = LwHttp.writeInt(tile.zoomLevel, pos, path);
path[pos++] = '/';
pos = LwHttp.writeInt(tile.tileX, pos, path);
path[pos++] = '/';
pos = LwHttp.writeInt(tile.tileY, pos, path);
return pos;
}
};
}
}
}

View File

@ -12,7 +12,7 @@
* 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.database.mapnik;
package org.oscim.tilesource.mapnik;
import java.io.IOException;
@ -24,14 +24,14 @@ import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.common.ProtobufDecoder;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.Pool;
import android.util.Log;
public class TileDecoder extends ProtobufDecoder {
public class TileDecoder extends PbfDecoder {
private final static String TAG = TileDecoder.class.getName();
private static final int TAG_TILE_LAYERS = 3;
@ -65,13 +65,13 @@ public class TileDecoder extends ProtobufDecoder {
private Tile mTile;
private final String mLocale = "de";
private IMapDataSink mMapDataCallback;
private ITileDataSink mMapDataCallback;
private final static float REF_TILE_SIZE = 4096.0f;
private float mScale;
@Override
public boolean decode(Tile tile, IMapDataSink mapDataCallback, InputStream is, int contentLength)
public boolean decode(Tile tile, ITileDataSink mapDataCallback, InputStream is, int contentLength)
throws IOException {
if (debug)
Log.d(TAG, tile + " decode");

View File

@ -0,0 +1,40 @@
/*
* 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.tilesource.oscimap;
import java.net.URL;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.common.LwHttp;
import org.oscim.tilesource.common.PbfTileDataSource;
import org.oscim.tilesource.common.UrlTileSource;
/**
* Deprecated
*
*/
public class OSciMap1TileSource extends UrlTileSource {
@Override
public ITileDataSource getDataSource() {
return new TileDataSource(mUrl);
}
class TileDataSource extends PbfTileDataSource {
public TileDataSource(URL url) {
super(new TileDecoder());
mConn = new LwHttp(url, "application/osmtile", "osmtile", false);
}
}
}

View File

@ -12,7 +12,7 @@
* 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.database.oscimap;
package org.oscim.tilesource.oscimap;
import org.oscim.core.Tag;

View File

@ -12,7 +12,7 @@
* 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.database.oscimap;
package org.oscim.tilesource.oscimap;
import java.io.IOException;
import java.io.InputStream;
@ -24,12 +24,12 @@ import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.common.ProtobufDecoder;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.ITileDataSink;
import android.util.Log;
public class TileDecoder extends ProtobufDecoder {
public class TileDecoder extends PbfDecoder {
private final static String TAG = TileDecoder.class.getName();
private final static float REF_TILE_SIZE = 4096.0f;
@ -56,7 +56,7 @@ public class TileDecoder extends ProtobufDecoder {
private Tag[] curTags = new Tag[MAX_TILE_TAGS];
private int mCurTagCnt;
private IMapDataSink mSink;
private ITileDataSink mSink;
private float mScale;
private Tile mTile;
private final MapElement mElem;
@ -66,7 +66,7 @@ public class TileDecoder extends ProtobufDecoder {
}
@Override
public boolean decode(Tile tile, IMapDataSink sink, InputStream is, int contentLength)
public boolean decode(Tile tile, ITileDataSink sink, InputStream is, int contentLength)
throws IOException {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012 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
@ -12,33 +12,41 @@
* 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.database.oscimap2;
package org.oscim.tilesource.oscimap2;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.common.LwHttp;
import org.oscim.database.common.ProtobufDecoder;
import org.oscim.database.common.ProtobufMapDatabase;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.common.LwHttp;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.common.PbfTileDataSource;
import org.oscim.tilesource.common.UrlTileSource;
import android.util.Log;
/**
* Current Protocol Implementation
*/
public class MapDatabase extends ProtobufMapDatabase {
public MapDatabase() {
super(new TileDecoder());
mConn = new LwHttp("application/osmtile", "osmtile", false);
public class OSciMap2TileSource extends UrlTileSource {
@Override
public ITileDataSource getDataSource() {
return new TileDataSource(mUrl);
}
static class TileDecoder extends ProtobufDecoder {
class TileDataSource extends PbfTileDataSource {
public TileDataSource(URL url) {
super(new TileDecoder());
mConn = new LwHttp(url, "application/osmtile", "osmtile", false);
}
}
static class TileDecoder extends PbfDecoder {
private final static String TAG = TileDecoder.class.getName();
private static final int TAG_TILE_NUM_TAGS = 1;
private static final int TAG_TILE_TAG_KEYS = 2;
@ -74,7 +82,7 @@ public class MapDatabase extends ProtobufMapDatabase {
private final MapElement mElem;
private IMapDataSink mMapDataSink;
private ITileDataSink mMapDataSink;
TileDecoder() {
mElem = new MapElement();
@ -88,7 +96,7 @@ public class MapDatabase extends ProtobufMapDatabase {
}
@Override
public boolean decode(Tile tile, IMapDataSink sink, InputStream is, int contentLength)
public boolean decode(Tile tile, ITileDataSink sink, InputStream is, int contentLength)
throws IOException {
int byteCount = readUnsignedInt(is, buffer);

View File

@ -12,7 +12,7 @@
* 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.database.oscimap2;
package org.oscim.tilesource.oscimap2;
import org.oscim.core.Tag;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012 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
@ -12,18 +12,26 @@
* 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.database.oscimap4;
package org.oscim.tilesource.oscimap4;
import org.oscim.database.common.LwHttp;
import org.oscim.database.common.ProtobufMapDatabase;
import java.net.URL;
/**
* Protocol Version in Development
*/
public class MapDatabase extends ProtobufMapDatabase {
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.common.LwHttp;
import org.oscim.tilesource.common.PbfTileDataSource;
import org.oscim.tilesource.common.UrlTileSource;
public MapDatabase() {
super(new TileDecoder());
mConn = new LwHttp("application/x-protobuf", "vtm", false);
public class OSciMap4TileSource extends UrlTileSource {
@Override
public ITileDataSource getDataSource() {
return new TileDataSource(mUrl);
}
class TileDataSource extends PbfTileDataSource {
public TileDataSource(URL url) {
super(new TileDecoder());
mConn = new LwHttp(url, "application/x-protobuf", "vtm", false);
}
}
}

View File

@ -12,7 +12,7 @@
* 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.database.oscimap4;
package org.oscim.tilesource.oscimap4;
public class Tags {
// TODO this should be retrieved from tile 0/0/0

View File

@ -12,7 +12,7 @@
* 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.database.oscimap4;
package org.oscim.tilesource.oscimap4;
import java.io.IOException;
import java.io.InputStream;
@ -23,12 +23,12 @@ import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.database.IMapDataSink;
import org.oscim.database.common.ProtobufDecoder;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.ITileDataSink;
import android.util.Log;
public class TileDecoder extends ProtobufDecoder {
public class TileDecoder extends PbfDecoder {
private final static String TAG = TileDecoder.class.getName();
private static final int TAG_TILE_VERSION = 1;
@ -66,7 +66,7 @@ public class TileDecoder extends ProtobufDecoder {
private final Tag[][] mElementTags;
private final TagSet curTags = new TagSet(100);
private IMapDataSink mMapDataSink;
private ITileDataSink mMapDataSink;
// scale coordinates to tile size
private final static float REF_TILE_SIZE = 4096.0f;
private final float mScaleFactor = REF_TILE_SIZE / Tile.SIZE;
@ -83,7 +83,7 @@ public class TileDecoder extends ProtobufDecoder {
}
@Override
public boolean decode(Tile tile, IMapDataSink sink, InputStream is, int contentLength)
public boolean decode(Tile tile, ITileDataSink sink, InputStream is, int contentLength)
throws IOException {
int byteCount = readUnsignedInt(is, buffer);

View File

@ -12,23 +12,22 @@
* 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.database.test;
package org.oscim.tilesource.test;
import org.oscim.core.BoundingBox;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDataSink;
import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions;
import org.oscim.layers.tile.MapTile;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
import org.oscim.tilesource.MapInfo;
/**
*
*
*/
public class MapDatabase implements IMapDatabase {
public class TestTileSource implements ITileDataSource {
private final Tag[] mTags = {
new Tag("natural", "water")
@ -51,11 +50,11 @@ public class MapDatabase implements IMapDatabase {
new Byte((byte) 5), null, null, 0, 0, 0,
"", "", "", null);
private boolean mOpenFile = false;
private final boolean mOpenFile = false;
private final MapElement mElem;
public MapDatabase() {
public TestTileSource() {
mElem = new MapElement();
}
@ -65,7 +64,7 @@ public class MapDatabase implements IMapDatabase {
@Override
public QueryResult executeQuery(MapTile tile,
IMapDataSink mapDataSink) {
ITileDataSink mapDataSink) {
int size = Tile.SIZE;
MapElement e = mElem;
@ -164,34 +163,32 @@ public class MapDatabase implements IMapDatabase {
return QueryResult.SUCCESS;
}
@Override
public String getMapProjection() {
return null;
}
// @Override
// public boolean isOpen() {
// return mOpenFile;
// }
//
// @Override
// public OpenResult open(MapOptions options) {
// mOpenFile = true;
// return OpenResult.SUCCESS;
// }
//
// @Override
// public void close() {
// mOpenFile = false;
// }
//
// @Override
// public void cancel() {
// }
@Override
public MapInfo getMapInfo() {
return mMapInfo;
}
public void destroy() {
// TODO Auto-generated method stub
@Override
public boolean isOpen() {
return mOpenFile;
}
@Override
public OpenResult open(MapOptions options) {
mOpenFile = true;
return OpenResult.SUCCESS;
}
@Override
public void close() {
mOpenFile = false;
}
@Override
public void cancel() {
}
}

View File

@ -21,7 +21,6 @@ import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.database.MapOptions;
import org.oscim.layers.Layer;
import org.oscim.layers.MapEventLayer;
import org.oscim.layers.overlay.BuildingOverlay;
@ -31,6 +30,7 @@ import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.layers.tile.vector.MapTileLayer;
import org.oscim.layers.tile.vector.MapTileLoader;
import org.oscim.renderer.GLView;
import org.oscim.tilesource.TileSource;
import android.content.Context;
import android.util.AttributeSet;
@ -138,10 +138,10 @@ public class MapView extends RelativeLayout {
redrawMap(false);
}
public MapTileLayer setBaseMap(MapOptions options) {
public MapTileLayer setBaseMap(TileSource tileSource) {
MapTileLayer baseLayer = new MapTileLayer(this);
baseLayer.setMapDatabase(options);
baseLayer.setTileSource(tileSource);
mLayerManager.add(0, new MapEventLayer(this));
@ -211,7 +211,7 @@ public class MapView extends RelativeLayout {
mWidth = width;
mHeight = height;
mInitialized = (mWidth > 0 && mWidth > 0);
mInitialized = (mWidth > 0 && mHeight > 0);
if (mInitialized)
mMapViewPosition.setViewport(width, height);