Line texture: stipple implementation, PathLayer support, #105

This commit is contained in:
Emux 2016-07-29 22:41:28 +03:00
parent 4a663f949e
commit 88611257f1
26 changed files with 735 additions and 253 deletions

View File

@ -2,16 +2,18 @@
## New for 0.6.0
- Render themes SVG resources [#60](https://github.com/mapsforge/vtm/issues/60)
**Revive of VTM vector map library.**
- Render theme SVG resources [#60](https://github.com/mapsforge/vtm/issues/60)
- Mapsforge multilingual maps [#34](https://github.com/mapsforge/vtm/issues/34)
- vtm-ios update module [#29](https://github.com/mapsforge/vtm/issues/29)
- Native libraries for all platforms [#14](https://github.com/mapsforge/vtm/issues/14)
- Line stipple and texture rendering
- Layer groups [#99](https://github.com/mapsforge/vtm/issues/99) [#103](https://github.com/mapsforge/vtm/issues/103)
- Map scale bar multi-platform implementation [#84](https://github.com/mapsforge/vtm/issues/84)
- Render themes area tessellation option [#37](https://github.com/mapsforge/vtm/issues/37)
- Map scale bar multi-platform [#84](https://github.com/mapsforge/vtm/issues/84)
- Render theme area tessellation option [#37](https://github.com/mapsforge/vtm/issues/37)
- Graphics API platform enhancements [#92](https://github.com/mapsforge/vtm/issues/92)
- vtm-jts create module [#53](https://github.com/mapsforge/vtm/issues/53)
- vtm-jts module [#53](https://github.com/mapsforge/vtm/issues/53)
- Internal render themes various enhancements
- Revive VTM library
- Many other minor improvements and bug fixes
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.6.0)

View File

@ -35,6 +35,9 @@
<activity
android:name=".LayerGroupActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity
android:name=".LineTexActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity
android:name=".MapsforgeMapActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />

View File

@ -0,0 +1,139 @@
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* 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.android.test;
import android.os.Bundle;
import android.os.SystemClock;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeoPoint;
import org.oscim.layers.PathLayer;
import org.oscim.renderer.bucket.TextureItem;
import org.oscim.theme.styles.LineStyle;
import java.util.ArrayList;
import java.util.List;
import static org.oscim.tiling.source.bitmap.DefaultSources.STAMEN_TONER;
/**
* This is a very INEFFICIENT and somewhat less useful example for how to use
* PathLayers!
*/
public class LineTexActivity extends BitmapTileMapActivity {
public LineTexActivity() {
super(STAMEN_TONER.build());
}
TextureItem tex;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png"));
tex.mipmap = true;
createLayers(1, true);
//looooop();
}
@Override
protected void onResume() {
super.onResume();
/* ignore saved position */
mMap.setMapPosition(0, 0, 1 << 2);
}
void looooop() {
mMap.postDelayed(new Runnable() {
@Override
public void run() {
long t = SystemClock.uptimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos, false);
//Samples.log.debug("update took" + (SystemClock.uptimeMillis() - t) + " " + pos);
looooop();
redraw();
}
}, 50);
}
void redraw() {
mMap.render();
}
ArrayList<PathLayer> mPathLayers = new ArrayList<>();
void createLayers(float pos, boolean init) {
int i = 0;
for (double lat = -90; lat <= 90; lat += 5) {
List<GeoPoint> pts = new ArrayList<>();
for (double lon = -180; lon <= 180; lon += 2) {
//pts.add(new GeoPoint(lat, lon));
double longitude = lon + (pos * 180);
if (longitude < -180)
longitude += 360;
if (longitude > 180)
longitude -= 360;
double latitude = lat + (pos * 90);
if (latitude < -90)
latitude += 180;
if (latitude > 90)
latitude -= 180;
latitude += Math.sin((Math.abs(pos) * (lon / Math.PI)));
pts.add(new GeoPoint(latitude, longitude));
}
PathLayer pathLayer;
if (init) {
int c = Color.fade(Color.rainbow((float) (lat + 90) / 180), 0.9f);
LineStyle style = LineStyle.builder()
.stippleColor(c)
.stipple(24)
.stippleWidth(1)
.strokeWidth(12)
.strokeColor(c)
.fixed(true)
.texture(tex)
.build();
pathLayer = new PathLayer(mMap, style);
mMap.layers().add(pathLayer);
mPathLayers.add(pathLayer);
} else {
pathLayer = mPathLayers.get(i++);
}
pathLayer.setPoints(pts);
}
}
}

View File

@ -49,6 +49,7 @@ public class MarkerOverlayActivity extends BitmapTileMapActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
/* directly load bitmap from resources */
Bitmap bitmap = drawableToBitmap(getResources(), R.drawable.marker_poi);

View File

@ -26,15 +26,20 @@ import org.oscim.layers.vector.PathLayer;
import org.oscim.map.Map.UpdateListener;
import java.util.ArrayList;
import java.util.List;
import static org.oscim.tiling.source.bitmap.DefaultSources.STAMEN_TONER;
/**
* This is a very INEFFICIENT and somewhat less usefull example for how to use
* This is a very INEFFICIENT and somewhat less useful example for how to use
* PathLayers!
*/
public class PathOverlayActivity extends BitmapTileMapActivity {
private static final boolean ANIMATION = true;
private List<PathLayer> mPathLayers = new ArrayList<>();
public PathOverlayActivity() {
super(STAMEN_TONER.build());
}
@ -42,9 +47,8 @@ public class PathOverlayActivity extends BitmapTileMapActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//mBitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
mBitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
mMap.setMapPosition(0, 0, 1 << 2);
for (double lat = -90; lat <= 90; lat += 5) {
int c = Color.fade(Color.rainbow((float) (lat + 90) / 180), 0.5f);
PathLayer pathLayer = new PathLayer(mMap, c, 6);
@ -52,18 +56,20 @@ public class PathOverlayActivity extends BitmapTileMapActivity {
mPathLayers.add(pathLayer);
}
mMap.events.bind(new UpdateListener() {
@Override
public void onMapEvent(Event e, MapPosition mapPosition) {
//if (e == Map.UPDATE_EVENT) {
long t = System.currentTimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos);
mMap.updateMap(true);
//}
}
});
if (ANIMATION)
mMap.events.bind(new UpdateListener() {
@Override
public void onMapEvent(Event e, MapPosition mapPosition) {
//if (e == Map.UPDATE_EVENT) {
long t = System.currentTimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos);
mMap.updateMap(true);
//}
}
});
else
createLayers(1);
}
@Override
@ -74,14 +80,12 @@ public class PathOverlayActivity extends BitmapTileMapActivity {
mMap.setMapPosition(0, 0, 1 << 2);
}
ArrayList<PathLayer> mPathLayers = new ArrayList<>();
void createLayers(float pos) {
int i = 0;
for (double lat = -90; lat <= 90; lat += 5) {
double[] packedCoordinates = new double[360 + 2];
//List<GeoPoint> pts = new ArrayList<GeoPoint>();
//List<GeoPoint> pts = new ArrayList<>();
int c = 0;
for (double lon = -180; lon <= 180; lon += 2) {
//pts.add(new GeoPoint(lat, lon));

View File

@ -46,6 +46,7 @@ public class Samples extends Activity {
linearLayout.addView(createButton(MapsforgeMapActivity.class));
linearLayout.addView(createButton(MarkerOverlayActivity.class));
linearLayout.addView(createButton(PathOverlayActivity.class));
linearLayout.addView(createButton(LineTexActivity.class));
linearLayout.addView(createButton(LayerGroupActivity.class));
linearLayout.addView(createButton(ThemeStylerActivity.class));
linearLayout.addView(createButton(S3DBMapActivity.class));

View File

@ -18,6 +18,7 @@ package org.oscim.test;
import com.badlogic.gdx.Input;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Color;
import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.core.GeometryBuffer;
@ -29,6 +30,7 @@ import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.bucket.LineBucket;
import org.oscim.renderer.bucket.LineTexBucket;
import org.oscim.renderer.bucket.TextureItem;
import org.oscim.theme.styles.LineStyle;
public class LineRenderTest extends GdxMap {
@ -68,28 +70,27 @@ public class LineRenderTest extends GdxMap {
if (fixed) {
line1 = new LineStyle(Color.RED, 0.5f);
line2 = new LineStyle(Color.GREEN, 1);
line3 = new LineStyle(Color.BLUE, 2);
line4 = new LineStyle(Color.LTGRAY, 3);
} else {
line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f,
Cap.BUTT, false, 0, 0, 0, 0, 1f, false);
line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, true, 0, 0,
0, 0, 1f, false);
line3 = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 4,
Color.CYAN, 1, 0, 0, false);
line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0,
0, 0, 0, 1f, false);
line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null);
line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null);
line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, false, null);
}
LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0,
0, 0, 0, 1f, true);
TextureItem tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/dot.png"));
tex.mipmap = true;
line3 = LineStyle.builder()
.stippleColor(Color.CYAN)
.stipple(8)
.stippleWidth(0.6f)
.strokeWidth(4)
.strokeColor(Color.BLUE)
.fixed(fixed)
.texture(tex)
.build();
LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0,
0, 0, 0, 0, true);
LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, true, null);
LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 0, true, null);
LineBucket ol = l.buckets.addLineBucket(0, outline);
LineBucket ol2 = l.buckets.addLineBucket(5, outline2);
@ -112,14 +113,10 @@ public class LineRenderTest extends GdxMap {
LineTexBucket lt = l.buckets.getLineTexBucket(30);
lt.line = line3;
lt.width = line3.width;
lt.addLine(g.translate(0, 10.5f));
lt.addLine(g.translate(0, 10.5f));
addCircle(200, 200, 100, lt);
// if (addOutline)
// ol2.addOutline(ll);
ll = l.buckets.addLineBucket(40, line4);
ll.addLine(g.translate(0, 10.5f));
ll.addLine(g.translate(0, 10.5f));

View File

@ -0,0 +1,202 @@
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* 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.test;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeoPoint;
import org.oscim.gdx.GdxMap;
import org.oscim.gdx.GdxMapApp;
import org.oscim.layers.PathLayer;
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.renderer.bucket.TextureItem;
import org.oscim.theme.styles.LineStyle;
import org.oscim.tiling.source.bitmap.DefaultSources;
import java.util.ArrayList;
import java.util.List;
public class LineTexTest extends GdxMap {
TextureItem tex;
@Override
protected void createLayers() {
BitmapTileLayer bitmapLayer = new BitmapTileLayer(mMap, DefaultSources.STAMEN_TONER.build());
bitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
mMap.setBaseMap(bitmapLayer);
mMap.setMapPosition(0, 0, 1 << 2);
tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png"));
tex.mipmap = true;
// LineStyle style = LineStyle.builder()
// .stippleColor(Color.BLACK)
// .stipple(64)
// .stippleWidth(1)
// .strokeWidth(8)
// .strokeColor(Color.RED)
// .fixed(true)
// .texture(tex)
// .build();
//PathLayer pl = new PathLayer(mMap, style);
//PathLayer pl = new PathLayer(mMap, Color.RED);
//pl.addGreatCircle(new GeoPoint(53.1, -85.), new GeoPoint(-40.0, 85.0));
//mMap.layers().add(pl);
createLayers(1, true);
/*mMap.events.bind(new Map.UpdateListener() {
@Override
public void onMapEvent(Event e, MapPosition mapPosition) {
//if (e == Map.UPDATE_EVENT) {
long t = System.currentTimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos, false);
mMap.updateMap(true);
//}
}
});*/
}
ArrayList<PathLayer> mPathLayers = new ArrayList<>();
void createLayers(float pos, boolean init) {
int i = 0;
for (double lat = -90; lat <= 90; lat += 5) {
List<GeoPoint> pts = new ArrayList<>();
for (double lon = -180; lon <= 180; lon += 2) {
//pts.add(new GeoPoint(lat, lon));
double longitude = lon + (pos * 180);
if (longitude < -180)
longitude += 360;
if (longitude > 180)
longitude -= 360;
double latitude = lat + (pos * 90);
if (latitude < -90)
latitude += 180;
if (latitude > 90)
latitude -= 180;
latitude += Math.sin((Math.abs(pos) * (lon / Math.PI)));
pts.add(new GeoPoint(latitude, longitude));
}
PathLayer pathLayer;
if (init) {
int c = Color.fade(Color.rainbow((float) (lat + 90) / 180), 0.9f);
LineStyle style = LineStyle.builder()
.stippleColor(c)
.stipple(24)
.stippleWidth(1)
.strokeWidth(12)
.strokeColor(c)
.fixed(true)
.texture(tex)
.build();
pathLayer = new PathLayer(mMap, style);
mMap.layers().add(pathLayer);
mPathLayers.add(pathLayer);
} else {
pathLayer = mPathLayers.get(i++);
}
pathLayer.setPoints(pts);
}
}
// mMap.layers().add(new GenericLayer(mMap, new BucketRenderer() {
// boolean init;
//
// GeometryBuffer g = new GeometryBuffer(10, 1);
//
// LineBucket lb = buckets.addLineBucket(0,
// new LineStyle(Color.fade(Color.CYAN, 0.5f), 2.5f));
//
// LineTexBucket ll;
//
// @Override
// public boolean setup() {
//
// //lb.next = ll;
// ll = buckets.getLineTexBucket(1);
//
// TextureItem tex = new TextureItem(CanvasAdapter.getBitmapAsset("patterns/dot.png"));
// tex.mipmap = true;
//
// ll.line = LineStyle.builder()
// .stippleColor(Color.BLACK)
// .stipple(16)
// .stippleWidth(1)
// .strokeWidth(8)
// .strokeColor(Color.RED)
// .fixed(true)
// .texture(tex)
// .build();
//
// //ll.width = 8;
//
// return super.setup();
// }
//
// @Override
// public void update(GLViewport v) {
// if (!init) {
// mMapPosition.copy(v.pos);
// init = true;
// }
//
// buckets.clear();
// buckets.set(lb);
//GeometryBuffer.makeCircle(g, 0, 0, 600, 40);
//
// // g.clear();
// // g.startLine();
// // g.addPoint(-1, 0);
// // g.addPoint(1, 0);
// // g.addPoint(1, -1);
// // g.addPoint(-1, -1);
// // g.scale(100, 100);
//
// for (int i = 0; i < 15; i++) {
// lb.addLine(g);
// ll.addLine(g);
// g.scale(0.8f, 0.8f);
// }
// compile();
//
// }
// }));
public static void main(String[] args) {
GdxMapApp.init();
GdxMapApp.run(new LineTexTest(), null, 256);
}
}

View File

@ -31,28 +31,33 @@ import java.util.List;
public class PathLayerTest extends GdxMapApp {
private static final boolean ANIMATION = true;
private List<PathLayer> mPathLayers = new ArrayList<>();
@Override
public void createLayers() {
mMap.setBaseMap(new BitmapTileLayer(mMap, DefaultSources.STAMEN_TONER.build()));
createLayers(1, true);
BitmapTileLayer bitmapLayer = new BitmapTileLayer(mMap, DefaultSources.STAMEN_TONER.build());
bitmapLayer.tileRenderer().setBitmapAlpha(0.5f);
mMap.setBaseMap(bitmapLayer);
mMap.setMapPosition(0, 0, 1 << 2);
mMap.events.bind(new UpdateListener() {
@Override
public void onMapEvent(Event e, MapPosition mapPosition) {
//if (e == Map.UPDATE_EVENT) {
long t = System.currentTimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos, false);
mMap.updateMap(true);
//}
}
});
}
createLayers(1, true);
ArrayList<PathLayer> mPathLayers = new ArrayList<>();
if (ANIMATION)
mMap.events.bind(new UpdateListener() {
@Override
public void onMapEvent(Event e, MapPosition mapPosition) {
//if (e == Map.UPDATE_EVENT) {
long t = System.currentTimeMillis();
float pos = t % 20000 / 10000f - 1f;
createLayers(pos, false);
mMap.updateMap(true);
//}
}
});
}
void createLayers(float pos, boolean init) {

View File

@ -34,7 +34,7 @@ public class SymbolRenderLayer extends BucketRenderer {
it.billboard = false;
try {
it.bitmap = CanvasAdapter.getBitmapAsset("", "jar:symbols/cafe.png");
it.bitmap = CanvasAdapter.getBitmapAsset("", "symbols/food/cafe.svg");
} catch (Exception e) {
e.printStackTrace();

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

View File

@ -0,0 +1,46 @@
#ifdef GLES
precision mediump float;
#endif
uniform mat4 u_mvp;
uniform vec4 u_color;
uniform float u_pscale;
uniform float u_width;
attribute vec4 a_pos0;
attribute vec4 a_pos1;
attribute vec2 a_len0;
attribute vec2 a_len1;
attribute float a_flip;
varying vec2 v_st;
void
main(){
vec4 pos;
if (a_flip == 0.0) {
// vec2 dir = u_width * a_pos0.zw;
pos = vec4(a_pos0.xy + (u_width * a_pos0.zw), 0.0, 1.0);
v_st = vec2(a_len0.x / u_pscale, 1.0);
}
else {
// vec2 dir = u_width * a_pos1.zw;
pos = vec4(a_pos1.xy - (u_width * a_pos1.zw), 0.0, 1.0);
v_st = vec2(a_len1.x / u_pscale, -1.0);
}
gl_Position = u_mvp * pos;
}
$$
#extension GL_OES_standard_derivatives : enable
#ifdef GLES
precision mediump float;
#endif
uniform vec4 u_color;
uniform vec4 u_bgcolor;
uniform float u_pwidth;
varying vec2 v_st;
uniform sampler2D tex;
void
main(){
vec4 c=texture2D(tex,vec2(abs(mod(v_st.s+1.0,2.0)),(v_st.t+1.0)*0.5));
float fuzz=fwidth(c.a);
gl_FragColor=(c * u_color) *smoothstep(0.5-fuzz,0.5+fuzz,c.a);
}

View File

@ -1,6 +1,7 @@
/*
* Copyright 2012 osmdroid authors: Viesturs Zarins, Martin Pearman
* Copyright 2012 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -15,7 +16,6 @@
* 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.layers;
import org.oscim.backend.canvas.Paint.Cap;
@ -38,7 +38,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* This class draws a path line in given color.
* This class draws a path line in given color or texture.
*/
public class PathLayer extends Layer {
@ -55,18 +55,27 @@ public class PathLayer extends Layer {
final Worker mWorker;
public PathLayer(Map map, int lineColor, float lineWidth) {
public PathLayer(Map map, LineStyle style) {
super(map);
mWorker = new Worker(map);
mLineStyle = new LineStyle(lineColor, lineWidth, Cap.BUTT);
mLineStyle = style;
mPoints = new ArrayList<>();
mRenderer = new RenderPath();
mPoints = new ArrayList<GeoPoint>();
mWorker = new Worker(map);
}
public PathLayer(Map map, int lineColor, float lineWidth) {
this(map, new LineStyle(lineColor, lineWidth, Cap.BUTT));
}
public PathLayer(Map map, int lineColor) {
this(map, lineColor, 2);
}
public void setStyle(LineStyle style) {
mLineStyle = style;
}
public void clearPath() {
if (mPoints.isEmpty())
return;
@ -190,11 +199,6 @@ public class PathLayer extends Layer {
***/
final class RenderPath extends BucketRenderer {
public RenderPath() {
buckets.addLineBucket(0, mLineStyle);
}
private int mCurX = -1;
private int mCurY = -1;
private int mCurZ = -1;
@ -205,7 +209,7 @@ public class PathLayer extends Layer {
int tx = (int) (v.pos.x * tz);
int ty = (int) (v.pos.y * tz);
// update layers when map moved by at least one tile
/* update layers when map moved by at least one tile */
if ((tx != mCurX || ty != mCurY || tz != mCurZ)) {
mWorker.submit(100);
mCurX = tx;
@ -217,10 +221,10 @@ public class PathLayer extends Layer {
if (t == null)
return;
// keep position to render relative to current state
/* keep position to render relative to current state */
mMapPosition.copy(t.pos);
// compile new layers
/* compile new layers */
buckets.set(t.bucket.get());
compile();
}
@ -301,11 +305,16 @@ public class PathLayer extends Layer {
return true;
}
RenderBuckets layers = task.bucket;
LineBucket ll;
if (mLineStyle.stipple == 0 && mLineStyle.texture == null)
ll = task.bucket.getLineBucket(0);
else
ll = task.bucket.getLineTexBucket(0);
LineBucket ll = layers.getLineBucket(0);
ll.line = mLineStyle;
ll.scale = ll.line.width;
//ll.scale = ll.line.width;
mMap.getMapPosition(task.pos);

View File

@ -1,8 +1,24 @@
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* 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.layers.tile;
import org.oscim.backend.GL;
import org.oscim.backend.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.GLMatrix;
import org.oscim.renderer.GLViewport;
@ -90,7 +106,7 @@ public class VectorTileRenderer extends TileRenderer {
drawTile(t, v, 0);
}
/* draw parent or children as proxy for visibile tiles that dont
/* draw parent or children as proxy for visible tiles that don't
* have data yet. Proxies are clipped to the region where nothing
* was drawn to depth buffer.
* TODO draw proxies for placeholder */
@ -159,16 +175,13 @@ public class VectorTileRenderer extends TileRenderer {
return;
}
MapPosition pos = v.pos;
/* place tile relative to map position */
int z = tile.zoomLevel;
float div = FastMath.pow(z - pos.zoomLevel);
double tileScale = Tile.SIZE * pos.scale;
float x = (float) ((tile.x - pos.x) * tileScale);
float y = (float) ((tile.y - pos.y) * tileScale);
double tileScale = Tile.SIZE * v.pos.scale;
float x = (float) ((tile.x - v.pos.x) * tileScale);
float y = (float) ((tile.y - v.pos.y) * tileScale);
/* scale relative to zoom-level of this tile */
float scale = (float) (pos.scale / (1 << z));
float scale = (float) (v.pos.scale / (1 << tile.zoomLevel));
v.mvp.setTransScale(x, y, scale / COORD_SCALE);
v.mvp.multiplyLhs(v.viewproj);
@ -176,6 +189,8 @@ public class VectorTileRenderer extends TileRenderer {
mClipMVP.setTransScale(x, y, scale / COORD_SCALE);
mClipMVP.multiplyLhs(mClipProj);
float zoomDiv = FastMath.pow(tile.zoomLevel - v.pos.zoomLevel);
buckets.bind();
PolygonBucket.Renderer.clip(mClipMVP, mClipMode);
@ -184,7 +199,7 @@ public class VectorTileRenderer extends TileRenderer {
for (RenderBucket b = buckets.get(); b != null; ) {
switch (b.type) {
case POLYGON:
b = PolygonBucket.Renderer.draw(b, v, div, first);
b = PolygonBucket.Renderer.draw(b, v, zoomDiv, first);
first = false;
/* set test for clip to tile region */
gl.stencilFunc(GL.EQUAL, 0x80, 0x80);
@ -193,7 +208,7 @@ public class VectorTileRenderer extends TileRenderer {
b = LineBucket.Renderer.draw(b, v, scale, buckets);
break;
case TEXLINE:
b = LineTexBucket.Renderer.draw(b, v, div, buckets);
b = LineTexBucket.Renderer.draw(b, v, zoomDiv, buckets);
break;
case MESH:
b = MeshBucket.Renderer.draw(b, v);
@ -216,9 +231,9 @@ public class VectorTileRenderer extends TileRenderer {
}
if (debugOverdraw) {
if (tile.zoomLevel > pos.zoomLevel)
if (tile.zoomLevel > v.pos.zoomLevel)
PolygonBucket.Renderer.drawOver(mClipMVP, Color.BLUE, 0.5f);
else if (tile.zoomLevel < pos.zoomLevel)
else if (tile.zoomLevel < v.pos.zoomLevel)
PolygonBucket.Renderer.drawOver(mClipMVP, Color.RED, 0.5f);
else
PolygonBucket.Renderer.drawOver(mClipMVP, Color.GREEN, 0.5f);

View File

@ -243,19 +243,25 @@ public class VectorTileLoader extends TileLoader implements RenderStyle.Callback
public void renderWay(LineStyle line, int level) {
int nLevel = mCurBucket + level;
if (line.stipple == 0) {
if (line.outline && mCurLineBucket == null) {
log.debug("missing line for outline! " + mElement.tags
+ " lvl:" + level + " layer:" + mElement.layer);
return;
}
if (line.outline && mCurLineBucket == null) {
log.debug("missing line for outline! " + mElement.tags
+ " lvl:" + level + " layer:" + mElement.layer);
return;
}
//LineBucket lb;
if (line.stipple == 0 && line.texture == null) {
//lb = mBuckets.getLineBucket(nLevel);
// else
// lb = mBuckets.getLineTexBucket(nLevel);
LineBucket lb = mBuckets.getLineBucket(nLevel);
if (lb.line == null) {
lb.line = line;
lb.scale = line.fixed ? 1 : mLineScale;
lb.setExtents(-4, Tile.SIZE + 4);
lb.setExtents(-16, Tile.SIZE + 16);
}
if (line.outline) {
@ -266,6 +272,7 @@ public class VectorTileLoader extends TileLoader implements RenderStyle.Callback
lb.addLine(mElement);
/* keep reference for outline layer(s) */
//if (!(lb instanceof LineTexBucket))
mCurLineBucket = lb;
} else {
@ -273,13 +280,16 @@ public class VectorTileLoader extends TileLoader implements RenderStyle.Callback
if (lb.line == null) {
lb.line = line;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
lb.width = w;
lb.scale = line.fixed ? 1 : mLineScale;
lb.setExtents(-16, Tile.SIZE + 16);
}
//if (lb.line == null) {
// lb.line = line;
// float w = line.width;
// if (!line.fixed)
// w *= mLineScale;
// lb.scale = w;
//}
lb.addLine(mElement);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -27,6 +28,7 @@ import org.oscim.renderer.bucket.PolygonBucket;
import org.oscim.renderer.bucket.RenderBucket;
import org.oscim.renderer.bucket.RenderBuckets;
import org.oscim.renderer.bucket.TextureBucket;
import org.oscim.utils.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -117,7 +119,10 @@ public class BucketRenderer extends LayerRenderer {
b = LineBucket.Renderer.draw(b, v, div, buckets);
break;
case TEXLINE:
b = LineTexBucket.Renderer.draw(b, v, div, buckets);
b = LineTexBucket.Renderer.draw(b,
v,
FastMath.pow(layerPos.zoomLevel - v.pos.zoomLevel),
buckets);
break;
case MESH:
b = MeshBucket.Renderer.draw(b, v);

View File

@ -107,38 +107,6 @@ public class GLUtils {
return textureIds[0];
}
public static int loadStippleTexture(byte[] stipple) {
int sum = 0;
for (byte flip : stipple)
sum += flip;
byte[] pixel = new byte[sum];
boolean on = true;
int pos = 0;
for (byte flip : stipple) {
float max = flip;
for (int s = 0; s < flip; s++) {
float color = Math.abs(s / (max - 1) - 0.5f);
if (on)
color = 255 * (1 - color);
else
color = 255 * color;
pixel[pos + s] = FastMath.clampToByte((int) color);
}
on = !on;
pos += flip;
}
return loadTexture(pixel, sum, 1, GL.ALPHA,
GL.LINEAR, GL.LINEAR,
// GLES20.GL_NEAREST, GLES20.GL_NEAREST,
GL.REPEAT,
GL.REPEAT);
}
public static void checkGlError(String op) {
//GL = GLAdapter.get();

View File

@ -1,5 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -38,7 +39,7 @@ import static org.oscim.backend.GLAdapter.gl;
* resolution for coordinates is 0.25 as points will be converted
* to fixed point values.
*/
public final class LineBucket extends RenderBucket {
public class LineBucket extends RenderBucket {
static final Logger log = LoggerFactory.getLogger(LineBucket.class);
private static final float COORD_SCALE = MapRenderer.COORD_SCALE;
@ -81,6 +82,10 @@ public final class LineBucket extends RenderBucket {
this.level = layer;
}
LineBucket(int type, boolean indexed, boolean quads) {
super(type, indexed, quads);
}
public void addOutline(LineBucket link) {
for (LineBucket l = outlines; l != null; l = l.outlines)
if (link == l)
@ -116,7 +121,7 @@ public final class LineBucket extends RenderBucket {
addLine(points, null, numPoints, closed);
}
private void addLine(float[] points, int[] index, int numPoints, boolean closed) {
void addLine(float[] points, int[] index, int numPoints, boolean closed) {
boolean rounded = false;
boolean squared = false;
@ -622,6 +627,9 @@ public final class LineBucket extends RenderBucket {
float heightOffset = 0;
gl.uniform1f(uLineHeight, heightOffset);
// if (1 == 1)
// return b.next;
//
for (; b != null && b.type == RenderBucket.LINE; b = b.next) {
LineBucket lb = (LineBucket) b;
LineStyle line = lb.line.current();

View File

@ -1,5 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -24,6 +25,7 @@ import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,6 +34,7 @@ import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import static org.oscim.backend.GLAdapter.gl;
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
import static org.oscim.renderer.MapRenderer.MAX_INDICES;
import static org.oscim.renderer.MapRenderer.bindQuadIndicesVBO;
@ -80,21 +83,14 @@ import static org.oscim.renderer.MapRenderer.bindQuadIndicesVBO;
* - in our case there is always the polygon fill array at start
* - see addLine hack otherwise.
*/
public final class LineTexBucket extends RenderBucket {
public final class LineTexBucket extends LineBucket {
static final Logger log = LoggerFactory.getLogger(LineTexBucket.class);
private static final float COORD_SCALE = MapRenderer.COORD_SCALE;
/* scale factor mapping extrusion vector to short values */
public static final float DIR_SCALE = 2048;
public LineStyle line;
public float width;
public int evenQuads;
public int oddQuads;
private boolean evenSegment;
private boolean evenSegment = true;
protected boolean mRandomizeOffset = true;
@ -106,28 +102,21 @@ public final class LineTexBucket extends RenderBucket {
}
public void addLine(GeometryBuffer geom) {
addLine(geom.points, geom.index);
addLine(geom.points, geom.index, -1, false);
}
public void addLine(float[] points, int[] index) {
@Override
void addLine(float[] points, int[] index, int numPoints, boolean closed) {
if (vertexItems.empty()) {
/* HACK add one vertex offset when compiling
* buffer otherwise one cant use the full
* VertexItem (see Layers.compile)
* add the two 'x' at front and end */
//numVertices = 2;
/* the additional end vertex to make sure
* not to read outside allocated memory */
/* The additional end vertex to make sure not to read outside
* allocated memory */
numVertices = 1;
}
VertexData vi = vertexItems;
boolean even = evenSegment;
/* reset offset to last written position */
if (!even)
if (!evenSegment)
vi.seek(-12);
int n;
@ -135,7 +124,7 @@ public final class LineTexBucket extends RenderBucket {
if (index == null) {
n = 1;
length = points.length;
length = numPoints;
} else {
n = index.length;
}
@ -169,48 +158,36 @@ public final class LineTexBucket extends RenderBucket {
float vx = nx - x;
float vy = ny - y;
float a = (float) Math.sqrt(vx * vx + vy * vy);
// /* normalize vector */
double a = Math.sqrt(vx * vx + vy * vy);
// vx /= a;
// vy /= a;
/* normalized perpendicular to line segment */
short dx = (short) ((-vy / a) * DIR_SCALE);
short dy = (short) ((vx / a) * DIR_SCALE);
/* normal vector */
vx /= a;
vy /= a;
/* perpendicular to line segment */
float ux = -vy;
float uy = vx;
short dx = (short) (ux * DIR_SCALE);
short dy = (short) (uy * DIR_SCALE);
vi.add((short) x,
(short) y,
dx, dy,
(short) lineLength,
(short) 0);
vi.add((short) x, (short) y, dx, dy, (short) lineLength, (short) 0);
lineLength += a;
vi.seek(6);
vi.add((short) nx,
(short) ny,
dx, dy,
(short) lineLength,
(short) 0);
vi.add((short) nx, (short) ny, dx, dy, (short) lineLength, (short) 0);
x = nx;
y = ny;
if (even) {
if (evenSegment) {
/* go to second segment */
vi.seek(-12);
even = false;
evenSegment = false;
/* vertex 0 and 2 were added */
numVertices += 3;
evenQuads++;
} else {
/* go to next block */
even = true;
evenSegment = true;
/* vertex 1 and 3 were added */
numVertices += 1;
@ -219,13 +196,19 @@ public final class LineTexBucket extends RenderBucket {
}
}
evenSegment = even;
/* advance offset to last written position */
if (!even)
if (!evenSegment)
vi.seek(12);
}
@Override
protected void clear() {
evenSegment = true;
evenQuads = 0;
oddQuads = 0;
super.clear();
}
@Override
protected void compile(ShortBuffer vboData, ShortBuffer iboData) {
compileVertexItems(vboData);
@ -271,7 +254,8 @@ public final class LineTexBucket extends RenderBucket {
public static void init() {
shader = new Shader("linetex_layer");
shader = new Shader("linetex_layer_tex");
//shader = new Shader("linetex_layer");
int[] vboIds = GLUtils.glGenBuffers(1);
mVertexFlipID = vboIds[0];
@ -294,11 +278,46 @@ public final class LineTexBucket extends RenderBucket {
GL.STATIC_DRAW);
GLState.bindVertexBuffer(0);
// mTexID = new int[10];
// byte[] stipple = new byte[2];
// stipple[0] = 32;
// stipple[1] = 32;
// mTexID[0] = GlUtils.loadStippleTexture(stipple);
// mTexID = new int[10];
// byte[] stipple = new byte[40];
// stipple[0] = 32;
// stipple[1] = 32;
// mTexID[0] = loadStippleTexture(stipple);
//tex = new TextureItem(CanvasAdapter.getBitmapAsset("patterns/arrow.png"));
//tex.mipmap = true;
}
//static TextureItem tex;
public static int loadStippleTexture(byte[] stipple) {
int sum = 0;
for (byte flip : stipple)
sum += flip;
byte[] pixel = new byte[sum];
boolean on = true;
int pos = 0;
for (byte flip : stipple) {
float max = flip;
for (int s = 0; s < flip; s++) {
float alpha = Math.abs(s / (max - 1) - 0.5f);
if (on)
alpha = 255 * (1 - alpha);
else
alpha = 255 * alpha;
pixel[pos + s] = FastMath.clampToByte((int) alpha);
}
on = !on;
pos += flip;
}
return GLUtils.loadTexture(pixel, sum, 1, GL.ALPHA,
GL.LINEAR, GL.LINEAR,
GL.REPEAT, GL.REPEAT);
}
private final static int STRIDE = 12;
@ -307,11 +326,7 @@ public final class LineTexBucket extends RenderBucket {
public static RenderBucket draw(RenderBucket b, GLViewport v,
float div, RenderBuckets buckets) {
//if (shader == 0)
// return curLayer.next;
GLState.blend(true);
//GLState.useProgram(shader);
shader.useProgram();
GLState.enableVertexArrays(-1, -1);
@ -339,30 +354,38 @@ public final class LineTexBucket extends RenderBucket {
buckets.vbo.bind();
float scale = (float) v.pos.getZoomScale();
float s = scale / div;
//GL.bindTexture(GL20.TEXTURE_2D, mTexID[0]);
for (; b != null && b.type == TEXLINE; b = b.next) {
LineTexBucket lb = (LineTexBucket) b;
LineStyle line = lb.line.current();
if (line.texture != null)
line.texture.bind();
GLUtils.setColor(shader.uColor, line.stippleColor, 1);
GLUtils.setColor(shader.uBgColor, line.color, 1);
float pScale = (int) (s + 0.5f);
if (pScale < 1)
pScale = 1;
float pScale;
gl.uniform1f(shader.uPatternScale,
(MapRenderer.COORD_SCALE * line.stipple) / pScale);
if (s >= 1) {
pScale = (line.stipple * s);
int cnt = (int) (pScale / line.stipple);
pScale = line.stipple / (cnt + 1);
} else {
pScale = line.stipple / s;
int cnt = (int) (pScale / line.stipple);
pScale = line.stipple * cnt;
}
//log.debug("pScale {} {}", pScale, s);
gl.uniform1f(shader.uPatternScale, COORD_SCALE * pScale);
gl.uniform1f(shader.uPatternWidth, line.stippleWidth);
//GL.uniform1f(hScale, scale);
/* keep line width fixed */
gl.uniform1f(shader.uWidth, lb.width / s * COORD_SCALE_BY_DIR_SCALE);
gl.uniform1f(shader.uWidth, (lb.scale * line.width) / s * COORD_SCALE_BY_DIR_SCALE);
/* add offset vertex */
int vOffset = -STRIDE;
@ -418,7 +441,6 @@ public final class LineTexBucket extends RenderBucket {
gl.drawElements(GL.TRIANGLES, numIndices,
GL.UNSIGNED_SHORT, 0);
}
//GlUtils.checkGlError(TAG);
}
gl.disableVertexAttribArray(aPos0);
@ -427,8 +449,6 @@ public final class LineTexBucket extends RenderBucket {
gl.disableVertexAttribArray(aLen1);
gl.disableVertexAttribArray(aFlip);
//GL.bindTexture(GL20.TEXTURE_2D, 0);
return b;
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright 2012, 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -48,7 +49,8 @@ public class TextureBucket extends RenderBucket {
*/
public final static TexturePool pool = new TexturePool(POOL_FILL,
TEXTURE_WIDTH,
TEXTURE_HEIGHT);
TEXTURE_HEIGHT,
false);
public TextureBucket(int type) {
super(type, false, true);

View File

@ -1,5 +1,6 @@
/*
* Copyright 2012, 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -75,6 +76,8 @@ public class TextureItem extends Inlist<TextureItem> {
final TexturePool pool;
public boolean mipmap;
private TextureItem(TexturePool pool, int id) {
this(pool, id, pool.mWidth, pool.mHeight, false);
}
@ -159,17 +162,19 @@ public class TextureItem extends Inlist<TextureItem> {
private final int mHeight;
private final int mWidth;
private final boolean mUseBitmapPool;
private final boolean mMipmaps;
//private final int mBitmapFormat;
//private final int mBitmapType;
protected int mTexCnt = 0;
public TexturePool(int maxFill, int width, int height) {
public TexturePool(int maxFill, int width, int height, boolean mipmap) {
super(maxFill);
mWidth = width;
mHeight = height;
mUseBitmapPool = true;
mMipmaps = mipmap;
}
public TexturePool(int maxFill) {
@ -177,6 +182,7 @@ public class TextureItem extends Inlist<TextureItem> {
mWidth = 0;
mHeight = 0;
mUseBitmapPool = false;
mMipmaps = false;
}
@Override
@ -274,6 +280,8 @@ public class TextureItem extends Inlist<TextureItem> {
int[] textureIds = GLUtils.glGenTextures(1);
t.id = textureIds[0];
t.mipmap |= mMipmaps;
initTexture(t);
if (dbg)
@ -291,6 +299,9 @@ public class TextureItem extends Inlist<TextureItem> {
t.bitmap.uploadToTexture(true);
}
if (t.mipmap)
gl.generateMipmap(GL.TEXTURE_2D);
if (dbg)
GLUtils.checkGlError(TextureItem.class.getName());
@ -301,8 +312,14 @@ public class TextureItem extends Inlist<TextureItem> {
protected void initTexture(TextureItem t) {
GLState.bindTex2D(t.id);
gl.texParameterf(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER,
GL.LINEAR);
if (t.mipmap) {
gl.texParameterf(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER,
GL.LINEAR_MIPMAP_LINEAR);
} else {
gl.texParameterf(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER,
GL.LINEAR);
}
gl.texParameterf(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER,
GL.LINEAR);
@ -320,8 +337,6 @@ public class TextureItem extends Inlist<TextureItem> {
}
}
;
/* Pool for not-pooled textures. Disposed items will only be released
* on the GL-Thread and will not be put back in any pool. */
final static TexturePool NOPOOL = new TexturePool(0);

View File

@ -370,7 +370,7 @@ public class XmlThemeBuilder extends DefaultHandler {
} else {
mCurrentRule.addStyle(line);
/* Note 'outline' will not be inherited, it's just a
* shorcut to add the outline RenderInstruction. */
* shortcut to add the outline RenderInstruction. */
addOutline(attributes.getValue("outline"));
}
}
@ -394,10 +394,11 @@ public class XmlThemeBuilder extends DefaultHandler {
if ("id".equals(name))
b.style = value;
else if ("src".equals(name))
;// src = value;
else if ("use".equals(name))
else if ("src".equals(name)) {
b.texture = loadTexture(value);
/*if (b.texture != null)
b.texture.mipmap = true;*/
} else if ("use".equals(name))
;// ignore
else if ("outline".equals(name))
@ -450,6 +451,7 @@ public class XmlThemeBuilder extends DefaultHandler {
else
logUnknownAttribute(elementName, name, value, i);
}
return b.build();
}
@ -484,8 +486,6 @@ public class XmlThemeBuilder extends DefaultHandler {
AreaBuilder<?> b = mAreaBuilder.set(area);
b.level(level);
String src = null;
for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
@ -497,7 +497,7 @@ public class XmlThemeBuilder extends DefaultHandler {
;// ignore
else if ("src".equals(name))
src = value;
b.texture = loadTexture(value);
else if ("fill".equals(name))
b.color(value);
@ -526,18 +526,25 @@ public class XmlThemeBuilder extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i);
}
if (src != null) {
try {
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src);
if (bitmap != null)
b.texture = new TextureItem(bitmap, true);
} catch (Exception e) {
log.debug(e.getMessage());
}
}
return b.build();
}
private TextureItem loadTexture(String src) {
if (src == null)
return null;
try {
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mRelativePathPrefix, src);
if (bitmap != null) {
log.debug("loading {}", src);
return new TextureItem(bitmap, true);
}
} catch (Exception e) {
log.debug("missing file / {}", e.getMessage());
}
return null;
}
private void addOutline(String style) {
if (style != null) {
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);

View File

@ -1,6 +1,7 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -19,6 +20,7 @@ package org.oscim.theme.styles;
import org.oscim.backend.canvas.Color;
import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.renderer.bucket.TextureItem;
import static org.oscim.backend.canvas.Color.parseColor;
@ -37,26 +39,28 @@ public final class LineStyle extends RenderStyle {
public final int stipple;
public final int stippleColor;
public final float stippleWidth;
public final TextureItem texture;
private LineStyle(LineBuilder<?> builer) {
this.level = builer.level;
this.style = builer.style;
this.width = builer.strokeWidth;
this.color = builer.fillColor;
this.cap = builer.cap;
this.outline = builer.outline;
this.fixed = builer.fixed;
this.fadeScale = builer.fadeScale;
this.blur = builer.blur;
this.stipple = builer.stipple;
this.stippleColor = builer.stippleColor;
this.stippleWidth = builer.stippleWidth;
private LineStyle(LineBuilder<?> builder) {
this.level = builder.level;
this.style = builder.style;
this.width = builder.strokeWidth;
this.color = builder.fillColor;
this.cap = builder.cap;
this.outline = builder.outline;
this.fixed = builder.fixed;
this.fadeScale = builder.fadeScale;
this.blur = builder.blur;
this.stipple = builder.stipple;
this.stippleColor = builder.stippleColor;
this.stippleWidth = builder.stippleWidth;
this.texture = builder.texture;
}
public LineStyle(int level, String style, int color, float width,
Cap cap, boolean fixed,
int stipple, int stippleColor, float stippleWidth,
int fadeScale, float blur, boolean isOutline) {
int fadeScale, float blur, boolean isOutline, TextureItem texture) {
this.level = level;
this.style = style;
@ -70,21 +74,22 @@ public final class LineStyle extends RenderStyle {
this.stipple = stipple;
this.stippleColor = stippleColor;
this.stippleWidth = stippleWidth;
this.texture = texture;
this.blur = blur;
this.fadeScale = fadeScale;
}
public LineStyle(int stroke, float width) {
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null);
}
public LineStyle(int level, int stroke, float width) {
this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null);
}
public LineStyle(int stroke, float width, Cap cap) {
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false);
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null);
}
@Override
@ -109,6 +114,7 @@ public final class LineStyle extends RenderStyle {
public int stipple;
public int stippleColor;
public float stippleWidth;
public TextureItem texture;
public T set(LineStyle line) {
if (line == null)
@ -125,6 +131,7 @@ public final class LineStyle extends RenderStyle {
this.stipple = line.stipple;
this.stippleColor = line.stippleColor;
this.stippleWidth = line.stippleWidth;
this.texture = line.texture;
return self();
}
@ -142,6 +149,7 @@ public final class LineStyle extends RenderStyle {
stipple = 0;
stippleWidth = 1;
stippleColor = Color.BLACK;
texture = null;
return self();
}
@ -161,6 +169,11 @@ public final class LineStyle extends RenderStyle {
return self();
}
public T stipple(int width) {
this.stipple = width;
return self();
}
public T stippleColor(int color) {
this.stippleColor = color;
return self();
@ -171,6 +184,11 @@ public final class LineStyle extends RenderStyle {
return self();
}
public T stippleWidth(float width) {
this.stippleWidth = width;
return self();
}
public T isOutline(boolean outline) {
this.outline = outline;
return self();
@ -189,6 +207,11 @@ public final class LineStyle extends RenderStyle {
this.fixed = b;
return self();
}
public T texture(TextureItem texture) {
this.texture = texture;
return self();
}
}
@SuppressWarnings("rawtypes")