From d1fdca170e4411a475d8973f813bd3d2997a157f Mon Sep 17 00:00:00 2001 From: Longri Date: Thu, 16 Mar 2017 11:43:38 +0100 Subject: [PATCH] POT textures (#334) --- .../oscim/android/canvas/AndroidCanvas.java | 9 ++ vtm-desktop/src/org/oscim/awt/AwtCanvas.java | 7 ++ .../org/oscim/ios/test/ExampleLauncher.java | 9 +- .../org/oscim/ios/test/IOSLineTexTest.java | 7 +- .../src/org/oscim/ios/test/IOSMapApp.java | 4 +- .../src/org/oscim/ios/backend/IosCanvas.java | 9 ++ .../oscim/test/MapsforgeLine_NPOT_Test.java | 87 ++++++++++++++++++ .../oscim/test/MapsforgeLine_POT_Test.java | 90 +++++++++++++++++++ .../src/org/oscim/gdx/client/GwtCanvas.java | 5 ++ vtm/src/org/oscim/backend/canvas/Canvas.java | 6 ++ vtm/src/org/oscim/theme/ThemeLoader.java | 1 + vtm/src/org/oscim/theme/XmlThemeBuilder.java | 23 ++++- 12 files changed, 244 insertions(+), 13 deletions(-) create mode 100644 vtm-playground/src/org/oscim/test/MapsforgeLine_NPOT_Test.java create mode 100644 vtm-playground/src/org/oscim/test/MapsforgeLine_POT_Test.java diff --git a/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java b/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java index 13d7bcf3..bbef0388 100644 --- a/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java +++ b/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java @@ -2,6 +2,7 @@ * Copyright 2013 Hannes Janetzek * Copyright 2016-2017 devemux86 * Copyright 2017 nebular + * Copyright 2017 Longri * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -58,6 +59,14 @@ public class AndroidCanvas implements Canvas { } } + @Override + public void drawBitmap(Bitmap bitmap) { + android.graphics.Bitmap scaledBitmap = android.graphics.Bitmap.createScaledBitmap( + ((AndroidBitmap) bitmap).mBitmap, canvas.getWidth(), canvas.getHeight(), true); + canvas.drawBitmap(scaledBitmap, 0, 0, null); + scaledBitmap.recycle(); + } + @Override public void drawBitmap(Bitmap bitmap, float x, float y) { canvas.drawBitmap(((AndroidBitmap) bitmap).mBitmap, x, y, null); diff --git a/vtm-desktop/src/org/oscim/awt/AwtCanvas.java b/vtm-desktop/src/org/oscim/awt/AwtCanvas.java index 7b50faaa..4259b140 100644 --- a/vtm-desktop/src/org/oscim/awt/AwtCanvas.java +++ b/vtm-desktop/src/org/oscim/awt/AwtCanvas.java @@ -28,6 +28,7 @@ import org.oscim.backend.canvas.Paint; import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Graphics2D; +import java.awt.Image; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.font.TextLayout; @@ -127,6 +128,12 @@ public class AwtCanvas implements Canvas { } } + @Override + public void drawBitmap(Bitmap bitmap) { + Image scaledImage = ((AwtBitmap) bitmap).bitmap.getScaledInstance(this.bitmap.getWidth(), this.bitmap.getHeight(), Image.SCALE_DEFAULT); + this.canvas.drawImage(scaledImage, 0, 0, this.bitmap.getWidth(), this.bitmap.getHeight(), null); + } + @Override public void drawBitmap(Bitmap bitmap, float x, float y) { BufferedImage src = ((AwtBitmap) bitmap).bitmap; diff --git a/vtm-ios-example/src/org/oscim/ios/test/ExampleLauncher.java b/vtm-ios-example/src/org/oscim/ios/test/ExampleLauncher.java index eb880d80..964d985a 100644 --- a/vtm-ios-example/src/org/oscim/ios/test/ExampleLauncher.java +++ b/vtm-ios-example/src/org/oscim/ios/test/ExampleLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Longri + * Copyright 2016-2017 Longri * Copyright 2016 devemux86 * * This program is free software: you can redistribute it and/or modify it under the @@ -19,6 +19,7 @@ import com.badlogic.gdx.backends.iosrobovm.IOSApplication; import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration; import org.oscim.backend.CanvasAdapter; +import org.oscim.theme.ThemeLoader; import org.robovm.apple.foundation.NSAutoreleasePool; import org.robovm.apple.glkit.GLKViewDrawableStencilFormat; import org.robovm.apple.uikit.UIApplication; @@ -37,12 +38,12 @@ public class ExampleLauncher extends IOSApplication.Delegate { float scale = (float) (getIosVersion() >= 8 ? UIScreen.getMainScreen().getNativeScale() : UIScreen.getMainScreen().getScale()); CanvasAdapter.dpi *= scale; -// IOSMapApp iosMapApp = new IOSMapApp(); +// IOSMapApp iosMapApp = new IOSMapApp(); + IOSLineTexTest iosMapApp = new IOSLineTexTest(); // IOSMapAppCluster iosMapApp = new IOSMapAppCluster(); - IOSLineTexTest iosMapApp = new IOSLineTexTest(); - + ThemeLoader.POT_TEXTURES = true; iosMapApp.init(); return new IOSApplication(iosMapApp, config); diff --git a/vtm-ios-example/src/org/oscim/ios/test/IOSLineTexTest.java b/vtm-ios-example/src/org/oscim/ios/test/IOSLineTexTest.java index 5e017814..7f4ce361 100644 --- a/vtm-ios-example/src/org/oscim/ios/test/IOSLineTexTest.java +++ b/vtm-ios-example/src/org/oscim/ios/test/IOSLineTexTest.java @@ -1,6 +1,6 @@ /* * Copyright 2013 Hannes Janetzek - * Copyright 2016 Longri + * Copyright 2016-2017 Longri * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -17,7 +17,6 @@ */ package org.oscim.ios.test; -import org.oscim.backend.CanvasAdapter; import org.oscim.backend.GLAdapter; import org.oscim.backend.canvas.Color; import org.oscim.core.GeoPoint; @@ -35,6 +34,7 @@ import org.oscim.layers.vector.geometries.Style; import org.oscim.map.Map; import org.oscim.renderer.bucket.TextureItem; import org.oscim.theme.VtmThemes; +import org.oscim.theme.XmlThemeBuilder; import org.oscim.tiling.source.oscimap4.OSciMap4TileSource; import java.util.ArrayList; @@ -63,7 +63,8 @@ public class IOSLineTexTest extends GdxMap { mMap.setMapPosition(0, 0, 1 << 2); - tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png")); + tex = XmlThemeBuilder.loadTexture("", "patterns/pike.png", 0, 0, 100); +// tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png")); tex.mipmap = true; createLayers(1, true); diff --git a/vtm-ios-example/src/org/oscim/ios/test/IOSMapApp.java b/vtm-ios-example/src/org/oscim/ios/test/IOSMapApp.java index 37769467..2caa84db 100644 --- a/vtm-ios-example/src/org/oscim/ios/test/IOSMapApp.java +++ b/vtm-ios-example/src/org/oscim/ios/test/IOSMapApp.java @@ -1,6 +1,6 @@ /* * Copyright 2013 Hannes Janetzek - * Copyright 2016 Longri + * Copyright 2016-2017 Longri * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -69,7 +69,7 @@ public class IOSMapApp extends GdxMap { renderer.setOffset(5, 0); map.layers().add(mapScaleBarLayer); - map.setTheme(VtmThemes.DEFAULT); + map.setTheme(VtmThemes.OSMARENDER); map.setMapPosition(53.075, 8.808, 1 << 17); } } diff --git a/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java b/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java index d5ccb066..8087742e 100644 --- a/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java +++ b/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java @@ -83,6 +83,15 @@ public class IosCanvas implements Canvas { iosFill.drawLine(this.cgBitmapContext, string, x, y); } + @Override + public void drawBitmap(Bitmap bitmap) { + CGRect rect = new CGRect(0, 0, this.cgBitmapContext.getWidth(), this.cgBitmapContext.getHeight()); + this.cgBitmapContext.saveGState(); + this.cgBitmapContext.translateCTM(0, 0); + this.cgBitmapContext.drawImage(rect, ((IosBitmap) bitmap).cgBitmapContext.toImage()); + this.cgBitmapContext.restoreGState(); + } + @Override public void drawBitmap(Bitmap bitmap, float x, float y) { this.cgBitmapContext.saveGState(); diff --git a/vtm-playground/src/org/oscim/test/MapsforgeLine_NPOT_Test.java b/vtm-playground/src/org/oscim/test/MapsforgeLine_NPOT_Test.java new file mode 100644 index 00000000..e45f5294 --- /dev/null +++ b/vtm-playground/src/org/oscim/test/MapsforgeLine_NPOT_Test.java @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Longri + * + * 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 org.oscim.gdx.GdxMap; +import org.oscim.gdx.GdxMapApp; +import org.oscim.layers.TileGridLayer; +import org.oscim.layers.tile.vector.VectorTileLayer; +import org.oscim.renderer.BitmapRenderer; +import org.oscim.renderer.GLViewport; +import org.oscim.scalebar.DefaultMapScaleBar; +import org.oscim.scalebar.ImperialUnitAdapter; +import org.oscim.scalebar.MapScaleBar; +import org.oscim.scalebar.MapScaleBarLayer; +import org.oscim.scalebar.MetricUnitAdapter; +import org.oscim.theme.VtmThemes; +import org.oscim.tiling.source.mapfile.MapFileTileSource; + +import java.io.File; + +public class MapsforgeLine_NPOT_Test extends GdxMap { + + private static File mapFile; + + @Override + public void createLayers() { + MapFileTileSource tileSource = new MapFileTileSource(); + tileSource.setMapFile(mapFile.getAbsolutePath()); + tileSource.setPreferredLanguage("en"); + + VectorTileLayer l = mMap.setBaseMap(tileSource); + mMap.setTheme(VtmThemes.DEFAULT); + mMap.layers().add(new TileGridLayer(mMap)); + + DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap); + mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH); + mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE); + mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE); + mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT); + + MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar); + BitmapRenderer renderer = mapScaleBarLayer.getRenderer(); + renderer.setPosition(GLViewport.Position.BOTTOM_LEFT); + renderer.setOffset(5, 0); + mMap.layers().add(mapScaleBarLayer); + + //https://www.google.de/maps/@52.5808431,13.4000501,19.5z + mMap.setMapPosition(52.5808431, 13.4000501, 1 << 21); + } + + private static File getMapFile(String[] args) { + if (args.length == 0) { + throw new IllegalArgumentException("missing argument: "); + } + + File file = new File(args[0]); + if (!file.exists()) { + throw new IllegalArgumentException("file does not exist: " + file); + } else if (!file.isFile()) { + throw new IllegalArgumentException("not a file: " + file); + } else if (!file.canRead()) { + throw new IllegalArgumentException("cannot read file: " + file); + } + return file; + } + + public static void main(String[] args) { + mapFile = getMapFile(args); + + GdxMapApp.init(); + GdxMapApp.run(new MapsforgeLine_NPOT_Test()); + } +} \ No newline at end of file diff --git a/vtm-playground/src/org/oscim/test/MapsforgeLine_POT_Test.java b/vtm-playground/src/org/oscim/test/MapsforgeLine_POT_Test.java new file mode 100644 index 00000000..c24a5c81 --- /dev/null +++ b/vtm-playground/src/org/oscim/test/MapsforgeLine_POT_Test.java @@ -0,0 +1,90 @@ +/* + * Copyright 2017 Longri + * + * 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 org.oscim.gdx.GdxMap; +import org.oscim.gdx.GdxMapApp; +import org.oscim.layers.TileGridLayer; +import org.oscim.layers.tile.vector.VectorTileLayer; +import org.oscim.renderer.BitmapRenderer; +import org.oscim.renderer.GLViewport; +import org.oscim.scalebar.DefaultMapScaleBar; +import org.oscim.scalebar.ImperialUnitAdapter; +import org.oscim.scalebar.MapScaleBar; +import org.oscim.scalebar.MapScaleBarLayer; +import org.oscim.scalebar.MetricUnitAdapter; +import org.oscim.theme.ThemeLoader; +import org.oscim.theme.VtmThemes; +import org.oscim.tiling.source.mapfile.MapFileTileSource; + +import java.io.File; + +public class MapsforgeLine_POT_Test extends GdxMap { + + private static File mapFile; + + @Override + public void createLayers() { + ThemeLoader.POT_TEXTURES = true; + + MapFileTileSource tileSource = new MapFileTileSource(); + tileSource.setMapFile(mapFile.getAbsolutePath()); + tileSource.setPreferredLanguage("en"); + + VectorTileLayer l = mMap.setBaseMap(tileSource); + mMap.setTheme(VtmThemes.DEFAULT); + mMap.layers().add(new TileGridLayer(mMap)); + + DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap); + mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH); + mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE); + mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE); + mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT); + + MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar); + BitmapRenderer renderer = mapScaleBarLayer.getRenderer(); + renderer.setPosition(GLViewport.Position.BOTTOM_LEFT); + renderer.setOffset(5, 0); + mMap.layers().add(mapScaleBarLayer); + + //https://www.google.de/maps/@52.5808431,13.4000501,19.5z + mMap.setMapPosition(52.5808431, 13.4000501, 1 << 21); + } + + private static File getMapFile(String[] args) { + if (args.length == 0) { + throw new IllegalArgumentException("missing argument: "); + } + + File file = new File(args[0]); + if (!file.exists()) { + throw new IllegalArgumentException("file does not exist: " + file); + } else if (!file.isFile()) { + throw new IllegalArgumentException("not a file: " + file); + } else if (!file.canRead()) { + throw new IllegalArgumentException("cannot read file: " + file); + } + return file; + } + + public static void main(String[] args) { + mapFile = getMapFile(args); + + GdxMapApp.init(); + GdxMapApp.run(new MapsforgeLine_POT_Test()); + } +} \ No newline at end of file diff --git a/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java b/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java index 792cac92..654956de 100644 --- a/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java +++ b/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java @@ -90,6 +90,11 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas { } } + @Override + public void drawBitmap(Bitmap bitmap) { + // TODO + } + @Override public void drawBitmap(Bitmap bitmap, float x, float y) { // TODO diff --git a/vtm/src/org/oscim/backend/canvas/Canvas.java b/vtm/src/org/oscim/backend/canvas/Canvas.java index 7eefe492..f0900055 100644 --- a/vtm/src/org/oscim/backend/canvas/Canvas.java +++ b/vtm/src/org/oscim/backend/canvas/Canvas.java @@ -2,6 +2,7 @@ * Copyright 2013 Hannes Janetzek * Copyright 2016-2017 devemux86 * Copyright 2017 nebular + * Copyright 2017 Longri * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * @@ -38,6 +39,11 @@ public interface Canvas { */ void drawText(String string, float x, float y, Paint fill, Paint stroke); + /** + * Draw Bitmap to fill target by stretching. + */ + void drawBitmap(Bitmap bitmap); + /** * Draw Bitmap to Canvas. */ diff --git a/vtm/src/org/oscim/theme/ThemeLoader.java b/vtm/src/org/oscim/theme/ThemeLoader.java index 91974e37..be58129d 100644 --- a/vtm/src/org/oscim/theme/ThemeLoader.java +++ b/vtm/src/org/oscim/theme/ThemeLoader.java @@ -24,6 +24,7 @@ import org.oscim.theme.IRenderTheme.ThemeException; public class ThemeLoader { public static boolean USE_ATLAS; + public static boolean POT_TEXTURES; public static IRenderTheme load(String renderThemePath) throws ThemeException { return load(new ExternalRenderTheme(renderThemePath)); diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java index fa3e2f1b..6e19cd4e 100644 --- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java @@ -23,6 +23,7 @@ package org.oscim.theme; import org.oscim.backend.CanvasAdapter; import org.oscim.backend.XMLReaderAdapter; import org.oscim.backend.canvas.Bitmap; +import org.oscim.backend.canvas.Canvas; import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Paint.Cap; import org.oscim.backend.canvas.Paint.FontFamily; @@ -49,6 +50,7 @@ import org.oscim.theme.styles.SymbolStyle; import org.oscim.theme.styles.SymbolStyle.SymbolBuilder; import org.oscim.theme.styles.TextStyle; import org.oscim.theme.styles.TextStyle.TextBuilder; +import org.oscim.utils.math.MathUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; @@ -559,7 +561,7 @@ public class XmlThemeBuilder extends DefaultHandler { logUnknownAttribute(elementName, name, value, i); } - b.texture = loadTexture(src, b.symbolWidth, b.symbolHeight, b.symbolPercent); + b.texture = loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent); /*if (b.texture != null) b.texture.mipmap = true;*/ @@ -652,19 +654,32 @@ public class XmlThemeBuilder extends DefaultHandler { logUnknownAttribute(elementName, name, value, i); } - b.texture = loadTexture(src, b.symbolWidth, b.symbolHeight, b.symbolPercent); + b.texture = loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent); return b.build(); } - private TextureItem loadTexture(String src, int width, int height, int percent) { + public static TextureItem loadTexture(String relativePathPrefix, String src, int width, int height, int percent) { if (src == null || src.length() == 0) return null; try { - Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src, width, height, percent); + Bitmap bitmap = CanvasAdapter.getBitmapAsset(relativePathPrefix, src, width, height, percent); if (bitmap != null) { log.debug("loading {}", src); + + if (ThemeLoader.POT_TEXTURES) { + int potWidth = MathUtils.nextPowerOfTwo(bitmap.getWidth()); + int potHeight = MathUtils.nextPowerOfTwo(bitmap.getHeight()); + if (potWidth != bitmap.getWidth() || potHeight != bitmap.getHeight()) { + log.debug("POT texture: {}x{} -> {}x{}", bitmap.getWidth(), bitmap.getHeight(), potWidth, potHeight); + Bitmap potBitmap = CanvasAdapter.newBitmap(potWidth, potHeight, 0); + Canvas canvas = CanvasAdapter.newCanvas(); + canvas.setBitmap(potBitmap); + canvas.drawBitmap(bitmap); + bitmap = potBitmap; + } + } return new TextureItem(bitmap, true); } } catch (Exception e) {