use TagSet instead of Tag[] in MapElement

This commit is contained in:
Hannes Janetzek 2013-06-12 02:52:23 +02:00
parent 0ed0d1a154
commit 48369f6baf
11 changed files with 205 additions and 241 deletions

View File

@ -24,19 +24,12 @@ package org.oscim.core;
*/
public class MapElement extends GeometryBuffer {
// osm layer of the way.
public int layer;
// osm tags of the way.
public Tag[] tags;
//public Tag[] tags;
// ---- random stuff, to be removed ----
// building tags
public int height;
public int minHeight;
public int priority;
public final TagSet tags = new TagSet();
public MapElement() {
super(1024, 16);
@ -46,8 +39,18 @@ public class MapElement extends GeometryBuffer {
super(points, indices);
}
public void set(Tag[] tags, int layer) {
public void setLayer(int layer) {
this.layer = layer;
this.tags = tags;
//this.tags = tags;
}
@Override
public void clear() {
super.clear();
}
// ---- random stuff, to be removed ----
// building tags
public int height;
public int minHeight;
public int priority;
}

View File

@ -16,12 +16,11 @@ package org.oscim.layers.tile.vector;
import static org.oscim.layers.tile.MapTile.STATE_NONE;
import java.util.Arrays;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
@ -261,10 +260,11 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
// only with different name.
// Maybe this should be done within RenderTheme, also allowing
// to set these replacement rules in theme file.
private boolean filterTags(Tag[] tags) {
private boolean filterTags(TagSet in) {
mRenderBuildingModel = false;
Tag[] tags = in.tags;
for (int i = 0; i < tags.length; i++) {
for (int i = 0; i < in.numTags; i++) {
String key = tags[i].key;
if (tags[i].key == Tag.TAG_KEY_NAME) {
if (tags[i].value != null) {
@ -337,17 +337,16 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
mElement = null;
}
private void debugUnmatched(boolean closed, Tag[] tags) {
Log.d(TAG, "DBG way not matched: " + closed + " "
+ Arrays.deepToString(tags));
mTagName = new Tag("name", tags[0].key + ":"
+ tags[0].value, false);
mElement.tags = closed ? debugTagArea : debugTagWay;
RenderInstruction[] ri = renderTheme.matchElement(mElement, mTile.zoomLevel);
renderWay(ri);
private void debugUnmatched(boolean closed, TagSet tags) {
// Log.d(TAG, "DBG way not matched: " + closed + " "
// + Arrays.deepToString(tags));
//
// mTagName = new Tag("name", tags[0].key + ":"
// + tags[0].value, false);
//
// mElement.tags = closed ? debugTagArea : debugTagWay;
// RenderInstruction[] ri = renderTheme.matchElement(mElement, mTile.zoomLevel);
// renderWay(ri);
}
private void renderWay(RenderInstruction[] ri) {

View File

@ -15,6 +15,7 @@
package org.oscim.theme;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
class MatchingCacheKey {
int mHash;
@ -24,34 +25,38 @@ class MatchingCacheKey {
}
MatchingCacheKey(MatchingCacheKey key) {
// need to clone tags as they belong to TileDataSource
mTags = key.mTags.clone();
mTags = key.mTags;
mHash = key.mHash;
}
// set temporary values for comparison
boolean set(Tag[] tags, MatchingCacheKey compare) {
int length = tags.length;
boolean set(TagSet tags, MatchingCacheKey compare) {
int numTags = tags.numTags;
if (compare != null && length == compare.mTags.length) {
if (compare != null && numTags == compare.mTags.length) {
int i = 0;
for (; i < length; i++) {
Tag t1 = tags[i];
for (; i < numTags; i++) {
Tag t1 = tags.tags[i];
Tag t2 = compare.mTags[i];
if (!(t1 == t2 || (t1.key == t2.key && t1.value == t2.value)))
break;
}
if (i == length)
if (i == numTags)
return true;
}
// need to clone tags as they belong to TileDataSource
mTags = new Tag[numTags];
int result = 7;
for (int i = 0; i < length; i++)
result = 31 * result + tags[i].hashCode();
for (int i = 0; i < numTags; i++){
Tag t = tags.tags[i];
result = 31 * result + t.hashCode();
mTags[i] = t;
}
mHash = 31 * result;
mTags = tags;
return false;
}

View File

@ -105,6 +105,9 @@ public class RenderTheme implements IRenderTheme {
cacheKey = new MatchingCacheKey();
matchType = type;
}
RenderInstructionItem getRenderInstructions(){
return cache.get(cacheKey);
}
}
class RenderInstructionItem {
@ -200,7 +203,8 @@ public class RenderTheme implements IRenderTheme {
}
if (ri == null) {
ris = cache.cache.get(cache.cacheKey);
// get instruction for current cacheKey
ris = cache.getRenderInstructions();
for (ri = ris; ri != null; ri = ri.next)
if ((ri.zoom & zoomMask) != 0)
@ -216,7 +220,7 @@ public class RenderTheme implements IRenderTheme {
matches.clear();
for (Rule rule : mRules)
rule.matchElement(cache.matchType, element.tags, zoomMask, matches);
rule.matchElement(cache.matchType, cache.cacheKey.mTags, zoomMask, matches);
int size = matches.size();
if (size > 1) {
@ -225,7 +229,7 @@ public class RenderTheme implements IRenderTheme {
for (int j = i + 1; j < size; j++) {
if (matches.get(j) == r) {
Log.d(TAG, "fix duplicate instruction! "
+ Arrays.deepToString(element.tags)
+ Arrays.deepToString(cache.cacheKey.mTags)
+ ":" + zoomLevel);
matches.remove(j--);
size--;

View File

@ -471,8 +471,7 @@ public class MapDatabase implements ITileDataSource {
*/
private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois) {
Tag[] poiTags = mTileSource.fileInfo.poiTags;
Tag[] tags = null;
Tag[] curTags;
int numTags = 0;
long x = mTile.tileX * Tile.SIZE;
long y = mTile.tileY * Tile.SIZE + Tile.SIZE;
@ -510,13 +509,14 @@ public class MapDatabase implements ITileDataSource {
byte numberOfTags = (byte) (specialByte & POI_NUMBER_OF_TAGS_BITMASK);
if (numberOfTags != 0) {
tags = mReadBuffer.readTags(poiTags, numberOfTags);
if (!mReadBuffer.readTags(mElem.tags, poiTags, numberOfTags))
return false;
numTags = numberOfTags;
}
if (tags == null)
return false;
curTags = tags;
// reset to common tag position
mElem.tags.numTags = numTags;
// get the feature bitmask (1 byte)
byte featureByte = mReadBuffer.readByte();
@ -525,10 +525,7 @@ public class MapDatabase implements ITileDataSource {
// check if the POI has a name
if ((featureByte & POI_FEATURE_NAME) != 0) {
String str = mReadBuffer.readUTF8EncodedString();
curTags = new Tag[tags.length + 1];
System.arraycopy(tags, 0, curTags, 0, tags.length);
curTags[tags.length] = new Tag(Tag.TAG_KEY_NAME, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_NAME, str, false));
}
// check if the POI has a house number
@ -551,18 +548,12 @@ public class MapDatabase implements ITileDataSource {
latitude = (int) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
mElem.clear();
mElem.startPoints();
mElem.addPoint(longitude, latitude);
mElem.type = GeometryType.POINT;
mElem.set(curTags, layer);
mElem.setLayer(layer);
mapDataSink.process(mElem);
// mGeom.points[0] = longitude;
// mGeom.points[1] = latitude;
// mGeom.index[0] = 2;
// mapDatabaseCallback.renderPOI(layer, curTags, mGeom);
}
return true;
@ -715,9 +706,8 @@ public class MapDatabase implements ITileDataSource {
ITileDataSink mapDataSink,
int numberOfWays) {
Tag[] tags = null;
Tag[] curTags;
Tag[] wayTags = mTileSource.fileInfo.wayTags;
int numTags = 0;
int wayDataBlocks;
@ -757,11 +747,11 @@ public class MapDatabase implements ITileDataSource {
mReadBuffer.setBufferPosition(mReadBuffer.lastTagPosition);
byte numberOfTags = (byte) (mReadBuffer.readByte() & WAY_NUMBER_OF_TAGS_BITMASK);
tags = mReadBuffer.readTags(wayTags, numberOfTags);
if (tags == null)
if (!mReadBuffer.readTags(mElem.tags, wayTags, numberOfTags))
return false;
numTags = numberOfTags;
mReadBuffer.setBufferPosition(pos);
}
} else {
@ -787,13 +777,13 @@ public class MapDatabase implements ITileDataSource {
// bit 5-8 represent the number of tag IDs
byte numberOfTags = (byte) (specialByte & WAY_NUMBER_OF_TAGS_BITMASK);
if (numberOfTags != 0)
tags = mReadBuffer.readTags(wayTags, numberOfTags);
if (numberOfTags != 0){
if (tags == null)
return false;
if (!mReadBuffer.readTags(mElem.tags, wayTags, numberOfTags))
return false;
curTags = tags;
numTags = numberOfTags;
}
// get the feature bitmask (1 byte)
byte featureByte = mReadBuffer.readByte();
@ -805,42 +795,36 @@ public class MapDatabase implements ITileDataSource {
boolean hasHouseNr = (featureByte & WAY_FEATURE_HOUSE_NUMBER) != 0;
boolean hasRef = (featureByte & WAY_FEATURE_REF) != 0;
int add = (hasName ? 1 : 0) + (hasHouseNr ? 1 : 0) + (hasRef ? 1 : 0);
int addTag = tags.length;
if (add > 0) {
curTags = new Tag[tags.length + add];
System.arraycopy(tags, 0, curTags, 0, tags.length);
}
mElem.tags.numTags = numTags;
if (mTileSource.experimental) {
if (hasName) {
int textPos = mReadBuffer.readUnsignedInt();
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
curTags[addTag++] = new Tag(Tag.TAG_KEY_NAME, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_NAME, str, false));
}
if (hasHouseNr) {
int textPos = mReadBuffer.readUnsignedInt();
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
curTags[addTag++] = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_HOUSE_NUMBER, str, false));
}
if (hasRef) {
int textPos = mReadBuffer.readUnsignedInt();
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
curTags[addTag++] = new Tag(Tag.TAG_KEY_REF, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_REF, str, false));
}
} else {
if (hasName) {
String str = mReadBuffer.readUTF8EncodedString();
curTags[addTag++] = new Tag(Tag.TAG_KEY_NAME, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_NAME, str, false));
}
if (hasHouseNr) {
String str = mReadBuffer.readUTF8EncodedString();
curTags[addTag++] = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_HOUSE_NUMBER, str, false));
}
if (hasRef) {
String str = mReadBuffer.readUTF8EncodedString();
curTags[addTag++] = new Tag(Tag.TAG_KEY_REF, str, false);
mElem.tags.add(new Tag(Tag.TAG_KEY_REF, str, false));
}
}
if ((featureByte & WAY_FEATURE_LABEL_POSITION) != 0)
@ -870,10 +854,9 @@ public class MapDatabase implements ITileDataSource {
&& mElem.points[1] == mElem.points[l - 1];
projectToTile(mElem.points, mElem.index);
mElem.layer = layer;
mElem.type = closed ? GeometryType.POLY : GeometryType.LINE;
mElem.set(curTags, layer);
mElem.setLayer(layer);
mapDataSink.process(mElem);
}
@ -894,16 +877,6 @@ public class MapDatabase implements ITileDataSource {
return labelPosition;
}
// private int readOptionalWayDataBlocksByte(boolean
// featureWayDataBlocksByte) {
// if (featureWayDataBlocksByte) {
// // get and check the number of way data blocks (VBE-U)
// return mReadBuffer.readUnsignedInt();
// }
// // only one way data block exists
// return 1;
// }
private int[][] readZoomTable(SubFileParameter subFileParameter) {
int rows = subFileParameter.zoomLevelMax - subFileParameter.zoomLevelMin + 1;
int[][] zoomTable = new int[rows][2];

View File

@ -20,6 +20,7 @@ import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
/**
* Reads from a {@link RandomAccessFile} into a buffer and decodes the data.
@ -400,8 +401,8 @@ public class ReadBuffer {
mBufferPosition += bytes;
}
Tag[] readTags(Tag[] wayTags, byte numberOfTags) {
Tag[] tags = new Tag[numberOfTags];
boolean readTags(TagSet tags, Tag[] wayTags, byte numberOfTags) {
tags.clear();
int maxTag = wayTags.length;
@ -409,11 +410,11 @@ public class ReadBuffer {
int tagId = readUnsignedInt();
if (tagId < 0 || tagId >= maxTag) {
LOG.warning("invalid tag ID: " + tagId);
return null;
return true;
}
tags[i] = wayTags[tagId];
tags.add(wayTags[tagId]);
}
return tags;
return true;
}
private static final int WAY_NUMBER_OF_TAGS_BITMASK = 0x0f;

View File

@ -22,10 +22,9 @@ import java.util.ArrayList;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.Pool;
@ -201,8 +200,8 @@ public class TileDecoder extends PbfDecoder {
if (f.elem.type == GeometryType.NONE)
continue;
mTagSet.clear();
mTagSet.add(layerTag);
f.elem.tags.clear();
f.elem.tags.add(layerTag);
boolean hasName = false;
String fallbackName = null;
@ -223,19 +222,19 @@ public class TileDecoder extends PbfDecoder {
if (keyIdx == matchedLocal) {
hasName = true;
mTagSet.add(new Tag(Tag.TAG_KEY_NAME, val, false));
f.elem.tags.add(new Tag(Tag.TAG_KEY_NAME, val, false));
} else {
key = keys.get(keyIdx);
mTagSet.add(new Tag(key, val));
f.elem.tags.add(new Tag(key, val));
}
}
if (!hasName && fallbackName != null)
mTagSet.add(new Tag(Tag.TAG_KEY_NAME, fallbackName, false));
f.elem.tags.add(new Tag(Tag.TAG_KEY_NAME, fallbackName, false));
// FIXME extract layer tag here
f.elem.set(mTagSet.asArray(), 5);
f.elem.setLayer(5);
mMapDataCallback.process(f.elem);
mFeaturePool.release(f);
}
@ -243,7 +242,6 @@ public class TileDecoder extends PbfDecoder {
return true;
}
private final TagSet mTagSet = new TagSet();
private final Pool<Feature> mFeaturePool = new Pool<Feature>() {
int count;
@ -260,7 +258,7 @@ public class TileDecoder extends PbfDecoder {
return false;
}
item.elem.tags = null;
item.elem.tags.clear();
item.elem.clear();
item.tags = null;
item.type = 0;
@ -339,9 +337,7 @@ public class TileDecoder extends PbfDecoder {
case TAG_FEATURE_TYPE:
type = decodeVarint32();
//Log.d(TAG, "got type " + type);
break;
case TAG_FEATURE_GEOMETRY:

View File

@ -24,8 +24,8 @@ import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.tilesource.common.PbfDecoder;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.common.PbfDecoder;
import android.util.Log;
@ -69,7 +69,6 @@ public class TileDecoder extends PbfDecoder {
public boolean decode(Tile tile, ITileDataSink sink, InputStream is, int contentLength)
throws IOException {
setInputStream(is, contentLength);
mTile = tile;
@ -164,7 +163,6 @@ public class TileDecoder extends PbfDecoder {
int tagCnt = 0;
int coordCnt = 0;
int layer = 5;
Tag[] tags = null;
boolean fail = false;
@ -178,11 +176,11 @@ public class TileDecoder extends PbfDecoder {
switch (tag) {
case TAG_WAY_TAGS:
tags = decodeWayTags(tagCnt);
if (!decodeWayTags(tagCnt))
return false;
break;
case TAG_WAY_INDEX:
//index =
decodeWayIndices(indexCnt);
break;
@ -223,9 +221,9 @@ public class TileDecoder extends PbfDecoder {
}
}
if (fail || tags == null || indexCnt == 0 || tagCnt == 0) {
if (fail || indexCnt == 0 || tagCnt == 0) {
Log.d(TAG, "failed reading way: bytes:" + bytes + " index:"
+ (tags != null ? tags.toString() : "...") + " "
//+ (tags != null ? tags.toString() : "...") + " "
+ indexCnt + " " + coordCnt + " " + tagCnt);
return false;
}
@ -234,7 +232,7 @@ public class TileDecoder extends PbfDecoder {
//if (layer == 0)
// layer = 5;
mElem.type = polygon ? GeometryType.POLY : GeometryType.LINE;
mElem.set(tags, layer);
mElem.setLayer(layer);
mSink.process(mElem);
return true;
}
@ -246,7 +244,6 @@ public class TileDecoder extends PbfDecoder {
int tagCnt = 0;
int coordCnt = 0;
byte layer = 0;
Tag[] tags = null;
while (position() < end) {
// read tag and wire type
@ -258,11 +255,12 @@ public class TileDecoder extends PbfDecoder {
switch (tag) {
case TAG_NODE_TAGS:
tags = decodeWayTags(tagCnt);
if (!decodeWayTags(tagCnt))
return false;
break;
case TAG_NODE_COORDS:
int cnt = decodeNodeCoordinates(coordCnt, layer, tags);
int cnt = decodeNodeCoordinates(coordCnt, layer);
if (cnt != coordCnt) {
Log.d(TAG, "X wrong number of coordintes");
return false;
@ -289,7 +287,7 @@ public class TileDecoder extends PbfDecoder {
return true;
}
private int decodeNodeCoordinates(int numNodes, byte layer, Tag[] tags)
private int decodeNodeCoordinates(int numNodes, byte layer)
throws IOException {
int bytes = decodeVarint32();
@ -312,48 +310,54 @@ public class TileDecoder extends PbfDecoder {
mElem.index[0] = (short) numNodes;
mElem.type = GeometryType.POINT;
mElem.set(tags, layer);
mElem.setLayer(layer);
mSink.process(mElem);
return cnt;
}
private Tag[] decodeWayTags(int tagCnt) throws IOException {
private boolean decodeWayTags(int tagCnt) throws IOException {
int bytes = decodeVarint32();
Tag[] tags = new Tag[tagCnt];
mElem.tags.clear();
int cnt = 0;
int end = position() + bytes;
int max = mCurTagCnt;
while (position() < end) {
for (; position() < end; cnt++) {
int tagNum = decodeVarint32();
if (tagNum < 0 || cnt == tagCnt) {
Log.d(TAG, "NULL TAG: " + mTile + " invalid tag:" + tagNum
Log.d(TAG, "NULL TAG: " + mTile
+ " invalid tag:" + tagNum
+ " " + tagCnt + "/" + cnt);
} else {
if (tagNum < Tags.MAX)
tags[cnt++] = Tags.tags[tagNum];
else {
tagNum -= Tags.LIMIT;
continue;
}
if (tagNum >= 0 && tagNum < max) {
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
tags[cnt++] = curTags[tagNum];
} else {
Log.d(TAG, "NULL TAG: " + mTile + " could find tag:"
+ tagNum + " " + tagCnt + "/" + cnt);
}
}
if (tagNum < Tags.MAX) {
mElem.tags.add(Tags.tags[tagNum]);
continue;
}
tagNum -= Tags.LIMIT;
if (tagNum >= 0 && tagNum < max) {
mElem.tags.add(curTags[tagNum]);
} else {
Log.d(TAG, "NULL TAG: " + mTile
+ " could find tag:"
+ tagNum + " " + tagCnt
+ "/" + cnt);
}
}
if (tagCnt != cnt)
if (tagCnt != cnt) {
Log.d(TAG, "NULL TAG: " + mTile);
return false;
}
return tags;
return true;
}
private int decodeWayIndices(int indexCnt) throws IOException {
@ -432,7 +436,7 @@ public class TileDecoder extends PbfDecoder {
even = false;
} else {
lastY = lastY + s;
coords[cnt++] = Tile.SIZE - lastY / scale;
coords[cnt++] = Tile.SIZE - lastY / scale;
even = true;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Arrays;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.tilesource.ITileDataSink;
import org.oscim.tilesource.ITileDataSource;
@ -67,32 +68,24 @@ public class OSciMap2TileSource extends UrlTileSource {
private static final int TAG_ELEM_MIN_HEIGHT = 32;
private static final int TAG_ELEM_PRIORITY = 41;
private short[] mSArray = new short[100];
private final Tag[] mTmpTags = new Tag[20];
private final Tag[][] mElementTags;
private final int MAX_TILE_TAGS = 100;
private Tag[] curTags = new Tag[MAX_TILE_TAGS];
private int mCurTagCnt;
private short[] mSArray;
private final TagSet mTileTags;
private final MapElement mElem;
private Tile mTile;
private ITileDataSink mMapDataSink;
// scale coordinates to tile size
private final static float REF_TILE_SIZE = 4096.0f;
private float mScale;
private Tile mTile;
private final MapElement mElem;
private ITileDataSink mMapDataSink;
TileDecoder() {
mElem = new MapElement();
mTileTags = new TagSet(20);
// reusable tag set
Tag[][] tags = new Tag[10][];
for (int i = 0; i < 10; i++)
tags[i] = new Tag[i + 1];
mElementTags = tags;
// temp array for decoding shorts
mSArray = new short[100];
}
@Override
@ -113,7 +106,7 @@ public class OSciMap2TileSource extends UrlTileSource {
mScale = REF_TILE_SIZE / Tile.SIZE;
mCurTagCnt = 0;
mTileTags.clear();
int val;
int numTags = 0;
@ -125,8 +118,6 @@ public class OSciMap2TileSource extends UrlTileSource {
switch (tag) {
case TAG_TILE_NUM_TAGS:
numTags = decodeVarint32();
if (numTags > curTags.length)
curTags = new Tag[numTags];
break;
case TAG_TILE_TAG_KEYS:
@ -139,7 +130,7 @@ public class OSciMap2TileSource extends UrlTileSource {
case TAG_TILE_TAG_VALUES:
// this wastes one byte, as there is no packed string...
decodeTileTags(mCurTagCnt++);
decodeTileTags();
break;
case TAG_TILE_LINE:
@ -156,9 +147,11 @@ public class OSciMap2TileSource extends UrlTileSource {
return true;
}
private boolean decodeTileTags(int curTag) throws IOException {
private boolean decodeTileTags() throws IOException {
String tagString = decodeString();
int curTag = mTileTags.numTags;
String key = Tags.keys[mSArray[curTag]];
Tag tag;
@ -168,7 +161,8 @@ public class OSciMap2TileSource extends UrlTileSource {
tag = new Tag(key, tagString, true);
if (debug)
Log.d(TAG, mTile + " add tag: " + curTag + " " + tag);
curTags[curTag] = tag;
mTileTags.add(tag);
return true;
}
@ -194,7 +188,6 @@ public class OSciMap2TileSource extends UrlTileSource {
private boolean decodeTileElement(int type) throws IOException {
int bytes = decodeVarint32();
Tag[] tags = null;
short[] index = null;
int end = position() + bytes;
@ -223,7 +216,8 @@ public class OSciMap2TileSource extends UrlTileSource {
switch (tag) {
case TAG_ELEM_TAGS:
tags = decodeElementTags();
if (!decodeElementTags())
return false;
break;
case TAG_ELEM_NUM_INDICES:
@ -269,15 +263,14 @@ public class OSciMap2TileSource extends UrlTileSource {
}
}
if (fail || tags == null || indexCnt == 0) {
if (fail || indexCnt == 0) {
Log.d(TAG, mTile + " failed reading way: bytes:" + bytes + " index:"
+ (Arrays.toString(index)) + " tag:"
+ (tags != null ? Arrays.deepToString(tags) : "null") + " "
+ indexCnt + " " + coordCnt);
+ (mElem.tags.numTags > 0 ? Arrays.deepToString(mElem.tags.tags) : "null")
+ " " + indexCnt + " " + coordCnt);
return false;
}
mElem.tags = tags;
switch (type) {
case TAG_TILE_LINE:
mElem.type = GeometryType.LINE;
@ -295,49 +288,46 @@ public class OSciMap2TileSource extends UrlTileSource {
return true;
}
private Tag[] decodeElementTags() throws IOException {
private boolean decodeElementTags() throws IOException {
int bytes = decodeVarint32();
Tag[] tmp = mTmpTags;
mElem.tags.clear();
int cnt = 0;
int end = position() + bytes;
int max = mCurTagCnt;
int max = mTileTags.numTags - 1;
while (position() < end) {
for (; position() < end; cnt++) {
int tagNum = decodeVarint32();
if (tagNum < 0) {
Log.d(TAG, "NULL TAG: " + mTile + " invalid tag:" + tagNum + " " + cnt);
} else if (tagNum < Tags.MAX) {
tmp[cnt++] = Tags.tags[tagNum];
} else {
tagNum -= Tags.LIMIT;
if (tagNum >= 0 && tagNum < max) {
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
tmp[cnt++] = curTags[tagNum];
} else {
Log.d(TAG, "NULL TAG: " + mTile + " could not find tag:"
+ tagNum + " " + cnt);
}
Log.d(TAG, "NULL TAG: " + mTile
+ " invalid tag:"
+ tagNum + " " + cnt);
return false;
}
if (tagNum < Tags.MAX) {
mElem.tags.add(Tags.tags[tagNum]);
continue;
}
tagNum -= Tags.LIMIT;
if (tagNum < 0 || tagNum > max) {
Log.d(TAG, "NULL TAG: " + mTile
+ " could not find tag:"
+ tagNum + " " + cnt);
return false;
}
mElem.tags.add(mTileTags.tags[tagNum]);
}
if (cnt == 0) {
Log.d(TAG, "got no TAG!");
return false;
}
Tag[] tags;
if (cnt < 11)
tags = mElementTags[cnt - 1];
else
tags = new Tag[cnt];
for (int i = 0; i < cnt; i++)
tags[i] = tmp[i];
return tags;
return true;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013
* 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
@ -54,32 +54,23 @@ public class TileDecoder extends PbfDecoder {
private static final int TAG_ELEM_INDEX = 12;
private static final int TAG_ELEM_COORDS = 13;
private static final int TAG_ELEM_LAYER = 21;
//private static final int TAG_ELEM_HEIGHT = 31;
//private static final int TAG_ELEM_MIN_HEIGHT = 32;
//private static final int TAG_ELEM_PRIORITY = 41;
private short[] mSArray = new short[100];
private Tile mTile;
private final MapElement mElem;
private final Tag[][] mElementTags;
private final TagSet curTags = new TagSet(100);
private final TagSet mTileTags;
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;
TileDecoder() {
mElem = new MapElement();
// reusable tag set
Tag[][] tags = new Tag[10][];
for (int i = 0; i < 10; i++)
tags[i] = new Tag[i + 1];
mElementTags = tags;
mTileTags = new TagSet(100);
}
@Override
@ -98,7 +89,7 @@ public class TileDecoder extends PbfDecoder {
mTile = tile;
mMapDataSink = sink;
curTags.clear(true);
mTileTags.clear(true);
int version = -1;
int val;
@ -218,12 +209,17 @@ public class TileDecoder extends PbfDecoder {
// FIXME filter out all variable tags
// might depend on theme though
if (key == Tag.TAG_KEY_NAME || key == Tag.KEY_HEIGHT || key == Tag.KEY_MIN_HEIGHT)
if (key == Tag.TAG_KEY_NAME
|| key == Tag.KEY_HEIGHT
|| key == Tag.KEY_MIN_HEIGHT
|| key == Tag.TAG_KEY_HOUSE_NUMBER
|| key == Tag.TAG_KEY_REF
|| key == Tag.TAG_KEY_ELE)
tag = new Tag(key, val, false);
else
tag = new Tag(key, val, true);
curTags.add(tag);
mTileTags.add(tag);
}
return true;
@ -251,7 +247,6 @@ public class TileDecoder extends PbfDecoder {
private boolean decodeTileElement(int type) throws IOException {
int bytes = decodeVarint32();
Tag[] tags = null;
short[] index = null;
int end = position() + bytes;
@ -282,7 +277,8 @@ public class TileDecoder extends PbfDecoder {
switch (tag) {
case TAG_ELEM_TAGS:
tags = decodeElementTags(numTags);
if (!decodeElementTags(numTags))
return false;
break;
case TAG_ELEM_NUM_INDICES:
@ -322,15 +318,14 @@ public class TileDecoder extends PbfDecoder {
}
}
if (fail || tags == null || numIndices == 0) {
if (fail || numTags == 0 || numIndices == 0) {
Log.d(TAG, mTile + " failed reading way: bytes:" + bytes + " index:"
+ (Arrays.toString(index)) + " tag:"
+ (tags != null ? Arrays.deepToString(tags) : "null") + " "
+ numIndices + " " + coordCnt);
+ (mElem.tags.numTags > 0 ? Arrays.deepToString(mElem.tags.tags) : "null")
+ " " + numIndices + " " + coordCnt);
return false;
}
mElem.tags = tags;
switch (type) {
case TAG_TILE_LINE:
mElem.type = GeometryType.LINE;
@ -348,33 +343,27 @@ public class TileDecoder extends PbfDecoder {
return true;
}
private Tag[] decodeElementTags(int numTags) throws IOException {
private boolean decodeElementTags(int numTags) throws IOException {
if (mSArray.length < numTags)
mSArray = new short[numTags];
short[] tagIds = mSArray;
decodeVarintArray(numTags, tagIds);
Tag[] tags;
mElem.tags.clear();
if (numTags < 11)
tags = mElementTags[numTags - 1];
else
tags = new Tag[numTags];
int max = curTags.numTags;
int max = mTileTags.numTags - 1;
for (int i = 0; i < numTags; i++) {
int idx = tagIds[i];
if (idx < 0 || idx > max) {
Log.d(TAG, mTile + " invalid tag:" + idx + " " + i);
return null;
return false;
}
tags[i] = curTags.tags[idx];
mElem.tags.add(mTileTags.tags[idx]);
}
return tags;
return true;
}
}

View File

@ -94,7 +94,7 @@ public class TestTileSource implements ITileDataSource {
e.addPoint(x2, y2);
e.addPoint(x1, y2);
e.set(mTags, 0);
//// FIXME e.setLayer(mTags, 0);
mapDataSink.process(e);
if (renderWays) {
@ -115,7 +115,7 @@ public class TestTileSource implements ITileDataSource {
e.addPoint(size / 2, size / 2);
e.addPoint(size / 2, size / 2 + size);
e.set(mTagsWay, 0);
////e.setLayer(mTagsWay, 0);
mapDataSink.process(e);
e.clear();
@ -132,7 +132,7 @@ public class TestTileSource implements ITileDataSource {
e.addPoint(10, 0);
e.addPoint(10, size);
e.set(mTagsWay, 1);
//// --e.setLayer(mTagsWay, 1);
mapDataSink.process(e);
}
@ -147,7 +147,7 @@ public class TestTileSource implements ITileDataSource {
r + (float) Math.sin(d) * (r - 40));
}
e.set(mTagsBoundary, 1);
//// e.setLayer(mTagsBoundary, 1);
mapDataSink.process(e);
}
@ -157,7 +157,7 @@ public class TestTileSource implements ITileDataSource {
e.addPoint(size / 2, size / 2);
mTagsPlace[1] = new Tag("name", tile.toString());
e.set(mTagsPlace, 0);
//// e.setLayer(mTagsPlace, 0);
mapDataSink.process(e);
}
return QueryResult.SUCCESS;