Add MapElement as a buffer object to pass map elements to TileGenerator

- unify IMapDatabase callback
This commit is contained in:
Hannes Janetzek 2013-04-21 17:44:57 +02:00
parent e0805cdf2d
commit 119f2ac14c
8 changed files with 271 additions and 267 deletions

View File

@ -0,0 +1,58 @@
/*
* Copyright 2012 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.core;
/**
* MapElement is created by MapDatabase(s) and passed to TileGenerator
* via IMapDatabaseCallback.renderElement() TileGenerator processes the
* data into MapTile.layers.
* -----
* This is really just a buffer object that belongs to MapDatabase, so
* dont keep a reference to it when passed as parameter.
*/
public class MapElement extends GeometryBuffer {
public static final int GEOM_NONE = 0;
public static final int GEOM_POINT = 1;
public static final int GEOM_LINE = 2;
public static final int GEOM_POLY = 3;
// osm layer of the way.
public int layer;
// osm tags of the way.
public Tag[] tags;
// GEOM_*
public int geometryType;
// ---- random stuff, to be removed ----
// building tags
public int height;
public int minHeight;
public int priority;
public MapElement() {
super(4096, 128);
}
public MapElement(int points, int indices) {
super(points, indices);
}
public void set(Tag[] tags, int layer, int type) {
this.layer = layer;
this.tags = tags;
this.geometryType = type;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2010, 2011, 2012 mapsforge.org * Copyright 2013 Hannes Janetzek
* *
* This program is free software: you can redistribute it and/or modify it under the * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -14,77 +14,16 @@
*/ */
package org.oscim.database; package org.oscim.database;
import org.oscim.core.GeometryBuffer; import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.database.mapfile.MapDatabase;
/** /**
* Callback methods which can be triggered from the {@link MapDatabase}. * MapDatabase callbacks (implemented by TileGenerator)
* ____ * ____
* NOTE: All parameters passed belong to the caller! i.e. dont hold * NOTE: All parameters passed belong to the caller! i.e. dont hold
* references to any arrays after callback function returns. * references to any arrays after callback function returns.
*/ */
public interface IMapDatabaseCallback { public interface IMapDatabaseCallback {
public class WayData{ void renderElement(MapElement element);
public WayData(){
}
public WayData(GeometryBuffer geom, Tag[] tags) {
this.geom = geom;
this.tags = tags;
}
public GeometryBuffer geom;
// closed == geometry is polygon
public boolean closed;
// osm layer of the way.
public int layer;
// osm tags of the way.
public Tag[] tags;
// building tags
public int height;
public int minHeight;
// unused
public int priority;
}
/**
* Renders a single point of interest node (POI).
*
* @param layer
* the layer of the node.
* @param tags
* the tags of the node.
*/
void renderPOI(byte layer, Tag[] tags, GeometryBuffer geom);
/**
* Renders water background for the current tile.
*/
void renderWaterBackground();
/**
* Renders a single way or area.
*
*/
void renderWay(WayData way);
// /**
// * TBD: check if way will be rendered before decoding - MUST be called before renderWay!
// *
// * @param tags
// * ...
// * @param closed
// * ...
// * @return true if the way will be rendered (i.e. found match in
// * RenderTheme)
// */
// boolean matchWay(Tag[] tags, boolean closed);
} }

View File

@ -18,12 +18,11 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import org.oscim.core.GeometryBuffer; import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase; import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.database.OpenResult; import org.oscim.database.OpenResult;
import org.oscim.database.QueryResult; import org.oscim.database.QueryResult;
@ -198,8 +197,9 @@ public class MapDatabase implements IMapDatabase {
private int mTileLongitude; private int mTileLongitude;
private int[] mIntBuffer; private int[] mIntBuffer;
private final GeometryBuffer mGeom = new GeometryBuffer(1 << 14, 1 << 8); //private final GeometryBuffer mElem = new GeometryBuffer(1 << 14, 1 << 8);
private final WayData mWay = new WayData(); //private final WayData mWay = new WayData();
private final MapElement mElem = new MapElement();
private int minLat, minLon; private int minLat, minLon;
private Tile mTile; private Tile mTile;
@ -668,10 +668,18 @@ public class MapDatabase implements IMapDatabase {
double sinLat = Math.sin(latitude * PI180); double sinLat = Math.sin(latitude * PI180);
latitude = (int) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy); latitude = (int) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
mGeom.points[0] = longitude; mElem.clear();
mGeom.points[1] = latitude;
mGeom.index[0] = 2; mElem.startPoints();
mapDatabaseCallback.renderPOI(layer, curTags, mGeom); mElem.addPoint(longitude, latitude);
mElem.set(curTags, layer, MapElement.GEOM_POINT);
mapDatabaseCallback.renderElement(mElem);
// mGeom.points[0] = longitude;
// mGeom.points[1] = latitude;
// mGeom.index[0] = 2;
// mapDatabaseCallback.renderPOI(layer, curTags, mGeom);
} }
@ -687,11 +695,11 @@ public class MapDatabase implements IMapDatabase {
} }
//short[] wayLengths = new short[numBlocks]; //short[] wayLengths = new short[numBlocks];
short[] wayLengths = mGeom.ensureIndexSize(numBlocks, false); short[] wayLengths = mElem.ensureIndexSize(numBlocks, false);
if (wayLengths.length > numBlocks) if (wayLengths.length > numBlocks)
wayLengths[numBlocks] = -1; wayLengths[numBlocks] = -1;
mGeom.pointPos = 0; mElem.pointPos = 0;
// read the way coordinate blocks // read the way coordinate blocks
for (int coordinateBlock = 0; coordinateBlock < numBlocks; ++coordinateBlock) { for (int coordinateBlock = 0; coordinateBlock < numBlocks; ++coordinateBlock) {
@ -723,8 +731,8 @@ public class MapDatabase implements IMapDatabase {
mReadBuffer.readSignedInt(buffer, length); mReadBuffer.readSignedInt(buffer, length);
float[] outBuffer = mGeom.ensurePointSize(mGeom.pointPos + length, true); float[] outBuffer = mElem.ensurePointSize(mElem.pointPos + length, true);
int pointPos = mGeom.pointPos; int pointPos = mElem.pointPos;
// get the first way node latitude offset (VBE-S) // get the first way node latitude offset (VBE-S)
int wayNodeLatitude = mTileLatitude + buffer[0]; int wayNodeLatitude = mTileLatitude + buffer[0];
@ -761,7 +769,7 @@ public class MapDatabase implements IMapDatabase {
} }
} }
mGeom.pointPos = pointPos; mElem.pointPos = pointPos;
return cnt; return cnt;
} }
@ -770,8 +778,8 @@ public class MapDatabase implements IMapDatabase {
int[] buffer = mIntBuffer; int[] buffer = mIntBuffer;
mReadBuffer.readSignedInt(buffer, length); mReadBuffer.readSignedInt(buffer, length);
float[] outBuffer = mGeom.ensurePointSize(mGeom.pointPos + length, true); float[] outBuffer = mElem.ensurePointSize(mElem.pointPos + length, true);
int pointPos = mGeom.pointPos; int pointPos = mElem.pointPos;
// get the first way node latitude single-delta offset (VBE-S) // get the first way node latitude single-delta offset (VBE-S)
int wayNodeLatitude = mTileLatitude + buffer[0]; int wayNodeLatitude = mTileLatitude + buffer[0];
@ -803,7 +811,7 @@ public class MapDatabase implements IMapDatabase {
} }
} }
mGeom.pointPos = pointPos; mElem.pointPos = pointPos;
return cnt; return cnt;
} }
@ -974,18 +982,18 @@ public class MapDatabase implements IMapDatabase {
return false; return false;
// wayDataContainer.textPos = textPos; // wayDataContainer.textPos = textPos;
int l = mGeom.index[0]; int l = mElem.index[0];
boolean closed = mGeom.points[0] == mGeom.points[l - 2] boolean closed = mElem.points[0] == mElem.points[l - 2]
&& mGeom.points[1] == mGeom.points[l - 1]; && mElem.points[1] == mElem.points[l - 1];
projectToTile(mGeom.points, mGeom.index); projectToTile(mElem.points, mElem.index);
mWay.geom = mGeom; mElem.layer = layer;
mWay.layer = layer;
mWay.closed = closed;
mWay.tags = curTags;
mapDatabaseCallback.renderWay(mWay); mElem.geometryType = closed ? MapElement.GEOM_POLY : MapElement.GEOM_LINE;
mElem.tags = curTags;
mapDatabaseCallback.renderElement(mElem);
} }
} }

View File

@ -23,12 +23,11 @@ import java.util.Arrays;
import org.oscim.core.BoundingBox; import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint; import org.oscim.core.GeoPoint;
import org.oscim.core.GeometryBuffer; import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase; import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.database.OpenResult; import org.oscim.database.OpenResult;
@ -75,7 +74,8 @@ public class MapDatabase implements IMapDatabase {
private final boolean debug = false; private final boolean debug = false;
private LwHttp lwHttp; private LwHttp lwHttp;
private final WayData mWay = new WayData(); //private final WayData mWay = new WayData();
private final MapElement mElem = new MapElement();
@Override @Override
public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) { public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) {
@ -211,7 +211,7 @@ public class MapDatabase implements IMapDatabase {
} }
// /////////////// hand sewed tile protocol buffers decoder /////////////// // /////////////// hand sewed tile protocol buffers decoder ///////////////
private final int MAX_WAY_COORDS = 1 << 14; //private final int MAX_WAY_COORDS = 1 << 14;
// overall bytes of content processed // overall bytes of content processed
private int mBytesProcessed; private int mBytesProcessed;
@ -240,7 +240,7 @@ public class MapDatabase implements IMapDatabase {
//private float[] mTmpCoords; //private float[] mTmpCoords;
//private short[] mIndices = new short[10]; //private short[] mIndices = new short[10];
private final GeometryBuffer mGeom = new GeometryBuffer(MAX_WAY_COORDS, 128); //private final GeometryBuffer mElem = new GeometryBuffer(MAX_WAY_COORDS, 128);
private Tag[][] mElementTags; private Tag[][] mElementTags;
@ -315,9 +315,9 @@ public class MapDatabase implements IMapDatabase {
} }
private int decodeWayIndices(int indexCnt) throws IOException { private int decodeWayIndices(int indexCnt) throws IOException {
mGeom.index = decodeShortArray(indexCnt, mGeom.index); mElem.index = decodeShortArray(indexCnt, mElem.index);
short[] index = mGeom.index; short[] index = mElem.index;
int coordCnt = 0; int coordCnt = 0;
for (int i = 0; i < indexCnt; i++) { for (int i = 0; i < indexCnt; i++) {
@ -348,13 +348,13 @@ public class MapDatabase implements IMapDatabase {
int coordCnt = 0; int coordCnt = 0;
if (type == TAG_TILE_POINT){ if (type == TAG_TILE_POINT){
coordCnt = 2; coordCnt = 2;
mGeom.index[0] = 2; mElem.index[0] = 2;
} }
mWay.layer = 5; mElem.layer = 5;
mWay.priority = 0; mElem.priority = 0;
mWay.height = 0; mElem.height = 0;
mWay.minHeight = 0; mElem.minHeight = 0;
while (mBytesProcessed < end) { while (mBytesProcessed < end) {
// read tag and wire type // read tag and wire type
@ -391,19 +391,19 @@ public class MapDatabase implements IMapDatabase {
break; break;
case TAG_ELEM_LAYER: case TAG_ELEM_LAYER:
mWay.layer = decodeVarint32(); mElem.layer = decodeVarint32();
break; break;
case TAG_ELEM_HEIGHT: case TAG_ELEM_HEIGHT:
mWay.height= decodeVarint32(); mElem.height= decodeVarint32();
break; break;
case TAG_ELEM_MIN_HEIGHT: case TAG_ELEM_MIN_HEIGHT:
mWay.minHeight = decodeVarint32(); mElem.minHeight = decodeVarint32();
break; break;
case TAG_ELEM_PRIORITY: case TAG_ELEM_PRIORITY:
mWay.priority = decodeVarint32(); mElem.priority = decodeVarint32();
break; break;
default: default:
@ -419,23 +419,22 @@ public class MapDatabase implements IMapDatabase {
return false; return false;
} }
mWay.geom = mGeom; mElem.tags = tags;
mWay.tags = tags;
switch (type) { switch (type) {
case TAG_TILE_LINE: case TAG_TILE_LINE:
mWay.closed = false; mElem.geometryType= MapElement.GEOM_LINE;
mMapGenerator.renderWay(mWay);
break; break;
case TAG_TILE_POLY: case TAG_TILE_POLY:
mWay.closed = true; mElem.geometryType= MapElement.GEOM_POLY;
mMapGenerator.renderWay(mWay);
break; break;
case TAG_TILE_POINT: case TAG_TILE_POINT:
mMapGenerator.renderPOI((byte) mWay.layer, tags, mGeom); mElem.geometryType= MapElement.GEOM_POINT;
break; break;
} }
mMapGenerator.renderElement(mElem);
return true; return true;
} }
@ -506,7 +505,7 @@ public class MapDatabase implements IMapDatabase {
float scale = mScaleFactor; float scale = mScaleFactor;
float[] coords = mGeom.ensurePointSize(nodes, false); float[] coords = mElem.ensurePointSize(nodes, false);
// if (nodes * 2 > coords.length) { // if (nodes * 2 > coords.length) {
// Log.d(TAG, mTile + " increase way coord buffer to " + (nodes * 2)); // Log.d(TAG, mTile + " increase way coord buffer to " + (nodes * 2));

View File

@ -37,11 +37,11 @@ import java.util.Map;
import org.oscim.core.BoundingBox; import org.oscim.core.BoundingBox;
import org.oscim.core.GeoPoint; import org.oscim.core.GeoPoint;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase; import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.database.OpenResult; import org.oscim.database.OpenResult;
@ -103,7 +103,7 @@ public class MapDatabase implements IMapDatabase {
private static final int MAX_TAGS_CACHE = 100; private static final int MAX_TAGS_CACHE = 100;
private final WayData mWay = new WayData(); private final MapElement mElement = new MapElement();
private static Map<String, Tag> tagHash = Collections private static Map<String, Tag> tagHash = Collections
.synchronizedMap(new LinkedHashMap<String, Tag>( .synchronizedMap(new LinkedHashMap<String, Tag>(
@ -454,12 +454,13 @@ public class MapDatabase implements IMapDatabase {
if (layer == 0) if (layer == 0)
layer = 5; layer = 5;
mWay.geom = mGeom; mElement.set(tags, layer, polygon ? MapElement.GEOM_POLY : MapElement.GEOM_LINE);
mWay.tags = tags;
mWay.layer = layer;
mWay.closed = polygon;
mMapGenerator.renderWay(mWay); // mElement.tags = tags;
// mElement.layer = layer;
// mElement.closed = polygon;
mMapGenerator.renderElement(mElement);
return true; return true;
} }
@ -535,8 +536,12 @@ public class MapDatabase implements IMapDatabase {
coords[cnt++] = Tile.SIZE - lastY / scale; coords[cnt++] = Tile.SIZE - lastY / scale;
} }
mGeom.index[0] = (short)numNodes;
mMapGenerator.renderPOI(layer, tags, mGeom); mElement.index[0] = (short)numNodes;
mElement.set(tags, layer, MapElement.GEOM_POINT);
mMapGenerator.renderElement(mElement);
//mMapGenerator.renderPOI(layer, tags, mGeom);
return cnt; return cnt;
} }

View File

@ -14,19 +14,21 @@
*/ */
package org.oscim.database.test; package org.oscim.database.test;
import static org.oscim.core.MapElement.GEOM_LINE;
import static org.oscim.core.MapElement.GEOM_POINT;
import static org.oscim.core.MapElement.GEOM_POLY;
import org.oscim.core.BoundingBox; import org.oscim.core.BoundingBox;
import org.oscim.core.GeometryBuffer; import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase; import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.database.OpenResult; import org.oscim.database.OpenResult;
import org.oscim.database.QueryResult; import org.oscim.database.QueryResult;
import org.oscim.generator.JobTile; import org.oscim.generator.JobTile;
/** /**
* *
* *
@ -56,13 +58,10 @@ public class MapDatabase implements IMapDatabase {
private boolean mOpenFile = false; private boolean mOpenFile = false;
private final WayData mWay; private final MapElement mElem;
private final GeometryBuffer mGeom;
public MapDatabase() { public MapDatabase() {
mGeom = new GeometryBuffer(1, 1); mElem = new MapElement();
mWay = new WayData();
mWay.geom = mGeom;
} }
@Override @Override
@ -70,100 +69,91 @@ public class MapDatabase implements IMapDatabase {
IMapDatabaseCallback mapDatabaseCallback) { IMapDatabaseCallback mapDatabaseCallback) {
int size = Tile.SIZE; int size = Tile.SIZE;
GeometryBuffer g = mGeom; MapElement e = mElem;
float x1 = -1; float x1 = -1;
float y1 = -1; float y1 = -1;
float x2 = size + 1; float x2 = size + 1;
float y2 = size + 1; float y2 = size + 1;
g.clear(); e.clear();
g.startPolygon(); e.startPolygon();
g.addPoint(x1, y1); e.addPoint(x1, y1);
g.addPoint(x2, y1); e.addPoint(x2, y1);
g.addPoint(x2, y2); e.addPoint(x2, y2);
g.addPoint(x1, y2); e.addPoint(x1, y2);
y1 = 40; y1 = 40;
y2 = size - 40; y2 = size - 40;
x1 = 40; x1 = 40;
x2 = size - 40; x2 = size - 40;
g.startHole(); e.startHole();
g.addPoint(x1, y1); e.addPoint(x1, y1);
g.addPoint(x2, y1); e.addPoint(x2, y1);
g.addPoint(x2, y2); e.addPoint(x2, y2);
g.addPoint(x1, y2); e.addPoint(x1, y2);
mWay.tags = mTags; e.set(mTags, 0, GEOM_POLY);
mWay.layer = 0; mapDatabaseCallback.renderElement(e);
mWay.closed = true;
mapDatabaseCallback.renderWay(mWay); e.clear();
g.clear();
// middle horizontal // middle horizontal
g.startLine(); e.startLine();
g.addPoint(0, size / 2); e.addPoint(0, size / 2);
g.addPoint(size, size / 2); e.addPoint(size, size / 2);
// center up // center up
g.startLine(); e.startLine();
g.addPoint(size / 2, -size / 2); e.addPoint(size / 2, -size / 2);
g.addPoint(size / 2, size / 2); e.addPoint(size / 2, size / 2);
// center down // center down
g.startLine(); e.startLine();
g.addPoint(size / 2, size / 2); e.addPoint(size / 2, size / 2);
g.addPoint(size / 2, size / 2 + size); e.addPoint(size / 2, size / 2 + size);
mWay.closed = false; e.set(mTagsWay, 0, GEOM_LINE);
mWay.layer = 0; mapDatabaseCallback.renderElement(e);
mWay.tags = mTagsWay;
mapDatabaseCallback.renderWay(mWay);
g.clear(); e.clear();
// left-top to center // left-top to center
g.startLine(); e.startLine();
g.addPoint(size / 2, size / 2); e.addPoint(size / 2, size / 2);
g.addPoint(10, 10); e.addPoint(10, 10);
g.startLine(); e.startLine();
g.addPoint(0, 10); e.addPoint(0, 10);
g.addPoint(size, 10); e.addPoint(size, 10);
g.startLine(); e.startLine();
g.addPoint(10, 0); e.addPoint(10, 0);
g.addPoint(10, size); e.addPoint(10, size);
mWay.closed = false; e.set(mTagsWay, 1, GEOM_LINE);
mWay.layer = 1; mapDatabaseCallback.renderElement(e);
mWay.tags = mTagsWay;
mapDatabaseCallback.renderWay(mWay);
g.clear(); e.clear();
g.startPolygon(); e.startPolygon();
float r = size / 2; float r = size / 2;
for (int i = 0; i < 360; i += 4) { for (int i = 0; i < 360; i += 4) {
double d = Math.toRadians(i); double d = Math.toRadians(i);
g.addPoint(r + (float) Math.cos(d) * (r - 40), r + (float) Math.sin(d) * (r - 40)); e.addPoint(r + (float) Math.cos(d) * (r - 40), r + (float) Math.sin(d) * (r - 40));
} }
mWay.closed = true; e.set(mTagsBoundary, 1, GEOM_LINE);
mWay.layer = 1; mapDatabaseCallback.renderElement(e);
mWay.tags = mTagsBoundary;
mapDatabaseCallback.renderWay(mWay);
e.clear();
e.startPoints();
e.addPoint(size/2, size/2);
g.clear();
g.startPoints();
g.addPoint(size/2, size/2);
mTagsPlace[1] = new Tag("name", tile.toString()); mTagsPlace[1] = new Tag("name", tile.toString());
e.set(mTagsPlace, 0, GEOM_POINT);
mapDatabaseCallback.renderPOI((byte)0, mTagsPlace, g); mapDatabaseCallback.renderElement(e);
return QueryResult.SUCCESS; return QueryResult.SUCCESS;
} }

View File

@ -13,12 +13,14 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.generator; package org.oscim.generator;
import static org.oscim.core.MapElement.GEOM_LINE;
import static org.oscim.core.MapElement.GEOM_POINT;
import static org.oscim.core.MapElement.GEOM_POLY;
import static org.oscim.generator.JobTile.STATE_NONE; import static org.oscim.generator.JobTile.STATE_NONE;
import java.util.Arrays; import java.util.Arrays;
import org.oscim.core.GeometryBuffer; import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection; import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
@ -66,22 +68,10 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
public static final byte STROKE_MIN_ZOOM_LEVEL = 12; public static final byte STROKE_MIN_ZOOM_LEVEL = 12;
public static final byte STROKE_MAX_ZOOM_LEVEL = 17; public static final byte STROKE_MAX_ZOOM_LEVEL = 17;
//private static final Tag[] debugTagBox = ;
private static final Tag[] debugTagWay = { new Tag("debug", "way") }; private static final Tag[] debugTagWay = { new Tag("debug", "way") };
private static final Tag[] debugTagArea = { new Tag("debug", "area") }; private static final Tag[] debugTagArea = { new Tag("debug", "area") };
private final GeometryBuffer mDebugPoint = new GeometryBuffer( private final MapElement mDebugWay, mDebugPoint;
new float[] { Tile.SIZE >> 1, 10 },
new short[] { 2 });
private final WayData mDebugWay = new WayData(
new GeometryBuffer(
new float[] { 0, 0, 0, Tile.SIZE,
Tile.SIZE, Tile.SIZE,
Tile.SIZE, 0, 0, 0 },
new short[] { 10 }),
new Tag[] { new Tag("debug", "box") }
);
private static RenderTheme renderTheme; private static RenderTheme renderTheme;
private static int renderLevels; private static int renderLevels;
@ -93,10 +83,8 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
// currently processed tile // currently processed tile
private MapTile mTile; private MapTile mTile;
// currently processed geometry // currently processed MapElement
private GeometryBuffer mGeom; private MapElement mElement;
private WayData mWay;
// current line layer, will be added to outline layers // current line layer, will be added to outline layers
private LineLayer mCurLineLayer; private LineLayer mCurLineLayer;
@ -108,6 +96,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
private float mGroundResolution; private float mGroundResolution;
// replacement for variable value tags that should not be matched by RenderTheme // replacement for variable value tags that should not be matched by RenderTheme
// FIXME make this general, maybe subclass tags
private final static Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false); private final static Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
private final static Tag mTagEmptyHouseNr = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, null, false); private final static Tag mTagEmptyHouseNr = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, null, false);
private Tag mTagName; private Tag mTagName;
@ -128,6 +117,22 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
*/ */
public TileGenerator() { public TileGenerator() {
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true); mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
MapElement m = mDebugWay = new MapElement();
m.startLine();
int s = Tile.SIZE;
m.addPoint(0, 0);
m.addPoint(0, s);
m.addPoint(s, s);
m.addPoint(s, 0);
m.addPoint(0, 0);
m.tags = new Tag[] { new Tag("debug", "box") };
m.geometryType = GEOM_LINE;
m = mDebugPoint= new MapElement();
m.startPoints();
m.addPoint(s >> 1, 10);
m.geometryType = GEOM_POINT;
} }
public void cleanup() { public void cleanup() {
@ -178,13 +183,13 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
if (debug.drawTileFrames) { if (debug.drawTileFrames) {
// draw tile coordinate // draw tile coordinate
mTagName = new Tag("name", mTile.toString(), false); mTagName = new Tag("name", mTile.toString(), false);
mGeom = mDebugPoint; mElement = mDebugPoint;
RenderInstruction[] ri; RenderInstruction[] ri;
ri = renderTheme.matchNode(debugTagWay, (byte) 0); ri = renderTheme.matchNode(debugTagWay, (byte) 0);
renderNode(ri); renderNode(ri);
// draw tile box // draw tile box
mWay = mDebugWay; mElement = mDebugWay;
mDrawingLayer = 100 * renderLevels; mDrawingLayer = 100 * renderLevels;
ri = renderTheme.matchWay(mDebugWay.tags, (byte) 0, false); ri = renderTheme.matchWay(mDebugWay.tags, (byte) 0, false);
renderWay(ri); renderWay(ri);
@ -263,48 +268,47 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
} }
// ---------------- MapDatabaseCallback ----------------- // ---------------- MapDatabaseCallback -----------------
@Override @Override
public void renderPOI(byte layer, Tag[] tags, GeometryBuffer geom) { public void renderElement(MapElement element) {
clearState(); clearState();
// remove tags that should not be cached in Rendertheme mElement = element;
filterTags(tags);
// get render instructions if (element.geometryType == GEOM_POINT) {
RenderInstruction[] ri = renderTheme.matchNode(tags, mTile.zoomLevel); // remove tags that should not be cached in Rendertheme
filterTags(element.tags);
if (ri == null) // get render instructions
return; RenderInstruction[] ri = renderTheme.matchNode(element.tags, mTile.zoomLevel);
mGeom = geom; if (ri != null)
renderNode(ri); renderNode(ri);
}
else {
// replace tags that should not be cached in Rendertheme (e.g. name)
if (!filterTags(element.tags))
return;
boolean closed = element.geometryType == GEOM_POLY;
mDrawingLayer = getValidLayer(element.layer) * renderLevels;
// get render instructions
RenderInstruction[] ri = renderTheme.matchWay(element.tags,
(byte) (mTile.zoomLevel + 0), closed);
renderWay(ri);
if (debug.debugTheme && ri == null)
debugUnmatched(closed, element.tags);
mCurLineLayer = null;
}
mElement = null;
} }
@Override
public void renderWay(WayData way) {
mWay = way;
clearState();
// replace tags that should not be cached in Rendertheme (e.g. name)
if (!filterTags(way.tags))
return;
mDrawingLayer = getValidLayer(way.layer) * renderLevels;
// get render instructions
RenderInstruction[] ri = renderTheme.matchWay(way.tags,
(byte) (mTile.zoomLevel + 0), way.closed);
renderWay(ri);
if (debug.debugTheme && ri == null)
debugUnmatched(way.closed, way.tags);
mCurLineLayer = null;
mWay = null;
}
private void debugUnmatched(boolean closed, Tag[] tags) { private void debugUnmatched(boolean closed, Tag[] tags) {
Log.d(TAG, "DBG way not matched: " + closed + " " Log.d(TAG, "DBG way not matched: " + closed + " "
@ -342,9 +346,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
mCurLineLayer = null; mCurLineLayer = null;
} }
@Override // @Override
public void renderWaterBackground() { // public void renderWaterBackground() {
} // }
// ----------------- RenderThemeCallback ----------------- // ----------------- RenderThemeCallback -----------------
@Override @Override
@ -378,7 +382,8 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
return; return;
} }
lineLayer.addLine(mWay.geom.points, mWay.geom.index, mWay.closed); lineLayer.addLine(mElement.points, mElement.index,
mElement.geometryType == GEOM_POLY);
// keep reference for outline layer // keep reference for outline layer
mCurLineLayer = lineLayer; mCurLineLayer = lineLayer;
@ -400,7 +405,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
lineLayer.width = w; lineLayer.width = w;
} }
lineLayer.addLine(mWay.geom.points, mWay.geom.index); lineLayer.addLine(mElement.points, mElement.index);
} }
} }
@ -413,7 +418,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
if (mTile.layers.extrusionLayers == null) if (mTile.layers.extrusionLayers == null)
mTile.layers.extrusionLayers = new ExtrusionLayer(0, mGroundResolution); mTile.layers.extrusionLayers = new ExtrusionLayer(0, mGroundResolution);
((ExtrusionLayer) mTile.layers.extrusionLayers).addBuildings(mWay); ((ExtrusionLayer) mTile.layers.extrusionLayers).addBuildings(mElement);
return; return;
} }
@ -429,7 +434,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
if (layer.area == null) if (layer.area == null)
layer.area = area; layer.area = area;
layer.addPolygon(mWay.geom.points, mWay.geom.index); layer.addPolygon(mElement.points, mElement.index);
} }
private String textValueForKey(Text text) { private String textValueForKey(Text text) {
@ -453,8 +458,8 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
if (value == null) if (value == null)
return; return;
float x = mWay.geom.points[0]; float x = mElement.points[0];
float y = mWay.geom.points[1]; float y = mElement.points[1];
mTile.addLabel(TextItem.pool.get().set(x, y, value, text)); mTile.addLabel(TextItem.pool.get().set(x, y, value, text));
} }
@ -465,9 +470,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
if (value == null) if (value == null)
return; return;
for (int i = 0, n = mGeom.index[0]; i < n; i += 2) { for (int i = 0, n = mElement.index[0]; i < n; i += 2) {
float x = mGeom.points[i]; float x = mElement.points[i];
float y = mGeom.points[i + 1]; float y = mElement.points[i + 1];
mTile.addLabel(TextItem.pool.get().set(x, y, value, text)); mTile.addLabel(TextItem.pool.get().set(x, y, value, text));
} }
} }
@ -479,12 +484,12 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
return; return;
int offset = 0; int offset = 0;
for (int i = 0, n = mWay.geom.index.length; i < n; i++) { for (int i = 0, n = mElement.index.length; i < n; i++) {
int length = mWay.geom.index[i]; int length = mElement.index[i];
if (length < 4) if (length < 4)
break; break;
WayDecorator.renderText(mClipper, mWay.geom.points, value, text, WayDecorator.renderText(mClipper, mElement.points, value, text,
offset, length, mTile); offset, length, mTile);
offset += length; offset += length;
} }

View File

@ -19,8 +19,8 @@ import java.nio.ByteOrder;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapElement;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLRenderer; import org.oscim.renderer.GLRenderer;
import org.oscim.utils.LineClipper; import org.oscim.utils.LineClipper;
@ -76,13 +76,13 @@ public class ExtrusionLayer extends Layer {
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE); mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE);
} }
public void addBuildings(WayData way) { public void addBuildings(MapElement element) {
short[] index = way.geom.index; short[] index = element.index;
float[] points = way.geom.points; float[] points = element.points;
float height = way.height; float height = element.height;
float minHeight = way.minHeight; float minHeight = element.minHeight;
// 12m default // 12m default
if (height == 0) if (height == 0)
@ -123,7 +123,7 @@ public class ExtrusionLayer extends Layer {
// start next polygon // start next polygon
if (length == 0) { if (length == 0) {
if (complexOutline) if (complexOutline)
addRoof(startVertex, way.geom, geomIndexPos, geomPointPos); addRoof(startVertex, element, geomIndexPos, geomPointPos);
startVertex = mNumVertices; startVertex = mNumVertices;
simpleOutline = true; simpleOutline = true;
@ -163,7 +163,7 @@ public class ExtrusionLayer extends Layer {
} }
} }
if (complexOutline) if (complexOutline)
addRoof(startVertex, way.geom, geomIndexPos, geomPointPos); addRoof(startVertex, element, geomIndexPos, geomPointPos);
} }
private void addRoofSimple(int startVertex, int len) { private void addRoofSimple(int startVertex, int len) {