Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Add api and demo for expression distance (#339)
Browse files Browse the repository at this point in the history
* Add api and demo for expression distance

* Update test case
  • Loading branch information
Kevin Li authored Apr 24, 2020
1 parent 161abf8 commit 5cee66a
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.mapbox.geojson.GeoJson;
import com.mapbox.geojson.Polygon;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
import com.mapbox.mapboxsdk.style.layers.PropertyValue;
Expand Down Expand Up @@ -1574,6 +1575,42 @@ public static Expression in(@NonNull String needle, @NonNull Expression haystack
return new Expression("in", literal(needle), haystack);
}

/**
* Retrieves the shortest distance between two geometries.
* The returned value can be consumed as an input into another expression for changing a paint or layout property
* or filtering features by distance.
*
* @param geoJson the target feature geoJso.
* Currently supports `Point`, `MultiPoint`, `LineString`, `MultiLineString` geometry types
* @param unit the unit for the returned value.
* Currently supports `metres`, `kilometers`, `miles`, `nauticalmiles`, "yards","feet","inches"。
* @return the distance in the unit that is provided.
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-distance">Style specification</a>
*/
public static Expression distance(@NonNull GeoJson geoJson, String unit) {
Map<String, Expression> map = new HashMap<>();
map.put("json", literal(geoJson.toJson()));
return new Expression("distance", new ExpressionMap(map), literal(unit));
}

/**
* Retrieves the shortest distance between two geometries.
* The returned value can be consumed as an input into another expression for changing a paint or layout property
* or filtering features by distance.
* <p>
* Currently supports `Point`, `MultiPoint`, `LineString`, `MultiLineString` geometry types.
*
* @param geoJson the target feature geoJson.
* Currently supports `Point`, `MultiPoint`, `LineString`, `MultiLineString` geometry types
* @return the distance in the unit "meters".
* @see <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-distance">Style specification</a>
*/
public static Expression distance(@NonNull GeoJson geoJson) {
Map<String, Expression> map = new HashMap<>();
map.put("json", literal(geoJson.toJson()));
return new Expression("distance", new ExpressionMap(map));
}

public static Expression within(@NonNull Polygon polygon) {
Map<String, Expression> map = new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import static com.mapbox.mapboxsdk.style.expressions.Expression.concat;
import static com.mapbox.mapboxsdk.style.expressions.Expression.cos;
import static com.mapbox.mapboxsdk.style.expressions.Expression.cubicBezier;
import static com.mapbox.mapboxsdk.style.expressions.Expression.distance;
import static com.mapbox.mapboxsdk.style.expressions.Expression.division;
import static com.mapbox.mapboxsdk.style.expressions.Expression.downcase;
import static com.mapbox.mapboxsdk.style.expressions.Expression.e;
Expand Down Expand Up @@ -487,6 +488,22 @@ public void testInNumber() throws Exception {
assertTrue("expression should match", Arrays.deepEquals(expected, actual));
}


@Test
public void testDistance() throws Exception {
Point point = Point.fromLngLat(1, 2);
HashMap<String, String> map = new HashMap<>();
map.put("json", point.toJson());
Object[] expected = new Object[] {"distance", map};
Object[] actual = distance(point).toArray();
assertTrue("expression should match", Arrays.deepEquals(expected, actual));

Object[] expectedWithUnit = new Object[] {"distance", map, "meters"};
Object[] actualWithUnit = distance(point, "meters").toArray();
assertTrue("expression should match", Arrays.deepEquals(expectedWithUnit, actualWithUnit));
}


@Test
public void testInArray() throws Exception {
Object[] expected = new Object[] {"in", "one", new Object[] {"literal", new Object[] {"one", "two"}}};
Expand Down
12 changes: 12 additions & 0 deletions MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,18 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
<activity
android:name=".activity.style.DistanceExpressionActivity"
android:description="@string/description_distance_style"
android:exported="true"
android:label="@string/activity_distance_style">
<meta-data
android:name="@string/category"
android:value="@string/category_style" />
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity" />
</activity>
<activity
android:name=".activity.style.GradientLineActivity"
android:description="@string/description_gradient_line"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.mapbox.mapboxsdk.testapp.activity.style

import android.graphics.Color
import android.os.Bundle
import android.os.PersistableBundle
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.Point
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.expressions.Expression.distance
import com.mapbox.mapboxsdk.style.expressions.Expression.lt
import com.mapbox.mapboxsdk.style.layers.FillLayer
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.GeoJsonSource
import com.mapbox.mapboxsdk.testapp.R
import com.mapbox.turf.TurfConstants
import com.mapbox.turf.TurfTransformation
import kotlinx.android.synthetic.main.activity_physical_circle.*

/**
* An Activity that showcases the within expression to filter features outside a geometry
*/
class DistanceExpressionActivity : AppCompatActivity() {

private lateinit var mapboxMap: MapboxMap

private val lat = 37.78794572301525
private val lon = -122.40752220153807

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(lat, lon))
.zoom(16.0)
.build()
setupStyle()
}
}

private fun setupStyle() {
val center = Point.fromLngLat(lon, lat)
val circle = TurfTransformation.circle(center, 150.0, TurfConstants.UNIT_METRES)
// 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, Point.fromLngLat(lon, lat)
),
GeoJsonSource(CIRCLE_ID, circle)
)
.withLayerBelow(
FillLayer(CIRCLE_ID, CIRCLE_ID)
.withProperties(
fillOpacity(0.5f),
fillColor(Color.parseColor("#3bb2d0"))
), "poi-label"
)
) { style ->
// Show only POI labels inside circle radius using distance expression
val symbolLayer = style.getLayer("poi-label") as SymbolLayer
symbolLayer.setFilter(lt(
distance(
Point.fromLngLat(lon, lat), "meters"
), 150)
)

// 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()
mapView.onDestroy()
}

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

companion object {
const val POINT_ID = "point"
const val CIRCLE_ID = "circle"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<string name="description_dynamic_info_window_adapter">Learn how to create a dynamic custom InfoWindow</string>
<string name="description_viewpager">Use SupportMapFragments in a ViewPager</string>
<string name="description_runtime_style">Adopt the map style on the fly</string>
<string name="description_distance_style">Show POIs on a map with distance expression filter</string>
<string name="description_gradient_line">Show a gradient line layer from a geojson source</string>
<string name="description_data_driven_style">Use functions to change the map appearance</string>
<string name="description_symbol_layer">Manipulate symbols at runtime</string>
Expand Down
1 change: 1 addition & 0 deletions MapboxGLAndroidSDKTestApp/src/main/res/values/titles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<string name="activity_minmax_zoom">Min/Max Zoom</string>
<string name="activity_viewpager">ViewPager</string>
<string name="activity_runtime_style">Runtime Style</string>
<string name="activity_distance_style">Distance Expression</string>
<string name="activity_gradient_line">Gradient line layer</string>
<string name="activity_data_driven_style">Data Driven Style</string>
<string name="activity_circle_layer">Circle layer</string>
Expand Down
2 changes: 1 addition & 1 deletion vendor/mapbox-gl-native
Submodule mapbox-gl-native updated 77 files
+26 −0 CHANGELOG.md
+5 −2 CMakeLists.txt
+23 −0 LICENSE.mbgl-core.md
+4 −4 circle.yml
+13 −0 include/mbgl/platform/time.hpp
+4 −0 include/mbgl/storage/resource.hpp
+38 −0 include/mbgl/style/expression/distance.hpp
+2 −1 include/mbgl/style/expression/expression.hpp
+0 −1 include/mbgl/style/expression/within.hpp
+21 −6 include/mbgl/style/source.hpp
+3 −1 include/mbgl/util/chrono.hpp
+1 −1 metrics/binary-size/android-armeabi-v7a/metrics.json
+1 −1 metrics/binary-size/android-x86/metrics.json
+1 −1 metrics/binary-size/android-x86_64/metrics.json
+3 −3 metrics/binary-size/linux-clang8/metrics.json
+1 −0 platform/android/android.cmake
+11 −0 platform/default/src/mbgl/platform/time.cpp
+4 −1 platform/default/src/mbgl/storage/database_file_source.cpp
+30 −25 platform/default/src/mbgl/storage/online_file_source.cpp
+1 −0 platform/default/src/mbgl/text/bidi.cpp
+2 −2 platform/ios/ccache.cmake
+1 −0 platform/ios/ios.cmake
+1 −0 platform/linux/linux.cmake
+2 −3 platform/macos/macos.cmake
+1 −0 platform/node/CMakeLists.txt
+1 −0 platform/qt/qt.cmake
+5 −5 scripts/check_benchmark_results.sh
+2 −4 src/mbgl/annotation/render_annotation_source.cpp
+3 −3 src/mbgl/geometry/feature_index.cpp
+12 −15 src/mbgl/renderer/sources/render_custom_geometry_source.cpp
+11 −14 src/mbgl/renderer/sources/render_geojson_source.cpp
+2 −4 src/mbgl/renderer/sources/render_raster_dem_source.cpp
+2 −4 src/mbgl/renderer/sources/render_raster_source.cpp
+11 −14 src/mbgl/renderer/sources/render_vector_source.cpp
+13 −11 src/mbgl/renderer/tile_pyramid.cpp
+7 −8 src/mbgl/renderer/tile_pyramid.hpp
+4 −2 src/mbgl/style/custom_tile_loader.hpp
+623 −0 src/mbgl/style/expression/distance.cpp
+4 −0 src/mbgl/style/expression/is_constant.cpp
+2 −0 src/mbgl/style/expression/parsing_context.cpp
+21 −13 src/mbgl/style/expression/within.cpp
+24 −0 src/mbgl/style/source.cpp
+8 −2 src/mbgl/style/source_impl.hpp
+4 −0 src/mbgl/tile/raster_dem_tile.cpp
+2 −1 src/mbgl/tile/raster_dem_tile.hpp
+4 −0 src/mbgl/tile/raster_tile.cpp
+2 −1 src/mbgl/tile/raster_tile.hpp
+14 −0 src/mbgl/tile/tile.hpp
+7 −10 src/mbgl/tile/tile_loader.hpp
+28 −1 src/mbgl/tile/tile_loader_impl.hpp
+4 −0 src/mbgl/tile/vector_tile.cpp
+1 −0 src/mbgl/tile/vector_tile.hpp
+0 −28 src/mbgl/util/bounding_volumes.cpp
+1 −0 src/mbgl/util/convert.cpp
+165 −0 src/mbgl/util/geometry_util.cpp
+52 −0 src/mbgl/util/geometry_util.hpp
+0 −143 src/mbgl/util/geometry_within.cpp
+0 −29 src/mbgl/util/geometry_within.hpp
+2 −1 src/mbgl/util/http_header.cpp
+3 −3 src/mbgl/util/http_timeout.cpp
+29 −0 src/mbgl/util/mat3.hpp
+5 −0 test/fixtures/expression_equality/distance.a.json
+5 −0 test/fixtures/expression_equality/distance.b.json
+259 −0 test/fixtures/geometry_data/line_string_1.geojson
+106 −0 test/fixtures/geometry_data/line_string_2.geojson
+199 −0 test/fixtures/geometry_data/multi_line_string_1.geojson
+88 −0 test/fixtures/geometry_data/multi_line_string_2.geojson
+91 −0 test/fixtures/geometry_data/multi_point_1.geojson
+85 −0 test/fixtures/geometry_data/multi_point_2.geojson
+90 −0 test/map/map.test.cpp
+31 −0 test/storage/database_file_source.test.cpp
+27 −0 test/storage/main_resource_loader.test.cpp
+18 −0 test/storage/online_file_source.test.cpp
+369 −1 test/style/property_expression.test.cpp
+58 −12 test/style/source.test.cpp
+1 −1 vendor/mapbox-base
+9 −0 vendor/mapbox-base.cmake

0 comments on commit 5cee66a

Please sign in to comment.