Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d5f4a0ca | ||
|
|
2859a18d72 | ||
|
|
869446ad13 | ||
|
|
b2fd22885e | ||
|
|
7d6c623a80 | ||
|
|
6bea801bf6 | ||
|
|
d446a3448b | ||
|
|
d006ba5361 | ||
|
|
0eb4f3752f | ||
|
|
789c280fc2 | ||
|
|
a881eec9b1 | ||
|
|
1bc1d88464 | ||
|
|
1c18221f05 | ||
|
|
f4162acf04 | ||
|
|
1138978c22 | ||
|
|
bd43baba20 | ||
|
|
2e6da74af8 | ||
|
|
f6561d2a2e | ||
|
|
45a42bb242 | ||
|
|
3043173814 | ||
|
|
cde5d898c7 | ||
|
|
58f6215c0f | ||
|
|
d7d6fa57ac | ||
|
|
57bf615ab7 | ||
|
|
9bf3161010 | ||
|
|
98a977ea72 | ||
|
|
661bc08bbf | ||
|
|
804c8c4603 | ||
|
|
e103c38e3e | ||
|
|
e3b4ff502e | ||
|
|
6116ebb348 | ||
|
|
5c3a728d05 | ||
|
|
2070145880 | ||
|
|
e9a670f274 | ||
|
|
e5c87ba06e | ||
|
|
fa992b93f5 | ||
|
|
bf67074cf3 | ||
|
|
074320d6d2 | ||
|
|
6616c22a32 | ||
|
|
1ddba0fe8f |
@@ -4,8 +4,8 @@ jdk:
|
|||||||
- openjdk8
|
- openjdk8
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- ANDROID=29
|
- ANDROID=30
|
||||||
- ANDROID_BUILD_TOOLS=29.0.3
|
- ANDROID_BUILD_TOOLS=30.0.3
|
||||||
- GRADLE_OPTS="-Xmx2048m"
|
- GRADLE_OPTS="-Xmx2048m"
|
||||||
- secure: sW674wuFZOuoX7jHQHDbX3j8NxL8JxR07cyq+CrrqJ537dU9lxWQmMBRUpOb+p/q7sQ74PUtiKJkmFgKCSJSAKY+nr6GJ8P/q6u5TUKbmUWODSn8znehX2zualfvFwpF4PILok/wUzXBQE62jn4lUua7cMdsHRMNHbLmKqBoVL0meObDDjsaJ/RCbOPuruy3FmgvXPp0+Y4zl1GsklDSyjFzg4LBzjAk9Ryvh1O4zvJBkkyfCgurLKCnOKIPy3v5fPMS9oDfO1aarAVGoZZe416pvTW4hb8cdB6kn9XWYDob4NDFX/sP5k7XIhd/NAIn9LrKFg0sLtATaKLX+BcasF1CgDR/u6+SEeQd5QaRF7Go2Nq5Ltuu4OIFONI2qhEeVDDK6Otf2WSWj9KPno2GHuumBfbg4ypWoJgmZrMXk8JeVV/OP/0jIQz3p/7yfF21X1XBEqYaVHPAMKdEYYkCSa46KfACyOt6LfnkuCHtoTOpFo7sq0omIA2HOtpIx1u3vMBUyAbQqT6cokkKB1b6gNTFwhHc+8ybfLFPljJB8cWshI+V/b06S6fekRmvTNxvDykWNsdlkENBYqc9hMfjcT4hO4K+76SWN62mimQYODvFyfTVMC7WkQ3k/XEnmqUPV5XkbaILbS1d/tA57N148FiJ5/QXtI6Y94imubYyVqU=
|
- secure: sW674wuFZOuoX7jHQHDbX3j8NxL8JxR07cyq+CrrqJ537dU9lxWQmMBRUpOb+p/q7sQ74PUtiKJkmFgKCSJSAKY+nr6GJ8P/q6u5TUKbmUWODSn8znehX2zualfvFwpF4PILok/wUzXBQE62jn4lUua7cMdsHRMNHbLmKqBoVL0meObDDjsaJ/RCbOPuruy3FmgvXPp0+Y4zl1GsklDSyjFzg4LBzjAk9Ryvh1O4zvJBkkyfCgurLKCnOKIPy3v5fPMS9oDfO1aarAVGoZZe416pvTW4hb8cdB6kn9XWYDob4NDFX/sP5k7XIhd/NAIn9LrKFg0sLtATaKLX+BcasF1CgDR/u6+SEeQd5QaRF7Go2Nq5Ltuu4OIFONI2qhEeVDDK6Otf2WSWj9KPno2GHuumBfbg4ypWoJgmZrMXk8JeVV/OP/0jIQz3p/7yfF21X1XBEqYaVHPAMKdEYYkCSa46KfACyOt6LfnkuCHtoTOpFo7sq0omIA2HOtpIx1u3vMBUyAbQqT6cokkKB1b6gNTFwhHc+8ybfLFPljJB8cWshI+V/b06S6fekRmvTNxvDykWNsdlkENBYqc9hMfjcT4hO4K+76SWN62mimQYODvFyfTVMC7WkQ3k/XEnmqUPV5XkbaILbS1d/tA57N148FiJ5/QXtI6Y94imubYyVqU=
|
||||||
- secure: AdKSZKA4gMuKXI4X4dQNJqcMv5OmPIHdN8fpy55Y9yoOQPQHZE3Zwc4QDWBh20q298jyEC854tVTPTysdZ7h+2s2FhsprYv1Bt/QNzKIrLpeIMj2quuVGMbdPuk08y55gost94KwVLJv0sIDpRlB/PEQkA7Mg/UDsT9zR8E1Ms5x+ul2C8e1ag0zzNl1wVnT5jY8WCp74uA/XXCcJl/80qT1stUERazCKwbKNo007hi7rdm4HA7YGevORq8e2r67je+WIBZUAwrHT0Zjuo4ibwUii4LdwvjuN3w0Z6e9Wf4x5bBqGgnih0T31uom2yPjNx+U/c2AWI+Nxfy/SEF2U+9bjBEZ3ZhI7F1B9ofXo2mhvvsVDiUrymMBbG2V64C9kAzeUh7xIBTqIrbdtpAEBV9FlLAtF2swVTwtCgZgcVTOt3RKXCi3X3nk3cuH7PAorFa/QGfT4xxVu2011FVAt2Rm7SD0ZWztZTSTz/4Nt/egtGBOJfrCc7oLEygLzDmLqsqCwCROITVQjWLjrtqDyLteaNiSXeNIQMKun3izApbXnHmXB+FV3R3EZocboqk3v5bmPTahnG6Ghc2zknWyyxSx+O9qIfOpHUL8JMJiT82lUQUeibtCn7DCE8wVQ/gYC5i+a+KO/d3NemSzIFlZ8aoUiEPYq18dYlsDXeLXwF0=
|
- secure: AdKSZKA4gMuKXI4X4dQNJqcMv5OmPIHdN8fpy55Y9yoOQPQHZE3Zwc4QDWBh20q298jyEC854tVTPTysdZ7h+2s2FhsprYv1Bt/QNzKIrLpeIMj2quuVGMbdPuk08y55gost94KwVLJv0sIDpRlB/PEQkA7Mg/UDsT9zR8E1Ms5x+ul2C8e1ag0zzNl1wVnT5jY8WCp74uA/XXCcJl/80qT1stUERazCKwbKNo007hi7rdm4HA7YGevORq8e2r67je+WIBZUAwrHT0Zjuo4ibwUii4LdwvjuN3w0Z6e9Wf4x5bBqGgnih0T31uom2yPjNx+U/c2AWI+Nxfy/SEF2U+9bjBEZ3ZhI7F1B9ofXo2mhvvsVDiUrymMBbG2V64C9kAzeUh7xIBTqIrbdtpAEBV9FlLAtF2swVTwtCgZgcVTOt3RKXCi3X3nk3cuH7PAorFa/QGfT4xxVu2011FVAt2Rm7SD0ZWztZTSTz/4Nt/egtGBOJfrCc7oLEygLzDmLqsqCwCROITVQjWLjrtqDyLteaNiSXeNIQMKun3izApbXnHmXB+FV3R3EZocboqk3v5bmPTahnG6Ghc2zknWyyxSx+O9qIfOpHUL8JMJiT82lUQUeibtCn7DCE8wVQ/gYC5i+a+KO/d3NemSzIFlZ8aoUiEPYq18dYlsDXeLXwF0=
|
||||||
|
|||||||
13
build.gradle
13
build.gradle
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
classpath 'com.android.tools.build:gradle:4.0.2'
|
||||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ allprojects {
|
|||||||
version = 'master-SNAPSHOT'
|
version = 'master-SNAPSHOT'
|
||||||
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
|
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
|
||||||
|
|
||||||
ext.androidBuildVersionTools = "29.0.3"
|
ext.androidBuildVersionTools = "30.0.3"
|
||||||
ext.gdxVersion = "1.9.10"
|
ext.gdxVersion = "1.9.10"
|
||||||
ext.gwtVersion = "2.8.2"
|
ext.gwtVersion = "2.8.2"
|
||||||
ext.slf4jVersion = "1.7.28"
|
ext.slf4jVersion = "1.7.28"
|
||||||
@@ -28,12 +28,12 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static def androidCompileSdk() { return 29 }
|
static def androidCompileSdk() { return 30 }
|
||||||
|
|
||||||
// 14 for Support Library, 16 for sqlite-android
|
// 14 for Support Library, 16 for sqlite-android
|
||||||
static def androidMinSdk() { return 16 }
|
static def androidMinSdk() { return 16 }
|
||||||
|
|
||||||
static def androidTargetSdk() { return 29 }
|
static def androidTargetSdk() { return 30 }
|
||||||
|
|
||||||
static def versionCode() { return 1 }
|
static def versionCode() { return 1 }
|
||||||
|
|
||||||
@@ -50,5 +50,10 @@ subprojects {
|
|||||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||||
targetCompatibility = JavaVersion.VERSION_1_7
|
targetCompatibility = JavaVersion.VERSION_1_7
|
||||||
options.encoding = 'UTF-8'
|
options.encoding = 'UTF-8'
|
||||||
|
if (JavaVersion.current().isJava9Compatible()) {
|
||||||
|
if (!project.properties.containsKey('android')) {
|
||||||
|
options.compilerArgs.addAll(['--release', '7'])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ if (project.hasProperty("android")) {
|
|||||||
task javadoc(type: Javadoc) {
|
task javadoc(type: Javadoc) {
|
||||||
source = android.sourceSets.main.java.srcDirs
|
source = android.sourceSets.main.java.srcDirs
|
||||||
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||||
|
classpath += project.android.libraryVariants.toList().first().javaCompileProvider.get().classpath
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
task sourcesJar(type: Jar) {
|
task sourcesJar(type: Jar) {
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## New since 0.15.0
|
||||||
|
|
||||||
|
- Many other minor improvements and bug fixes
|
||||||
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.16.0)
|
||||||
|
|
||||||
|
## Version 0.15.0 (2021-01-01)
|
||||||
|
|
||||||
|
- Android: scoped storage example [#785](https://github.com/mapsforge/vtm/pull/785)
|
||||||
|
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
||||||
|
- Render theme from Android content providers [#783](https://github.com/mapsforge/vtm/pull/783)
|
||||||
|
- Render theme xml pull parser [#786](https://github.com/mapsforge/vtm/pull/786)
|
||||||
|
- Symbol scale option [#790](https://github.com/mapsforge/vtm/pull/790)
|
||||||
|
- `Parameters.SYMBOL_SCALING`
|
||||||
|
- Many other minor improvements and bug fixes
|
||||||
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.15.0)
|
||||||
|
|
||||||
## Version 0.14.0 (2020-08-25)
|
## Version 0.14.0 (2020-08-25)
|
||||||
|
|
||||||
- Render themes: symbol styles [#769](https://github.com/mapsforge/vtm/pull/769)
|
- Render themes: symbol styles [#769](https://github.com/mapsforge/vtm/pull/769)
|
||||||
@@ -224,6 +240,8 @@
|
|||||||
- libGDX layer gestures [#151](https://github.com/mapsforge/vtm/issues/151)
|
- libGDX layer gestures [#151](https://github.com/mapsforge/vtm/issues/151)
|
||||||
- Render theme area tessellation option [#37](https://github.com/mapsforge/vtm/issues/37)
|
- Render theme area tessellation option [#37](https://github.com/mapsforge/vtm/issues/37)
|
||||||
- Render theme resources optional location prefixes [#66](https://github.com/mapsforge/vtm/issues/66)
|
- Render theme resources optional location prefixes [#66](https://github.com/mapsforge/vtm/issues/66)
|
||||||
|
- Render theme from input stream [#161](https://github.com/mapsforge/vtm/issues/161)
|
||||||
|
- Render theme from Android assets [#162](https://github.com/mapsforge/vtm/issues/162)
|
||||||
- Graphics API platform enhancements [#92](https://github.com/mapsforge/vtm/issues/92)
|
- Graphics API platform enhancements [#92](https://github.com/mapsforge/vtm/issues/92)
|
||||||
- GeoPoint & BoundingBox improvements [#201](https://github.com/mapsforge/vtm/issues/201) [#200](https://github.com/mapsforge/vtm/issues/200)
|
- GeoPoint & BoundingBox improvements [#201](https://github.com/mapsforge/vtm/issues/201) [#200](https://github.com/mapsforge/vtm/issues/200)
|
||||||
- vtm-jts module [#53](https://github.com/mapsforge/vtm/issues/53)
|
- vtm-jts module [#53](https://github.com/mapsforge/vtm/issues/53)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Current version is [
|
### Desktop (LWJGL)
|
||||||
```groovy
|
```groovy
|
||||||
|
implementation 'org.mapsforge:vtm-desktop-lwjgl:[CURRENT-VERSION]'
|
||||||
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl:1.9.10'
|
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl:1.9.10'
|
||||||
implementation 'org.lwjgl.lwjgl:lwjgl:2.9.3'
|
implementation 'org.lwjgl.lwjgl:lwjgl:2.9.3'
|
||||||
implementation 'org.lwjgl.lwjgl:lwjgl-platform:2.9.3:natives-linux'
|
implementation 'org.lwjgl.lwjgl:lwjgl-platform:2.9.3:natives-linux'
|
||||||
@@ -73,6 +74,7 @@ implementation 'org.lwjgl.lwjgl:lwjgl-platform:2.9.3:natives-windows'
|
|||||||
|
|
||||||
### Desktop (LWJGL 3)
|
### Desktop (LWJGL 3)
|
||||||
```groovy
|
```groovy
|
||||||
|
implementation 'org.mapsforge:vtm-desktop-lwjgl3:[CURRENT-VERSION]'
|
||||||
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl3:1.9.10'
|
implementation 'com.badlogicgames.gdx:gdx-backend-lwjgl3:1.9.10'
|
||||||
implementation 'org.lwjgl:lwjgl:3.2.3'
|
implementation 'org.lwjgl:lwjgl:3.2.3'
|
||||||
implementation 'org.lwjgl:lwjgl:3.2.3:natives-linux'
|
implementation 'org.lwjgl:lwjgl:3.2.3:natives-linux'
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx2048m
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
# Android operating system, and which are packaged with your app's APK
|
# Android operating system, and which are packaged with your app"s APK
|
||||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
# Automatically convert third-party libraries to use AndroidX
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".Samples"
|
android:name=".Samples"
|
||||||
@@ -33,6 +34,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ClusterMarkerOverlayActivity"
|
android:name=".ClusterMarkerOverlayActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||||
|
<activity
|
||||||
|
android:name=".FragmentActivity"
|
||||||
|
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".GettingStarted"
|
android:name=".GettingStarted"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||||
@@ -60,12 +64,6 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".MapsforgeActivity"
|
android:name=".MapsforgeActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||||
<activity
|
|
||||||
android:name=".MapsforgeActivity$MapFilePicker"
|
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
|
||||||
<activity
|
|
||||||
android:name=".MapsforgeActivity$ThemeFilePicker"
|
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MapsforgeS3DBActivity"
|
android:name=".MapsforgeS3DBActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ dependencies {
|
|||||||
implementation project(':vtm-gdx')
|
implementation project(':vtm-gdx')
|
||||||
implementation project(':vtm-gdx-poi3d')
|
implementation project(':vtm-gdx-poi3d')
|
||||||
|
|
||||||
implementation 'org.mapsforge:mapsforge-poi-android:0.14.0'
|
implementation 'org.mapsforge:mapsforge-poi-android:0.15.0'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.14.0:natives-armeabi-v7a'
|
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-armeabi-v7a'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.14.0:natives-arm64-v8a'
|
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-arm64-v8a'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.14.0:natives-x86'
|
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-x86'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.14.0:natives-x86_64'
|
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-x86_64'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|||||||
12
vtm-android-example/res/layout/fragment_blank.xml
Normal file
12
vtm-android-example/res/layout/fragment_blank.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/white">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/empty_fragment_text" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/white">
|
android:background="@android:color/white">
|
||||||
|
|
||||||
<org.oscim.android.MapView
|
<RelativeLayout
|
||||||
android:id="@+id/mapView"
|
android:id="@+id/mapView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
9
vtm-android-example/res/menu/fragment_menu.xml
Normal file
9
vtm-android-example/res/menu/fragment_menu.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/replace_fragment"
|
||||||
|
android:showAsAction="never"
|
||||||
|
android:title="@string/replace_fragment" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
@@ -28,5 +28,7 @@
|
|||||||
<string name="warning">Warning</string>
|
<string name="warning">Warning</string>
|
||||||
<string name="startup_message_mbtiles">To run this sample activity, you need an MBTiles database installed on storage.\n\nadb push %s %s</string>
|
<string name="startup_message_mbtiles">To run this sample activity, you need an MBTiles database installed on storage.\n\nadb push %s %s</string>
|
||||||
<string name="exit">Exit</string>
|
<string name="exit">Exit</string>
|
||||||
|
<string name="replace_fragment">Replace fragment</string>
|
||||||
|
<string name="empty_fragment_text">This is a fragment to test the back stack behaviour of the map fragment.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -16,18 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.android.filepicker;
|
package org.oscim.android.filepicker;
|
||||||
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ThemeLoader;
|
||||||
import org.oscim.theme.ThemeFile;
|
|
||||||
import org.oscim.theme.XmlThemeBuilder;
|
|
||||||
import org.oscim.tiling.TileSource.OpenResult;
|
import org.oscim.tiling.TileSource.OpenResult;
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts all valid render theme XML files.
|
* Accepts all valid render theme XML files.
|
||||||
*/
|
*/
|
||||||
@@ -36,13 +29,8 @@ public final class ValidRenderTheme implements ValidFileFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file) {
|
public boolean accept(File file) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
ThemeLoader.load(file.getAbsolutePath());
|
||||||
DefaultHandler renderThemeHandler = new XmlThemeBuilder(theme);
|
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
|
||||||
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
|
||||||
mOpenResult = OpenResult.SUCCESS;
|
mOpenResult = OpenResult.SUCCESS;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
mOpenResult = new OpenResult(e.getMessage());
|
mOpenResult = new OpenResult(e.getMessage());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -20,8 +20,8 @@ package org.oscim.android.test;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.TileGridLayer;
|
import org.oscim.layers.TileGridLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
@@ -29,11 +29,10 @@ import org.oscim.theme.VtmThemes;
|
|||||||
import org.oscim.tiling.TileSource;
|
import org.oscim.tiling.TileSource;
|
||||||
import org.oscim.tiling.source.OkHttpEngine;
|
import org.oscim.tiling.source.OkHttpEngine;
|
||||||
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
import java.io.File;
|
||||||
|
|
||||||
public class BaseMapActivity extends MapActivity {
|
public class BaseMapActivity extends MapActivity {
|
||||||
static final Logger log = LoggerFactory.getLogger(BaseMapActivity.class);
|
|
||||||
|
|
||||||
static final boolean USE_CACHE = false;
|
static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
@@ -41,8 +40,6 @@ public class BaseMapActivity extends MapActivity {
|
|||||||
TileSource mTileSource;
|
TileSource mTileSource;
|
||||||
TileGridLayer mGridLayer;
|
TileGridLayer mGridLayer;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
public BaseMapActivity(int contentView) {
|
public BaseMapActivity(int contentView) {
|
||||||
super(contentView);
|
super(contentView);
|
||||||
}
|
}
|
||||||
@@ -54,15 +51,19 @@ public class BaseMapActivity extends MapActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
mTileSource = OSciMap4TileSource.builder()
|
mTileSource = OSciMap4TileSource.builder()
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
mTileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
mBaseLayer = mMap.setBaseMap(mTileSource);
|
mBaseLayer = mMap.setBaseMap(mTileSource);
|
||||||
|
|
||||||
/* set initial position on first run */
|
/* set initial position on first run */
|
||||||
@@ -72,14 +73,6 @@ public class BaseMapActivity extends MapActivity {
|
|||||||
mMap.setMapPosition(53.08, 8.83, Math.pow(2, 16));
|
mMap.setMapPosition(53.08, 8.83, Math.pow(2, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
|
||||||
|
|||||||
@@ -16,22 +16,21 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.Cache;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||||
import org.oscim.renderer.MapRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.tiling.source.OkHttpEngine;
|
||||||
import org.oscim.tiling.source.bitmap.BitmapTileSource;
|
import org.oscim.tiling.source.bitmap.BitmapTileSource;
|
||||||
import org.oscim.tiling.source.bitmap.DefaultSources;
|
import org.oscim.tiling.source.bitmap.DefaultSources;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class BitmapTileActivity extends MapActivity {
|
public class BitmapTileActivity extends MapActivity {
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(BitmapTileActivity.class);
|
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private final BitmapTileSource mTileSource;
|
private final BitmapTileSource mTileSource;
|
||||||
@@ -43,12 +42,9 @@ public class BitmapTileActivity extends MapActivity {
|
|||||||
|
|
||||||
public BitmapTileActivity(BitmapTileSource tileSource) {
|
public BitmapTileActivity(BitmapTileSource tileSource) {
|
||||||
super(R.layout.activity_map);
|
super(R.layout.activity_map);
|
||||||
tileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example"));
|
|
||||||
mTileSource = tileSource;
|
mTileSource = tileSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -58,31 +54,24 @@ public class BitmapTileActivity extends MapActivity {
|
|||||||
if (mTileSource == null)
|
if (mTileSource == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
if (USE_CACHE) {
|
if (USE_CACHE) {
|
||||||
String cacheFile = mTileSource.getUrl()
|
// Cache the tiles into file system
|
||||||
.toString()
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
.replaceFirst("https?://", "")
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
.replaceAll("/", "-");
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
log.debug("use bitmap cache {}", cacheFile);
|
|
||||||
mCache = new TileCache(this, null, cacheFile);
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
mTileSource.setCache(mCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTileSource.setHttpEngine(new OkHttpEngine.OkHttpFactory(builder));
|
||||||
|
mTileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example"));
|
||||||
|
|
||||||
mBitmapLayer = new BitmapTileLayer(mMap, mTileSource);
|
mBitmapLayer = new BitmapTileLayer(mMap, mTileSource);
|
||||||
mMap.layers().add(mBitmapLayer);
|
mMap.layers().add(mBitmapLayer);
|
||||||
|
|
||||||
//loooop(1);
|
//loooop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stress testing
|
// Stress testing
|
||||||
void loooop(final int i) {
|
void loooop(final int i) {
|
||||||
final long time = (long) (500 + Math.random() * 1000);
|
final long time = (long) (500 + Math.random() * 1000);
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Meibes
|
||||||
|
*
|
||||||
|
* 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.app.Fragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class BlankFragment extends Fragment {
|
||||||
|
|
||||||
|
static BlankFragment newInstance() {
|
||||||
|
BlankFragment instance = new BlankFragment();
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
instance.setArguments(args);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_blank, container, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Meibes
|
||||||
|
*
|
||||||
|
* 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.app.Activity;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.app.FragmentTransaction;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
public class FragmentActivity extends Activity {
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_map_fragment);
|
||||||
|
|
||||||
|
setTitle(getClass().getSimpleName());
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
Fragment mapFragment = MapFragment.newInstance();
|
||||||
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
|
ft.add(R.id.fragment_container, mapFragment).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.fragment_menu, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.replace_fragment) {
|
||||||
|
Fragment blankFragment = BlankFragment.newInstance();
|
||||||
|
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||||
|
ft.replace(R.id.fragment_container, blankFragment);
|
||||||
|
ft.addToBackStack(null);
|
||||||
|
ft.commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018-2019 devemux86
|
* Copyright 2018-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import org.oscim.android.MapView;
|
import org.oscim.android.MapView;
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
@@ -25,23 +28,24 @@ import org.oscim.renderer.GLViewport;
|
|||||||
import org.oscim.scalebar.DefaultMapScaleBar;
|
import org.oscim.scalebar.DefaultMapScaleBar;
|
||||||
import org.oscim.scalebar.MapScaleBar;
|
import org.oscim.scalebar.MapScaleBar;
|
||||||
import org.oscim.scalebar.MapScaleBarLayer;
|
import org.oscim.scalebar.MapScaleBarLayer;
|
||||||
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.VtmThemes;
|
import org.oscim.theme.VtmThemes;
|
||||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A very basic Android app example.
|
* A very basic Android app example.
|
||||||
* <p>
|
* <p>
|
||||||
* You'll need a map with filename berlin.map from download.mapsforge.org in device storage:
|
* You'll need a map with filename berlin.map from download.mapsforge.org in device storage.
|
||||||
* /sdcard/Android/data/org.oscim.android.test/files/
|
|
||||||
*/
|
*/
|
||||||
public class GettingStarted extends Activity {
|
public class GettingStarted extends Activity {
|
||||||
|
|
||||||
// Name of the map file in device storage
|
// Request code for selecting a map file
|
||||||
private static final String MAP_FILE = "berlin.map";
|
private static final int SELECT_MAP_FILE = 0;
|
||||||
|
|
||||||
private MapView mapView;
|
private MapView mapView;
|
||||||
|
private IRenderTheme theme;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -51,10 +55,30 @@ public class GettingStarted extends Activity {
|
|||||||
mapView = new MapView(this);
|
mapView = new MapView(this);
|
||||||
setContentView(mapView);
|
setContentView(mapView);
|
||||||
|
|
||||||
// Tile source
|
// Open map
|
||||||
MapFileTileSource tileSource = new MapFileTileSource();
|
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
||||||
String mapPath = new File(getExternalFilesDir(null), MAP_FILE).getAbsolutePath();
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
if (tileSource.setMapFile(mapPath)) {
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, SELECT_MAP_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode == SELECT_MAP_FILE && resultCode == Activity.RESULT_OK) {
|
||||||
|
if (data != null) {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
openMap(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openMap(Uri uri) {
|
||||||
|
try {
|
||||||
|
// Tile source
|
||||||
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
|
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
||||||
|
tileSource.setMapFileInputStream(fis);
|
||||||
|
|
||||||
// Vector layer
|
// Vector layer
|
||||||
VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource);
|
VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource);
|
||||||
|
|
||||||
@@ -65,7 +89,7 @@ public class GettingStarted extends Activity {
|
|||||||
mapView.map().layers().add(new LabelLayer(mapView.map(), tileLayer));
|
mapView.map().layers().add(new LabelLayer(mapView.map(), tileLayer));
|
||||||
|
|
||||||
// Render theme
|
// Render theme
|
||||||
mapView.map().setTheme(VtmThemes.DEFAULT);
|
theme = mapView.map().setTheme(VtmThemes.DEFAULT);
|
||||||
|
|
||||||
// Scale bar
|
// Scale bar
|
||||||
MapScaleBar mapScaleBar = new DefaultMapScaleBar(mapView.map());
|
MapScaleBar mapScaleBar = new DefaultMapScaleBar(mapView.map());
|
||||||
@@ -76,6 +100,11 @@ public class GettingStarted extends Activity {
|
|||||||
|
|
||||||
// Note: this map position is specific to Berlin area
|
// Note: this map position is specific to Berlin area
|
||||||
mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12);
|
mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
* In case of map file errors avoid crash, but developers should handle these cases!
|
||||||
|
*/
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +123,7 @@ public class GettingStarted extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
mapView.onDestroy();
|
mapView.onDestroy();
|
||||||
|
theme.dispose();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
125
vtm-android-example/src/org/oscim/android/test/MapFragment.java
Normal file
125
vtm-android-example/src/org/oscim/android/test/MapFragment.java
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2020 devemux86
|
||||||
|
* Copyright 2020 Meibes
|
||||||
|
*
|
||||||
|
* 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.app.Fragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import org.oscim.android.MapView;
|
||||||
|
import org.oscim.backend.CanvasAdapter;
|
||||||
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
|
import org.oscim.renderer.GLViewport;
|
||||||
|
import org.oscim.scalebar.DefaultMapScaleBar;
|
||||||
|
import org.oscim.scalebar.MapScaleBar;
|
||||||
|
import org.oscim.scalebar.MapScaleBarLayer;
|
||||||
|
import org.oscim.theme.IRenderTheme;
|
||||||
|
import org.oscim.theme.VtmThemes;
|
||||||
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You'll need a map with filename berlin.map from download.mapsforge.org in device storage.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class MapFragment extends Fragment {
|
||||||
|
|
||||||
|
private MapView mapView;
|
||||||
|
private IRenderTheme theme;
|
||||||
|
|
||||||
|
public static MapFragment newInstance() {
|
||||||
|
MapFragment instance = new MapFragment();
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
instance.setArguments(args);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_map, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
mapView = new MapView(getActivity());
|
||||||
|
RelativeLayout relativeLayout = view.findViewById(R.id.mapView);
|
||||||
|
relativeLayout.addView(mapView);
|
||||||
|
|
||||||
|
// Tile source
|
||||||
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
|
File file = new File(getActivity().getExternalFilesDir(null), "berlin.map");
|
||||||
|
tileSource.setMapFile(file.getAbsolutePath());
|
||||||
|
|
||||||
|
// Vector layer
|
||||||
|
VectorTileLayer tileLayer = mapView.map().setBaseMap(tileSource);
|
||||||
|
|
||||||
|
// Building layer
|
||||||
|
mapView.map().layers().add(new BuildingLayer(mapView.map(), tileLayer));
|
||||||
|
|
||||||
|
// Label layer
|
||||||
|
mapView.map().layers().add(new LabelLayer(mapView.map(), tileLayer));
|
||||||
|
|
||||||
|
// Render theme
|
||||||
|
theme = mapView.map().setTheme(VtmThemes.DEFAULT);
|
||||||
|
|
||||||
|
// Scale bar
|
||||||
|
MapScaleBar mapScaleBar = new DefaultMapScaleBar(mapView.map());
|
||||||
|
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mapView.map(), mapScaleBar);
|
||||||
|
mapScaleBarLayer.getRenderer().setPosition(GLViewport.Position.BOTTOM_LEFT);
|
||||||
|
mapScaleBarLayer.getRenderer().setOffset(5 * CanvasAdapter.getScale(), 0);
|
||||||
|
mapView.map().layers().add(mapScaleBarLayer);
|
||||||
|
|
||||||
|
// Note: this map position is specific to Berlin area
|
||||||
|
mapView.map().setMapPosition(52.517037, 13.38886, 1 << 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (mapView != null) {
|
||||||
|
mapView.onResume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
if (mapView != null) {
|
||||||
|
mapView.onPause();
|
||||||
|
}
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
if (mapView != null) {
|
||||||
|
mapView.onDestroy();
|
||||||
|
mapView = null;
|
||||||
|
}
|
||||||
|
if (theme != null) {
|
||||||
|
theme.dispose();
|
||||||
|
theme = null;
|
||||||
|
}
|
||||||
|
super.onDestroyView();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018-2019 devemux86
|
* Copyright 2018-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -16,10 +16,10 @@ package org.oscim.android.test;
|
|||||||
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import okhttp3.CipherSuite;
|
import okhttp3.CipherSuite;
|
||||||
import okhttp3.ConnectionSpec;
|
import okhttp3.ConnectionSpec;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.android.cache.TileCache;
|
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
@@ -30,6 +30,7 @@ import org.oscim.tiling.source.UrlTileSource;
|
|||||||
import org.oscim.tiling.source.bitmap.DefaultSources;
|
import org.oscim.tiling.source.bitmap.DefaultSources;
|
||||||
import org.oscim.tiling.source.mvt.MapilionMvtTileSource;
|
import org.oscim.tiling.source.mvt.MapilionMvtTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -41,13 +42,18 @@ public class MapilionMvtActivity extends MapActivity {
|
|||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
// https://github.com/square/okhttp/issues/4053
|
// https://github.com/square/okhttp/issues/4053
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
|
||||||
@@ -71,13 +77,6 @@ public class MapilionMvtActivity extends MapActivity {
|
|||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.OPENMAPTILES);
|
mMap.setTheme(VtmThemes.OPENMAPTILES);
|
||||||
|
|
||||||
@@ -91,12 +90,4 @@ public class MapilionMvtActivity extends MapActivity {
|
|||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Hannes Janetzek
|
* Copyright 2014 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2018 Gustl22
|
* Copyright 2018 Gustl22
|
||||||
*
|
*
|
||||||
@@ -19,15 +19,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import org.oscim.android.theme.ContentRenderTheme;
|
||||||
import org.oscim.android.filepicker.FilePicker;
|
|
||||||
import org.oscim.android.filepicker.FilterByFileExtension;
|
|
||||||
import org.oscim.android.filepicker.ValidMapFile;
|
|
||||||
import org.oscim.android.filepicker.ValidRenderTheme;
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
@@ -42,23 +41,26 @@ import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
|||||||
import org.oscim.renderer.BitmapRenderer;
|
import org.oscim.renderer.BitmapRenderer;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.bucket.RenderBuckets;
|
import org.oscim.renderer.bucket.RenderBuckets;
|
||||||
import org.oscim.scalebar.DefaultMapScaleBar;
|
import org.oscim.scalebar.*;
|
||||||
import org.oscim.scalebar.ImperialUnitAdapter;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.scalebar.MapScaleBar;
|
import org.oscim.theme.ThemeFile;
|
||||||
import org.oscim.scalebar.MapScaleBarLayer;
|
|
||||||
import org.oscim.scalebar.MetricUnitAdapter;
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
|
||||||
import org.oscim.theme.ThemeUtils;
|
|
||||||
import org.oscim.theme.VtmThemes;
|
import org.oscim.theme.VtmThemes;
|
||||||
import org.oscim.theme.styles.AreaStyle;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
import org.oscim.tiling.source.mapfile.MapInfo;
|
import org.oscim.tiling.source.mapfile.MapInfo;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class MapsforgeActivity extends MapActivity {
|
public class MapsforgeActivity extends MapActivity {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MapsforgeActivity.class);
|
||||||
|
|
||||||
static final int SELECT_MAP_FILE = 0;
|
static final int SELECT_MAP_FILE = 0;
|
||||||
static final int SELECT_THEME_FILE = SELECT_MAP_FILE + 1;
|
static final int SELECT_THEME_FILE = 1;
|
||||||
|
|
||||||
private static final Tag ISSEA_TAG = new Tag("natural", "issea");
|
private static final Tag ISSEA_TAG = new Tag("natural", "issea");
|
||||||
private static final Tag NOSEA_TAG = new Tag("natural", "nosea");
|
private static final Tag NOSEA_TAG = new Tag("natural", "nosea");
|
||||||
@@ -66,7 +68,8 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
|
|
||||||
private TileGridLayer mGridLayer;
|
private TileGridLayer mGridLayer;
|
||||||
private Menu mMenu;
|
private Menu mMenu;
|
||||||
private boolean mS3db;
|
private final boolean mS3db;
|
||||||
|
IRenderTheme mTheme;
|
||||||
VectorTileLayer mTileLayer;
|
VectorTileLayer mTileLayer;
|
||||||
|
|
||||||
public MapsforgeActivity() {
|
public MapsforgeActivity() {
|
||||||
@@ -87,22 +90,10 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
startActivityForResult(new Intent(this, MapFilePicker.class),
|
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
||||||
SELECT_MAP_FILE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
}
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, SELECT_MAP_FILE);
|
||||||
public static class MapFilePicker extends FilePicker {
|
|
||||||
public MapFilePicker() {
|
|
||||||
setFileDisplayFilter(new FilterByFileExtension(".map"));
|
|
||||||
setFileSelectFilter(new ValidMapFile());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ThemeFilePicker extends FilePicker {
|
|
||||||
public ThemeFilePicker() {
|
|
||||||
setFileDisplayFilter(new FilterByFileExtension(".xml"));
|
|
||||||
setFileSelectFilter(new ValidRenderTheme());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -117,33 +108,45 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.theme_default:
|
case R.id.theme_default:
|
||||||
mMap.setTheme(VtmThemes.DEFAULT);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.DEFAULT);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_osmarender:
|
case R.id.theme_osmarender:
|
||||||
mMap.setTheme(VtmThemes.OSMARENDER);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.OSMARENDER);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_osmagray:
|
case R.id.theme_osmagray:
|
||||||
mMap.setTheme(VtmThemes.OSMAGRAY);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.OSMAGRAY);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_tubes:
|
case R.id.theme_tubes:
|
||||||
mMap.setTheme(VtmThemes.TRONRENDER);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.TRONRENDER);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_newtron:
|
case R.id.theme_newtron:
|
||||||
mMap.setTheme(VtmThemes.NEWTRON);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.NEWTRON);
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_external:
|
case R.id.theme_external:
|
||||||
startActivityForResult(new Intent(this, ThemeFilePicker.class),
|
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
||||||
SELECT_THEME_FILE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("*/*");
|
||||||
|
startActivityForResult(intent, SELECT_THEME_FILE);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.gridlayer:
|
case R.id.gridlayer:
|
||||||
@@ -165,58 +168,64 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
|
||||||
if (requestCode == SELECT_MAP_FILE) {
|
if (requestCode == SELECT_MAP_FILE) {
|
||||||
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
if (resultCode != Activity.RESULT_OK || data == null) {
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapFileTileSource mTileSource = new MapFileTileSource();
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
//mTileSource.setPreferredLanguage("en");
|
//tileSource.setPreferredLanguage("en");
|
||||||
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
|
||||||
if (mTileSource.setMapFile(file)) {
|
|
||||||
|
|
||||||
mTileLayer = mMap.setBaseMap(mTileSource);
|
try {
|
||||||
loadTheme(null);
|
Uri uri = data.getData();
|
||||||
|
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
||||||
if (mS3db)
|
tileSource.setMapFileInputStream(fis);
|
||||||
mMap.layers().add(new S3DBLayer(mMap, mTileLayer));
|
} catch (IOException e) {
|
||||||
else
|
log.error(e.getMessage());
|
||||||
mMap.layers().add(new BuildingLayer(mMap, mTileLayer));
|
finish();
|
||||||
mMap.layers().add(new LabelLayer(mMap, mTileLayer));
|
|
||||||
|
|
||||||
DefaultMapScaleBar mMapScaleBar = new DefaultMapScaleBar(mMap);
|
|
||||||
mMapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
|
|
||||||
mMapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
|
|
||||||
mMapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
|
|
||||||
mMapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT);
|
|
||||||
|
|
||||||
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mMapScaleBar);
|
|
||||||
BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
|
|
||||||
renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
|
|
||||||
renderer.setOffset(5 * CanvasAdapter.getScale(), 0);
|
|
||||||
mMap.layers().add(mapScaleBarLayer);
|
|
||||||
|
|
||||||
MapInfo info = mTileSource.getMapInfo();
|
|
||||||
if (!info.boundingBox.contains(mMap.getMapPosition().getGeoPoint())) {
|
|
||||||
MapPosition pos = new MapPosition();
|
|
||||||
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
|
||||||
mMap.setMapPosition(pos);
|
|
||||||
mPrefs.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (requestCode == SELECT_THEME_FILE) {
|
|
||||||
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
mTileLayer = mMap.setBaseMap(tileSource);
|
||||||
ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(file);
|
loadTheme(null);
|
||||||
|
|
||||||
|
if (mS3db)
|
||||||
|
mMap.layers().add(new S3DBLayer(mMap, mTileLayer));
|
||||||
|
else
|
||||||
|
mMap.layers().add(new BuildingLayer(mMap, mTileLayer));
|
||||||
|
mMap.layers().add(new LabelLayer(mMap, mTileLayer));
|
||||||
|
|
||||||
|
DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap);
|
||||||
|
mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
|
||||||
|
mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT);
|
||||||
|
|
||||||
|
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar);
|
||||||
|
BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
|
||||||
|
renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
|
||||||
|
renderer.setOffset(5 * CanvasAdapter.getScale(), 0);
|
||||||
|
mMap.layers().add(mapScaleBarLayer);
|
||||||
|
|
||||||
|
MapInfo info = tileSource.getMapInfo();
|
||||||
|
if (!info.boundingBox.contains(mMap.getMapPosition().getGeoPoint())) {
|
||||||
|
MapPosition pos = new MapPosition();
|
||||||
|
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
||||||
|
mMap.setMapPosition(pos);
|
||||||
|
mPrefs.clear();
|
||||||
|
}
|
||||||
|
} else if (requestCode == SELECT_THEME_FILE) {
|
||||||
|
if (resultCode != Activity.RESULT_OK || data == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Uri uri = data.getData();
|
||||||
|
ThemeFile theme = new ContentRenderTheme(getContentResolver(), "", uri);
|
||||||
|
|
||||||
// Use tessellation with sea and land for Mapsforge themes
|
// Use tessellation with sea and land for Mapsforge themes
|
||||||
if (ThemeUtils.isMapsforgeTheme(externalRenderTheme)) {
|
if (theme.isMapsforgeTheme()) {
|
||||||
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
||||||
@Override
|
@Override
|
||||||
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
||||||
@@ -233,12 +242,16 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mMap.setTheme(externalRenderTheme);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(theme);
|
||||||
mMenu.findItem(R.id.theme_external).setChecked(true);
|
mMenu.findItem(R.id.theme_external).setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadTheme(final String styleId) {
|
protected void loadTheme(final String styleId) {
|
||||||
mMap.setTheme(VtmThemes.DEFAULT);
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(VtmThemes.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -17,7 +17,6 @@ package org.oscim.android.test;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.oscim.android.theme.AssetsRenderTheme;
|
import org.oscim.android.theme.AssetsRenderTheme;
|
||||||
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
||||||
import org.oscim.theme.XmlRenderThemeStyleLayer;
|
import org.oscim.theme.XmlRenderThemeStyleLayer;
|
||||||
@@ -58,7 +57,9 @@ public class MapsforgeStyleActivity extends MapsforgeActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadTheme(final String styleId) {
|
protected void loadTheme(final String styleId) {
|
||||||
mMap.setTheme(new AssetsRenderTheme(getAssets(), "", "vtm/stylemenu.xml", new XmlRenderThemeMenuCallback() {
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(new AssetsRenderTheme(getAssets(), "", "vtm/stylemenu.xml", new XmlRenderThemeMenuCallback() {
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getCategories(XmlRenderThemeStyleMenu renderThemeStyleMenu) {
|
public Set<String> getCategories(XmlRenderThemeStyleMenu renderThemeStyleMenu) {
|
||||||
// Use the selected style or the default
|
// Use the selected style or the default
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 devemux86
|
* Copyright 2017-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
@@ -25,41 +25,35 @@ import org.oscim.tiling.source.OkHttpEngine;
|
|||||||
import org.oscim.tiling.source.UrlTileSource;
|
import org.oscim.tiling.source.UrlTileSource;
|
||||||
import org.oscim.tiling.source.geojson.MapzenGeojsonTileSource;
|
import org.oscim.tiling.source.geojson.MapzenGeojsonTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class MapzenGeojsonActivity extends MapActivity {
|
public class MapzenGeojsonActivity extends MapActivity {
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
UrlTileSource tileSource = MapzenGeojsonTileSource.builder()
|
UrlTileSource tileSource = MapzenGeojsonTileSource.builder()
|
||||||
.apiKey("xxxxxxx") // Put a proper API key
|
.apiKey("xxxxxxx") // Put a proper API key
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.MAPZEN);
|
mMap.setTheme(VtmThemes.MAPZEN);
|
||||||
|
|
||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2017 Mathieu De Brito
|
* Copyright 2017 Mathieu De Brito
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
@@ -26,41 +26,35 @@ import org.oscim.tiling.source.OkHttpEngine;
|
|||||||
import org.oscim.tiling.source.UrlTileSource;
|
import org.oscim.tiling.source.UrlTileSource;
|
||||||
import org.oscim.tiling.source.mvt.MapzenMvtTileSource;
|
import org.oscim.tiling.source.mvt.MapzenMvtTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class MapzenMvtActivity extends MapActivity {
|
public class MapzenMvtActivity extends MapActivity {
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
UrlTileSource tileSource = MapzenMvtTileSource.builder()
|
UrlTileSource tileSource = MapzenMvtTileSource.builder()
|
||||||
.apiKey("xxxxxxx") // Put a proper API key
|
.apiKey("xxxxxxx") // Put a proper API key
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.MAPZEN);
|
mMap.setTheme(VtmThemes.MAPZEN);
|
||||||
|
|
||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 devemux86
|
* Copyright 2018-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
@@ -25,41 +25,35 @@ import org.oscim.tiling.source.OkHttpEngine;
|
|||||||
import org.oscim.tiling.source.UrlTileSource;
|
import org.oscim.tiling.source.UrlTileSource;
|
||||||
import org.oscim.tiling.source.geojson.NextzenGeojsonTileSource;
|
import org.oscim.tiling.source.geojson.NextzenGeojsonTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class NextzenGeojsonActivity extends MapActivity {
|
public class NextzenGeojsonActivity extends MapActivity {
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
UrlTileSource tileSource = NextzenGeojsonTileSource.builder()
|
UrlTileSource tileSource = NextzenGeojsonTileSource.builder()
|
||||||
.apiKey("xxxxxxx") // Put a proper API key
|
.apiKey("xxxxxxx") // Put a proper API key
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.MAPZEN);
|
mMap.setTheme(VtmThemes.MAPZEN);
|
||||||
|
|
||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2018 devemux86
|
* Copyright 2018-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
@@ -25,41 +25,35 @@ import org.oscim.tiling.source.OkHttpEngine;
|
|||||||
import org.oscim.tiling.source.UrlTileSource;
|
import org.oscim.tiling.source.UrlTileSource;
|
||||||
import org.oscim.tiling.source.mvt.NextzenMvtTileSource;
|
import org.oscim.tiling.source.mvt.NextzenMvtTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class NextzenMvtActivity extends MapActivity {
|
public class NextzenMvtActivity extends MapActivity {
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
UrlTileSource tileSource = NextzenMvtTileSource.builder()
|
UrlTileSource tileSource = NextzenMvtTileSource.builder()
|
||||||
.apiKey("xxxxxxx") // Put a proper API key
|
.apiKey("xxxxxxx") // Put a proper API key
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.MAPZEN);
|
mMap.setTheme(VtmThemes.MAPZEN);
|
||||||
|
|
||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import okhttp3.Cache;
|
||||||
import org.oscim.android.cache.TileCache;
|
import okhttp3.OkHttpClient;
|
||||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
@@ -25,41 +25,35 @@ import org.oscim.tiling.source.OkHttpEngine;
|
|||||||
import org.oscim.tiling.source.UrlTileSource;
|
import org.oscim.tiling.source.UrlTileSource;
|
||||||
import org.oscim.tiling.source.mvt.OpenMapTilesMvtTileSource;
|
import org.oscim.tiling.source.mvt.OpenMapTilesMvtTileSource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class OpenMapTilesMvtActivity extends MapActivity {
|
public class OpenMapTilesMvtActivity extends MapActivity {
|
||||||
|
|
||||||
private static final boolean USE_CACHE = false;
|
private static final boolean USE_CACHE = false;
|
||||||
|
|
||||||
private TileCache mCache;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||||
|
if (USE_CACHE) {
|
||||||
|
// Cache the tiles into file system
|
||||||
|
File cacheDirectory = new File(getExternalCacheDir(), "tiles");
|
||||||
|
int cacheSize = 10 * 1024 * 1024; // 10 MB
|
||||||
|
Cache cache = new Cache(cacheDirectory, cacheSize);
|
||||||
|
builder.cache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
UrlTileSource tileSource = OpenMapTilesMvtTileSource.builder()
|
UrlTileSource tileSource = OpenMapTilesMvtTileSource.builder()
|
||||||
.apiKey("xxxxxxx") // Put a proper API key
|
.apiKey("xxxxxxx") // Put a proper API key
|
||||||
.httpFactory(new OkHttpEngine.OkHttpFactory())
|
.httpFactory(new OkHttpEngine.OkHttpFactory(builder))
|
||||||
//.locale("en")
|
//.locale("en")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (USE_CACHE) {
|
|
||||||
// Cache the tiles into a local SQLite database
|
|
||||||
mCache = new TileCache(this, null, "tile.db");
|
|
||||||
mCache.setCacheSize(512 * (1 << 10));
|
|
||||||
tileSource.setCache(mCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.OPENMAPTILES);
|
mMap.setTheme(VtmThemes.OPENMAPTILES);
|
||||||
|
|
||||||
mMap.layers().add(new BuildingLayer(mMap, l));
|
mMap.layers().add(new BuildingLayer(mMap, l));
|
||||||
mMap.layers().add(new LabelLayer(mMap, l));
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
|
|
||||||
if (mCache != null)
|
|
||||||
mCache.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ package org.oscim.android.test;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
@@ -126,5 +125,6 @@ public class Samples extends Activity {
|
|||||||
linearLayout.addView(createButton(GdxPoi3DActivity.class));
|
linearLayout.addView(createButton(GdxPoi3DActivity.class));
|
||||||
linearLayout.addView(createButton(OverpassActivity.class));
|
linearLayout.addView(createButton(OverpassActivity.class));
|
||||||
linearLayout.addView(createButton(ClusterMarkerOverlayActivity.class));
|
linearLayout.addView(createButton(ClusterMarkerOverlayActivity.class));
|
||||||
|
linearLayout.addView(createButton(FragmentActivity.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
109
vtm-android/src/org/oscim/android/theme/ContentRenderTheme.java
Normal file
109
vtm-android/src/org/oscim/android/theme/ContentRenderTheme.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.android.theme;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.net.Uri;
|
||||||
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
|
import org.oscim.theme.ThemeFile;
|
||||||
|
import org.oscim.theme.ThemeUtils;
|
||||||
|
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
||||||
|
import org.oscim.utils.Utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ContentRenderTheme allows for customizing the rendering style of the map
|
||||||
|
* via an XML from the Android content providers.
|
||||||
|
*/
|
||||||
|
public class ContentRenderTheme implements ThemeFile {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final ContentResolver mContentResolver;
|
||||||
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
|
private final String mRelativePathPrefix;
|
||||||
|
private final Uri mUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contentResolver the Android content resolver.
|
||||||
|
* @param relativePathPrefix the prefix for all relative resource paths.
|
||||||
|
* @param uri the XML render theme URI.
|
||||||
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
|
*/
|
||||||
|
public ContentRenderTheme(ContentResolver contentResolver, String relativePathPrefix, Uri uri) throws ThemeException {
|
||||||
|
this(contentResolver, relativePathPrefix, uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contentResolver the Android content resolver.
|
||||||
|
* @param relativePathPrefix the prefix for all relative resource paths.
|
||||||
|
* @param uri the XML render theme URI.
|
||||||
|
* @param menuCallback the interface callback to create a settings menu on the fly.
|
||||||
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
|
*/
|
||||||
|
public ContentRenderTheme(ContentResolver contentResolver, String relativePathPrefix, Uri uri, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
|
||||||
|
mContentResolver = contentResolver;
|
||||||
|
mRelativePathPrefix = relativePathPrefix;
|
||||||
|
mUri = uri;
|
||||||
|
mMenuCallback = menuCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
} else if (!(obj instanceof ContentRenderTheme)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ContentRenderTheme other = (ContentRenderTheme) obj;
|
||||||
|
if (getRenderThemeAsStream() != other.getRenderThemeAsStream()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Utils.equals(mRelativePathPrefix, other.mRelativePathPrefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlRenderThemeMenuCallback getMenuCallback() {
|
||||||
|
return mMenuCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelativePathPrefix() {
|
||||||
|
return mRelativePathPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getRenderThemeAsStream() throws ThemeException {
|
||||||
|
try {
|
||||||
|
return mContentResolver.openInputStream(mUri);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ThemeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMapsforgeTheme() {
|
||||||
|
return ThemeUtils.isMapsforgeTheme(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
|
mMenuCallback = menuCallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/application_name"
|
android:label="@string/application_name"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
<!-- android:theme="@style/Theme.TileMap" -->
|
<!-- android:theme="@style/Theme.TileMap" -->
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2016 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -15,40 +15,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.app.filefilter;
|
package org.oscim.app.filefilter;
|
||||||
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ThemeLoader;
|
||||||
import org.oscim.theme.ThemeFile;
|
|
||||||
import org.oscim.theme.XmlThemeBuilder;
|
|
||||||
import org.oscim.tiling.TileSource.OpenResult;
|
import org.oscim.tiling.TileSource.OpenResult;
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts all valid render theme XML files.
|
* Accepts all valid render theme XML files.
|
||||||
*/
|
*/
|
||||||
public final class ValidRenderTheme implements ValidFileFilter {
|
public final class ValidRenderTheme implements ValidFileFilter {
|
||||||
private OpenResult openResult;
|
private OpenResult mOpenResult;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file) {
|
public boolean accept(File file) {
|
||||||
try {
|
try {
|
||||||
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
ThemeLoader.load(file.getAbsolutePath());
|
||||||
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme);
|
mOpenResult = OpenResult.SUCCESS;
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
|
||||||
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
|
||||||
this.openResult = OpenResult.SUCCESS;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.openResult = new OpenResult(e.getMessage());
|
mOpenResult = new OpenResult(e.getMessage());
|
||||||
}
|
}
|
||||||
return this.openResult.isSuccess();
|
return mOpenResult.isSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenResult getFileOpenResult() {
|
public OpenResult getFileOpenResult() {
|
||||||
return this.openResult;
|
return mOpenResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ExternalRenderThemeTest extends GdxMapApp {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
IRenderTheme theme = ThemeLoader.load(name);
|
IRenderTheme theme = ThemeLoader.load(name);
|
||||||
mapLayer.setRenderTheme(theme);
|
mapLayer.setTheme(theme);
|
||||||
MapRenderer.setBackgroundColor(theme.getMapBackground());
|
MapRenderer.setBackgroundColor(theme.getMapBackground());
|
||||||
} catch (ThemeException e) {
|
} catch (ThemeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -80,7 +80,7 @@ public class ExternalRenderThemeTest extends GdxMapApp {
|
|||||||
// IRenderTheme theme =
|
// IRenderTheme theme =
|
||||||
// ThemeLoader.load("themes/elevate/theme.xml");
|
// ThemeLoader.load("themes/elevate/theme.xml");
|
||||||
// IRenderTheme theme = ThemeLoader.load("themes/vmap/theme.xml");
|
// IRenderTheme theme = ThemeLoader.load("themes/vmap/theme.xml");
|
||||||
l.setRenderTheme(theme);
|
l.setTheme(theme);
|
||||||
MapRenderer.setBackgroundColor(theme.getMapBackground());
|
MapRenderer.setBackgroundColor(theme.getMapBackground());
|
||||||
} catch (ThemeException e) {
|
} catch (ThemeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class ThemeTest extends GdxMapApp {
|
|||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(ts);
|
VectorTileLayer l = mMap.setBaseMap(ts);
|
||||||
|
|
||||||
l.setRenderTheme(new RenderTheme());
|
l.setTheme(new RenderTheme());
|
||||||
|
|
||||||
MapRenderer.setBackgroundColor(0xffcccccc);
|
MapRenderer.setBackgroundColor(0xffcccccc);
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ dependencies {
|
|||||||
implementation 'com.fifesoft:rsyntaxtextarea:2.6.1'
|
implementation 'com.fifesoft:rsyntaxtextarea:2.6.1'
|
||||||
implementation 'com.jtattoo:JTattoo:1.6.11'
|
implementation 'com.jtattoo:JTattoo:1.6.11'
|
||||||
|
|
||||||
implementation 'org.mapsforge:mapsforge-core:0.14.0'
|
implementation 'org.mapsforge:mapsforge-core:0.15.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map:0.14.0'
|
implementation 'org.mapsforge:mapsforge-map:0.15.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-awt:0.14.0'
|
implementation 'org.mapsforge:mapsforge-map-awt:0.15.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-reader:0.14.0'
|
implementation 'org.mapsforge:mapsforge-map-reader:0.15.0'
|
||||||
implementation 'org.mapsforge:mapsforge-themes:0.14.0'
|
implementation 'org.mapsforge:mapsforge-themes:0.15.0'
|
||||||
implementation 'net.sf.kxml:kxml2:2.3.0'
|
implementation 'net.sf.kxml:kxml2:2.3.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
||||||
classpath 'org.akhikhl.gretty:gretty:2.0.0'
|
classpath 'org.gretty:gretty:3.0.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'gwt'
|
apply plugin: 'gwt'
|
||||||
apply plugin: 'war'
|
apply plugin: 'war'
|
||||||
apply plugin: 'org.akhikhl.gretty'
|
apply plugin: 'org.gretty'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs = ['src']
|
main.java.srcDirs = ['src']
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
||||||
classpath 'org.akhikhl.gretty:gretty:2.0.0'
|
classpath 'org.gretty:gretty:3.0.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'gwt'
|
apply plugin: 'gwt'
|
||||||
apply plugin: 'war'
|
apply plugin: 'war'
|
||||||
apply plugin: 'org.akhikhl.gretty'
|
apply plugin: 'org.gretty'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs = ['src']
|
main.java.srcDirs = ['src']
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ gwt {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
|
if (JavaVersion.current().isJava9Compatible()) {
|
||||||
|
options.addStringOption("-release", "8")
|
||||||
|
}
|
||||||
options.addStringOption("sourcepath", "")
|
options.addStringOption("sourcepath", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1124
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlPullParser.java
Normal file
1124
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlPullParser.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
|||||||
|
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
|
||||||
|
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
|
||||||
|
|
||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown to signal XML Pull Parser related faults.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
|
||||||
|
*/
|
||||||
|
public class XmlPullParserException extends Exception {
|
||||||
|
protected Throwable detail;
|
||||||
|
protected int row = -1;
|
||||||
|
protected int column = -1;
|
||||||
|
|
||||||
|
/* public XmlPullParserException() {
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public XmlPullParserException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public XmlPullParserException(String s, Throwable thrwble) {
|
||||||
|
super(s);
|
||||||
|
this.detail = thrwble;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlPullParserException(String s, int row, int column) {
|
||||||
|
super(s);
|
||||||
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public XmlPullParserException(String msg, XmlPullParser parser, Throwable chain) {
|
||||||
|
super ((msg == null ? "" : msg+" ")
|
||||||
|
+ (parser == null ? "" : "(position:"+parser.getPositionDescription()+") ")
|
||||||
|
+ (chain == null ? "" : "caused by: "+chain));
|
||||||
|
|
||||||
|
if (parser != null) {
|
||||||
|
this.row = parser.getLineNumber();
|
||||||
|
this.column = parser.getColumnNumber();
|
||||||
|
}
|
||||||
|
this.detail = chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getDetail() { return detail; }
|
||||||
|
// public void setDetail(Throwable cause) { this.detail = cause; }
|
||||||
|
public int getLineNumber() { return row; }
|
||||||
|
public int getColumnNumber() { return column; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
public String getMessage() {
|
||||||
|
if(detail == null)
|
||||||
|
return super.getMessage();
|
||||||
|
else
|
||||||
|
return super.getMessage() + "; nested exception is: \n\t"
|
||||||
|
+ detail.getMessage();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//NOTE: code that prints this and detail is difficult in J2ME
|
||||||
|
public void printStackTrace() {
|
||||||
|
if (detail == null) {
|
||||||
|
super.printStackTrace();
|
||||||
|
} else {
|
||||||
|
synchronized(System.err) {
|
||||||
|
System.err.println(super.getMessage() + "; nested exception is:");
|
||||||
|
detail.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
|
||||||
|
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
|
||||||
|
|
||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
|
||||||
|
*
|
||||||
|
* @see XmlPullParser
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
|
||||||
|
* @author Stefan Haustein
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class XmlPullParserFactory {
|
||||||
|
|
||||||
|
public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
|
||||||
|
protected ArrayList parserClasses;
|
||||||
|
protected ArrayList serializerClasses;
|
||||||
|
|
||||||
|
/** Unused, but we have to keep it because it's public API. */
|
||||||
|
protected String classNamesLocation = null;
|
||||||
|
|
||||||
|
// features are kept there
|
||||||
|
// TODO: This can't be made final because it's a public API.
|
||||||
|
protected HashMap<String, Boolean> features = new HashMap<String, Boolean>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor to be called by factory implementations.
|
||||||
|
*/
|
||||||
|
protected XmlPullParserFactory() {
|
||||||
|
parserClasses = new ArrayList<String>();
|
||||||
|
serializerClasses = new ArrayList<String>();
|
||||||
|
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
parserClasses.add(Class.forName("com.android.org.kxml2.io.KXmlParser"));
|
||||||
|
serializerClasses.add(Class.forName("com.android.org.kxml2.io.KXmlSerializer"));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the features to be set when XML Pull Parser is created by this factory.
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @param name string with URI identifying feature
|
||||||
|
* @param state if true feature will be set; if false will be ignored
|
||||||
|
*/
|
||||||
|
public void setFeature(String name, boolean state) throws XmlPullParserException {
|
||||||
|
features.put(name, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current value of the feature with given name.
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @param name The name of feature to be retrieved.
|
||||||
|
* @return The value of named feature.
|
||||||
|
* Unknown features are <string>always</strong> returned as false
|
||||||
|
*/
|
||||||
|
public boolean getFeature(String name) {
|
||||||
|
Boolean value = features.get(name);
|
||||||
|
return value != null ? value.booleanValue() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the parser produced by this factory will provide
|
||||||
|
* support for XML namespaces.
|
||||||
|
* By default the value of this is set to false.
|
||||||
|
*
|
||||||
|
* @param awareness true if the parser produced by this code
|
||||||
|
* will provide support for XML namespaces; false otherwise.
|
||||||
|
*/
|
||||||
|
public void setNamespaceAware(boolean awareness) {
|
||||||
|
features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, awareness);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the factory is configured to produce
|
||||||
|
* parsers which are namespace aware
|
||||||
|
* (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
|
||||||
|
*
|
||||||
|
* @return true if the factory is configured to produce parsers
|
||||||
|
* which are namespace aware; false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isNamespaceAware() {
|
||||||
|
return getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the parser produced by this factory will be validating
|
||||||
|
* (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
|
||||||
|
*
|
||||||
|
* By default the value of this is set to false.
|
||||||
|
*
|
||||||
|
* @param validating - if true the parsers created by this factory must be validating.
|
||||||
|
*/
|
||||||
|
public void setValidating(boolean validating) {
|
||||||
|
features.put(XmlPullParser.FEATURE_VALIDATION, validating);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the factory is configured to produce parsers
|
||||||
|
* which validate the XML content during parse.
|
||||||
|
*
|
||||||
|
* @return true if the factory is configured to produce parsers
|
||||||
|
* which validate the XML content during parse; false otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isValidating() {
|
||||||
|
return getFeature(XmlPullParser.FEATURE_VALIDATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a XML Pull Parser
|
||||||
|
* using the currently configured factory features.
|
||||||
|
*
|
||||||
|
* @return A new instance of a XML Pull Parser.
|
||||||
|
*/
|
||||||
|
public XmlPullParser newPullParser() throws XmlPullParserException {
|
||||||
|
final XmlPullParser pp = getParserInstance();
|
||||||
|
for (Map.Entry<String, Boolean> entry : features.entrySet()) {
|
||||||
|
// NOTE: This test is needed for compatibility reasons. We guarantee
|
||||||
|
// that we only set a feature on a parser if its value is true.
|
||||||
|
if (entry.getValue()) {
|
||||||
|
pp.setFeature(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlPullParser getParserInstance() throws XmlPullParserException {
|
||||||
|
ArrayList<Exception> exceptions = null;
|
||||||
|
|
||||||
|
if (parserClasses != null && !parserClasses.isEmpty()) {
|
||||||
|
exceptions = new ArrayList<Exception>();
|
||||||
|
for (Object o : parserClasses) {
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
if (o != null) {
|
||||||
|
Class<?> parserClass = (Class<?>) o;
|
||||||
|
return (XmlPullParser) parserClass.newInstance();
|
||||||
|
}
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw newInstantiationException("Invalid parser class list", exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlSerializer getSerializerInstance() throws XmlPullParserException {
|
||||||
|
ArrayList<Exception> exceptions = null;
|
||||||
|
|
||||||
|
if (serializerClasses != null && !serializerClasses.isEmpty()) {
|
||||||
|
exceptions = new ArrayList<Exception>();
|
||||||
|
for (Object o : serializerClasses) {
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
if (o != null) {
|
||||||
|
Class<?> serializerClass = (Class<?>) o;
|
||||||
|
return (XmlSerializer) serializerClass.newInstance();
|
||||||
|
}
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw newInstantiationException("Invalid serializer class list", exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static XmlPullParserException newInstantiationException(String message,
|
||||||
|
ArrayList<Exception> exceptions) {
|
||||||
|
if (exceptions == null || exceptions.isEmpty()) {
|
||||||
|
return new XmlPullParserException(message);
|
||||||
|
} else {
|
||||||
|
XmlPullParserException exception = new XmlPullParserException(message);
|
||||||
|
for (Exception ex : exceptions) {
|
||||||
|
exception.addSuppressed(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a XML Serializer.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @return A new instance of a XML Serializer.
|
||||||
|
* @throws XmlPullParserException if a parser cannot be created which satisfies the
|
||||||
|
* requested configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public XmlSerializer newSerializer() throws XmlPullParserException {
|
||||||
|
return getSerializerInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a PullParserFactory that can be used
|
||||||
|
* to create XML pull parsers. The factory will always return instances
|
||||||
|
* of Android's built-in {@link XmlPullParser} and {@link XmlSerializer}.
|
||||||
|
*/
|
||||||
|
public static XmlPullParserFactory newInstance () throws XmlPullParserException {
|
||||||
|
return new XmlPullParserFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a factory that always returns instances of Android's built-in
|
||||||
|
* {@link XmlPullParser} and {@link XmlSerializer} implementation. This
|
||||||
|
* <b>does not</b> support factories capable of creating arbitrary parser
|
||||||
|
* and serializer implementations. Both arguments to this method are unused.
|
||||||
|
*/
|
||||||
|
public static XmlPullParserFactory newInstance (String unused, Class unused2)
|
||||||
|
throws XmlPullParserException {
|
||||||
|
return newInstance();
|
||||||
|
}
|
||||||
|
}
|
||||||
325
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlSerializer.java
Normal file
325
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlSerializer.java
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define an interface to serialization of XML Infoset.
|
||||||
|
* This interface abstracts away if serialized XML is XML 1.0 compatible text or
|
||||||
|
* other formats of XML 1.0 serializations (such as binary XML for example with WBXML).
|
||||||
|
*
|
||||||
|
* <p><b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API.
|
||||||
|
* It is included as basis for discussion. It may change in any way.
|
||||||
|
*
|
||||||
|
* <p>Exceptions that may be thrown are: IOException or runtime exception
|
||||||
|
* (more runtime exceptions can be thrown but are not declared and as such
|
||||||
|
* have no semantics defined for this interface):
|
||||||
|
* <ul>
|
||||||
|
* <li><em>IllegalArgumentException</em> - for almost all methods to signal that
|
||||||
|
* argument is illegal
|
||||||
|
* <li><em>IllegalStateException</em> - to signal that call has good arguments but
|
||||||
|
* is not expected here (violation of contract) and for features/properties
|
||||||
|
* when requesting setting unimplemented feature/property
|
||||||
|
* (UnsupportedOperationException would be better but it is not in MIDP)
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> writing CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE,
|
||||||
|
* PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some implementations
|
||||||
|
* may not be supported (for example when serializing to WBXML).
|
||||||
|
* In such case IllegalStateException will be thrown and it is recommended
|
||||||
|
* to use an optional feature to signal that implementation is not
|
||||||
|
* supporting this kind of output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface XmlSerializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feature identified by name (recommended to be URI for uniqueness).
|
||||||
|
* Some well known optional features are defined in
|
||||||
|
* <a href="http://www.xmlpull.org/v1/doc/features.html">
|
||||||
|
* http://www.xmlpull.org/v1/doc/features.html</a>.
|
||||||
|
*
|
||||||
|
* If feature is not recognized or can not be set
|
||||||
|
* then IllegalStateException MUST be thrown.
|
||||||
|
*
|
||||||
|
* @exception IllegalStateException If the feature is not supported or can not be set
|
||||||
|
*/
|
||||||
|
void setFeature(String name,
|
||||||
|
boolean state)
|
||||||
|
throws IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current value of the feature with given name.
|
||||||
|
* <p><strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null
|
||||||
|
*
|
||||||
|
* @param name The name of feature to be retrieved.
|
||||||
|
* @return The value of named feature.
|
||||||
|
* @exception IllegalArgumentException if feature string is null
|
||||||
|
*/
|
||||||
|
boolean getFeature(String name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of a property.
|
||||||
|
* (the property name is recommended to be URI for uniqueness).
|
||||||
|
* Some well known optional properties are defined in
|
||||||
|
* <a href="http://www.xmlpull.org/v1/doc/properties.html">
|
||||||
|
* http://www.xmlpull.org/v1/doc/properties.html</a>.
|
||||||
|
*
|
||||||
|
* If property is not recognized or can not be set
|
||||||
|
* then IllegalStateException MUST be thrown.
|
||||||
|
*
|
||||||
|
* @exception IllegalStateException if the property is not supported or can not be set
|
||||||
|
*/
|
||||||
|
void setProperty(String name,
|
||||||
|
Object value)
|
||||||
|
throws IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the value of a property.
|
||||||
|
*
|
||||||
|
* The property name is any fully-qualified URI. I
|
||||||
|
* <p><strong>NOTE:</strong> unknown properties are <string>always</strong> returned as null
|
||||||
|
*
|
||||||
|
* @param name The name of property to be retrieved.
|
||||||
|
* @return The value of named property.
|
||||||
|
*/
|
||||||
|
Object getProperty(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to use binary output stream with given encoding.
|
||||||
|
*/
|
||||||
|
void setOutput (OutputStream os, String encoding)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the output to the given writer.
|
||||||
|
* <p><b>WARNING</b> no information about encoding is available!
|
||||||
|
*/
|
||||||
|
void setOutput (Writer writer)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write <?xml declaration with encoding (if encoding not null)
|
||||||
|
* and standalone flag (if standalone not null)
|
||||||
|
* This method can only be called just after setOutput.
|
||||||
|
*/
|
||||||
|
void startDocument (String encoding, Boolean standalone)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish writing. All unclosed start tags will be closed and output
|
||||||
|
* will be flushed. After calling this method no more output can be
|
||||||
|
* serialized until next call to setOutput()
|
||||||
|
*/
|
||||||
|
void endDocument ()
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the given prefix to the given namespace.
|
||||||
|
* This call is valid for the next element including child elements.
|
||||||
|
* The prefix and namespace MUST be always declared even if prefix
|
||||||
|
* is not used in element (startTag() or attribute()) - for XML 1.0
|
||||||
|
* it must result in declaring <code>xmlns:prefix='namespace'</code>
|
||||||
|
* (or <code>xmlns:prefix="namespace"</code> depending what character is used
|
||||||
|
* to quote attribute value).
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> this method MUST be called directly before startTag()
|
||||||
|
* and if anything but startTag() or setPrefix() is called next there will be exception.
|
||||||
|
* <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
|
||||||
|
* and can not be redefined see:
|
||||||
|
* <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>.
|
||||||
|
* <p><b>NOTE:</b> to set default namespace use as prefix empty string.
|
||||||
|
*
|
||||||
|
* @param prefix must be not null (or IllegalArgumentException is thrown)
|
||||||
|
* @param namespace must be not null
|
||||||
|
*/
|
||||||
|
void setPrefix (String prefix, String namespace)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return namespace that corresponds to given prefix
|
||||||
|
* If there is no prefix bound to this namespace return null
|
||||||
|
* but if generatePrefix is false then return generated prefix.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> if the prefix is empty string "" and default namespace is bound
|
||||||
|
* to this prefix then empty string ("") is returned.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
|
||||||
|
* will have values as defined
|
||||||
|
* <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a>
|
||||||
|
*/
|
||||||
|
String getPrefix (String namespace, boolean generatePrefix)
|
||||||
|
throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current depth of the element.
|
||||||
|
* Outside the root element, the depth is 0. The
|
||||||
|
* depth is incremented by 1 when startTag() is called.
|
||||||
|
* The depth is decremented after the call to endTag()
|
||||||
|
* event was observed.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <!-- outside --> 0
|
||||||
|
* <root> 1
|
||||||
|
* sometext 1
|
||||||
|
* <foobar> 2
|
||||||
|
* </foobar> 2
|
||||||
|
* </root> 1
|
||||||
|
* <!-- outside --> 0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
int getDepth();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the namespace URI of the current element as set by startTag().
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> that means in particular that: <ul>
|
||||||
|
* <li>if there was startTag("", ...) then getNamespace() returns ""
|
||||||
|
* <li>if there was startTag(null, ...) then getNamespace() returns null
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return namespace set by startTag() that is currently in scope
|
||||||
|
*/
|
||||||
|
String getNamespace ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the current element as set by startTag().
|
||||||
|
* It can only be null before first call to startTag()
|
||||||
|
* or when last endTag() is called to close first startTag().
|
||||||
|
*
|
||||||
|
* @return namespace set by startTag() that is currently in scope
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a start tag with the given namespace and name.
|
||||||
|
* If there is no prefix defined for the given namespace,
|
||||||
|
* a prefix will be defined automatically.
|
||||||
|
* The explicit prefixes for namespaces can be established by calling setPrefix()
|
||||||
|
* immediately before this method.
|
||||||
|
* If namespace is null no namespace prefix is printed but just name.
|
||||||
|
* If namespace is empty string then serializer will make sure that
|
||||||
|
* default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
* or throw IllegalStateException if default namespace is already bound
|
||||||
|
* to non-empty string.
|
||||||
|
*/
|
||||||
|
XmlSerializer startTag (String namespace, String name)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an attribute. Calls to attribute() MUST follow a call to
|
||||||
|
* startTag() immediately. If there is no prefix defined for the
|
||||||
|
* given namespace, a prefix will be defined automatically.
|
||||||
|
* If namespace is null or empty string
|
||||||
|
* no namespace prefix is printed but just name.
|
||||||
|
*/
|
||||||
|
XmlSerializer attribute (String namespace, String name, String value)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write end tag. Repetition of namespace and name is just for avoiding errors.
|
||||||
|
* <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
|
||||||
|
* very difficult to find...
|
||||||
|
* If namespace is null no namespace prefix is printed but just name.
|
||||||
|
* If namespace is empty string then serializer will make sure that
|
||||||
|
* default empty namespace is declared (in XML 1.0 xmlns='').
|
||||||
|
*/
|
||||||
|
XmlSerializer endTag (String namespace, String name)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Writes a start tag with the given namespace and name.
|
||||||
|
// * <br />If there is no prefix defined (prefix == null) for the given namespace,
|
||||||
|
// * a prefix will be defined automatically.
|
||||||
|
// * <br />If explicit prefixes is passed (prefix != null) then it will be used
|
||||||
|
// *and namespace declared if not already declared or
|
||||||
|
// * throw IllegalStateException the same prefix was already set on this
|
||||||
|
// * element (setPrefix()) and was bound to different namespace.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
// * or throw IllegalStateException if default namespace is already bound
|
||||||
|
// * to non-empty string.
|
||||||
|
// */
|
||||||
|
// XmlSerializer startTag (String prefix, String namespace, String name)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Write an attribute. Calls to attribute() MUST follow a call to
|
||||||
|
// * startTag() immediately.
|
||||||
|
// * <br />If there is no prefix defined (prefix == null) for the given namespace,
|
||||||
|
// * a prefix will be defined automatically.
|
||||||
|
// * <br />If explicit prefixes is passed (prefix != null) then it will be used
|
||||||
|
// * and namespace declared if not already declared or
|
||||||
|
// * throw IllegalStateException the same prefix was already set on this
|
||||||
|
// * element (setPrefix()) and was bound to different namespace.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
// * or throw IllegalStateException if default namespace is already bound
|
||||||
|
// * to non-empty string.
|
||||||
|
// */
|
||||||
|
// XmlSerializer attribute (String prefix, String namespace, String name, String value)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors.
|
||||||
|
// * <br />If namespace or name arguments are different from corresponding startTag call
|
||||||
|
// * then IllegalArgumentException is thrown, if prefix argument is not null and is different
|
||||||
|
// * from corresponding starTag then IllegalArgumentException is thrown.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='').
|
||||||
|
// * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
|
||||||
|
// * very difficult to find...</p>
|
||||||
|
// */
|
||||||
|
// ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking
|
||||||
|
// XmlSerializer endTag (String prefix, String namespace, String name)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes text, where special XML chars are escaped automatically
|
||||||
|
*/
|
||||||
|
XmlSerializer text (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes text, where special XML chars are escaped automatically
|
||||||
|
*/
|
||||||
|
XmlSerializer text (char [] buf, int start, int len)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
void cdsect (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void entityRef (String text) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException;
|
||||||
|
void processingInstruction (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void comment (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void docdecl (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void ignorableWhitespace (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write all pending output to the stream.
|
||||||
|
* If method startTag() or attribute() was called then start tag is closed (final >)
|
||||||
|
* before flush() is called on underlying output stream.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> if there is need to close start tag
|
||||||
|
* (so no more attribute() calls are allowed) but without flushing output
|
||||||
|
* call method text() with empty string (text("")).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void flush ()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ apply plugin: 'java-library'
|
|||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api 'net.sf.kxml:kxml2:2.3.0'
|
||||||
api "org.slf4j:slf4j-api:$slf4jVersion"
|
api "org.slf4j:slf4j-api:$slf4jVersion"
|
||||||
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
|
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 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).
|
||||||
@@ -59,6 +59,11 @@ public abstract class CanvasAdapter {
|
|||||||
*/
|
*/
|
||||||
public static Platform platform = Platform.UNKNOWN;
|
public static Platform platform = Platform.UNKNOWN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The symbol scale.
|
||||||
|
*/
|
||||||
|
public static float symbolScale = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text scale.
|
* The text scale.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -254,8 +254,8 @@ public final class Color {
|
|||||||
* exception. Supported formats are:
|
* exception. Supported formats are:
|
||||||
* #RRGGBB
|
* #RRGGBB
|
||||||
* #AARRGGBB
|
* #AARRGGBB
|
||||||
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
|
* rgb(r, g, b)
|
||||||
* 'yellow', 'lightgray', 'darkgray'
|
* rgba(r, g, b, a)
|
||||||
*
|
*
|
||||||
* @param colorString the color string
|
* @param colorString the color string
|
||||||
* @return the int
|
* @return the int
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class JobQueue {
|
|||||||
if (t.state(LOADING | CANCEL)) {
|
if (t.state(LOADING | CANCEL)) {
|
||||||
t.setState(NONE);
|
t.setState(NONE);
|
||||||
} else {
|
} else {
|
||||||
log.error("Wrong tile in queue {} {}", t, t.state());
|
log.debug("Wrong tile in queue {} {}", t, t.state());
|
||||||
}
|
}
|
||||||
tiles[i] = null;
|
tiles[i] = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 Andrey Novikov
|
* Copyright 2016 Andrey Novikov
|
||||||
|
* Copyright 2020 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -22,16 +23,10 @@ import org.oscim.event.Event;
|
|||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.map.Map.UpdateListener;
|
import org.oscim.map.Map.UpdateListener;
|
||||||
import org.slf4j.Logger;
|
import org.oscim.tiling.TileSource;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO - add a TileLayer.Builder
|
|
||||||
*/
|
|
||||||
public abstract class TileLayer extends Layer implements UpdateListener {
|
public abstract class TileLayer extends Layer implements UpdateListener {
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(TileLayer.class);
|
|
||||||
|
|
||||||
private int mNumLoaders = 4;
|
private int mNumLoaders = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +37,8 @@ public abstract class TileLayer extends Layer implements UpdateListener {
|
|||||||
|
|
||||||
protected TileLoader[] mTileLoader;
|
protected TileLoader[] mTileLoader;
|
||||||
|
|
||||||
|
protected TileSource mTileSource;
|
||||||
|
|
||||||
public TileLayer(Map map, TileManager tileManager, TileRenderer renderer) {
|
public TileLayer(Map map, TileManager tileManager, TileRenderer renderer) {
|
||||||
super(map);
|
super(map);
|
||||||
renderer.setTileManager(tileManager);
|
renderer.setTileManager(tileManager);
|
||||||
@@ -116,6 +113,8 @@ public abstract class TileLayer extends Layer implements UpdateListener {
|
|||||||
loader.finish();
|
loader.finish();
|
||||||
loader.dispose();
|
loader.dispose();
|
||||||
}
|
}
|
||||||
|
if (mTileSource != null)
|
||||||
|
mTileSource.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyLoaders() {
|
void notifyLoaders() {
|
||||||
@@ -148,4 +147,8 @@ public abstract class TileLayer extends Layer implements UpdateListener {
|
|||||||
public TileManager getManager() {
|
public TileManager getManager() {
|
||||||
return mTileManager;
|
return mTileManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TileSource getTileSource() {
|
||||||
|
return mTileSource;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
* Copyright 2017-2018 devemux86
|
* Copyright 2017-2020 devemux86
|
||||||
* Copyright 2019 Gustl22
|
* Copyright 2019 Gustl22
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@@ -38,8 +38,6 @@ public class BitmapTileLayer extends TileLayer {
|
|||||||
|
|
||||||
private static final int CACHE_LIMIT = 40;
|
private static final int CACHE_LIMIT = 40;
|
||||||
|
|
||||||
protected final TileSource mTileSource;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bitmap alpha in range 0 to 1.
|
* Bitmap alpha in range 0 to 1.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
* Copyright 2020 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -34,8 +35,6 @@ public class S3DBTileLayer extends TileLayer {
|
|||||||
private static final int MIN_ZOOM = 16;
|
private static final int MIN_ZOOM = 16;
|
||||||
private static final int MAX_ZOOM = 16;
|
private static final int MAX_ZOOM = 16;
|
||||||
|
|
||||||
private final TileSource mTileSource;
|
|
||||||
|
|
||||||
public S3DBTileLayer(Map map, TileSource tileSource) {
|
public S3DBTileLayer(Map map, TileSource tileSource) {
|
||||||
this(map, tileSource, true, false);
|
this(map, tileSource, true, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.oscim.core.Tag;
|
|||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.layers.tile.TileLoader;
|
import org.oscim.layers.tile.TileLoader;
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.tiling.TileSource;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.utils.Utils;
|
||||||
|
|
||||||
public class OsmTileLayer extends VectorTileLayer {
|
public class OsmTileLayer extends VectorTileLayer {
|
||||||
@@ -36,6 +37,12 @@ public class OsmTileLayer extends VectorTileLayer {
|
|||||||
mTileManager.setZoomLevel(zoomMin, zoomMax);
|
mTileManager.setZoomLevel(zoomMin, zoomMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OsmTileLayer(Map map, TileSource tileSource) {
|
||||||
|
this(map);
|
||||||
|
|
||||||
|
setTileSource(tileSource);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TileLoader createLoader() {
|
protected TileLoader createLoader() {
|
||||||
return new OsmTileLoader(this);
|
return new OsmTileLoader(this);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 Longri
|
* Copyright 2016 Longri
|
||||||
|
* Copyright 2020 devemux86
|
||||||
*
|
*
|
||||||
* 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,11 +19,7 @@
|
|||||||
package org.oscim.layers.tile.vector;
|
package org.oscim.layers.tile.vector;
|
||||||
|
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.*;
|
||||||
import org.oscim.layers.tile.TileLayer;
|
|
||||||
import org.oscim.layers.tile.TileLoader;
|
|
||||||
import org.oscim.layers.tile.TileManager;
|
|
||||||
import org.oscim.layers.tile.VectorTileRenderer;
|
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.bucket.RenderBuckets;
|
import org.oscim.renderer.bucket.RenderBuckets;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
@@ -42,7 +39,11 @@ import org.slf4j.LoggerFactory;
|
|||||||
public class VectorTileLayer extends TileLayer {
|
public class VectorTileLayer extends TileLayer {
|
||||||
static final Logger log = LoggerFactory.getLogger(VectorTileLayer.class);
|
static final Logger log = LoggerFactory.getLogger(VectorTileLayer.class);
|
||||||
|
|
||||||
protected TileSource mTileSource;
|
private final List<LList<TileLoaderProcessHook>> mLoaderProcessHooks = new List<>();
|
||||||
|
|
||||||
|
private final List<LList<TileLoaderThemeHook>> mLoaderThemeHooks = new List<>();
|
||||||
|
|
||||||
|
private IRenderTheme mTheme;
|
||||||
|
|
||||||
public VectorTileLayer(Map map, TileSource tileSource) {
|
public VectorTileLayer(Map map, TileSource tileSource) {
|
||||||
this(map, new TileManager(map,
|
this(map, new TileManager(map,
|
||||||
@@ -104,14 +105,18 @@ public class VectorTileLayer extends TileLayer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileSource getTileSource() {
|
/**
|
||||||
return mTileSource;
|
* Set {@link IRenderTheme} used by {@link TileLoader}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setRenderTheme(IRenderTheme theme) {
|
||||||
|
setTheme(theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set {@link IRenderTheme} used by {@link TileLoader}
|
* Set {@link IRenderTheme} used by {@link TileLoader}
|
||||||
*/
|
*/
|
||||||
public void setRenderTheme(IRenderTheme theme) {
|
public void setTheme(IRenderTheme theme) {
|
||||||
/* wait for loaders to finish all current jobs to
|
/* wait for loaders to finish all current jobs to
|
||||||
* not change theme instance hold by loader instance
|
* not change theme instance hold by loader instance
|
||||||
* while running */
|
* while running */
|
||||||
@@ -127,8 +132,6 @@ public class VectorTileLayer extends TileLayer {
|
|||||||
resumeLoaders();
|
resumeLoaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRenderTheme mTheme;
|
|
||||||
|
|
||||||
public IRenderTheme getTheme() {
|
public IRenderTheme getTheme() {
|
||||||
return mTheme;
|
return mTheme;
|
||||||
}
|
}
|
||||||
@@ -164,12 +167,6 @@ public class VectorTileLayer extends TileLayer {
|
|||||||
public void complete(MapTile tile, boolean success);
|
public void complete(MapTile tile, boolean success);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LList<TileLoaderProcessHook>> mLoaderProcessHooks =
|
|
||||||
new List<LList<TileLoaderProcessHook>>();
|
|
||||||
|
|
||||||
private List<LList<TileLoaderThemeHook>> mLoaderThemeHooks =
|
|
||||||
new List<LList<TileLoaderThemeHook>>();
|
|
||||||
|
|
||||||
public void addHook(TileLoaderProcessHook h) {
|
public void addHook(TileLoaderProcessHook h) {
|
||||||
mLoaderProcessHooks.append(new LList<TileLoaderProcessHook>(h));
|
mLoaderProcessHooks.append(new LList<TileLoaderProcessHook>(h));
|
||||||
}
|
}
|
||||||
@@ -178,13 +175,6 @@ public class VectorTileLayer extends TileLayer {
|
|||||||
mLoaderThemeHooks.append(new LList<TileLoaderThemeHook>(h));
|
mLoaderThemeHooks.append(new LList<TileLoaderThemeHook>(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetach() {
|
|
||||||
super.onDetach();
|
|
||||||
if (mTileSource != null)
|
|
||||||
mTileSource.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void callThemeHooks(MapTile tile, RenderBuckets layers, MapElement element,
|
public void callThemeHooks(MapTile tile, RenderBuckets layers, MapElement element,
|
||||||
RenderStyle style, int level) {
|
RenderStyle style, int level) {
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 Andrey Novikov
|
* Copyright 2016 Andrey Novikov
|
||||||
* Copyright 2016 Stephan Leuschner
|
* Copyright 2016 Stephan Leuschner
|
||||||
* Copyright 2016-2019 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2016 Longri
|
* Copyright 2016 Longri
|
||||||
* Copyright 2018 Gustl22
|
* Copyright 2018 Gustl22
|
||||||
*
|
*
|
||||||
@@ -24,11 +24,7 @@ package org.oscim.map;
|
|||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.Box;
|
import org.oscim.core.Box;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.event.Event;
|
import org.oscim.event.*;
|
||||||
import org.oscim.event.EventDispatcher;
|
|
||||||
import org.oscim.event.EventListener;
|
|
||||||
import org.oscim.event.Gesture;
|
|
||||||
import org.oscim.event.MotionEvent;
|
|
||||||
import org.oscim.layers.AbstractMapEventLayer;
|
import org.oscim.layers.AbstractMapEventLayer;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.layers.MapEventLayer;
|
import org.oscim.layers.MapEventLayer;
|
||||||
@@ -189,16 +185,18 @@ public abstract class Map implements TaskQueue {
|
|||||||
* Utility function to set theme of base vector-layer and
|
* Utility function to set theme of base vector-layer and
|
||||||
* use map background color from theme.
|
* use map background color from theme.
|
||||||
*/
|
*/
|
||||||
public void setTheme(ThemeFile theme) {
|
public IRenderTheme setTheme(ThemeFile theme) {
|
||||||
setTheme(theme, false);
|
return setTheme(theme, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to set theme of base vector-layer, optionally
|
* Utility function to set theme of base vector-layer, optionally
|
||||||
* to all vector layers and use map background color from theme.
|
* to all vector layers and use map background color from theme.
|
||||||
*/
|
*/
|
||||||
public void setTheme(ThemeFile theme, boolean allLayers) {
|
public IRenderTheme setTheme(ThemeFile theme, boolean allLayers) {
|
||||||
setTheme(ThemeLoader.load(theme), allLayers);
|
IRenderTheme renderTheme = ThemeLoader.load(theme);
|
||||||
|
setTheme(renderTheme, allLayers);
|
||||||
|
return renderTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTheme(IRenderTheme theme) {
|
public void setTheme(IRenderTheme theme) {
|
||||||
@@ -213,7 +211,7 @@ public abstract class Map implements TaskQueue {
|
|||||||
boolean themeSet = false;
|
boolean themeSet = false;
|
||||||
for (Layer layer : mLayers) {
|
for (Layer layer : mLayers) {
|
||||||
if (layer instanceof VectorTileLayer) {
|
if (layer instanceof VectorTileLayer) {
|
||||||
((VectorTileLayer) layer).setRenderTheme(theme);
|
((VectorTileLayer) layer).setTheme(theme);
|
||||||
themeSet = true;
|
themeSet = true;
|
||||||
if (!allLayers)
|
if (!allLayers)
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2017-2018 devemux86
|
* Copyright 2017-2020 devemux86
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@@ -17,7 +17,6 @@ package org.oscim.theme;
|
|||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.Platform;
|
import org.oscim.backend.Platform;
|
||||||
import org.oscim.backend.XMLReaderAdapter;
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas;
|
import org.oscim.renderer.atlas.TextureAtlas;
|
||||||
import org.oscim.renderer.atlas.TextureRegion;
|
import org.oscim.renderer.atlas.TextureRegion;
|
||||||
@@ -26,8 +25,11 @@ import org.oscim.theme.rule.Rule;
|
|||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.theme.styles.SymbolStyle;
|
import org.oscim.theme.styles.SymbolStyle;
|
||||||
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
import org.oscim.utils.TextureAtlasUtils;
|
import org.oscim.utils.TextureAtlasUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -51,20 +53,23 @@ public class XmlAtlasThemeBuilder extends XmlThemeBuilder {
|
|||||||
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
||||||
*/
|
*/
|
||||||
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
||||||
Map<Object, TextureRegion> outputMap = new HashMap<>();
|
InputStream inputStream = null;
|
||||||
List<TextureAtlas> atlasList = new ArrayList<>();
|
|
||||||
XmlAtlasThemeBuilder renderThemeHandler = new XmlAtlasThemeBuilder(theme, themeCallback, outputMap, atlasList);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new XMLReaderAdapter().parse(renderThemeHandler, theme.getRenderThemeAsStream());
|
XmlPullParser pullParser = getXmlPullParserFactory().newPullParser();
|
||||||
|
Map<Object, TextureRegion> outputMap = new HashMap<>();
|
||||||
|
List<TextureAtlas> atlasList = new ArrayList<>();
|
||||||
|
XmlAtlasThemeBuilder renderThemeHandler = new XmlAtlasThemeBuilder(theme, pullParser, themeCallback, outputMap, atlasList);
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
pullParser.setInput(inputStream, null);
|
||||||
|
renderThemeHandler.processRenderTheme();
|
||||||
|
TextureAtlasUtils.createTextureRegions(renderThemeHandler.bitmapMap, outputMap, atlasList,
|
||||||
|
true, CanvasAdapter.platform == Platform.IOS);
|
||||||
|
return replaceThemeSymbols(renderThemeHandler.mRenderTheme, outputMap);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureAtlasUtils.createTextureRegions(renderThemeHandler.bitmapMap, outputMap, atlasList,
|
|
||||||
true, CanvasAdapter.platform == Platform.IOS);
|
|
||||||
|
|
||||||
return replaceThemeSymbols(renderThemeHandler.mRenderTheme, outputMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRenderTheme replaceThemeSymbols(RenderTheme renderTheme, Map<Object, TextureRegion> regionMap) {
|
private static IRenderTheme replaceThemeSymbols(RenderTheme renderTheme, Map<Object, TextureRegion> regionMap) {
|
||||||
@@ -98,14 +103,14 @@ public class XmlAtlasThemeBuilder extends XmlThemeBuilder {
|
|||||||
|
|
||||||
private final Map<Object, Bitmap> bitmapMap = new HashMap<>();
|
private final Map<Object, Bitmap> bitmapMap = new HashMap<>();
|
||||||
|
|
||||||
public XmlAtlasThemeBuilder(ThemeFile theme,
|
public XmlAtlasThemeBuilder(ThemeFile theme, XmlPullParser pullParser,
|
||||||
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
||||||
this(theme, null, regionMap, atlasList);
|
this(theme, pullParser, null, regionMap, atlasList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlAtlasThemeBuilder(ThemeFile theme, ThemeCallback themeCallback,
|
public XmlAtlasThemeBuilder(ThemeFile theme, XmlPullParser pullParser, ThemeCallback themeCallback,
|
||||||
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
||||||
super(theme, themeCallback);
|
super(theme, pullParser, themeCallback);
|
||||||
this.regionMap = regionMap;
|
this.regionMap = regionMap;
|
||||||
this.atlasList = atlasList;
|
this.atlasList = atlasList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2019 devemux86
|
* Copyright 2014 Ludwig M Brinckmann
|
||||||
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2016-2017 Longri
|
* Copyright 2016-2017 Longri
|
||||||
* Copyright 2016-2020 Andrey Novikov
|
* Copyright 2016-2020 Andrey Novikov
|
||||||
* Copyright 2018-2019 Gustl22
|
* Copyright 2018-2019 Gustl22
|
||||||
@@ -24,7 +25,6 @@
|
|||||||
package org.oscim.theme;
|
package org.oscim.theme;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
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;
|
||||||
@@ -49,27 +49,26 @@ import org.oscim.theme.styles.LineStyle.LineBuilder;
|
|||||||
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
||||||
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
|
import org.oscim.utils.Parameters;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.utils.Utils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.Attributes;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xml.sax.SAXException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xmlpull.v1.XmlPullParserFactory;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
public class XmlThemeBuilder {
|
||||||
import static java.lang.Float.parseFloat;
|
|
||||||
import static java.lang.Integer.parseInt;
|
|
||||||
|
|
||||||
public class XmlThemeBuilder extends DefaultHandler {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
|
||||||
|
|
||||||
private static final int RENDER_THEME_VERSION_MAPSFORGE = 6;
|
private static final int RENDER_THEME_VERSION_MAPSFORGE = 6;
|
||||||
private static final int RENDER_THEME_VERSION_VTM = 1;
|
private static final int RENDER_THEME_VERSION_VTM = 1;
|
||||||
|
private static XmlPullParserFactory xmlPullParserFactory = null;
|
||||||
|
|
||||||
private enum Element {
|
private enum Element {
|
||||||
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RECT, RENDERING_STYLE, TAG_TRANSFORM
|
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RECT, RENDERING_STYLE, TAG_TRANSFORM
|
||||||
@@ -109,15 +108,30 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
||||||
*/
|
*/
|
||||||
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
||||||
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme, themeCallback);
|
InputStream inputStream = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new XMLReaderAdapter().parse(renderThemeHandler, theme.getRenderThemeAsStream());
|
XmlPullParser pullParser = getXmlPullParserFactory().newPullParser();
|
||||||
|
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme, pullParser, themeCallback);
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
pullParser.setInput(inputStream, null);
|
||||||
|
renderThemeHandler.processRenderTheme();
|
||||||
|
return renderThemeHandler.mRenderTheme;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return renderThemeHandler.mRenderTheme;
|
public static XmlPullParserFactory getXmlPullParserFactory() throws XmlPullParserException {
|
||||||
|
if (xmlPullParserFactory == null) {
|
||||||
|
xmlPullParserFactory = XmlPullParserFactory.newInstance();
|
||||||
|
}
|
||||||
|
return xmlPullParserFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setXmlPullParserFactory(XmlPullParserFactory xmlPullParserFactory) {
|
||||||
|
XmlThemeBuilder.xmlPullParserFactory = xmlPullParserFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,19 +142,17 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param value the XML attribute value.
|
* @param value the XML attribute value.
|
||||||
* @param attributeIndex the XML attribute index position.
|
* @param attributeIndex the XML attribute index position.
|
||||||
*/
|
*/
|
||||||
private static void logUnknownAttribute(String element, String name,
|
private static void logUnknownAttribute(String element, String name, String value, int attributeIndex) {
|
||||||
String value, int attributeIndex) {
|
log.debug("unknown attribute in element {} {} : {} = {}", element, attributeIndex, name, value);
|
||||||
log.debug("unknown attribute in element {} () : {} = {}",
|
|
||||||
element, attributeIndex, name, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<>();
|
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<>();
|
||||||
private final Stack<Element> mElementStack = new Stack<>();
|
private final Stack<Element> mElementStack = new Stack<>();
|
||||||
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 Map<String, RenderStyle<?>> mStyles = new HashMap<>(10);
|
||||||
|
|
||||||
private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
private final Map<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
||||||
private final HashMap<String, SymbolStyle.SymbolBuilder<?>> mSymbolStyles = new HashMap<>(10);
|
private final Map<String, SymbolStyle.SymbolBuilder<?>> mSymbolStyles = 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();
|
||||||
@@ -157,6 +169,8 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
private float mStrokeScale = 1;
|
private float mStrokeScale = 1;
|
||||||
float mTextScale = 1;
|
float mTextScale = 1;
|
||||||
|
|
||||||
|
private final XmlPullParser mPullParser;
|
||||||
|
private String qName;
|
||||||
final ThemeFile mTheme;
|
final ThemeFile mTheme;
|
||||||
private final ThemeCallback mThemeCallback;
|
private final ThemeCallback mThemeCallback;
|
||||||
RenderTheme mRenderTheme;
|
RenderTheme mRenderTheme;
|
||||||
@@ -168,21 +182,38 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
private XmlRenderThemeStyleLayer mCurrentLayer;
|
private XmlRenderThemeStyleLayer mCurrentLayer;
|
||||||
private XmlRenderThemeStyleMenu mRenderThemeStyleMenu;
|
private XmlRenderThemeStyleMenu mRenderThemeStyleMenu;
|
||||||
|
|
||||||
private Map<String, String> mTransformKeyMap = new HashMap<>();
|
private final Map<String, String> mTransformKeyMap = new HashMap<>();
|
||||||
private Map<Tag, Tag> mTransformTagMap = new HashMap<>();
|
private final Map<Tag, Tag> mTransformTagMap = new HashMap<>();
|
||||||
|
|
||||||
public XmlThemeBuilder(ThemeFile theme) {
|
public XmlThemeBuilder(ThemeFile theme, XmlPullParser pullParser) {
|
||||||
this(theme, null);
|
this(theme, pullParser, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlThemeBuilder(ThemeFile theme, ThemeCallback themeCallback) {
|
public XmlThemeBuilder(ThemeFile theme, XmlPullParser pullParser, ThemeCallback themeCallback) {
|
||||||
mTheme = theme;
|
mTheme = theme;
|
||||||
|
mPullParser = pullParser;
|
||||||
mThemeCallback = themeCallback;
|
mThemeCallback = themeCallback;
|
||||||
mMapsforgeTheme = theme.isMapsforgeTheme();
|
mMapsforgeTheme = theme.isMapsforgeTheme();
|
||||||
mScale = CanvasAdapter.getScale();
|
mScale = CanvasAdapter.getScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void processRenderTheme() throws XmlPullParserException, IOException {
|
||||||
|
int eventType = mPullParser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == XmlPullParser.START_DOCUMENT) {
|
||||||
|
// no-op
|
||||||
|
} else if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
startElement();
|
||||||
|
} else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
endElement();
|
||||||
|
} else if (eventType == XmlPullParser.TEXT) {
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
|
eventType = mPullParser.next();
|
||||||
|
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
|
endDocument();
|
||||||
|
}
|
||||||
|
|
||||||
public void endDocument() {
|
public void endDocument() {
|
||||||
if (mMapsforgeTheme) {
|
if (mMapsforgeTheme) {
|
||||||
// Building rule for Mapsforge themes
|
// Building rule for Mapsforge themes
|
||||||
@@ -209,11 +240,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
|
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void endElement() {
|
||||||
public void endElement(String uri, String localName, String qName) {
|
qName = mPullParser.getName();
|
||||||
|
|
||||||
mElementStack.pop();
|
mElementStack.pop();
|
||||||
|
|
||||||
if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(localName) || ELEMENT_NAME_MATCH_VTM.equals(localName)) {
|
if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(qName) || ELEMENT_NAME_MATCH_VTM.equals(qName)) {
|
||||||
mRuleStack.pop();
|
mRuleStack.pop();
|
||||||
if (mRuleStack.empty()) {
|
if (mRuleStack.empty()) {
|
||||||
if (isVisible(mCurrentRule)) {
|
if (isVisible(mCurrentRule)) {
|
||||||
@@ -222,7 +254,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
} else {
|
} else {
|
||||||
mCurrentRule = mRuleStack.peek();
|
mCurrentRule = mRuleStack.peek();
|
||||||
}
|
}
|
||||||
} else if (ELEMENT_NAME_STYLE_MENU.equals(localName)) {
|
} else if (ELEMENT_NAME_STYLE_MENU.equals(qName)) {
|
||||||
// when we are finished parsing the menu part of the file, we can get the
|
// when we are finished parsing the menu part of the file, we can get the
|
||||||
// categories to render from the initiator. This allows the creating action
|
// categories to render from the initiator. This allows the creating action
|
||||||
// to select which of the menu options to choose
|
// to select which of the menu options to choose
|
||||||
@@ -233,118 +265,108 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void startElement() throws ThemeException {
|
||||||
public void error(SAXParseException exception) {
|
qName = mPullParser.getName();
|
||||||
log.debug(exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void warning(SAXParseException exception) {
|
|
||||||
log.debug(exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startElement(String uri, String localName, String qName,
|
|
||||||
Attributes attributes) throws ThemeException {
|
|
||||||
try {
|
try {
|
||||||
if (ELEMENT_NAME_RENDER_THEME.equals(localName)) {
|
if (ELEMENT_NAME_RENDER_THEME.equals(qName)) {
|
||||||
checkState(localName, Element.RENDER_THEME);
|
checkState(qName, Element.RENDER_THEME);
|
||||||
createRenderTheme(localName, attributes);
|
createRenderTheme(qName);
|
||||||
|
|
||||||
} else if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(localName) || ELEMENT_NAME_MATCH_VTM.equals(localName)) {
|
} else if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(qName) || ELEMENT_NAME_MATCH_VTM.equals(qName)) {
|
||||||
checkState(localName, Element.RULE);
|
checkState(qName, Element.RULE);
|
||||||
RuleBuilder rule = createRule(localName, attributes);
|
RuleBuilder rule = createRule(qName);
|
||||||
if (!mRuleStack.empty() && isVisible(rule)) {
|
if (!mRuleStack.empty() && isVisible(rule)) {
|
||||||
mCurrentRule.addSubRule(rule);
|
mCurrentRule.addSubRule(rule);
|
||||||
}
|
}
|
||||||
mCurrentRule = rule;
|
mCurrentRule = rule;
|
||||||
mRuleStack.push(mCurrentRule);
|
mRuleStack.push(mCurrentRule);
|
||||||
|
|
||||||
} else if ("style-text".equals(localName)) {
|
} else if ("style-text".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleTextElement(localName, attributes, true, false);
|
handleTextElement(qName, true, false);
|
||||||
|
|
||||||
} else if ("style-symbol".equals(localName)) {
|
} else if ("style-symbol".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleSymbolElement(localName, attributes, true);
|
handleSymbolElement(qName, true);
|
||||||
|
|
||||||
} else if ("style-area".equals(localName)) {
|
} else if ("style-area".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleAreaElement(localName, attributes, true);
|
handleAreaElement(qName, true);
|
||||||
|
|
||||||
} else if ("style-line".equals(localName)) {
|
} else if ("style-line".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleLineElement(localName, attributes, true, false);
|
handleLineElement(qName, true, false);
|
||||||
|
|
||||||
} else if ("outline-layer".equals(localName)) {
|
} else if ("outline-layer".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
LineStyle line = createLine(null, localName, attributes, mLevels++, true, false);
|
LineStyle line = createLine(null, qName, mLevels++, true, false);
|
||||||
mStyles.put(OUTLINE_STYLE + line.style, line);
|
mStyles.put(OUTLINE_STYLE + line.style, line);
|
||||||
|
|
||||||
} else if ("area".equals(localName)) {
|
} else if ("area".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleAreaElement(localName, attributes, false);
|
handleAreaElement(qName, false);
|
||||||
|
|
||||||
} else if ("caption".equals(localName)) {
|
} else if ("caption".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleTextElement(localName, attributes, false, true);
|
handleTextElement(qName, false, true);
|
||||||
|
|
||||||
} else if ("circle".equals(localName)) {
|
} else if ("circle".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
CircleStyle circle = createCircle(localName, attributes, mLevels++);
|
CircleStyle circle = createCircle(qName, mLevels++);
|
||||||
if (isVisible(circle))
|
if (isVisible(circle))
|
||||||
mCurrentRule.addStyle(circle);
|
mCurrentRule.addStyle(circle);
|
||||||
|
|
||||||
} else if ("line".equals(localName)) {
|
} else if ("line".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleLineElement(localName, attributes, false, false);
|
handleLineElement(qName, false, false);
|
||||||
|
|
||||||
} else if ("text".equals(localName) || "pathText".equals(localName)) {
|
} else if ("text".equals(qName) || "pathText".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleTextElement(localName, attributes, false, false);
|
handleTextElement(qName, false, false);
|
||||||
|
|
||||||
} else if ("symbol".equals(localName)) {
|
} else if ("symbol".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleSymbolElement(localName, attributes, false);
|
handleSymbolElement(qName, false);
|
||||||
|
|
||||||
} else if ("outline".equals(localName)) {
|
} else if ("outline".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
LineStyle outline = createOutline(attributes.getValue("use"), attributes);
|
LineStyle outline = createOutline(getStringAttribute("use"));
|
||||||
if (outline != null && isVisible(outline))
|
if (outline != null && isVisible(outline))
|
||||||
mCurrentRule.addStyle(outline);
|
mCurrentRule.addStyle(outline);
|
||||||
|
|
||||||
} else if ("extrusion".equals(localName)) {
|
} else if ("extrusion".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
ExtrusionStyle extrusion = createExtrusion(localName, attributes, mLevels++);
|
ExtrusionStyle extrusion = createExtrusion(qName, mLevels++);
|
||||||
if (isVisible(extrusion))
|
if (isVisible(extrusion))
|
||||||
mCurrentRule.addStyle(extrusion);
|
mCurrentRule.addStyle(extrusion);
|
||||||
|
|
||||||
} else if ("lineSymbol".equals(localName)) {
|
} else if ("lineSymbol".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleLineElement(localName, attributes, false, true);
|
handleLineElement(qName, false, true);
|
||||||
|
|
||||||
} else if ("atlas".equals(localName)) {
|
} else if ("atlas".equals(qName)) {
|
||||||
checkState(localName, Element.ATLAS);
|
checkState(qName, Element.ATLAS);
|
||||||
createAtlas(localName, attributes);
|
createAtlas(qName);
|
||||||
|
|
||||||
} else if ("rect".equals(localName)) {
|
} else if ("rect".equals(qName)) {
|
||||||
checkState(localName, Element.RECT);
|
checkState(qName, Element.RECT);
|
||||||
createTextureRegion(localName, attributes);
|
createTextureRegion(qName);
|
||||||
|
|
||||||
} else if ("cat".equals(localName)) {
|
} else if ("cat".equals(qName)) {
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mCurrentLayer.addCategory(getStringAttribute(attributes, "id"));
|
mCurrentLayer.addCategory(getStringAttribute("id"));
|
||||||
|
|
||||||
} else if ("layer".equals(localName)) {
|
} else if ("layer".equals(qName)) {
|
||||||
// render theme menu layer
|
// render theme menu layer
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
boolean enabled = false;
|
boolean enabled = false;
|
||||||
if (getStringAttribute(attributes, "enabled") != null) {
|
if (getStringAttribute("enabled") != null) {
|
||||||
enabled = Boolean.valueOf(getStringAttribute(attributes, "enabled"));
|
enabled = Boolean.parseBoolean(getStringAttribute("enabled"));
|
||||||
}
|
}
|
||||||
boolean visible = Boolean.valueOf(getStringAttribute(attributes, "visible"));
|
boolean visible = Boolean.parseBoolean(getStringAttribute("visible"));
|
||||||
mCurrentLayer = mRenderThemeStyleMenu.createLayer(getStringAttribute(attributes, "id"), visible, enabled);
|
mCurrentLayer = mRenderThemeStyleMenu.createLayer(getStringAttribute("id"), visible, enabled);
|
||||||
String parent = getStringAttribute(attributes, "parent");
|
String parent = getStringAttribute("parent");
|
||||||
if (null != parent) {
|
if (null != parent) {
|
||||||
XmlRenderThemeStyleLayer parentEntry = mRenderThemeStyleMenu.getLayer(parent);
|
XmlRenderThemeStyleLayer parentEntry = mRenderThemeStyleMenu.getLayer(parent);
|
||||||
if (null != parentEntry) {
|
if (null != parentEntry) {
|
||||||
@@ -357,40 +379,38 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("name".equals(localName)) {
|
} else if ("name".equals(qName)) {
|
||||||
// render theme menu name
|
// render theme menu name
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mCurrentLayer.addTranslation(getStringAttribute(attributes, "lang"), getStringAttribute(attributes, "value"));
|
mCurrentLayer.addTranslation(getStringAttribute("lang"), getStringAttribute("value"));
|
||||||
|
|
||||||
} else if ("overlay".equals(localName)) {
|
} else if ("overlay".equals(qName)) {
|
||||||
// render theme menu overlay
|
// render theme menu overlay
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
XmlRenderThemeStyleLayer overlay = mRenderThemeStyleMenu.getLayer(getStringAttribute(attributes, "id"));
|
XmlRenderThemeStyleLayer overlay = mRenderThemeStyleMenu.getLayer(getStringAttribute("id"));
|
||||||
if (overlay != null) {
|
if (overlay != null) {
|
||||||
mCurrentLayer.addOverlay(overlay);
|
mCurrentLayer.addOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("stylemenu".equals(localName)) {
|
} else if ("stylemenu".equals(qName)) {
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute(attributes, "id"),
|
mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute("id"),
|
||||||
getStringAttribute(attributes, "defaultlang"), getStringAttribute(attributes, "defaultvalue"));
|
getStringAttribute("defaultlang"), getStringAttribute("defaultvalue"));
|
||||||
|
|
||||||
} else if ("tag-transform".equals(localName)) {
|
} else if ("tag-transform".equals(qName)) {
|
||||||
checkState(qName, Element.TAG_TRANSFORM);
|
checkState(qName, Element.TAG_TRANSFORM);
|
||||||
tagTransform(localName, attributes);
|
tagTransform(qName);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.error("unknown element: {}", localName);
|
log.error("unknown element: {}", qName);
|
||||||
throw new SAXException("unknown element: " + localName);
|
throw new XmlPullParserException("unknown element: " + qName);
|
||||||
}
|
}
|
||||||
} catch (SAXException e) {
|
} catch (XmlPullParserException | IOException e) {
|
||||||
throw new ThemeException(e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RuleBuilder createRule(String localName, Attributes attributes) {
|
private RuleBuilder createRule(String qName) {
|
||||||
String cat = null;
|
String cat = null;
|
||||||
int element = Rule.Element.ANY;
|
int element = Rule.Element.ANY;
|
||||||
int closed = Closed.ANY;
|
int closed = Closed.ANY;
|
||||||
@@ -400,9 +420,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
byte zoomMax = Byte.MAX_VALUE;
|
byte zoomMax = Byte.MAX_VALUE;
|
||||||
int selector = 0;
|
int selector = 0;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("e".equals(name)) {
|
if ("e".equals(name)) {
|
||||||
String val = value.toUpperCase(Locale.ENGLISH);
|
String val = value.toUpperCase(Locale.ENGLISH);
|
||||||
@@ -440,7 +460,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 {
|
||||||
logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(qName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,10 +494,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean hasSymbol)
|
private void handleLineElement(String qName, boolean isStyle, boolean hasSymbol) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = getStringAttribute("use");
|
||||||
LineStyle style = null;
|
LineStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
@@ -488,7 +507,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LineStyle line = createLine(style, localName, attributes, mLevels++, false, hasSymbol);
|
LineStyle line = createLine(style, qName, mLevels++, false, hasSymbol);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(LINE_STYLE + line.style, line);
|
mStyles.put(LINE_STYLE + line.style, line);
|
||||||
@@ -497,9 +516,9 @@ 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. */
|
||||||
String outlineValue = attributes.getValue("outline");
|
String outlineValue = getStringAttribute("outline");
|
||||||
if (outlineValue != null) {
|
if (outlineValue != null) {
|
||||||
LineStyle outline = createOutline(outlineValue, attributes);
|
LineStyle outline = createOutline(outlineValue);
|
||||||
if (outline != null)
|
if (outline != null)
|
||||||
mCurrentRule.addStyle(outline);
|
mCurrentRule.addStyle(outline);
|
||||||
}
|
}
|
||||||
@@ -513,17 +532,16 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param isOutline is outline layer
|
* @param isOutline is outline layer
|
||||||
* @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, int level, boolean isOutline, boolean hasSymbol) {
|
||||||
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);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
String src = null;
|
String src = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@@ -544,7 +562,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b.color(value);
|
b.color(value);
|
||||||
|
|
||||||
else if ("width".equals(name) || "stroke-width".equals(name)) {
|
else if ("width".equals(name) || "stroke-width".equals(name)) {
|
||||||
b.strokeWidth = parseFloat(value) * mScale * mStrokeScale;
|
b.strokeWidth = Float.parseFloat(value) * mScale * mStrokeScale;
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
if (!isOutline)
|
if (!isOutline)
|
||||||
validateNonNegative("width", b.strokeWidth);
|
validateNonNegative("width", b.strokeWidth);
|
||||||
@@ -558,16 +576,16 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b.cap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH));
|
b.cap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH));
|
||||||
|
|
||||||
else if ("fix".equals(name))
|
else if ("fix".equals(name))
|
||||||
b.fixed = parseBoolean(value);
|
b.fixed = Boolean.parseBoolean(value);
|
||||||
|
|
||||||
else if ("stipple".equals(name))
|
else if ("stipple".equals(name))
|
||||||
b.stipple = Math.round(parseInt(value) * mScale * mStrokeScale);
|
b.stipple = Math.round(Integer.parseInt(value) * mScale * mStrokeScale);
|
||||||
|
|
||||||
else if ("stipple-stroke".equals(name))
|
else if ("stipple-stroke".equals(name))
|
||||||
b.stippleColor(value);
|
b.stippleColor(value);
|
||||||
|
|
||||||
else if ("stipple-width".equals(name))
|
else if ("stipple-width".equals(name))
|
||||||
b.stippleWidth = parseFloat(value);
|
b.stippleWidth = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("fade".equals(name))
|
else if ("fade".equals(name))
|
||||||
b.fadeScale = Integer.parseInt(value);
|
b.fadeScale = Integer.parseInt(value);
|
||||||
@@ -576,7 +594,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
; //min = Float.parseFloat(value);
|
; //min = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("blur".equals(name))
|
else if ("blur".equals(name))
|
||||||
b.blur = parseFloat(value);
|
b.blur = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("style".equals(name))
|
else if ("style".equals(name))
|
||||||
; // ignore
|
; // ignore
|
||||||
@@ -646,8 +664,10 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b.stippleWidth = 1;
|
b.stippleWidth = 1;
|
||||||
b.stippleColor = b.fillColor;
|
b.stippleColor = b.fillColor;
|
||||||
} else {
|
} else {
|
||||||
if (src != null)
|
if (src != null) {
|
||||||
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
float symbolScale = Parameters.SYMBOL_SCALING == Parameters.SymbolScaling.ALL ? CanvasAdapter.symbolScale : 1;
|
||||||
|
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale));
|
||||||
|
}
|
||||||
|
|
||||||
if (b.texture != null && hasSymbol) {
|
if (b.texture != null && hasSymbol) {
|
||||||
// Line symbol
|
// Line symbol
|
||||||
@@ -671,10 +691,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
|
private void handleAreaElement(String qName, boolean isStyle) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = getStringAttribute("use");
|
||||||
AreaStyle style = null;
|
AreaStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
@@ -685,7 +704,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AreaStyle area = createArea(style, localName, attributes, mLevels++);
|
AreaStyle area = createArea(style, qName, mLevels++);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(AREA_STYLE + area.style, area);
|
mStyles.put(AREA_STYLE + area.style, area);
|
||||||
@@ -698,16 +717,15 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* @return a new Area with the given rendering attributes.
|
* @return a new Area with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private AreaStyle createArea(AreaStyle area, String elementName, Attributes attributes,
|
private AreaStyle createArea(AreaStyle area, String elementName, int level) {
|
||||||
int level) {
|
|
||||||
AreaBuilder<?> b = mAreaBuilder.set(area);
|
AreaBuilder<?> b = mAreaBuilder.set(area);
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
String src = null;
|
String src = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@@ -766,15 +784,15 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LineStyle createOutline(String style, Attributes attributes) {
|
private LineStyle createOutline(String style) {
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
|
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
|
||||||
if (line != null && line.outline) {
|
if (line != null && line.outline) {
|
||||||
String cat = null;
|
String cat = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("cat".equals(name)) {
|
if ("cat".equals(name)) {
|
||||||
cat = value;
|
cat = value;
|
||||||
@@ -790,12 +808,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAtlas(String elementName, Attributes attributes) throws IOException {
|
private void createAtlas(String elementName) throws IOException {
|
||||||
String img = null;
|
String img = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("img".equals(name)) {
|
if ("img".equals(name)) {
|
||||||
img = value;
|
img = value;
|
||||||
@@ -810,16 +828,16 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextureAtlas = new TextureAtlas(bitmap);
|
mTextureAtlas = new TextureAtlas(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTextureRegion(String elementName, Attributes attributes) {
|
private void createTextureRegion(String elementName) {
|
||||||
if (mTextureAtlas == null)
|
if (mTextureAtlas == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String regionName = null;
|
String regionName = null;
|
||||||
Rect r = null;
|
Rect r = null;
|
||||||
|
|
||||||
for (int i = 0, n = attributes.getLength(); i < n; i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name)) {
|
if ("id".equals(name)) {
|
||||||
regionName = value;
|
regionName = value;
|
||||||
@@ -841,12 +859,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkElement(String elementName, Element element) throws SAXException {
|
private void checkElement(String elementName, Element element) throws XmlPullParserException {
|
||||||
Element parentElement;
|
Element parentElement;
|
||||||
switch (element) {
|
switch (element) {
|
||||||
case RENDER_THEME:
|
case RENDER_THEME:
|
||||||
if (!mElementStack.empty()) {
|
if (!mElementStack.empty()) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_STACK_NOT_EMPTY + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_STACK_NOT_EMPTY + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -854,34 +872,34 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME
|
if (parentElement != Element.RENDER_THEME
|
||||||
&& parentElement != Element.RULE) {
|
&& parentElement != Element.RULE) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RULE_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RULE_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case STYLE:
|
case STYLE:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_STYLE_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_STYLE_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RENDERING_INSTRUCTION:
|
case RENDERING_INSTRUCTION:
|
||||||
if (mElementStack.peek() != Element.RULE) {
|
if (mElementStack.peek() != Element.RULE) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RENDERING_INSTRUCTION_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RENDERING_INSTRUCTION_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ATLAS:
|
case ATLAS:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_ATLAS_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_ATLAS_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RECT:
|
case RECT:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.ATLAS) {
|
if (parentElement != Element.ATLAS) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RECT_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RECT_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -891,28 +909,28 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
case TAG_TRANSFORM:
|
case TAG_TRANSFORM:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_TAG_TRANSFORM_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_TAG_TRANSFORM_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SAXException("unknown enum value: " + element);
|
throw new XmlPullParserException("unknown enum value: " + element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkState(String elementName, Element element) throws SAXException {
|
private void checkState(String elementName, Element element) throws XmlPullParserException {
|
||||||
checkElement(elementName, element);
|
checkElement(elementName, element);
|
||||||
mElementStack.push(element);
|
mElementStack.push(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRenderTheme(String elementName, Attributes attributes) {
|
private void createRenderTheme(String elementName) {
|
||||||
Integer version = null;
|
Integer version = null;
|
||||||
int mapBackground = Color.WHITE;
|
int mapBackground = Color.WHITE;
|
||||||
float baseStrokeWidth = 1;
|
float baseStrokeWidth = 1;
|
||||||
float baseTextScale = 1;
|
float baseTextScale = 1;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("schemaLocation".equals(name))
|
if ("schemaLocation".equals(name))
|
||||||
continue;
|
continue;
|
||||||
@@ -950,10 +968,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextScale = baseTextScale;
|
mTextScale = baseTextScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTextElement(String localName, Attributes attributes, boolean isStyle,
|
private void handleTextElement(String qName, boolean isStyle, boolean isCaption) {
|
||||||
boolean isCaption) throws SAXException {
|
|
||||||
|
|
||||||
String style = attributes.getValue("use");
|
String style = getStringAttribute("use");
|
||||||
TextBuilder<?> pt = null;
|
TextBuilder<?> pt = null;
|
||||||
|
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
@@ -964,7 +981,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextBuilder<?> b = createText(localName, attributes, isCaption, pt);
|
TextBuilder<?> b = createText(qName, isCaption, pt);
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
log.debug("put style {}", b.style);
|
log.debug("put style {}", b.style);
|
||||||
mTextStyles.put(b.style, TextStyle.builder().from(b));
|
mTextStyles.put(b.style, TextStyle.builder().from(b));
|
||||||
@@ -979,8 +996,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param caption ...
|
* @param caption ...
|
||||||
* @return a new Text with the given rendering attributes.
|
* @return a new Text with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private TextBuilder<?> createText(String elementName, Attributes attributes,
|
private TextBuilder<?> createText(String elementName, boolean caption, TextBuilder<?> style) {
|
||||||
boolean caption, TextBuilder<?> style) {
|
|
||||||
TextBuilder<?> b;
|
TextBuilder<?> b;
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
b = mTextBuilder.reset();
|
b = mTextBuilder.reset();
|
||||||
@@ -995,9 +1011,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b.priority = DEFAULT_PRIORITY;
|
b.priority = DEFAULT_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@@ -1046,7 +1062,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
|
|
||||||
else if ("dy".equals(name))
|
else if ("dy".equals(name))
|
||||||
// NB: minus..
|
// NB: minus..
|
||||||
b.dy = -Float.parseFloat(value) * mScale;
|
b.dy = -Float.parseFloat(value) * mScale * CanvasAdapter.symbolScale;
|
||||||
|
|
||||||
else if ("symbol".equals(name))
|
else if ("symbol".equals(name))
|
||||||
symbol = value;
|
symbol = value;
|
||||||
@@ -1071,7 +1087,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
if (b.dy == 0) {
|
if (b.dy == 0) {
|
||||||
value = "above".equals(value) ? "20" : "-20";
|
value = "above".equals(value) ? "20" : "-20";
|
||||||
// NB: minus..
|
// NB: minus..
|
||||||
b.dy = -Float.parseFloat(value) * mScale;
|
b.dy = -Float.parseFloat(value) * mScale * CanvasAdapter.symbolScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
@@ -1086,7 +1102,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
String lowValue = symbol.toLowerCase(Locale.ENGLISH);
|
String lowValue = symbol.toLowerCase(Locale.ENGLISH);
|
||||||
if (lowValue.endsWith(".png") || lowValue.endsWith(".svg")) {
|
if (lowValue.endsWith(".png") || lowValue.endsWith(".svg")) {
|
||||||
try {
|
try {
|
||||||
b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), symbol, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), symbol, b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * CanvasAdapter.symbolScale));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("{}: {}", symbol, e.getMessage());
|
log.error("{}: {}", symbol, e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -1101,14 +1117,14 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param level the drawing level of this instruction.
|
* @param level the drawing level of this instruction.
|
||||||
* @return a new Circle with the given rendering attributes.
|
* @return a new Circle with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private CircleStyle createCircle(String elementName, Attributes attributes, int level) {
|
private CircleStyle createCircle(String elementName, int level) {
|
||||||
CircleBuilder<?> b = mCircleBuilder.reset();
|
CircleBuilder<?> b = mCircleBuilder.reset();
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("r".equals(name) || "radius".equals(name))
|
if ("r".equals(name) || "radius".equals(name))
|
||||||
b.radius(Float.parseFloat(value) * mScale * mStrokeScale);
|
b.radius(Float.parseFloat(value) * mScale * mStrokeScale);
|
||||||
@@ -1139,10 +1155,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSymbolElement(String localName, Attributes attributes, boolean isStyle)
|
private void handleSymbolElement(String qName, boolean isStyle) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String style = attributes.getValue("use");
|
String style = getStringAttribute("use");
|
||||||
SymbolBuilder<?> ps = null;
|
SymbolBuilder<?> ps = null;
|
||||||
|
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
@@ -1153,7 +1168,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolBuilder<?> b = createSymbol(localName, attributes, ps);
|
SymbolBuilder<?> b = createSymbol(qName, ps);
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
log.debug("put style {}", b.style);
|
log.debug("put style {}", b.style);
|
||||||
mSymbolStyles.put(b.style, SymbolStyle.builder().from(b));
|
mSymbolStyles.put(b.style, SymbolStyle.builder().from(b));
|
||||||
@@ -1167,8 +1182,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* @return a new Symbol with the given rendering attributes.
|
* @return a new Symbol with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private SymbolBuilder<?> createSymbol(String elementName, Attributes attributes,
|
private SymbolBuilder<?> createSymbol(String elementName, SymbolBuilder<?> style) {
|
||||||
SymbolBuilder<?> style) {
|
|
||||||
SymbolBuilder<?> b;
|
SymbolBuilder<?> b;
|
||||||
if (style == null)
|
if (style == null)
|
||||||
b = mSymbolBuilder.reset();
|
b = mSymbolBuilder.reset();
|
||||||
@@ -1176,9 +1190,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b = mSymbolBuilder.from(style);
|
b = mSymbolBuilder.from(style);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@@ -1232,7 +1246,17 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
String lowSrc = b.src.toLowerCase(Locale.ENGLISH);
|
String lowSrc = b.src.toLowerCase(Locale.ENGLISH);
|
||||||
if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) {
|
if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) {
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), b.src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
float symbolScale = 1;
|
||||||
|
switch (Parameters.SYMBOL_SCALING) {
|
||||||
|
case ALL:
|
||||||
|
symbolScale = CanvasAdapter.symbolScale;
|
||||||
|
break;
|
||||||
|
case POI:
|
||||||
|
if (!b.repeat)
|
||||||
|
symbolScale = CanvasAdapter.symbolScale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), b.src, b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale));
|
||||||
if (bitmap != null)
|
if (bitmap != null)
|
||||||
return buildSymbol(b, b.src, bitmap);
|
return buildSymbol(b, b.src, bitmap);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -1247,14 +1271,14 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.bitmap(bitmap).build();
|
return b.bitmap(bitmap).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) {
|
private ExtrusionStyle createExtrusion(String elementName, int level) {
|
||||||
ExtrusionBuilder<?> b = mExtrusionBuilder.reset();
|
ExtrusionBuilder<?> b = mExtrusionBuilder.reset();
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("cat".equals(name))
|
if ("cat".equals(name))
|
||||||
b.cat(value);
|
b.cat(value);
|
||||||
@@ -1287,10 +1311,11 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringAttribute(Attributes attributes, String name) {
|
private String getStringAttribute(String name) {
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
int n = mPullParser.getAttributeCount();
|
||||||
if (attributes.getLocalName(i).equals(name)) {
|
for (int i = 0; i < n; i++) {
|
||||||
return attributes.getValue(i);
|
if (mPullParser.getAttributeName(i).equals(name)) {
|
||||||
|
return mPullParser.getAttributeValue(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -1300,7 +1325,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* A style is visible if categories is not set or the style has no category
|
* A style is visible if categories is not set or the style has no category
|
||||||
* or the categories contain the style's category.
|
* or the categories contain the style's category.
|
||||||
*/
|
*/
|
||||||
private boolean isVisible(RenderStyle renderStyle) {
|
private boolean isVisible(RenderStyle<?> renderStyle) {
|
||||||
return mCategories == null || renderStyle.cat == null || mCategories.contains(renderStyle.cat);
|
return mCategories == null || renderStyle.cat == null || mCategories.contains(renderStyle.cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1321,13 +1346,13 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return dashIntervals;
|
return dashIntervals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tagTransform(String localName, Attributes attributes) {
|
private void tagTransform(String qName) {
|
||||||
String k, v, libK, libV;
|
String k, v, libK, libV;
|
||||||
k = v = libK = libV = null;
|
k = v = libK = libV = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "k":
|
case "k":
|
||||||
@@ -1343,12 +1368,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
libV = value;
|
libV = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(qName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k == null || k.isEmpty() || libK == null || libK.isEmpty()) {
|
if (k == null || k.isEmpty() || libK == null || libK.isEmpty()) {
|
||||||
log.debug("empty key in element " + localName);
|
log.debug("empty key in element " + qName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
* Copyright 2017-2020 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -20,7 +21,8 @@ import org.oscim.tiling.source.mapfile.header.SubFileParameter;
|
|||||||
import org.oscim.utils.LRUCache;
|
import org.oscim.utils.LRUCache;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -44,15 +46,15 @@ class IndexCache {
|
|||||||
* SubFileParameter.BYTES_PER_INDEX_ENTRY;
|
* SubFileParameter.BYTES_PER_INDEX_ENTRY;
|
||||||
|
|
||||||
private final Map<IndexCacheEntryKey, byte[]> map;
|
private final Map<IndexCacheEntryKey, byte[]> map;
|
||||||
private final RandomAccessFile randomAccessFile;
|
private final FileChannel fileChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param randomAccessFile the map file from which the index should be read and cached.
|
* @param inputChannel the map file from which the index should be read and cached.
|
||||||
* @param capacity the maximum number of entries in the cache.
|
* @param capacity the maximum number of entries in the cache.
|
||||||
* @throws IllegalArgumentException if the capacity is negative.
|
* @throws IllegalArgumentException if the capacity is negative.
|
||||||
*/
|
*/
|
||||||
IndexCache(RandomAccessFile randomAccessFile, int capacity) {
|
IndexCache(FileChannel inputChannel, int capacity) {
|
||||||
this.randomAccessFile = randomAccessFile;
|
this.fileChannel = inputChannel;
|
||||||
this.map = Collections.synchronizedMap(new LRUCache<IndexCacheEntryKey, byte[]>(capacity));
|
this.map = Collections.synchronizedMap(new LRUCache<IndexCacheEntryKey, byte[]>(capacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,11 +99,14 @@ class IndexCache {
|
|||||||
int remainingIndexSize = (int) (subFileParameter.indexEndAddress - indexBlockPosition);
|
int remainingIndexSize = (int) (subFileParameter.indexEndAddress - indexBlockPosition);
|
||||||
int indexBlockSize = Math.min(SIZE_OF_INDEX_BLOCK, remainingIndexSize);
|
int indexBlockSize = Math.min(SIZE_OF_INDEX_BLOCK, remainingIndexSize);
|
||||||
indexBlock = new byte[indexBlockSize];
|
indexBlock = new byte[indexBlockSize];
|
||||||
|
ByteBuffer indexBlockWrapper = ByteBuffer.wrap(indexBlock, 0, indexBlockSize);
|
||||||
|
|
||||||
this.randomAccessFile.seek(indexBlockPosition);
|
synchronized (this.fileChannel) {
|
||||||
if (this.randomAccessFile.read(indexBlock, 0, indexBlockSize) != indexBlockSize) {
|
this.fileChannel.position(indexBlockPosition);
|
||||||
LOG.warning("reading the current index block has failed");
|
if (this.fileChannel.read(indexBlockWrapper) != indexBlockSize) {
|
||||||
return -1;
|
LOG.warning("reading the current index block has failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// put the index block in the map
|
// put the index block in the map
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2013, 2014 Hannes Janetzek
|
* Copyright 2013, 2014 Hannes Janetzek
|
||||||
* Copyright 2014-2015 Ludwig M Brinckmann
|
* Copyright 2014-2015 Ludwig M Brinckmann
|
||||||
* Copyright 2016-2019 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2016 Andrey Novikov
|
* Copyright 2016 Andrey Novikov
|
||||||
* Copyright 2017-2018 Gustl22
|
* Copyright 2017-2018 Gustl22
|
||||||
* Copyright 2018 Bezzu
|
* Copyright 2018 Bezzu
|
||||||
@@ -38,8 +38,9 @@ import org.oscim.utils.geom.TileSeparator;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -202,8 +203,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
private long mFileSize;
|
private long mFileSize;
|
||||||
private boolean mDebugFile;
|
private boolean mDebugFile;
|
||||||
private RandomAccessFile mInputFile;
|
private FileChannel mInputChannel;
|
||||||
private ReadBuffer mReadBuffer;
|
|
||||||
private String mSignatureBlock;
|
private String mSignatureBlock;
|
||||||
private String mSignaturePoi;
|
private String mSignaturePoi;
|
||||||
private String mSignatureWay;
|
private String mSignatureWay;
|
||||||
@@ -227,11 +227,15 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
public MapDatabase(MapFileTileSource tileSource) throws IOException {
|
public MapDatabase(MapFileTileSource tileSource) throws IOException {
|
||||||
mTileSource = tileSource;
|
mTileSource = tileSource;
|
||||||
try {
|
try {
|
||||||
/* open the file in read only mode */
|
// false positive: stream gets closed when the channel is closed
|
||||||
mInputFile = new RandomAccessFile(tileSource.mapFile, "r");
|
// see e.g. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4796385
|
||||||
mFileSize = mInputFile.length();
|
if (tileSource.mapFileInputStream != null)
|
||||||
mReadBuffer = new ReadBuffer(mInputFile);
|
mInputChannel = tileSource.mapFileInputStream.getChannel();
|
||||||
|
else {
|
||||||
|
FileInputStream fis = new FileInputStream(tileSource.mapFile);
|
||||||
|
mInputChannel = fis.getChannel();
|
||||||
|
}
|
||||||
|
mFileSize = mInputChannel.size();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
/* make sure that the file is closed */
|
/* make sure that the file is closed */
|
||||||
@@ -314,12 +318,10 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
mReadBuffer = null;
|
if (mInputChannel != null) {
|
||||||
if (mInputFile != null) {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mInputFile.close();
|
mInputChannel.close();
|
||||||
mInputFile = null;
|
mInputChannel = null;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -351,13 +353,13 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
private void processBlock(QueryParameters queryParameters,
|
private void processBlock(QueryParameters queryParameters,
|
||||||
SubFileParameter subFileParameter, ITileDataSink mapDataSink,
|
SubFileParameter subFileParameter, ITileDataSink mapDataSink,
|
||||||
BoundingBox boundingBox, Selector selector,
|
BoundingBox boundingBox, Selector selector,
|
||||||
MapReadResult mapReadResult) {
|
MapReadResult mapReadResult, ReadBuffer readBuffer) {
|
||||||
|
|
||||||
if (!processBlockSignature()) {
|
if (!processBlockSignature(readBuffer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][] zoomTable = readZoomTable(subFileParameter);
|
int[][] zoomTable = readZoomTable(subFileParameter, readBuffer);
|
||||||
if (zoomTable == null) {
|
if (zoomTable == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -366,7 +368,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
int waysOnQueryZoomLevel = zoomTable[zoomTableRow][1];
|
int waysOnQueryZoomLevel = zoomTable[zoomTableRow][1];
|
||||||
|
|
||||||
/* get the relative offset to the first stored way in the block */
|
/* get the relative offset to the first stored way in the block */
|
||||||
int firstWayOffset = mReadBuffer.readUnsignedInt();
|
int firstWayOffset = readBuffer.readUnsignedInt();
|
||||||
if (firstWayOffset < 0) {
|
if (firstWayOffset < 0) {
|
||||||
log.warn(INVALID_FIRST_WAY_OFFSET + firstWayOffset);
|
log.warn(INVALID_FIRST_WAY_OFFSET + firstWayOffset);
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
@@ -376,8 +378,8 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add the current buffer position to the relative first way offset */
|
/* add the current buffer position to the relative first way offset */
|
||||||
firstWayOffset += mReadBuffer.getBufferPosition();
|
firstWayOffset += readBuffer.getBufferPosition();
|
||||||
if (firstWayOffset > mReadBuffer.getBufferSize()) {
|
if (firstWayOffset > readBuffer.getBufferSize()) {
|
||||||
log.warn(INVALID_FIRST_WAY_OFFSET + firstWayOffset);
|
log.warn(INVALID_FIRST_WAY_OFFSET + firstWayOffset);
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||||
@@ -391,13 +393,13 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
if (mapReadResult != null)
|
if (mapReadResult != null)
|
||||||
pois = new ArrayList<>();
|
pois = new ArrayList<>();
|
||||||
|
|
||||||
if (!processPOIs(mapDataSink, poisOnQueryZoomLevel, boundingBox, filterRequired, pois)) {
|
if (!processPOIs(mapDataSink, poisOnQueryZoomLevel, boundingBox, filterRequired, pois, readBuffer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finished reading POIs, check if the current buffer position is valid */
|
/* finished reading POIs, check if the current buffer position is valid */
|
||||||
if (mReadBuffer.getBufferPosition() > firstWayOffset) {
|
if (readBuffer.getBufferPosition() > firstWayOffset) {
|
||||||
log.warn("invalid buffer position: " + mReadBuffer.getBufferPosition());
|
log.warn("invalid buffer position: " + readBuffer.getBufferPosition());
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||||
}
|
}
|
||||||
@@ -405,13 +407,13 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* move the pointer to the first way */
|
/* move the pointer to the first way */
|
||||||
mReadBuffer.setBufferPosition(firstWayOffset);
|
readBuffer.setBufferPosition(firstWayOffset);
|
||||||
|
|
||||||
List<Way> ways = null;
|
List<Way> ways = null;
|
||||||
if (mapReadResult != null && Selector.POIS != selector)
|
if (mapReadResult != null && Selector.POIS != selector)
|
||||||
ways = new ArrayList<>();
|
ways = new ArrayList<>();
|
||||||
|
|
||||||
if (!processWays(queryParameters, mapDataSink, waysOnQueryZoomLevel, boundingBox, filterRequired, selector, ways)) {
|
if (!processWays(queryParameters, mapDataSink, waysOnQueryZoomLevel, boundingBox, filterRequired, selector, ways, readBuffer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,10 +578,9 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* seek to the current block in the map file */
|
/* seek to the current block in the map file */
|
||||||
mInputFile.seek(subFileParameter.startAddress + blockPointer);
|
|
||||||
|
|
||||||
/* read the current block into the buffer */
|
/* read the current block into the buffer */
|
||||||
if (!mReadBuffer.readFromFile(blockSize)) {
|
ReadBuffer readBuffer = new ReadBuffer(mInputChannel);
|
||||||
|
if (!readBuffer.readFromFile(subFileParameter.startAddress + blockPointer, blockSize)) {
|
||||||
/* skip the current block */
|
/* skip the current block */
|
||||||
log.warn("reading current block has failed: " + blockSize);
|
log.warn("reading current block has failed: " + blockSize);
|
||||||
return;
|
return;
|
||||||
@@ -596,7 +597,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
mTileLatitude = (int) (tileLatitudeDeg * 1E6);
|
mTileLatitude = (int) (tileLatitudeDeg * 1E6);
|
||||||
mTileLongitude = (int) (tileLongitudeDeg * 1E6);
|
mTileLongitude = (int) (tileLongitudeDeg * 1E6);
|
||||||
|
|
||||||
processBlock(queryParams, subFileParameter, mapDataSink, boundingBox, selector, mapReadResult);
|
processBlock(queryParams, subFileParameter, mapDataSink, boundingBox, selector, mapReadResult, readBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,10 +608,10 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
* @return true if the block signature could be processed successfully,
|
* @return true if the block signature could be processed successfully,
|
||||||
* false otherwise.
|
* false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean processBlockSignature() {
|
private boolean processBlockSignature(ReadBuffer readBuffer) {
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
/* get and check the block signature */
|
/* get and check the block signature */
|
||||||
mSignatureBlock = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_BLOCK);
|
mSignatureBlock = readBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_BLOCK);
|
||||||
if (!mSignatureBlock.startsWith("###TileStart")) {
|
if (!mSignatureBlock.startsWith("###TileStart")) {
|
||||||
log.warn("invalid block signature: " + mSignatureBlock);
|
log.warn("invalid block signature: " + mSignatureBlock);
|
||||||
return false;
|
return false;
|
||||||
@@ -628,7 +629,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois, BoundingBox boundingBox,
|
private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois, BoundingBox boundingBox,
|
||||||
boolean filterRequired, List<PointOfInterest> pois) {
|
boolean filterRequired, List<PointOfInterest> pois, ReadBuffer readBuffer) {
|
||||||
Tag[] poiTags = mTileSource.fileInfo.poiTags;
|
Tag[] poiTags = mTileSource.fileInfo.poiTags;
|
||||||
MapElement e = mElem;
|
MapElement e = mElem;
|
||||||
|
|
||||||
@@ -638,7 +639,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
/* get and check the POI signature */
|
/* get and check the POI signature */
|
||||||
mSignaturePoi = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_POI);
|
mSignaturePoi = readBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_POI);
|
||||||
if (!mSignaturePoi.startsWith("***POIStart")) {
|
if (!mSignaturePoi.startsWith("***POIStart")) {
|
||||||
log.warn("invalid POI signature: " + mSignaturePoi);
|
log.warn("invalid POI signature: " + mSignaturePoi);
|
||||||
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||||
@@ -647,12 +648,12 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the POI latitude offset (VBE-S) */
|
/* get the POI latitude offset (VBE-S) */
|
||||||
int latitude = mTileLatitude + mReadBuffer.readSignedInt();
|
int latitude = mTileLatitude + readBuffer.readSignedInt();
|
||||||
/* get the POI longitude offset (VBE-S) */
|
/* get the POI longitude offset (VBE-S) */
|
||||||
int longitude = mTileLongitude + mReadBuffer.readSignedInt();
|
int longitude = mTileLongitude + readBuffer.readSignedInt();
|
||||||
|
|
||||||
/* get the special byte which encodes multiple flags */
|
/* get the special byte which encodes multiple flags */
|
||||||
byte specialByte = mReadBuffer.readByte();
|
byte specialByte = readBuffer.readByte();
|
||||||
|
|
||||||
/* bit 1-4 represent the layer */
|
/* bit 1-4 represent the layer */
|
||||||
byte layer = (byte) ((specialByte & POI_LAYER_BITMASK) >>> POI_LAYER_SHIFT);
|
byte layer = (byte) ((specialByte & POI_LAYER_BITMASK) >>> POI_LAYER_SHIFT);
|
||||||
@@ -661,29 +662,29 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
byte numberOfTags = (byte) (specialByte & POI_NUMBER_OF_TAGS_BITMASK);
|
byte numberOfTags = (byte) (specialByte & POI_NUMBER_OF_TAGS_BITMASK);
|
||||||
|
|
||||||
if (numberOfTags != 0) {
|
if (numberOfTags != 0) {
|
||||||
if (!mReadBuffer.readTags(e.tags, poiTags, numberOfTags))
|
if (!readBuffer.readTags(e.tags, poiTags, numberOfTags))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the feature bitmask (1 byte) */
|
/* get the feature bitmask (1 byte) */
|
||||||
byte featureByte = mReadBuffer.readByte();
|
byte featureByte = readBuffer.readByte();
|
||||||
|
|
||||||
/* bit 1-3 enable optional features
|
/* bit 1-3 enable optional features
|
||||||
* check if the POI has a name */
|
* check if the POI has a name */
|
||||||
if ((featureByte & POI_FEATURE_NAME) != 0) {
|
if ((featureByte & POI_FEATURE_NAME) != 0) {
|
||||||
String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedString());
|
String str = mTileSource.extractLocalized(readBuffer.readUTF8EncodedString());
|
||||||
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the POI has a house number */
|
/* check if the POI has a house number */
|
||||||
if ((featureByte & POI_FEATURE_HOUSE_NUMBER) != 0) {
|
if ((featureByte & POI_FEATURE_HOUSE_NUMBER) != 0) {
|
||||||
String str = mReadBuffer.readUTF8EncodedString();
|
String str = readBuffer.readUTF8EncodedString();
|
||||||
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the POI has an elevation */
|
/* check if the POI has an elevation */
|
||||||
if ((featureByte & POI_FEATURE_ELEVATION) != 0) {
|
if ((featureByte & POI_FEATURE_ELEVATION) != 0) {
|
||||||
String str = Integer.toString(mReadBuffer.readSignedInt());
|
String str = Integer.toString(readBuffer.readSignedInt());
|
||||||
e.tags.add(new Tag(Tag.KEY_ELE, str, false));
|
e.tags.add(new Tag(Tag.KEY_ELE, str, false));
|
||||||
}
|
}
|
||||||
mTileProjection.projectPoint(latitude, longitude, e);
|
mTileProjection.projectPoint(latitude, longitude, e);
|
||||||
@@ -712,9 +713,9 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processWayDataBlock(MapElement e, boolean doubleDeltaEncoding, boolean isLine, List<GeoPoint[]> wayCoordinates, int[] labelPosition) {
|
private boolean processWayDataBlock(MapElement e, boolean doubleDeltaEncoding, boolean isLine, List<GeoPoint[]> wayCoordinates, int[] labelPosition, ReadBuffer readBuffer) {
|
||||||
/* get and check the number of way coordinate blocks (VBE-U) */
|
/* get and check the number of way coordinate blocks (VBE-U) */
|
||||||
int numBlocks = mReadBuffer.readUnsignedInt();
|
int numBlocks = readBuffer.readUnsignedInt();
|
||||||
if (numBlocks < 1 || numBlocks > Short.MAX_VALUE) {
|
if (numBlocks < 1 || numBlocks > Short.MAX_VALUE) {
|
||||||
log.warn("invalid number of way coordinate blocks: " + numBlocks);
|
log.warn("invalid number of way coordinate blocks: " + numBlocks);
|
||||||
return false;
|
return false;
|
||||||
@@ -726,7 +727,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
/* read the way coordinate blocks */
|
/* read the way coordinate blocks */
|
||||||
for (int coordinateBlock = 0; coordinateBlock < numBlocks; ++coordinateBlock) {
|
for (int coordinateBlock = 0; coordinateBlock < numBlocks; ++coordinateBlock) {
|
||||||
int numWayNodes = mReadBuffer.readUnsignedInt();
|
int numWayNodes = readBuffer.readUnsignedInt();
|
||||||
|
|
||||||
if (numWayNodes < 2 || numWayNodes > Short.MAX_VALUE) {
|
if (numWayNodes < 2 || numWayNodes > Short.MAX_VALUE) {
|
||||||
log.warn("invalid number of way nodes: " + numWayNodes);
|
log.warn("invalid number of way nodes: " + numWayNodes);
|
||||||
@@ -744,7 +745,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
// label position must be set on first coordinate block
|
// label position must be set on first coordinate block
|
||||||
wayLengths[coordinateBlock] = decodeWayNodes(doubleDeltaEncoding, e, len, isLine,
|
wayLengths[coordinateBlock] = decodeWayNodes(doubleDeltaEncoding, e, len, isLine,
|
||||||
coordinateBlock == 0 ? labelPosition : null, waySegment);
|
coordinateBlock == 0 ? labelPosition : null, waySegment, readBuffer);
|
||||||
|
|
||||||
if (wayCoordinates != null)
|
if (wayCoordinates != null)
|
||||||
wayCoordinates.add(waySegment);
|
wayCoordinates.add(waySegment);
|
||||||
@@ -753,9 +754,9 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int decodeWayNodes(boolean doubleDelta, MapElement e, int length, boolean isLine, int[] labelPosition, GeoPoint[] waySegment) {
|
private int decodeWayNodes(boolean doubleDelta, MapElement e, int length, boolean isLine, int[] labelPosition, GeoPoint[] waySegment, ReadBuffer readBuffer) {
|
||||||
int[] buffer = mIntBuffer;
|
int[] buffer = mIntBuffer;
|
||||||
mReadBuffer.readSignedInt(buffer, length);
|
readBuffer.readSignedInt(buffer, length);
|
||||||
|
|
||||||
float[] outBuffer = e.ensurePointSize(e.pointNextPos + length, true);
|
float[] outBuffer = e.ensurePointSize(e.pointNextPos + length, true);
|
||||||
int outPos = e.pointNextPos;
|
int outPos = e.pointNextPos;
|
||||||
@@ -848,7 +849,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
*/
|
*/
|
||||||
private boolean processWays(QueryParameters queryParameters, ITileDataSink mapDataSink,
|
private boolean processWays(QueryParameters queryParameters, ITileDataSink mapDataSink,
|
||||||
int numberOfWays, BoundingBox boundingBox, boolean filterRequired,
|
int numberOfWays, BoundingBox boundingBox, boolean filterRequired,
|
||||||
Selector selector, List<Way> ways) {
|
Selector selector, List<Way> ways, ReadBuffer readBuffer) {
|
||||||
|
|
||||||
Tag[] wayTags = mTileSource.fileInfo.wayTags;
|
Tag[] wayTags = mTileSource.fileInfo.wayTags;
|
||||||
MapElement e = mElem;
|
MapElement e = mElem;
|
||||||
@@ -860,9 +861,9 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
stringOffset = 0;
|
stringOffset = 0;
|
||||||
|
|
||||||
if (mTileSource.experimental) {
|
if (mTileSource.experimental) {
|
||||||
stringsSize = mReadBuffer.readUnsignedInt();
|
stringsSize = readBuffer.readUnsignedInt();
|
||||||
stringOffset = mReadBuffer.getBufferPosition();
|
stringOffset = readBuffer.getBufferPosition();
|
||||||
mReadBuffer.skipBytes(stringsSize);
|
readBuffer.skipBytes(stringsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//setTileClipping(queryParameters);
|
//setTileClipping(queryParameters);
|
||||||
@@ -873,7 +874,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
// get and check the way signature
|
// get and check the way signature
|
||||||
mSignatureWay = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_WAY);
|
mSignatureWay = readBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_WAY);
|
||||||
if (!mSignatureWay.startsWith("---WayStart")) {
|
if (!mSignatureWay.startsWith("---WayStart")) {
|
||||||
log.warn("invalid way signature: " + mSignatureWay);
|
log.warn("invalid way signature: " + mSignatureWay);
|
||||||
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||||
@@ -882,7 +883,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (queryParameters.useTileBitmask) {
|
if (queryParameters.useTileBitmask) {
|
||||||
elementCounter = mReadBuffer.skipWays(queryParameters.queryTileBitmask,
|
elementCounter = readBuffer.skipWays(queryParameters.queryTileBitmask,
|
||||||
elementCounter);
|
elementCounter);
|
||||||
|
|
||||||
if (elementCounter == 0)
|
if (elementCounter == 0)
|
||||||
@@ -891,19 +892,19 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
if (elementCounter < 0)
|
if (elementCounter < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mTileSource.experimental && mReadBuffer.lastTagPosition > 0) {
|
if (mTileSource.experimental && readBuffer.lastTagPosition > 0) {
|
||||||
int pos = mReadBuffer.getBufferPosition();
|
int pos = readBuffer.getBufferPosition();
|
||||||
mReadBuffer.setBufferPosition(mReadBuffer.lastTagPosition);
|
readBuffer.setBufferPosition(readBuffer.lastTagPosition);
|
||||||
|
|
||||||
byte numberOfTags =
|
byte numberOfTags =
|
||||||
(byte) (mReadBuffer.readByte() & WAY_NUMBER_OF_TAGS_BITMASK);
|
(byte) (readBuffer.readByte() & WAY_NUMBER_OF_TAGS_BITMASK);
|
||||||
if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags))
|
if (!readBuffer.readTags(e.tags, wayTags, numberOfTags))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mReadBuffer.setBufferPosition(pos);
|
readBuffer.setBufferPosition(pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int wayDataSize = mReadBuffer.readUnsignedInt();
|
int wayDataSize = readBuffer.readUnsignedInt();
|
||||||
if (wayDataSize < 0) {
|
if (wayDataSize < 0) {
|
||||||
log.warn("invalid way data size: " + wayDataSize);
|
log.warn("invalid way data size: " + wayDataSize);
|
||||||
if (mDebugFile) {
|
if (mDebugFile) {
|
||||||
@@ -914,11 +915,11 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ignore the way tile bitmask (2 bytes) */
|
/* ignore the way tile bitmask (2 bytes) */
|
||||||
mReadBuffer.skipBytes(2);
|
readBuffer.skipBytes(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the special byte which encodes multiple flags */
|
/* get the special byte which encodes multiple flags */
|
||||||
byte specialByte = mReadBuffer.readByte();
|
byte specialByte = readBuffer.readByte();
|
||||||
|
|
||||||
/* bit 1-4 represent the layer */
|
/* bit 1-4 represent the layer */
|
||||||
byte layer = (byte) ((specialByte & WAY_LAYER_BITMASK) >>> WAY_LAYER_SHIFT);
|
byte layer = (byte) ((specialByte & WAY_LAYER_BITMASK) >>> WAY_LAYER_SHIFT);
|
||||||
@@ -926,12 +927,12 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
byte numberOfTags = (byte) (specialByte & WAY_NUMBER_OF_TAGS_BITMASK);
|
byte numberOfTags = (byte) (specialByte & WAY_NUMBER_OF_TAGS_BITMASK);
|
||||||
|
|
||||||
if (numberOfTags != 0) {
|
if (numberOfTags != 0) {
|
||||||
if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags))
|
if (!readBuffer.readTags(e.tags, wayTags, numberOfTags))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the feature bitmask (1 byte) */
|
/* get the feature bitmask (1 byte) */
|
||||||
byte featureByte = mReadBuffer.readByte();
|
byte featureByte = readBuffer.readByte();
|
||||||
|
|
||||||
/* bit 1-6 enable optional features */
|
/* bit 1-6 enable optional features */
|
||||||
boolean featureWayDoubleDeltaEncoding =
|
boolean featureWayDoubleDeltaEncoding =
|
||||||
@@ -943,42 +944,42 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
if (mTileSource.experimental) {
|
if (mTileSource.experimental) {
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
int textPos = mReadBuffer.readUnsignedInt();
|
int textPos = readBuffer.readUnsignedInt();
|
||||||
String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos));
|
String str = mTileSource.extractLocalized(readBuffer.readUTF8EncodedStringAt(stringOffset + textPos));
|
||||||
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
if (hasHouseNr) {
|
if (hasHouseNr) {
|
||||||
int textPos = mReadBuffer.readUnsignedInt();
|
int textPos = readBuffer.readUnsignedInt();
|
||||||
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
|
String str = readBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
|
||||||
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
||||||
}
|
}
|
||||||
if (hasRef) {
|
if (hasRef) {
|
||||||
int textPos = mReadBuffer.readUnsignedInt();
|
int textPos = readBuffer.readUnsignedInt();
|
||||||
String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
|
String str = readBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
|
||||||
e.tags.add(new Tag(Tag.KEY_REF, str, false));
|
e.tags.add(new Tag(Tag.KEY_REF, str, false));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedString());
|
String str = mTileSource.extractLocalized(readBuffer.readUTF8EncodedString());
|
||||||
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
if (hasHouseNr) {
|
if (hasHouseNr) {
|
||||||
String str = mReadBuffer.readUTF8EncodedString();
|
String str = readBuffer.readUTF8EncodedString();
|
||||||
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
|
||||||
}
|
}
|
||||||
if (hasRef) {
|
if (hasRef) {
|
||||||
String str = mReadBuffer.readUTF8EncodedString();
|
String str = readBuffer.readUTF8EncodedString();
|
||||||
e.tags.add(new Tag(Tag.KEY_REF, str, false));
|
e.tags.add(new Tag(Tag.KEY_REF, str, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] labelPosition = null;
|
int[] labelPosition = null;
|
||||||
if ((featureByte & WAY_FEATURE_LABEL_POSITION) != 0) {
|
if ((featureByte & WAY_FEATURE_LABEL_POSITION) != 0) {
|
||||||
labelPosition = readOptionalLabelPosition();
|
labelPosition = readOptionalLabelPosition(readBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((featureByte & WAY_FEATURE_DATA_BLOCKS_BYTE) != 0) {
|
if ((featureByte & WAY_FEATURE_DATA_BLOCKS_BYTE) != 0) {
|
||||||
wayDataBlocks = mReadBuffer.readUnsignedInt();
|
wayDataBlocks = readBuffer.readUnsignedInt();
|
||||||
|
|
||||||
if (wayDataBlocks < 1) {
|
if (wayDataBlocks < 1) {
|
||||||
log.warn("invalid number of way data blocks: " + wayDataBlocks);
|
log.warn("invalid number of way data blocks: " + wayDataBlocks);
|
||||||
@@ -999,7 +1000,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
if (ways != null)
|
if (ways != null)
|
||||||
wayNodes = new ArrayList<>();
|
wayNodes = new ArrayList<>();
|
||||||
|
|
||||||
if (!processWayDataBlock(e, featureWayDoubleDeltaEncoding, linearFeature, wayNodes, labelPosition))
|
if (!processWayDataBlock(e, featureWayDoubleDeltaEncoding, linearFeature, wayNodes, labelPosition, readBuffer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* drop invalid outer ring */
|
/* drop invalid outer ring */
|
||||||
@@ -1152,14 +1153,14 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
return mapReadResult;
|
return mapReadResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] readOptionalLabelPosition() {
|
private int[] readOptionalLabelPosition(ReadBuffer readBuffer) {
|
||||||
int[] labelPosition = new int[2];
|
int[] labelPosition = new int[2];
|
||||||
|
|
||||||
/* get the label position latitude offset (VBE-S) */
|
/* get the label position latitude offset (VBE-S) */
|
||||||
labelPosition[1] = mReadBuffer.readSignedInt();
|
labelPosition[1] = readBuffer.readSignedInt();
|
||||||
|
|
||||||
/* get the label position longitude offset (VBE-S) */
|
/* get the label position longitude offset (VBE-S) */
|
||||||
labelPosition[0] = mReadBuffer.readSignedInt();
|
labelPosition[0] = readBuffer.readSignedInt();
|
||||||
|
|
||||||
return labelPosition;
|
return labelPosition;
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1188,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
return readMapData(upperLeft, lowerRight, Selector.POIS);
|
return readMapData(upperLeft, lowerRight, Selector.POIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[][] readZoomTable(SubFileParameter subFileParameter) {
|
private int[][] readZoomTable(SubFileParameter subFileParameter, ReadBuffer readBuffer) {
|
||||||
int rows = subFileParameter.zoomLevelMax - subFileParameter.zoomLevelMin + 1;
|
int rows = subFileParameter.zoomLevelMax - subFileParameter.zoomLevelMin + 1;
|
||||||
int[][] zoomTable = new int[rows][2];
|
int[][] zoomTable = new int[rows][2];
|
||||||
|
|
||||||
@@ -1195,8 +1196,8 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
int cumulatedNumberOfWays = 0;
|
int cumulatedNumberOfWays = 0;
|
||||||
|
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = 0; row < rows; row++) {
|
||||||
cumulatedNumberOfPois += mReadBuffer.readUnsignedInt();
|
cumulatedNumberOfPois += readBuffer.readUnsignedInt();
|
||||||
cumulatedNumberOfWays += mReadBuffer.readUnsignedInt();
|
cumulatedNumberOfWays += readBuffer.readUnsignedInt();
|
||||||
|
|
||||||
zoomTable[row][0] = cumulatedNumberOfPois;
|
zoomTable[row][0] = cumulatedNumberOfPois;
|
||||||
zoomTable[row][1] = cumulatedNumberOfWays;
|
zoomTable[row][1] = cumulatedNumberOfWays;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 mapsforge.org
|
* Copyright 2013 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2020 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -25,13 +25,13 @@ import org.oscim.tiling.OverzoomTileDataSource;
|
|||||||
import org.oscim.tiling.TileSource;
|
import org.oscim.tiling.TileSource;
|
||||||
import org.oscim.tiling.source.mapfile.header.MapFileHeader;
|
import org.oscim.tiling.source.mapfile.header.MapFileHeader;
|
||||||
import org.oscim.tiling.source.mapfile.header.MapFileInfo;
|
import org.oscim.tiling.source.mapfile.header.MapFileInfo;
|
||||||
import org.oscim.utils.IOUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.nio.channels.FileChannel;
|
||||||
|
|
||||||
public class MapFileTileSource extends TileSource implements IMapFileTileSource {
|
public class MapFileTileSource extends TileSource implements IMapFileTileSource {
|
||||||
private static final Logger log = LoggerFactory.getLogger(MapFileTileSource.class);
|
private static final Logger log = LoggerFactory.getLogger(MapFileTileSource.class);
|
||||||
@@ -40,14 +40,14 @@ public class MapFileTileSource extends TileSource implements IMapFileTileSource
|
|||||||
* Amount of cache blocks that the index cache should store.
|
* Amount of cache blocks that the index cache should store.
|
||||||
*/
|
*/
|
||||||
private static final int INDEX_CACHE_SIZE = 64;
|
private static final int INDEX_CACHE_SIZE = 64;
|
||||||
private static final String READ_ONLY_MODE = "r";
|
|
||||||
|
|
||||||
MapFileHeader fileHeader;
|
MapFileHeader fileHeader;
|
||||||
MapFileInfo fileInfo;
|
MapFileInfo fileInfo;
|
||||||
IndexCache databaseIndexCache;
|
IndexCache databaseIndexCache;
|
||||||
boolean experimental;
|
boolean experimental;
|
||||||
File mapFile;
|
File mapFile;
|
||||||
private RandomAccessFile mInputFile;
|
FileInputStream mapFileInputStream;
|
||||||
|
private FileChannel inputChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The preferred language when extracting labels from this tile source.
|
* The preferred language when extracting labels from this tile source.
|
||||||
@@ -98,6 +98,10 @@ public class MapFileTileSource extends TileSource implements IMapFileTileSource
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMapFileInputStream(FileInputStream fileInputStream) {
|
||||||
|
this.mapFileInputStream = fileInputStream;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPreferredLanguage(String preferredLanguage) {
|
public void setPreferredLanguage(String preferredLanguage) {
|
||||||
this.preferredLanguage = preferredLanguage;
|
this.preferredLanguage = preferredLanguage;
|
||||||
@@ -105,31 +109,38 @@ public class MapFileTileSource extends TileSource implements IMapFileTileSource
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenResult open() {
|
public OpenResult open() {
|
||||||
if (!options.containsKey("file"))
|
if (mapFileInputStream == null && !options.containsKey("file"))
|
||||||
return new OpenResult("no map file set");
|
return new OpenResult("no map file set");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// make sure to close any previously opened file first
|
// false positive: stream gets closed when the channel is closed
|
||||||
//close();
|
// see e.g. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4796385
|
||||||
|
File file = null;
|
||||||
|
if (mapFileInputStream != null)
|
||||||
|
inputChannel = mapFileInputStream.getChannel();
|
||||||
|
else {
|
||||||
|
// make sure to close any previously opened file first
|
||||||
|
//close();
|
||||||
|
|
||||||
File file = new File(options.get("file"));
|
file = new File(options.get("file"));
|
||||||
|
|
||||||
// check if the file exists and is readable
|
// check if the file exists and is readable
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
return new OpenResult("file does not exist: " + file);
|
return new OpenResult("file does not exist: " + file);
|
||||||
} else if (!file.isFile()) {
|
} else if (!file.isFile()) {
|
||||||
return new OpenResult("not a file: " + file);
|
return new OpenResult("not a file: " + file);
|
||||||
} else if (!file.canRead()) {
|
} else if (!file.canRead()) {
|
||||||
return new OpenResult("cannot read file: " + file);
|
return new OpenResult("cannot read file: " + file);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
inputChannel = fis.getChannel();
|
||||||
}
|
}
|
||||||
|
long fileSize = inputChannel.size();
|
||||||
// open the file in read only mode
|
ReadBuffer readBuffer = new ReadBuffer(inputChannel);
|
||||||
mInputFile = new RandomAccessFile(file, READ_ONLY_MODE);
|
|
||||||
long mFileSize = mInputFile.length();
|
|
||||||
ReadBuffer mReadBuffer = new ReadBuffer(mInputFile);
|
|
||||||
|
|
||||||
fileHeader = new MapFileHeader();
|
fileHeader = new MapFileHeader();
|
||||||
OpenResult openResult = fileHeader.readHeader(mReadBuffer, mFileSize);
|
OpenResult openResult = fileHeader.readHeader(readBuffer, fileSize);
|
||||||
|
|
||||||
if (!openResult.isSuccess()) {
|
if (!openResult.isSuccess()) {
|
||||||
close();
|
close();
|
||||||
@@ -137,10 +148,7 @@ public class MapFileTileSource extends TileSource implements IMapFileTileSource
|
|||||||
}
|
}
|
||||||
fileInfo = fileHeader.getMapFileInfo();
|
fileInfo = fileHeader.getMapFileInfo();
|
||||||
mapFile = file;
|
mapFile = file;
|
||||||
databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
|
databaseIndexCache = new IndexCache(inputChannel, INDEX_CACHE_SIZE);
|
||||||
|
|
||||||
// Experimental?
|
|
||||||
//experimental = fileInfo.fileVersion == 4;
|
|
||||||
|
|
||||||
log.debug("File version: " + fileInfo.fileVersion);
|
log.debug("File version: " + fileInfo.fileVersion);
|
||||||
return OpenResult.SUCCESS;
|
return OpenResult.SUCCESS;
|
||||||
@@ -164,8 +172,14 @@ public class MapFileTileSource extends TileSource implements IMapFileTileSource
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
IOUtils.closeQuietly(mInputFile);
|
if (inputChannel != null) {
|
||||||
mInputFile = null;
|
try {
|
||||||
|
inputChannel.close();
|
||||||
|
inputChannel = null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
fileHeader = null;
|
fileHeader = null;
|
||||||
fileInfo = null;
|
fileInfo = null;
|
||||||
mapFile = null;
|
mapFile = null;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
||||||
* Copyright 2015-2016 devemux86
|
* Copyright 2015-2020 devemux86
|
||||||
* Copyright 2015-2016 lincomatic
|
* Copyright 2015-2016 lincomatic
|
||||||
|
* Copyright 2020 Meibes
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -19,19 +20,31 @@ package org.oscim.tiling.source.mapfile;
|
|||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public final class OSMUtils {
|
public final class OSMUtils {
|
||||||
|
|
||||||
|
private static final Set<String> areaKeys = new HashSet<>(Arrays.asList(
|
||||||
|
"building", "natural", "landuse", "amenity", "leisure", "aeroway",
|
||||||
|
"highway", "barrier",
|
||||||
|
"railway",
|
||||||
|
"area"
|
||||||
|
));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Heuristic to determine from attributes if a map element is likely to be an area.
|
* Heuristic to determine from attributes if a map element is likely to be an area.
|
||||||
* Precondition for this call is that the first and last node of a map element are the
|
* Precondition for this call is that the first and last node of a map element are the
|
||||||
* same, so that this method should only return false if it is known that the
|
* same, so that this method should only return false if it is known that the
|
||||||
* feature should not be an area even if the geometry is a polygon.
|
* feature should not be an area even if the geometry is a polygon.
|
||||||
* <p/>
|
* <p>
|
||||||
* Determining what is an area is neigh impossible in OSM, this method inspects tag elements
|
* Determining what is an area is neigh impossible in OSM, this method inspects tag elements
|
||||||
* to give a likely answer. See http://wiki.openstreetmap.org/wiki/The_Future_of_Areas and
|
* to give a likely answer. See http://wiki.openstreetmap.org/wiki/The_Future_of_Areas and
|
||||||
* http://wiki.openstreetmap.org/wiki/Way
|
* http://wiki.openstreetmap.org/wiki/Way
|
||||||
|
* <p>
|
||||||
|
* The order in which the if-clauses are checked is determined with the help from https://taginfo.openstreetmap.org
|
||||||
*
|
*
|
||||||
* @param mapElement the map element (which is assumed to be closed and have enough nodes to be an area)
|
* @param mapElement the map element (which is assumed to be closed and have enough nodes to be an area)
|
||||||
* @return true if tags indicate this is an area, otherwise false.
|
* @return true if tags indicate this is an area, otherwise false.
|
||||||
@@ -41,34 +54,35 @@ public final class OSMUtils {
|
|||||||
for (int i = 0; i < mapElement.tags.size(); i++) {
|
for (int i = 0; i < mapElement.tags.size(); i++) {
|
||||||
Tag tag = mapElement.tags.get(i);
|
Tag tag = mapElement.tags.get(i);
|
||||||
String key = tag.key.toLowerCase(Locale.ENGLISH);
|
String key = tag.key.toLowerCase(Locale.ENGLISH);
|
||||||
String value = tag.value.toLowerCase(Locale.ENGLISH);
|
if (!areaKeys.contains(key)) {
|
||||||
if ("area".equals(key)) {
|
continue;
|
||||||
// obvious result
|
|
||||||
if (("yes").equals(value) || ("y").equals(value) || ("true").equals(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (("no").equals(value) || ("n").equals(value) || ("false").equals(value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// as specified by http://wiki.openstreetmap.org/wiki/Key:area
|
if ("building".equals(key) || "natural".equals(key) || "landuse".equals(key) || "amenity".equals(key) || "leisure".equals(key) || "aeroway".equals(key)) {
|
||||||
if ("aeroway".equals(key) || "building".equals(key) || "landuse".equals(key) || "leisure".equals(key) || "natural".equals(key) || "amenity".equals(key)) {
|
// as specified by http://wiki.openstreetmap.org/wiki/Key:area
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if ("highway".equals(key) || "barrier".equals(key)) {
|
||||||
if ("highway".equals(key) || "barrier".equals(key)) {
|
|
||||||
// false unless something else overrides this.
|
// false unless something else overrides this.
|
||||||
result = false;
|
result = false;
|
||||||
}
|
} else if ("railway".equals(key)) {
|
||||||
if ("railway".equals(key)) {
|
String value = tag.value.toLowerCase(Locale.ENGLISH);
|
||||||
// there is more to the railway tag then just rails, this excludes the
|
// there is more to the railway tag then just rails, this excludes the
|
||||||
// most common railway lines from being detected as areas if they are closed.
|
// most common railway lines from being detected as areas if they are closed.
|
||||||
// Since this method is only called if the first and last node are the same
|
// Since this method is only called if the first and last node are the same
|
||||||
// this should be safe
|
// this should be safe
|
||||||
if ("rail".equals(value) || "tram".equals(value) || "subway".equals(value)
|
if ("rail".equals(value) || "tram".equals(value) || "subway".equals(value)
|
||||||
|| "monorail".equals(value) || "narrow_gauge".equals(value) || "preserved".equals(value)
|
|| "narrow_gauge".equals(value) || "light_rail".equals(value)
|
||||||
|| "light_rail".equals(value) || "construction".equals(value)) {
|
|| "construction".equals(value) || "preserved".equals(value)
|
||||||
|
|| "monorail".equals(value)) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
} else if ("area".equals(key)) {
|
||||||
|
String value = tag.value.toLowerCase(Locale.ENGLISH);
|
||||||
|
if (("yes").equals(value) || ("y").equals(value) || ("true").equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (("no").equals(value) || ("n").equals(value) || ("false").equals(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import org.oscim.utils.Parameters;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -39,16 +41,17 @@ public class ReadBuffer {
|
|||||||
|
|
||||||
private byte[] mBufferData;
|
private byte[] mBufferData;
|
||||||
private int mBufferPosition;
|
private int mBufferPosition;
|
||||||
private final RandomAccessFile mInputFile;
|
private ByteBuffer mBufferWrapper;
|
||||||
|
private final FileChannel mInputChannel;
|
||||||
|
|
||||||
private final List<Integer> mTagIds = new ArrayList<>();
|
private final List<Integer> mTagIds = new ArrayList<>();
|
||||||
|
|
||||||
ReadBuffer(RandomAccessFile inputFile) {
|
ReadBuffer(FileChannel inputChannel) {
|
||||||
mInputFile = inputFile;
|
mInputChannel = inputChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns one signed byte from the read buffer.
|
* Returns one byte from the read buffer.
|
||||||
*
|
*
|
||||||
* @return the byte value.
|
* @return the byte value.
|
||||||
*/
|
*/
|
||||||
@@ -91,13 +94,54 @@ public class ReadBuffer {
|
|||||||
LOG.log(Level.SEVERE, t.getMessage(), t);
|
LOG.log(Level.SEVERE, t.getMessage(), t);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
mBufferWrapper = ByteBuffer.wrap(mBufferData, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
mBufferPosition = 0;
|
mBufferPosition = 0;
|
||||||
|
mBufferWrapper.clear();
|
||||||
|
|
||||||
// reset the buffer position and read the data into the buffer
|
// reset the buffer position and read the data into the buffer
|
||||||
// bufferPosition = 0;
|
// bufferPosition = 0;
|
||||||
return mInputFile.read(mBufferData, 0, length) == length;
|
return mInputChannel.read(mBufferWrapper) == length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the given amount of bytes from the file into the read buffer and
|
||||||
|
* resets the internal buffer position. If
|
||||||
|
* the capacity of the read buffer is too small, a larger one is created
|
||||||
|
* automatically.
|
||||||
|
*
|
||||||
|
* @param offset the offset position, measured in bytes from the beginning of the file, at which to set the file pointer.
|
||||||
|
* @param length the amount of bytes to read from the file.
|
||||||
|
* @return true if the whole data was read successfully, false otherwise.
|
||||||
|
* @throws IOException if an error occurs while reading the file.
|
||||||
|
*/
|
||||||
|
public boolean readFromFile(long offset, int length) throws IOException {
|
||||||
|
// ensure that the read buffer is large enough
|
||||||
|
if (mBufferData == null || mBufferData.length < length) {
|
||||||
|
// ensure that the read buffer is not too large
|
||||||
|
if (length > Parameters.MAXIMUM_BUFFER_SIZE) {
|
||||||
|
LOG.warning("invalid read length: " + length);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mBufferData = new byte[length];
|
||||||
|
} catch (Throwable t) {
|
||||||
|
LOG.log(Level.SEVERE, t.getMessage(), t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mBufferWrapper = ByteBuffer.wrap(mBufferData, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
mBufferPosition = 0;
|
||||||
|
mBufferWrapper.clear();
|
||||||
|
|
||||||
|
// reset the buffer position and read the data into the buffer
|
||||||
|
// bufferPosition = 0;
|
||||||
|
synchronized (mInputChannel) {
|
||||||
|
mInputChannel.position(offset);
|
||||||
|
return mInputChannel.read(mBufferWrapper) == length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ package org.oscim.utils;
|
|||||||
|
|
||||||
public final class Parameters {
|
public final class Parameters {
|
||||||
|
|
||||||
|
public enum SymbolScaling {ALL, POI}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true the <code>Animator2</code> will be used instead of default <code>Animator</code>.
|
* If true the <code>Animator2</code> will be used instead of default <code>Animator</code>.
|
||||||
*/
|
*/
|
||||||
@@ -44,7 +46,7 @@ public final class Parameters {
|
|||||||
/**
|
/**
|
||||||
* Maximum buffer size for map files.
|
* Maximum buffer size for map files.
|
||||||
*/
|
*/
|
||||||
public static int MAXIMUM_BUFFER_SIZE = 8000000;
|
public static int MAXIMUM_BUFFER_SIZE = 10000000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculation of centroids for all polygons.
|
* Calculation of centroids for all polygons.
|
||||||
@@ -73,6 +75,11 @@ public final class Parameters {
|
|||||||
*/
|
*/
|
||||||
public static int SIMPLIFICATION_TOLERANCE = 0;
|
public static int SIMPLIFICATION_TOLERANCE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symbol scaling mode.
|
||||||
|
*/
|
||||||
|
public static SymbolScaling SYMBOL_SCALING = SymbolScaling.POI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Texture atlas in themes.
|
* Texture atlas in themes.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user