parent
b695d43fee
commit
f4f8eb8d1c
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## New since 0.8.0
|
## New since 0.8.0
|
||||||
|
|
||||||
|
- Mapsforge themes compatibility [#100](https://github.com/mapsforge/vtm/issues/100)
|
||||||
- vtm-theme-comparator module [#387](https://github.com/mapsforge/vtm/issues/387)
|
- vtm-theme-comparator module [#387](https://github.com/mapsforge/vtm/issues/387)
|
||||||
- Many other minor improvements and bug fixes
|
- Many other minor improvements and bug fixes
|
||||||
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.9.0)
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.9.0)
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
android:id="@+id/theme_newtron"
|
android:id="@+id/theme_newtron"
|
||||||
android:title="@string/theme_newtron" />
|
android:title="@string/theme_newtron" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/theme_load"
|
android:id="@+id/theme_external"
|
||||||
android:title="@string/theme_load" />
|
android:title="@string/theme_external" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<string name="theme_osmagray">Osmagray</string>
|
<string name="theme_osmagray">Osmagray</string>
|
||||||
<string name="theme_tubes">Tubes</string>
|
<string name="theme_tubes">Tubes</string>
|
||||||
<string name="theme_newtron">NewTron</string>
|
<string name="theme_newtron">NewTron</string>
|
||||||
|
<string name="theme_external">External theme</string>
|
||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="error">Error</string>
|
<string name="error">Error</string>
|
||||||
@ -17,6 +18,5 @@
|
|||||||
<string name="style_1">Show nature</string>
|
<string name="style_1">Show nature</string>
|
||||||
<string name="style_2">Hide nature</string>
|
<string name="style_2">Hide nature</string>
|
||||||
<string name="menu_gridlayer">Grid</string>
|
<string name="menu_gridlayer">Grid</string>
|
||||||
<string name="theme_load">load theme extern</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -43,11 +43,10 @@ public final class ValidRenderTheme implements ValidFileFilter {
|
|||||||
try {
|
try {
|
||||||
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
||||||
DefaultHandler renderThemeHandler;
|
DefaultHandler renderThemeHandler;
|
||||||
if(ThemeUtils.isMapsforgeTheme(new FileInputStream(file))) {
|
if (ThemeUtils.isMapsforgeTheme(new FileInputStream(file)))
|
||||||
renderThemeHandler = new XmlMapsforgeThemeBuilder(theme);
|
renderThemeHandler = new XmlMapsforgeThemeBuilder(theme);
|
||||||
}else{
|
else
|
||||||
renderThemeHandler = new XmlThemeBuilder(theme);
|
renderThemeHandler = new XmlThemeBuilder(theme);
|
||||||
}
|
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
xmlReader.setContentHandler(renderThemeHandler);
|
||||||
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
||||||
|
@ -51,6 +51,7 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
|
|
||||||
private TileGridLayer mGridLayer;
|
private TileGridLayer mGridLayer;
|
||||||
private DefaultMapScaleBar mMapScaleBar;
|
private DefaultMapScaleBar mMapScaleBar;
|
||||||
|
private Menu mMenu;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -85,6 +86,7 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.theme_menu, menu);
|
getMenuInflater().inflate(R.menu.theme_menu, menu);
|
||||||
|
mMenu = menu;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +119,8 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_load:
|
case R.id.theme_external:
|
||||||
startActivityForResult(new Intent(MapsforgeMapActivity.this, ThemeFilePicker.class),
|
startActivityForResult(new Intent(this, ThemeFilePicker.class),
|
||||||
SELECT_THEME_FILE);
|
SELECT_THEME_FILE);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -181,18 +183,13 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
}
|
}
|
||||||
} else if (requestCode == SELECT_THEME_FILE) {
|
} else if (requestCode == SELECT_THEME_FILE) {
|
||||||
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
||||||
finish();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String themePath = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
||||||
|
ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(file);
|
||||||
ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(themePath);
|
mMap.setTheme(externalRenderTheme);
|
||||||
try {
|
mMenu.findItem(R.id.theme_external).setChecked(true);
|
||||||
mMap.setTheme(externalRenderTheme, true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,14 @@ public class AndroidCanvas implements Canvas {
|
|||||||
canvas.drawColor(color, color == Color.TRANSPARENT ? PorterDuff.Mode.CLEAR : PorterDuff.Mode.SRC_OVER);
|
canvas.drawColor(color, color == Color.TRANSPARENT ? PorterDuff.Mode.CLEAR : PorterDuff.Mode.SRC_OVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillRectangle(float x, float y, float width, float height, int color) {
|
||||||
|
RectF rect = new RectF(x, y, x + width, y + height);
|
||||||
|
android.graphics.Paint paint = new android.graphics.Paint();
|
||||||
|
paint.setColor(color);
|
||||||
|
canvas.drawRect(rect, paint);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return canvas.getHeight();
|
return canvas.getHeight();
|
||||||
@ -97,12 +105,4 @@ public class AndroidCanvas implements Canvas {
|
|||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return canvas.getWidth();
|
return canvas.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fillRectangle(int x, int y, int width, int height, int color) {
|
|
||||||
RectF rec = new RectF(x, y, x + width, y + height);
|
|
||||||
android.graphics.Paint paint = new android.graphics.Paint();
|
|
||||||
paint.setColor(color);
|
|
||||||
canvas.drawRect(rec, paint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,16 @@ public class AwtCanvas implements Canvas {
|
|||||||
fillRectangle(0, 0, getWidth(), getHeight(), color);
|
fillRectangle(0, 0, getWidth(), getHeight(), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillRectangle(float x, float y, float width, float height, int color) {
|
||||||
|
java.awt.Color awtColor = color == Color.TRANSPARENT ? TRANSPARENT : new java.awt.Color(color);
|
||||||
|
Composite originalComposite = this.canvas.getComposite();
|
||||||
|
this.canvas.setComposite(AlphaComposite.getInstance(color == Color.TRANSPARENT ? AlphaComposite.CLEAR : AlphaComposite.SRC_OVER));
|
||||||
|
this.canvas.setColor(awtColor);
|
||||||
|
this.canvas.fillRect((int) x, (int) y, (int) width, (int) height);
|
||||||
|
this.canvas.setComposite(originalComposite);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return this.bitmap != null ? this.bitmap.getHeight() : 0;
|
return this.bitmap != null ? this.bitmap.getHeight() : 0;
|
||||||
@ -195,14 +205,4 @@ public class AwtCanvas implements Canvas {
|
|||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return this.bitmap != null ? this.bitmap.getWidth() : 0;
|
return this.bitmap != null ? this.bitmap.getWidth() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fillRectangle(int x, int y, int width, int height, int color) {
|
|
||||||
java.awt.Color awtColor = color == Color.TRANSPARENT ? TRANSPARENT : new java.awt.Color(color);
|
|
||||||
Composite originalComposite = this.canvas.getComposite();
|
|
||||||
this.canvas.setComposite(AlphaComposite.getInstance(color == Color.TRANSPARENT ? AlphaComposite.CLEAR : AlphaComposite.SRC_OVER));
|
|
||||||
this.canvas.setColor(awtColor);
|
|
||||||
this.canvas.fillRect(x, y, width, height);
|
|
||||||
this.canvas.setComposite(originalComposite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,14 @@ public class IosCanvas implements Canvas {
|
|||||||
this.cgBitmapContext.fillRect(rect);
|
this.cgBitmapContext.fillRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillRectangle(float x, float y, float width, float height, int color) {
|
||||||
|
CGRect rect = new CGRect(x, y, width, height);
|
||||||
|
setFillColor(this.cgBitmapContext, (color));
|
||||||
|
this.cgBitmapContext.setBlendMode(CGBlendMode.Normal);
|
||||||
|
this.cgBitmapContext.fillRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getHeight() : 0;
|
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getHeight() : 0;
|
||||||
@ -159,12 +167,4 @@ public class IosCanvas implements Canvas {
|
|||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getWidth() : 0;
|
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getWidth() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fillRectangle(int x, int y, int width, int height, int color) {
|
|
||||||
CGRect rect = new CGRect(x, y, width, height);
|
|
||||||
setFillColor(this.cgBitmapContext, (color));
|
|
||||||
this.cgBitmapContext.setBlendMode(CGBlendMode.Normal);
|
|
||||||
this.cgBitmapContext.fillRect(rect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -72,9 +72,9 @@ public class LineRenderTest extends GdxMap {
|
|||||||
line2 = new LineStyle(Color.GREEN, 1);
|
line2 = new LineStyle(Color.GREEN, 1);
|
||||||
line4 = new LineStyle(Color.LTGRAY, 3);
|
line4 = new LineStyle(Color.LTGRAY, 3);
|
||||||
} else {
|
} else {
|
||||||
line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true);
|
line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true, null);
|
||||||
line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true);
|
line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true, null);
|
||||||
line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, false, null, true);
|
line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, false, null, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureItem tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/dot.png"));
|
TextureItem tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/dot.png"));
|
||||||
@ -90,8 +90,8 @@ public class LineRenderTest extends GdxMap {
|
|||||||
.randomOffset(true)
|
.randomOffset(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, true, null, true);
|
LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, true, null, true, null);
|
||||||
LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 0, true, null, true);
|
LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 0, true, null, true, null);
|
||||||
|
|
||||||
LineBucket ol = l.buckets.addLineBucket(0, outline);
|
LineBucket ol = l.buckets.addLineBucket(0, outline);
|
||||||
LineBucket ol2 = l.buckets.addLineBucket(5, outline2);
|
LineBucket ol2 = l.buckets.addLineBucket(5, outline2);
|
||||||
|
@ -116,6 +116,11 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillRectangle(float x, float y, float width, float height, int color) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return this.bitmap != null ? this.bitmap.getHeight() : 0;
|
return this.bitmap != null ? this.bitmap.getHeight() : 0;
|
||||||
@ -125,9 +130,4 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas {
|
|||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return this.bitmap != null ? this.bitmap.getWidth() : 0;
|
return this.bitmap != null ? this.bitmap.getWidth() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fillRectangle(int x, int y, int width, int height, int color) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
* Copyright 2017 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class with theme specific helper methods.
|
||||||
|
*/
|
||||||
|
public final class ThemeUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given InputStream is a Mapsforge render theme.
|
||||||
|
*/
|
||||||
|
public static boolean isMapsforgeTheme(InputStream is) {
|
||||||
|
// TODO
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThemeUtils() {
|
||||||
|
}
|
||||||
|
}
|
@ -44,10 +44,9 @@ uniform float u_mode;
|
|||||||
void
|
void
|
||||||
main(){
|
main(){
|
||||||
if (u_mode >= 1.0) {
|
if (u_mode >= 1.0) {
|
||||||
|
float step = 2.0;
|
||||||
float step= 2.0;
|
if (u_mode == 2.0) { // dashed texture
|
||||||
if (u_mode == 3.0){// dashed texture
|
step = 1.0;
|
||||||
step =1.0;
|
|
||||||
}
|
}
|
||||||
vec4 c=texture2D(tex,vec2(abs(mod(v_st.s+1.0,step)),(v_st.t+1.0)*0.5));
|
vec4 c=texture2D(tex,vec2(abs(mod(v_st.s+1.0,step)),(v_st.t+1.0)*0.5));
|
||||||
float fuzz=fwidth(c.a);
|
float fuzz=fwidth(c.a);
|
||||||
|
@ -55,9 +55,9 @@ public interface Canvas {
|
|||||||
|
|
||||||
void fillColor(int color);
|
void fillColor(int color);
|
||||||
|
|
||||||
|
void fillRectangle(float x, float y, float width, float height, int color);
|
||||||
|
|
||||||
int getHeight();
|
int getHeight();
|
||||||
|
|
||||||
int getWidth();
|
int getWidth();
|
||||||
|
|
||||||
void fillRectangle(int x, int y, int width, int height, int color);
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 devemux86
|
* Copyright 2016-2017 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@ -359,7 +359,7 @@ public final class LineTexBucket extends LineBucket {
|
|||||||
LineTexBucket lb = (LineTexBucket) b;
|
LineTexBucket lb = (LineTexBucket) b;
|
||||||
LineStyle line = lb.line.current();
|
LineStyle line = lb.line.current();
|
||||||
|
|
||||||
gl.uniform1f(shader.uMode, line.dashTexture? 3 : line.texture != null ? 1 : 0);
|
gl.uniform1f(shader.uMode, line.dashArray != null ? 2 : (line.texture != null ? 1 : 0));
|
||||||
|
|
||||||
if (line.texture != null)
|
if (line.texture != null)
|
||||||
line.texture.bind();
|
line.texture.bind();
|
||||||
|
23
vtm/src/org/oscim/theme/SAXTerminationException.java
Normal file
23
vtm/src/org/oscim/theme/SAXTerminationException.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
public class SAXTerminationException extends SAXException {
|
||||||
|
public SAXTerminationException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 devemux86
|
* Copyright 2016-2017 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@ -18,21 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme;
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
public class ThemeLoader {
|
public class ThemeLoader {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ThemeLoader.class);
|
|
||||||
|
|
||||||
public static boolean USE_ATLAS;
|
public static boolean USE_ATLAS;
|
||||||
public static boolean POT_TEXTURES;
|
public static boolean POT_TEXTURES;
|
||||||
|
|
||||||
@ -56,21 +46,12 @@ public class ThemeLoader {
|
|||||||
return load(theme, null);
|
return load(theme, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static IRenderTheme load(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
public static IRenderTheme load(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
||||||
IRenderTheme t = null;
|
IRenderTheme t;
|
||||||
|
if (ThemeUtils.isMapsforgeTheme(theme.getRenderThemeAsStream()))
|
||||||
try {
|
t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback);
|
||||||
if(ThemeUtils.isMapsforgeTheme(theme.getRenderThemeAsStream())){
|
else
|
||||||
t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback);
|
t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback);
|
||||||
}else{
|
|
||||||
t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback);
|
|
||||||
}
|
|
||||||
} catch (IOException | ParserConfigurationException | SAXException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t != null)
|
if (t != null)
|
||||||
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI - 1));
|
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI - 1));
|
||||||
return t;
|
return t;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
*
|
* Copyright 2017 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
|
* 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
|
||||||
@ -16,63 +15,59 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme;
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Longri on 30.08.2017.
|
* A utility class with theme specific helper methods.
|
||||||
*/
|
*/
|
||||||
|
public final class ThemeUtils {
|
||||||
|
|
||||||
public class ThemeUtils {
|
private static final Logger log = LoggerFactory.getLogger(ThemeUtils.class);
|
||||||
|
|
||||||
public static class SAXTerminatorException extends SAXException {
|
|
||||||
public SAXTerminatorException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true, if the given InputStream a Mapsforge render theme!
|
* Check if the given InputStream is a Mapsforge render theme.
|
||||||
*
|
|
||||||
* @param stream
|
|
||||||
* @return TRUE or FALSE
|
|
||||||
* @throws IOException
|
|
||||||
* @throws SAXException
|
|
||||||
* @throws ParserConfigurationException
|
|
||||||
*/
|
*/
|
||||||
public static boolean isMapsforgeTheme(InputStream stream) throws IOException, SAXException, ParserConfigurationException {
|
public static boolean isMapsforgeTheme(InputStream is) {
|
||||||
final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false);
|
|
||||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
|
||||||
factory.setNamespaceAware(true);
|
|
||||||
|
|
||||||
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
|
|
||||||
xmlReader.setContentHandler(new DefaultHandler() {
|
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
|
||||||
if (localName.equals("rendertheme")) {
|
|
||||||
isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
|
|
||||||
//we have all info's, break parsing
|
|
||||||
throw new SAXTerminatorException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
xmlReader.parse(new InputSource(stream));
|
final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false);
|
||||||
} catch (SAXTerminatorException e) {
|
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||||
// do nothing
|
factory.setNamespaceAware(true);
|
||||||
|
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
|
||||||
|
xmlReader.setContentHandler(new DefaultHandler() {
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (localName.equals("rendertheme")) {
|
||||||
|
isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
|
||||||
|
// We have all info, break parsing
|
||||||
|
throw new SAXTerminationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
xmlReader.parse(new InputSource(is));
|
||||||
|
} catch (SAXTerminationException e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
return isMapsforgeTheme.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(is);
|
||||||
}
|
}
|
||||||
stream.close();
|
|
||||||
return isMapsforgeTheme.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ThemeUtils() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import org.oscim.backend.XMLReaderAdapter;
|
|||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.backend.canvas.Paint;
|
|
||||||
import org.oscim.backend.canvas.Paint.Cap;
|
import org.oscim.backend.canvas.Paint.Cap;
|
||||||
import org.oscim.backend.canvas.Paint.FontFamily;
|
import org.oscim.backend.canvas.Paint.FontFamily;
|
||||||
import org.oscim.backend.canvas.Paint.FontStyle;
|
import org.oscim.backend.canvas.Paint.FontStyle;
|
||||||
@ -65,7 +64,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
import static java.lang.Float.parseFloat;
|
import static java.lang.Float.parseFloat;
|
||||||
@ -74,11 +72,7 @@ import static java.lang.Integer.parseInt;
|
|||||||
public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
||||||
private static final Logger log = LoggerFactory.getLogger(XmlMapsforgeThemeBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(XmlMapsforgeThemeBuilder.class);
|
||||||
|
|
||||||
private static final int RENDER_THEME_VERSION = 4;
|
private static final int RENDER_THEME_VERSION = 6;
|
||||||
private static final Pattern SPLIT_PATTERN = Pattern.compile(",");
|
|
||||||
private static final float REPEAT_GAP_DEFAULT = 200f;
|
|
||||||
private static final float REPEAT_START_DEFAULT = 30f;
|
|
||||||
|
|
||||||
|
|
||||||
private enum Element {
|
private enum Element {
|
||||||
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RENDERING_STYLE
|
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RENDERING_STYLE
|
||||||
@ -93,6 +87,9 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
private static final String OUTLINE_STYLE = "O";
|
private static final String OUTLINE_STYLE = "O";
|
||||||
private static final String AREA_STYLE = "A";
|
private static final String AREA_STYLE = "A";
|
||||||
|
|
||||||
|
private static final float REPEAT_GAP_DEFAULT = 200f;
|
||||||
|
private static final float REPEAT_START_DEFAULT = 30f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param theme an input theme containing valid render theme XML data.
|
* @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.
|
* @return a new RenderTheme which is created by parsing the XML data from the input theme.
|
||||||
@ -139,7 +136,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
private final Stack<RuleBuilder> mRuleStack = new Stack<>();
|
private final Stack<RuleBuilder> mRuleStack = new Stack<>();
|
||||||
private final HashMap<String, RenderStyle> mStyles = new HashMap<>(10);
|
private final HashMap<String, RenderStyle> mStyles = new HashMap<>(10);
|
||||||
|
|
||||||
private final HashMap<String, TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
||||||
|
|
||||||
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
|
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
|
||||||
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
|
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
|
||||||
@ -415,7 +412,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
if ("when-matched".equals(value))
|
if ("when-matched".equals(value))
|
||||||
selector |= Selector.WHEN_MATCHED;
|
selector |= Selector.WHEN_MATCHED;
|
||||||
} else {
|
} else {
|
||||||
XmlMapsforgeThemeBuilder.logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(localName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,8 +421,8 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if (closed == Closed.NO)
|
else if (closed == Closed.NO)
|
||||||
element = Rule.Element.LINE;
|
element = Rule.Element.LINE;
|
||||||
|
|
||||||
XmlMapsforgeThemeBuilder.validateNonNegative("zoom-min", zoomMin);
|
validateNonNegative("zoom-min", zoomMin);
|
||||||
XmlMapsforgeThemeBuilder.validateNonNegative("zoom-max", zoomMax);
|
validateNonNegative("zoom-max", zoomMax);
|
||||||
if (zoomMin > zoomMax)
|
if (zoomMin > zoomMax)
|
||||||
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
||||||
|
|
||||||
@ -449,7 +446,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean symbolLine)
|
private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean hasSymbol)
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = attributes.getValue("use");
|
||||||
@ -463,7 +460,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LineStyle line = createLine(style, localName, attributes, mLevels++, false, symbolLine);
|
LineStyle line = createLine(style, localName, attributes, mLevels++, false, hasSymbol);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(LINE_STYLE + line.style, line);
|
mStyles.put(LINE_STYLE + line.style, line);
|
||||||
@ -489,7 +486,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
* @return a new Line with the given rendering attributes.
|
* @return a new Line with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private LineStyle createLine(LineStyle line, String elementName, Attributes attributes,
|
private LineStyle createLine(LineStyle line, String elementName, Attributes attributes,
|
||||||
int level, boolean isOutline, boolean symbolLine) {
|
int level, boolean isOutline, boolean hasSymbol) {
|
||||||
LineBuilder<?> b = mLineBuilder.set(line);
|
LineBuilder<?> b = mLineBuilder.set(line);
|
||||||
b.isOutline(isOutline);
|
b.isOutline(isOutline);
|
||||||
b.level(level);
|
b.level(level);
|
||||||
@ -556,10 +553,13 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("style".equals(name))
|
else if ("style".equals(name))
|
||||||
; // ignore
|
; // ignore
|
||||||
|
|
||||||
else if ("dasharray".equals(name))
|
else if ("stroke-dasharray".equals(name)) {
|
||||||
; // TBD
|
b.dashArray = parseFloatArray(value);
|
||||||
|
for (int j = 0; j < b.dashArray.length; ++j) {
|
||||||
|
b.dashArray[j] = b.dashArray[j] * mScale;
|
||||||
|
}
|
||||||
|
|
||||||
else if ("symbol-width".equals(name))
|
} else if ("symbol-width".equals(name))
|
||||||
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
|
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
|
||||||
|
|
||||||
else if ("symbol-height".equals(name))
|
else if ("symbol-height".equals(name))
|
||||||
@ -568,31 +568,22 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("stroke-dasharray".equals(name)) {
|
else if ("symbol-scaling".equals(name))
|
||||||
b.strokeDasharray = parseFloatArray(value);
|
; // no-op
|
||||||
for (int j = 0; j < b.strokeDasharray.length; ++j) {
|
|
||||||
b.strokeDasharray[j] = b.strokeDasharray[j] * mScale;
|
else
|
||||||
}
|
|
||||||
} else if ("dy".equals(name)) {
|
|
||||||
// NB: minus..
|
|
||||||
//TODO b.dy = -Float.parseFloat(value) * mScale;
|
|
||||||
} else if ("align-center".equals(name)) {
|
|
||||||
//TODO handle align-center
|
|
||||||
} else if ("repeat".equals(name)) {
|
|
||||||
//TODO handle repeat
|
|
||||||
} else if ("display".equals(name)) {
|
|
||||||
//TODO handle display
|
|
||||||
} else
|
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b.dashArray != null) {
|
||||||
if (b.strokeDasharray != null) {//create a dashed texture
|
// Create a dashed texture
|
||||||
int bmpWidth = 0;
|
int bmpWidth = 0;
|
||||||
int bmpHeight = (int) (b.strokeWidth);
|
int bmpHeight = (int) (b.strokeWidth);
|
||||||
if (bmpHeight < 1) bmpHeight = 2;
|
if (bmpHeight < 1)
|
||||||
for (float f : b.strokeDasharray) {
|
bmpHeight = 2;
|
||||||
if (f < 1) f = 1;
|
for (float f : b.dashArray) {
|
||||||
|
if (f < 1)
|
||||||
|
f = 1;
|
||||||
bmpWidth += f;
|
bmpWidth += f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,9 +594,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
|
|
||||||
boolean bw = false;
|
boolean bw = false;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
for (float f : b.strokeDasharray) {
|
for (float f : b.dashArray) {
|
||||||
if (f < 1) f = 1;
|
if (f < 1)
|
||||||
canvas.fillRectangle(x * factor, 0, (int) f * factor, bmpHeight * factor, (bw ? Color.TRANSPARENT : Color.WHITE));
|
f = 1;
|
||||||
|
canvas.fillRectangle(x * factor, 0, f * factor, bmpHeight * factor, (bw ? Color.TRANSPARENT : Color.WHITE));
|
||||||
x += f;
|
x += f;
|
||||||
bw = !bw;
|
bw = !bw;
|
||||||
}
|
}
|
||||||
@ -619,13 +611,12 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
b.stippleColor = b.fillColor;
|
b.stippleColor = b.fillColor;
|
||||||
b.fillColor = Color.TRANSPARENT;
|
b.fillColor = Color.TRANSPARENT;
|
||||||
b.strokeColor = Color.TRANSPARENT;
|
b.strokeColor = Color.TRANSPARENT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
||||||
if (symbolLine) {
|
|
||||||
|
|
||||||
// we have no way to set a repeatGap for the renderer,
|
if (hasSymbol) {
|
||||||
// so we create a texture that already contains this repeatGap.
|
// We have no way to set a repeat gap for the renderer,
|
||||||
|
// so we create a texture that already contains this repeat gap.
|
||||||
float repeatGap = REPEAT_GAP_DEFAULT * mScale;
|
float repeatGap = REPEAT_GAP_DEFAULT * mScale;
|
||||||
float repeatStart = REPEAT_START_DEFAULT * mScale;
|
float repeatStart = REPEAT_START_DEFAULT * mScale;
|
||||||
int width = (int) (b.texture.width + repeatGap);
|
int width = (int) (b.texture.width + repeatGap);
|
||||||
@ -636,13 +627,13 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
canvas.drawBitmap(b.texture.bitmap, repeatStart, 0);
|
canvas.drawBitmap(b.texture.bitmap, repeatStart, 0);
|
||||||
b.texture = new TextureItem(bmp);
|
b.texture = new TextureItem(bmp);
|
||||||
|
|
||||||
// we must set stipple values
|
// We must set stipple values
|
||||||
// The multipliers are determined empirically to
|
// The multipliers are determined empirically to
|
||||||
// correspond to the representation at Mapsforge!
|
// correspond to the representation at Mapsforge.
|
||||||
b.stipple = b.texture.width * 3;
|
b.stipple = b.texture.width * 3;
|
||||||
b.strokeWidth *= 2 * mScale;
|
b.strokeWidth *= 2 * mScale;
|
||||||
|
|
||||||
// use texture color
|
// Use texture color
|
||||||
b.stippleColor = Color.WHITE;
|
b.stippleColor = Color.WHITE;
|
||||||
b.fillColor = Color.TRANSPARENT;
|
b.fillColor = Color.TRANSPARENT;
|
||||||
b.strokeColor = Color.TRANSPARENT;
|
b.strokeColor = Color.TRANSPARENT;
|
||||||
@ -736,9 +727,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("symbol-scaling".equals(name)) {
|
else if ("symbol-scaling".equals(name))
|
||||||
// no-op
|
; // no-op
|
||||||
} else
|
|
||||||
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +773,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
if ("img".equals(name)) {
|
if ("img".equals(name)) {
|
||||||
img = value;
|
img = value;
|
||||||
} else {
|
} else {
|
||||||
XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateExists("img", img, elementName);
|
validateExists("img", img, elementName);
|
||||||
@ -813,7 +805,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
Integer.parseInt(pos[3]));
|
Integer.parseInt(pos[3]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateExists("id", regionName, elementName);
|
validateExists("id", regionName, elementName);
|
||||||
@ -899,18 +891,15 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("base-text-scale".equals(name))
|
else if ("base-text-scale".equals(name))
|
||||||
baseTextScale = Float.parseFloat(value);
|
baseTextScale = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("map-background-outside".equals(name)) {
|
else
|
||||||
//TODO handle map-background-outside
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
} else
|
|
||||||
XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validateExists("version", version, elementName);
|
validateExists("version", version, elementName);
|
||||||
|
|
||||||
if (version != RENDER_THEME_VERSION)
|
if (version > RENDER_THEME_VERSION)
|
||||||
throw new ThemeException("invalid render theme version:"
|
throw new ThemeException("invalid render theme version:" + version);
|
||||||
+ version);
|
|
||||||
|
|
||||||
validateNonNegative("base-stroke-width", baseStrokeWidth);
|
validateNonNegative("base-stroke-width", baseStrokeWidth);
|
||||||
validateNonNegative("base-text-scale", baseTextScale);
|
validateNonNegative("base-text-scale", baseTextScale);
|
||||||
@ -1018,12 +1007,17 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("display".equals(name)) {
|
else if ("symbol-scaling".equals(name))
|
||||||
//TODO Handle display attribute NEVER, ALWAYS, IFSPACE;
|
; // no-op
|
||||||
} else if ("symbol-id".equals(name)) {
|
|
||||||
//TODO Handle symbol-id;
|
else if ("position".equals(name)) {
|
||||||
} else if ("position".equals(name)) {
|
// Until implement position..
|
||||||
//TODO Handle position: AUTO, CENTER, BELOW, BELOW_LEFT, BELOW_RIGHT, ABOVE, ABOVE_LEFT, ABOVE_RIGHT, LEFT, RIGHT
|
if (b.dy == 0) {
|
||||||
|
value = "below".equals(value) ? "-20" : "20";
|
||||||
|
// NB: minus..
|
||||||
|
b.dy = -Float.parseFloat(value) * mScale;
|
||||||
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
@ -1115,15 +1109,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("symbol-scaling".equals(name)) {
|
else if ("symbol-scaling".equals(name))
|
||||||
// no-op
|
; // no-op
|
||||||
} else if ("display".equals(name)) {
|
|
||||||
//TODO Handle display attribute NEVER, ALWAYS, IFSPACE;
|
else
|
||||||
} else if ("id".equals(name)) {
|
|
||||||
//TODO Handle 'id'
|
|
||||||
} else if ("priority".equals(name)) {
|
|
||||||
//TODO Handle 'priority'
|
|
||||||
} else
|
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1203,6 +1192,15 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
return mCategories == null || rule.cat == null || mCategories.contains(rule.cat);
|
return mCategories == null || rule.cat == null || mCategories.contains(rule.cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float[] parseFloatArray(String dashString) {
|
||||||
|
String[] dashEntries = dashString.split(",");
|
||||||
|
float[] dashIntervals = new float[dashEntries.length];
|
||||||
|
for (int i = 0; i < dashEntries.length; ++i) {
|
||||||
|
dashIntervals[i] = Float.parseFloat(dashEntries[i]);
|
||||||
|
}
|
||||||
|
return dashIntervals;
|
||||||
|
}
|
||||||
|
|
||||||
private static void validateNonNegative(String name, float value) {
|
private static void validateNonNegative(String name, float value) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
throw new ThemeException(name + " must not be negative: "
|
throw new ThemeException(name + " must not be negative: "
|
||||||
@ -1214,13 +1212,4 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
|
|||||||
throw new ThemeException("missing attribute " + name
|
throw new ThemeException("missing attribute " + name
|
||||||
+ " for element: " + elementName);
|
+ " for element: " + elementName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] parseFloatArray(String dashString) {
|
|
||||||
String[] dashEntries = SPLIT_PATTERN.split(dashString);
|
|
||||||
float[] dashIntervals = new float[dashEntries.length];
|
|
||||||
for (int i = 0; i < dashEntries.length; ++i) {
|
|
||||||
dashIntervals[i] = Float.parseFloat(dashEntries[i]);
|
|
||||||
}
|
|
||||||
return dashIntervals;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
if ("when-matched".equals(value))
|
if ("when-matched".equals(value))
|
||||||
selector |= Selector.WHEN_MATCHED;
|
selector |= Selector.WHEN_MATCHED;
|
||||||
} else {
|
} else {
|
||||||
XmlThemeBuilder.logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(localName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,8 +414,8 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
else if (closed == Closed.NO)
|
else if (closed == Closed.NO)
|
||||||
element = Rule.Element.LINE;
|
element = Rule.Element.LINE;
|
||||||
|
|
||||||
XmlThemeBuilder.validateNonNegative("zoom-min", zoomMin);
|
validateNonNegative("zoom-min", zoomMin);
|
||||||
XmlThemeBuilder.validateNonNegative("zoom-max", zoomMax);
|
validateNonNegative("zoom-max", zoomMax);
|
||||||
if (zoomMin > zoomMax)
|
if (zoomMin > zoomMax)
|
||||||
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
||||||
|
|
||||||
@ -462,9 +462,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mCurrentRule.addStyle(line);
|
mCurrentRule.addStyle(line);
|
||||||
/* Note 'outline' will not be inherited, it's just a
|
/* Note 'outline' will not be inherited, it's just a
|
||||||
* shortcut to add the outline RenderInstruction. */
|
* shortcut to add the outline RenderInstruction. */
|
||||||
LineStyle outline = createOutline(attributes.getValue("outline"), attributes);
|
String outlineValue = attributes.getValue("outline");
|
||||||
if (outline != null)
|
if (outlineValue != null) {
|
||||||
mCurrentRule.addStyle(outline);
|
LineStyle outline = createOutline(outlineValue, attributes);
|
||||||
|
if (outline != null)
|
||||||
|
mCurrentRule.addStyle(outline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -555,6 +558,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
|
else if ("symbol-scaling".equals(name))
|
||||||
|
; // no-op
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
@ -648,6 +654,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
|
else if ("symbol-scaling".equals(name))
|
||||||
|
; // no-op
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
@ -691,7 +700,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
if ("img".equals(name)) {
|
if ("img".equals(name)) {
|
||||||
img = value;
|
img = value;
|
||||||
} else {
|
} else {
|
||||||
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateExists("img", img, elementName);
|
validateExists("img", img, elementName);
|
||||||
@ -723,7 +732,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
Integer.parseInt(pos[3]));
|
Integer.parseInt(pos[3]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateExists("id", regionName, elementName);
|
validateExists("id", regionName, elementName);
|
||||||
@ -810,15 +819,14 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
baseTextScale = Float.parseFloat(value);
|
baseTextScale = Float.parseFloat(value);
|
||||||
|
|
||||||
else
|
else
|
||||||
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validateExists("version", version, elementName);
|
validateExists("version", version, elementName);
|
||||||
|
|
||||||
if (version != RENDER_THEME_VERSION)
|
if (version > RENDER_THEME_VERSION)
|
||||||
throw new ThemeException("invalid render theme version:"
|
throw new ThemeException("invalid render theme version:" + version);
|
||||||
+ version);
|
|
||||||
|
|
||||||
validateNonNegative("base-stroke-width", baseStrokeWidth);
|
validateNonNegative("base-stroke-width", baseStrokeWidth);
|
||||||
validateNonNegative("base-text-scale", baseTextScale);
|
validateNonNegative("base-text-scale", baseTextScale);
|
||||||
@ -926,6 +934,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
|
else if ("symbol-scaling".equals(name))
|
||||||
|
; // no-op
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
@ -1017,6 +1028,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
else if ("symbol-percent".equals(name))
|
else if ("symbol-percent".equals(name))
|
||||||
b.symbolPercent = Integer.parseInt(value);
|
b.symbolPercent = Integer.parseInt(value);
|
||||||
|
|
||||||
|
else if ("symbol-scaling".equals(name))
|
||||||
|
; // no-op
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
@ -48,25 +48,26 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
public final int symbolWidth;
|
public final int symbolWidth;
|
||||||
public final int symbolHeight;
|
public final int symbolHeight;
|
||||||
public final int symbolPercent;
|
public final int symbolPercent;
|
||||||
public boolean dashTexture;
|
|
||||||
|
public final float[] dashArray;
|
||||||
|
|
||||||
public LineStyle(int stroke, float width) {
|
public LineStyle(int stroke, float width) {
|
||||||
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
|
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineStyle(int level, int stroke, float width) {
|
public LineStyle(int level, int stroke, float width) {
|
||||||
this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
|
this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineStyle(int stroke, float width, Cap cap) {
|
public LineStyle(int stroke, float width, Cap cap) {
|
||||||
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true);
|
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineStyle(int level, String style, int color, float width,
|
public LineStyle(int level, String style, int color, float width,
|
||||||
Cap cap, boolean fixed,
|
Cap cap, boolean fixed,
|
||||||
int stipple, int stippleColor, float stippleWidth,
|
int stipple, int stippleColor, float stippleWidth,
|
||||||
int fadeScale, float blur, boolean isOutline, TextureItem texture,
|
int fadeScale, float blur, boolean isOutline, TextureItem texture,
|
||||||
boolean randomOffset) {
|
boolean randomOffset, float[] dashArray) {
|
||||||
|
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.style = style;
|
this.style = style;
|
||||||
@ -91,6 +92,8 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
this.symbolWidth = 0;
|
this.symbolWidth = 0;
|
||||||
this.symbolHeight = 0;
|
this.symbolHeight = 0;
|
||||||
this.symbolPercent = 100;
|
this.symbolPercent = 100;
|
||||||
|
|
||||||
|
this.dashArray = dashArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LineStyle(LineBuilder<?> b) {
|
private LineStyle(LineBuilder<?> b) {
|
||||||
@ -114,7 +117,8 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
this.symbolWidth = b.symbolWidth;
|
this.symbolWidth = b.symbolWidth;
|
||||||
this.symbolHeight = b.symbolHeight;
|
this.symbolHeight = b.symbolHeight;
|
||||||
this.symbolPercent = b.symbolPercent;
|
this.symbolPercent = b.symbolPercent;
|
||||||
this.dashTexture = b.strokeDasharray != null;
|
|
||||||
|
this.dashArray = b.dashArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -146,7 +150,8 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
public int symbolWidth;
|
public int symbolWidth;
|
||||||
public int symbolHeight;
|
public int symbolHeight;
|
||||||
public int symbolPercent;
|
public int symbolPercent;
|
||||||
public float[] strokeDasharray;
|
|
||||||
|
public float[] dashArray;
|
||||||
|
|
||||||
public LineBuilder() {
|
public LineBuilder() {
|
||||||
}
|
}
|
||||||
@ -176,6 +181,8 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
this.symbolHeight = line.symbolHeight;
|
this.symbolHeight = line.symbolHeight;
|
||||||
this.symbolPercent = line.symbolPercent;
|
this.symbolPercent = line.symbolPercent;
|
||||||
|
|
||||||
|
this.dashArray = line.dashArray;
|
||||||
|
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +261,11 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T dashArray(float[] dashArray) {
|
||||||
|
this.dashArray = dashArray;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
public T reset() {
|
public T reset() {
|
||||||
level = -1;
|
level = -1;
|
||||||
style = null;
|
style = null;
|
||||||
@ -277,7 +289,9 @@ public final class LineStyle extends RenderStyle<LineStyle> {
|
|||||||
symbolWidth = 0;
|
symbolWidth = 0;
|
||||||
symbolHeight = 0;
|
symbolHeight = 0;
|
||||||
symbolPercent = 100;
|
symbolPercent = 100;
|
||||||
strokeDasharray = null;
|
|
||||||
|
dashArray = null;
|
||||||
|
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user