Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e62e27cf22 | ||
|
|
76bf76a090 | ||
|
|
e906305910 | ||
|
|
08b94a0c42 | ||
|
|
c508bde844 | ||
|
|
d4b7e34d17 | ||
|
|
d5543bd7ef | ||
|
|
354bc16ead | ||
|
|
8889235690 | ||
|
|
9b43d7f498 | ||
|
|
ef2d2dd197 | ||
|
|
1245158ba3 | ||
|
|
ef5f7acbdf | ||
|
|
e1c24ee8cf | ||
|
|
9f5ddd2381 | ||
|
|
1fbc501bef | ||
|
|
d7c69e12d6 | ||
|
|
1fa86b5e07 | ||
|
|
efed81bdeb | ||
|
|
a308eb48ac | ||
|
|
5926dd3e65 | ||
|
|
a11e620792 | ||
|
|
6850eff26c | ||
|
|
ddf94ae2ca | ||
|
|
22ed9653ec | ||
|
|
3bb8ce00c5 | ||
|
|
b9cbd97c40 | ||
|
|
6801b895e4 |
@@ -12,7 +12,7 @@ VTM (Vector Tile Map) was developed within the [OpenScienceMap](https://github.c
|
|||||||
|
|
||||||
See the **[integration guide](docs/Integration.md)** and [changelog](docs/Changelog.md). And read through [how to contribute](docs/CONTRIBUTING.md) guidelines.
|
See the **[integration guide](docs/Integration.md)** and [changelog](docs/Changelog.md). And read through [how to contribute](docs/CONTRIBUTING.md) guidelines.
|
||||||
|
|
||||||
If you have any questions or problems, don't hesitate to ask our public [forum](https://groups.google.com/group/mapsforge-dev) for help.
|
If you have any questions or problems, don't hesitate to ask the Discussions for help.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Java map library
|
- Java map library
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.0.2'
|
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,8 +42,9 @@ def versionName() { return version }
|
|||||||
subprojects {
|
subprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
maven { url "https://plugins.gradle.org/m2/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
| [GPSLogger II](https://play.google.com/store/apps/details?id=com.emacberry.gpslogger) | Map and navigation, Fitness & Cycling application | Proprietary/Free | Android | Closed |
|
| [GPSLogger II](https://play.google.com/store/apps/details?id=com.emacberry.gpslogger) | Map and navigation, Fitness & Cycling application | Proprietary/Free | Android | Closed |
|
||||||
| [HabanaTrans](https://play.google.com/store/apps/details?id=cu.pabloapk.habanatrans&hl=es_419) | Public transport, map offline, gps, routing | Proprietary/Free | Android | Closed |
|
| [HabanaTrans](https://play.google.com/store/apps/details?id=cu.pabloapk.habanatrans&hl=es_419) | Public transport, map offline, gps, routing | Proprietary/Free | Android | Closed |
|
||||||
| [Hunt Cyprus](https://play.google.com/store/apps/developer?id=Talent+S.A.) | Map and navigation application for hunters | Proprietary/Free and Commercial | Android | Closed |
|
| [Hunt Cyprus](https://play.google.com/store/apps/developer?id=Talent+S.A.) | Map and navigation application for hunters | Proprietary/Free and Commercial | Android | Closed |
|
||||||
| [Kurviger](https://kurviger.de/en) | Route planner specialized on motorcyclists | Proprietary/Free and Commercial | Android | Closed |
|
| [Kurviger](https://kurviger.de/en) | Route planner specialized on motorcyclists | Proprietary/Free (in-app purchases) | Android | Closed |
|
||||||
| [MapTrek](http://maptrek.mobi) | Application for outdoor activities | GPL3/Free and Commercial | Android | Open |
|
| [MapTrek](http://maptrek.mobi) | Application for outdoor activities | GPL3/Free and Commercial | Android | Open |
|
||||||
| [MyRunningApp](https://play.google.com/store/apps/details?id=it.nimarsolutions.rungpstracker) | Fitness app | Proprietary/Free | Android | Closed |
|
| [MyRunningApp](https://play.google.com/store/apps/details?id=it.nimarsolutions.rungpstracker) | Fitness app | Proprietary/Free | Android | Closed |
|
||||||
| [MyTourbook](http://mytourbook.sourceforge.net/mytourbook/) | Visualize and analyze tours | GPL2/Free | Desktop | Open |
|
| [MyTourbook](http://mytourbook.sourceforge.net/mytourbook/) | Visualize and analyze tours | GPL2/Free | Desktop | Open |
|
||||||
@@ -21,5 +21,3 @@
|
|||||||
| [VTM with Eclipse RCP](https://github.com/wolfgang-ch/vtm-with-rcp) | VTM with an Eclipse RCP application | GPL3/Free | Desktop | Open |
|
| [VTM with Eclipse RCP](https://github.com/wolfgang-ch/vtm-with-rcp) | VTM with an Eclipse RCP application | GPL3/Free | Desktop | Open |
|
||||||
| [Walkaholic](https://play.google.com/store/apps/details?id=com.walkaholic.hikeapp) | Hiking app with official routes and online/offline maps | Proprietary/Free (in-app purchases) | Android | Closed |
|
| [Walkaholic](https://play.google.com/store/apps/details?id=com.walkaholic.hikeapp) | Hiking app with official routes and online/offline maps | Proprietary/Free (in-app purchases) | Android | Closed |
|
||||||
| [XCTrack](http://xctrack.org/) | Flight computer for paraglider pilots | Proprietary/Free | Android | Closed |
|
| [XCTrack](http://xctrack.org/) | Flight computer for paraglider pilots | Proprietary/Free | Android | Closed |
|
||||||
|
|
||||||
You know an application that is missing here? Please inform us by sending a message via our public [forum](https://groups.google.com/group/mapsforge-dev).
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
As an open source project, we welcome new contributors and appreciate your help.
|
As an open source project, we welcome new contributors and appreciate your help.
|
||||||
|
|
||||||
Before you start working on an unresolved issue or try to implement a new feature, please contact us via our public [forum](https://groups.google.com/group/mapsforge-dev). We will then discuss the best way to realize your proposal and figure out how we can help you to get started quickly.
|
Before you start working on an unresolved issue or try to implement a new feature, please contact us via the Discussions. We will then discuss the best way to realize your proposal and figure out how we can help you to get started quickly.
|
||||||
|
|
||||||
If you are only requesting a small change in the code, you may attach a patch file to the corresponding issue, but it is best to create a pull request on Github. Make sure that your patch is derived from the latest version in our **master** repository, otherwise we might be unable to apply it. Important is to keep pull requests simple with one feature in each. Please follow our code and style conventions.
|
If you are only requesting a small change in the code, you may attach a patch file to the corresponding issue, but it is best to create a pull request on Github. Make sure that your patch is derived from the latest version in our **master** repository, otherwise we might be unable to apply it. Important is to keep pull requests simple with one feature in each. Please follow our code and style conventions.
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## New since 0.15.0
|
## New since 0.16.0
|
||||||
|
|
||||||
|
- Many other minor improvements and bug fixes
|
||||||
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.17.0)
|
||||||
|
|
||||||
|
## Version 0.16.0 (2021-05-27)
|
||||||
|
|
||||||
|
- Android: scoped storage map / theme example [#804](https://github.com/mapsforge/vtm/pull/804)
|
||||||
|
- Render theme from zip archive [#804](https://github.com/mapsforge/vtm/pull/804)
|
||||||
|
- Render themes: custom resource providers [#804](https://github.com/mapsforge/vtm/pull/804)
|
||||||
|
- Nautical unit adapter with feet [#803](https://github.com/mapsforge/vtm/pull/803)
|
||||||
|
- Distant labels rendering option [#844](https://github.com/mapsforge/vtm/pull/844)
|
||||||
|
- `Parameters.DISTANT_LABELS`
|
||||||
- Many other minor improvements and bug fixes
|
- Many other minor improvements and bug fixes
|
||||||
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.16.0)
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.16.0)
|
||||||
|
|
||||||
## Version 0.15.0 (2021-01-01)
|
## Version 0.15.0 (2021-01-01)
|
||||||
|
|
||||||
- Android: scoped storage example [#785](https://github.com/mapsforge/vtm/pull/785)
|
- Android: scoped storage map example [#785](https://github.com/mapsforge/vtm/pull/785)
|
||||||
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
- 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 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)
|
- Render theme xml pull parser [#786](https://github.com/mapsforge/vtm/pull/786)
|
||||||
@@ -223,7 +234,7 @@
|
|||||||
- Many other minor improvements and bug fixes
|
- Many other minor improvements and bug fixes
|
||||||
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.7.0)
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.7.0)
|
||||||
|
|
||||||
## Version 0.6.0 (2016-10-28) - VTM revive
|
## Version 0.6.0 (2016-10-28) - VTM revival
|
||||||
|
|
||||||
- Mapsforge maps **v4** support [#34](https://github.com/mapsforge/vtm/issues/34)
|
- Mapsforge maps **v4** support [#34](https://github.com/mapsforge/vtm/issues/34)
|
||||||
- Render theme SVG resources [#60](https://github.com/mapsforge/vtm/issues/60)
|
- Render theme SVG resources [#60](https://github.com/mapsforge/vtm/issues/60)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
For questions or discussion please use the [forum](https://groups.google.com/group/mapsforge-dev).
|
For questions, reports and feature requests please use the Discussions.
|
||||||
@@ -48,10 +48,6 @@ Detailed iOS instructions can be found [here](ios.md).
|
|||||||
|
|
||||||
### Desktop
|
### Desktop
|
||||||
```groovy
|
```groovy
|
||||||
repositories {
|
|
||||||
maven { url 'https://jitpack.io' }
|
|
||||||
}
|
|
||||||
|
|
||||||
implementation 'org.mapsforge:vtm-gdx:[CURRENT-VERSION]'
|
implementation 'org.mapsforge:vtm-gdx:[CURRENT-VERSION]'
|
||||||
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]'
|
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]'
|
||||||
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]:natives-linux'
|
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]:natives-linux'
|
||||||
@@ -59,7 +55,7 @@ implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]:natives-osx'
|
|||||||
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]:natives-windows'
|
implementation 'org.mapsforge:vtm-desktop:[CURRENT-VERSION]:natives-windows'
|
||||||
implementation 'com.badlogicgames.gdx:gdx:1.9.10'
|
implementation 'com.badlogicgames.gdx:gdx:1.9.10'
|
||||||
implementation 'com.badlogicgames.gdx:gdx-platform:1.9.10:natives-desktop'
|
implementation 'com.badlogicgames.gdx:gdx-platform:1.9.10:natives-desktop'
|
||||||
implementation 'com.github.blackears:svgSalamander:v1.1.1'
|
implementation 'com.formdev:svgSalamander:1.1.2.4'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Desktop (LWJGL)
|
### Desktop (LWJGL)
|
||||||
@@ -95,7 +91,7 @@ implementation 'org.locationtech.jts:jts-core:1.15.1'
|
|||||||
```groovy
|
```groovy
|
||||||
implementation 'org.mapsforge:vtm-http:[CURRENT-VERSION]'
|
implementation 'org.mapsforge:vtm-http:[CURRENT-VERSION]'
|
||||||
// https://github.com/square/okhttp/issues/4481
|
// https://github.com/square/okhttp/issues/4481
|
||||||
implementation 'com.squareup.okhttp3:okhttp:3.12.5'
|
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||||
implementation 'com.squareup.okio:okio:1.15.0'
|
implementation 'com.squareup.okio:okio:1.15.0'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,3 @@
|
|||||||
- [OpenAndroMaps](https://www.openandromaps.org/en/)
|
- [OpenAndroMaps](https://www.openandromaps.org/en/)
|
||||||
- [OpenMaps](https://openmaps.eu/)
|
- [OpenMaps](https://openmaps.eu/)
|
||||||
- [vector.city](https://vector.city/)
|
- [vector.city](https://vector.city/)
|
||||||
|
|
||||||
You know a Mapsforge map provider that is missing here? Please inform us by sending a message via our public [forum](https://groups.google.com/group/mapsforge-dev).
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# RenderTheme
|
# RenderTheme
|
||||||
|
|
||||||
**This article describes how to use XML-based render-themes to style maps.**
|
This article describes how to use XML-based render-themes to style maps.
|
||||||
|
|
||||||
If you have any questions or problems, don't hesitate to ask our public [forum](https://groups.google.com/group/mapsforge-dev) for help.
|
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
|||||||
# 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
|
|
||||||
android.enableJetifier=true
|
|
||||||
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.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -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.15.0'
|
implementation 'org.mapsforge:mapsforge-poi-android:0.16.0'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-armeabi-v7a'
|
implementation 'org.mapsforge:sqlite-android:0.16.0:natives-armeabi-v7a'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-arm64-v8a'
|
implementation 'org.mapsforge:sqlite-android:0.16.0:natives-arm64-v8a'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-x86'
|
implementation 'org.mapsforge:sqlite-android:0.16.0:natives-x86'
|
||||||
implementation 'org.mapsforge:sqlite-android:0.15.0:natives-x86_64'
|
implementation 'org.mapsforge:sqlite-android:0.16.0:natives-x86_64'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/theme_newtron"
|
android:id="@+id/theme_newtron"
|
||||||
android:title="@string/theme_newtron" />
|
android:title="@string/theme_newtron" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/theme_external_archive"
|
||||||
|
android:title="@string/theme_external_archive" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/theme_external"
|
android:id="@+id/theme_external"
|
||||||
android:title="@string/theme_external" />
|
android:title="@string/theme_external" />
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<string name="theme_osmagray">Osmagray</string>
|
<string name="theme_osmagray">Osmagray</string>
|
||||||
<string name="theme_tubes">Tubes</string>
|
<string name="theme_tubes">Tubes</string>
|
||||||
<string name="theme_newtron">NewTron</string>
|
<string name="theme_newtron">NewTron</string>
|
||||||
<string name="theme_external">External theme</string>
|
<string name="theme_external">External theme (Android 5)</string>
|
||||||
|
<string name="theme_external_archive">External theme archive</string>
|
||||||
<string name="styler_mode_line">Line</string>
|
<string name="styler_mode_line">Line</string>
|
||||||
<string name="styler_mode_area">Area</string>
|
<string name="styler_mode_area">Area</string>
|
||||||
<string name="styler_mode_outline">Outline</string>
|
<string name="styler_mode_outline">Outline</string>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
<string name="style_2">Hide nature</string>
|
<string name="style_2">Hide nature</string>
|
||||||
<string name="menu_gridlayer">Grid</string>
|
<string name="menu_gridlayer">Grid</string>
|
||||||
<string name="dialog_reverse_geocoding_title">Reverse Geocoding</string>
|
<string name="dialog_reverse_geocoding_title">Reverse Geocoding</string>
|
||||||
|
<string name="dialog_theme_title">Select a theme</string>
|
||||||
<string name="add">Add</string>
|
<string name="add">Add</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="error">Error</string>
|
<string name="error">Error</string>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 Hannes Janetzek
|
* Copyright 2014 Hannes Janetzek
|
||||||
* Copyright 2016-2020 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2018 Gustl22
|
* Copyright 2018 Gustl22
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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,13 +21,17 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
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.theme.ContentRenderTheme;
|
||||||
|
import org.oscim.android.theme.ContentResolverResourceProvider;
|
||||||
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,9 +47,7 @@ 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.*;
|
import org.oscim.scalebar.*;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.*;
|
||||||
import org.oscim.theme.ThemeFile;
|
|
||||||
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;
|
||||||
@@ -52,15 +55,20 @@ import org.oscim.tiling.source.mapfile.MapInfo;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
public class MapsforgeActivity extends MapActivity {
|
public class MapsforgeActivity extends MapActivity {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MapsforgeActivity.class);
|
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 = 1;
|
private static final int SELECT_THEME_ARCHIVE = 1;
|
||||||
|
private static final int SELECT_THEME_DIR = 2;
|
||||||
|
static final int SELECT_THEME_FILE = 3;
|
||||||
|
|
||||||
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");
|
||||||
@@ -71,6 +79,7 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
private final boolean mS3db;
|
private final boolean mS3db;
|
||||||
IRenderTheme mTheme;
|
IRenderTheme mTheme;
|
||||||
VectorTileLayer mTileLayer;
|
VectorTileLayer mTileLayer;
|
||||||
|
private Uri mThemeDirUri;
|
||||||
|
|
||||||
public MapsforgeActivity() {
|
public MapsforgeActivity() {
|
||||||
this(false);
|
this(false);
|
||||||
@@ -142,11 +151,19 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.theme_external:
|
case R.id.theme_external_archive:
|
||||||
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
intent.setType("*/*");
|
intent.setType("*/*");
|
||||||
startActivityForResult(intent, SELECT_THEME_FILE);
|
startActivityForResult(intent, SELECT_THEME_ARCHIVE);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case R.id.theme_external:
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
return false;
|
||||||
|
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||||
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
startActivityForResult(intent, SELECT_THEME_DIR);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.gridlayer:
|
case R.id.gridlayer:
|
||||||
@@ -176,75 +193,103 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapFileTileSource tileSource = new MapFileTileSource();
|
|
||||||
//tileSource.setPreferredLanguage("en");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
|
|
||||||
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
|
//tileSource.setPreferredLanguage("en");
|
||||||
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
|
||||||
tileSource.setMapFileInputStream(fis);
|
tileSource.setMapFileInputStream(fis);
|
||||||
} catch (IOException e) {
|
|
||||||
|
mTileLayer = mMap.setBaseMap(tileSource);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
finish();
|
finish();
|
||||||
|
}
|
||||||
|
} else if (requestCode == SELECT_THEME_ARCHIVE) {
|
||||||
|
if (resultCode != Activity.RESULT_OK || data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Uri uri = data.getData();
|
||||||
|
|
||||||
|
final List<String> xmlThemes = ZipXmlThemeResourceProvider.scanXmlThemes(new ZipInputStream(new BufferedInputStream(getContentResolver().openInputStream(uri))));
|
||||||
|
if (xmlThemes.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setTitle(R.string.dialog_theme_title);
|
||||||
|
builder.setSingleChoiceItems(xmlThemes.toArray(new String[0]), -1, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
try {
|
||||||
|
dialog.dismiss();
|
||||||
|
ThemeFile theme = new ZipRenderTheme(xmlThemes.get(which), new ZipXmlThemeResourceProvider(new ZipInputStream(new BufferedInputStream(getContentResolver().openInputStream(uri)))));
|
||||||
|
if (mTheme != null)
|
||||||
|
mTheme.dispose();
|
||||||
|
mTheme = mMap.setTheme(theme);
|
||||||
|
mapsforgeTheme(mTheme);
|
||||||
|
mMenu.findItem(R.id.theme_external_archive).setChecked(true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.show();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
} else if (requestCode == SELECT_THEME_DIR) {
|
||||||
|
if (resultCode != Activity.RESULT_OK || data == null)
|
||||||
|
return;
|
||||||
|
|
||||||
mTileLayer = mMap.setBaseMap(tileSource);
|
mThemeDirUri = data.getData();
|
||||||
loadTheme(null);
|
|
||||||
|
|
||||||
if (mS3db)
|
// Now we have the directory for resources, but we need to let the user also select a theme file
|
||||||
mMap.layers().add(new S3DBLayer(mMap, mTileLayer));
|
Intent intent = new Intent(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT);
|
||||||
else
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
mMap.layers().add(new BuildingLayer(mMap, mTileLayer));
|
intent.setType("*/*");
|
||||||
mMap.layers().add(new LabelLayer(mMap, mTileLayer));
|
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, mThemeDirUri);
|
||||||
|
startActivityForResult(intent, SELECT_THEME_FILE);
|
||||||
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) {
|
} else if (requestCode == SELECT_THEME_FILE) {
|
||||||
if (resultCode != Activity.RESULT_OK || data == null)
|
if (resultCode != Activity.RESULT_OK || data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
ThemeFile theme = new ContentRenderTheme(getContentResolver(), "", uri);
|
ThemeFile theme = new ContentRenderTheme(getContentResolver(), uri);
|
||||||
|
theme.setResourceProvider(new ContentResolverResourceProvider(getContentResolver(), mThemeDirUri));
|
||||||
// Use tessellation with sea and land for Mapsforge themes
|
|
||||||
if (theme.isMapsforgeTheme()) {
|
|
||||||
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
|
||||||
@Override
|
|
||||||
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
|
||||||
if (element.tags.contains(ISSEA_TAG) || element.tags.contains(SEA_TAG) || element.tags.contains(NOSEA_TAG)) {
|
|
||||||
if (style instanceof AreaStyle)
|
|
||||||
((AreaStyle) style).mesh = true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void complete(MapTile tile, boolean success) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTheme != null)
|
if (mTheme != null)
|
||||||
mTheme.dispose();
|
mTheme.dispose();
|
||||||
mTheme = mMap.setTheme(theme);
|
mTheme = mMap.setTheme(theme);
|
||||||
|
mapsforgeTheme(mTheme);
|
||||||
mMenu.findItem(R.id.theme_external).setChecked(true);
|
mMenu.findItem(R.id.theme_external).setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,4 +299,25 @@ public class MapsforgeActivity extends MapActivity {
|
|||||||
mTheme.dispose();
|
mTheme.dispose();
|
||||||
mTheme = mMap.setTheme(VtmThemes.DEFAULT);
|
mTheme = mMap.setTheme(VtmThemes.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mapsforgeTheme(IRenderTheme theme) {
|
||||||
|
if (!theme.isMapsforgeTheme())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Use tessellation with sea and land for Mapsforge themes
|
||||||
|
mTileLayer.addHook(new VectorTileLayer.TileLoaderThemeHook() {
|
||||||
|
@Override
|
||||||
|
public boolean process(MapTile tile, RenderBuckets buckets, MapElement element, RenderStyle style, int level) {
|
||||||
|
if (element.tags.contains(ISSEA_TAG) || element.tags.contains(SEA_TAG) || element.tags.contains(NOSEA_TAG)) {
|
||||||
|
if (style instanceof AreaStyle)
|
||||||
|
((AreaStyle) style).mesh = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete(MapTile tile, boolean success) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ public class Samples extends Activity {
|
|||||||
LinearLayout linearLayout = findViewById(R.id.samples);
|
LinearLayout linearLayout = findViewById(R.id.samples);
|
||||||
linearLayout.addView(createButton(GettingStarted.class));
|
linearLayout.addView(createButton(GettingStarted.class));
|
||||||
linearLayout.addView(createLabel(null));
|
linearLayout.addView(createLabel(null));
|
||||||
linearLayout.addView(createButton(SimpleMapActivity.class));
|
|
||||||
linearLayout.addView(createButton(MapsforgeActivity.class));
|
linearLayout.addView(createButton(MapsforgeActivity.class));
|
||||||
|
linearLayout.addView(createButton(SimpleMapActivity.class));
|
||||||
linearLayout.addView(createButton(MBTilesMvtActivity.class));
|
linearLayout.addView(createButton(MBTilesMvtActivity.class));
|
||||||
linearLayout.addView(createButton(MapilionMvtActivity.class));
|
linearLayout.addView(createButton(MapilionMvtActivity.class));
|
||||||
/*linearLayout.addView(createButton(MapzenMvtActivity.class));
|
/*linearLayout.addView(createButton(MapzenMvtActivity.class));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016 Longri
|
* Copyright 2016 Longri
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2021 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,7 +22,6 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.opengl.GLUtils;
|
import android.opengl.GLUtils;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.utils.GraphicUtils;
|
import org.oscim.utils.GraphicUtils;
|
||||||
import org.oscim.utils.IOUtils;
|
import org.oscim.utils.IOUtils;
|
||||||
@@ -39,6 +38,7 @@ public class AndroidBitmap implements org.oscim.backend.canvas.Bitmap {
|
|||||||
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
||||||
try {
|
try {
|
||||||
GLUtils.getType(bitmap);
|
GLUtils.getType(bitmap);
|
||||||
|
GLUtils.getInternalFormat(bitmap);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
bitmap = bitmap.copy(ARGB_8888, false);
|
bitmap = bitmap.copy(ARGB_8888, false);
|
||||||
}
|
}
|
||||||
@@ -95,6 +95,9 @@ public class AndroidBitmap implements org.oscim.backend.canvas.Bitmap {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uploadToTexture(boolean replace) {
|
public void uploadToTexture(boolean replace) {
|
||||||
|
if (mBitmap.isRecycled())
|
||||||
|
return;
|
||||||
|
|
||||||
int format = GLUtils.getInternalFormat(mBitmap);
|
int format = GLUtils.getInternalFormat(mBitmap);
|
||||||
int type = GLUtils.getType(mBitmap);
|
int type = GLUtils.getType(mBitmap);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.oscim.backend.canvas.Canvas;
|
|||||||
import org.oscim.backend.canvas.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
import org.oscim.layers.marker.MarkerSymbol;
|
import org.oscim.layers.marker.MarkerSymbol;
|
||||||
import org.oscim.layers.marker.MarkerSymbol.HotspotPlace;
|
import org.oscim.layers.marker.MarkerSymbol.HotspotPlace;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -69,8 +70,8 @@ public final class AndroidGraphics extends CanvasAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
|
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException {
|
||||||
return createBitmap(relativePathPrefix, src, width, height, percent);
|
return createBitmap(relativePathPrefix, src, resourceProvider, width, height, percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -18,11 +19,10 @@ package org.oscim.android.theme;
|
|||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.theme.ThemeFile;
|
import org.oscim.theme.ThemeFile;
|
||||||
import org.oscim.theme.ThemeUtils;
|
|
||||||
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.utils.Utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -37,8 +37,10 @@ public class AssetsRenderTheme implements ThemeFile {
|
|||||||
|
|
||||||
private final AssetManager mAssetManager;
|
private final AssetManager mAssetManager;
|
||||||
private final String mFileName;
|
private final String mFileName;
|
||||||
|
private boolean mMapsforgeTheme;
|
||||||
private XmlRenderThemeMenuCallback mMenuCallback;
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
private final String mRelativePathPrefix;
|
private final String mRelativePathPrefix;
|
||||||
|
private XmlThemeResourceProvider mResourceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param assetManager the Android asset manager.
|
* @param assetManager the Android asset manager.
|
||||||
@@ -100,13 +102,28 @@ public class AssetsRenderTheme implements ThemeFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return mResourceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapsforgeTheme() {
|
public boolean isMapsforgeTheme() {
|
||||||
return ThemeUtils.isMapsforgeTheme(this);
|
return mMapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
mMapsforgeTheme = mapsforgeTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 devemux86
|
* Copyright 2020-2021 devemux86
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -18,9 +19,8 @@ import android.content.ContentResolver;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.theme.ThemeFile;
|
import org.oscim.theme.ThemeFile;
|
||||||
import org.oscim.theme.ThemeUtils;
|
|
||||||
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
import org.oscim.theme.XmlRenderThemeMenuCallback;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -33,30 +33,28 @@ public class ContentRenderTheme implements ThemeFile {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final ContentResolver mContentResolver;
|
private final ContentResolver mContentResolver;
|
||||||
|
private boolean mMapsforgeTheme;
|
||||||
private XmlRenderThemeMenuCallback mMenuCallback;
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
private final String mRelativePathPrefix;
|
private XmlThemeResourceProvider mResourceProvider;
|
||||||
private final Uri mUri;
|
private final Uri mUri;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param contentResolver the Android content resolver.
|
* @param contentResolver the Android content resolver.
|
||||||
* @param relativePathPrefix the prefix for all relative resource paths.
|
* @param uri the XML render theme URI.
|
||||||
* @param uri the XML render theme URI.
|
|
||||||
* @throws ThemeException if an error occurs while reading the render theme XML.
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
*/
|
*/
|
||||||
public ContentRenderTheme(ContentResolver contentResolver, String relativePathPrefix, Uri uri) throws ThemeException {
|
public ContentRenderTheme(ContentResolver contentResolver, Uri uri) throws ThemeException {
|
||||||
this(contentResolver, relativePathPrefix, uri, null);
|
this(contentResolver, uri, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param contentResolver the Android content resolver.
|
* @param contentResolver the Android content resolver.
|
||||||
* @param relativePathPrefix the prefix for all relative resource paths.
|
* @param uri the XML render theme URI.
|
||||||
* @param uri the XML render theme URI.
|
* @param menuCallback the interface callback to create a settings menu on the fly.
|
||||||
* @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.
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
*/
|
*/
|
||||||
public ContentRenderTheme(ContentResolver contentResolver, String relativePathPrefix, Uri uri, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
|
public ContentRenderTheme(ContentResolver contentResolver, Uri uri, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
|
||||||
mContentResolver = contentResolver;
|
mContentResolver = contentResolver;
|
||||||
mRelativePathPrefix = relativePathPrefix;
|
|
||||||
mUri = uri;
|
mUri = uri;
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
@@ -72,9 +70,6 @@ public class ContentRenderTheme implements ThemeFile {
|
|||||||
if (getRenderThemeAsStream() != other.getRenderThemeAsStream()) {
|
if (getRenderThemeAsStream() != other.getRenderThemeAsStream()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Utils.equals(mRelativePathPrefix, other.mRelativePathPrefix)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +80,7 @@ public class ContentRenderTheme implements ThemeFile {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRelativePathPrefix() {
|
public String getRelativePathPrefix() {
|
||||||
return mRelativePathPrefix;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -97,13 +92,28 @@ public class ContentRenderTheme implements ThemeFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return mResourceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapsforgeTheme() {
|
public boolean isMapsforgeTheme() {
|
||||||
return ThemeUtils.isMapsforgeTheme(this);
|
return mMapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
mMapsforgeTheme = mapsforgeTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
|
*
|
||||||
|
* 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.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
|
import org.oscim.backend.CanvasAdapter;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An xml theme resource provider resolving resources using Android scoped storage (document framework).
|
||||||
|
* <p>
|
||||||
|
* Implementation note: these methods do not use DocumentFile internally,
|
||||||
|
* but query directly for document info due to vastly better performance.
|
||||||
|
* Also for better performance, this implementation caches resource uris.
|
||||||
|
* <p>
|
||||||
|
* Note: this implementation requires minimum Android 5.0 (API 21)
|
||||||
|
*/
|
||||||
|
public class ContentResolverResourceProvider implements XmlThemeResourceProvider {
|
||||||
|
|
||||||
|
private final ContentResolver contentResolver;
|
||||||
|
private final Uri relativeRootUri;
|
||||||
|
private final boolean isDocumentUri;
|
||||||
|
|
||||||
|
private final Map<String, Uri> resourceUriCache = new HashMap<>();
|
||||||
|
|
||||||
|
private static class DocumentInfo {
|
||||||
|
private final String name;
|
||||||
|
private final Uri uri;
|
||||||
|
private final boolean isDirectory;
|
||||||
|
|
||||||
|
private DocumentInfo(String name, Uri uri, boolean isDirectory) {
|
||||||
|
this.name = name;
|
||||||
|
this.uri = uri;
|
||||||
|
this.isDirectory = isDirectory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new content resolver resource provider.
|
||||||
|
*
|
||||||
|
* @param contentResolver content resolver used to read content.
|
||||||
|
* @param relativeRootUri uri pointing to a directory.
|
||||||
|
* Uri is assumed to be a pure tree Uri (as e.g. returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}).
|
||||||
|
*/
|
||||||
|
public ContentResolverResourceProvider(ContentResolver contentResolver, Uri relativeRootUri) {
|
||||||
|
this(contentResolver, relativeRootUri, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new content resolver resource provider.
|
||||||
|
*
|
||||||
|
* @param contentResolver content resolver used to read content.
|
||||||
|
* @param relativeRootUri uri pointing to a directory.
|
||||||
|
* @param isDocumentUri Uris as returned e.g. by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}) cannot directly be used to scan directories and read content.
|
||||||
|
* They must be converted to document uris first using {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)}.
|
||||||
|
* However, in some situations this conversion was done previously by caller (e.g. if root dir should be subdirectory of a directory returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}).
|
||||||
|
* In these cases, converted Uri will point to original root directory which is not always the wanted behaviour.
|
||||||
|
* Thus, this parameter allows caller to control whether conversion should be done or not.
|
||||||
|
* If set to true, then given Uri is considered to be a document uri already and no conversion is done.
|
||||||
|
* If set to false, uri is considered to be a pure tree uri as returned e.g. by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}) and it is converted.
|
||||||
|
*/
|
||||||
|
public ContentResolverResourceProvider(ContentResolver contentResolver, Uri relativeRootUri, boolean isDocumentUri) {
|
||||||
|
this.contentResolver = contentResolver;
|
||||||
|
this.relativeRootUri = relativeRootUri;
|
||||||
|
this.isDocumentUri = isDocumentUri;
|
||||||
|
|
||||||
|
refreshCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build uri cache for one dir level (recursive function).
|
||||||
|
*/
|
||||||
|
private void buildCacheLevel(String prefix, Uri dirUri) {
|
||||||
|
List<DocumentInfo> docs = queryDir(dirUri);
|
||||||
|
for (DocumentInfo doc : docs) {
|
||||||
|
if (doc.isDirectory) {
|
||||||
|
buildCacheLevel(prefix + doc.name + "/", doc.uri);
|
||||||
|
} else {
|
||||||
|
// Store both relative urls and absolute urls
|
||||||
|
resourceUriCache.put(CanvasAdapter.PREFIX_FILE + prefix + doc.name, doc.uri);
|
||||||
|
resourceUriCache.put(CanvasAdapter.PREFIX_FILE + "/" + prefix + doc.name, doc.uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream createInputStream(String relativePath, String source) throws FileNotFoundException {
|
||||||
|
Uri docUri = resourceUriCache.get(source);
|
||||||
|
if (docUri != null) {
|
||||||
|
return contentResolver.openInputStream(docUri);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the content of a directory using scoped storage.
|
||||||
|
*
|
||||||
|
* @return a list of arrays with info [0: name (String), 1: uri (Uri), 2: isDir (boolean)]
|
||||||
|
*/
|
||||||
|
private List<DocumentInfo> queryDir(Uri dirUri) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
if (dirUri == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DocumentInfo> result = new ArrayList<>();
|
||||||
|
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(dirUri, DocumentsContract.getDocumentId(dirUri));
|
||||||
|
|
||||||
|
String[] columns = new String[]{
|
||||||
|
DocumentsContract.Document.COLUMN_DOCUMENT_ID,
|
||||||
|
DocumentsContract.Document.COLUMN_DISPLAY_NAME,
|
||||||
|
DocumentsContract.Document.COLUMN_MIME_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
Cursor c = null;
|
||||||
|
try {
|
||||||
|
c = contentResolver.query(childrenUri, columns, null, null, null);
|
||||||
|
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
String documentId = c.getString(0);
|
||||||
|
String name = c.getString(1);
|
||||||
|
String mimeType = c.getString(2);
|
||||||
|
|
||||||
|
Uri uri = DocumentsContract.buildDocumentUriUsingTree(dirUri, documentId);
|
||||||
|
boolean isDir = DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType);
|
||||||
|
result.add(new DocumentInfo(name, uri, isDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the uri cache by recreating it.
|
||||||
|
*/
|
||||||
|
private void refreshCache() {
|
||||||
|
resourceUriCache.clear();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (relativeRootUri == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri dirUri = relativeRootUri;
|
||||||
|
if (!isDocumentUri) {
|
||||||
|
// Convert "tree uri" to a "document uri"
|
||||||
|
dirUri = DocumentsContract.buildDocumentUriUsingTree(dirUri, DocumentsContract.getTreeDocumentId(dirUri));
|
||||||
|
}
|
||||||
|
buildCacheLevel("", dirUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ dependencies {
|
|||||||
implementation project(':vtm-extras')
|
implementation project(':vtm-extras')
|
||||||
implementation project(':vtm-themes')
|
implementation project(':vtm-themes')
|
||||||
// https://github.com/square/okhttp/issues/4481
|
// https://github.com/square/okhttp/issues/4481
|
||||||
implementation 'com.squareup.okhttp3:okhttp:3.12.5'
|
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||||
implementation "org.slf4j:slf4j-android:$slf4jVersion"
|
implementation "org.slf4j:slf4j-android:$slf4jVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apply plugin: 'maven'
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':vtm-gdx')
|
api project(':vtm-gdx')
|
||||||
api 'com.github.blackears:svgSalamander:v1.1.1'
|
api 'com.formdev:svgSalamander:1.1.2.4'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
@@ -23,11 +23,9 @@ import org.oscim.backend.Platform;
|
|||||||
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.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.*;
|
||||||
import java.awt.FontMetrics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -119,7 +117,7 @@ public class AwtGraphics extends CanvasAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
|
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException {
|
||||||
return createBitmap(relativePathPrefix, src, width, height, percent);
|
return createBitmap(relativePathPrefix, src, resourceProvider, width, height, percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 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).
|
||||||
@@ -22,7 +22,6 @@ import com.badlogic.gdx.Gdx;
|
|||||||
import com.badlogic.gdx.Input;
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.Input.Buttons;
|
import com.badlogic.gdx.Input.Buttons;
|
||||||
import com.badlogic.gdx.InputProcessor;
|
import com.badlogic.gdx.InputProcessor;
|
||||||
|
|
||||||
import org.oscim.layers.GenericLayer;
|
import org.oscim.layers.GenericLayer;
|
||||||
import org.oscim.layers.GroupLayer;
|
import org.oscim.layers.GroupLayer;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
@@ -79,19 +78,19 @@ public class InputHandler implements InputProcessor {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Input.Keys.UP:
|
case Input.Keys.UP:
|
||||||
mViewport.moveMap(0, -50);
|
|
||||||
mMap.updateMap(true);
|
|
||||||
break;
|
|
||||||
case Input.Keys.DOWN:
|
|
||||||
mViewport.moveMap(0, 50);
|
mViewport.moveMap(0, 50);
|
||||||
mMap.updateMap(true);
|
mMap.updateMap(true);
|
||||||
break;
|
break;
|
||||||
|
case Input.Keys.DOWN:
|
||||||
|
mViewport.moveMap(0, -50);
|
||||||
|
mMap.updateMap(true);
|
||||||
|
break;
|
||||||
case Input.Keys.LEFT:
|
case Input.Keys.LEFT:
|
||||||
mViewport.moveMap(-50, 0);
|
mViewport.moveMap(50, 0);
|
||||||
mMap.updateMap(true);
|
mMap.updateMap(true);
|
||||||
break;
|
break;
|
||||||
case Input.Keys.RIGHT:
|
case Input.Keys.RIGHT:
|
||||||
mViewport.moveMap(50, 0);
|
mViewport.moveMap(-50, 0);
|
||||||
mMap.updateMap(true);
|
mMap.updateMap(true);
|
||||||
break;
|
break;
|
||||||
case Input.Keys.D:
|
case Input.Keys.D:
|
||||||
@@ -110,6 +109,15 @@ public class InputHandler implements InputProcessor {
|
|||||||
mMap.animator().animateZoom(500, 2, 0, 0);
|
mMap.animator().animateZoom(500, 2, 0, 0);
|
||||||
mMap.updateMap(false);
|
mMap.updateMap(false);
|
||||||
break;
|
break;
|
||||||
|
case Input.Keys.MINUS:
|
||||||
|
mMap.animator().animateZoom(500, 0.5, 0, 0);
|
||||||
|
mMap.updateMap(true);
|
||||||
|
break;
|
||||||
|
case Input.Keys.PLUS:
|
||||||
|
case Input.Keys.EQUALS:
|
||||||
|
mMap.animator().animateZoom(500, 2, 0, 0);
|
||||||
|
mMap.updateMap(true);
|
||||||
|
break;
|
||||||
|
|
||||||
case Input.Keys.NUM_1:
|
case Input.Keys.NUM_1:
|
||||||
mMap.setTheme(VtmThemes.DEFAULT);
|
mMap.setTheme(VtmThemes.DEFAULT);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ apply plugin: 'maven'
|
|||||||
dependencies {
|
dependencies {
|
||||||
api project(':vtm')
|
api project(':vtm')
|
||||||
// https://github.com/square/okhttp/issues/4481
|
// https://github.com/square/okhttp/issues/4481
|
||||||
api 'com.squareup.okhttp3:okhttp:3.12.5'
|
api 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.7'
|
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.7'
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
package org.oscim.ios.test;
|
package org.oscim.ios.test;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.glutils.GLVersion;
|
import com.badlogic.gdx.graphics.glutils.GLVersion;
|
||||||
|
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
@@ -74,7 +73,7 @@ public class IOSPathLayerTest extends GdxMap {
|
|||||||
|
|
||||||
mMap.setMapPosition(0, 0, 1 << 2);
|
mMap.setMapPosition(0, 0, 1 << 2);
|
||||||
|
|
||||||
tex = Utils.loadTexture("", "patterns/pike.png", 0, 0, 100);
|
tex = Utils.loadTexture("", "patterns/pike.png", null, 0, 0, 100);
|
||||||
// tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png"));
|
// tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/pike.png"));
|
||||||
tex.mipmap = true;
|
tex.mipmap = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.7'
|
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.7'
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.oscim.backend.Platform;
|
|||||||
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.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ public class IosGraphics extends CanvasAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
|
protected Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException {
|
||||||
return createBitmap(relativePathPrefix, src, width, height, percent);
|
return createBitmap(relativePathPrefix, src, resourceProvider, width, height, percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ dependencies {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
main.java.srcDirs = ['src']
|
main.java.srcDirs = ['src']
|
||||||
test.java.srcDirs = ['test']
|
test.java.srcDirs = ['test']
|
||||||
|
test.resources.srcDirs = ['resources']
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
vtm-tests/resources/xmlthemetest.zip
Normal file
BIN
vtm-tests/resources/xmlthemetest.zip
Normal file
Binary file not shown.
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
|
* Copyright 2021 devemux86
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
public class ZipXmlThemeResourceProviderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openZip() throws IOException {
|
||||||
|
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(ZipXmlThemeResourceProviderTest.class.getResourceAsStream("/xmlthemetest.zip")));
|
||||||
|
Assert.assertNotNull(zis);
|
||||||
|
|
||||||
|
ZipXmlThemeResourceProvider zts = new ZipXmlThemeResourceProvider(zis);
|
||||||
|
|
||||||
|
// All files contained
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:one.xml"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:two.xml"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/three.xml"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/blue_star_1.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/test.txt"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/sub/four.xml"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/sub/blue_star_sub_1.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:res/sub/blue_star_sub_2.svg"));
|
||||||
|
|
||||||
|
//Relative Reference ok
|
||||||
|
Assert.assertNotNull(zts.createInputStream("", "file:res/sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream("res", "file:sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream("/", "file:res/sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream("/res", "file:sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream("res/", "file:/sub/blue_star_sub_2.svg"));
|
||||||
|
|
||||||
|
// Can get same files using various other formats
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "res/sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "/res/sub/blue_star_sub_2.svg"));
|
||||||
|
Assert.assertNotNull(zts.createInputStream(null, "file:/res/sub/blue_star_sub_2.svg"));
|
||||||
|
|
||||||
|
// Dirs NOT contained!
|
||||||
|
Assert.assertNull(zts.createInputStream(null, "file:res/"));
|
||||||
|
|
||||||
|
Assert.assertEquals(8, zts.getCount());
|
||||||
|
|
||||||
|
List<String> xmlThemes = zts.getXmlThemes();
|
||||||
|
Assert.assertEquals(4, xmlThemes.size());
|
||||||
|
Assert.assertTrue(xmlThemes.contains("one.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("two.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("res/three.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("res/sub/four.xml"));
|
||||||
|
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(zts.createInputStream(null, "file:res/test.txt")));
|
||||||
|
String line = reader.readLine();
|
||||||
|
Assert.assertEquals(line, "This is a test");
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openEmpty() throws IOException {
|
||||||
|
Assert.assertTrue(new ZipXmlThemeResourceProvider(null).getXmlThemes().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void scanZipForXmlThemes() throws IOException {
|
||||||
|
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(ZipXmlThemeResourceProviderTest.class.getResourceAsStream("/xmlthemetest.zip")));
|
||||||
|
Assert.assertNotNull(zis);
|
||||||
|
|
||||||
|
List<String> xmlThemes = ZipXmlThemeResourceProvider.scanXmlThemes(zis);
|
||||||
|
|
||||||
|
Assert.assertEquals(4, xmlThemes.size());
|
||||||
|
Assert.assertTrue(xmlThemes.contains("one.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("two.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("res/three.xml"));
|
||||||
|
Assert.assertTrue(xmlThemes.contains("res/sub/four.xml"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.15.0'
|
implementation 'org.mapsforge:mapsforge-core:0.16.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map:0.15.0'
|
implementation 'org.mapsforge:mapsforge-map:0.16.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-awt:0.15.0'
|
implementation 'org.mapsforge:mapsforge-map-awt:0.16.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-reader:0.15.0'
|
implementation 'org.mapsforge:mapsforge-map-reader:0.16.0'
|
||||||
implementation 'org.mapsforge:mapsforge-themes:0.15.0'
|
implementation 'org.mapsforge:mapsforge-themes:0.16.0'
|
||||||
implementation 'net.sf.kxml:kxml2:2.3.0'
|
implementation 'net.sf.kxml:kxml2:2.3.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -456,12 +456,14 @@
|
|||||||
<m k="lock" v="yes|true">
|
<m k="lock" v="yes|true">
|
||||||
<line stroke="#f8f8f8" use="fix" width="0.5" />
|
<line stroke="#f8f8f8" use="fix" width="0.5" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m e="way">
|
<m e="way">
|
||||||
<m closed="yes" k="natural" v="water">
|
<m closed="yes" k="natural" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
<!--<line use="water:outline" />-->
|
<!--<line use="water:outline" />-->
|
||||||
</m>
|
</m>
|
||||||
|
|||||||
@@ -400,6 +400,8 @@
|
|||||||
<m k="rank" v="9" zoom-min="9">
|
<m k="rank" v="9" zoom-min="9">
|
||||||
<line fade="9" use="water" width="0.1" />
|
<line fade="9" use="water" width="0.1" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
<!-- TODO this breaks the rendering -->
|
<!-- TODO this breaks the rendering -->
|
||||||
<!--<m v="riverbank|dock">
|
<!--<m v="riverbank|dock">
|
||||||
@@ -420,7 +422,7 @@
|
|||||||
<m e="way">
|
<m e="way">
|
||||||
<m closed="yes" k="kind" v="water">
|
<m closed="yes" k="kind" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
<!--<line use="water:outline" />-->
|
<!--<line use="water:outline" />-->
|
||||||
</m>
|
</m>
|
||||||
|
|||||||
@@ -374,11 +374,13 @@
|
|||||||
<m k="lock" v="yes|true">
|
<m k="lock" v="yes|true">
|
||||||
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m k="natural" v="water">
|
<m k="natural" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
<!--<line use="water:outline" width="0.5" fix="true" />-->
|
<!--<line use="water:outline" width="0.5" fix="true" />-->
|
||||||
</m>
|
</m>
|
||||||
|
|||||||
@@ -368,7 +368,7 @@
|
|||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m k="layer" v="water_name">
|
<m k="layer" v="water_name">
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
@@ -387,6 +387,8 @@
|
|||||||
<line use="river" width="0.3" />
|
<line use="river" width="0.3" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<!-- building -->
|
<!-- building -->
|
||||||
|
|||||||
@@ -267,6 +267,8 @@
|
|||||||
<line cap="butt" stroke="#000000" width="2.0" />
|
<line cap="butt" stroke="#000000" width="2.0" />
|
||||||
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#3b3b3b" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +308,7 @@
|
|||||||
|
|
||||||
<m k="natural" v="water">
|
<m k="natural" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#3b3b3b" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#3b3b3b" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
|||||||
@@ -267,6 +267,8 @@
|
|||||||
<line cap="butt" stroke="#000000" width="2.0" />
|
<line cap="butt" stroke="#000000" width="2.0" />
|
||||||
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +308,7 @@
|
|||||||
|
|
||||||
<m k="natural" v="water">
|
<m k="natural" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
|||||||
@@ -374,11 +374,13 @@
|
|||||||
<m k="lock" v="yes|true">
|
<m k="lock" v="yes|true">
|
||||||
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
<line cap="butt" stroke="#f8f8f8" width="1.5" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
|
<text fill="#404000" k="name" size="14" stroke="#aaffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m k="natural" v="water">
|
<m k="natural" v="water">
|
||||||
<area use="water" />
|
<area use="water" />
|
||||||
<caption area-size="0.4" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
<caption area-size="0.2" fill="#404000" k="name" size="16" stroke="#aaffffff"
|
||||||
stroke-width="2.0" />
|
stroke-width="2.0" />
|
||||||
<!--<line use="water:outline" width="0.5" fix="true" />-->
|
<!--<line use="water:outline" width="0.5" fix="true" />-->
|
||||||
</m>
|
</m>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 nebular
|
* Copyright 2017 nebular
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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,12 +60,25 @@ public enum VtmThemes implements ThemeFile {
|
|||||||
return AssetAdapter.readFileAsStream(mPath);
|
return AssetAdapter.readFileAsStream(mPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapsforgeTheme() {
|
public boolean isMapsforgeTheme() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
|
maven { url "https://plugins.gradle.org/m2/" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
||||||
classpath 'org.gretty:gretty:3.0.3'
|
classpath 'gradle.plugin.org.gretty:gretty:3.0.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
|
maven { url "https://plugins.gradle.org/m2/" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
||||||
classpath 'org.gretty:gretty:3.0.3'
|
classpath 'gradle.plugin.org.gretty:gretty:3.0.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.13'
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ package org.oscim.gdx.client;
|
|||||||
import com.google.gwt.canvas.client.Canvas;
|
import com.google.gwt.canvas.client.Canvas;
|
||||||
import com.google.gwt.canvas.dom.client.Context2d;
|
import com.google.gwt.canvas.dom.client.Context2d;
|
||||||
import com.google.gwt.canvas.dom.client.TextMetrics;
|
import com.google.gwt.canvas.dom.client.TextMetrics;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.Platform;
|
import org.oscim.backend.Platform;
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.backend.canvas.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -68,7 +68,7 @@ public class GwtGdxGraphics extends CanvasAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) {
|
public Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) {
|
||||||
String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src;
|
String pathName = (relativePathPrefix == null || relativePathPrefix.length() == 0 ? "" : relativePathPrefix + File.separatorChar) + src;
|
||||||
return new GwtBitmap(pathName);
|
return new GwtBitmap(pathName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2020 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -21,6 +22,7 @@ package org.oscim.backend;
|
|||||||
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.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ public abstract class CanvasAdapter {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(CanvasAdapter.class);
|
private static final Logger log = LoggerFactory.getLogger(CanvasAdapter.class);
|
||||||
|
|
||||||
private static final String PREFIX_ASSETS = "assets:";
|
private static final String PREFIX_ASSETS = "assets:";
|
||||||
private static final String PREFIX_FILE = "file:";
|
public static final String PREFIX_FILE = "file:";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The instance provided by backend
|
* The instance provided by backend
|
||||||
@@ -156,34 +158,45 @@ public abstract class CanvasAdapter {
|
|||||||
* @param src the resource
|
* @param src the resource
|
||||||
* @return the bitmap
|
* @return the bitmap
|
||||||
*/
|
*/
|
||||||
protected abstract Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, int width, int height, int percent) throws IOException;
|
protected abstract Bitmap loadBitmapAssetImpl(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException;
|
||||||
|
|
||||||
public static Bitmap getBitmapAsset(String relativePathPrefix, String src) throws IOException {
|
public static Bitmap getBitmapAsset(String relativePathPrefix, String src) throws IOException {
|
||||||
return getBitmapAsset(relativePathPrefix, src, 0, 0, 100);
|
return getBitmapAsset(relativePathPrefix, src, null, 0, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap getBitmapAsset(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
|
public static Bitmap getBitmapAsset(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException {
|
||||||
return g.loadBitmapAssetImpl(relativePathPrefix, src, width, height, percent);
|
return g.loadBitmapAssetImpl(relativePathPrefix, src, resourceProvider, width, height, percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Bitmap createBitmap(String relativePathPrefix, String src, int width, int height, int percent) throws IOException {
|
protected static Bitmap createBitmap(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) throws IOException {
|
||||||
if (src == null || src.length() == 0) {
|
if (src == null || src.length() == 0) {
|
||||||
// no image source defined
|
// no image source defined
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream inputStream;
|
InputStream inputStream = null;
|
||||||
if (src.startsWith(PREFIX_ASSETS)) {
|
if (resourceProvider != null) {
|
||||||
src = src.substring(PREFIX_ASSETS.length());
|
try {
|
||||||
inputStream = inputStreamFromAssets(relativePathPrefix, src);
|
inputStream = resourceProvider.createInputStream(relativePathPrefix, src);
|
||||||
} else if (src.startsWith(PREFIX_FILE)) {
|
} catch (IOException ioe) {
|
||||||
src = src.substring(PREFIX_FILE.length());
|
log.debug("Exception trying to access resource: " + src + " using custom provider: " + ioe);
|
||||||
inputStream = inputStreamFromFile(relativePathPrefix, src);
|
// Ignore and try to resolve input stream using the standard process
|
||||||
} else {
|
}
|
||||||
inputStream = inputStreamFromFile(relativePathPrefix, src);
|
}
|
||||||
|
|
||||||
if (inputStream == null)
|
if (inputStream == null) {
|
||||||
|
if (src.startsWith(PREFIX_ASSETS)) {
|
||||||
|
src = src.substring(PREFIX_ASSETS.length());
|
||||||
inputStream = inputStreamFromAssets(relativePathPrefix, src);
|
inputStream = inputStreamFromAssets(relativePathPrefix, src);
|
||||||
|
} else if (src.startsWith(PREFIX_FILE)) {
|
||||||
|
src = src.substring(PREFIX_FILE.length());
|
||||||
|
inputStream = inputStreamFromFile(relativePathPrefix, src);
|
||||||
|
} else {
|
||||||
|
inputStream = inputStreamFromFile(relativePathPrefix, src);
|
||||||
|
|
||||||
|
if (inputStream == null)
|
||||||
|
inputStream = inputStreamFromAssets(relativePathPrefix, src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to internal resources
|
// Fallback to internal resources
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2019 devemux86
|
* Copyright 2016-2019 devemux86
|
||||||
* Copyright 2018 Gustl22
|
* Copyright 2018 Gustl22
|
||||||
|
* Copyright 2021 blakfast
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -31,6 +32,7 @@ import org.oscim.renderer.bucket.SymbolItem;
|
|||||||
import org.oscim.renderer.bucket.TextItem;
|
import org.oscim.renderer.bucket.TextItem;
|
||||||
import org.oscim.theme.styles.TextStyle;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.Parameters;
|
||||||
import org.oscim.utils.geom.OBB2D;
|
import org.oscim.utils.geom.OBB2D;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -49,6 +51,7 @@ public class LabelPlacement {
|
|||||||
return (LabelTileData) tile.getData(LabelLayer.LABEL_DATA);
|
return (LabelTileData) tile.getData(LabelLayer.LABEL_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final float DISTANCE_COEFFICIENT = 3;
|
||||||
private static final float MIN_CAPTION_DIST = 5;
|
private static final float MIN_CAPTION_DIST = 5;
|
||||||
private static final float MIN_WAY_DIST = 3;
|
private static final float MIN_WAY_DIST = 3;
|
||||||
|
|
||||||
@@ -352,9 +355,18 @@ public class LabelPlacement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* estimation for visible area to be labeled */
|
/* estimation for visible area to be labeled */
|
||||||
int mw = (mMap.getWidth() + Tile.SIZE) / 2;
|
if (Parameters.DISTANT_LABELS) {
|
||||||
int mh = (mMap.getHeight() + Tile.SIZE) / 2;
|
int mw = mMap.getWidth();
|
||||||
mSquareRadius = mw * mw + mh * mh;
|
int mh = mMap.getHeight();
|
||||||
|
float k = pos.tilt / mMap.viewport().getMaxTilt() * DISTANCE_COEFFICIENT;
|
||||||
|
if (k < 0.5)
|
||||||
|
k = 0.5f;
|
||||||
|
mSquareRadius = (mw * mw + mh * mh) * k;
|
||||||
|
} else {
|
||||||
|
int mw = (mMap.getWidth() + Tile.SIZE) / 2;
|
||||||
|
int mh = (mMap.getHeight() + Tile.SIZE) / 2;
|
||||||
|
mSquareRadius = mw * mw + mh * mh;
|
||||||
|
}
|
||||||
|
|
||||||
/* scale of tiles zoom-level relative to current position */
|
/* scale of tiles zoom-level relative to current position */
|
||||||
double scale = pos.scale / (1 << zoom);
|
double scale = pos.scale / (1 << zoom);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
||||||
* Copyright 2014 Ludwig M Brinckmann
|
* Copyright 2014 Ludwig M Brinckmann
|
||||||
* Copyright 2014-2019 devemux86
|
* Copyright 2014-2021 devemux86
|
||||||
* Copyright 2014 Erik Duisters
|
* Copyright 2014 Erik Duisters
|
||||||
* Copyright 2014 Christian Pesch
|
* Copyright 2014 Christian Pesch
|
||||||
*
|
*
|
||||||
@@ -66,6 +66,11 @@ public class DefaultMapScaleBar extends MapScaleBar {
|
|||||||
this.paintScaleTextStroke = createTextPaint(Color.WHITE, 2, Paint.Style.STROKE);
|
this.paintScaleTextStroke = createTextPaint(Color.WHITE, 2, Paint.Style.STROKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setColor(int color) {
|
||||||
|
this.paintScaleBar.setColor(color);
|
||||||
|
this.paintScaleText.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the secondary {@link DistanceUnitAdapter} in use by this MapScaleBar
|
* @return the secondary {@link DistanceUnitAdapter} in use by this MapScaleBar
|
||||||
*/
|
*/
|
||||||
@@ -100,7 +105,7 @@ public class DefaultMapScaleBar extends MapScaleBar {
|
|||||||
paint.setColor(color);
|
paint.setColor(color);
|
||||||
paint.setStrokeWidth(strokeWidth * this.scale);
|
paint.setStrokeWidth(strokeWidth * this.scale);
|
||||||
paint.setStyle(style);
|
paint.setStyle(style);
|
||||||
paint.setStrokeCap(Paint.Cap.SQUARE);
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
return paint;
|
return paint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
vtm/src/org/oscim/scalebar/NauticalImperialUnitAdapter.java
Normal file
45
vtm/src/org/oscim/scalebar/NauticalImperialUnitAdapter.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Christian Pesch
|
||||||
|
* Copyright 2014-2021 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.scalebar;
|
||||||
|
|
||||||
|
public class NauticalImperialUnitAdapter implements DistanceUnitAdapter {
|
||||||
|
public static final NauticalImperialUnitAdapter INSTANCE = new NauticalImperialUnitAdapter();
|
||||||
|
public static final double METER_FOOT_RATIO = 0.3048;
|
||||||
|
public static final int ONE_MILE = 6076;
|
||||||
|
public static final int[] SCALE_BAR_VALUES = {30380000, 12152000, 6076000, 3038000, 1215200, 607600, 303800,
|
||||||
|
121520, 60760, 30380, 12152, 6076, 3038, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMeterRatio() {
|
||||||
|
return METER_FOOT_RATIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getScaleBarValues() {
|
||||||
|
return SCALE_BAR_VALUES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getScaleText(int mapScaleValue) {
|
||||||
|
if (mapScaleValue < ONE_MILE / 2) {
|
||||||
|
return mapScaleValue + " ft";
|
||||||
|
}
|
||||||
|
if (mapScaleValue == ONE_MILE / 2) {
|
||||||
|
return "0.5 nmi";
|
||||||
|
}
|
||||||
|
return (mapScaleValue / ONE_MILE) + " nmi";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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,10 @@ public class ExternalRenderTheme implements ThemeFile {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final long mFileModificationDate;
|
private final long mFileModificationDate;
|
||||||
|
private boolean mMapsforgeTheme;
|
||||||
private XmlRenderThemeMenuCallback mMenuCallback;
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
private final String mPath;
|
private final String mPath;
|
||||||
|
private XmlThemeResourceProvider mResourceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param fileName the path to the XML render theme file.
|
* @param fileName the path to the XML render theme file.
|
||||||
@@ -108,13 +111,28 @@ public class ExternalRenderTheme implements ThemeFile {
|
|||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return mResourceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapsforgeTheme() {
|
public boolean isMapsforgeTheme() {
|
||||||
return ThemeUtils.isMapsforgeTheme(this);
|
return mMapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
mMapsforgeTheme = mapsforgeTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -18,8 +19,6 @@ package org.oscim.theme;
|
|||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.utils.Utils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,14 +29,17 @@ public class StreamRenderTheme implements ThemeFile {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final InputStream mInputStream;
|
private final InputStream mInputStream;
|
||||||
|
private boolean mMapsforgeTheme;
|
||||||
private XmlRenderThemeMenuCallback mMenuCallback;
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
private final String mRelativePathPrefix;
|
private final String mRelativePathPrefix;
|
||||||
|
private XmlThemeResourceProvider mResourceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param relativePathPrefix the prefix for all relative resource paths.
|
* @param relativePathPrefix the prefix for all relative resource paths.
|
||||||
* @param inputStream an input stream containing valid render theme XML data.
|
* @param inputStream an input stream containing valid render theme XML data.
|
||||||
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
*/
|
*/
|
||||||
public StreamRenderTheme(String relativePathPrefix, InputStream inputStream) {
|
public StreamRenderTheme(String relativePathPrefix, InputStream inputStream) throws ThemeException {
|
||||||
this(relativePathPrefix, inputStream, null);
|
this(relativePathPrefix, inputStream, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,11 +47,11 @@ public class StreamRenderTheme implements ThemeFile {
|
|||||||
* @param relativePathPrefix the prefix for all relative resource paths.
|
* @param relativePathPrefix the prefix for all relative resource paths.
|
||||||
* @param inputStream an input stream containing valid render theme XML data.
|
* @param inputStream an input stream containing valid render theme XML data.
|
||||||
* @param menuCallback the interface callback to create a settings menu on the fly.
|
* @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 StreamRenderTheme(String relativePathPrefix, InputStream inputStream, XmlRenderThemeMenuCallback menuCallback) {
|
public StreamRenderTheme(String relativePathPrefix, InputStream inputStream, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
|
||||||
mRelativePathPrefix = relativePathPrefix;
|
mRelativePathPrefix = relativePathPrefix;
|
||||||
mInputStream = new BufferedInputStream(inputStream);
|
mInputStream = inputStream;
|
||||||
mInputStream.mark(0);
|
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,21 +84,31 @@ public class StreamRenderTheme implements ThemeFile {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getRenderThemeAsStream() throws ThemeException {
|
public InputStream getRenderThemeAsStream() throws ThemeException {
|
||||||
try {
|
|
||||||
mInputStream.reset();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ThemeException(e.getMessage());
|
|
||||||
}
|
|
||||||
return mInputStream;
|
return mInputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return mResourceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMapsforgeTheme() {
|
public boolean isMapsforgeTheme() {
|
||||||
return ThemeUtils.isMapsforgeTheme(this);
|
return mMapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
mMapsforgeTheme = mapsforgeTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
mMenuCallback = menuCallback;
|
mMenuCallback = menuCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2017 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -44,6 +45,11 @@ public interface ThemeFile extends Serializable {
|
|||||||
*/
|
*/
|
||||||
InputStream getRenderThemeAsStream() throws ThemeException;
|
InputStream getRenderThemeAsStream() throws ThemeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a custom provider to retrieve resources internally referenced by "src" attribute (e.g. images, icons).
|
||||||
|
*/
|
||||||
|
XmlThemeResourceProvider getResourceProvider();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells ThemeLoader if theme file is in Mapsforge format
|
* Tells ThemeLoader if theme file is in Mapsforge format
|
||||||
*
|
*
|
||||||
@@ -51,8 +57,18 @@ public interface ThemeFile extends Serializable {
|
|||||||
*/
|
*/
|
||||||
boolean isMapsforgeTheme();
|
boolean isMapsforgeTheme();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mapsforgeTheme true if theme file is in Mapsforge format
|
||||||
|
*/
|
||||||
|
void setMapsforgeTheme(boolean mapsforgeTheme);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param menuCallback the interface callback to create a settings menu on the fly.
|
* @param menuCallback the interface callback to create a settings menu on the fly.
|
||||||
*/
|
*/
|
||||||
void setMenuCallback(XmlRenderThemeMenuCallback menuCallback);
|
void setMenuCallback(XmlRenderThemeMenuCallback menuCallback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resourceProvider a custom provider to retrieve resources internally referenced by "src" attribute (e.g. images, icons).
|
||||||
|
*/
|
||||||
|
void setResourceProvider(XmlThemeResourceProvider resourceProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2017-2020 devemux86
|
* Copyright 2017-2021 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
|
||||||
@@ -117,7 +117,7 @@ public class XmlAtlasThemeBuilder extends XmlThemeBuilder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
RenderTheme createTheme(Rule[] rules) {
|
RenderTheme createTheme(Rule[] rules) {
|
||||||
return new AtlasRenderTheme(mMapBackground, mTextScale, rules, mLevels, mMapsforgeTheme, regionMap, atlasList);
|
return new AtlasRenderTheme(mMapBackground, mTextScale, rules, mLevels, mTheme.isMapsforgeTheme(), regionMap, atlasList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2014 Ludwig M Brinckmann
|
* Copyright 2014 Ludwig M Brinckmann
|
||||||
* Copyright 2016-2020 devemux86
|
* Copyright 2016-2021 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
|
||||||
* Copyright 2018 Izumi Kawashima
|
* Copyright 2018 Izumi Kawashima
|
||||||
* Copyright 2019 Murray Hughes
|
* Copyright 2019 Murray Hughes
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@@ -175,7 +176,6 @@ public class XmlThemeBuilder {
|
|||||||
private final ThemeCallback mThemeCallback;
|
private final ThemeCallback mThemeCallback;
|
||||||
RenderTheme mRenderTheme;
|
RenderTheme mRenderTheme;
|
||||||
|
|
||||||
final boolean mMapsforgeTheme;
|
|
||||||
private final float mScale;
|
private final float mScale;
|
||||||
|
|
||||||
private Set<String> mCategories;
|
private Set<String> mCategories;
|
||||||
@@ -193,7 +193,6 @@ public class XmlThemeBuilder {
|
|||||||
mTheme = theme;
|
mTheme = theme;
|
||||||
mPullParser = pullParser;
|
mPullParser = pullParser;
|
||||||
mThemeCallback = themeCallback;
|
mThemeCallback = themeCallback;
|
||||||
mMapsforgeTheme = theme.isMapsforgeTheme();
|
|
||||||
mScale = CanvasAdapter.getScale();
|
mScale = CanvasAdapter.getScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,14 +214,14 @@ public class XmlThemeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void endDocument() {
|
public void endDocument() {
|
||||||
if (mMapsforgeTheme) {
|
if (mTheme.isMapsforgeTheme()) {
|
||||||
// Building rule for Mapsforge themes
|
// Building rule for Mapsforge themes
|
||||||
mRulesList.add(buildingRule());
|
mRulesList.add(buildingRule());
|
||||||
}
|
}
|
||||||
|
|
||||||
Rule[] rules = new Rule[mRulesList.size()];
|
Rule[] rules = new Rule[mRulesList.size()];
|
||||||
for (int i = 0, n = rules.length; i < n; i++)
|
for (int i = 0, n = rules.length; i < n; i++)
|
||||||
rules[i] = mRulesList.get(i).onComplete(mMapsforgeTheme ? new int[1] : null);
|
rules[i] = mRulesList.get(i).onComplete(mTheme.isMapsforgeTheme() ? new int[1] : null);
|
||||||
|
|
||||||
mRenderTheme = createTheme(rules);
|
mRenderTheme = createTheme(rules);
|
||||||
|
|
||||||
@@ -237,7 +236,7 @@ public class XmlThemeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderTheme createTheme(Rule[] rules) {
|
RenderTheme createTheme(Rule[] rules) {
|
||||||
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
|
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mTheme.isMapsforgeTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void endElement() {
|
public void endElement() {
|
||||||
@@ -431,13 +430,13 @@ public class XmlThemeBuilder {
|
|||||||
else if ("NODE".equals(val))
|
else if ("NODE".equals(val))
|
||||||
element = Rule.Element.NODE;
|
element = Rule.Element.NODE;
|
||||||
} else if ("k".equals(name)) {
|
} else if ("k".equals(name)) {
|
||||||
if (mMapsforgeTheme) {
|
if (mTheme.isMapsforgeTheme()) {
|
||||||
if (!"*".equals(value))
|
if (!"*".equals(value))
|
||||||
keys = value;
|
keys = value;
|
||||||
} else
|
} else
|
||||||
keys = value;
|
keys = value;
|
||||||
} else if ("v".equals(name)) {
|
} else if ("v".equals(name)) {
|
||||||
if (mMapsforgeTheme) {
|
if (mTheme.isMapsforgeTheme()) {
|
||||||
if (!"*".equals(value))
|
if (!"*".equals(value))
|
||||||
values = value;
|
values = value;
|
||||||
} else
|
} else
|
||||||
@@ -666,7 +665,7 @@ public class XmlThemeBuilder {
|
|||||||
} else {
|
} else {
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
float symbolScale = Parameters.SYMBOL_SCALING == Parameters.SymbolScaling.ALL ? CanvasAdapter.symbolScale : 1;
|
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));
|
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, mTheme.getResourceProvider(), b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.texture != null && hasSymbol) {
|
if (b.texture != null && hasSymbol) {
|
||||||
@@ -779,7 +778,7 @@ public class XmlThemeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (src != null)
|
if (src != null)
|
||||||
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, mTheme.getResourceProvider(), b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
||||||
|
|
||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
@@ -935,7 +934,10 @@ public class XmlThemeBuilder {
|
|||||||
if ("schemaLocation".equals(name))
|
if ("schemaLocation".equals(name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ("version".equals(name))
|
if ("xmlns".equals(name))
|
||||||
|
mTheme.setMapsforgeTheme("http://mapsforge.org/renderTheme".equals(value));
|
||||||
|
|
||||||
|
else if ("version".equals(name))
|
||||||
version = Integer.parseInt(value);
|
version = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("map-background".equals(name)) {
|
else if ("map-background".equals(name)) {
|
||||||
@@ -956,7 +958,7 @@ public class XmlThemeBuilder {
|
|||||||
|
|
||||||
validateExists("version", version, elementName);
|
validateExists("version", version, elementName);
|
||||||
|
|
||||||
int renderThemeVersion = mMapsforgeTheme ? RENDER_THEME_VERSION_MAPSFORGE : RENDER_THEME_VERSION_VTM;
|
int renderThemeVersion = mTheme.isMapsforgeTheme() ? RENDER_THEME_VERSION_MAPSFORGE : RENDER_THEME_VERSION_VTM;
|
||||||
if (version > renderThemeVersion)
|
if (version > renderThemeVersion)
|
||||||
throw new ThemeException("invalid render theme version:" + version);
|
throw new ThemeException("invalid render theme version:" + version);
|
||||||
|
|
||||||
@@ -1006,7 +1008,7 @@ public class XmlThemeBuilder {
|
|||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
String symbol = null;
|
String symbol = null;
|
||||||
|
|
||||||
if (mMapsforgeTheme) {
|
if (mTheme.isMapsforgeTheme()) {
|
||||||
// Reset default priority
|
// Reset default priority
|
||||||
b.priority = DEFAULT_PRIORITY;
|
b.priority = DEFAULT_PRIORITY;
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1053,7 @@ public class XmlThemeBuilder {
|
|||||||
else if ("priority".equals(name)) {
|
else if ("priority".equals(name)) {
|
||||||
b.priority = Integer.parseInt(value);
|
b.priority = Integer.parseInt(value);
|
||||||
|
|
||||||
if (mMapsforgeTheme) {
|
if (mTheme.isMapsforgeTheme()) {
|
||||||
// Mapsforge: higher priorities are drawn first (0 = default priority)
|
// Mapsforge: higher priorities are drawn first (0 = default priority)
|
||||||
// VTM: lower priorities are drawn first (0 = highest priority)
|
// VTM: lower priorities are drawn first (0 = highest priority)
|
||||||
b.priority = FastMath.clamp(DEFAULT_PRIORITY - b.priority, 0, Integer.MAX_VALUE);
|
b.priority = FastMath.clamp(DEFAULT_PRIORITY - b.priority, 0, Integer.MAX_VALUE);
|
||||||
@@ -1102,7 +1104,7 @@ public class XmlThemeBuilder {
|
|||||||
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, (int) (b.symbolPercent * CanvasAdapter.symbolScale));
|
b.bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), symbol, mTheme.getResourceProvider(), 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());
|
||||||
}
|
}
|
||||||
@@ -1256,7 +1258,7 @@ public class XmlThemeBuilder {
|
|||||||
symbolScale = CanvasAdapter.symbolScale;
|
symbolScale = CanvasAdapter.symbolScale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), b.src, b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale));
|
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), b.src, mTheme.getResourceProvider(), 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) {
|
||||||
|
|||||||
32
vtm/src/org/oscim/theme/XmlThemeResourceProvider.java
Normal file
32
vtm/src/org/oscim/theme/XmlThemeResourceProvider.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a provider of resources referenced inside XML themes.
|
||||||
|
*/
|
||||||
|
public interface XmlThemeResourceProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param relativePath a relative path to use as a base for search in the resource provuider
|
||||||
|
* @param source a source string parsed out of an XML render theme "src" attribute.
|
||||||
|
* @return an InputStream to read the resource data from.
|
||||||
|
* @throws IOException if the resource cannot be found or an access error occurred.
|
||||||
|
*/
|
||||||
|
InputStream createInputStream(String relativePath, String source) throws IOException;
|
||||||
|
}
|
||||||
120
vtm/src/org/oscim/theme/ZipRenderTheme.java
Normal file
120
vtm/src/org/oscim/theme/ZipRenderTheme.java
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 devemux86
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
|
import org.oscim.utils.Utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ZipRenderTheme allows for customizing the rendering style of the map
|
||||||
|
* via an XML from an archive.
|
||||||
|
*/
|
||||||
|
public class ZipRenderTheme implements ThemeFile {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private boolean mMapsforgeTheme;
|
||||||
|
private XmlRenderThemeMenuCallback mMenuCallback;
|
||||||
|
private final String mRelativePathPrefix;
|
||||||
|
private XmlThemeResourceProvider mResourceProvider;
|
||||||
|
protected final String mXmlTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param xmlTheme the XML theme path in the archive.
|
||||||
|
* @param resourceProvider the custom provider to retrieve resources internally referenced by "src" attribute (e.g. images, icons).
|
||||||
|
* @throws ThemeException if an error occurs while reading the render theme XML.
|
||||||
|
*/
|
||||||
|
public ZipRenderTheme(String xmlTheme, XmlThemeResourceProvider resourceProvider) throws ThemeException {
|
||||||
|
this(xmlTheme, resourceProvider, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param xmlTheme the XML theme path in the archive.
|
||||||
|
* @param resourceProvider the custom provider to retrieve resources internally referenced by "src" attribute (e.g. images, icons).
|
||||||
|
* @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 ZipRenderTheme(String xmlTheme, XmlThemeResourceProvider resourceProvider, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
|
||||||
|
mXmlTheme = xmlTheme;
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
mMenuCallback = menuCallback;
|
||||||
|
|
||||||
|
mRelativePathPrefix = xmlTheme.substring(0, xmlTheme.lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
} else if (!(obj instanceof ZipRenderTheme)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ZipRenderTheme other = (ZipRenderTheme) 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 mResourceProvider.createInputStream(mRelativePathPrefix, mXmlTheme.substring(mXmlTheme.lastIndexOf("/") + 1));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ThemeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlThemeResourceProvider getResourceProvider() {
|
||||||
|
return mResourceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMapsforgeTheme() {
|
||||||
|
return mMapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMapsforgeTheme(boolean mapsforgeTheme) {
|
||||||
|
mMapsforgeTheme = mapsforgeTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMenuCallback(XmlRenderThemeMenuCallback menuCallback) {
|
||||||
|
mMenuCallback = menuCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceProvider(XmlThemeResourceProvider resourceProvider) {
|
||||||
|
mResourceProvider = resourceProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
167
vtm/src/org/oscim/theme/ZipXmlThemeResourceProvider.java
Normal file
167
vtm/src/org/oscim/theme/ZipXmlThemeResourceProvider.java
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 eddiemuc
|
||||||
|
* Copyright 2021 devemux86
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme;
|
||||||
|
|
||||||
|
import org.oscim.backend.CanvasAdapter;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource provider reading resource files out of a zip input stream.
|
||||||
|
* <p>
|
||||||
|
* Resources are cached.
|
||||||
|
*/
|
||||||
|
public class ZipXmlThemeResourceProvider implements XmlThemeResourceProvider {
|
||||||
|
|
||||||
|
private final Map<String, byte[]> files = new HashMap<>();
|
||||||
|
private final List<String> xmlThemes = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param zipInputStream zip stream to read resources from
|
||||||
|
* @throws IOException if a problem occurs reading the stream
|
||||||
|
*/
|
||||||
|
public ZipXmlThemeResourceProvider(ZipInputStream zipInputStream) throws IOException {
|
||||||
|
this(zipInputStream, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param zipInputStream zip stream to read resources from
|
||||||
|
* @param maxResourceSizeToCache only resources in the zip stream with a maximum size of this parameter (in bytes) are cached and provided
|
||||||
|
* @throws IOException if a problem occurs reading the stream
|
||||||
|
*/
|
||||||
|
public ZipXmlThemeResourceProvider(ZipInputStream zipInputStream, int maxResourceSizeToCache) throws IOException {
|
||||||
|
if (zipInputStream == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ZipEntry zipEntry;
|
||||||
|
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||||
|
if (zipEntry.isDirectory() || zipEntry.getSize() > maxResourceSizeToCache) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte[] entry = streamToBytes(zipInputStream, (int) zipEntry.getSize());
|
||||||
|
String fileName = zipEntryName(zipEntry.getName());
|
||||||
|
files.put(fileName, entry);
|
||||||
|
if (isXmlTheme(fileName)) {
|
||||||
|
xmlThemes.add(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(zipInputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream createInputStream(String relativePath, String source) {
|
||||||
|
String sourceKey = source;
|
||||||
|
if (sourceKey.startsWith(CanvasAdapter.PREFIX_FILE)) {
|
||||||
|
sourceKey = sourceKey.substring(CanvasAdapter.PREFIX_FILE.length());
|
||||||
|
}
|
||||||
|
if (sourceKey.startsWith("/")) {
|
||||||
|
sourceKey = sourceKey.substring(1);
|
||||||
|
}
|
||||||
|
if (relativePath != null) {
|
||||||
|
if (relativePath.startsWith("/")) {
|
||||||
|
relativePath = relativePath.substring(1);
|
||||||
|
}
|
||||||
|
if (relativePath.endsWith("/")) {
|
||||||
|
relativePath = relativePath.substring(0, relativePath.length() - 1);
|
||||||
|
}
|
||||||
|
sourceKey = relativePath.isEmpty() ? sourceKey : relativePath + "/" + sourceKey;
|
||||||
|
}
|
||||||
|
if (files.containsKey(sourceKey)) {
|
||||||
|
return new ByteArrayInputStream(files.get(sourceKey));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of files in the archive.
|
||||||
|
*/
|
||||||
|
public int getCount() {
|
||||||
|
return files.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the XML theme paths in the archive.
|
||||||
|
*/
|
||||||
|
public List<String> getXmlThemes() {
|
||||||
|
return xmlThemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isXmlTheme(String fileName) {
|
||||||
|
return fileName.toLowerCase(Locale.ROOT).endsWith(".xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans a given zip stream for contained xml themes without actually reading and storing its content in memory.
|
||||||
|
* <p>
|
||||||
|
* This method is useful to find out which xml themes are available across multiple zip files
|
||||||
|
* without actually have to read them all into memory.
|
||||||
|
*
|
||||||
|
* @param zipInputStream zip stream to read resources from
|
||||||
|
* @return the XML theme paths in the archive
|
||||||
|
* @throws IOException if a problem occurs reading the stream
|
||||||
|
*/
|
||||||
|
public static List<String> scanXmlThemes(ZipInputStream zipInputStream) throws IOException {
|
||||||
|
if (zipInputStream == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> xmlThemes = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ZipEntry zipEntry;
|
||||||
|
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||||
|
if (zipEntry.isDirectory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String fileName = zipEntryName(zipEntry.getName());
|
||||||
|
if (isXmlTheme(fileName)) {
|
||||||
|
xmlThemes.add(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(zipInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlThemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] streamToBytes(InputStream in, int size) throws IOException {
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
int count, offset = 0;
|
||||||
|
while ((count = in.read(bytes, offset, size)) > 0) {
|
||||||
|
size -= count;
|
||||||
|
offset += count;
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String zipEntryName(String name) {
|
||||||
|
if (name.startsWith("/")) {
|
||||||
|
return name.substring(1);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2018 devemux86
|
* Copyright 2016-2021 devemux86
|
||||||
* Copyright 2017 Andrey Novikov
|
* Copyright 2017 Andrey Novikov
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@@ -204,11 +204,11 @@ public abstract class TileSource {
|
|||||||
private final boolean success;
|
private final boolean success;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param errorMessage a textual message describing the error, must not be null.
|
* @param errorMessage a textual message describing the error.
|
||||||
*/
|
*/
|
||||||
public OpenResult(String errorMessage) {
|
public OpenResult(String errorMessage) {
|
||||||
if (errorMessage == null) {
|
if (errorMessage == null) {
|
||||||
throw new IllegalArgumentException("error message must not be null");
|
errorMessage = "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
this.success = false;
|
this.success = false;
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ public final class Parameters {
|
|||||||
*/
|
*/
|
||||||
public static boolean CUSTOM_TILE_SIZE = false;
|
public static boolean CUSTOM_TILE_SIZE = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendering of distant labels.
|
||||||
|
*/
|
||||||
|
public static boolean DISTANT_LABELS = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true the <code>MapEventLayer2</code> will be used instead of default <code>MapEventLayer</code>.
|
* If true the <code>MapEventLayer2</code> will be used instead of default <code>MapEventLayer</code>.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
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.renderer.bucket.TextureItem;
|
import org.oscim.renderer.bucket.TextureItem;
|
||||||
|
import org.oscim.theme.XmlThemeResourceProvider;
|
||||||
import org.oscim.utils.math.MathUtils;
|
import org.oscim.utils.math.MathUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -37,12 +38,12 @@ public final class Utils {
|
|||||||
/**
|
/**
|
||||||
* Load a texture from a specified location and optional dimensions.
|
* Load a texture from a specified location and optional dimensions.
|
||||||
*/
|
*/
|
||||||
public static TextureItem loadTexture(String relativePathPrefix, String src, int width, int height, int percent) {
|
public static TextureItem loadTexture(String relativePathPrefix, String src, XmlThemeResourceProvider resourceProvider, int width, int height, int percent) {
|
||||||
if (src == null || src.length() == 0)
|
if (src == null || src.length() == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = CanvasAdapter.getBitmapAsset(relativePathPrefix, src, width, height, percent);
|
Bitmap bitmap = CanvasAdapter.getBitmapAsset(relativePathPrefix, src, resourceProvider, width, height, percent);
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
log.debug("loading {}", src);
|
log.debug("loading {}", src);
|
||||||
return new TextureItem(potBitmap(bitmap), true);
|
return new TextureItem(potBitmap(bitmap), true);
|
||||||
|
|||||||
Reference in New Issue
Block a user