Skip to content

Commit eb77a67

Browse files
authored
Hillshading from HGT digital elevation model data (#1189)
1 parent cd03dff commit eb77a67

File tree

17 files changed

+813
-56
lines changed

17 files changed

+813
-56
lines changed

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ If you have any questions or problems, don't hesitate to ask the [forum](https:/
1818
- Java map library
1919
- OpenGL vector-tile rendering
2020
- Themeable vector layers ([render themes](docs/Rendertheme.md))
21+
- Hillshading from HGT digital elevation model data
2122
- Support for multiple tile sources:
22-
- OpenScienceMap vector tiles
2323
- Mapsforge vector maps
24-
- MBTiles vector & raster maps
25-
- Mapbox vector tiles (e.g. Mapilion, Mapzen, Nextzen, OpenMapTiles)
26-
- GeoJSON vector tiles (e.g. Mapzen, Nextzen)
27-
- Raster tiles: any quadtree-scheme tiles as texture
24+
- MBTiles vector & raster
25+
- Mapbox vector tiles
26+
- GeoJSON vector tiles
27+
- OpenScienceMap vector tiles
28+
- Raster tiles
2829
- Backends:
2930
- Android ([example](vtm-android-example))
3031
- iOS (libGDX/RoboVM, [instructions](docs/ios.md))
@@ -34,13 +35,14 @@ If you have any questions or problems, don't hesitate to ask the [forum](https:/
3435

3536
### Projects
3637
- **vtm** core library
38+
- **vtm-hillshading** hillshading
39+
- **vtm-jts** overlays
40+
- **vtm-http** online tiles
41+
- **vtm-mvt** MBTiles
3742
- **vtm-android** Android backend
3843
- **vtm-android-example** Android examples
3944
- **vtm-gdx** common libGDX backend
40-
- **vtm-android-gdx** Android libGDX backend
4145
- **vtm-desktop** Desktop libGDX backend
42-
- **vtm-desktop-lwjgl** Desktop LWJGL backend
43-
- **vtm-desktop-lwjgl3** Desktop LWJGL 3 backend
4446
- **vtm-playground** Desktop examples
4547
- **vtm-ios** iOS libGDX backend
4648
- **vtm-ios-example** iOS examples

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ allprojects {
66
group = 'org.mapsforge'
77
version = 'master-SNAPSHOT'
88

9+
ext.mapsforgeVersion = "0.24.1"
910
ext.gdxVersion = "1.11.0"
1011
ext.gwtVersion = "2.8.2"
1112

docs/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Next version
44

5+
- Hillshading from HGT digital elevation model data [#1189](https://github.com/mapsforge/vtm/pull/1189)
56
- Motorider map theme improvements [#1183](https://github.com/mapsforge/vtm/issues/1183)
67
- Rename `MapDatabase` to `MapFile` [#1184](https://github.com/mapsforge/vtm/pull/1184)
78
- Rename `MultiMapDatabase` to `MultiMapFile`

docs/Integration.md

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,18 @@ implementation '[PACKAGE]:vtm:[CURRENT-VERSION]'
2626
implementation '[PACKAGE]:vtm-themes:[CURRENT-VERSION]'
2727
```
2828

29-
### Android
29+
## Android
3030

3131
```groovy
32-
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-armeabi-v7a'
33-
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-arm64-v8a'
34-
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-x86'
35-
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-x86_64'
3632
implementation '[PACKAGE]:vtm-android:[CURRENT-VERSION]'
37-
implementation 'com.caverock:androidsvg:1.4'
38-
```
39-
40-
### Android (libGDX)
41-
42-
```groovy
4333
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-armeabi-v7a'
4434
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-arm64-v8a'
4535
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-x86'
4636
runtimeOnly '[PACKAGE]:vtm-android:[CURRENT-VERSION]:natives-x86_64'
47-
implementation '[PACKAGE]:vtm-android:[CURRENT-VERSION]'
48-
implementation '[PACKAGE]:vtm-gdx:[CURRENT-VERSION]'
49-
runtimeOnly '[PACKAGE]:vtm-android-gdx:[CURRENT-VERSION]:natives-armeabi-v7a'
50-
runtimeOnly '[PACKAGE]:vtm-android-gdx:[CURRENT-VERSION]:natives-arm64-v8a'
51-
runtimeOnly '[PACKAGE]:vtm-android-gdx:[CURRENT-VERSION]:natives-x86'
52-
runtimeOnly '[PACKAGE]:vtm-android-gdx:[CURRENT-VERSION]:natives-x86_64'
53-
implementation '[PACKAGE]:vtm-android-gdx:[CURRENT-VERSION]'
54-
implementation 'com.badlogicgames.gdx:gdx:1.11.0'
55-
implementation 'com.badlogicgames.gdx:gdx-backend-android:1.11.0'
5637
implementation 'com.caverock:androidsvg:1.4'
5738
```
5839

59-
### iOS
60-
61-
Detailed iOS instructions can be found [here](ios.md).
62-
63-
### Desktop
40+
## Desktop
6441

6542
```groovy
6643
implementation '[PACKAGE]:vtm-gdx:[CURRENT-VERSION]'
@@ -74,7 +51,7 @@ implementation 'guru.nidi.com.kitfox:svgSalamander:1.1.3'
7451
implementation 'net.sf.kxml:kxml2:2.3.0'
7552
```
7653

77-
#### Desktop (LWJGL 2)
54+
### LWJGL 2
7855

7956
```groovy
8057
implementation '[PACKAGE]:vtm-desktop-lwjgl:[CURRENT-VERSION]'
@@ -85,7 +62,7 @@ runtimeOnly 'org.lwjgl.lwjgl:lwjgl-platform:2.9.3:natives-osx'
8562
runtimeOnly 'org.lwjgl.lwjgl:lwjgl-platform:2.9.3:natives-windows'
8663
```
8764

88-
#### Desktop (LWJGL 3)
65+
### LWJGL 3
8966

9067
```groovy
9168
implementation '[PACKAGE]:vtm-desktop-lwjgl3:[CURRENT-VERSION]'
@@ -96,7 +73,18 @@ runtimeOnly 'org.lwjgl:lwjgl:3.3.1:natives-macos'
9673
runtimeOnly 'org.lwjgl:lwjgl:3.3.1:natives-windows'
9774
```
9875

99-
### JTS overlays
76+
## Features
77+
78+
### Hillshading
79+
80+
```groovy
81+
implementation '[PACKAGE]:vtm-hillshading:[CURRENT-VERSION]'
82+
implementation 'org.mapsforge:mapsforge-core:0.24.1'
83+
implementation 'org.mapsforge:mapsforge-map:0.24.1'
84+
implementation 'org.mapsforge:mapsforge-map-android:0.24.1'
85+
```
86+
87+
### Overlays
10088

10189
```groovy
10290
implementation '[PACKAGE]:vtm-jts:[CURRENT-VERSION]'

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ include ':vtm-desktop-lwjgl3'
2626
include ':vtm-extras'
2727
include ':vtm-gdx'
2828
include ':vtm-gdx-poi3d'
29+
include ':vtm-hillshading'
2930
include ':vtm-http'
3031
//include ':vtm-ios'
3132
//include ':vtm-ios-example'

vtm-android-example/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
<activity
5252
android:name=".GdxPoi3DActivity"
5353
android:configChanges="keyboardHidden|orientation|screenSize" />
54+
<activity
55+
android:name=".HillshadingActivity"
56+
android:configChanges="keyboardHidden|orientation|screenSize" />
5457
<!--<activity
5558
android:name=".JeoIndoorActivity"
5659
android:configChanges="keyboardHidden|orientation|screenSize" />-->

vtm-android-example/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dependencies {
44
implementation project(':vtm-android')
55
implementation project(':vtm-android-mvt')
66
implementation project(':vtm-extras')
7+
implementation project(':vtm-hillshading')
78
implementation project(':vtm-http')
89
//implementation project(':vtm-jeo')
910
implementation project(':vtm-json')
@@ -15,7 +16,8 @@ dependencies {
1516
implementation project(':vtm-gdx')
1617
implementation project(':vtm-gdx-poi3d')
1718

18-
implementation 'org.mapsforge:mapsforge-poi-android:0.24.0'
19+
implementation "org.mapsforge:mapsforge-map-android:$mapsforgeVersion"
20+
implementation "org.mapsforge:mapsforge-poi-android:$mapsforgeVersion"
1921
}
2022

2123
android {
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* Copyright 2025 devemux86
3+
*
4+
* This program is free software: you can redistribute it and/or modify it under the
5+
* terms of the GNU Lesser General Public License as published by the Free Software
6+
* Foundation, either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
9+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10+
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public License along with
13+
* this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
package org.oscim.android.test;
16+
17+
import android.app.Activity;
18+
import android.content.Intent;
19+
import android.graphics.Color;
20+
import android.net.Uri;
21+
import android.os.Bundle;
22+
import android.widget.Toast;
23+
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
24+
import org.mapsforge.map.android.hills.DemFolderAndroidContent;
25+
import org.mapsforge.map.layer.hills.AdaptiveClasyHillShading;
26+
import org.mapsforge.map.layer.hills.DemFolder;
27+
import org.oscim.android.cache.TileCache;
28+
import org.oscim.backend.CanvasAdapter;
29+
import org.oscim.core.MapPosition;
30+
import org.oscim.core.Tile;
31+
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
32+
import org.oscim.layers.tile.buildings.BuildingLayer;
33+
import org.oscim.layers.tile.vector.VectorTileLayer;
34+
import org.oscim.layers.tile.vector.labeling.LabelLayer;
35+
import org.oscim.map.Viewport;
36+
import org.oscim.renderer.BitmapRenderer;
37+
import org.oscim.renderer.GLViewport;
38+
import org.oscim.scalebar.*;
39+
import org.oscim.theme.internal.VtmThemes;
40+
import org.oscim.tiling.ITileCache;
41+
import org.oscim.tiling.source.hills.HillshadingTileSource;
42+
import org.oscim.tiling.source.mapfile.MapFileTileSource;
43+
import org.oscim.tiling.source.mapfile.MapInfo;
44+
45+
import java.io.FileInputStream;
46+
import java.util.logging.Logger;
47+
48+
/**
49+
* Standard map view with hill shading.
50+
*/
51+
public class HillshadingActivity extends MapActivity {
52+
53+
private static final Logger log = Logger.getLogger(HillshadingActivity.class.getName());
54+
55+
private static final boolean USE_CACHE = false;
56+
57+
private static final int SELECT_MAP_FILE = 0;
58+
private static final int SELECT_DEM_DIR = 1;
59+
60+
@Override
61+
protected void onCreate(Bundle savedInstanceState) {
62+
super.onCreate(savedInstanceState);
63+
64+
// Select map file
65+
Toast.makeText(this, "Select map file", Toast.LENGTH_SHORT).show();
66+
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
67+
intent.addCategory(Intent.CATEGORY_OPENABLE);
68+
intent.setType("*/*");
69+
startActivityForResult(intent, SELECT_MAP_FILE);
70+
}
71+
72+
@Override
73+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
74+
75+
if (requestCode == SELECT_MAP_FILE) {
76+
if (resultCode != Activity.RESULT_OK || data == null) {
77+
finish();
78+
return;
79+
}
80+
81+
try {
82+
Uri uri = data.getData();
83+
84+
MapFileTileSource tileSource = new MapFileTileSource();
85+
//tileSource.setPreferredLanguage("en");
86+
FileInputStream fis = (FileInputStream) getContentResolver().openInputStream(uri);
87+
tileSource.setMapFileInputStream(fis);
88+
89+
VectorTileLayer tileLayer = mMap.setBaseMap(tileSource);
90+
mMap.setTheme(VtmThemes.MOTORIDER);
91+
92+
mMap.layers().add(new BuildingLayer(mMap, tileLayer));
93+
mMap.layers().add(new LabelLayer(mMap, tileLayer));
94+
95+
DefaultMapScaleBar mapScaleBar = new DefaultMapScaleBar(mMap);
96+
mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
97+
mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
98+
mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
99+
mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_LEFT);
100+
101+
MapScaleBarLayer mapScaleBarLayer = new MapScaleBarLayer(mMap, mapScaleBar);
102+
BitmapRenderer renderer = mapScaleBarLayer.getRenderer();
103+
renderer.setPosition(GLViewport.Position.BOTTOM_LEFT);
104+
renderer.setOffset(5 * CanvasAdapter.getScale(), 0);
105+
mMap.layers().add(mapScaleBarLayer);
106+
107+
MapInfo info = tileSource.getMapInfo();
108+
if (!info.boundingBox.contains(mMap.getMapPosition().getGeoPoint())) {
109+
MapPosition pos = new MapPosition();
110+
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
111+
mMap.setMapPosition(pos);
112+
mPrefs.clear();
113+
}
114+
115+
// Select DEM folder
116+
Toast.makeText(this, "Select DEM folder", Toast.LENGTH_SHORT).show();
117+
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
118+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
119+
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
120+
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
121+
);
122+
startActivityForResult(intent, SELECT_DEM_DIR);
123+
} catch (Exception e) {
124+
log.severe(e.toString());
125+
finish();
126+
}
127+
} else if (requestCode == SELECT_DEM_DIR) {
128+
if (resultCode != Activity.RESULT_OK || data == null)
129+
return;
130+
131+
Uri uri = data.getData();
132+
133+
DemFolder demFolder = new DemFolderAndroidContent(uri, this, getContentResolver());
134+
final AdaptiveClasyHillShading algorithm = new AdaptiveClasyHillShading()
135+
// You can make additional behavior adjustments
136+
.setAdaptiveZoomEnabled(true)
137+
// .setZoomMinOverride(0)
138+
// .setZoomMaxOverride(17)
139+
.setCustomQualityScale(1);
140+
HillshadingTileSource hillshadingTileSource = new HillshadingTileSource(Viewport.MIN_ZOOM_LEVEL, Viewport.MAX_ZOOM_LEVEL, demFolder, algorithm, 128, Color.BLACK, AndroidGraphicFactory.INSTANCE);
141+
if (USE_CACHE) {
142+
ITileCache tileCache = new TileCache(this, getExternalCacheDir().getAbsolutePath(), "hillshading");
143+
hillshadingTileSource.setCache(tileCache);
144+
}
145+
mMap.layers().add(new BitmapTileLayer(mMap, hillshadingTileSource, 150));
146+
mMap.clearMap();
147+
}
148+
}
149+
}

vtm-android-example/src/org/oscim/android/test/Samples.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ protected void onCreate(Bundle savedInstanceState) {
8888

8989
linearLayout.addView(createLabel(null));
9090
linearLayout.addView(createButton(LocationTextureActivity.class));
91+
linearLayout.addView(createButton(HillshadingActivity.class));
9192
linearLayout.addView(createButton(PoiSearchActivity.class));
9293
linearLayout.addView(createButton(MapsforgeStyleActivity.class));
9394
linearLayout.addView(createButton(MapsforgeS3DBActivity.class));

vtm-hillshading/build.gradle

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apply plugin: 'java-library'
2+
apply plugin: 'maven-publish'
3+
4+
dependencies {
5+
api project(':vtm')
6+
api "org.mapsforge:mapsforge-map:$mapsforgeVersion"
7+
}
8+
9+
sourceSets {
10+
main.java.srcDirs = ['src']
11+
}
12+
13+
publishing {
14+
publications {
15+
maven(MavenPublication) {
16+
from components.java
17+
}
18+
}
19+
}
20+
21+
if (project.hasProperty("SONATYPE_USERNAME")) {
22+
afterEvaluate {
23+
project.apply from: "${rootProject.projectDir}/deploy.gradle"
24+
}
25+
}

0 commit comments

Comments
 (0)