use TagSet instead of Tag[] in MapElement
This commit is contained in:
parent
0ed0d1a154
commit
48369f6baf
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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--;
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user