package org.oscim.layers;
import java.util.HashMap;
import org.jeo.data.VectorDataset;
import org.jeo.feature.Feature;
import org.jeo.map.CartoCSS;
import org.jeo.map.RGB;
import org.jeo.map.Rule;
import org.jeo.map.Style;
import org.oscim.backend.canvas.Color;
import org.oscim.jeo.JeoUtils;
import org.oscim.map.Map;
import org.oscim.renderer.bucket.LineBucket;
import org.oscim.renderer.bucket.MeshBucket;
import org.oscim.renderer.bucket.TextBucket;
import org.oscim.renderer.bucket.TextItem;
import org.oscim.theme.styles.AreaStyle;
import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.TextStyle;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
public class OSMIndoorLayer extends JeoVectorLayer {
protected TextBucket mTextLayer;
protected TextStyle mText = TextStyle.builder()
.fontSize(16).color(Color.BLACK)
.strokeWidth(2.2f).strokeColor(Color.WHITE)
.build();
public OSMIndoorLayer(Map map, VectorDataset data, Style style) {
super(map, data, style);
}
public boolean[] activeLevels = new boolean[10];
@Override
protected void processFeatures(Task t, Envelope b) {
mTextLayer = new TextBucket();
t.buckets.set(mTextLayer);
super.processFeatures(t, b);
//render TextItems to a bitmap and prepare vertex buffer data.
mTextLayer.prepare();
mTextLayer.clearLabels();
}
protected void addLine(Task t, Feature f, Rule rule, Geometry g) {
if (((LineString) g).isClosed()) {
addPolygon(t, f, rule, g);
return;
}
int level = getLevel(f);
LineBucket ll = t.buckets.getLineBucket(level * 3 + 2);
if (ll.line == null) {
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
ll.line = new LineStyle(0, JeoUtils.color(color), width);
ll.heightOffset = level * 4;
ll.setDropDistance(0);
}
addLine(t, g, ll);
}
protected void addPolygon(Task t, Feature f, Rule rule, Geometry g) {
int level = getLevel(f);
LineBucket ll = t.buckets.getLineBucket(level * 3 + 1);
boolean active = activeLevels[level + 1];
if (ll.line == null) {
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
int color = Color.rainbow((level + 1) / 10f);
if (level > -2 && !active)
color = Color.fade(color, 0.1f);
ll.line = new LineStyle(0, color, width);
ll.heightOffset = level * 4;
ll.setDropDistance(0);
}
MeshBucket mesh = t.buckets.getMeshBucket(level * 3);
if (mesh.area == null) {
int color = JeoUtils.color(rule.color(f, CartoCSS.POLYGON_FILL, RGB.red));
if (level > -2 && !active)
color = Color.fade(color, 0.1f);
mesh.area = new AreaStyle(color);
//mesh.area = new Area(Color.fade(Color.DKGRAY, 0.1f));
mesh.heightOffset = level * 4f;
}
addPolygon(t, g, mesh, ll);
if (active) {
Object o = f.get("name");
if (o instanceof String) {
float x = 0;
float y = 0;
int n = mGeom.index[0];
for (int i = 0; i < n;) {
x += mGeom.points[i++];
y += mGeom.points[i++];
}
TextItem ti = TextItem.pool.get();
ti.set(x / (n / 2) / 8, y / (n / 2) / 8, (String) o, mText);
mTextLayer.addText(ti);
}
}
}
@Override
protected void addPoint(Task t, Feature f, Rule rule, Geometry g) {
}
private int getLevel(Feature f) {
/* not sure if one could match these geojson properties with cartocss */
Object o = f.get("@relations");
if (o instanceof HashMap) {
@SuppressWarnings("unchecked")
HashMap<String, Object> tags = (HashMap<String, Object>) o;
@SuppressWarnings("unchecked")
HashMap<String, Object> reltags = (HashMap<String, Object>) tags.get("reltags");
if (reltags != null) {
o = reltags.get("level");
if (o instanceof String) {
//log.debug("got level {}", o);
return Integer.parseInt((String) o);
}
}
}
return 0;
}
}