From 7c97ac5101740a2a08d9dfc6bb5494308e031d5e Mon Sep 17 00:00:00 2001 From: Emux Date: Sat, 3 Sep 2016 17:13:55 +0300 Subject: [PATCH] - Render theme styles, closes #93 - Stream render theme, closes #161 --- docs/Changelog.md | 1 + resources/rendertheme.xsd | 73 ++++- .../android/filepicker/ValidRenderTheme.java | 30 +-- .../app/filefilter/ValidRenderTheme.java | 30 +-- .../src/org/oscim/stuff/MapzenTest.java | 3 +- .../oscim/test/ExternalRenderThemeTest.java | 23 +- vtm-themes/src/org/oscim/theme/VtmThemes.java | 9 +- .../org/oscim/backend/XMLReaderAdapter.java | 21 +- .../org/oscim/theme/ExternalRenderTheme.java | 19 +- .../org/oscim/theme/StreamRenderTheme.java | 82 ++++++ vtm/src/org/oscim/theme/ThemeFile.java | 12 +- vtm/src/org/oscim/theme/ThemeLoader.java | 49 +--- .../theme/XmlRenderThemeMenuCallback.java | 28 ++ .../oscim/theme/XmlRenderThemeStyleLayer.java | 95 +++++++ .../oscim/theme/XmlRenderThemeStyleMenu.java | 68 +++++ vtm/src/org/oscim/theme/XmlThemeBuilder.java | 251 ++++++++++++++---- vtm/src/org/oscim/theme/rule/Rule.java | 9 +- vtm/src/org/oscim/theme/rule/RuleBuilder.java | 30 ++- vtm/src/org/oscim/theme/styles/AreaStyle.java | 2 +- .../org/oscim/theme/styles/CircleStyle.java | 5 +- .../oscim/theme/styles/ExtrusionStyle.java | 3 +- vtm/src/org/oscim/theme/styles/LineStyle.java | 2 +- .../org/oscim/theme/styles/RenderStyle.java | 37 ++- .../org/oscim/theme/styles/SymbolStyle.java | 2 +- vtm/src/org/oscim/theme/styles/TextStyle.java | 2 +- 25 files changed, 667 insertions(+), 219 deletions(-) create mode 100644 vtm/src/org/oscim/theme/StreamRenderTheme.java create mode 100644 vtm/src/org/oscim/theme/XmlRenderThemeMenuCallback.java create mode 100644 vtm/src/org/oscim/theme/XmlRenderThemeStyleLayer.java create mode 100644 vtm/src/org/oscim/theme/XmlRenderThemeStyleMenu.java diff --git a/docs/Changelog.md b/docs/Changelog.md index 97c223dc..550a7ba5 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -6,6 +6,7 @@ - Render theme SVG resources [#60](https://github.com/mapsforge/vtm/issues/60) - Mapsforge multilingual maps [#34](https://github.com/mapsforge/vtm/issues/34) +- Render theme styles [#93](https://github.com/mapsforge/vtm/issues/93) - vtm-ios update module [#29](https://github.com/mapsforge/vtm/issues/29) - Native libraries for all platforms [#14](https://github.com/mapsforge/vtm/issues/14) - Line stipple and texture rendering [#105](https://github.com/mapsforge/vtm/issues/105) diff --git a/resources/rendertheme.xsd b/resources/rendertheme.xsd index 04e88219..fe4af0f0 100644 --- a/resources/rendertheme.xsd +++ b/resources/rendertheme.xsd @@ -2,6 +2,7 @@ + @@ -88,8 +89,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -103,6 +134,7 @@ + @@ -119,6 +151,7 @@ + @@ -127,6 +160,8 @@ + + @@ -154,23 +189,24 @@ - + + + + + @@ -188,16 +224,17 @@ + + - @@ -222,10 +259,10 @@ + - @@ -240,9 +277,20 @@ + + + + + + + + + + + @@ -271,7 +319,6 @@ use="optional" /> - diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java index 15f6b715..93ff8f4d 100644 --- a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java +++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java @@ -15,18 +15,15 @@ */ package org.oscim.android.filepicker; +import org.oscim.theme.ExternalRenderTheme; +import org.oscim.theme.ThemeFile; import org.oscim.theme.XmlThemeBuilder; import org.oscim.tiling.TileSource.OpenResult; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; /** @@ -37,31 +34,16 @@ public final class ValidRenderTheme implements ValidFileFilter { @Override public boolean accept(File file) { - InputStream inputStream = null; - try { - inputStream = new FileInputStream(file); - XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(file.getParent()); + ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath()); + XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme); XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); xmlReader.setContentHandler(renderThemeHandler); - xmlReader.parse(new InputSource(inputStream)); + xmlReader.parse(new InputSource(theme.getRenderThemeAsStream())); mOpenResult = OpenResult.SUCCESS; - } catch (ParserConfigurationException e) { + } catch (Exception e) { mOpenResult = new OpenResult(e.getMessage()); - } catch (SAXException e) { - mOpenResult = new OpenResult(e.getMessage()); - } catch (IOException e) { - mOpenResult = new OpenResult(e.getMessage()); - } finally { - try { - if (inputStream != null) { - inputStream.close(); - } - } catch (IOException e) { - mOpenResult = new OpenResult(e.getMessage()); - } } - return mOpenResult.isSuccess(); } diff --git a/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java b/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java index 052eea4a..00403277 100644 --- a/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java +++ b/vtm-app/src/org/oscim/app/filefilter/ValidRenderTheme.java @@ -15,18 +15,15 @@ */ package org.oscim.app.filefilter; +import org.oscim.theme.ExternalRenderTheme; +import org.oscim.theme.ThemeFile; import org.oscim.theme.XmlThemeBuilder; import org.oscim.tiling.TileSource.OpenResult; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; /** @@ -37,31 +34,16 @@ public final class ValidRenderTheme implements ValidFileFilter { @Override public boolean accept(File file) { - InputStream inputStream = null; - try { - inputStream = new FileInputStream(file); - XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(file.getParent()); + ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath()); + XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme); XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); xmlReader.setContentHandler(renderThemeHandler); - xmlReader.parse(new InputSource(inputStream)); + xmlReader.parse(new InputSource(theme.getRenderThemeAsStream())); this.openResult = OpenResult.SUCCESS; - } catch (ParserConfigurationException e) { + } catch (Exception e) { this.openResult = new OpenResult(e.getMessage()); - } catch (SAXException e) { - this.openResult = new OpenResult(e.getMessage()); - } catch (IOException e) { - this.openResult = new OpenResult(e.getMessage()); - } finally { - try { - if (inputStream != null) { - inputStream.close(); - } - } catch (IOException e) { - this.openResult = new OpenResult(e.getMessage()); - } } - return this.openResult.isSuccess(); } diff --git a/vtm-playground/src/org/oscim/stuff/MapzenTest.java b/vtm-playground/src/org/oscim/stuff/MapzenTest.java index 0099d460..90a99fff 100644 --- a/vtm-playground/src/org/oscim/stuff/MapzenTest.java +++ b/vtm-playground/src/org/oscim/stuff/MapzenTest.java @@ -24,6 +24,7 @@ import org.oscim.layers.tile.buildings.BuildingLayer; import org.oscim.layers.tile.vector.VectorTileLayer; import org.oscim.layers.tile.vector.labeling.LabelLayer; import org.oscim.theme.IRenderTheme.ThemeException; +import org.oscim.theme.StreamRenderTheme; import org.oscim.theme.ThemeLoader; import org.oscim.tiling.source.OkHttpEngine; import org.oscim.tiling.source.UrlTileSource; @@ -61,7 +62,7 @@ public class MapzenTest extends GdxMap { private void loadTheme() { try { - mMap.setTheme(ThemeLoader.load(getClass().getResourceAsStream("/assets/styles/mapzen.xml"))); + mMap.setTheme(ThemeLoader.load(new StreamRenderTheme("", getClass().getResourceAsStream("/assets/styles/mapzen.xml")))); } catch (ThemeException e) { e.printStackTrace(); } diff --git a/vtm-playground/src/org/oscim/test/ExternalRenderThemeTest.java b/vtm-playground/src/org/oscim/test/ExternalRenderThemeTest.java index f055d2e8..cd7a60eb 100644 --- a/vtm-playground/src/org/oscim/test/ExternalRenderThemeTest.java +++ b/vtm-playground/src/org/oscim/test/ExternalRenderThemeTest.java @@ -1,3 +1,19 @@ +/* + * Copyright 2016 devemux86 + * + * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). + * + * 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 . + */ package org.oscim.test; import com.badlogic.gdx.Input; @@ -8,11 +24,10 @@ import org.oscim.layers.tile.vector.VectorTileLayer; import org.oscim.layers.tile.vector.labeling.LabelLayer; import org.oscim.renderer.MapRenderer; import org.oscim.theme.IRenderTheme; +import org.oscim.theme.IRenderTheme.ThemeException; import org.oscim.theme.ThemeLoader; import org.oscim.tiling.source.mapfile.MapFileTileSource; -import java.io.FileNotFoundException; - public class ExternalRenderThemeTest extends GdxMap { VectorTileLayer mapLayer; @@ -34,7 +49,7 @@ public class ExternalRenderThemeTest extends GdxMap { IRenderTheme theme = ThemeLoader.load(name); mapLayer.setRenderTheme(theme); MapRenderer.setBackgroundColor(theme.getMapBackground()); - } catch (FileNotFoundException e) { + } catch (ThemeException e) { e.printStackTrace(); } @@ -67,7 +82,7 @@ public class ExternalRenderThemeTest extends GdxMap { // IRenderTheme theme = ThemeLoader.load("themes/vmap/theme.xml"); l.setRenderTheme(theme); MapRenderer.setBackgroundColor(theme.getMapBackground()); - } catch (FileNotFoundException e) { + } catch (ThemeException e) { e.printStackTrace(); } diff --git a/vtm-themes/src/org/oscim/theme/VtmThemes.java b/vtm-themes/src/org/oscim/theme/VtmThemes.java index 5c13de89..2f1edf25 100644 --- a/vtm-themes/src/org/oscim/theme/VtmThemes.java +++ b/vtm-themes/src/org/oscim/theme/VtmThemes.java @@ -28,9 +28,9 @@ import java.io.InputStream; public enum VtmThemes implements ThemeFile { DEFAULT("styles/default.xml"), - TRONRENDER("styles/tronrender.xml"), NEWTRON("styles/newtron.xml"), - OSMARENDER("styles/osmarender.xml"); + OSMARENDER("styles/osmarender.xml"), + TRONRENDER("styles/tronrender.xml"); private final String mPath; @@ -38,6 +38,11 @@ public enum VtmThemes implements ThemeFile { mPath = path; } + @Override + public XmlRenderThemeMenuCallback getMenuCallback() { + return null; + } + @Override public String getRelativePathPrefix() { return ""; diff --git a/vtm/src/org/oscim/backend/XMLReaderAdapter.java b/vtm/src/org/oscim/backend/XMLReaderAdapter.java index 73b74021..40b93bf2 100644 --- a/vtm/src/org/oscim/backend/XMLReaderAdapter.java +++ b/vtm/src/org/oscim/backend/XMLReaderAdapter.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -28,24 +29,16 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; /** - * The Class XMLReaderAdapter. Used by RenderTheme. Note: GWT Backend provides - * its own implementation. + * The class XMLReaderAdapter is used by RenderTheme. + * Note: GWT Backend provides its own implementation. */ public class XMLReaderAdapter { - public void parse(DefaultHandler handler, InputStream is) throws IOException { - + public void parse(DefaultHandler handler, InputStream is) throws ParserConfigurationException, SAXException, IOException { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); - try { - XMLReader xmlReader = factory.newSAXParser().getXMLReader(); - xmlReader.setContentHandler(handler); - xmlReader.parse(new InputSource(is)); - - } catch (SAXException e) { - e.printStackTrace(); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } + XMLReader xmlReader = factory.newSAXParser().getXMLReader(); + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(is)); } } diff --git a/vtm/src/org/oscim/theme/ExternalRenderTheme.java b/vtm/src/org/oscim/theme/ExternalRenderTheme.java index 5bb75baa..ece85407 100644 --- a/vtm/src/org/oscim/theme/ExternalRenderTheme.java +++ b/vtm/src/org/oscim/theme/ExternalRenderTheme.java @@ -33,14 +33,23 @@ public class ExternalRenderTheme implements ThemeFile { private static final long serialVersionUID = 1L; private final long mFileModificationDate; + private final XmlRenderThemeMenuCallback mMenuCallback; private final String mPath; /** * @param fileName the path to the XML render theme file. * @throws ThemeException if the file does not exist or cannot be read. */ - public ExternalRenderTheme(String fileName) { + public ExternalRenderTheme(String fileName) throws ThemeException { + this(fileName, null); + } + /** + * @param fileName the path to the XML render theme file. + * @param menuCallback the interface callback to create a settings menu on the fly. + * @throws ThemeException if the file does not exist or cannot be read. + */ + public ExternalRenderTheme(String fileName, XmlRenderThemeMenuCallback menuCallback) throws ThemeException { File themeFile = new File(fileName); if (!themeFile.exists()) { throw new ThemeException("file does not exist: " + themeFile.getAbsolutePath()); @@ -55,6 +64,7 @@ public class ExternalRenderTheme implements ThemeFile { throw new ThemeException("cannot read last modification time"); } mPath = fileName; + mMenuCallback = menuCallback; } @Override @@ -75,13 +85,18 @@ public class ExternalRenderTheme implements ThemeFile { return true; } + @Override + public XmlRenderThemeMenuCallback getMenuCallback() { + return mMenuCallback; + } + @Override public String getRelativePathPrefix() { return new File(mPath).getParent(); } @Override - public InputStream getRenderThemeAsStream() { + public InputStream getRenderThemeAsStream() throws ThemeException { InputStream is; try { diff --git a/vtm/src/org/oscim/theme/StreamRenderTheme.java b/vtm/src/org/oscim/theme/StreamRenderTheme.java new file mode 100644 index 00000000..b73c65ba --- /dev/null +++ b/vtm/src/org/oscim/theme/StreamRenderTheme.java @@ -0,0 +1,82 @@ +/* + * Copyright 2016 devemux86 + * + * 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 . + */ +package org.oscim.theme; + +import org.oscim.theme.IRenderTheme.ThemeException; + +import java.io.InputStream; + +/** + * A StreamRenderTheme allows for customizing the rendering style of the map + * via an XML input stream. + */ +public class StreamRenderTheme implements ThemeFile { + private static final long serialVersionUID = 1L; + + private final InputStream mInputStream; + private final XmlRenderThemeMenuCallback mMenuCallback; + private final String mRelativePathPrefix; + + /** + * @param relativePathPrefix the prefix for all relative resource paths. + * @param inputStream an input stream containing valid render theme XML data. + */ + public StreamRenderTheme(String relativePathPrefix, InputStream inputStream) { + this(relativePathPrefix, inputStream, null); + } + + /** + * @param relativePathPrefix the prefix for all relative resource paths. + * @param inputStream an input stream containing valid render theme XML data. + * @param menuCallback the interface callback to create a settings menu on the fly. + */ + public StreamRenderTheme(String relativePathPrefix, InputStream inputStream, XmlRenderThemeMenuCallback menuCallback) { + mRelativePathPrefix = relativePathPrefix; + mInputStream = inputStream; + mMenuCallback = menuCallback; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (!(obj instanceof StreamRenderTheme)) { + return false; + } + StreamRenderTheme other = (StreamRenderTheme) obj; + if (mInputStream != other.mInputStream) { + return false; + } + if (mRelativePathPrefix != other.mRelativePathPrefix) { + return false; + } + return true; + } + + @Override + public XmlRenderThemeMenuCallback getMenuCallback() { + return mMenuCallback; + } + + @Override + public String getRelativePathPrefix() { + return mRelativePathPrefix; + } + + @Override + public InputStream getRenderThemeAsStream() throws ThemeException { + return mInputStream; + } +} diff --git a/vtm/src/org/oscim/theme/ThemeFile.java b/vtm/src/org/oscim/theme/ThemeFile.java index 1a13e6b2..1555a0dd 100644 --- a/vtm/src/org/oscim/theme/ThemeFile.java +++ b/vtm/src/org/oscim/theme/ThemeFile.java @@ -18,11 +18,17 @@ */ package org.oscim.theme; -import java.io.FileNotFoundException; +import org.oscim.theme.IRenderTheme.ThemeException; + import java.io.InputStream; import java.io.Serializable; public interface ThemeFile extends Serializable { + /** + * @return the interface callback to create a settings menu on the fly. + */ + XmlRenderThemeMenuCallback getMenuCallback(); + /** * @return the prefix for all relative resource paths. */ @@ -30,7 +36,7 @@ public interface ThemeFile extends Serializable { /** * @return an InputStream to read the render theme data from. - * @throws FileNotFoundException if the render theme file cannot be found. + * @throws ThemeException if an error occurs while reading the render theme XML. */ - InputStream getRenderThemeAsStream() throws FileNotFoundException; + InputStream getRenderThemeAsStream() throws ThemeException; } diff --git a/vtm/src/org/oscim/theme/ThemeLoader.java b/vtm/src/org/oscim/theme/ThemeLoader.java index eda78c28..912ff1de 100644 --- a/vtm/src/org/oscim/theme/ThemeLoader.java +++ b/vtm/src/org/oscim/theme/ThemeLoader.java @@ -19,52 +19,21 @@ package org.oscim.theme; import org.oscim.backend.CanvasAdapter; import org.oscim.theme.IRenderTheme.ThemeException; -import org.oscim.utils.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileNotFoundException; -import java.io.InputStream; public class ThemeLoader { - static final Logger log = LoggerFactory.getLogger(ThemeLoader.class); - /** - * Load theme from XML file. - * - * @throws FileNotFoundException - * @throws ThemeException - */ - public static IRenderTheme load(String renderThemePath) throws ThemeException, - FileNotFoundException { + public static IRenderTheme load(String renderThemePath) throws ThemeException { return load(new ExternalRenderTheme(renderThemePath)); } + public static IRenderTheme load(String renderThemePath, XmlRenderThemeMenuCallback menuCallback) throws ThemeException { + return load(new ExternalRenderTheme(renderThemePath, menuCallback)); + } + public static IRenderTheme load(ThemeFile theme) throws ThemeException { - - try { - InputStream is = theme.getRenderThemeAsStream(); - return load(theme.getRelativePathPrefix(), is); - } catch (FileNotFoundException e) { - log.error(e.getMessage()); - } - - return null; - } - - public static IRenderTheme load(InputStream inputStream) throws ThemeException { - return load("", inputStream); - } - - public static IRenderTheme load(String relativePathPrefix, InputStream inputStream) throws ThemeException { - - try { - IRenderTheme t = XmlThemeBuilder.read(relativePathPrefix, inputStream); - if (t != null) - t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f); - return t; - } finally { - IOUtils.closeQuietly(inputStream); - } + IRenderTheme t = XmlThemeBuilder.read(theme); + if (t != null) + t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f); + return t; } } diff --git a/vtm/src/org/oscim/theme/XmlRenderThemeMenuCallback.java b/vtm/src/org/oscim/theme/XmlRenderThemeMenuCallback.java new file mode 100644 index 00000000..a617959f --- /dev/null +++ b/vtm/src/org/oscim/theme/XmlRenderThemeMenuCallback.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Ludwig M Brinckmann + * Copyright 2016 devemux86 + * + * 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 . + */ +package org.oscim.theme; + +import java.util.Set; + +/** + * Interface callback in render theme to create a settings menu on the fly. + */ +public interface XmlRenderThemeMenuCallback { + /** + * Called when the style menu section of the xml file has been parsed. + */ + Set getCategories(XmlRenderThemeStyleMenu style); +} diff --git a/vtm/src/org/oscim/theme/XmlRenderThemeStyleLayer.java b/vtm/src/org/oscim/theme/XmlRenderThemeStyleLayer.java new file mode 100644 index 00000000..9b2ff23d --- /dev/null +++ b/vtm/src/org/oscim/theme/XmlRenderThemeStyleLayer.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 Ludwig M Brinckmann + * Copyright 2016 devemux86 + * + * 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 . + */ +package org.oscim.theme; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * An individual layer in the render theme menu system. + * A layer can have translations, categories that will always be enabled when the layer is selected, + * as well as optional overlays. + */ +public class XmlRenderThemeStyleLayer implements Serializable { + private static final long serialVersionUID = 1L; + + private final Set categories; + private final String defaultLanguage; + private final boolean enabled; + private final String id; + private final List overlays; + private final Map titles; + private final boolean visible; + + XmlRenderThemeStyleLayer(String id, boolean visible, boolean enabled, String defaultLanguage) { + this.id = id; + this.titles = new HashMap<>(); + this.categories = new LinkedHashSet<>(); + this.visible = visible; + this.defaultLanguage = defaultLanguage; + this.enabled = enabled; + this.overlays = new ArrayList<>(); + } + + public void addCategory(String category) { + this.categories.add(category); + } + + public void addOverlay(XmlRenderThemeStyleLayer overlay) { + this.overlays.add(overlay); + } + + public void addTranslation(String language, String name) { + this.titles.put(language, name); + } + + public Set getCategories() { + return this.categories; + } + + public String getId() { + return this.id; + } + + public List getOverlays() { + return this.overlays; + } + + public String getTitle(String language) { + String result = this.titles.get(language); + if (result == null) { + return this.titles.get(this.defaultLanguage); + } + return result; + } + + public Map getTitles() { + return this.titles; + } + + public boolean isEnabled() { + return this.enabled; + } + + public boolean isVisible() { + return this.visible; + } +} diff --git a/vtm/src/org/oscim/theme/XmlRenderThemeStyleMenu.java b/vtm/src/org/oscim/theme/XmlRenderThemeStyleMenu.java new file mode 100644 index 00000000..bf80afa6 --- /dev/null +++ b/vtm/src/org/oscim/theme/XmlRenderThemeStyleMenu.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 Ludwig M Brinckmann + * Copyright 2016 devemux86 + * + * 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 . + */ +package org.oscim.theme; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Entry class for automatically building menus from render theme files. + * This class holds all the defined layers and allows to retrieve them by name or through iteration. + * This class is Serializable to be able to pass an instance of it through the Android Intent + * mechanism. + */ +public class XmlRenderThemeStyleMenu implements Serializable { + private static final long serialVersionUID = 1L; + + private final String defaultLanguage; + private final String defaultValue; + private final String id; + private final Map layers; + + public XmlRenderThemeStyleMenu(String id, String defaultLanguage, String defaultValue) { + this.id = id; + this.defaultLanguage = defaultLanguage; + this.defaultValue = defaultValue; + this.layers = new LinkedHashMap<>(); + } + + public XmlRenderThemeStyleLayer createLayer(String id, boolean visible, boolean enabled) { + XmlRenderThemeStyleLayer style = new XmlRenderThemeStyleLayer(id, visible, enabled, this.defaultLanguage); + this.layers.put(id, style); + return style; + } + + public String getDefaultLanguage() { + return this.defaultLanguage; + } + + public String getDefaultValue() { + return this.defaultValue; + } + + public String getId() { + return this.id; + } + + public XmlRenderThemeStyleLayer getLayer(String id) { + return this.layers.get(id); + } + + public Map getLayers() { + return this.layers; + } +} diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java index 719bcfae..5ecaffd4 100644 --- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java @@ -52,10 +52,10 @@ import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; +import java.util.Set; import java.util.Stack; import static java.lang.Boolean.parseBoolean; @@ -67,11 +67,12 @@ public class XmlThemeBuilder extends DefaultHandler { private static final int RENDER_THEME_VERSION = 1; - private static enum Element { - RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS; + private enum Element { + RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RENDERING_STYLE } private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme"; + private static final String ELEMENT_NAME_STYLE_MENU = "stylemenu"; private static final String ELEMENT_NAME_MATCH = "m"; private static final String UNEXPECTED_ELEMENT = "unexpected element: "; @@ -80,21 +81,16 @@ public class XmlThemeBuilder extends DefaultHandler { private static final String AREA_STYLE = "A"; /** - * @param relativePathPrefix the prefix for all relative resource paths. - * @param inputStream an input stream containing valid render theme XML data. - * @return a new RenderTheme which is created by parsing the XML data from - * the input stream. + * @param theme an input theme containing valid render theme XML data. + * @return a new RenderTheme which is created by parsing the XML data from the input theme. * @throws ThemeException if an error occurs while parsing the render theme XML. - * @throws IOException if an I/O error occurs while reading from the input stream. */ - public static IRenderTheme read(String relativePathPrefix, InputStream inputStream) - throws ThemeException { - - XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(relativePathPrefix); + public static IRenderTheme read(ThemeFile theme) throws ThemeException { + XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme); try { - new XMLReaderAdapter().parse(renderThemeHandler, inputStream); - } catch (IOException e) { + new XMLReaderAdapter().parse(renderThemeHandler, theme.getRenderThemeAsStream()); + } catch (Exception e) { throw new ThemeException(e.getMessage()); } @@ -115,14 +111,12 @@ public class XmlThemeBuilder extends DefaultHandler { element, attributeIndex, name, value); } - private final ArrayList mRulesList = new ArrayList(); - private final Stack mElementStack = new Stack(); - private final Stack mRuleStack = new Stack(); - private final HashMap mStyles = - new HashMap(10); + private final ArrayList mRulesList = new ArrayList<>(); + private final Stack mElementStack = new Stack<>(); + private final Stack mRuleStack = new Stack<>(); + private final HashMap mStyles = new HashMap<>(10); - private final HashMap> mTextStyles = - new HashMap>(10); + private final HashMap> mTextStyles = new HashMap<>(10); private final TextBuilder mTextBuilder = TextStyle.builder(); private final AreaBuilder mAreaBuilder = AreaStyle.builder(); @@ -135,11 +129,15 @@ public class XmlThemeBuilder extends DefaultHandler { private int mMapBackground = 0xffffffff; private float mTextScale = 1; - private final String mRelativePathPrefix; + private final ThemeFile mTheme; private RenderTheme mRenderTheme; - public XmlThemeBuilder(String relativePathPrefix) { - mRelativePathPrefix = relativePathPrefix; + private Set mCategories; + private XmlRenderThemeStyleLayer mCurrentLayer; + private XmlRenderThemeStyleMenu mRenderThemeStyleMenu; + + public XmlThemeBuilder(ThemeFile theme) { + mTheme = theme; } @Override @@ -166,10 +164,20 @@ public class XmlThemeBuilder extends DefaultHandler { if (ELEMENT_NAME_MATCH.equals(localName)) { mRuleStack.pop(); if (mRuleStack.empty()) { - mRulesList.add(mCurrentRule); + if (isVisible(mCurrentRule)) { + mRulesList.add(mCurrentRule); + } } else { mCurrentRule = mRuleStack.peek(); } + } else if (ELEMENT_NAME_STYLE_MENU.equals(localName)) { + // when we are finished parsing the menu part of the file, we can get the + // categories to render from the initiator. This allows the creating action + // to select which of the menu options to choose + if (null != mTheme.getMenuCallback()) { + // if there is no callback, there is no menu, so the categories will be null + mCategories = mTheme.getMenuCallback().getCategories(mRenderThemeStyleMenu); + } } } @@ -193,8 +201,8 @@ public class XmlThemeBuilder extends DefaultHandler { } else if (ELEMENT_NAME_MATCH.equals(localName)) { checkState(localName, Element.RULE); - RuleBuilder rule = createRule(localName, attributes, mRuleStack); - if (!mRuleStack.empty()) { + RuleBuilder rule = createRule(localName, attributes); + if (!mRuleStack.empty() && isVisible(rule)) { mCurrentRule.addSubRule(rule); } mCurrentRule = rule; @@ -228,7 +236,8 @@ public class XmlThemeBuilder extends DefaultHandler { } else if ("circle".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); CircleStyle circle = createCircle(localName, attributes, mLevels++); - mCurrentRule.addStyle(circle); + if (isVisible(circle)) + mCurrentRule.addStyle(circle); } else if ("line".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); @@ -241,17 +250,20 @@ public class XmlThemeBuilder extends DefaultHandler { } else if ("symbol".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); SymbolStyle symbol = createSymbol(localName, attributes); - if (symbol != null) + if (symbol != null && isVisible(symbol)) mCurrentRule.addStyle(symbol); } else if ("outline".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); - addOutline(attributes.getValue("use")); + LineStyle outline = createOutline(attributes.getValue("use"), attributes); + if (outline != null && isVisible(outline)) + mCurrentRule.addStyle(outline); } else if ("extrusion".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); ExtrusionStyle extrusion = createExtrusion(localName, attributes, mLevels++); - mCurrentRule.addStyle(extrusion); + if (isVisible(extrusion)) + mCurrentRule.addStyle(extrusion); } else if ("lineSymbol".equals(localName)) { checkState(localName, Element.RENDERING_INSTRUCTION); @@ -265,9 +277,53 @@ public class XmlThemeBuilder extends DefaultHandler { checkState(localName, Element.ATLAS); createTextureRegion(localName, attributes); + } else if ("cat".equals(localName)) { + checkState(qName, Element.RENDERING_STYLE); + mCurrentLayer.addCategory(getStringAttribute(attributes, "id")); + + } else if ("layer".equals(localName)) { + // render theme menu layer + checkState(qName, Element.RENDERING_STYLE); + boolean enabled = false; + if (getStringAttribute(attributes, "enabled") != null) { + enabled = Boolean.valueOf(getStringAttribute(attributes, "enabled")); + } + boolean visible = Boolean.valueOf(getStringAttribute(attributes, "visible")); + mCurrentLayer = mRenderThemeStyleMenu.createLayer(getStringAttribute(attributes, "id"), visible, enabled); + String parent = getStringAttribute(attributes, "parent"); + if (null != parent) { + XmlRenderThemeStyleLayer parentEntry = mRenderThemeStyleMenu.getLayer(parent); + if (null != parentEntry) { + for (String cat : parentEntry.getCategories()) { + mCurrentLayer.addCategory(cat); + } + for (XmlRenderThemeStyleLayer overlay : parentEntry.getOverlays()) { + mCurrentLayer.addOverlay(overlay); + } + } + } + + } else if ("name".equals(localName)) { + // render theme menu name + checkState(qName, Element.RENDERING_STYLE); + mCurrentLayer.addTranslation(getStringAttribute(attributes, "lang"), getStringAttribute(attributes, "value")); + + } else if ("overlay".equals(localName)) { + // render theme menu overlay + checkState(qName, Element.RENDERING_STYLE); + XmlRenderThemeStyleLayer overlay = mRenderThemeStyleMenu.getLayer(getStringAttribute(attributes, "id")); + if (overlay != null) { + mCurrentLayer.addOverlay(overlay); + } + + } else if ("stylemenu".equals(localName)) { + checkState(qName, Element.RENDERING_STYLE); + mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute(attributes, "id"), + getStringAttribute(attributes, "defaultlang"), getStringAttribute(attributes, "defaultvalue")); + } else { log.error("unknown element: {}", localName); - //throw new SAXException("unknown element: " + localName); + throw new SAXException("unknown element: " + localName); } } catch (SAXException e) { throw new ThemeException(e.getMessage()); @@ -276,8 +332,8 @@ public class XmlThemeBuilder extends DefaultHandler { } } - private RuleBuilder createRule(String localName, Attributes attributes, - Stack ruleStack) { + private RuleBuilder createRule(String localName, Attributes attributes) { + String cat = null; int element = Rule.Element.ANY; int closed = Closed.ANY; String keys = null; @@ -300,6 +356,8 @@ public class XmlThemeBuilder extends DefaultHandler { keys = value; } else if ("v".equals(name)) { values = value; + } else if ("cat".equals(name)) { + cat = value; } else if ("closed".equals(name)) { String val = value.toUpperCase(); if ("YES".equals(val)) @@ -331,6 +389,7 @@ public class XmlThemeBuilder extends DefaultHandler { throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin); RuleBuilder b = RuleBuilder.create(keys, values); + b.cat(cat); b.zoom(zoomMin, zoomMax); b.element(element); b.select(selector); @@ -368,10 +427,14 @@ public class XmlThemeBuilder extends DefaultHandler { if (isStyle) { mStyles.put(LINE_STYLE + line.style, line); } else { - mCurrentRule.addStyle(line); - /* Note 'outline' will not be inherited, it's just a - * shortcut to add the outline RenderInstruction. */ - addOutline(attributes.getValue("outline")); + if (isVisible(line)) { + mCurrentRule.addStyle(line); + /* Note 'outline' will not be inherited, it's just a + * shortcut to add the outline RenderInstruction. */ + LineStyle outline = createOutline(attributes.getValue("outline"), attributes); + if (outline != null) + mCurrentRule.addStyle(outline); + } } } @@ -394,6 +457,9 @@ public class XmlThemeBuilder extends DefaultHandler { if ("id".equals(name)) b.style = value; + else if ("cat".equals(name)) + b.cat(value); + else if ("src".equals(name)) { b.texture = loadTexture(value); /*if (b.texture != null) @@ -474,7 +540,8 @@ public class XmlThemeBuilder extends DefaultHandler { if (isStyle) { mStyles.put(AREA_STYLE + area.style, area); } else { - mCurrentRule.addStyle(area); + if (isVisible(area)) + mCurrentRule.addStyle(area); } } @@ -493,6 +560,9 @@ public class XmlThemeBuilder extends DefaultHandler { if ("id".equals(name)) b.style = value; + else if ("cat".equals(name)) + b.cat(value); + else if ("use".equals(name)) ;// ignore @@ -534,7 +604,7 @@ public class XmlThemeBuilder extends DefaultHandler { return null; try { - Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src); if (bitmap != null) { log.debug("loading {}", src); return new TextureItem(bitmap, true); @@ -545,14 +615,28 @@ public class XmlThemeBuilder extends DefaultHandler { return null; } - private void addOutline(String style) { + private LineStyle createOutline(String style, Attributes attributes) { if (style != null) { LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style); - if (line != null && line.outline) - mCurrentRule.addStyle(line); - else - log.debug("BUG not an outline style: " + style); + if (line != null && line.outline) { + String cat = null; + + for (int i = 0; i < attributes.getLength(); i++) { + String name = attributes.getLocalName(i); + String value = attributes.getValue(i); + + if ("cat".equals(name)) { + cat = value; + break; + } + } + + return line + .setCat(cat); + } } + log.debug("BUG not an outline style: " + style); + return null; } private void createAtlas(String elementName, Attributes attributes) throws IOException { @@ -570,7 +654,7 @@ public class XmlThemeBuilder extends DefaultHandler { } validateExists("img", img, elementName); - Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, img); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), img); if (bitmap != null) mTextureAtlas = new TextureAtlas(bitmap); } @@ -635,6 +719,7 @@ public class XmlThemeBuilder extends DefaultHandler { throw new SAXException(UNEXPECTED_ELEMENT + elementName); } return; + case ATLAS: parentElement = mElementStack.peek(); // FIXME @@ -643,6 +728,9 @@ public class XmlThemeBuilder extends DefaultHandler { throw new SAXException(UNEXPECTED_ELEMENT + elementName); } return; + + case RENDERING_STYLE: + return; } throw new SAXException("unknown enum value: " + element); @@ -666,8 +754,8 @@ public class XmlThemeBuilder extends DefaultHandler { if ("schemaLocation".equals(name)) continue; - else if ("version".equals(name)) - version = Integer.valueOf(Integer.parseInt(value)); + if ("version".equals(name)) + version = Integer.parseInt(value); else if ("map-background".equals(name)) mapBackground = Color.parseColor(value); @@ -685,7 +773,7 @@ public class XmlThemeBuilder extends DefaultHandler { validateExists("version", version, elementName); - if (version.intValue() != RENDER_THEME_VERSION) + if (version != RENDER_THEME_VERSION) throw new ThemeException("invalid render theme version:" + version); @@ -715,7 +803,9 @@ public class XmlThemeBuilder extends DefaultHandler { log.debug("put style {}", b.style); mTextStyles.put(b.style, TextStyle.builder().from(b)); } else { - mCurrentRule.addStyle(b.buildInternal()); + TextStyle text = b.buildInternal(); + if (isVisible(text)) + mCurrentRule.addStyle(text); } } @@ -739,6 +829,9 @@ public class XmlThemeBuilder extends DefaultHandler { if ("id".equals(name)) b.style = value; + else if ("cat".equals(name)) + b.cat(value); + else if ("k".equals(name)) b.textKey = value.intern(); @@ -774,7 +867,7 @@ public class XmlThemeBuilder extends DefaultHandler { String lowValue = value.toLowerCase(Locale.ENGLISH); if (lowValue.endsWith(".png") || lowValue.endsWith(".svg")) { try { - b.bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, value); + b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), value); } catch (Exception e) { log.debug(e.getMessage()); } @@ -798,6 +891,7 @@ public class XmlThemeBuilder extends DefaultHandler { * @return a new Circle with the given rendering attributes. */ private static CircleStyle createCircle(String elementName, Attributes attributes, int level) { + String cat = null; Float radius = null; boolean scaleRadius = false; int fill = Color.TRANSPARENT; @@ -809,7 +903,10 @@ public class XmlThemeBuilder extends DefaultHandler { String value = attributes.getValue(i); if ("r".equals(name) || "radius".equals(name)) - radius = Float.valueOf(Float.parseFloat(value)); + radius = Float.parseFloat(value); + + else if ("cat".equals(name)) + cat = value; else if ("scale-radius".equals(name)) scaleRadius = Boolean.parseBoolean(value); @@ -831,13 +928,15 @@ public class XmlThemeBuilder extends DefaultHandler { validateNonNegative("radius", radius); validateNonNegative("stroke-width", strokeWidth); - return new CircleStyle(radius, scaleRadius, fill, stroke, strokeWidth, level); + return new CircleStyle(radius, scaleRadius, fill, stroke, strokeWidth, level) + .setCat(cat); } /** * @return a new Symbol with the given rendering attributes. */ private SymbolStyle createSymbol(String elementName, Attributes attributes) { + String cat = null; String src = null; for (int i = 0; i < attributes.getLength(); i++) { @@ -846,6 +945,10 @@ public class XmlThemeBuilder extends DefaultHandler { if ("src".equals(name)) src = value; + + else if ("cat".equals(name)) + cat = value; + else logUnknownAttribute(elementName, name, value, i); } @@ -855,18 +958,21 @@ public class XmlThemeBuilder extends DefaultHandler { String lowSrc = src.toLowerCase(Locale.ENGLISH); if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) { try { - Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src); if (bitmap != null) - return new SymbolStyle(bitmap); + return new SymbolStyle(bitmap) + .setCat(cat); } catch (Exception e) { log.debug(e.getMessage()); } return null; } - return new SymbolStyle(getAtlasRegion(src)); + return new SymbolStyle(getAtlasRegion(src)) + .setCat(cat); } private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) { + String cat = null; int colorSide = 0; int colorTop = 0; int colorLine = 0; @@ -876,7 +982,10 @@ public class XmlThemeBuilder extends DefaultHandler { String name = attributes.getLocalName(i); String value = attributes.getValue(i); - if ("side-color".equals(name)) + if ("cat".equals(name)) + cat = value; + + else if ("side-color".equals(name)) colorSide = Color.parseColor(value); else if ("top-color".equals(name)) @@ -892,7 +1001,33 @@ public class XmlThemeBuilder extends DefaultHandler { logUnknownAttribute(elementName, name, value, i); } - return new ExtrusionStyle(level, colorSide, colorTop, colorLine, defaultHeight); + return new ExtrusionStyle(level, colorSide, colorTop, colorLine, defaultHeight) + .setCat(cat); + } + + private String getStringAttribute(Attributes attributes, String name) { + for (int i = 0; i < attributes.getLength(); ++i) { + if (attributes.getLocalName(i).equals(name)) { + return attributes.getValue(i); + } + } + return null; + } + + /** + * A style is visible if categories is not set or the style has no category + * or the categories contain the style's category. + */ + private boolean isVisible(RenderStyle renderStyle) { + return mCategories == null || renderStyle.cat == null || mCategories.contains(renderStyle.cat); + } + + /** + * A rule is visible if categories is not set or the rule has no category + * or the categories contain the rule's category. + */ + private boolean isVisible(RuleBuilder rule) { + return mCategories == null || rule.cat == null || mCategories.contains(rule.cat); } public static void validateNonNegative(String name, float value) { diff --git a/vtm/src/org/oscim/theme/rule/Rule.java b/vtm/src/org/oscim/theme/rule/Rule.java index d9212acf..0485698b 100644 --- a/vtm/src/org/oscim/theme/rule/Rule.java +++ b/vtm/src/org/oscim/theme/rule/Rule.java @@ -1,6 +1,7 @@ /* * Copyright 2014 Hannes Janetzek - * + * Copyright 2016 devemux86 + * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * * This program is free software: you can redistribute it and/or modify it under the @@ -49,6 +50,7 @@ public class Rule { public final Rule[] subRules; public final RenderStyle[] styles; + public String cat; public final int zoom; public final int element; public final boolean selectFirstMatch; @@ -127,6 +129,11 @@ public class Rule { subRule.scaleTextSize(scaleFactor); } + public Rule setCat(String cat) { + this.cat = cat; + return this; + } + public void updateStyles() { for (RenderStyle ri : styles) ri.update(); diff --git a/vtm/src/org/oscim/theme/rule/RuleBuilder.java b/vtm/src/org/oscim/theme/rule/RuleBuilder.java index 9c33dfeb..398cf0be 100644 --- a/vtm/src/org/oscim/theme/rule/RuleBuilder.java +++ b/vtm/src/org/oscim/theme/rule/RuleBuilder.java @@ -40,6 +40,7 @@ public class RuleBuilder { EXCLUDE } + public String cat; int zoom; int element; int selector; @@ -153,7 +154,8 @@ public class RuleBuilder { int numVals = values.length; if (numKeys == 0 && numVals == 0) - return new Rule(element, zoom, selector, rules, styles); + return new Rule(element, zoom, selector, rules, styles) + .setCat(cat); for (int i = 0; i < numVals; i++) values[i] = values[i].intern(); @@ -162,24 +164,23 @@ public class RuleBuilder { keys[i] = keys[i].intern(); if (type != RuleType.POSITIVE) - return new NegativeRule(type, element, zoom, selector, - keys, values, rules, styles); + return new NegativeRule(type, element, zoom, selector, keys, values, rules, styles) + .setCat(cat); if (numKeys == 1 && numVals == 0) - return new PositiveRuleK(element, zoom, selector, keys[0], - rules, styles); + return new PositiveRuleK(element, zoom, selector, keys[0], rules, styles) + .setCat(cat); if (numKeys == 0 && numVals == 1) - return new PositiveRuleV(element, zoom, selector, values[0], - rules, styles); + return new PositiveRuleV(element, zoom, selector, values[0], rules, styles) + .setCat(cat); if (numKeys == 1 && numVals == 1) - return new PositiveRuleKV(element, zoom, selector, - keys[0], values[0], rules, styles); - - return new PositiveRuleMultiKV(element, zoom, selector, - keys, values, rules, styles); + return new PositiveRuleKV(element, zoom, selector, keys[0], values[0], rules, styles) + .setCat(cat); + return new PositiveRuleMultiKV(element, zoom, selector, keys, values, rules, styles) + .setCat(cat); } public RuleBuilder addStyle(RenderStyle style) { @@ -216,4 +217,9 @@ public class RuleBuilder { this.element = element; return this; } + + public RuleBuilder cat(String cat) { + this.cat = cat; + return this; + } } diff --git a/vtm/src/org/oscim/theme/styles/AreaStyle.java b/vtm/src/org/oscim/theme/styles/AreaStyle.java index ca719119..0edc9a09 100644 --- a/vtm/src/org/oscim/theme/styles/AreaStyle.java +++ b/vtm/src/org/oscim/theme/styles/AreaStyle.java @@ -27,7 +27,7 @@ import static org.oscim.backend.canvas.Color.parseColor; * - add custom shaders * - create distance field per tile? */ -public class AreaStyle extends RenderStyle { +public class AreaStyle extends RenderStyle { private static final float FADE_START = 0.25f; diff --git a/vtm/src/org/oscim/theme/styles/CircleStyle.java b/vtm/src/org/oscim/theme/styles/CircleStyle.java index e3d51ebc..d5be548b 100644 --- a/vtm/src/org/oscim/theme/styles/CircleStyle.java +++ b/vtm/src/org/oscim/theme/styles/CircleStyle.java @@ -1,6 +1,7 @@ /* * Copyright 2010, 2011, 2012 mapsforge.org * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -20,7 +21,7 @@ package org.oscim.theme.styles; /** * Represents a round area on the map. */ -public final class CircleStyle extends RenderStyle { +public final class CircleStyle extends RenderStyle { public final int level; @@ -35,7 +36,7 @@ public final class CircleStyle extends RenderStyle { float strokeWidth, int level) { super(); - this.radius = radius.floatValue(); + this.radius = radius; this.scaleRadius = scaleRadius; this.fill = fill; diff --git a/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java b/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java index 022729b7..a5d666aa 100644 --- a/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java +++ b/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -18,7 +19,7 @@ package org.oscim.theme.styles; import org.oscim.backend.canvas.Color; -public class ExtrusionStyle extends RenderStyle { +public class ExtrusionStyle extends RenderStyle { public ExtrusionStyle(int level, int colorSides, int colorTop, int colorLine, int defaultHeight) { diff --git a/vtm/src/org/oscim/theme/styles/LineStyle.java b/vtm/src/org/oscim/theme/styles/LineStyle.java index e29f7af3..9bbb93a3 100644 --- a/vtm/src/org/oscim/theme/styles/LineStyle.java +++ b/vtm/src/org/oscim/theme/styles/LineStyle.java @@ -24,7 +24,7 @@ import org.oscim.renderer.bucket.TextureItem; import static org.oscim.backend.canvas.Color.parseColor; -public final class LineStyle extends RenderStyle { +public final class LineStyle extends RenderStyle { final int level; public final String style; diff --git a/vtm/src/org/oscim/theme/styles/RenderStyle.java b/vtm/src/org/oscim/theme/styles/RenderStyle.java index 1f174db7..5a246994 100644 --- a/vtm/src/org/oscim/theme/styles/RenderStyle.java +++ b/vtm/src/org/oscim/theme/styles/RenderStyle.java @@ -23,10 +23,10 @@ import static org.oscim.backend.canvas.Color.parseColor; /** * A RenderInstruction is a basic graphical primitive to draw a map. */ -public abstract class RenderStyle { +public abstract class RenderStyle> { public static abstract class StyleBuilder> { - + public String cat; public String style; public int level; @@ -36,6 +36,11 @@ public abstract class RenderStyle { public int strokeColor; public float strokeWidth; + public T cat(String cat) { + this.cat = cat; + return self(); + } + public T style(String style) { this.style = style; return self(); @@ -88,20 +93,14 @@ public abstract class RenderStyle { /** * Callback methods for rendering areas, ways and points of interest (POIs). */ - public static interface Callback { + public interface Callback { /** * Renders an area with the given parameters. - * - * @param area - * @param level */ void renderArea(AreaStyle area, int level); /** * Renders an extrusion with the given parameters. - * - * @param extrusion - * @param level */ void renderExtrusion(ExtrusionStyle extrusion, int level); @@ -122,25 +121,35 @@ public abstract class RenderStyle { /** * Renders a way with the given parameters. - * - * @param line - * @param level */ void renderWay(LineStyle line, int level); /** * Renders a way with the given text along the way path. - * - * @param text */ void renderText(TextStyle text); } + /** + * Category + */ + public String cat = null; + RenderStyle mCurrent = this; RenderStyle mNext; boolean update; + public T setCat(String cat) { + this.cat = cat; + return self(); + } + + @SuppressWarnings("unchecked") + protected T self() { + return (T) this; + } + public void set(RenderStyle next) { update = true; mNext = next; diff --git a/vtm/src/org/oscim/theme/styles/SymbolStyle.java b/vtm/src/org/oscim/theme/styles/SymbolStyle.java index a5f8ea85..2abb3c5a 100644 --- a/vtm/src/org/oscim/theme/styles/SymbolStyle.java +++ b/vtm/src/org/oscim/theme/styles/SymbolStyle.java @@ -24,7 +24,7 @@ import org.oscim.renderer.atlas.TextureRegion; /** * Represents an icon on the map. */ -public final class SymbolStyle extends RenderStyle { +public final class SymbolStyle extends RenderStyle { public Bitmap bitmap; public TextureRegion texture; diff --git a/vtm/src/org/oscim/theme/styles/TextStyle.java b/vtm/src/org/oscim/theme/styles/TextStyle.java index 5d479903..e961c854 100644 --- a/vtm/src/org/oscim/theme/styles/TextStyle.java +++ b/vtm/src/org/oscim/theme/styles/TextStyle.java @@ -26,7 +26,7 @@ import org.oscim.backend.canvas.Paint.FontFamily; import org.oscim.backend.canvas.Paint.FontStyle; import org.oscim.renderer.atlas.TextureRegion; -public final class TextStyle extends RenderStyle { +public final class TextStyle extends RenderStyle { public static class TextBuilder> extends StyleBuilder {