Skip to content

Commit ab73081

Browse files
rom14514gunt0001shubham7109
authored
Sample - add elevation source from tile package (#432)
Co-authored-by: Gunther Heppner <gheppner@esri.com> Co-authored-by: Shubham Sharma <shubhamsharma@esri.com>
1 parent b12a8f9 commit ab73081

File tree

10 files changed

+344
-0
lines changed

10 files changed

+344
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Add elevation source from tile package
2+
3+
Set the terrain surface with elevation described by a local tile package.
4+
5+
![Image of add elevation source from tile package](add-elevation-source-from-tile-package.png)
6+
7+
## Use case
8+
9+
In a scene view, the terrain surface is what the basemap, operational layers, and graphics are draped onto. For example, when viewing a scene in a mountainous region, applying a terrain surface to the scene will help in recognizing the slopes, valleys, and elevated areas.
10+
11+
## How to use the sample
12+
13+
When loaded, the sample will show a scene with a terrain surface applied. Pan and zoom to explore the scene and observe how the terrain surface allows visualizing elevation differences.
14+
15+
## How it works
16+
17+
1. Create an `ArcGISScene` with an `ArcGISImagery` basemap style.
18+
2. Create an `ArcGISTiledElevationSource` using the path to a local elevation tile package (.tpkx).
19+
3. Create a `Surface` and add the elevation source to the surface's `elevationSources` collection.
20+
4. Assign the `surface` to the scene's `baseSurface`.
21+
5. Display the scene in a `SceneView` by passing the `ArcGISScene`.
22+
23+
## Relevant API
24+
25+
* ArcGISTiledElevationSource
26+
* Surface
27+
28+
## Offline data
29+
30+
This sample uses the [Monterey Elevation](https://www.arcgis.com/home/item.html?id=52ca74b4ba8042b78b3c653696f34a9c) tile package, using CompactV2 storage format (.tpkx). It is downloaded from ArcGIS Online automatically.
31+
32+
## Additional information
33+
34+
The tile package must be a LERC (limited error raster compression) encoded TPK/TPKX. Details on can be found in the topic [Share a tile package](https://pro.arcgis.com/en/pro-app/help/sharing/overview/tile-package.htm) in the *ArcGIS Pro* documentation.
35+
36+
## Tags
37+
38+
3D, elevation, LERC, surface, terrain, tile cache
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"category": "Scenes",
3+
"description": "Set the terrain surface with elevation described by a local tile package.",
4+
"formal_name": "AddElevationSourceFromTilePackage",
5+
"ignore": false,
6+
"images": [
7+
"add-elevation-source-from-tile-package.png"
8+
],
9+
"keywords": [
10+
"3D",
11+
"LERC",
12+
"elevation",
13+
"surface",
14+
"terrain",
15+
"tile cache",
16+
"ArcGISTiledElevationSource",
17+
"Surface"
18+
],
19+
"language": "kotlin",
20+
"provision_from": [
21+
"https://www.arcgis.com/home/item.html?id=52ca74b4ba8042b78b3c653696f34a9c"
22+
],
23+
"provision_to": [],
24+
"redirect_from": "",
25+
"relevant_apis": [
26+
"ArcGISTiledElevationSource",
27+
"Surface"
28+
],
29+
"snippets": [
30+
"src/main/java/com/esri/arcgismaps/sample/addelevationsourcefromtilepackage/components/AddElevationSourceFromTilePackageViewModel.kt",
31+
"src/main/java/com/esri/arcgismaps/sample/addelevationsourcefromtilepackage/MainActivity.kt",
32+
"src/main/java/com/esri/arcgismaps/sample/addelevationsourcefromtilepackage/DownloadActivity.kt",
33+
"src/main/java/com/esri/arcgismaps/sample/addelevationsourcefromtilepackage/screens/AddElevationSourceFromTilePackageScreen.kt"
34+
],
35+
"title": "Add elevation source from tile package"
36+
}
525 KB
Loading
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
alias(libs.plugins.arcgismaps.android.library)
3+
alias(libs.plugins.arcgismaps.android.library.compose)
4+
alias(libs.plugins.arcgismaps.kotlin.sample)
5+
alias(libs.plugins.gradle.secrets)
6+
}
7+
8+
secrets {
9+
// this file doesn't contain secrets, it just provides defaults which can be committed into git.
10+
defaultPropertiesFileName = "secrets.defaults.properties"
11+
}
12+
13+
android {
14+
namespace = "com.esri.arcgismaps.sample.addelevationsourcefromtilepackage"
15+
buildFeatures {
16+
buildConfig = true
17+
}
18+
}
19+
20+
dependencies {
21+
// Only module specific dependencies needed here
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
6+
<application><activity
7+
android:exported="true"
8+
android:name=".MainActivity"
9+
android:label="@string/add_elevation_source_from_tile_package_app_name">
10+
11+
</activity>
12+
<activity
13+
android:name=".DownloadActivity"
14+
android:exported="true"
15+
android:label="@string/add_elevation_source_from_tile_package_app_name" />
16+
</application>
17+
18+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.esri.arcgismaps.sample.addelevationsourcefromtilepackage
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import com.esri.arcgismaps.sample.sampleslib.DownloaderActivity
6+
7+
class DownloadActivity : DownloaderActivity() {
8+
override fun onCreate(savedInstanceState: Bundle?) {
9+
super.onCreate(savedInstanceState)
10+
downloadAndStartSample(
11+
Intent(this, MainActivity::class.java),
12+
getString(R.string.add_elevation_source_from_tile_package_app_name),
13+
listOf(
14+
"https://arcgisruntime.maps.arcgis.com/home/item.html?id=52ca74b4ba8042b78b3c653696f34a9c"
15+
)
16+
)
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.addelevationsourcefromtilepackage
18+
19+
import android.os.Bundle
20+
import androidx.activity.ComponentActivity
21+
import androidx.activity.compose.setContent
22+
import androidx.compose.material3.MaterialTheme
23+
import androidx.compose.material3.Surface
24+
import androidx.compose.runtime.Composable
25+
import com.arcgismaps.ApiKey
26+
import com.arcgismaps.ArcGISEnvironment
27+
import com.esri.arcgismaps.sample.sampleslib.theme.SampleAppTheme
28+
import com.esri.arcgismaps.sample.addelevationsourcefromtilepackage.screens.AddElevationSourceFromTilePackageScreen
29+
30+
class MainActivity : ComponentActivity() {
31+
32+
override fun onCreate(savedInstanceState: Bundle?) {
33+
super.onCreate(savedInstanceState)
34+
// authentication with an API key or named user is
35+
// required to access basemaps and other location services
36+
ArcGISEnvironment.apiKey = ApiKey.create(BuildConfig.ACCESS_TOKEN)
37+
38+
setContent {
39+
SampleAppTheme {
40+
AddElevationSourceFromTilePackageApp()
41+
}
42+
}
43+
}
44+
45+
@Composable
46+
private fun AddElevationSourceFromTilePackageApp() {
47+
Surface(color = MaterialTheme.colorScheme.background) {
48+
AddElevationSourceFromTilePackageScreen(
49+
sampleName = getString(R.string.add_elevation_source_from_tile_package_app_name)
50+
)
51+
}
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.addelevationsourcefromtilepackage.components
18+
19+
import android.app.Application
20+
import androidx.lifecycle.AndroidViewModel
21+
import androidx.lifecycle.viewModelScope
22+
import com.arcgismaps.geometry.Point
23+
import com.arcgismaps.geometry.SpatialReference
24+
import com.arcgismaps.mapping.ArcGISScene
25+
import com.arcgismaps.mapping.ArcGISTiledElevationSource
26+
import com.arcgismaps.mapping.BasemapStyle
27+
import com.arcgismaps.mapping.Surface
28+
import com.arcgismaps.mapping.Viewpoint
29+
import com.arcgismaps.mapping.view.Camera
30+
import com.esri.arcgismaps.sample.addelevationsourcefromtilepackage.R
31+
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
32+
import kotlinx.coroutines.launch
33+
import java.io.File
34+
35+
class AddElevationSourceFromTilePackageViewModel(app: Application) : AndroidViewModel(app) {
36+
// Message dialog view model to display errors
37+
val messageDialogVM = MessageDialogViewModel()
38+
39+
// Base provision path for this sample's offline resources
40+
private val provisionPath: String by lazy {
41+
val basePath = app.getExternalFilesDir(null)?.path ?: ""
42+
basePath + File.separator + app.getString(R.string.add_elevation_source_from_tile_package_app_name)
43+
}
44+
45+
// Camera location point (Monterey, CA)
46+
private val cameraLocation: Point by lazy {
47+
Point(
48+
x = -121.8,
49+
y = 36.525,
50+
z = 300.0,
51+
spatialReference = SpatialReference.wgs84()
52+
)
53+
}
54+
55+
// Camera to view the scene
56+
private val camera: Camera by lazy {
57+
Camera(
58+
locationPoint = cameraLocation,
59+
heading = 180.0,
60+
pitch = 80.0,
61+
roll = 0.0
62+
)
63+
}
64+
65+
// Create the ArcGISScene with imagery basemap
66+
val arcGISScene: ArcGISScene = ArcGISScene(BasemapStyle.ArcGISImagery).apply {
67+
// Create a surface and add the local elevation source if found
68+
baseSurface = Surface().apply {
69+
val tilePackageFile = File(provisionPath, "MontereyElevation.tpkx")
70+
if (tilePackageFile.exists()) {
71+
elevationSources.add(ArcGISTiledElevationSource(tilePackageFile.path))
72+
} else {
73+
messageDialogVM.showMessageDialog(
74+
title = "Elevation tile package not found",
75+
description = "Expected file at:\n${tilePackageFile.path}"
76+
)
77+
}
78+
}
79+
// Set initial viewpoint using boundingGeometry with camera
80+
initialViewpoint = Viewpoint(
81+
boundingGeometry = cameraLocation,
82+
camera = camera
83+
)
84+
}
85+
86+
init {
87+
viewModelScope.launch {
88+
arcGISScene.load().onFailure { error ->
89+
messageDialogVM.showMessageDialog(error)
90+
}
91+
}
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.addelevationsourcefromtilepackage.screens
18+
19+
import androidx.compose.foundation.layout.Column
20+
import androidx.compose.foundation.layout.fillMaxSize
21+
import androidx.compose.foundation.layout.padding
22+
import androidx.compose.material3.Scaffold
23+
import androidx.compose.runtime.Composable
24+
import androidx.compose.ui.Modifier
25+
import androidx.lifecycle.viewmodel.compose.viewModel
26+
import com.arcgismaps.toolkit.geoviewcompose.SceneView
27+
import com.esri.arcgismaps.sample.addelevationsourcefromtilepackage.components.AddElevationSourceFromTilePackageViewModel
28+
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialog
29+
import com.esri.arcgismaps.sample.sampleslib.components.SampleTopAppBar
30+
31+
@Composable
32+
fun AddElevationSourceFromTilePackageScreen(sampleName: String) {
33+
val sceneViewModel: AddElevationSourceFromTilePackageViewModel = viewModel()
34+
35+
Scaffold(
36+
topBar = { SampleTopAppBar(title = sampleName) },
37+
content = { padding ->
38+
Column(
39+
modifier = Modifier
40+
.fillMaxSize()
41+
.padding(padding)
42+
) {
43+
SceneView(
44+
modifier = Modifier
45+
.fillMaxSize()
46+
.weight(1f),
47+
arcGISScene = sceneViewModel.arcGISScene
48+
)
49+
}
50+
51+
// Display a dialog if the sample encounters an error
52+
sceneViewModel.messageDialogVM.apply {
53+
if (dialogStatus) {
54+
MessageDialog(
55+
title = messageTitle,
56+
description = messageDescription,
57+
onDismissRequest = ::dismissDialog
58+
)
59+
}
60+
}
61+
}
62+
)
63+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="add_elevation_source_from_tile_package_app_name">Add elevation source from tile package</string>
3+
</resources>

0 commit comments

Comments
 (0)