Improve code / xml formatting, closes #54
This commit is contained in:
@@ -16,6 +16,25 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.source.ITileDecoder;
|
||||
import org.oscim.utils.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
|
||||
import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
|
||||
import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;
|
||||
@@ -27,324 +46,304 @@ import static com.fasterxml.jackson.core.JsonToken.VALUE_STRING;
|
||||
import static org.oscim.core.MercatorProjection.latitudeToY;
|
||||
import static org.oscim.core.MercatorProjection.longitudeToX;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.source.ITileDecoder;
|
||||
import org.oscim.utils.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
public class GeoJsonTileDecoder implements ITileDecoder {
|
||||
static final Logger log = LoggerFactory.getLogger(GeoJsonTileDecoder.class);
|
||||
static final Logger log = LoggerFactory.getLogger(GeoJsonTileDecoder.class);
|
||||
|
||||
private final MapElement mMapElement;
|
||||
private final GeoJsonTileSource mTileSource;
|
||||
private final LinkedHashMap<String, Object> mTagMap;
|
||||
private final JsonFactory mJsonFactory;
|
||||
private final MapElement mMapElement;
|
||||
private final GeoJsonTileSource mTileSource;
|
||||
private final LinkedHashMap<String, Object> mTagMap;
|
||||
private final JsonFactory mJsonFactory;
|
||||
|
||||
private final static char[] FIELD_FEATURES = "features".toCharArray();
|
||||
private final static char[] FIELD_GEOMETRY = "geometry".toCharArray();
|
||||
private final static char[] FIELD_PROPERTIES = "properties".toCharArray();
|
||||
private final static char[] FIELD_COORDINATES = "coordinates".toCharArray();
|
||||
private final static char[] FIELD_TYPE = "type".toCharArray();
|
||||
private final static char[] FIELD_FEATURES = "features".toCharArray();
|
||||
private final static char[] FIELD_GEOMETRY = "geometry".toCharArray();
|
||||
private final static char[] FIELD_PROPERTIES = "properties".toCharArray();
|
||||
private final static char[] FIELD_COORDINATES = "coordinates".toCharArray();
|
||||
private final static char[] FIELD_TYPE = "type".toCharArray();
|
||||
|
||||
private final static char[] LINETRING = "LineString".toCharArray();
|
||||
private final static char[] POLYGON = "Polygon".toCharArray();
|
||||
private final static char[] POINT = "Point".toCharArray();
|
||||
private final static char[] MULTI_LINESTRING = "MultiLineString".toCharArray();
|
||||
private final static char[] MULTI_POLYGON = "MultiPolygon".toCharArray();
|
||||
private final static char[] MULTI_POINT = "MultiPoint".toCharArray();
|
||||
private final static char[] LINETRING = "LineString".toCharArray();
|
||||
private final static char[] POLYGON = "Polygon".toCharArray();
|
||||
private final static char[] POINT = "Point".toCharArray();
|
||||
private final static char[] MULTI_LINESTRING = "MultiLineString".toCharArray();
|
||||
private final static char[] MULTI_POLYGON = "MultiPolygon".toCharArray();
|
||||
private final static char[] MULTI_POINT = "MultiPoint".toCharArray();
|
||||
|
||||
private ITileDataSink mTileDataSink;
|
||||
private ITileDataSink mTileDataSink;
|
||||
|
||||
private double mTileY, mTileX, mTileScale;
|
||||
private double mTileY, mTileX, mTileScale;
|
||||
|
||||
public GeoJsonTileDecoder(GeoJsonTileSource tileSource) {
|
||||
mTileSource = tileSource;
|
||||
mTagMap = new LinkedHashMap<String, Object>();
|
||||
mJsonFactory = new JsonFactory();
|
||||
public GeoJsonTileDecoder(GeoJsonTileSource tileSource) {
|
||||
mTileSource = tileSource;
|
||||
mTagMap = new LinkedHashMap<String, Object>();
|
||||
mJsonFactory = new JsonFactory();
|
||||
|
||||
mMapElement = new MapElement();
|
||||
mMapElement.layer = 5;
|
||||
}
|
||||
mMapElement = new MapElement();
|
||||
mMapElement.layer = 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException {
|
||||
mTileDataSink = sink;
|
||||
mTileScale = 1 << tile.zoomLevel;
|
||||
mTileX = tile.tileX / mTileScale;
|
||||
mTileY = tile.tileY / mTileScale;
|
||||
mTileScale *= Tile.SIZE;
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is) throws IOException {
|
||||
mTileDataSink = sink;
|
||||
mTileScale = 1 << tile.zoomLevel;
|
||||
mTileX = tile.tileX / mTileScale;
|
||||
mTileY = tile.tileY / mTileScale;
|
||||
mTileScale *= Tile.SIZE;
|
||||
|
||||
JsonParser jp = mJsonFactory.createParser(new InputStreamReader(is));
|
||||
JsonParser jp = mJsonFactory.createParser(new InputStreamReader(is));
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_FEATURES)) {
|
||||
if (jp.nextToken() != START_ARRAY)
|
||||
continue;
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_FEATURES)) {
|
||||
if (jp.nextToken() != START_ARRAY)
|
||||
continue;
|
||||
|
||||
while ((t = jp.nextToken()) != null) {
|
||||
if (t == START_OBJECT)
|
||||
parseFeature(jp);
|
||||
while ((t = jp.nextToken()) != null) {
|
||||
if (t == START_OBJECT)
|
||||
parseFeature(jp);
|
||||
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseFeature(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
private void parseFeature(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
mMapElement.clear();
|
||||
mMapElement.tags.clear();
|
||||
mTagMap.clear();
|
||||
mMapElement.clear();
|
||||
mMapElement.tags.clear();
|
||||
mTagMap.clear();
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_GEOMETRY)) {
|
||||
if (jp.nextToken() == START_OBJECT)
|
||||
parseGeometry(jp);
|
||||
}
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_GEOMETRY)) {
|
||||
if (jp.nextToken() == START_OBJECT)
|
||||
parseGeometry(jp);
|
||||
}
|
||||
|
||||
if (match(jp, FIELD_PROPERTIES)) {
|
||||
if (jp.nextToken() == START_OBJECT)
|
||||
parseProperties(jp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
if (match(jp, FIELD_PROPERTIES)) {
|
||||
if (jp.nextToken() == START_OBJECT)
|
||||
parseProperties(jp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
|
||||
//add tag information
|
||||
mTileSource.decodeTags(mMapElement, mTagMap);
|
||||
if (mMapElement.tags.numTags == 0)
|
||||
return;
|
||||
//add tag information
|
||||
mTileSource.decodeTags(mMapElement, mTagMap);
|
||||
if (mMapElement.tags.numTags == 0)
|
||||
return;
|
||||
|
||||
mTileSource.postGeomHook(mMapElement);
|
||||
mTileSource.postGeomHook(mMapElement);
|
||||
|
||||
if (mMapElement.type == GeometryType.NONE)
|
||||
return;
|
||||
if (mMapElement.type == GeometryType.NONE)
|
||||
return;
|
||||
|
||||
//process this element
|
||||
mTileDataSink.process(mMapElement);
|
||||
}
|
||||
//process this element
|
||||
mTileDataSink.process(mMapElement);
|
||||
}
|
||||
|
||||
private void parseProperties(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == FIELD_NAME) {
|
||||
String text = jp.getCurrentName();
|
||||
private void parseProperties(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == FIELD_NAME) {
|
||||
String text = jp.getCurrentName();
|
||||
|
||||
t = jp.nextToken();
|
||||
if (t == VALUE_STRING) {
|
||||
mTagMap.put(text, jp.getText());
|
||||
} else if (t == VALUE_NUMBER_INT) {
|
||||
mTagMap.put(text, jp.getNumberValue());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
t = jp.nextToken();
|
||||
if (t == VALUE_STRING) {
|
||||
mTagMap.put(text, jp.getText());
|
||||
} else if (t == VALUE_NUMBER_INT) {
|
||||
mTagMap.put(text, jp.getNumberValue());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGeometry(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
private void parseGeometry(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
boolean multi = false;
|
||||
GeometryType type = GeometryType.NONE;
|
||||
boolean multi = false;
|
||||
GeometryType type = GeometryType.NONE;
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_COORDINATES)) {
|
||||
if (jp.nextToken() != START_ARRAY)
|
||||
continue;
|
||||
if (multi) {
|
||||
parseMulti(jp, type);
|
||||
} else {
|
||||
if (type == GeometryType.POLY)
|
||||
parsePolygon(jp);
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == FIELD_NAME) {
|
||||
if (match(jp, FIELD_COORDINATES)) {
|
||||
if (jp.nextToken() != START_ARRAY)
|
||||
continue;
|
||||
if (multi) {
|
||||
parseMulti(jp, type);
|
||||
} else {
|
||||
if (type == GeometryType.POLY)
|
||||
parsePolygon(jp);
|
||||
|
||||
if (type == GeometryType.LINE)
|
||||
parseLineString(jp);
|
||||
if (type == GeometryType.LINE)
|
||||
parseLineString(jp);
|
||||
|
||||
if (type == GeometryType.POINT)
|
||||
parseCoordinate(jp);
|
||||
if (type == GeometryType.POINT)
|
||||
parseCoordinate(jp);
|
||||
|
||||
}
|
||||
} else if (match(jp, FIELD_TYPE)) {
|
||||
multi = false;
|
||||
}
|
||||
} else if (match(jp, FIELD_TYPE)) {
|
||||
multi = false;
|
||||
|
||||
jp.nextToken();
|
||||
jp.nextToken();
|
||||
|
||||
if (match(jp, LINETRING))
|
||||
type = GeometryType.LINE;
|
||||
else if (match(jp, POLYGON))
|
||||
type = GeometryType.POLY;
|
||||
else if (match(jp, POINT))
|
||||
type = GeometryType.POINT;
|
||||
else if (match(jp, MULTI_LINESTRING)) {
|
||||
type = GeometryType.LINE;
|
||||
multi = true;
|
||||
}
|
||||
else if (match(jp, MULTI_POLYGON)) {
|
||||
type = GeometryType.POLY;
|
||||
multi = true;
|
||||
}
|
||||
else if (match(jp, MULTI_POINT)) {
|
||||
type = GeometryType.POINT;
|
||||
multi = true;
|
||||
}
|
||||
if (match(jp, LINETRING))
|
||||
type = GeometryType.LINE;
|
||||
else if (match(jp, POLYGON))
|
||||
type = GeometryType.POLY;
|
||||
else if (match(jp, POINT))
|
||||
type = GeometryType.POINT;
|
||||
else if (match(jp, MULTI_LINESTRING)) {
|
||||
type = GeometryType.LINE;
|
||||
multi = true;
|
||||
} else if (match(jp, MULTI_POLYGON)) {
|
||||
type = GeometryType.POLY;
|
||||
multi = true;
|
||||
} else if (match(jp, MULTI_POINT)) {
|
||||
type = GeometryType.POINT;
|
||||
multi = true;
|
||||
}
|
||||
|
||||
if (type == GeometryType.POINT)
|
||||
mMapElement.startPoints();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type == GeometryType.POINT)
|
||||
mMapElement.startPoints();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (t == END_OBJECT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseMulti(JsonParser jp, GeometryType type)
|
||||
throws JsonParseException, IOException {
|
||||
private void parseMulti(JsonParser jp, GeometryType type)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
|
||||
if (t == START_ARRAY) {
|
||||
if (type == GeometryType.POLY)
|
||||
parsePolygon(jp);
|
||||
if (t == START_ARRAY) {
|
||||
if (type == GeometryType.POLY)
|
||||
parsePolygon(jp);
|
||||
|
||||
else if (type == GeometryType.LINE)
|
||||
parseLineString(jp);
|
||||
else if (type == GeometryType.LINE)
|
||||
parseLineString(jp);
|
||||
|
||||
else if (type == GeometryType.POINT)
|
||||
parseCoordinate(jp);;
|
||||
else if (type == GeometryType.POINT)
|
||||
parseCoordinate(jp);
|
||||
;
|
||||
|
||||
} else {
|
||||
//....
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//....
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePolygon(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
int ring = 0;
|
||||
private void parsePolygon(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
int ring = 0;
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == START_ARRAY) {
|
||||
if (ring == 0)
|
||||
mMapElement.startPolygon();
|
||||
else
|
||||
mMapElement.startHole();
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == START_ARRAY) {
|
||||
if (ring == 0)
|
||||
mMapElement.startPolygon();
|
||||
else
|
||||
mMapElement.startHole();
|
||||
|
||||
ring++;
|
||||
parseCoordSequence(jp);
|
||||
removeLastPoint();
|
||||
continue;
|
||||
}
|
||||
ring++;
|
||||
parseCoordSequence(jp);
|
||||
removeLastPoint();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLastPoint() {
|
||||
mMapElement.pointPos -= 2;
|
||||
mMapElement.index[mMapElement.indexPos] -= 2;
|
||||
}
|
||||
private void removeLastPoint() {
|
||||
mMapElement.pointPos -= 2;
|
||||
mMapElement.index[mMapElement.indexPos] -= 2;
|
||||
}
|
||||
|
||||
private void parseLineString(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
mMapElement.startLine();
|
||||
parseCoordSequence(jp);
|
||||
}
|
||||
private void parseLineString(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
mMapElement.startLine();
|
||||
parseCoordSequence(jp);
|
||||
}
|
||||
|
||||
private void parseCoordSequence(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
private void parseCoordSequence(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
|
||||
if (t == START_ARRAY) {
|
||||
parseCoordinate(jp);
|
||||
continue;
|
||||
}
|
||||
if (t == START_ARRAY) {
|
||||
parseCoordinate(jp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCoordinate(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
int pos = 0;
|
||||
double x = 0, y = 0; //, z = 0;
|
||||
private void parseCoordinate(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
int pos = 0;
|
||||
double x = 0, y = 0; //, z = 0;
|
||||
|
||||
for (JsonToken t; (t = jp.nextToken()) != null;) {
|
||||
if (t == VALUE_NUMBER_FLOAT || t == VALUE_NUMBER_INT) {
|
||||
for (JsonToken t; (t = jp.nextToken()) != null; ) {
|
||||
if (t == VALUE_NUMBER_FLOAT || t == VALUE_NUMBER_INT) {
|
||||
|
||||
// avoid String allocation (by getDouble...)
|
||||
char[] val = jp.getTextCharacters();
|
||||
int offset = jp.getTextOffset();
|
||||
int length = jp.getTextLength();
|
||||
double c = ArrayUtils.parseNumber(val, offset, offset + length);
|
||||
// avoid String allocation (by getDouble...)
|
||||
char[] val = jp.getTextCharacters();
|
||||
int offset = jp.getTextOffset();
|
||||
int length = jp.getTextLength();
|
||||
double c = ArrayUtils.parseNumber(val, offset, offset + length);
|
||||
|
||||
if (pos == 0)
|
||||
x = c;
|
||||
if (pos == 1)
|
||||
y = c;
|
||||
//if (pos == 2)
|
||||
//z = c;
|
||||
if (pos == 0)
|
||||
x = c;
|
||||
if (pos == 1)
|
||||
y = c;
|
||||
//if (pos == 2)
|
||||
//z = c;
|
||||
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
if (t == END_ARRAY)
|
||||
break;
|
||||
}
|
||||
|
||||
mMapElement.addPoint((float) ((longitudeToX(x) - mTileX) * mTileScale),
|
||||
(float) ((latitudeToY(y) - mTileY) * mTileScale));
|
||||
mMapElement.addPoint((float) ((longitudeToX(x) - mTileX) * mTileScale),
|
||||
(float) ((latitudeToY(y) - mTileY) * mTileScale));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private final static boolean match(JsonParser jp, char[] fieldName)
|
||||
throws JsonParseException, IOException {
|
||||
private final static boolean match(JsonParser jp, char[] fieldName)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
int length = jp.getTextLength();
|
||||
if (length != fieldName.length)
|
||||
return false;
|
||||
int length = jp.getTextLength();
|
||||
if (length != fieldName.length)
|
||||
return false;
|
||||
|
||||
char[] val = jp.getTextCharacters();
|
||||
int offset = jp.getTextOffset();
|
||||
char[] val = jp.getTextCharacters();
|
||||
int offset = jp.getTextOffset();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (fieldName[i] != val[i + offset])
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (fieldName[i] != val[i + offset])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,56 +16,60 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.source.UrlTileDataSource;
|
||||
import org.oscim.tiling.source.UrlTileSource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class GeoJsonTileSource extends UrlTileSource {
|
||||
|
||||
public GeoJsonTileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.json");
|
||||
Map<String, String> opt = new HashMap<String, String>();
|
||||
opt.put("Accept-Encoding", "gzip");
|
||||
setHttpRequestHeaders(opt);
|
||||
}
|
||||
public GeoJsonTileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.json");
|
||||
Map<String, String> opt = new HashMap<String, String>();
|
||||
opt.put("Accept-Encoding", "gzip");
|
||||
setHttpRequestHeaders(opt);
|
||||
}
|
||||
|
||||
public GeoJsonTileSource(String url, int zoomMin, int zoomMax) {
|
||||
super(url, "/{Z}/{X}/{Y}.json", zoomMin, zoomMax);
|
||||
Map<String, String> opt = new HashMap<String, String>();
|
||||
opt.put("Accept-Encoding", "gzip");
|
||||
setHttpRequestHeaders(opt);
|
||||
}
|
||||
public GeoJsonTileSource(String url, int zoomMin, int zoomMax) {
|
||||
super(url, "/{Z}/{X}/{Y}.json", zoomMin, zoomMax);
|
||||
Map<String, String> opt = new HashMap<String, String>();
|
||||
opt.put("Accept-Encoding", "gzip");
|
||||
setHttpRequestHeaders(opt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
|
||||
return new UrlTileDataSource(this, new GeoJsonTileDecoder(this), getHttpEngine());
|
||||
}
|
||||
return new UrlTileDataSource(this, new GeoJsonTileDecoder(this), getHttpEngine());
|
||||
}
|
||||
|
||||
public Tag getFeatureTag() {
|
||||
return null;
|
||||
}
|
||||
public Tag getFeatureTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** allow overriding tag handling */
|
||||
public abstract void decodeTags(MapElement mapElement, Map<String, Object> properties);
|
||||
/**
|
||||
* allow overriding tag handling
|
||||
*/
|
||||
public abstract void decodeTags(MapElement mapElement, Map<String, Object> properties);
|
||||
|
||||
public Tag rewriteTag(String key, Object value) {
|
||||
public Tag rewriteTag(String key, Object value) {
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
String val = (value instanceof String) ? (String) value : String.valueOf(value);
|
||||
String val = (value instanceof String) ? (String) value : String.valueOf(value);
|
||||
|
||||
return new Tag(key, val);
|
||||
}
|
||||
return new Tag(key, val);
|
||||
}
|
||||
|
||||
/** modify mapElement before process() */
|
||||
public void postGeomHook(MapElement mapElement) {
|
||||
/**
|
||||
* modify mapElement before process()
|
||||
*/
|
||||
public void postGeomHook(MapElement mapElement) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,23 +16,23 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class OsmBuildingJsonTileSource extends GeoJsonTileSource {
|
||||
|
||||
public OsmBuildingJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-buildings");
|
||||
}
|
||||
public OsmBuildingJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-buildings");
|
||||
}
|
||||
|
||||
Tag mTagBuilding = new Tag("building", "yes");
|
||||
Tag mTagBuilding = new Tag("building", "yes");
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
|
||||
mapElement.tags.add(mTagBuilding);
|
||||
mapElement.tags.add(mTagBuilding);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,112 +16,112 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class OsmLanduseJsonTileSource extends GeoJsonTileSource {
|
||||
static final Logger log = LoggerFactory.getLogger(OsmLanduseJsonTileSource.class);
|
||||
static final Logger log = LoggerFactory.getLogger(OsmLanduseJsonTileSource.class);
|
||||
|
||||
public OsmLanduseJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-land-usages");
|
||||
}
|
||||
public OsmLanduseJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-land-usages");
|
||||
}
|
||||
|
||||
private static LinkedHashMap<String, Tag> mappings =
|
||||
new LinkedHashMap<String, Tag>();
|
||||
private static LinkedHashMap<String, Tag> mappings =
|
||||
new LinkedHashMap<String, Tag>();
|
||||
|
||||
static void addMapping(String key, String val) {
|
||||
mappings.put(val, new Tag(key, val));
|
||||
}
|
||||
static void addMapping(String key, String val) {
|
||||
mappings.put(val, new Tag(key, val));
|
||||
}
|
||||
|
||||
static {
|
||||
addMapping("landuse", "residential");
|
||||
addMapping("landuse", "commercial");
|
||||
addMapping("landuse", "retail");
|
||||
addMapping("landuse", "railway");
|
||||
addMapping("landuse", "grass");
|
||||
addMapping("landuse", "meadow");
|
||||
addMapping("landuse", "forest");
|
||||
addMapping("landuse", "farm");
|
||||
addMapping("landuse", "allotments");
|
||||
addMapping("landuse", "cemetery");
|
||||
addMapping("landuse", "farmyard");
|
||||
addMapping("landuse", "farmland");
|
||||
addMapping("landuse", "quarry");
|
||||
addMapping("landuse", "military");
|
||||
addMapping("landuse", "industrial");
|
||||
addMapping("landuse", "greenfield");
|
||||
addMapping("landuse", "village_green");
|
||||
addMapping("landuse", "recreation_ground");
|
||||
addMapping("landuse", "conservation");
|
||||
addMapping("landuse", "landfill");
|
||||
addMapping("landuse", "construction");
|
||||
static {
|
||||
addMapping("landuse", "residential");
|
||||
addMapping("landuse", "commercial");
|
||||
addMapping("landuse", "retail");
|
||||
addMapping("landuse", "railway");
|
||||
addMapping("landuse", "grass");
|
||||
addMapping("landuse", "meadow");
|
||||
addMapping("landuse", "forest");
|
||||
addMapping("landuse", "farm");
|
||||
addMapping("landuse", "allotments");
|
||||
addMapping("landuse", "cemetery");
|
||||
addMapping("landuse", "farmyard");
|
||||
addMapping("landuse", "farmland");
|
||||
addMapping("landuse", "quarry");
|
||||
addMapping("landuse", "military");
|
||||
addMapping("landuse", "industrial");
|
||||
addMapping("landuse", "greenfield");
|
||||
addMapping("landuse", "village_green");
|
||||
addMapping("landuse", "recreation_ground");
|
||||
addMapping("landuse", "conservation");
|
||||
addMapping("landuse", "landfill");
|
||||
addMapping("landuse", "construction");
|
||||
|
||||
addMapping("leisure", "common");
|
||||
addMapping("leisure", "park");
|
||||
addMapping("leisure", "pitch");
|
||||
addMapping("leisure", "garden");
|
||||
addMapping("leisure", "sports_centre");
|
||||
addMapping("leisure", "playground");
|
||||
addMapping("leisure", "nature_reserve");
|
||||
addMapping("leisure", "golf_course");
|
||||
addMapping("leisure", "stadium");
|
||||
addMapping("leisure", "common");
|
||||
addMapping("leisure", "park");
|
||||
addMapping("leisure", "pitch");
|
||||
addMapping("leisure", "garden");
|
||||
addMapping("leisure", "sports_centre");
|
||||
addMapping("leisure", "playground");
|
||||
addMapping("leisure", "nature_reserve");
|
||||
addMapping("leisure", "golf_course");
|
||||
addMapping("leisure", "stadium");
|
||||
|
||||
addMapping("amenity", "hospital");
|
||||
addMapping("amenity", "cinema");
|
||||
addMapping("amenity", "school");
|
||||
addMapping("amenity", "college");
|
||||
addMapping("amenity", "university");
|
||||
addMapping("amenity", "theatre");
|
||||
addMapping("amenity", "library");
|
||||
addMapping("amenity", "parking");
|
||||
addMapping("amenity", "place_of_worship");
|
||||
addMapping("amenity", "hospital");
|
||||
addMapping("amenity", "cinema");
|
||||
addMapping("amenity", "school");
|
||||
addMapping("amenity", "college");
|
||||
addMapping("amenity", "university");
|
||||
addMapping("amenity", "theatre");
|
||||
addMapping("amenity", "library");
|
||||
addMapping("amenity", "parking");
|
||||
addMapping("amenity", "place_of_worship");
|
||||
|
||||
addMapping("highway", "pedestrian");
|
||||
addMapping("highway", "footway");
|
||||
addMapping("highway", "service");
|
||||
addMapping("highway", "street");
|
||||
addMapping("highway", "pedestrian");
|
||||
addMapping("highway", "footway");
|
||||
addMapping("highway", "service");
|
||||
addMapping("highway", "street");
|
||||
|
||||
addMapping("natural", "scrub");
|
||||
addMapping("natural", "wood");
|
||||
addMapping("natural", "scrub");
|
||||
addMapping("natural", "wood");
|
||||
|
||||
mappings.put("urban area", new Tag("landuse", "urban"));
|
||||
mappings.put("park or protected land", new Tag("leisure", "park"));
|
||||
}
|
||||
mappings.put("urban area", new Tag("landuse", "urban"));
|
||||
mappings.put("park or protected land", new Tag("leisure", "park"));
|
||||
}
|
||||
|
||||
private final static Tag mTagArea = new Tag("area", "yes");
|
||||
private final static Tag mTagArea = new Tag("area", "yes");
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
|
||||
if (!"kind".equals(key))
|
||||
continue;
|
||||
if (!"kind".equals(key))
|
||||
continue;
|
||||
|
||||
String value = (String) entry.getValue();
|
||||
String value = (String) entry.getValue();
|
||||
|
||||
Tag tag = mappings.get(value);
|
||||
if (tag == null) {
|
||||
System.out.println("unmatched " + value);
|
||||
} else {
|
||||
mapElement.tags.add(tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Tag tag = mappings.get(value);
|
||||
if (tag == null) {
|
||||
System.out.println("unmatched " + value);
|
||||
} else {
|
||||
mapElement.tags.add(tag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postGeomHook(MapElement mapElement) {
|
||||
//if (mapElement.type != GeometryType.POLY) {
|
||||
mapElement.type = GeometryType.POLY;
|
||||
mapElement.tags.add(mTagArea);
|
||||
//}
|
||||
}
|
||||
@Override
|
||||
public void postGeomHook(MapElement mapElement) {
|
||||
//if (mapElement.type != GeometryType.POLY) {
|
||||
mapElement.type = GeometryType.POLY;
|
||||
mapElement.tags.add(mTagArea);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,35 +25,34 @@ import java.util.Map;
|
||||
|
||||
public class OsmRoadLabelJsonTileSource extends GeoJsonTileSource {
|
||||
|
||||
static final Logger log = LoggerFactory.getLogger(OsmRoadLabelJsonTileSource.class);
|
||||
static final Logger log = LoggerFactory.getLogger(OsmRoadLabelJsonTileSource.class);
|
||||
|
||||
public OsmRoadLabelJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-skeletron");
|
||||
}
|
||||
public OsmRoadLabelJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-skeletron");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
String highway = null;
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
String highway = null;
|
||||
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
//log.debug(key + " : " + String.valueOf(value));
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
//log.debug(key + " : " + String.valueOf(value));
|
||||
|
||||
if (value == null)
|
||||
continue;
|
||||
if (value == null)
|
||||
continue;
|
||||
|
||||
if ("highway".equals(key) && value instanceof String) {
|
||||
highway = (String) entry.getValue();
|
||||
}
|
||||
else if ("name".equals(key) && value instanceof String) {
|
||||
mapElement.tags.add(new Tag("name", (String) value));
|
||||
}
|
||||
}
|
||||
if ("highway".equals(key) && value instanceof String) {
|
||||
highway = (String) entry.getValue();
|
||||
} else if ("name".equals(key) && value instanceof String) {
|
||||
mapElement.tags.add(new Tag("name", (String) value));
|
||||
}
|
||||
}
|
||||
|
||||
if (highway == null)
|
||||
return;
|
||||
if (highway == null)
|
||||
return;
|
||||
|
||||
mapElement.tags.add(new Tag("highway", highway));
|
||||
}
|
||||
mapElement.tags.add(new Tag("highway", highway));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,83 +16,78 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class OsmRoadLineJsonTileSource extends GeoJsonTileSource {
|
||||
|
||||
static final Logger log = LoggerFactory.getLogger(OsmRoadLineJsonTileSource.class);
|
||||
static final Logger log = LoggerFactory.getLogger(OsmRoadLineJsonTileSource.class);
|
||||
|
||||
Tag mTagTunnel = new Tag("tunnel", "yes");
|
||||
Tag mTagBridge = new Tag("bridge", "yes");
|
||||
Tag mTagTunnel = new Tag("tunnel", "yes");
|
||||
Tag mTagBridge = new Tag("bridge", "yes");
|
||||
|
||||
public OsmRoadLineJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-highroad");
|
||||
}
|
||||
public OsmRoadLineJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-highroad");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
String highway = null;
|
||||
boolean isLink = false;
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
String highway = null;
|
||||
boolean isLink = false;
|
||||
|
||||
mapElement.layer = 5;
|
||||
mapElement.layer = 5;
|
||||
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
//log.debug(key + " : " + String.valueOf(value));
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
//log.debug(key + " : " + String.valueOf(value));
|
||||
|
||||
if (value == null)
|
||||
continue;
|
||||
if (value == null)
|
||||
continue;
|
||||
|
||||
if ("no".equals(value))
|
||||
continue;
|
||||
if ("no".equals(value))
|
||||
continue;
|
||||
|
||||
if ("highway".equals(key) && value instanceof String) {
|
||||
highway = (String) entry.getValue();
|
||||
}
|
||||
else if ("is_link".equals(key)) {
|
||||
isLink = "yes".equals(value);
|
||||
}
|
||||
else if ("is_tunnel".equals(key)) {
|
||||
mapElement.tags.add(mTagTunnel);
|
||||
}
|
||||
else if ("is_bridge".equals(key)) {
|
||||
mapElement.tags.add(mTagBridge);
|
||||
}
|
||||
else if ("sort_key".equals(key)) {
|
||||
if (value instanceof Integer)
|
||||
mapElement.layer = 5 + (Integer) value;
|
||||
}
|
||||
else if ("railway".equals(key) && value instanceof String) {
|
||||
mapElement.tags.add(new Tag("railway", (String) value));
|
||||
}
|
||||
}
|
||||
if ("highway".equals(key) && value instanceof String) {
|
||||
highway = (String) entry.getValue();
|
||||
} else if ("is_link".equals(key)) {
|
||||
isLink = "yes".equals(value);
|
||||
} else if ("is_tunnel".equals(key)) {
|
||||
mapElement.tags.add(mTagTunnel);
|
||||
} else if ("is_bridge".equals(key)) {
|
||||
mapElement.tags.add(mTagBridge);
|
||||
} else if ("sort_key".equals(key)) {
|
||||
if (value instanceof Integer)
|
||||
mapElement.layer = 5 + (Integer) value;
|
||||
} else if ("railway".equals(key) && value instanceof String) {
|
||||
mapElement.tags.add(new Tag("railway", (String) value));
|
||||
}
|
||||
}
|
||||
|
||||
if (highway == null)
|
||||
return;
|
||||
if (highway == null)
|
||||
return;
|
||||
|
||||
if (isLink)
|
||||
highway += "_link";
|
||||
if (isLink)
|
||||
highway += "_link";
|
||||
|
||||
mapElement.tags.add(new Tag("highway", highway));
|
||||
mapElement.tags.add(new Tag("highway", highway));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag rewriteTag(String key, Object value) {
|
||||
if ("kind".equals(key))
|
||||
return null;
|
||||
@Override
|
||||
public Tag rewriteTag(String key, Object value) {
|
||||
if ("kind".equals(key))
|
||||
return null;
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
String val = (value instanceof String) ? (String) value : String.valueOf(value);
|
||||
String val = (value instanceof String) ? (String) value : String.valueOf(value);
|
||||
|
||||
return new Tag(key, val);
|
||||
}
|
||||
return new Tag(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,23 +16,23 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class OsmWaterJsonTileSource extends GeoJsonTileSource {
|
||||
|
||||
public OsmWaterJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-water-areas");
|
||||
}
|
||||
public OsmWaterJsonTileSource() {
|
||||
super("http://tile.openstreetmap.us/vectiles-water-areas");
|
||||
}
|
||||
|
||||
Tag mTagWater = new Tag("natural", "water");
|
||||
Tag mTagWater = new Tag("natural", "water");
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
|
||||
mapElement.tags.add(mTagWater);
|
||||
mapElement.tags.add(mTagWater);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package org.oscim.tiling.source.geojson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RiverJsonTileSource extends GeoJsonTileSource {
|
||||
|
||||
public RiverJsonTileSource() {
|
||||
super("http://www.somebits.com:8001/rivers");
|
||||
}
|
||||
public RiverJsonTileSource() {
|
||||
super("http://www.somebits.com:8001/rivers");
|
||||
}
|
||||
|
||||
Tag mTagWater = new Tag("waterway", "river");
|
||||
Tag mTagWater = new Tag("waterway", "river");
|
||||
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
@Override
|
||||
public void decodeTags(MapElement mapElement, Map<String, Object> properties) {
|
||||
|
||||
mapElement.tags.add(mTagWater);
|
||||
mapElement.tags.add(mTagWater);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,36 +23,36 @@ import org.oscim.tiling.source.UrlTileSource;
|
||||
|
||||
public class MapnikVectorTileSource extends UrlTileSource {
|
||||
|
||||
public MapnikVectorTileSource() {
|
||||
super("http://d1s11ojcu7opje.cloudfront.net/dev/764e0b8d", "");
|
||||
setUrlFormatter(new TileUrlFormatter() {
|
||||
@Override
|
||||
public String formatTilePath(UrlTileSource tileSource, Tile tile) {
|
||||
// url formatter for mapbox streets
|
||||
byte[] hexTable = {
|
||||
'0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f'
|
||||
};
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('/');
|
||||
sb.append(hexTable[(tile.tileX) % 16]);
|
||||
sb.append(hexTable[(tile.tileY) % 16]);
|
||||
sb.append('/');
|
||||
sb.append(tile.zoomLevel);
|
||||
sb.append('/');
|
||||
sb.append(tile.tileX);
|
||||
sb.append('/');
|
||||
sb.append(tile.tileY);
|
||||
public MapnikVectorTileSource() {
|
||||
super("http://d1s11ojcu7opje.cloudfront.net/dev/764e0b8d", "");
|
||||
setUrlFormatter(new TileUrlFormatter() {
|
||||
@Override
|
||||
public String formatTilePath(UrlTileSource tileSource, Tile tile) {
|
||||
// url formatter for mapbox streets
|
||||
byte[] hexTable = {
|
||||
'0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f'
|
||||
};
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('/');
|
||||
sb.append(hexTable[(tile.tileX) % 16]);
|
||||
sb.append(hexTable[(tile.tileY) % 16]);
|
||||
sb.append('/');
|
||||
sb.append(tile.zoomLevel);
|
||||
sb.append('/');
|
||||
sb.append(tile.tileX);
|
||||
sb.append('/');
|
||||
sb.append(tile.tileY);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,16 +22,15 @@ import org.oscim.tiling.source.UrlTileSource;
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*
|
||||
*/
|
||||
public class OSciMap1TileSource extends UrlTileSource {
|
||||
|
||||
public OSciMap1TileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.osmtile");
|
||||
}
|
||||
public OSciMap1TileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.osmtile");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,12 +16,6 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.oscimap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
@@ -31,427 +25,433 @@ import org.oscim.tiling.source.PbfDecoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TileDecoder extends PbfDecoder {
|
||||
static final Logger log = LoggerFactory.getLogger(TileDecoder.class);
|
||||
|
||||
private final static float REF_TILE_SIZE = 4096.0f;
|
||||
|
||||
private static final int TAG_TILE_TAGS = 1;
|
||||
private static final int TAG_TILE_WAYS = 2;
|
||||
private static final int TAG_TILE_POLY = 3;
|
||||
private static final int TAG_TILE_NODES = 4;
|
||||
private static final int TAG_WAY_TAGS = 11;
|
||||
private static final int TAG_WAY_INDEX = 12;
|
||||
private static final int TAG_WAY_COORDS = 13;
|
||||
private static final int TAG_WAY_LAYER = 21;
|
||||
private static final int TAG_WAY_NUM_TAGS = 1;
|
||||
private static final int TAG_WAY_NUM_INDICES = 2;
|
||||
private static final int TAG_WAY_NUM_COORDS = 3;
|
||||
|
||||
private static final int TAG_NODE_TAGS = 11;
|
||||
private static final int TAG_NODE_COORDS = 12;
|
||||
private static final int TAG_NODE_LAYER = 21;
|
||||
private static final int TAG_NODE_NUM_TAGS = 1;
|
||||
private static final int TAG_NODE_NUM_COORDS = 2;
|
||||
|
||||
private int MAX_TILE_TAGS = 100;
|
||||
private Tag[] curTags = new Tag[MAX_TILE_TAGS];
|
||||
private int mCurTagCnt;
|
||||
|
||||
private ITileDataSink mSink;
|
||||
private float mScale;
|
||||
private Tile mTile;
|
||||
private final MapElement mElem;
|
||||
|
||||
TileDecoder() {
|
||||
mElem = new MapElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is)
|
||||
throws IOException {
|
||||
|
||||
setInputStream(is);
|
||||
|
||||
mTile = tile;
|
||||
mSink = sink;
|
||||
mScale = REF_TILE_SIZE / Tile.SIZE;
|
||||
return decode();
|
||||
}
|
||||
|
||||
private static final int MAX_TAGS_CACHE = 100;
|
||||
private static Map<String, Tag> tagHash =
|
||||
Collections.synchronizedMap(new LinkedHashMap<String, Tag>(MAX_TAGS_CACHE,
|
||||
0.75f,
|
||||
true) {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//@Override
|
||||
//protected boolean removeEldestEntry(Entry<String, Tag> e) {
|
||||
//if (size() < MAX_TAGS_CACHE)
|
||||
//return false;
|
||||
//return true;
|
||||
//}
|
||||
});
|
||||
|
||||
private boolean decode() throws IOException {
|
||||
int val;
|
||||
mCurTagCnt = 0;
|
||||
|
||||
while (hasData() && (val = decodeVarint32()) > 0) {
|
||||
// read tag and wire type
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_TILE_TAGS:
|
||||
decodeTileTags();
|
||||
break;
|
||||
|
||||
case TAG_TILE_WAYS:
|
||||
decodeTileWays(false);
|
||||
break;
|
||||
|
||||
case TAG_TILE_POLY:
|
||||
decodeTileWays(true);
|
||||
break;
|
||||
|
||||
case TAG_TILE_NODES:
|
||||
decodeTileNodes();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("invalid type for tile: " + tag);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileTags() throws IOException {
|
||||
String tagString = decodeString();
|
||||
|
||||
if (tagString == null || tagString.length() == 0) {
|
||||
curTags[mCurTagCnt++] = new Tag(Tag.KEY_NAME, "...");
|
||||
return false;
|
||||
}
|
||||
|
||||
Tag tag = tagHash.get(tagString);
|
||||
|
||||
if (tag == null) {
|
||||
if (tagString.startsWith(Tag.KEY_NAME))
|
||||
tag = new Tag(Tag.KEY_NAME, tagString.substring(5), false);
|
||||
else
|
||||
tag = Tag.parse(tagString);
|
||||
|
||||
if (tag != null)
|
||||
tagHash.put(tagString, tag);
|
||||
}
|
||||
|
||||
if (mCurTagCnt >= MAX_TILE_TAGS) {
|
||||
MAX_TILE_TAGS = mCurTagCnt + 10;
|
||||
Tag[] tmp = new Tag[MAX_TILE_TAGS];
|
||||
System.arraycopy(curTags, 0, tmp, 0, mCurTagCnt);
|
||||
curTags = tmp;
|
||||
}
|
||||
curTags[mCurTagCnt++] = tag;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileWays(boolean polygon) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
int end = position() + bytes;
|
||||
int indexCnt = 0;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
int layer = 5;
|
||||
|
||||
boolean fail = false;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_WAY_TAGS:
|
||||
if (!decodeWayTags(tagCnt))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_WAY_INDEX:
|
||||
decodeWayIndices(indexCnt);
|
||||
break;
|
||||
|
||||
case TAG_WAY_COORDS:
|
||||
if (coordCnt == 0) {
|
||||
log.debug(mTile + " no coordinates");
|
||||
}
|
||||
|
||||
mElem.ensurePointSize(coordCnt, false);
|
||||
int cnt = decodeInterleavedPoints(mElem.points, mScale);
|
||||
|
||||
if (cnt != coordCnt) {
|
||||
log.debug(mTile + " wrong number of coordintes "
|
||||
+ coordCnt + "/" + cnt);
|
||||
fail = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TAG_WAY_LAYER:
|
||||
layer = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_INDICES:
|
||||
indexCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("X invalid type for way: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail || indexCnt == 0 || tagCnt == 0) {
|
||||
log.debug("failed reading way: bytes:" + bytes + " index:"
|
||||
//+ (tags != null ? tags.toString() : "...") + " "
|
||||
+ indexCnt + " " + coordCnt + " " + tagCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME, remove all tiles from cache then remove this below
|
||||
//if (layer == 0)
|
||||
// layer = 5;
|
||||
mElem.type = polygon ? GeometryType.POLY : GeometryType.LINE;
|
||||
mElem.setLayer(layer);
|
||||
mSink.process(mElem);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileNodes() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
int end = position() + bytes;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
byte layer = 0;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_NODE_TAGS:
|
||||
if (!decodeWayTags(tagCnt))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_NODE_COORDS:
|
||||
int cnt = decodeNodeCoordinates(coordCnt, layer);
|
||||
if (cnt != coordCnt) {
|
||||
log.debug("X wrong number of coordintes");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_NODE_LAYER:
|
||||
layer = (byte) decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("X invalid type for node: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeNodeCoordinates(int numNodes, byte layer)
|
||||
throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
fillBuffer(bytes);
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
// read repeated sint32
|
||||
int lastX = 0;
|
||||
int lastY = 0;
|
||||
float[] coords = mElem.ensurePointSize(numNodes, false);
|
||||
|
||||
while (position() < end && cnt < numNodes) {
|
||||
int lon = deZigZag(decodeVarint32());
|
||||
int lat = deZigZag(decodeVarint32());
|
||||
lastX = lon + lastX;
|
||||
lastY = lat + lastY;
|
||||
coords[cnt++] = lastX / mScale;
|
||||
coords[cnt++] = Tile.SIZE - lastY / mScale;
|
||||
}
|
||||
|
||||
mElem.index[0] = (short) numNodes;
|
||||
mElem.type = GeometryType.POINT;
|
||||
mElem.setLayer(layer);
|
||||
mSink.process(mElem);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private boolean decodeWayTags(int tagCnt) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
mElem.tags.clear();
|
||||
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
int max = mCurTagCnt;
|
||||
|
||||
for (; position() < end; cnt++) {
|
||||
int tagNum = decodeVarint32();
|
||||
|
||||
if (tagNum < 0 || cnt == tagCnt) {
|
||||
log.debug("NULL TAG: " + mTile
|
||||
+ " invalid tag:" + tagNum
|
||||
+ " " + tagCnt + "/" + cnt);
|
||||
continue;
|
||||
}
|
||||
|
||||
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.debug("NULL TAG: " + mTile
|
||||
+ " could find tag:"
|
||||
+ tagNum + " " + tagCnt
|
||||
+ "/" + cnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagCnt != cnt) {
|
||||
log.debug("NULL TAG: " + mTile);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeWayIndices(int indexCnt) throws IOException {
|
||||
mElem.ensureIndexSize(indexCnt, false);
|
||||
|
||||
decodeVarintArray(indexCnt, mElem.index);
|
||||
|
||||
int[] index = mElem.index;
|
||||
int coordCnt = 0;
|
||||
|
||||
for (int i = 0; i < indexCnt; i++) {
|
||||
coordCnt += index[i];
|
||||
index[i] *= 2;
|
||||
}
|
||||
|
||||
// set end marker
|
||||
if (indexCnt < index.length)
|
||||
index[indexCnt] = -1;
|
||||
|
||||
return coordCnt;
|
||||
}
|
||||
|
||||
//@Override
|
||||
protected int decodeInterleavedPoints(float[] coords, float scale)
|
||||
throws IOException {
|
||||
|
||||
int bytes = decodeVarint32();
|
||||
fillBuffer(bytes);
|
||||
|
||||
int cnt = 0;
|
||||
int lastX = 0;
|
||||
int lastY = 0;
|
||||
boolean even = true;
|
||||
|
||||
byte[] buf = buffer;
|
||||
int pos = bufferPos;
|
||||
int end = pos + bytes;
|
||||
int val;
|
||||
|
||||
while (pos < end) {
|
||||
if (buf[pos] >= 0) {
|
||||
val = buf[pos++];
|
||||
|
||||
} else if (buf[pos + 1] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| buf[pos++] << 7;
|
||||
|
||||
} else if (buf[pos + 2] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++]) << 14;
|
||||
|
||||
} else if (buf[pos + 3] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++] & 0x7f) << 14
|
||||
| (buf[pos++]) << 21;
|
||||
|
||||
} else {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++] & 0x7f) << 14
|
||||
| (buf[pos++] & 0x7f) << 21
|
||||
| (buf[pos]) << 28;
|
||||
|
||||
if (buf[pos++] < 0)
|
||||
throw INVALID_VARINT;
|
||||
}
|
||||
|
||||
// zigzag decoding
|
||||
int s = ((val >>> 1) ^ -(val & 1));
|
||||
|
||||
if (even) {
|
||||
lastX = lastX + s;
|
||||
coords[cnt++] = lastX / scale;
|
||||
even = false;
|
||||
} else {
|
||||
lastY = lastY + s;
|
||||
coords[cnt++] = Tile.SIZE - lastY / scale;
|
||||
even = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != bufferPos + bytes)
|
||||
throw INVALID_PACKED_SIZE;
|
||||
|
||||
bufferPos = pos;
|
||||
|
||||
// return number of points read
|
||||
return cnt;
|
||||
}
|
||||
static final Logger log = LoggerFactory.getLogger(TileDecoder.class);
|
||||
|
||||
private final static float REF_TILE_SIZE = 4096.0f;
|
||||
|
||||
private static final int TAG_TILE_TAGS = 1;
|
||||
private static final int TAG_TILE_WAYS = 2;
|
||||
private static final int TAG_TILE_POLY = 3;
|
||||
private static final int TAG_TILE_NODES = 4;
|
||||
private static final int TAG_WAY_TAGS = 11;
|
||||
private static final int TAG_WAY_INDEX = 12;
|
||||
private static final int TAG_WAY_COORDS = 13;
|
||||
private static final int TAG_WAY_LAYER = 21;
|
||||
private static final int TAG_WAY_NUM_TAGS = 1;
|
||||
private static final int TAG_WAY_NUM_INDICES = 2;
|
||||
private static final int TAG_WAY_NUM_COORDS = 3;
|
||||
|
||||
private static final int TAG_NODE_TAGS = 11;
|
||||
private static final int TAG_NODE_COORDS = 12;
|
||||
private static final int TAG_NODE_LAYER = 21;
|
||||
private static final int TAG_NODE_NUM_TAGS = 1;
|
||||
private static final int TAG_NODE_NUM_COORDS = 2;
|
||||
|
||||
private int MAX_TILE_TAGS = 100;
|
||||
private Tag[] curTags = new Tag[MAX_TILE_TAGS];
|
||||
private int mCurTagCnt;
|
||||
|
||||
private ITileDataSink mSink;
|
||||
private float mScale;
|
||||
private Tile mTile;
|
||||
private final MapElement mElem;
|
||||
|
||||
TileDecoder() {
|
||||
mElem = new MapElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is)
|
||||
throws IOException {
|
||||
|
||||
setInputStream(is);
|
||||
|
||||
mTile = tile;
|
||||
mSink = sink;
|
||||
mScale = REF_TILE_SIZE / Tile.SIZE;
|
||||
return decode();
|
||||
}
|
||||
|
||||
private static final int MAX_TAGS_CACHE = 100;
|
||||
private static Map<String, Tag> tagHash =
|
||||
Collections.synchronizedMap(new LinkedHashMap<String, Tag>(MAX_TAGS_CACHE,
|
||||
0.75f,
|
||||
true) {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//@Override
|
||||
//protected boolean removeEldestEntry(Entry<String, Tag> e) {
|
||||
//if (size() < MAX_TAGS_CACHE)
|
||||
//return false;
|
||||
//return true;
|
||||
//}
|
||||
});
|
||||
|
||||
private boolean decode() throws IOException {
|
||||
int val;
|
||||
mCurTagCnt = 0;
|
||||
|
||||
while (hasData() && (val = decodeVarint32()) > 0) {
|
||||
// read tag and wire type
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_TILE_TAGS:
|
||||
decodeTileTags();
|
||||
break;
|
||||
|
||||
case TAG_TILE_WAYS:
|
||||
decodeTileWays(false);
|
||||
break;
|
||||
|
||||
case TAG_TILE_POLY:
|
||||
decodeTileWays(true);
|
||||
break;
|
||||
|
||||
case TAG_TILE_NODES:
|
||||
decodeTileNodes();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("invalid type for tile: " + tag);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileTags() throws IOException {
|
||||
String tagString = decodeString();
|
||||
|
||||
if (tagString == null || tagString.length() == 0) {
|
||||
curTags[mCurTagCnt++] = new Tag(Tag.KEY_NAME, "...");
|
||||
return false;
|
||||
}
|
||||
|
||||
Tag tag = tagHash.get(tagString);
|
||||
|
||||
if (tag == null) {
|
||||
if (tagString.startsWith(Tag.KEY_NAME))
|
||||
tag = new Tag(Tag.KEY_NAME, tagString.substring(5), false);
|
||||
else
|
||||
tag = Tag.parse(tagString);
|
||||
|
||||
if (tag != null)
|
||||
tagHash.put(tagString, tag);
|
||||
}
|
||||
|
||||
if (mCurTagCnt >= MAX_TILE_TAGS) {
|
||||
MAX_TILE_TAGS = mCurTagCnt + 10;
|
||||
Tag[] tmp = new Tag[MAX_TILE_TAGS];
|
||||
System.arraycopy(curTags, 0, tmp, 0, mCurTagCnt);
|
||||
curTags = tmp;
|
||||
}
|
||||
curTags[mCurTagCnt++] = tag;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileWays(boolean polygon) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
int end = position() + bytes;
|
||||
int indexCnt = 0;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
int layer = 5;
|
||||
|
||||
boolean fail = false;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_WAY_TAGS:
|
||||
if (!decodeWayTags(tagCnt))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_WAY_INDEX:
|
||||
decodeWayIndices(indexCnt);
|
||||
break;
|
||||
|
||||
case TAG_WAY_COORDS:
|
||||
if (coordCnt == 0) {
|
||||
log.debug(mTile + " no coordinates");
|
||||
}
|
||||
|
||||
mElem.ensurePointSize(coordCnt, false);
|
||||
int cnt = decodeInterleavedPoints(mElem.points, mScale);
|
||||
|
||||
if (cnt != coordCnt) {
|
||||
log.debug(mTile + " wrong number of coordintes "
|
||||
+ coordCnt + "/" + cnt);
|
||||
fail = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TAG_WAY_LAYER:
|
||||
layer = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_INDICES:
|
||||
indexCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("X invalid type for way: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail || indexCnt == 0 || tagCnt == 0) {
|
||||
log.debug("failed reading way: bytes:" + bytes + " index:"
|
||||
//+ (tags != null ? tags.toString() : "...") + " "
|
||||
+ indexCnt + " " + coordCnt + " " + tagCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME, remove all tiles from cache then remove this below
|
||||
//if (layer == 0)
|
||||
// layer = 5;
|
||||
mElem.type = polygon ? GeometryType.POLY : GeometryType.LINE;
|
||||
mElem.setLayer(layer);
|
||||
mSink.process(mElem);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileNodes() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
int end = position() + bytes;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
byte layer = 0;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_NODE_TAGS:
|
||||
if (!decodeWayTags(tagCnt))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_NODE_COORDS:
|
||||
int cnt = decodeNodeCoordinates(coordCnt, layer);
|
||||
if (cnt != coordCnt) {
|
||||
log.debug("X wrong number of coordintes");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_NODE_LAYER:
|
||||
layer = (byte) decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug("X invalid type for node: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeNodeCoordinates(int numNodes, byte layer)
|
||||
throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
fillBuffer(bytes);
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
// read repeated sint32
|
||||
int lastX = 0;
|
||||
int lastY = 0;
|
||||
float[] coords = mElem.ensurePointSize(numNodes, false);
|
||||
|
||||
while (position() < end && cnt < numNodes) {
|
||||
int lon = deZigZag(decodeVarint32());
|
||||
int lat = deZigZag(decodeVarint32());
|
||||
lastX = lon + lastX;
|
||||
lastY = lat + lastY;
|
||||
coords[cnt++] = lastX / mScale;
|
||||
coords[cnt++] = Tile.SIZE - lastY / mScale;
|
||||
}
|
||||
|
||||
mElem.index[0] = (short) numNodes;
|
||||
mElem.type = GeometryType.POINT;
|
||||
mElem.setLayer(layer);
|
||||
mSink.process(mElem);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private boolean decodeWayTags(int tagCnt) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
mElem.tags.clear();
|
||||
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
int max = mCurTagCnt;
|
||||
|
||||
for (; position() < end; cnt++) {
|
||||
int tagNum = decodeVarint32();
|
||||
|
||||
if (tagNum < 0 || cnt == tagCnt) {
|
||||
log.debug("NULL TAG: " + mTile
|
||||
+ " invalid tag:" + tagNum
|
||||
+ " " + tagCnt + "/" + cnt);
|
||||
continue;
|
||||
}
|
||||
|
||||
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.debug("NULL TAG: " + mTile
|
||||
+ " could find tag:"
|
||||
+ tagNum + " " + tagCnt
|
||||
+ "/" + cnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagCnt != cnt) {
|
||||
log.debug("NULL TAG: " + mTile);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeWayIndices(int indexCnt) throws IOException {
|
||||
mElem.ensureIndexSize(indexCnt, false);
|
||||
|
||||
decodeVarintArray(indexCnt, mElem.index);
|
||||
|
||||
int[] index = mElem.index;
|
||||
int coordCnt = 0;
|
||||
|
||||
for (int i = 0; i < indexCnt; i++) {
|
||||
coordCnt += index[i];
|
||||
index[i] *= 2;
|
||||
}
|
||||
|
||||
// set end marker
|
||||
if (indexCnt < index.length)
|
||||
index[indexCnt] = -1;
|
||||
|
||||
return coordCnt;
|
||||
}
|
||||
|
||||
//@Override
|
||||
protected int decodeInterleavedPoints(float[] coords, float scale)
|
||||
throws IOException {
|
||||
|
||||
int bytes = decodeVarint32();
|
||||
fillBuffer(bytes);
|
||||
|
||||
int cnt = 0;
|
||||
int lastX = 0;
|
||||
int lastY = 0;
|
||||
boolean even = true;
|
||||
|
||||
byte[] buf = buffer;
|
||||
int pos = bufferPos;
|
||||
int end = pos + bytes;
|
||||
int val;
|
||||
|
||||
while (pos < end) {
|
||||
if (buf[pos] >= 0) {
|
||||
val = buf[pos++];
|
||||
|
||||
} else if (buf[pos + 1] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| buf[pos++] << 7;
|
||||
|
||||
} else if (buf[pos + 2] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++]) << 14;
|
||||
|
||||
} else if (buf[pos + 3] >= 0) {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++] & 0x7f) << 14
|
||||
| (buf[pos++]) << 21;
|
||||
|
||||
} else {
|
||||
val = (buf[pos++] & 0x7f)
|
||||
| (buf[pos++] & 0x7f) << 7
|
||||
| (buf[pos++] & 0x7f) << 14
|
||||
| (buf[pos++] & 0x7f) << 21
|
||||
| (buf[pos]) << 28;
|
||||
|
||||
if (buf[pos++] < 0)
|
||||
throw INVALID_VARINT;
|
||||
}
|
||||
|
||||
// zigzag decoding
|
||||
int s = ((val >>> 1) ^ -(val & 1));
|
||||
|
||||
if (even) {
|
||||
lastX = lastX + s;
|
||||
coords[cnt++] = lastX / scale;
|
||||
even = false;
|
||||
} else {
|
||||
lastY = lastY + s;
|
||||
coords[cnt++] = Tile.SIZE - lastY / scale;
|
||||
even = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != bufferPos + bytes)
|
||||
throw INVALID_PACKED_SIZE;
|
||||
|
||||
bufferPos = pos;
|
||||
|
||||
// return number of points read
|
||||
return cnt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
*/
|
||||
package org.oscim.tiling.source.oscimap2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.Tag;
|
||||
@@ -33,295 +29,299 @@ import org.oscim.tiling.source.UrlTileSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class OSciMap2TileSource extends UrlTileSource {
|
||||
|
||||
public OSciMap2TileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.osmtile");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
public OSciMap2TileSource(String url) {
|
||||
super(url, "/{Z}/{X}/{Y}.osmtile");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine());
|
||||
}
|
||||
|
||||
static class TileDecoder extends PbfDecoder {
|
||||
static final Logger log = LoggerFactory.getLogger(TileDecoder.class);
|
||||
private static final int TAG_TILE_NUM_TAGS = 1;
|
||||
private static final int TAG_TILE_TAG_KEYS = 2;
|
||||
private static final int TAG_TILE_TAG_VALUES = 3;
|
||||
static class TileDecoder extends PbfDecoder {
|
||||
static final Logger log = LoggerFactory.getLogger(TileDecoder.class);
|
||||
private static final int TAG_TILE_NUM_TAGS = 1;
|
||||
private static final int TAG_TILE_TAG_KEYS = 2;
|
||||
private static final int TAG_TILE_TAG_VALUES = 3;
|
||||
|
||||
private static final int TAG_TILE_LINE = 11;
|
||||
private static final int TAG_TILE_POLY = 12;
|
||||
private static final int TAG_TILE_POINT = 13;
|
||||
// private static final int TAG_TILE_LABEL = 21;
|
||||
// private static final int TAG_TILE_WATER = 31;
|
||||
private static final int TAG_TILE_LINE = 11;
|
||||
private static final int TAG_TILE_POLY = 12;
|
||||
private static final int TAG_TILE_POINT = 13;
|
||||
// private static final int TAG_TILE_LABEL = 21;
|
||||
// private static final int TAG_TILE_WATER = 31;
|
||||
|
||||
private static final int TAG_ELEM_NUM_INDICES = 1;
|
||||
private static final int TAG_ELEM_TAGS = 11;
|
||||
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 static final int TAG_ELEM_NUM_INDICES = 1;
|
||||
private static final int TAG_ELEM_TAGS = 11;
|
||||
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 int[] mSArray;
|
||||
private final TagSet mTileTags;
|
||||
private final MapElement mElem;
|
||||
private int[] 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 ITileDataSink mMapDataSink;
|
||||
|
||||
// scale coordinates to tile size
|
||||
private final static float REF_TILE_SIZE = 4096.0f;
|
||||
private float mScale;
|
||||
|
||||
TileDecoder() {
|
||||
mElem = new MapElement();
|
||||
mTileTags = new TagSet(20);
|
||||
TileDecoder() {
|
||||
mElem = new MapElement();
|
||||
mTileTags = new TagSet(20);
|
||||
|
||||
// temp array for decoding shorts
|
||||
mSArray = new int[100];
|
||||
}
|
||||
// temp array for decoding shorts
|
||||
mSArray = new int[100];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is)
|
||||
throws IOException {
|
||||
@Override
|
||||
public boolean decode(Tile tile, ITileDataSink sink, InputStream is)
|
||||
throws IOException {
|
||||
|
||||
readUnsignedInt(is, buffer);
|
||||
readUnsignedInt(is, buffer);
|
||||
|
||||
setInputStream(is);
|
||||
setInputStream(is);
|
||||
|
||||
mTile = tile;
|
||||
mMapDataSink = sink;
|
||||
mTile = tile;
|
||||
mMapDataSink = sink;
|
||||
|
||||
mScale = REF_TILE_SIZE / Tile.SIZE;
|
||||
mScale = REF_TILE_SIZE / Tile.SIZE;
|
||||
|
||||
mTileTags.clear();
|
||||
mTileTags.clear();
|
||||
|
||||
int val;
|
||||
int numTags = 0;
|
||||
int val;
|
||||
int numTags = 0;
|
||||
|
||||
while (hasData() && (val = decodeVarint32()) > 0) {
|
||||
// read tag and wire type
|
||||
int tag = (val >> 3);
|
||||
while (hasData() && (val = decodeVarint32()) > 0) {
|
||||
// read tag and wire type
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_TILE_NUM_TAGS:
|
||||
numTags = decodeVarint32();
|
||||
break;
|
||||
switch (tag) {
|
||||
case TAG_TILE_NUM_TAGS:
|
||||
numTags = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_TILE_TAG_KEYS:
|
||||
int len = numTags;
|
||||
if (mSArray.length < len)
|
||||
mSArray = new int[len];
|
||||
case TAG_TILE_TAG_KEYS:
|
||||
int len = numTags;
|
||||
if (mSArray.length < len)
|
||||
mSArray = new int[len];
|
||||
|
||||
decodeVarintArray(numTags, mSArray);
|
||||
break;
|
||||
decodeVarintArray(numTags, mSArray);
|
||||
break;
|
||||
|
||||
case TAG_TILE_TAG_VALUES:
|
||||
// this wastes one byte, as there is no packed string...
|
||||
decodeTileTags();
|
||||
break;
|
||||
case TAG_TILE_TAG_VALUES:
|
||||
// this wastes one byte, as there is no packed string...
|
||||
decodeTileTags();
|
||||
break;
|
||||
|
||||
case TAG_TILE_LINE:
|
||||
case TAG_TILE_POLY:
|
||||
case TAG_TILE_POINT:
|
||||
decodeTileElement(tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug(mTile + " invalid type for tile: " + tag);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case TAG_TILE_LINE:
|
||||
case TAG_TILE_POLY:
|
||||
case TAG_TILE_POINT:
|
||||
decodeTileElement(tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug(mTile + " invalid type for tile: " + tag);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileTags() throws IOException {
|
||||
String tagString = decodeString();
|
||||
private boolean decodeTileTags() throws IOException {
|
||||
String tagString = decodeString();
|
||||
|
||||
int curTag = mTileTags.numTags;
|
||||
int curTag = mTileTags.numTags;
|
||||
|
||||
String key = Tags.keys[mSArray[curTag]];
|
||||
Tag tag;
|
||||
String key = Tags.keys[mSArray[curTag]];
|
||||
Tag tag;
|
||||
|
||||
if (key == Tag.KEY_NAME)
|
||||
tag = new Tag(key, tagString, false);
|
||||
else
|
||||
tag = new Tag(key, tagString, true);
|
||||
if (debug)
|
||||
log.debug(mTile + " add tag: " + curTag + " " + tag);
|
||||
if (key == Tag.KEY_NAME)
|
||||
tag = new Tag(key, tagString, false);
|
||||
else
|
||||
tag = new Tag(key, tagString, true);
|
||||
if (debug)
|
||||
log.debug(mTile + " add tag: " + curTag + " " + tag);
|
||||
|
||||
mTileTags.add(tag);
|
||||
mTileTags.add(tag);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeWayIndices(int indexCnt) throws IOException {
|
||||
mElem.ensureIndexSize(indexCnt, false);
|
||||
decodeVarintArray(indexCnt, mElem.index);
|
||||
private int decodeWayIndices(int indexCnt) throws IOException {
|
||||
mElem.ensureIndexSize(indexCnt, false);
|
||||
decodeVarintArray(indexCnt, mElem.index);
|
||||
|
||||
int[] index = mElem.index;
|
||||
int coordCnt = 0;
|
||||
int[] index = mElem.index;
|
||||
int coordCnt = 0;
|
||||
|
||||
for (int i = 0; i < indexCnt; i++) {
|
||||
coordCnt += index[i];
|
||||
index[i] *= 2;
|
||||
}
|
||||
// set end marker
|
||||
if (indexCnt < index.length)
|
||||
index[indexCnt] = -1;
|
||||
|
||||
return coordCnt;
|
||||
}
|
||||
|
||||
private boolean decodeTileElement(int type) throws IOException {
|
||||
|
||||
int bytes = decodeVarint32();
|
||||
short[] index = null;
|
||||
|
||||
int end = position() + bytes;
|
||||
int indexCnt = 1;
|
||||
|
||||
boolean fail = false;
|
||||
|
||||
int coordCnt = 0;
|
||||
if (type == TAG_TILE_POINT) {
|
||||
coordCnt = 1;
|
||||
mElem.index[0] = 2;
|
||||
}
|
||||
|
||||
mElem.layer = 5;
|
||||
//mElem.height = 0;
|
||||
//mElem.minHeight = 0;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_ELEM_TAGS:
|
||||
if (!decodeElementTags())
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_ELEM_NUM_INDICES:
|
||||
indexCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_INDEX:
|
||||
coordCnt = decodeWayIndices(indexCnt);
|
||||
break;
|
||||
|
||||
case TAG_ELEM_COORDS:
|
||||
if (coordCnt == 0) {
|
||||
log.debug(mTile + " no coordinates");
|
||||
}
|
||||
|
||||
mElem.ensurePointSize(coordCnt, false);
|
||||
int cnt = decodeInterleavedPoints(mElem, mScale);
|
||||
|
||||
if (cnt != coordCnt) {
|
||||
log.debug(mTile + " wrong number of coordintes");
|
||||
fail = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_ELEM_LAYER:
|
||||
mElem.layer = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_HEIGHT:
|
||||
//mElem.height =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_MIN_HEIGHT:
|
||||
//mElem.minHeight =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_PRIORITY:
|
||||
//mElem.priority =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug(mTile + " invalid type for way: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail || indexCnt == 0) {
|
||||
log.debug(mTile + " failed reading way: bytes:" + bytes + " index:"
|
||||
+ (Arrays.toString(index)) + " tag:"
|
||||
+ (mElem.tags.numTags > 0 ? Arrays.deepToString(mElem.tags.tags) : "null")
|
||||
+ " " + indexCnt + " " + coordCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TAG_TILE_LINE:
|
||||
mElem.type = GeometryType.LINE;
|
||||
break;
|
||||
case TAG_TILE_POLY:
|
||||
mElem.type = GeometryType.POLY;
|
||||
break;
|
||||
case TAG_TILE_POINT:
|
||||
mElem.type = GeometryType.POINT;
|
||||
break;
|
||||
}
|
||||
|
||||
mMapDataSink.process(mElem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeElementTags() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
mElem.tags.clear();
|
||||
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
int max = mTileTags.numTags - 1;
|
||||
|
||||
for (; position() < end; cnt++) {
|
||||
int tagNum = decodeVarint32();
|
||||
|
||||
if (tagNum < 0) {
|
||||
log.debug("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.debug("NULL TAG: " + mTile
|
||||
+ " could not find tag:"
|
||||
+ tagNum + " " + cnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
mElem.tags.add(mTileTags.tags[tagNum]);
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
log.debug("got no TAG!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < indexCnt; i++) {
|
||||
coordCnt += index[i];
|
||||
index[i] *= 2;
|
||||
}
|
||||
// set end marker
|
||||
if (indexCnt < index.length)
|
||||
index[indexCnt] = -1;
|
||||
|
||||
return coordCnt;
|
||||
}
|
||||
|
||||
private boolean decodeTileElement(int type) throws IOException {
|
||||
|
||||
int bytes = decodeVarint32();
|
||||
short[] index = null;
|
||||
|
||||
int end = position() + bytes;
|
||||
int indexCnt = 1;
|
||||
|
||||
boolean fail = false;
|
||||
|
||||
int coordCnt = 0;
|
||||
if (type == TAG_TILE_POINT) {
|
||||
coordCnt = 1;
|
||||
mElem.index[0] = 2;
|
||||
}
|
||||
|
||||
mElem.layer = 5;
|
||||
//mElem.height = 0;
|
||||
//mElem.minHeight = 0;
|
||||
|
||||
while (position() < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
|
||||
switch (tag) {
|
||||
case TAG_ELEM_TAGS:
|
||||
if (!decodeElementTags())
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TAG_ELEM_NUM_INDICES:
|
||||
indexCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_INDEX:
|
||||
coordCnt = decodeWayIndices(indexCnt);
|
||||
break;
|
||||
|
||||
case TAG_ELEM_COORDS:
|
||||
if (coordCnt == 0) {
|
||||
log.debug(mTile + " no coordinates");
|
||||
}
|
||||
|
||||
mElem.ensurePointSize(coordCnt, false);
|
||||
int cnt = decodeInterleavedPoints(mElem, mScale);
|
||||
|
||||
if (cnt != coordCnt) {
|
||||
log.debug(mTile + " wrong number of coordintes");
|
||||
fail = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_ELEM_LAYER:
|
||||
mElem.layer = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_HEIGHT:
|
||||
//mElem.height =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_MIN_HEIGHT:
|
||||
//mElem.minHeight =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_ELEM_PRIORITY:
|
||||
//mElem.priority =
|
||||
decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
log.debug(mTile + " invalid type for way: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (fail || indexCnt == 0) {
|
||||
log.debug(mTile + " failed reading way: bytes:" + bytes + " index:"
|
||||
+ (Arrays.toString(index)) + " tag:"
|
||||
+ (mElem.tags.numTags > 0 ? Arrays.deepToString(mElem.tags.tags) : "null")
|
||||
+ " " + indexCnt + " " + coordCnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TAG_TILE_LINE:
|
||||
mElem.type = GeometryType.LINE;
|
||||
break;
|
||||
case TAG_TILE_POLY:
|
||||
mElem.type = GeometryType.POLY;
|
||||
break;
|
||||
case TAG_TILE_POINT:
|
||||
mElem.type = GeometryType.POINT;
|
||||
break;
|
||||
}
|
||||
|
||||
mMapDataSink.process(mElem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeElementTags() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
mElem.tags.clear();
|
||||
|
||||
int cnt = 0;
|
||||
int end = position() + bytes;
|
||||
int max = mTileTags.numTags - 1;
|
||||
|
||||
for (; position() < end; cnt++) {
|
||||
int tagNum = decodeVarint32();
|
||||
|
||||
if (tagNum < 0) {
|
||||
log.debug("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.debug("NULL TAG: " + mTile
|
||||
+ " could not find tag:"
|
||||
+ tagNum + " " + cnt);
|
||||
return false;
|
||||
}
|
||||
|
||||
mElem.tags.add(mTileTags.tags[tagNum]);
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
log.debug("got no TAG!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user