- adding MapDatabase backend for our TileStache provider

- fixing some renering bugs on nexus phone
and some refactoring and cleanup
This commit is contained in:
Hannes Janetzek
2012-08-07 03:04:39 +02:00
parent c5c952bf14
commit 124624785d
43 changed files with 2287 additions and 1779 deletions

View File

@@ -62,6 +62,8 @@ public interface IMapDatabase {
*/
public abstract FileOpenResult openFile(File mapFile);
public abstract String getMapProjection();
/**
* @param position
* ....
@@ -69,4 +71,4 @@ public interface IMapDatabase {
*/
public abstract String readString(int position);
}
}

View File

@@ -31,13 +31,14 @@ import org.mapsforge.database.MapFileInfo;
*/
public class MapDatabase implements IMapDatabase {
private final static String PROJECTION = "Mercator";
private float[] mCoords = new float[20];
private int[] mIndex = new int[1];
private int[] mIndex = new int[2];
// private Tag[] mTags = { new Tag("boundary", "administrative"), new Tag("admin_level", "2") };
private Tag[] mTags = { new Tag("building", "yes") };
private Tag[] mTags = { new Tag("natural", "water") };
private final MapFileInfo mMapInfo =
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
new Byte((byte) 0), null, "Mercator", 0, 0, 0, "de", "yo!", "by me");
new Byte((byte) 0), null, PROJECTION, 0, 0, 0, "de", "yo!", "by me");
private boolean mOpenFile = false;
@@ -95,10 +96,10 @@ public class MapDatabase implements IMapDatabase {
//
// mIndex[0] = 10;
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 80, tile.zoomLevel) * 1000000;
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 80, tile.zoomLevel) * 1000000;
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 80, tile.zoomLevel) * 1000000;
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 80, tile.zoomLevel) * 1000000;
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 139, tile.zoomLevel) * 1000000;
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 139, tile.zoomLevel) * 1000000;
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 139, tile.zoomLevel) * 1000000;
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 139, tile.zoomLevel) * 1000000;
mCoords[0] = lon1;
mCoords[1] = lat1;
@@ -117,9 +118,35 @@ public class MapDatabase implements IMapDatabase {
mIndex[0] = 10;
lon1 = (float) MercatorProjection.pixelXToLongitude(cx - 119, tile.zoomLevel) * 1000000;
lon2 = (float) MercatorProjection.pixelXToLongitude(cx + 119, tile.zoomLevel) * 1000000;
lat1 = (float) MercatorProjection.pixelYToLatitude(cy - 119, tile.zoomLevel) * 1000000;
lat2 = (float) MercatorProjection.pixelYToLatitude(cy + 119, tile.zoomLevel) * 1000000;
mCoords[10] = lon1;
mCoords[11] = lat1;
mCoords[12] = lon2;
mCoords[13] = lat1;
mCoords[14] = lon2;
mCoords[15] = lat2;
mCoords[16] = lon1;
mCoords[17] = lat2;
mCoords[18] = lon1;
mCoords[19] = lat1;
mIndex[1] = 10;
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
}
@Override
public String getMapProjection() {
return PROJECTION;
}
@Override
public MapFileInfo getMapFileInfo() {
return mMapInfo;

View File

@@ -177,11 +177,13 @@ public class MapDatabase implements IMapDatabase {
*/
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;
private IndexCache mDatabaseIndexCache;
private static IndexCache sDatabaseIndexCache;
private static MapFileHeader sMapFileHeader;
private static int instances = 0;
private long mFileSize;
private boolean mDebugFile;
private RandomAccessFile mInputFile;
private MapFileHeader mMapFileHeader;
private ReadBuffer mReadBuffer;
private String mSignatureBlock;
private String mSignaturePoi;
@@ -193,31 +195,6 @@ public class MapDatabase implements IMapDatabase {
private float[] mWayNodes = new float[100000];
private int mWayNodePosition;
/*
* (non-Javadoc)
* @see org.mapsforge.map.reader.IMapDatabase#closeFile()
*/
@Override
public void closeFile() {
try {
mMapFileHeader = null;
if (mDatabaseIndexCache != null) {
mDatabaseIndexCache.destroy();
mDatabaseIndexCache = null;
}
if (mInputFile != null) {
mInputFile.close();
mInputFile = null;
}
mReadBuffer = null;
} catch (IOException e) {
LOG.log(Level.SEVERE, null, e);
}
}
private int minLat, minLon;
/*
@@ -227,7 +204,7 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
if (mMapFileHeader == null)
if (sMapFileHeader == null)
return;
if (mIntBuffer == null)
@@ -235,29 +212,13 @@ public class MapDatabase implements IMapDatabase {
mWayNodePosition = 0;
// if (tile.zoomLevel < 10) {
// // reduce small nodes with distance smaller min pixel
// int min = 1;
// long cx = tile.getPixelX() + (Tile.TILE_SIZE >> 1);
// long cy = tile.getPixelY() + (Tile.TILE_SIZE >> 1);
// double l1 = MercatorProjection.pixelXToLongitude(cx, tile.zoomLevel);
// double l2 = MercatorProjection.pixelXToLongitude(cx + min, tile.zoomLevel);
// minLon = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
// l1 = MercatorProjection.pixelYToLatitude(cy, tile.zoomLevel);
// l2 = MercatorProjection.pixelYToLatitude(cy + min, tile.zoomLevel);
// minLat = (int) Math.abs((l1 * 1000000.0) - (l2 * 1000000.0));
// } else {
minLat = 0;
minLon = 0;
// }
try {
prepareExecution();
// prepareExecution();
QueryParameters queryParameters = new QueryParameters();
queryParameters.queryZoomLevel = mMapFileHeader
queryParameters.queryZoomLevel = sMapFileHeader
.getQueryZoomLevel(tile.zoomLevel);
// get and check the sub-file for the query zoom level
SubFileParameter subFileParameter = mMapFileHeader
SubFileParameter subFileParameter = sMapFileHeader
.getSubFileParameter(queryParameters.queryZoomLevel);
if (subFileParameter == null) {
LOG.warning("no sub-file for zoom level: "
@@ -279,10 +240,15 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public MapFileInfo getMapFileInfo() {
if (mMapFileHeader == null) {
if (sMapFileHeader == null) {
throw new IllegalStateException("no map file is currently opened");
}
return mMapFileHeader.getMapFileInfo();
return sMapFileHeader.getMapFileInfo();
}
@Override
public String getMapProjection() {
return getMapFileInfo().projectionName;
}
/*
@@ -300,6 +266,7 @@ public class MapDatabase implements IMapDatabase {
*/
@Override
public FileOpenResult openFile(File mapFile) {
try {
if (mapFile == null) {
// throw new IllegalArgumentException("mapFile must not be null");
@@ -323,14 +290,23 @@ public class MapDatabase implements IMapDatabase {
mFileSize = mInputFile.length();
mReadBuffer = new ReadBuffer(mInputFile);
mMapFileHeader = new MapFileHeader();
FileOpenResult fileOpenResult = mMapFileHeader.readHeader(mReadBuffer,
if (instances > 0) {
instances++;
return FileOpenResult.SUCCESS;
}
sMapFileHeader = new MapFileHeader();
FileOpenResult fileOpenResult = sMapFileHeader.readHeader(mReadBuffer,
mFileSize);
if (!fileOpenResult.isSuccess()) {
closeFile();
return fileOpenResult;
}
prepareExecution();
instances++;
return FileOpenResult.SUCCESS;
} catch (IOException e) {
LOG.log(Level.SEVERE, null, e);
@@ -340,6 +316,37 @@ public class MapDatabase implements IMapDatabase {
}
}
/*
* (non-Javadoc)
* @see org.mapsforge.map.reader.IMapDatabase#closeFile()
*/
@Override
public void closeFile() {
instances--;
if (instances > 0) {
mReadBuffer = null;
return;
}
try {
sMapFileHeader = null;
if (sDatabaseIndexCache != null) {
sDatabaseIndexCache.destroy();
sDatabaseIndexCache = null;
}
if (mInputFile != null) {
mInputFile.close();
mInputFile = null;
}
mReadBuffer = null;
} catch (IOException e) {
LOG.log(Level.SEVERE, null, e);
}
}
/**
* Logs the debug signatures of the current way and block.
*/
@@ -351,8 +358,8 @@ public class MapDatabase implements IMapDatabase {
}
private void prepareExecution() {
if (mDatabaseIndexCache == null) {
mDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
if (sDatabaseIndexCache == null) {
sDatabaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
}
}
@@ -436,7 +443,7 @@ public class MapDatabase implements IMapDatabase {
long blockNumber = row * subFileParameter.blocksWidth + column;
// get the current index entry
long currentBlockIndexEntry = mDatabaseIndexCache.getIndexEntry(
long currentBlockIndexEntry = sDatabaseIndexCache.getIndexEntry(
subFileParameter, blockNumber);
// check if the current query would still return a water tile
@@ -462,7 +469,7 @@ public class MapDatabase implements IMapDatabase {
nextBlockPointer = subFileParameter.subFileSize;
} else {
// get and check the next block pointer
nextBlockPointer = mDatabaseIndexCache.getIndexEntry(
nextBlockPointer = sDatabaseIndexCache.getIndexEntry(
subFileParameter, blockNumber + 1)
& BITMASK_INDEX_OFFSET;
if (nextBlockPointer < 1
@@ -559,7 +566,7 @@ public class MapDatabase implements IMapDatabase {
* @return true if the POIs could be processed successfully, false otherwise.
*/
private boolean processPOIs(IMapDatabaseCallback mapDatabaseCallback, int numberOfPois) {
Tag[] poiTags = mMapFileHeader.getMapFileInfo().poiTags;
Tag[] poiTags = sMapFileHeader.getMapFileInfo().poiTags;
Tag[] tags = null;
for (int elementCounter = numberOfPois; elementCounter != 0; --elementCounter) {
@@ -778,7 +785,7 @@ public class MapDatabase implements IMapDatabase {
int numberOfWays) {
Tag[] tags = null;
Tag[] wayTags = mMapFileHeader.getMapFileInfo().wayTags;
Tag[] wayTags = sMapFileHeader.getMapFileInfo().wayTags;
int[] textPos = new int[3];
// float[] labelPosition;
boolean skippedWays = false;
@@ -957,7 +964,7 @@ public class MapDatabase implements IMapDatabase {
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
LOG.warning("invalid cumulated number of ways in row " + row + ' '
+ cumulatedNumberOfWays);
if (mMapFileHeader.getMapFileInfo().debugFile) {
if (sMapFileHeader.getMapFileInfo().debugFile) {
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
}
return null;

View File

@@ -0,0 +1,513 @@
/*
* Copyright 2012 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mapsforge.database.pbmap;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicHeader;
import org.mapsforge.core.BoundingBox;
import org.mapsforge.core.GeoPoint;
import org.mapsforge.core.Tag;
import org.mapsforge.core.Tile;
import org.mapsforge.core.WebMercator;
import org.mapsforge.database.FileOpenResult;
import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.IMapDatabaseCallback;
import org.mapsforge.database.MapFileInfo;
import android.net.http.AndroidHttpClient;
import android.util.Log;
/**
*
*
*/
public class MapDatabase implements IMapDatabase {
private static final String TAG = "MapDatabase";
private static final MapFileInfo mMapInfo =
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
WebMercator.NAME, 0, 0, 0, "de", "comment", "author");
private boolean mOpenFile = false;
// private static final String URL = "http://city.informatik.uni-bremen.de:8020/test/%d/%d/%d.osmtile";
private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/test/%d/%d/%d.osmtile";
private static final Header encodingHeader =
new BasicHeader("Accept-Encoding", "gzip");
private static volatile HashMap<String, Tag> tagHash = new HashMap<String, Tag>(100);
private Tag[] curTags = new Tag[1000];
private int mCurTagCnt;
private AndroidHttpClient mClient;
private IMapDatabaseCallback mMapGenerator;
private float mScaleFactor;
@Override
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
String url = String.format(URL, Integer.valueOf(tile.zoomLevel),
Long.valueOf(tile.tileX), Long.valueOf(tile.tileY));
HttpGet getRequest = new HttpGet(url);
getRequest.addHeader(encodingHeader);
mMapGenerator = mapDatabaseCallback;
mCurTagCnt = 0;
// using variable coordinate scalefactor to take advantage of
// variable byte encoded integers
mScaleFactor = 1 / 100f;
if (tile.zoomLevel < 12)
mScaleFactor = (float) Math.pow(2, (12 - tile.zoomLevel)) / 100f;
try {
HttpResponse response = mClient.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.d(TAG, "Http response " + statusCode);
return;
}
final HttpEntity entity = response.getEntity();
if (entity == null) {
Log.d(TAG, "Somethings wrong? - no entity " + statusCode);
return;
}
InputStream is = null;
GZIPInputStream zis = null;
try {
is = entity.getContent();
zis = new GZIPInputStream(is);
decode(zis);
} finally {
if (zis != null)
zis.close();
if (is != null)
is.close();
entity.consumeContent();
}
} catch (Exception ex) {
getRequest.abort();
ex.printStackTrace();
}
}
@Override
public String getMapProjection() {
return WebMercator.NAME;
}
@Override
public MapFileInfo getMapFileInfo() {
return mMapInfo;
}
@Override
public boolean hasOpenFile() {
return mOpenFile;
}
@Override
public FileOpenResult openFile(File mapFile) {
mOpenFile = true;
mClient = AndroidHttpClient.newInstance("Android");
return new FileOpenResult();
}
@Override
public void closeFile() {
mOpenFile = false;
if (mClient != null)
mClient.close();
}
@Override
public String readString(int position) {
return null;
}
private static final int BUFFER_SIZE = 32768;
private final byte[] buffer = new byte[BUFFER_SIZE];
private int bufferPos;
private int bufferSize;
private InputStream inputStream;
private static final int TAG_TILE_TAGS = 1;
private static final int TAG_TILE_WAYS = 2;
private static final int TAG_TILE_NODES = 3;
private static final int TAG_WAY_TAGS = 1;
private static final int TAG_WAY_INDEX = 2;
private static final int TAG_WAY_COORDS = 3;
// private static final int TAG_NODE_TAGS = 1;
// private static final int TAG_NODE_COORDS = 2;
private int bytesRead;
private boolean decode(InputStream is) throws IOException {
inputStream = is;
bytesRead = 0;
bufferSize = 0;
bufferPos = 0;
while (true) {
// read tag and wire type
int val = decodeVarint32();
if (val == 0) {
// Log.d(TAG, "EOF, all good");
return true;
}
int tag = (val >> 3);
// int wireType = (val & 7);
// Log.d(TAG, "tile " + tag + " " + wireType);
switch (tag) {
case TAG_TILE_TAGS:
decodeTileTags();
break;
case TAG_TILE_WAYS:
decodeTileWays();
break;
case TAG_TILE_NODES:
decodeTileNodes();
break;
default:
Log.d(TAG, "invalid type for tile: " + tag);
return false;
}
}
}
private boolean decodeTileTags() throws IOException {
String tagString = decodeString();
Tag tag = tagHash.get(tagString);
if (tag == null) {
tag = new Tag(tagString);
tagHash.put(tagString, tag);
}
curTags[mCurTagCnt++] = tag;
// Log.d(TAG, "tag:" + tag);
return true;
}
private boolean decodeTileWays() throws IOException {
int bytes = decodeVarint32();
int end = bytesRead + bytes;
int indexCnt = 0;
int tagCnt = 0;
int coordCnt = 0;
while (bytesRead < end) {
// read tag and wire type
int val = decodeVarint32();
if (val == 0)
break;
int tag = (val >> 3);
// int wireType = val & 7;
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
switch (tag) {
case TAG_WAY_TAGS:
tagCnt = decodeWayTags();
break;
case TAG_WAY_INDEX:
indexCnt = decodeWayIndices();
break;
case TAG_WAY_COORDS:
coordCnt = decodeWayCoordinates();
break;
default:
Log.d(TAG, "invalid type for way: " + tag);
}
}
if (indexCnt == 0 || tagCnt == 0)
return false;
int[] index = new int[indexCnt];
int sum = 0;
for (int i = 0; i < indexCnt; i++) {
index[i] = tmpIndices[i] * 2;
sum += index[i];
}
Tag[] tags = new Tag[tagCnt];
for (int i = 0; i < tagCnt; i++)
tags[i] = curTags[tmpTags[i]];
float[] coords = tmpCoords;
int pos = 0;
if (coordCnt != sum) {
Log.d(TAG, "way length is wrong " + coordCnt + " " + sum);
return false;
}
float z = mScaleFactor;
for (int j = 0, m = indexCnt; j < m; j++) {
float lastX = 0;
float lastY = 0;
for (int n = index[j] + pos; pos < n; pos += 2) {
lastX = coords[pos] = (coords[pos] * z) + lastX;
lastY = coords[pos + 1] = (coords[pos + 1] * z) + lastY;
}
}
mMapGenerator.renderWay((byte) 0, tags, coords, index, true);
return true;
}
private boolean decodeTileNodes() throws IOException {
int bytes = decodeVarint32();
Log.d(TAG, "way nodes " + bytes);
return true;
}
private int MAX_WAY_COORDS = 32768;
private int MAX_WAY_INDICES = 1000;
private int[] tmpTags = new int[32];
private int[] tmpIndices = new int[MAX_WAY_INDICES];
private float[] tmpCoords = new float[MAX_WAY_COORDS];
// private boolean ensureBufferSize(int size) throws IOException {
// if (size > (bufferSize - bufferPos))
// readBuffer(size - (bufferSize - bufferPos));
//
// return true;
// }
private int decodeWayTags() throws IOException {
int bytes = decodeVarint32();
// Log.d(TAG, "way tags: " + bytes);
int cnt = 0;
int end = bytesRead + bytes;
while (bytesRead < end)
tmpTags[cnt++] = decodeVarint32();
return cnt;
}
private int decodeWayIndices() throws IOException {
int bytes = decodeVarint32();
// Log.d(TAG, "way indices: " + bytes);
int cnt = 0;
int end = bytesRead + bytes;
while (bytesRead < end) {
int val = decodeVarint32();
if (cnt >= MAX_WAY_INDICES) {
MAX_WAY_INDICES += 128;
Log.d(TAG, "increase indices array " + MAX_WAY_INDICES);
int[] tmp = new int[MAX_WAY_INDICES];
System.arraycopy(tmpIndices, 0, tmp, 0, cnt);
tmpIndices = tmp;
}
tmpIndices[cnt++] = val;
}
return cnt;
}
private int decodeWayCoordinates() throws IOException {
int bytes = decodeVarint32();
int cnt = 0;
int end = bytesRead + bytes;
while (bytesRead < end) {
int val = decodeZigZag32(decodeVarint32());
if (cnt >= MAX_WAY_COORDS) {
MAX_WAY_COORDS += 128;
Log.d(TAG, "increase coords array " + MAX_WAY_COORDS);
float[] tmp = new float[MAX_WAY_COORDS];
System.arraycopy(tmpCoords, 0, tmp, 0, cnt);
tmpCoords = tmp;
}
tmpCoords[cnt++] = val;
}
return cnt;
}
private void readBuffer() throws IOException {
int len = inputStream.read(buffer, 0, BUFFER_SIZE);
if (len < 0) {
buffer[bufferPos] = 0;
// Log.d(TAG, " nothing to read... pos " + bufferPos + ", size "
// + bufferSize + ", read " + bytesRead);
return;
}
bufferSize = len;
bufferPos = 0;
// Log.d(TAG, "pos " + bufferPos + ", size " + bufferSize + ", read "
// + bytesRead);
}
private void readBuffer(int size) throws IOException {
if (size < (bufferSize - bufferPos))
return;
if (size > BUFFER_SIZE) {
Log.d(TAG, "EEEK too large");
// FIXME throw exception, but frankly better sanitize tile data on compilation
// this only happen with Strings larger than 32kb
return;
}
if ((size - bufferSize) + bufferPos > BUFFER_SIZE) {
// copy bytes left to read from buffer to the beginning of buffer
System.arraycopy(buffer, bufferPos, buffer, 0, bufferSize - bufferPos);
bufferPos = 0;
}
while ((bufferSize - bufferPos) < size) {
// read until requested size is available in buffer
int len = inputStream.read(buffer, bufferSize, BUFFER_SIZE - bufferSize);
if (len < 0) {
buffer[bufferSize - 1] = 0; // FIXME is this needed?
break;
}
bufferSize += len;
}
// Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
// + bufferSize
// + ", read " + bytesRead);
}
/* All code below is taken from or based on Google's Protocol Buffers implementation: */
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
private byte readRawByte() throws IOException {
if (bufferPos == bufferSize) {
readBuffer();
}
bytesRead++;
return buffer[bufferPos++];
}
private int decodeVarint32() throws IOException {
byte tmp = readRawByte();
if (tmp >= 0) {
return tmp;
}
int result = tmp & 0x7f;
if ((tmp = readRawByte()) >= 0) {
return result | tmp << 7;
}
result |= (tmp & 0x7f) << 7;
if ((tmp = readRawByte()) >= 0) {
return result | tmp << 14;
}
result |= (tmp & 0x7f) << 14;
if ((tmp = readRawByte()) >= 0) {
return result | tmp << 21;
}
result |= (tmp & 0x7f) << 21;
result |= (tmp = readRawByte()) << 28;
if (tmp < 0) {
// Discard upper 32 bits.
for (int i = 0; i < 5; i++) {
if (readRawByte() >= 0) {
return result;
}
}
Log.d(TAG, "EEK malformedVarint");
// FIXME throw some poo
}
return result;
}
private String decodeString() throws IOException {
final int size = decodeVarint32();
readBuffer(size);
final String result = new String(buffer, bufferPos, size, "UTF-8");
bufferPos += size;
bytesRead += size;
return result;
}
public static int decodeZigZag32(final int n) {
return (n >>> 1) ^ -(n & 1);
}
}

View File

@@ -26,9 +26,9 @@ import java.util.Properties;
import org.mapsforge.core.BoundingBox;
import org.mapsforge.core.GeoPoint;
import org.mapsforge.core.WebMercator;
import org.mapsforge.core.Tag;
import org.mapsforge.core.Tile;
import org.mapsforge.core.WebMercator;
import org.mapsforge.database.FileOpenResult;
import org.mapsforge.database.IMapDatabase;
import org.mapsforge.database.IMapDatabaseCallback;
@@ -40,7 +40,7 @@ import org.postgresql.PGConnection;
*
*/
public class MapDatabase implements IMapDatabase {
private static final String QUERY = "SELECT * FROM __get_tile(?,?,?)";
private static final String QUERY = "SELECT tags, geom FROM __get_tile(?,?,?)";
private final float mScale = 1; // 1000000.0f;
@@ -55,16 +55,13 @@ public class MapDatabase implements IMapDatabase {
new MapFileInfo(new BoundingBox(-180, -85, 180, 85),
new Byte((byte) 14), new GeoPoint(53.11, 8.85),
WebMercator.NAME,
0, 0, 0, "de", "yo!", "hannes");
// new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
// new Byte((byte) 0), null, "Mercator",
// 0, 0, 0, "de", "yo!", "by me");
0, 0, 0, "de", "comment", "author");
private boolean mOpenFile = false;
private Connection connection = null;
private static HashMap<Entry<String, String>, Tag> tagHash = new HashMap<Entry<String, String>, Tag>(
100);
private static volatile HashMap<Entry<String, String>, Tag> tagHash =
new HashMap<Entry<String, String>, Tag>(100);
private PreparedStatement prepQuery = null;
private boolean connect() {
@@ -123,7 +120,6 @@ public class MapDatabase implements IMapDatabase {
byte[] b = null;
PGHStore h = null;
// long id;
try {
while (r != null && r.next()) {
@@ -131,9 +127,7 @@ public class MapDatabase implements IMapDatabase {
mCoordPos = 0;
try {
// id = r.getLong(1);
Object obj = r.getObject(2);
Object obj = r.getObject(1);
h = null;
if (obj instanceof PGHStore)
@@ -141,7 +135,7 @@ public class MapDatabase implements IMapDatabase {
else
continue;
b = r.getBytes(3);
b = r.getBytes(2);
} catch (SQLException e) {
e.printStackTrace();
@@ -184,6 +178,11 @@ public class MapDatabase implements IMapDatabase {
}
}
@Override
public String getMapProjection() {
return WebMercator.NAME;
}
@Override
public MapFileInfo getMapFileInfo() {
return mMapInfo;