SVG resources scaling, closes #214

This commit is contained in:
Emux 2016-12-07 19:58:23 +02:00
parent 6344542b10
commit 4cd11462da
16 changed files with 380 additions and 137 deletions

View File

@ -7,6 +7,7 @@
- Polygon label position enhancements [#80](https://github.com/mapsforge/vtm/issues/80) - Polygon label position enhancements [#80](https://github.com/mapsforge/vtm/issues/80)
- vtm-web modules update [#51](https://github.com/mapsforge/vtm/issues/51) - vtm-web modules update [#51](https://github.com/mapsforge/vtm/issues/51)
- Mapbox vector tiles [#57](https://github.com/mapsforge/vtm/issues/57) - Mapbox vector tiles [#57](https://github.com/mapsforge/vtm/issues/57)
- SVG resources scaling [#214](https://github.com/mapsforge/vtm/issues/214)
- Circle map style [#122](https://github.com/mapsforge/vtm/issues/122) - Circle map style [#122](https://github.com/mapsforge/vtm/issues/122)
- PathLayer (vtm) fix disappearing segments [#108](https://github.com/mapsforge/vtm/issues/108) - PathLayer (vtm) fix disappearing segments [#108](https://github.com/mapsforge/vtm/issues/108)
- House numbers (nodes) fix visibility [#168](https://github.com/mapsforge/vtm/issues/168) - House numbers (nodes) fix visibility [#168](https://github.com/mapsforge/vtm/issues/168)

View File

@ -124,6 +124,9 @@
<xs:attribute name="id" default="0" type="xs:string" use="optional" /> <xs:attribute name="id" default="0" type="xs:string" use="optional" />
<xs:attribute name="use" default="0" type="xs:string" use="optional" /> <xs:attribute name="use" default="0" type="xs:string" use="optional" />
<xs:attribute name="src" type="tns:src" use="optional" /> <xs:attribute name="src" type="tns:src" use="optional" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
<xs:attribute name="fill" default="#000000" type="tns:color" use="optional" /> <xs:attribute name="fill" default="#000000" type="tns:color" use="optional" />
<xs:attribute name="stroke" default="#00000000" type="tns:color" use="optional" /> <xs:attribute name="stroke" default="#00000000" type="tns:color" use="optional" />
<xs:attribute name="stroke-width" default="0" type="tns:nonNegativeFloat" use="optional" /> <xs:attribute name="stroke-width" default="0" type="tns:nonNegativeFloat" use="optional" />
@ -147,8 +150,11 @@
<xs:attribute name="area-size" default="0" type="tns:nonNegativeFloat" use="optional" /> <xs:attribute name="area-size" default="0" type="tns:nonNegativeFloat" use="optional" />
<!-- priority for label placement, 0 = highest priority --> <!-- priority for label placement, 0 = highest priority -->
<xs:attribute name="priority" default="0" type="xs:integer" use="optional" /> <xs:attribute name="priority" default="0" type="xs:integer" use="optional" />
<!-- symbol src name in atlas --> <!-- symbol src name -->
<xs:attribute name="symbol" type="tns:src" use="optional" /> <xs:attribute name="symbol" type="tns:src" use="optional" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
</xs:complexType> </xs:complexType>
<xs:complexType name="circle"> <xs:complexType name="circle">
@ -170,6 +176,9 @@
<xs:attribute name="use" default="0" type="xs:string" use="optional" /> <xs:attribute name="use" default="0" type="xs:string" use="optional" />
<xs:attribute name="src" type="tns:src" use="optional" /> <xs:attribute name="src" type="tns:src" use="optional" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
<xs:attribute name="stroke" default="#000000" type="tns:color" use="optional" /> <xs:attribute name="stroke" default="#000000" type="tns:color" use="optional" />
<xs:attribute name="width" default="0" type="xs:float" use="optional" /> <xs:attribute name="width" default="0" type="xs:float" use="optional" />
<!-- minimum scaled width to draw outline --> <!-- minimum scaled width to draw outline -->
@ -194,6 +203,9 @@
<xs:attribute name="cat" type="xs:string" use="optional" /> <xs:attribute name="cat" type="xs:string" use="optional" />
<xs:attribute name="name" default="0" type="xs:string" use="optional" /> <xs:attribute name="name" default="0" type="xs:string" use="optional" />
<xs:attribute name="src" type="tns:src" use="optional" /> <xs:attribute name="src" type="tns:src" use="optional" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
<xs:attribute name="stroke" default="#000000" type="tns:color" use="optional" /> <xs:attribute name="stroke" default="#000000" type="tns:color" use="optional" />
<xs:attribute name="stroke-width" default="0" type="tns:nonNegativeFloat" use="optional" /> <xs:attribute name="stroke-width" default="0" type="tns:nonNegativeFloat" use="optional" />
</xs:complexType>--> </xs:complexType>-->
@ -201,6 +213,9 @@
<xs:complexType name="lineSymbol"> <xs:complexType name="lineSymbol">
<xs:attribute name="cat" type="xs:string" use="optional" /> <xs:attribute name="cat" type="xs:string" use="optional" />
<xs:attribute name="src" type="tns:src" use="required" /> <xs:attribute name="src" type="tns:src" use="required" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
<xs:attribute name="align-center" default="false" type="xs:boolean" use="optional" /> <xs:attribute name="align-center" default="false" type="xs:boolean" use="optional" />
<xs:attribute name="repeat" default="false" type="xs:boolean" use="optional" /> <xs:attribute name="repeat" default="false" type="xs:boolean" use="optional" />
</xs:complexType> </xs:complexType>
@ -229,6 +244,9 @@
<xs:complexType name="symbol"> <xs:complexType name="symbol">
<xs:attribute name="cat" type="xs:string" use="optional" /> <xs:attribute name="cat" type="xs:string" use="optional" />
<xs:attribute name="src" type="tns:src" use="required" /> <xs:attribute name="src" type="tns:src" use="required" />
<xs:attribute name="symbol-width" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-height" type="xs:positiveInteger" use="optional" />
<xs:attribute name="symbol-percent" type="xs:positiveInteger" use="optional" />
</xs:complexType> </xs:complexType>
<xs:complexType name="extrusion"> <xs:complexType name="extrusion">

View File

@ -56,9 +56,9 @@ public final class AndroidGraphics extends CanvasAdapter {
} }
@Override @Override
public Bitmap decodeSvgBitmapImpl(InputStream inputStream) { public Bitmap decodeSvgBitmapImpl(InputStream inputStream, int width, int height, int percent) {
try { try {
return new AndroidSvgBitmap(inputStream); return new AndroidSvgBitmap(inputStream, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
@ -66,9 +66,9 @@ public final class AndroidGraphics extends CanvasAdapter {
} }
@Override @Override
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) {
try { try {
return createBitmap(relativePathPrefix, src); return createBitmap(relativePathPrefix, src, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -1,5 +1,7 @@
/* /*
* Copyright 2016 devemux86 * Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013-2014 Ludwig M Brinckmann
* Copyright 2014-2016 devemux86
* *
* This program is free software: you can redistribute it and/or modify it under the * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -74,13 +76,13 @@ public class AndroidSvgBitmap extends AndroidBitmap {
} }
} }
private static android.graphics.Bitmap getResourceBitmapImpl(InputStream inputStream) throws IOException { private static android.graphics.Bitmap getResourceBitmapImpl(InputStream inputStream, int width, int height, int percent) throws IOException {
synchronized (SVG.getVersion()) { synchronized (SVG.getVersion()) {
return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, 0, 0, 100); return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, width, height, percent);
} }
} }
public AndroidSvgBitmap(InputStream inputStream) throws IOException { public AndroidSvgBitmap(InputStream inputStream, int width, int height, int percent) throws IOException {
super(getResourceBitmapImpl(inputStream)); super(getResourceBitmapImpl(inputStream, width, height, percent));
} }
} }

View File

@ -103,9 +103,9 @@ public class AwtGraphics extends CanvasAdapter {
} }
@Override @Override
public Bitmap decodeSvgBitmapImpl(InputStream inputStream) { public Bitmap decodeSvgBitmapImpl(InputStream inputStream, int width, int height, int percent) {
try { try {
return new AwtSvgBitmap(inputStream); return new AwtSvgBitmap(inputStream, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
@ -113,9 +113,9 @@ public class AwtGraphics extends CanvasAdapter {
} }
@Override @Override
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) {
try { try {
return createBitmap(relativePathPrefix, src); return createBitmap(relativePathPrefix, src, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016 devemux86 * Copyright 2015-2016 devemux86
* *
* This program is free software: you can redistribute it and/or modify it under the * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -77,13 +77,13 @@ public class AwtSvgBitmap extends AwtBitmap {
} }
} }
private static BufferedImage getResourceBitmapImpl(InputStream inputStream) throws IOException { private static BufferedImage getResourceBitmapImpl(InputStream inputStream, int width, int height, int percent) throws IOException {
synchronized (SVGCache.getSVGUniverse()) { synchronized (SVGCache.getSVGUniverse()) {
return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, 0, 0, 100); return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, width, height, percent);
} }
} }
public AwtSvgBitmap(InputStream inputStream) throws IOException { public AwtSvgBitmap(InputStream inputStream, int width, int height, int percent) throws IOException {
super(getResourceBitmapImpl(inputStream)); super(getResourceBitmapImpl(inputStream, width, height, percent));
} }
} }

View File

@ -30,7 +30,7 @@ import java.io.InputStream;
*/ */
public class IosGraphics extends CanvasAdapter { public class IosGraphics extends CanvasAdapter {
static final Logger log = LoggerFactory.getLogger(IosGraphics.class); private static final Logger log = LoggerFactory.getLogger(IosGraphics.class);
public static void init() { public static void init() {
CanvasAdapter.init(new IosGraphics()); CanvasAdapter.init(new IosGraphics());
@ -62,9 +62,9 @@ public class IosGraphics extends CanvasAdapter {
} }
@Override @Override
protected Bitmap decodeSvgBitmapImpl(InputStream inputStream) { protected Bitmap decodeSvgBitmapImpl(InputStream inputStream, int width, int height, int percent) {
try { try {
return new IosSvgBitmap(inputStream); return new IosSvgBitmap(inputStream, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
log.error("decodeSvgBitmapImpl", e); log.error("decodeSvgBitmapImpl", e);
return null; return null;
@ -72,9 +72,9 @@ public class IosGraphics extends CanvasAdapter {
} }
@Override @Override
protected Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { protected Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) {
try { try {
return createBitmap(relativePathPrefix, src); return createBitmap(relativePathPrefix, src, width, height, percent);
} catch (IOException e) { } catch (IOException e) {
log.error("loadBitmapAssetImpl", e); log.error("loadBitmapAssetImpl", e);
return null; return null;

View File

@ -89,11 +89,11 @@ public class IosSvgBitmap extends IosBitmap {
return renderer.asImageWithSize(new CGSize(bitmapWidth, bitmapHeight), 1); return renderer.asImageWithSize(new CGSize(bitmapWidth, bitmapHeight), 1);
} }
private static UIImage getResourceBitmapImpl(InputStream inputStream) { private static UIImage getResourceBitmapImpl(InputStream inputStream, int width, int height, int percent) {
return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, 0, 0, 100); return getResourceBitmap(inputStream, CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI, DEFAULT_SIZE, width, height, percent);
} }
public IosSvgBitmap(InputStream inputStream) throws IOException { public IosSvgBitmap(InputStream inputStream, int width, int height, int percent) throws IOException {
super(getResourceBitmapImpl(inputStream)); super(getResourceBitmapImpl(inputStream, width, height, percent));
} }
} }

View File

@ -48,19 +48,19 @@ public class GwtGdxGraphics extends CanvasAdapter {
} }
@Override @Override
public Bitmap decodeBitmapImpl(InputStream in) { public Bitmap decodeBitmapImpl(InputStream inputStream) {
// TODO // TODO
return null; return null;
} }
@Override @Override
public Bitmap decodeSvgBitmapImpl(InputStream in) { public Bitmap decodeSvgBitmapImpl(InputStream inputStream, int width, int height, int percent) {
// TODO // TODO
return null; return null;
} }
@Override @Override
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src) { public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) {
String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src; String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src;
return new GwtBitmap(pathName); return new GwtBitmap(pathName);
} }

View File

@ -117,10 +117,10 @@ public abstract class CanvasAdapter {
* @param inputStream the input stream * @param inputStream the input stream
* @return the SVG bitmap * @return the SVG bitmap
*/ */
protected abstract Bitmap decodeSvgBitmapImpl(InputStream inputStream); protected abstract Bitmap decodeSvgBitmapImpl(InputStream inputStream, int width, int height, int percent);
public static Bitmap decodeSvgBitmap(InputStream inputStream) { public static Bitmap decodeSvgBitmap(InputStream inputStream, int width, int height, int percent) {
return g.decodeSvgBitmapImpl(inputStream); return g.decodeSvgBitmapImpl(inputStream, width, height, percent);
} }
/** /**
@ -130,13 +130,17 @@ public abstract class CanvasAdapter {
* @param src the resource * @param src the resource
* @return the bitmap * @return the bitmap
*/ */
protected abstract Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src); protected abstract Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent);
public static Bitmap getBitmapAsset(String relativePathPrefix, String src) { public static Bitmap getBitmapAsset(String relativePathPrefix, String src) {
return g.loadBitmapAssetImpl(relativePathPrefix, src); return getBitmapAsset(relativePathPrefix, src, 0, 0, 100);
} }
protected static Bitmap createBitmap(String relativePathPrefix, String src) throws IOException { public static Bitmap getBitmapAsset(String relativePathPrefix, String src, int width, int height, int percent) {
return g.loadBitmapAssetImpl(relativePathPrefix, src, width, height, percent);
}
protected static Bitmap createBitmap(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
if (src == null || src.length() == 0) { if (src == null || src.length() == 0) {
// no image source defined // no image source defined
return null; return null;
@ -163,7 +167,7 @@ public abstract class CanvasAdapter {
Bitmap bitmap; Bitmap bitmap;
if (src.toLowerCase(Locale.ENGLISH).endsWith(".svg")) if (src.toLowerCase(Locale.ENGLISH).endsWith(".svg"))
bitmap = decodeSvgBitmap(inputStream); bitmap = decodeSvgBitmap(inputStream, width, height, percent);
else else
bitmap = decodeBitmap(inputStream); bitmap = decodeBitmap(inputStream);
inputStream.close(); inputStream.close();

View File

@ -39,11 +39,13 @@ import org.oscim.theme.rule.RuleBuilder;
import org.oscim.theme.styles.AreaStyle; import org.oscim.theme.styles.AreaStyle;
import org.oscim.theme.styles.AreaStyle.AreaBuilder; import org.oscim.theme.styles.AreaStyle.AreaBuilder;
import org.oscim.theme.styles.CircleStyle; import org.oscim.theme.styles.CircleStyle;
import org.oscim.theme.styles.CircleStyle.CircleBuilder;
import org.oscim.theme.styles.ExtrusionStyle; import org.oscim.theme.styles.ExtrusionStyle;
import org.oscim.theme.styles.LineStyle; import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.LineStyle.LineBuilder; import org.oscim.theme.styles.LineStyle.LineBuilder;
import org.oscim.theme.styles.RenderStyle; import org.oscim.theme.styles.RenderStyle;
import org.oscim.theme.styles.SymbolStyle; 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;
import org.oscim.theme.styles.TextStyle.TextBuilder; import org.oscim.theme.styles.TextStyle.TextBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -120,9 +122,11 @@ public class XmlThemeBuilder extends DefaultHandler {
private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10); private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
private final TextBuilder<?> mTextBuilder = TextStyle.builder();
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder(); private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
private final LineBuilder<?> mLineBuilder = LineStyle.builder(); private final LineBuilder<?> mLineBuilder = LineStyle.builder();
private final SymbolBuilder<?> mSymbolBuilder = SymbolStyle.builder();
private final TextBuilder<?> mTextBuilder = TextStyle.builder();
private RuleBuilder mCurrentRule; private RuleBuilder mCurrentRule;
private TextureAtlas mTextureAtlas; private TextureAtlas mTextureAtlas;
@ -455,6 +459,7 @@ public class XmlThemeBuilder extends DefaultHandler {
LineBuilder<?> b = mLineBuilder.set(line); LineBuilder<?> b = mLineBuilder.set(line);
b.isOutline(isOutline); b.isOutline(isOutline);
b.level(level); b.level(level);
String src = null;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
@ -466,11 +471,10 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("cat".equals(name)) else if ("cat".equals(name))
b.cat(value); b.cat(value);
else if ("src".equals(name)) { else if ("src".equals(name))
b.texture = loadTexture(value); src = value;
/*if (b.texture != null)
b.texture.mipmap = true;*/ else if ("use".equals(name))
} else if ("use".equals(name))
;// ignore ;// ignore
else if ("outline".equals(name)) else if ("outline".equals(name))
@ -520,10 +524,23 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("dasharray".equals(name)) else if ("dasharray".equals(name))
; // TBD ; // TBD
else if ("symbol-width".equals(name))
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-height".equals(name))
b.symbolHeight = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
b.texture = loadTexture(src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
/*if (b.texture != null)
b.texture.mipmap = true;*/
return b.build(); return b.build();
} }
@ -558,6 +575,7 @@ public class XmlThemeBuilder extends DefaultHandler {
int level) { int level) {
AreaBuilder<?> b = mAreaBuilder.set(area); AreaBuilder<?> b = mAreaBuilder.set(area);
b.level(level); b.level(level);
String src = null;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
@ -573,7 +591,7 @@ public class XmlThemeBuilder extends DefaultHandler {
;// ignore ;// ignore
else if ("src".equals(name)) else if ("src".equals(name))
b.texture = loadTexture(value); src = value;
else if ("fill".equals(name)) else if ("fill".equals(name))
b.color(value); b.color(value);
@ -598,19 +616,30 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("mesh".equals(name)) else if ("mesh".equals(name))
b.mesh(Boolean.parseBoolean(value)); b.mesh(Boolean.parseBoolean(value));
else if ("symbol-width".equals(name))
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-height".equals(name))
b.symbolHeight = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
b.texture = loadTexture(src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
return b.build(); return b.build();
} }
private TextureItem loadTexture(String src) { private TextureItem loadTexture(String src, int width, int height, int percent) {
if (src == null) if (src == null || src.length() == 0)
return null; return null;
try { try {
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src); Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src, width, height, percent);
if (bitmap != null) { if (bitmap != null) {
log.debug("loading {}", src); log.debug("loading {}", src);
return new TextureItem(bitmap, true); return new TextureItem(bitmap, true);
@ -827,6 +856,7 @@ public class XmlThemeBuilder extends DefaultHandler {
b.caption = caption; b.caption = caption;
} else } else
b = mTextBuilder.from(style); b = mTextBuilder.from(style);
String symbol = null;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
@ -872,18 +902,21 @@ public class XmlThemeBuilder extends DefaultHandler {
// NB: minus.. // NB: minus..
b.dy = -Float.parseFloat(value) * mScale; b.dy = -Float.parseFloat(value) * mScale;
else if ("symbol".equals(name)) { else if ("symbol".equals(name))
String lowValue = value.toLowerCase(Locale.ENGLISH); symbol = value;
if (lowValue.endsWith(".png") || lowValue.endsWith(".svg")) {
try { else if ("use".equals(name))
b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), value);
} catch (Exception e) {
log.debug(e.getMessage());
}
} else
b.texture = getAtlasRegion(value);
} else if ("use".equals(name))
;/* ignore */ ;/* ignore */
else if ("symbol-width".equals(name))
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-height".equals(name))
b.symbolHeight = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
@ -892,6 +925,18 @@ public class XmlThemeBuilder extends DefaultHandler {
validateNonNegative("size", b.fontSize); validateNonNegative("size", b.fontSize);
validateNonNegative("stroke-width", b.strokeWidth); validateNonNegative("stroke-width", b.strokeWidth);
if (symbol != null && symbol.length() > 0) {
String lowValue = symbol.toLowerCase(Locale.ENGLISH);
if (lowValue.endsWith(".png") || lowValue.endsWith(".svg")) {
try {
b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), symbol, b.symbolWidth, b.symbolHeight, b.symbolPercent);
} catch (Exception e) {
log.debug(e.getMessage());
}
} else
b.texture = getAtlasRegion(symbol);
}
return b; return b;
} }
@ -900,52 +945,47 @@ public class XmlThemeBuilder extends DefaultHandler {
* @return a new Circle with the given rendering attributes. * @return a new Circle with the given rendering attributes.
*/ */
private CircleStyle createCircle(String elementName, Attributes attributes, int level) { private CircleStyle createCircle(String elementName, Attributes attributes, int level) {
String cat = null; CircleBuilder<?> b = mCircleBuilder.reset();
float radius = 0; b.level(level);
boolean scaleRadius = false;
int fill = Color.TRANSPARENT;
int stroke = Color.TRANSPARENT;
float strokeWidth = 0;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
String value = attributes.getValue(i); String value = attributes.getValue(i);
if ("r".equals(name) || "radius".equals(name)) if ("r".equals(name) || "radius".equals(name))
radius = Float.parseFloat(value) * mScale2; b.radius(Float.parseFloat(value) * mScale2);
else if ("cat".equals(name)) else if ("cat".equals(name))
cat = value; b.cat(value);
else if ("scale-radius".equals(name)) else if ("scale-radius".equals(name))
scaleRadius = Boolean.parseBoolean(value); b.scaleRadius(Boolean.parseBoolean(value));
else if ("fill".equals(name)) else if ("fill".equals(name))
fill = Color.parseColor(value); b.color(Color.parseColor(value));
else if ("stroke".equals(name)) else if ("stroke".equals(name))
stroke = Color.parseColor(value); b.strokeColor(Color.parseColor(value));
else if ("stroke-width".equals(name)) else if ("stroke-width".equals(name))
strokeWidth = Float.parseFloat(value) * mScale2; b.strokeWidth(Float.parseFloat(value) * mScale2);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateExists("radius", radius, elementName); validateExists("radius", b.radius, elementName);
validateNonNegative("radius", radius); validateNonNegative("radius", b.radius);
validateNonNegative("stroke-width", strokeWidth); validateNonNegative("stroke-width", b.strokeWidth);
return new CircleStyle(radius, scaleRadius, fill, stroke, strokeWidth, level) return b.build();
.setCat(cat);
} }
/** /**
* @return a new Symbol with the given rendering attributes. * @return a new Symbol with the given rendering attributes.
*/ */
private SymbolStyle createSymbol(String elementName, Attributes attributes) { private SymbolStyle createSymbol(String elementName, Attributes attributes) {
String cat = null; SymbolBuilder<?> b = mSymbolBuilder.reset();
String src = null; String src = null;
for (int i = 0; i < attributes.getLength(); i++) { for (int i = 0; i < attributes.getLength(); i++) {
@ -956,7 +996,16 @@ public class XmlThemeBuilder extends DefaultHandler {
src = value; src = value;
else if ("cat".equals(name)) else if ("cat".equals(name))
cat = value; b.cat(value);
else if ("symbol-width".equals(name))
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-height".equals(name))
b.symbolHeight = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
@ -967,17 +1016,15 @@ public class XmlThemeBuilder extends DefaultHandler {
String lowSrc = src.toLowerCase(Locale.ENGLISH); String lowSrc = src.toLowerCase(Locale.ENGLISH);
if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) { if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) {
try { try {
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src); Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
if (bitmap != null) if (bitmap != null)
return new SymbolStyle(bitmap) return b.bitmap(bitmap).build();
.setCat(cat);
} catch (Exception e) { } catch (Exception e) {
log.debug(e.getMessage()); log.debug(e.getMessage());
} }
return null; return null;
} }
return new SymbolStyle(getAtlasRegion(src)) return b.texture(getAtlasRegion(src)).build();
.setCat(cat);
} }
private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) { private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) {

View File

@ -1,4 +1,5 @@
/* /*
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2014 Hannes Janetzek * Copyright 2014 Hannes Janetzek
* Copyright 2016 devemux86 * Copyright 2016 devemux86
* *
@ -77,6 +78,10 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
*/ */
public final boolean mesh; public final boolean mesh;
public final int symbolWidth;
public final int symbolHeight;
public final int symbolPercent;
public AreaStyle(int color) { public AreaStyle(int color) {
this(0, color); this(0, color);
} }
@ -92,6 +97,10 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
this.strokeColor = color; this.strokeColor = color;
this.strokeWidth = 1; this.strokeWidth = 1;
this.mesh = false; this.mesh = false;
this.symbolWidth = 0;
this.symbolHeight = 0;
this.symbolPercent = 100;
} }
public AreaStyle(AreaBuilder<?> b) { public AreaStyle(AreaBuilder<?> b) {
@ -105,6 +114,10 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
this.strokeColor = b.strokeColor; this.strokeColor = b.strokeColor;
this.strokeWidth = b.strokeWidth; this.strokeWidth = b.strokeWidth;
this.mesh = b.mesh; this.mesh = b.mesh;
this.symbolWidth = b.symbolWidth;
this.symbolHeight = b.symbolHeight;
this.symbolPercent = b.symbolPercent;
} }
@Override @Override
@ -163,6 +176,10 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
public TextureItem texture; public TextureItem texture;
public int symbolWidth;
public int symbolHeight;
public int symbolPercent;
public AreaBuilder() { public AreaBuilder() {
} }
@ -181,6 +198,10 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
this.strokeWidth = area.strokeWidth; this.strokeWidth = area.strokeWidth;
this.mesh = area.mesh; this.mesh = area.mesh;
this.symbolWidth = area.symbolWidth;
this.symbolHeight = area.symbolHeight;
this.symbolPercent = area.symbolPercent;
return self(); return self();
} }
@ -214,6 +235,21 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
return self(); return self();
} }
public T symbolWidth(int symbolWidth) {
this.symbolWidth = symbolWidth;
return self();
}
public T symbolHeight(int symbolHeight) {
this.symbolHeight = symbolHeight;
return self();
}
public T symbolPercent(int symbolPercent) {
this.symbolPercent = symbolPercent;
return self();
}
public T reset() { public T reset() {
fillColor = Color.WHITE; fillColor = Color.WHITE;
strokeColor = Color.BLACK; strokeColor = Color.BLACK;
@ -224,6 +260,11 @@ public class AreaStyle extends RenderStyle<AreaStyle> {
style = null; style = null;
texture = null; texture = null;
mesh = false; mesh = false;
symbolWidth = 0;
symbolHeight = 0;
symbolPercent = 100;
return self(); return self();
} }

View File

@ -26,7 +26,7 @@ import org.oscim.backend.canvas.Color;
public final class CircleStyle extends RenderStyle<CircleStyle> { public final class CircleStyle extends RenderStyle<CircleStyle> {
public final int fillColor; public final int fillColor;
public final int level; private final int level;
public final float radius; public final float radius;
public final boolean scaleRadius; public final boolean scaleRadius;
public final int strokeColor; public final int strokeColor;

View File

@ -26,7 +26,7 @@ import static org.oscim.backend.canvas.Color.parseColor;
public final class LineStyle extends RenderStyle<LineStyle> { public final class LineStyle extends RenderStyle<LineStyle> {
final int level; private final int level;
public final String style; public final String style;
public final float width; public final float width;
public final int color; public final int color;
@ -43,21 +43,20 @@ public final class LineStyle extends RenderStyle<LineStyle> {
public final boolean randomOffset; public final boolean randomOffset;
private LineStyle(LineBuilder<?> builder) { public final int symbolWidth;
this.level = builder.level; public final int symbolHeight;
this.style = builder.style; public final int symbolPercent;
this.width = builder.strokeWidth;
this.color = builder.fillColor; public LineStyle(int stroke, float width) {
this.cap = builder.cap; this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
this.outline = builder.outline; }
this.fixed = builder.fixed;
this.fadeScale = builder.fadeScale; public LineStyle(int level, int stroke, float width) {
this.blur = builder.blur; this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
this.stipple = builder.stipple; }
this.stippleColor = builder.stippleColor;
this.stippleWidth = builder.stippleWidth; public LineStyle(int stroke, float width, Cap cap) {
this.texture = builder.texture; this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true);
this.randomOffset = builder.randomOffset;
} }
public LineStyle(int level, String style, int color, float width, public LineStyle(int level, String style, int color, float width,
@ -84,23 +83,31 @@ public final class LineStyle extends RenderStyle<LineStyle> {
this.fadeScale = fadeScale; this.fadeScale = fadeScale;
this.randomOffset = randomOffset; this.randomOffset = randomOffset;
this.symbolWidth = 0;
this.symbolHeight = 0;
this.symbolPercent = 100;
} }
public LineStyle(int stroke, float width) { private LineStyle(LineBuilder<?> b) {
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true); this.level = b.level;
} this.style = b.style;
this.width = b.strokeWidth;
this.color = b.fillColor;
this.cap = b.cap;
this.outline = b.outline;
this.fixed = b.fixed;
this.fadeScale = b.fadeScale;
this.blur = b.blur;
this.stipple = b.stipple;
this.stippleColor = b.stippleColor;
this.stippleWidth = b.stippleWidth;
this.texture = b.texture;
this.randomOffset = b.randomOffset;
public LineStyle(int level, int stroke, float width) { this.symbolWidth = b.symbolWidth;
this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true); this.symbolHeight = b.symbolHeight;
} this.symbolPercent = b.symbolPercent;
public LineStyle(int stroke, float width, Cap cap) {
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true);
}
@Override
public void renderWay(Callback cb) {
cb.renderWay(this, level);
} }
@Override @Override
@ -108,6 +115,11 @@ public final class LineStyle extends RenderStyle<LineStyle> {
return (LineStyle) mCurrent; return (LineStyle) mCurrent;
} }
@Override
public void renderWay(Callback cb) {
cb.renderWay(this, level);
}
public static class LineBuilder<T extends LineBuilder<T>> extends StyleBuilder<T> { public static class LineBuilder<T extends LineBuilder<T>> extends StyleBuilder<T> {
public Cap cap; public Cap cap;
@ -123,9 +135,17 @@ public final class LineStyle extends RenderStyle<LineStyle> {
public boolean randomOffset; public boolean randomOffset;
public int symbolWidth;
public int symbolHeight;
public int symbolPercent;
public LineBuilder() {
}
public T set(LineStyle line) { public T set(LineStyle line) {
if (line == null) if (line == null)
return reset(); return reset();
this.level = line.level; this.level = line.level;
this.style = line.style; this.style = line.style;
this.strokeWidth = line.width; this.strokeWidth = line.width;
@ -140,26 +160,10 @@ public final class LineStyle extends RenderStyle<LineStyle> {
this.stippleWidth = line.stippleWidth; this.stippleWidth = line.stippleWidth;
this.texture = line.texture; this.texture = line.texture;
this.randomOffset = line.randomOffset; this.randomOffset = line.randomOffset;
return self();
}
public T reset() { this.symbolWidth = line.symbolWidth;
level = -1; this.symbolHeight = line.symbolHeight;
style = null; this.symbolPercent = line.symbolPercent;
fillColor = Color.BLACK;
cap = Cap.ROUND;
strokeWidth = 1;
fixed = false;
fadeScale = -1;
blur = 0;
stipple = 0;
stippleWidth = 1;
stippleColor = Color.BLACK;
texture = null;
randomOffset = true;
return self(); return self();
} }
@ -199,10 +203,6 @@ public final class LineStyle extends RenderStyle<LineStyle> {
return self(); return self();
} }
public LineStyle build() {
return new LineStyle(this);
}
public T cap(Cap cap) { public T cap(Cap cap) {
this.cap = cap; this.cap = cap;
return self(); return self();
@ -222,6 +222,50 @@ public final class LineStyle extends RenderStyle<LineStyle> {
this.randomOffset = randomOffset; this.randomOffset = randomOffset;
return self(); return self();
} }
public T symbolWidth(int symbolWidth) {
this.symbolWidth = symbolWidth;
return self();
}
public T symbolHeight(int symbolHeight) {
this.symbolHeight = symbolHeight;
return self();
}
public T symbolPercent(int symbolPercent) {
this.symbolPercent = symbolPercent;
return self();
}
public T reset() {
level = -1;
style = null;
fillColor = Color.BLACK;
cap = Cap.ROUND;
strokeWidth = 1;
fixed = false;
fadeScale = -1;
blur = 0;
stipple = 0;
stippleWidth = 1;
stippleColor = Color.BLACK;
texture = null;
randomOffset = true;
symbolWidth = 0;
symbolHeight = 0;
symbolPercent = 100;
return self();
}
public LineStyle build() {
return new LineStyle(this);
}
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")

View File

@ -29,19 +29,35 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
public final Bitmap bitmap; public final Bitmap bitmap;
public final TextureRegion texture; public final TextureRegion texture;
public final int symbolWidth;
public final int symbolHeight;
public final int symbolPercent;
public SymbolStyle(Bitmap bitmap) { public SymbolStyle(Bitmap bitmap) {
this.bitmap = bitmap; this.bitmap = bitmap;
this.texture = null; this.texture = null;
this.symbolWidth = 0;
this.symbolHeight = 0;
this.symbolPercent = 100;
} }
public SymbolStyle(TextureRegion texture) { public SymbolStyle(TextureRegion texture) {
this.bitmap = null; this.bitmap = null;
this.texture = texture; this.texture = texture;
this.symbolWidth = 0;
this.symbolHeight = 0;
this.symbolPercent = 100;
} }
public SymbolStyle(SymbolBuilder<?> b) { public SymbolStyle(SymbolBuilder<?> b) {
this.bitmap = b.bitmap; this.bitmap = b.bitmap;
this.texture = b.texture; this.texture = b.texture;
this.symbolWidth = b.symbolWidth;
this.symbolHeight = b.symbolHeight;
this.symbolPercent = b.symbolPercent;
} }
@Override @Override
@ -70,6 +86,10 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
public Bitmap bitmap; public Bitmap bitmap;
public TextureRegion texture; public TextureRegion texture;
public int symbolWidth;
public int symbolHeight;
public int symbolPercent;
public SymbolBuilder() { public SymbolBuilder() {
} }
@ -80,6 +100,10 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
this.bitmap = symbol.bitmap; this.bitmap = symbol.bitmap;
this.texture = symbol.texture; this.texture = symbol.texture;
this.symbolWidth = symbol.symbolWidth;
this.symbolHeight = symbol.symbolHeight;
this.symbolPercent = symbol.symbolPercent;
return self(); return self();
} }
@ -93,9 +117,29 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
return self(); return self();
} }
public T symbolWidth(int symbolWidth) {
this.symbolWidth = symbolWidth;
return self();
}
public T symbolHeight(int symbolHeight) {
this.symbolHeight = symbolHeight;
return self();
}
public T symbolPercent(int symbolPercent) {
this.symbolPercent = symbolPercent;
return self();
}
public T reset() { public T reset() {
bitmap = null; bitmap = null;
texture = null; texture = null;
symbolWidth = 0;
symbolHeight = 0;
symbolPercent = 100;
return self(); return self();
} }

View File

@ -43,6 +43,10 @@ public final class TextStyle extends RenderStyle<TextStyle> {
public FontFamily fontFamily; public FontFamily fontFamily;
public FontStyle fontStyle; public FontStyle fontStyle;
public int symbolWidth;
public int symbolHeight;
public int symbolPercent;
public T reset() { public T reset() {
fontFamily = FontFamily.DEFAULT; fontFamily = FontFamily.DEFAULT;
fontStyle = FontStyle.NORMAL; fontStyle = FontStyle.NORMAL;
@ -58,6 +62,11 @@ public final class TextStyle extends RenderStyle<TextStyle> {
strokeColor = Color.BLACK; strokeColor = Color.BLACK;
strokeWidth = 0; strokeWidth = 0;
dy = 0; dy = 0;
symbolWidth = 0;
symbolHeight = 0;
symbolPercent = 100;
return self(); return self();
} }
@ -126,6 +135,21 @@ public final class TextStyle extends RenderStyle<TextStyle> {
return self(); return self();
} }
public T symbolWidth(int symbolWidth) {
this.symbolWidth = symbolWidth;
return self();
}
public T symbolHeight(int symbolHeight) {
this.symbolHeight = symbolHeight;
return self();
}
public T symbolPercent(int symbolPercent) {
this.symbolPercent = symbolPercent;
return self();
}
public T from(TextBuilder<?> other) { public T from(TextBuilder<?> other) {
fontFamily = other.fontFamily; fontFamily = other.fontFamily;
fontStyle = other.fontStyle; fontStyle = other.fontStyle;
@ -141,6 +165,11 @@ public final class TextStyle extends RenderStyle<TextStyle> {
strokeColor = other.strokeColor; strokeColor = other.strokeColor;
strokeWidth = other.strokeWidth; strokeWidth = other.strokeWidth;
dy = other.dy; dy = other.dy;
symbolWidth = other.symbolWidth;
symbolHeight = other.symbolHeight;
symbolPercent = other.symbolPercent;
return self(); return self();
} }
@ -159,6 +188,11 @@ public final class TextStyle extends RenderStyle<TextStyle> {
this.strokeColor = style.stroke.getColor(); this.strokeColor = style.stroke.getColor();
this.strokeWidth = 2; this.strokeWidth = 2;
this.fontSize = style.fontSize; this.fontSize = style.fontSize;
this.symbolWidth = style.symbolWidth;
this.symbolHeight = style.symbolHeight;
this.symbolPercent = style.symbolPercent;
return self(); return self();
} }
} }
@ -192,6 +226,10 @@ public final class TextStyle extends RenderStyle<TextStyle> {
stroke = null; stroke = null;
this.fontSize = tb.fontSize; this.fontSize = tb.fontSize;
this.symbolWidth = tb.symbolWidth;
this.symbolHeight = tb.symbolHeight;
this.symbolPercent = tb.symbolPercent;
} }
public final String style; public final String style;
@ -212,6 +250,10 @@ public final class TextStyle extends RenderStyle<TextStyle> {
public final Bitmap bitmap; public final Bitmap bitmap;
public final TextureRegion texture; public final TextureRegion texture;
public final int symbolWidth;
public final int symbolHeight;
public final int symbolPercent;
@Override @Override
public void dispose() { public void dispose() {
if (bitmap != null) if (bitmap != null)