Skip to content

Commit

Permalink
PR fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TADraeseke committed Feb 3, 2025
1 parent 16e2f5d commit d64e0fd
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<application><activity
android:exported="true"
android:name=".MainActivity"
android:label="@string/display_composable_map_view_app_name">
android:label="@string/filter_features_in_scene_app_name">

</activity>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.app.Application
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.arcgismaps.Color
import com.arcgismaps.geometry.Point
import com.arcgismaps.geometry.Polygon
Expand All @@ -40,14 +41,11 @@ import com.arcgismaps.mapping.view.Camera
import com.arcgismaps.mapping.view.Graphic
import com.arcgismaps.mapping.view.GraphicsOverlay
import com.arcgismaps.portal.Portal
import com.arcgismaps.toolkit.geoviewcompose.SceneViewProxy
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.launch

class FilterFeaturesInSceneViewModel(application: Application) : AndroidViewModel(application) {

val sceneViewProxy = SceneViewProxy()

// create a ViewModel to handle dialog interactions
val messageDialogVM: MessageDialogViewModel = MessageDialogViewModel()

Expand All @@ -65,7 +63,9 @@ class FilterFeaturesInSceneViewModel(application: Application) : AndroidViewMode
// Create a new ArcGISScene and set a basemap from a portal item with a vector tile layer
val arcGISScene: ArcGISScene by mutableStateOf(ArcGISScene(BasemapStyle.ArcGISTopographic).apply {
// Add an elevation source to the scene's base surface.
baseSurface.elevationSources.add(ArcGISTiledElevationSource(uri = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"))
val tiledElevationSource =
ArcGISTiledElevationSource(uri = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")
baseSurface.elevationSources.add(tiledElevationSource)
// OSM building layer
operationalLayers.add(osmBuildingsSceneLayer)
// Add the buildings scene layer to the operational layers
Expand All @@ -78,43 +78,45 @@ class FilterFeaturesInSceneViewModel(application: Application) : AndroidViewMode
)
})

// Create a boundary polygon that will be populated with the extent of the San Francisco buildings layer once loaded
private val sanFranciscoBuildingsBoundary = runBlocking { createBoundaryPolygon() }

// Set up graphic overlay and graphic for the San Francisco buildings layer extent. It is assigned to the SceneView
// in the composable function
val graphicsOverlay = GraphicsOverlay().apply {
graphics.add(
Graphic(
sanFranciscoBuildingsBoundary, SimpleFillSymbol(
style = SimpleFillSymbolStyle.Solid, color = Color.transparent, outline = SimpleLineSymbol(
style = SimpleLineSymbolStyle.Solid, color = Color.red, width = 5.0f
)
)
// Define a red boundary graphic
private val boundaryGraphic = Graphic(
symbol = SimpleFillSymbol(
style = SimpleFillSymbolStyle.Solid,
color = Color.transparent,
outline = SimpleLineSymbol(
style = SimpleLineSymbolStyle.Solid,
color = Color.red,
width = 5.0f
)
)
)

// Set up graphic overlay and graphic for the San Francisco buildings layer extent.
val graphicsOverlay = GraphicsOverlay(listOf(boundaryGraphic))

init {
loadBuildingsLayer()
}

/**
* One the San Francisco buildings layer is loaded, create and return a boundary [Polygon].
* Load the San Francisco buildings layer and create a polygon boundary using the layer extent.
*/
private suspend fun createBoundaryPolygon(): Polygon? {
// Load the San Francisco buildings layer
sanFranciscoBuildingsSceneLayer.load().onSuccess {
private fun loadBuildingsLayer() {
viewModelScope.launch {
// Load the San Francisco buildings layer
sanFranciscoBuildingsSceneLayer.load().onFailure {
messageDialogVM.showMessageDialog(it.message.toString(), it.cause.toString())
}
// Create a polygon boundary using the San Francisco buildings layer extent
return sanFranciscoBuildingsSceneLayer.fullExtent?.let {
PolygonBuilder().apply {
sanFranciscoBuildingsSceneLayer.fullExtent?.let {
boundaryGraphic.geometry = PolygonBuilder().apply {
addPoint(it.xMin, it.yMin)
addPoint(it.xMax, it.yMin)
addPoint(it.xMax, it.yMax)
addPoint(it.xMin, it.yMax)
}.toGeometry()
}
}.onFailure {
messageDialogVM.showMessageDialog(it.message.toString(), it.cause.toString())
}
// Return null if the layer doesn't load or the extent is not available
return null
}

/**
Expand All @@ -123,11 +125,23 @@ class FilterFeaturesInSceneViewModel(application: Application) : AndroidViewMode
*/
fun filterScene() {
// Check that the San Francisco buildings layer extent is available
sanFranciscoBuildingsBoundary?.let { boundary ->
(boundaryGraphic.geometry as? Polygon)?.let { boundary ->
// Create a polygon filter with the San Francisco buildings layer boundary polygon and set it to be disjoint
val sceneLayerPolygonFilter = SceneLayerPolygonFilter(listOf(boundary), SceneLayerPolygonFilterSpatialRelationship.Disjoint)
val sceneLayerPolygonFilter =
SceneLayerPolygonFilter(
polygons = listOf(boundary),
spatialRelationship = SceneLayerPolygonFilterSpatialRelationship.Disjoint
)
// Set the polygon filter to the OSM buildings layer
osmBuildingsSceneLayer.polygonFilter = sceneLayerPolygonFilter
}
}

/**
* Reset the OSM buildings layer filter to show all buildings.
*/
fun resetFilter() {
// Clear all polygon filters
osmBuildingsSceneLayer.polygonFilter?.polygons?.clear()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
Expand All @@ -42,6 +46,9 @@ import com.esri.arcgismaps.sample.sampleslib.components.SampleTopAppBar
@Composable
fun FilterFeaturesInSceneScreen(sampleName: String) {
val sceneViewModel: FilterFeaturesInSceneViewModel = viewModel()

var filteringScene by remember { mutableStateOf(false) }

Scaffold(
topBar = { SampleTopAppBar(title = sampleName) },
content = { padding ->
Expand All @@ -55,7 +62,6 @@ fun FilterFeaturesInSceneScreen(sampleName: String) {
.fillMaxSize()
.weight(1f),
arcGISScene = sceneViewModel.arcGISScene,
sceneViewProxy = sceneViewModel.sceneViewProxy,
graphicsOverlays = listOf(sceneViewModel.graphicsOverlay)
)
Row(
Expand All @@ -64,10 +70,25 @@ fun FilterFeaturesInSceneScreen(sampleName: String) {
.padding(4.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
onClick = { sceneViewModel.filterScene() }
) {
Text(text = stringResource(R.string.filter_osm_buildings))
if (!filteringScene) {
Button(
onClick = {
sceneViewModel.filterScene()
filteringScene = true
}
) {
Text(text = stringResource(R.string.filter_osm_buildings))
}

} else {
Button(
onClick = {
sceneViewModel.resetFilter()
filteringScene = false
}
) {
Text(text = stringResource(R.string.reset_filter))
}
}
}
// display a MessageDialog if the sample encounters an error
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<resources>
<string name="filter_features_in_scene_app_name">Filter features in scene</string>
<string name="filter_osm_buildings">Filter OSM buildings</string>
<string name="reset_filter">Reset filter</string>
</resources>

0 comments on commit d64e0fd

Please sign in to comment.