Search code examples
mapboxmapbox-android

Android Mapbox - Filering from GeoJson file so that only points with certain property show


Browsed and looked for an answer but was not able - hopefully this isnt a double.

Basically an activity in the app i'm developing would only show points (on a circlelayer) on the mapbox map - BUT only if they have a feature property set to true (boolean - which can have its value changed from another activity on the same app, depending if you have visited the location or not).

Here is the Json

{
  "features": [
    {
      "type": "Feature",
      "properties": {
        "title": "name of place",
        "Country": "countryname",
        "Region": "regionname",
        "poi": "Monument",
        "selected": false,
        "Visited": false, //This value here is to be filtered
        "Visityear": "No",
        "Visitmonth": "No",
      },
      "geometry": {
        "coordinates": [
          25.588019,
          45.641036
        ],
        "type": "Point"

...etc, more values, etc

Now, the boolean can be set from another activity as true or false, but on this particular map - i would only need to have the simple map, but showing only the points where the "Visited" is "true"

            private void addPointsLayer(@NonNull Style loadedMapStyle) {
                CircleLayer Seenlayer = new CircleLayer("points", GEOJSON_SOURCE_ID);
                Seenlayer.setProperties(
                        PropertyFactory.circleColor(Color.RED),
                        PropertyFactory.circleRadius(2f),
                        PropertyFactory.circleOpacity(0.4f));
                Seenlayer.setFilter(
                        Expression.all(
                                eq(literal("$type"), literal("Point")),
                                eq(get("Visited"), true))); //Im sure its something here!
                loadedMapStyle.addLayer(Seenlayer);
            }

Tried several options - but either no points show up at all, or they show up regardless of the value of "Visited"


Solution

  • Pretty sure that CircleLayers only respect Point geometries, so there's no need to include the geometry type in the filter. For now, I'd just leave it in your code. You can always experiment by removing it once everything else is working.

    Try

    Seenlayer.setFilter(
                        Expression.all(
                                eq(geometryType(), literal("Point")),
                                eq(get("Visited"), true)));
    

    If that doesn't work, try:

    Seenlayer.setFilter(
                        Expression.all(
                                eq(geometryType(), literal("Point")),
                                eq(get("Visited"), literal(true))));
    

    There are several Mapbox Android demo app examples that rely on this select state toggle functionality that you're trying to set up in your code. Wrapping the boolean in a literal() seems to be key to getting this to work

    https://github.com/mapbox/mapbox-android-demo/search?q=%22++++++.withFilter%28eq%28%28get%28PROPERTY_SELECTED%29%29%2C+literal%28true%29%29%29%29%3B%22&unscoped_q=%22++++++.withFilter%28eq%28%28get%28PROPERTY_SELECTED%29%29%2C+literal%28true%29%29%29%29%3B%22

    In your case it'd be literal(true)