package org.oscim.layers.tile.buildings;
import static org.oscim.layers.tile.buildings.S3DBLayer.getMaterialColor;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.bucket.ExtrusionBucket;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.TileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class S3DBTileLoader extends TileLoader {
static final Logger log = LoggerFactory.getLogger(S3DBTileLoader.class);
/** current TileDataSource used by this MapTileLoader */
private final ITileDataSource mTileDataSource;
private ExtrusionBucket mParts;
private ExtrusionBucket mRoofs;
private float mGroundScale;
static MapElement mTilePlane = new MapElement();
static {
mTilePlane = new MapElement();
GeometryBuffer g = mTilePlane;
g.type = GeometryType.TRIS;
g.points = new float[] {
0, 0, 0,
4096, 0, 0,
0, 4096, 0,
4096, 4096, 0 };
g.index = new int[] { 0, 1, 2, 2, 1, 3 };
mTilePlane.tags.add(new Tag("c", "transparent"));
}
public S3DBTileLoader(TileManager tileManager, TileSource tileSource) {
super(tileManager);
mTileDataSource = tileSource.getDataSource();
}
@Override
public void dispose() {
mTileDataSource.dispose();
}
@Override
public void cancel() {
mTileDataSource.cancel();
}
@Override
protected boolean loadTile(MapTile tile) {
mTile = tile;
try {
/* query database, which calls process() callback */
mTileDataSource.query(mTile, this);
} catch (Exception e) {
log.debug("{}", e);
return false;
}
return true;
}
private void initTile(MapTile tile) {
double lat = MercatorProjection.toLatitude(tile.y);
mGroundScale = (float) MercatorProjection
.groundResolution(lat, 1 << mTile.zoomLevel);
mRoofs = new ExtrusionBucket(0, mGroundScale, Color.get(247, 249, 250));
mParts = new ExtrusionBucket(0, mGroundScale, Color.get(255, 254, 252));
//mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(207, 209, 210));
mRoofs.next = mParts;
BuildingLayer.get(tile).setBuckets(mRoofs);
process(mTilePlane);
}
String COLOR_KEY = "c";
String MATERIAL_KEY = "m";
String ROOF_KEY = "roof";
String ROOF_SHAPE_KEY = "roof:shape";
@Override
public void process(MapElement element) {
if (element.type != GeometryType.TRIS) {
log.debug("wrong type " + element.type);
return;
}
if (mParts == null)
initTile(mTile);
boolean isRoof = element.tags.containsKey(ROOF_KEY);
//if (isRoof)
// log.debug(element.tags.toString());
int c = 0;
if (element.tags.containsKey(COLOR_KEY)) {
c = S3DBLayer.getColor(element.tags.getValue(COLOR_KEY), isRoof);
}
if (c == 0 && element.tags.containsKey(MATERIAL_KEY)) {
c = getMaterialColor(element.tags.getValue(MATERIAL_KEY), isRoof);
}
if (c == 0) {
String roofShape = element.tags.getValue(ROOF_SHAPE_KEY);
if (isRoof && (roofShape == null || "flat".equals(roofShape)))
mRoofs.add(element);
else
mParts.add(element);
return;
}
for (ExtrusionBucket l = mParts; l != null; l = l.next()) {
if (l.color == c) {
l.add(element);
return;
}
}
ExtrusionBucket l = new ExtrusionBucket(0, mGroundScale, c);
l.next = mParts.next;
mParts.next = l;
l.add(element);
}
@Override
public void completed(QueryResult result) {
mParts = null;
mRoofs = null;
super.completed(result);
}
}