package org.oscim.theme.carto; import static java.lang.System.out; import static org.jeo.map.CartoCSS.BACKGROUND_COLOR; import static org.jeo.map.CartoCSS.OPACITY; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.jeo.carto.Carto; import org.jeo.map.CartoCSS; import org.jeo.map.RGB; import org.jeo.map.Rule; import org.jeo.map.RuleList; import org.jeo.map.Style; import org.oscim.core.GeometryBuffer.GeometryType; import org.oscim.core.MapElement; import org.oscim.core.Tag; import org.oscim.core.TagSet; import org.oscim.theme.IRenderTheme; import org.oscim.theme.styles.AreaStyle; import org.oscim.theme.styles.LineStyle; import org.oscim.theme.styles.RenderStyle; public class RenderTheme implements IRenderTheme { final String STYLE = "" + "[building = 'yes'] {" + " z: 1;" + " polygon-fill: #eee;" + " [zoom >= 16] {" + " polygon-fill: #c00;" + " }" + "}" + "[admin_level = '2'] {" + " line-color: #000;" + " line-width: 1;" + " z: 1;" + "}" + "[admin_level = '2'] {" + " line-color: #000;" + " line-width: 1;" + " z: 1;" + "}" + "[admin_level = '4'] {" + " line-color: #aaa;" + " line-width: 1;" + " z: 2;" + "}" + "[highway = 'motorway'] {" + " line-color: #a00;" + " z: 10;" + "}" + "[highway = 'primary'] {" + " line-color: #aa0;" + " z: 11;" + "}" + "[highway = 'residential'],[highway = 'road'],[highway = 'secondary'] {" + " line-color: #fff;" + " z: 12;" + "}" + " [landuse = 'forest'] {" + " polygon-fill: #0a0;" + " z: 2;" + "}" + "[natural = 'water'] {" + " polygon-fill: #00a;" + " z: 3;" + "}"; private Style mStyle; private RuleList mRules; MatcherFeature mMatchFeature = new MatcherFeature(); private int mBackground; public RenderTheme() { try { mStyle = loadStyle(); } catch (IOException e) { e.printStackTrace(); } // get map background RuleList rules = mStyle.getRules().selectByName("Map", false, false); if (!rules.isEmpty()) { Rule rule = rules.collapse(); RGB bgColor = rule.color(null, BACKGROUND_COLOR, null); if (bgColor != null) { bgColor = bgColor.alpha(rule.number(null, OPACITY, 1f)); mBackground = color(bgColor); } } mRules = mStyle.getRules(); //out.println(mRules); //out.println(); if (mRules.get(1).equals(mRules.get(2))) out.println("ok"); for (Rule r : mRules) out.println(formatRule(r, 0)); } class StyleSet { int level; RenderStyle[] ri = new RenderStyle[2]; } Map<Rule, StyleSet> mStyleSets = new HashMap<Rule, StyleSet>(); int mCurLevel = 0; public String formatRule(Rule r, int indent) { StringBuilder sb = new StringBuilder(); String pad = ""; for (int i = 0; i < indent; i++) pad += " "; sb.append(pad); if (sb.length() > 0) sb.setLength(sb.length() - 1); sb.append(pad).append(" {").append("\n"); StyleSet s = new StyleSet(); RGB l = null; RGB p = null; if (r.properties().containsKey(CartoCSS.LINE_COLOR)) { l = r.color(null, CartoCSS.LINE_COLOR, RGB.black); } if (r.properties().containsKey(CartoCSS.POLYGON_FILL)) { p = r.color(null, CartoCSS.POLYGON_FILL, RGB.black); } if (p != null) { s.ri[0] = new AreaStyle(mCurLevel++, color(p)); } if (l != null) { s.ri[1] = new LineStyle(mCurLevel++, color(l), 1); } if (p != null || l != null) { mStyleSets.put(r, s); out.println("put " + s.ri[0] + s.ri[1]); } for (Map.Entry<String, Object> e : r.properties().entrySet()) { sb.append(pad).append(" ").append(e.getKey()).append(": ").append(e.getValue()) .append(";\n"); } for (Rule nested : r.nested()) { sb.append(formatRule(nested, indent + 2)).append("\n"); } sb.append(pad).append("}"); return sb.toString(); } Style loadStyle() throws IOException { return Carto.parse(STYLE); } @Override public synchronized RenderStyle[] matchElement(GeometryType type, TagSet tags, int zoomLevel) { MatcherFeature f = mMatchFeature; f.setTags(tags); f.setZoom(zoomLevel); RuleList rules = mRules.match(f); Rule r = rules.collapse(); //out.println(r); if (rules.isEmpty()) return null; int z = r.number(f, "z", 0f).intValue(); if (type == GeometryType.POLY) { RGB c = r.color(f, CartoCSS.POLYGON_FILL, RGB.black); out.println(z + " " + c); return new RenderStyle[] { new AreaStyle(z, color(c)) }; } else if (type == GeometryType.LINE) { RGB c = r.color(f, CartoCSS.LINE_COLOR, RGB.black); float width = r.number(f, CartoCSS.LINE_WIDTH, 2f); //out.println(z + " " + c); return new RenderStyle[] { new LineStyle(100 + z, color(c), width) }; } else if (type == GeometryType.POINT) { //RGB c = r.color(f, CartoCSS.MARKER_FILL, RGB.black); //out.println(c); //return new RenderInstruction[] { // new Caption(color(c), width) //}; } return null; } public static int color(RGB rgb) { return rgb.getAlpha() << 24 | rgb.getRed() << 16 | rgb.getGreen() << 8 | rgb.getBlue(); } @Override public void dispose() { } @Override public int getLevels() { return 1; } @Override public int getMapBackground() { return mBackground; } @Override public void scaleTextSize(float scaleFactor) { } public static void main(String[] args) { RenderTheme t = new RenderTheme(); MapElement e = new MapElement(); e.startPolygon(); e.tags.add(new Tag("building", "yes")); t.matchElement(GeometryType.POLY, e.tags, 16); t.matchElement(GeometryType.POLY, e.tags, 15); } @Override public void updateStyles() { // TODO Auto-generated method stub } }