Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Added within expression filter example #1334

Merged
merged 1 commit into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.mapbox.mapboxandroiddemo.examples.dds.CircleToIconTransitionActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.PropertyIconDeterminationActivity;
import com.mapbox.mapboxandroiddemo.examples.camera.ZoomToShowClusterLeavesActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.WithinExpressionActivity;
import com.mapbox.mapboxandroiddemo.examples.javaservices.DirectionsProfileToggleActivity;
import com.mapbox.mapboxandroiddemo.examples.javaservices.KotlinBorderedCircleActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.CreateHotspotsActivity;
Expand Down Expand Up @@ -1605,6 +1606,14 @@ private void initializeModels() {
null,
R.string.activity_dds_circle_icon_toggle_on_click_url, true, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.id.nav_dds,
R.string.activity_dds_within_expression_title,
R.string.activity_dds_within_expression_description,
null,
new Intent(MainActivity.this, WithinExpressionActivity.class),
R.string.activity_dds_within_expression_url, true, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.id.nav_basics,
R.string.activity_basic_simple_mapview_title,
Expand Down
7 changes: 7 additions & 0 deletions MapboxAndroidDemo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.dds.WithinExpressionActivity"
android:label="@string/activity_dds_within_expression_title">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.extrusions.MarathonExtrusionActivity"
android:label="@string/activity_extrusions_catalina_marathon_extrusions_title">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
package com.mapbox.mapboxandroiddemo.examples.dds

import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.PersistableBundle
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.*
import com.mapbox.mapboxandroiddemo.R
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.maps.MapView
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.expressions.Expression.within
import com.mapbox.mapboxsdk.style.layers.CircleLayer
import com.mapbox.mapboxsdk.style.layers.FillLayer
import com.mapbox.mapboxsdk.style.layers.LineLayer
import com.mapbox.mapboxsdk.style.layers.Property.NONE
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.*
import com.mapbox.mapboxsdk.style.layers.SymbolLayer
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
import kotlinx.android.synthetic.main.activity_dds_within_expression.*

/**
* Use the within expression to filter features outside a geometry
*/
class WithinExpressionActivity : AppCompatActivity() {

private lateinit var mapboxMap: MapboxMap
private val handler: Handler = Handler()
private val runnable: Runnable = Runnable {
optimizeStyle()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dds_within_expression)

mapView.onCreate(savedInstanceState)
mapView.getMapAsync { map ->
mapboxMap = map

// Setup camera position above Georgetown
mapboxMap.cameraPosition = CameraPosition.Builder()
.target(LatLng(38.90628988399711, -77.06574689337494))
.zoom(15.5)
.build()

// Wait for the map to become idle before manipulating the style and camera of the map
mapView.addOnDidBecomeIdleListener(object : MapView.OnDidBecomeIdleListener {
override fun onDidBecomeIdle() {
handler.postDelayed(runnable, 1500)
mapView.removeOnDidBecomeIdleListener(this)
}
})

// Load mapbox streets and add lines and circles
setupStyle()
}
}

private fun setupStyle() {
// Assume the route is represented by an array of coordinates.
val coordinates = listOf<Point>(
Point.fromLngLat(
-77.06866264343262,
38.90506061276737
),
Point.fromLngLat(
-77.06283688545227,
38.905194197410545
),
Point.fromLngLat(
-77.06285834312439,
38.906429843444094
),
Point.fromLngLat(
-77.0630407333374,
38.90680554236621
)
)

// Convert to a LineString
val routeLineString = LineString.fromLngLats(coordinates)

// Create buffer around linestring
val bufferedRouteGeometry = retrieveBufferLineStringGeometry(routeLineString)

// Setup style with additional layers, using Style.MAPBOX_STREETS as a base style
mapboxMap.setStyle(
Style.Builder()
.fromUri(Style.MAPBOX_STREETS)
.withSources(
GeoJsonSource(
POINT_ID, LineString.fromLngLats(coordinates)
),
GeoJsonSource(
FILL_ID,
FeatureCollection.fromFeature(Feature.fromGeometry(bufferedRouteGeometry)),
GeoJsonOptions().withBuffer(0).withTolerance(0.0f)
)
)
.withLayerBelow(
LineLayer(LINE_ID, POINT_ID)
.withProperties(lineWidth(7.5f), lineColor(Color.LTGRAY)),
"poi-label"
)
.withLayerBelow(
CircleLayer(POINT_ID, POINT_ID)
.withProperties(
circleRadius(7.5f),
circleColor(Color.DKGRAY),
circleOpacity(0.75f)
), "poi-label"
)
)
}

private fun optimizeStyle() {
mapboxMap.getStyle {
// Add FillLayer to represent a buffered LineString
it.addLayerBelow(
FillLayer(FILL_ID, FILL_ID)
.withProperties(
fillOpacity(0.12f),
fillColor(Color.YELLOW)
), LINE_ID
)

// Move to a new camera position
mapboxMap.easeCamera(
CameraUpdateFactory.newCameraPosition(
CameraPosition.Builder()
.zoom(16.0)
.target(LatLng(38.905156245642814, -77.06535338052844))
.bearing(80.68015859462369)
.tilt(55.0)
.build()
), 1750
)

// Show only POI labels inside geometry using within expression
val symbolLayer = it.getLayer("poi-label") as SymbolLayer
symbolLayer.setFilter(
within(
retrieveBufferLineStringGeometry()
)
)

// Hide other types of labels to highlight POI labels
(it.getLayer("road-label") as SymbolLayer).setProperties(visibility(NONE))
(it.getLayer("transit-label") as SymbolLayer).setProperties(visibility(NONE))
(it.getLayer("road-number-shield") as SymbolLayer).setProperties(visibility(NONE))
}
}

override fun onStart() {
super.onStart()
mapView.onStart()
}

override fun onResume() {
super.onResume()
mapView.onResume()
}

override fun onPause() {
super.onPause()
mapView.onPause()
}

override fun onStop() {
super.onStop()
mapView.onStop()
}

override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}

override fun onDestroy() {
super.onDestroy()
handler.removeCallbacks(runnable)
mapView.onDestroy()
}

override fun onSaveInstanceState(outState: Bundle?, outPersistentState: PersistableBundle?) {
super.onSaveInstanceState(outState, outPersistentState)
outState?.let {
mapView.onSaveInstanceState(it)
}
}

private fun retrieveBufferLineStringGeometry(lineString: LineString? = null): Polygon {
// TODO replace static data by Turf#Buffer: mapbox-java/issues/987
return FeatureCollection.fromJson(
"""
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-77.06867337226866,
38.90467655551809
],
[
-77.06233263015747,
38.90479344272695
],
[
-77.06234335899353,
38.906463238984344
],
[
-77.06290125846863,
38.907206285691615
],
[
-77.06364154815674,
38.90684728656818
],
[
-77.06326603889465,
38.90637140121084
],
[
-77.06321239471436,
38.905561553883246
],
[
-77.0691454410553,
38.905436318935635
],
[
-77.06912398338318,
38.90466820642439
],
[
-77.06867337226866,
38.90467655551809
]
]
]
}
}
]
}
""".trimIndent()
).features()!![0].geometry() as Polygon
}

companion object {
const val POINT_ID = "point"
const val FILL_ID = "fill"
const val LINE_ID = "line"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</FrameLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<string name="activity_dds_circle_to_icon_smooth_transition_description">Use expressions to create a smooth visual transition from circles to icons.</string>
<string name="activity_dds_property_icon_switch_description">Create a SymbolLayer and set the iconId to be dependent on each Feature\'s property key/value pair. </string>
<string name="activity_dds_circle_icon_toggle_on_click_description">Use layer filters and feature properties to create the visual effect of toggling between circles and icons when they\'re tapped on.</string>
<string name="activity_dds_within_expression_description">Check whether or not a feature is fully within the bounds of a GeoJSON polygon.</string>
<string name="activity_styles_text_field_formatting_description">Adjust the color, size, and fonts of SymbolLayer text fields.</string>
<string name="activity_camera_animate_description">"Animate the map's camera position, tilt, bearing, and zoom."</string>
<string name="activity_camera_bounding_box_description">Position the camera so that all the given markers are in view.</string>
Expand Down
1 change: 1 addition & 0 deletions MapboxAndroidDemo/src/main/res/values/titles_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
<string name="activity_dds_polygon_revealed_hole_outline_title">Outlined polygon hole</string>
<string name="activity_dds_property_icon_switch_title">Icon setting based on Feature property</string>
<string name="activity_dds_circle_icon_toggle_on_click_title">Circle icon toggle</string>
<string name="activity_dds_within_expression_title">Within filter</string>
<string name="activity_camera_animate_title">Animate the map camera</string>
<string name="activity_camera_bounding_box_title">Fit camera in bounding box</string>
<string name="activity_camera_restrict_title">Restrict map panning</string>
Expand Down
1 change: 1 addition & 0 deletions MapboxAndroidDemo/src/main/res/values/urls_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<string name="activity_dds_circle_to_icon_smooth_transition_url" translatable="false">https://i.imgur.com/LYmENg3.png</string>
<string name="activity_dds_property_icon_switch_url" translatable="false">https://i.imgur.com/GE1DZMp.png</string>
<string name="activity_dds_circle_icon_toggle_on_click_url" translatable="false">https://i.imgur.com/5ewVbqM.png</string>
<string name="activity_dds_within_expression_url" translatable="false">https://i.imgur.com/9kChmHL.png</string>
<string name="activity_styles_text_field_formatting_url" translatable="false">https://i.imgur.com/MSoIYmU.png</string>
<string name="activity_camera_animate_url" translatable="false">http://i.imgur.com/PN3vyNJ.jpg</string>
<string name="activity_camera_bounding_box_url" translatable="false">http://i.imgur.com/A0JL21Q.png</string>
Expand Down