From 73bc26dd2d46d3a104ae0e0a5026cda5812365c8 Mon Sep 17 00:00:00 2001 From: Emux Date: Wed, 13 Jul 2016 19:15:34 +0300 Subject: [PATCH] Render themes: read resources from files, besides assets, closes #65 --- .../android/filepicker/ValidRenderTheme.java | 3 +- .../oscim/android/canvas/AndroidGraphics.java | 4 +-- .../oscim/android/canvas/AndroidGraphics.java | 4 +-- .../src/org/oscim/awt/AwtGraphics.java | 4 +-- .../org/oscim/ios/backend/IosGraphics.java | 7 +++-- .../test/renderer/SymbolRenderLayer.java | 3 +- vtm-themes/src/org/oscim/theme/VtmThemes.java | 8 ++++- .../src/org/oscim/web/js/JsOverlays.java | 20 ++++++++++-- .../org/oscim/gdx/client/GwtGdxGraphics.java | 7 +++-- vtm/src/org/oscim/backend/CanvasAdapter.java | 31 ++++++++++++++----- .../org/oscim/theme/ExternalRenderTheme.java | 8 ++++- vtm/src/org/oscim/theme/ThemeFile.java | 6 ++++ vtm/src/org/oscim/theme/ThemeLoader.java | 10 ++++-- vtm/src/org/oscim/theme/XmlThemeBuilder.java | 24 +++++++++----- 14 files changed, 106 insertions(+), 33 deletions(-) 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 d6421143..15f6b715 100644 --- a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java +++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java @@ -1,5 +1,6 @@ /* * Copyright 2010, 2011, 2012 mapsforge.org + * 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 @@ -40,7 +41,7 @@ public final class ValidRenderTheme implements ValidFileFilter { try { inputStream = new FileInputStream(file); - XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(); + XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(file.getParent()); XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); xmlReader.setContentHandler(renderThemeHandler); xmlReader.parse(new InputSource(inputStream)); diff --git a/vtm-android-gdx/src/org/oscim/android/canvas/AndroidGraphics.java b/vtm-android-gdx/src/org/oscim/android/canvas/AndroidGraphics.java index 45a15738..34d229e2 100644 --- a/vtm-android-gdx/src/org/oscim/android/canvas/AndroidGraphics.java +++ b/vtm-android-gdx/src/org/oscim/android/canvas/AndroidGraphics.java @@ -56,9 +56,9 @@ public final class AndroidGraphics extends CanvasAdapter { } @Override - public Bitmap loadBitmapAssetImpl(String fileName) { + public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { try { - return createBitmap(fileName); + return createBitmap(relativePathPrefix, src); } catch (IOException e) { e.printStackTrace(); } diff --git a/vtm-android/src/org/oscim/android/canvas/AndroidGraphics.java b/vtm-android/src/org/oscim/android/canvas/AndroidGraphics.java index 45a15738..34d229e2 100644 --- a/vtm-android/src/org/oscim/android/canvas/AndroidGraphics.java +++ b/vtm-android/src/org/oscim/android/canvas/AndroidGraphics.java @@ -56,9 +56,9 @@ public final class AndroidGraphics extends CanvasAdapter { } @Override - public Bitmap loadBitmapAssetImpl(String fileName) { + public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { try { - return createBitmap(fileName); + return createBitmap(relativePathPrefix, src); } catch (IOException e) { e.printStackTrace(); } diff --git a/vtm-desktop/src/org/oscim/awt/AwtGraphics.java b/vtm-desktop/src/org/oscim/awt/AwtGraphics.java index c4cb8bd5..ba15e3fd 100644 --- a/vtm-desktop/src/org/oscim/awt/AwtGraphics.java +++ b/vtm-desktop/src/org/oscim/awt/AwtGraphics.java @@ -101,9 +101,9 @@ public class AwtGraphics extends CanvasAdapter { } @Override - public Bitmap loadBitmapAssetImpl(String fileName) { + public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { try { - return createBitmap(fileName); + return createBitmap(relativePathPrefix, src); } catch (IOException e) { e.printStackTrace(); } diff --git a/vtm-ios/src/org/oscim/ios/backend/IosGraphics.java b/vtm-ios/src/org/oscim/ios/backend/IosGraphics.java index 69542881..6b1f2fdc 100644 --- a/vtm-ios/src/org/oscim/ios/backend/IosGraphics.java +++ b/vtm-ios/src/org/oscim/ios/backend/IosGraphics.java @@ -1,5 +1,6 @@ /* * Copyright 2016 Longri + * 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 @@ -21,6 +22,7 @@ import org.oscim.backend.canvas.Paint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -61,9 +63,10 @@ public class IosGraphics extends CanvasAdapter { } @Override - protected Bitmap loadBitmapAssetImpl(String fileName) { + protected Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { try { - return new IosBitmap(fileName); + String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src; + return new IosBitmap(pathName); } catch (IOException e) { log.error("loadBitmapAssetImpl", e); return null; diff --git a/vtm-playground/src/org/oscim/test/renderer/SymbolRenderLayer.java b/vtm-playground/src/org/oscim/test/renderer/SymbolRenderLayer.java index fd1711b7..5b026dbf 100644 --- a/vtm-playground/src/org/oscim/test/renderer/SymbolRenderLayer.java +++ b/vtm-playground/src/org/oscim/test/renderer/SymbolRenderLayer.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -33,7 +34,7 @@ public class SymbolRenderLayer extends BucketRenderer { it.billboard = false; try { - it.bitmap = CanvasAdapter.getBitmapAsset("jar:symbols/cafe.png"); + it.bitmap = CanvasAdapter.getBitmapAsset("", "jar:symbols/cafe.png"); } catch (Exception e) { e.printStackTrace(); diff --git a/vtm-themes/src/org/oscim/theme/VtmThemes.java b/vtm-themes/src/org/oscim/theme/VtmThemes.java index bea032c2..5c13de89 100644 --- a/vtm-themes/src/org/oscim/theme/VtmThemes.java +++ b/vtm-themes/src/org/oscim/theme/VtmThemes.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). * @@ -33,10 +34,15 @@ public enum VtmThemes implements ThemeFile { private final String mPath; - private VtmThemes(String path) { + VtmThemes(String path) { mPath = path; } + @Override + public String getRelativePathPrefix() { + return ""; + } + @Override public InputStream getRenderThemeAsStream() { return AssetAdapter.readFileAsStream(mPath); diff --git a/vtm-web-js/src/org/oscim/web/js/JsOverlays.java b/vtm-web-js/src/org/oscim/web/js/JsOverlays.java index 00897fba..97c268d1 100644 --- a/vtm-web-js/src/org/oscim/web/js/JsOverlays.java +++ b/vtm-web-js/src/org/oscim/web/js/JsOverlays.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.web.js; import org.oscim.core.MapPosition; @@ -13,7 +29,7 @@ import org.oscim.map.Map; import org.oscim.renderer.LayerRenderer; import org.oscim.theme.IRenderTheme; import org.oscim.tiling.TileSource; -import org.oscim.tiling.source.geojson.HighroadJsonTileSource; +import org.oscim.tiling.source.geojson.OsmRoadLineJsonTileSource; import org.oscim.tiling.source.oscimap4.OSciMap4TileSource; import org.timepedia.exporter.client.Export; import org.timepedia.exporter.client.ExportOverlay; @@ -90,7 +106,7 @@ public class JsOverlays implements Exportable { @ExportPackage("vtm") @Export("HighroadJsonTileSource") public static class XHighroadJsonTileSource implements - ExportOverlay { + ExportOverlay { public XHighroadJsonTileSource() { } } diff --git a/vtm-web/src/org/oscim/gdx/client/GwtGdxGraphics.java b/vtm-web/src/org/oscim/gdx/client/GwtGdxGraphics.java index 51382a96..92d2e2ae 100644 --- a/vtm-web/src/org/oscim/gdx/client/GwtGdxGraphics.java +++ b/vtm-web/src/org/oscim/gdx/client/GwtGdxGraphics.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -24,6 +25,7 @@ import org.oscim.backend.CanvasAdapter; import org.oscim.backend.canvas.Bitmap; import org.oscim.backend.canvas.Paint; +import java.io.File; import java.io.InputStream; public class GwtGdxGraphics extends CanvasAdapter { @@ -52,8 +54,9 @@ public class GwtGdxGraphics extends CanvasAdapter { } @Override - public Bitmap loadBitmapAssetImpl(String fileName) { - return new GwtBitmap(fileName); + public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { + String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src; + return new GwtBitmap(pathName); } @Override diff --git a/vtm/src/org/oscim/backend/CanvasAdapter.java b/vtm/src/org/oscim/backend/CanvasAdapter.java index 09948606..10bd47c3 100644 --- a/vtm/src/org/oscim/backend/CanvasAdapter.java +++ b/vtm/src/org/oscim/backend/CanvasAdapter.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -19,7 +20,11 @@ package org.oscim.backend; import org.oscim.backend.canvas.Bitmap; import org.oscim.backend.canvas.Canvas; import org.oscim.backend.canvas.Paint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -27,6 +32,7 @@ import java.io.InputStream; * The Class CanvasAdapter. */ public abstract class CanvasAdapter { + private static final Logger log = LoggerFactory.getLogger(CanvasAdapter.class); /** * The instance provided by backend @@ -94,24 +100,35 @@ public abstract class CanvasAdapter { /** * Create {@link Bitmap} from bundled assets. * - * @param fileName the file name + * @param relativePathPrefix the prefix for relative resource path + * @param src the resource * @return the bitmap */ - protected abstract Bitmap loadBitmapAssetImpl(String fileName); + protected abstract Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src); - public static Bitmap getBitmapAsset(String fileName) { - return g.loadBitmapAssetImpl(fileName); + public static Bitmap getBitmapAsset(String relativePathPrefix, String src) { + return g.loadBitmapAssetImpl(relativePathPrefix, src); } - protected static Bitmap createBitmap(String src) throws IOException { + protected static Bitmap createBitmap(String relativePathPrefix, String src) throws IOException { if (src == null || src.length() == 0) { // no image source defined return null; } - InputStream inputStream = AssetAdapter.g.openFileAsStream(src); + String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix) + File.separatorChar + src; + + InputStream inputStream = null; + + File file = new File(pathName); + if (file.exists() && file.isFile() && file.canRead()) + inputStream = new FileInputStream(file); + + if (inputStream == null) + inputStream = AssetAdapter.g.openFileAsStream(pathName); + if (inputStream == null) { - //log.error("invalid bitmap source: " + src); + log.error("invalid resource: " + pathName); return null; } diff --git a/vtm/src/org/oscim/theme/ExternalRenderTheme.java b/vtm/src/org/oscim/theme/ExternalRenderTheme.java index 6c0d1931..5bb75baa 100644 --- a/vtm/src/org/oscim/theme/ExternalRenderTheme.java +++ b/vtm/src/org/oscim/theme/ExternalRenderTheme.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). * @@ -36,7 +37,7 @@ public class ExternalRenderTheme implements ThemeFile { /** * @param fileName the path to the XML render theme file. - * @throws FileNotFoundException if the file does not exist or cannot be read. + * @throws ThemeException if the file does not exist or cannot be read. */ public ExternalRenderTheme(String fileName) { @@ -74,6 +75,11 @@ public class ExternalRenderTheme implements ThemeFile { return true; } + @Override + public String getRelativePathPrefix() { + return new File(mPath).getParent(); + } + @Override public InputStream getRenderThemeAsStream() { InputStream is; diff --git a/vtm/src/org/oscim/theme/ThemeFile.java b/vtm/src/org/oscim/theme/ThemeFile.java index bbcfd830..1a13e6b2 100644 --- a/vtm/src/org/oscim/theme/ThemeFile.java +++ b/vtm/src/org/oscim/theme/ThemeFile.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). * @@ -22,6 +23,11 @@ import java.io.InputStream; import java.io.Serializable; public interface ThemeFile extends Serializable { + /** + * @return the prefix for all relative resource paths. + */ + String getRelativePathPrefix(); + /** * @return an InputStream to read the render theme data from. * @throws FileNotFoundException if the render theme file cannot be found. diff --git a/vtm/src/org/oscim/theme/ThemeLoader.java b/vtm/src/org/oscim/theme/ThemeLoader.java index 5dce0557..eda78c28 100644 --- a/vtm/src/org/oscim/theme/ThemeLoader.java +++ b/vtm/src/org/oscim/theme/ThemeLoader.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2016 devemux86 * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -14,7 +15,6 @@ * 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.backend.CanvasAdapter; @@ -44,7 +44,7 @@ public class ThemeLoader { try { InputStream is = theme.getRenderThemeAsStream(); - return load(is); + return load(theme.getRelativePathPrefix(), is); } catch (FileNotFoundException e) { log.error(e.getMessage()); } @@ -53,9 +53,13 @@ public class ThemeLoader { } 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(inputStream); + IRenderTheme t = XmlThemeBuilder.read(relativePathPrefix, inputStream); if (t != null) t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f); return t; diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java index 82d14c2e..f76570be 100644 --- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java @@ -80,16 +80,17 @@ public class XmlThemeBuilder extends DefaultHandler { private static final String AREA_STYLE = "A"; /** - * @param inputStream an input stream containing valid render theme XML data. + * @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. * @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(InputStream inputStream) + public static IRenderTheme read(String relativePathPrefix, InputStream inputStream) throws ThemeException { - XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(); + XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(relativePathPrefix); try { new XMLReaderAdapter().parse(renderThemeHandler, inputStream); @@ -134,8 +135,13 @@ public class XmlThemeBuilder extends DefaultHandler { private int mMapBackground = 0xffffffff; private float mTextScale = 1; + private final String mRelativePathPrefix; private RenderTheme mRenderTheme; + public XmlThemeBuilder(String relativePathPrefix) { + mRelativePathPrefix = relativePathPrefix; + } + @Override public void endDocument() { @@ -522,7 +528,7 @@ public class XmlThemeBuilder extends DefaultHandler { if (src != null) { try { - Bitmap bitmap = CanvasAdapter.getBitmapAsset(src); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src); if (bitmap != null) b.texture = new TextureItem(bitmap, true); } catch (Exception e) { @@ -557,11 +563,15 @@ public class XmlThemeBuilder extends DefaultHandler { } validateExists("img", img, elementName); - Bitmap bitmap = CanvasAdapter.getBitmapAsset(img); - mTextureAtlas = new TextureAtlas(bitmap); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, img); + if (bitmap != null) + mTextureAtlas = new TextureAtlas(bitmap); } private void createTextureRegion(String elementName, Attributes attributes) { + if (mTextureAtlas == null) + return; + String regionName = null; Rect r = null; @@ -829,7 +839,7 @@ public class XmlThemeBuilder extends DefaultHandler { if (src.toLowerCase(Locale.ENGLISH).endsWith(".png")) { try { - Bitmap bitmap = CanvasAdapter.getBitmapAsset(src); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src); if (bitmap != null) return new SymbolStyle(bitmap); } catch (Exception e) {