[testapp] - add example using within expression (#288)
This commit is contained in:
@@ -998,6 +998,17 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activity.FeatureOverviewActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.turf.WithinExpressionActivity"
|
||||
android:description="@string/description_within"
|
||||
android:label="@string/activity_within">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_style" />
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activity.FeatureOverviewActivity" />
|
||||
</activity>
|
||||
<!-- For Instrumentation tests -->
|
||||
<activity
|
||||
android:name=".activity.style.RuntimeStyleTimingTestActivity"
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.turf
|
||||
|
||||
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.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 com.mapbox.mapboxsdk.testapp.R
|
||||
import kotlinx.android.synthetic.main.activity_physical_circle.*
|
||||
|
||||
/**
|
||||
* An Activity that showcases 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_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, 2500)
|
||||
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 = bufferLineStringGeometry(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() {
|
||||
val style = mapboxMap.style!!
|
||||
|
||||
// Add fill layer to represent buffered LineString
|
||||
mapboxMap.style!!.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 = style.getLayer("poi-label") as SymbolLayer
|
||||
symbolLayer.setFilter(
|
||||
within(
|
||||
bufferLineStringGeometry()
|
||||
)
|
||||
)
|
||||
|
||||
// Hide other types of labels to highlight POI labels
|
||||
(style.getLayer("road-label") as SymbolLayer).setProperties(visibility(NONE))
|
||||
(style.getLayer("transit-label") as SymbolLayer).setProperties(visibility(NONE))
|
||||
(style.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 bufferLineStringGeometry(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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activity.style.DraggableMarkerActivity">
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -19,6 +19,7 @@
|
||||
<string name="description_debug_mode">Debug Mode</string>
|
||||
<string name="description_offline">Offline Map example</string>
|
||||
<string name="description_region">Download an offline region.</string>
|
||||
<string name="description_within">Usage of the within expression on a buffered geometry</string>
|
||||
<string name="description_update_metadata">Update metadata example</string>
|
||||
<string name="description_offline_region_delete">Delete region example</string>
|
||||
<string name="description_change_resources_cache_path">Change resources cache path example</string>
|
||||
|
||||
@@ -87,4 +87,5 @@
|
||||
<string name="activity_performance_measurement">Performance Measurement</string>
|
||||
<string name="activity_physical_circle">Physical Unit Circle</string>
|
||||
<string name="activity_region">Download region</string>
|
||||
<string name="activity_within">Within expression</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user