Select to view content in your preferred language

ServiceFeatureTable.populateFromService silently returns 0 features when returnGeometry=false + spatial filter

68
0
yesterday
BenHaas4
New Contributor

Summary

In FeatureRequestMode.ManualCacheServiceFeatureTable.populateFromService(...) with a spatial predicate (geometry + spatialRelationship) silently drops every server-returned feature when returnGeometry = false. The SDK appears to re-apply the spatial filter locally against the just-cached rows; those rows carry null geometry because the SDK itself requested returnGeometry=false; a local intersects(envelope, null) returns false for every row, so the cache evaluates to empty even though the server replied with the correct features. No exception, no log warning.

How to reproduce

LayerURL
Forestshttps://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View...
Siteshttps://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View...

 

Both support esriSpatialRelIntersects and esriSpatialRelEnvelopeIntersects. Both queryable anonymously.

REST Baseline

GET https://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View/FeatureServer/3/query
  ?where=1=1
  &geometry=-122.3,44.7,-121.4,45.7
  &geometryType=esriGeometryEnvelope
  &inSR=4326
  &spatialRel=esriSpatialRelEnvelopeIntersects
  &outFields=OBJECTID,COMMONNAME
  &returnGeometry=false
  &f=json

 

Returns 4 features:

OBJECTID COMMONNAME

61961Gifford Pinchot National Forest
61964Mt. Hood National Forest
61972Willamette National Forest
61974Columbia River Gorge National Scenic Area

 

Sites (point) — Trillium Lake area inside Mt. Hood NF. Bbox -121.80,45.20,-121.65,45.30 (WGS84).

GET https://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View/FeatureServer/0/query
  ?where=1=1
  &geometry=-121.80,45.20,-121.65,45.30
  &geometryType=esriGeometryEnvelope
  &inSR=4326
  &spatialRel=esriSpatialRelEnvelopeIntersects
  &outFields=OBJECTID,PUBLIC_SITE_NAME
  &returnGeometry=false
  &f=json

 

Returns 10 features: Pioneer Woman's Grave Trailhead, Jackpot Meadows, Trillium Lake Campground, Trillium Lake Day Use Area, Barlow Pass Snow Park & Trailhead, Snow Bunny Sliding Area Sno-Park, Frog Lake Snow Park & Trailhead, Devils Half Acre, Trillium Snow Park, Frog Lake Campground.

 
SDK reproducer — minimal standalone

The reproducer below uses only the public SDK API. It can be dropped into a fresh Android project's MainActivity.onCreate (with viewModelScope.launch { ... }) and run against the URLs above.

import com.arcgismaps.data.FeatureRequestMode
import com.arcgismaps.data.QueryParameters
import com.arcgismaps.data.ServiceFeatureTable
import com.arcgismaps.data.SpatialRelationship
import com.arcgismaps.geometry.Envelope
import com.arcgismaps.geometry.SpatialReference

suspend fun reproduce(serviceUrl: String, envelope: Envelope, outFields: List<String>) {
    for (returnGeometry in listOf(false, true)) {
        val table = ServiceFeatureTable(serviceUrl).apply {
            featureRequestMode = FeatureRequestMode.ManualCache
        }
        table.load().getOrThrow()
        val params = QueryParameters().apply {
            whereClause = "1=1"
            this.returnGeometry = returnGeometry
            geometry = envelope
            spatialRelationship = SpatialRelationship.Intersects // SDK coerces to EnvelopeIntersects for an Envelope input
        }
        val features = table.populateFromService(
            parameters = params,
            clearCache = true,
            outFields = outFields
        ).getOrThrow().toList()
        println("$serviceUrl  returnGeometry=$returnGeometry  → ${features.size} feature(s)")
    }
}

// Forests (polygon, expect 4)
reproduce(
    "https://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View/FeatureServer/3",
    Envelope(-122.3, 44.7, -121.4, 45.7, SpatialReference.wgs84()),
    listOf("OBJECTID", "COMMONNAME")
)
// Sites (point, expect 10)
reproduce(
    "https://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View/FeatureServer/0",
    Envelope(-121.80, 45.20, -121.65, 45.30, SpatialReference.wgs84()),
    listOf("OBJECTID", "PUBLIC_SITE_NAME")
)

 

Observed delta — deterministic one-flag reproducer (verified 2026-05-21 against SDK 200.8.0 and 300.0.0 on Android 16, emulator arm64-v8a)

Same code path, same envelope; only QueryParameters.returnGeometry changes.

Layer returnGeometry SDK 200.8.0 result SDK 300.0.0 result Server response (HTTP 200)

LayerreturnGeometrySDK 200.8SDK 300.0Server Response
FeatureServer/3 — forests, polygonfalse0 features0 features4 features in body
FeatureServer/3 — forests, polygontrue4 features4 features 4 features in body
FeatureServer/0 — sites, pointfalse0 features0 features10 features in body
FeatureServer/0 — sites, pointtrue10 features10 features10 features in body

 

Server returns the correct features in all eight runs. With returnGeometry = false the SDK silently filters them all out before returning to the caller. No exception, no log warning. The bug is unchanged between 200.8.0 and the most recent 300.0.0 release. SDK result counts pasted from SdkBugReproducer logcat output; server responses verified by SdkRequestCaptureInterceptor wire capture (see verbatim excerpts below).

Verbatim wire capture — forests layer, returnGeometry=false

SdkRequestCapture: → Get https://services1.arcgis.com/gGHDlz6USftL5Pau/ArcGIS/rest/services/FS_Recreation_One_App_Online_View/FeatureServer/3/query
  hdr User-Agent: ArcGISMaps-Kotlin/200.8.0 (Android 16.0; arm64-v8a; GOOGLE-SDK_GPHONE64_ARM64) gov.usda.fs.nfg.dev
  params:
    f=json
    geometry={"xmin":-122.3,"ymin":44.700000000000003,"xmax":-121.40000000000001,"ymax":45.700000000000003}
    geometryType=esriGeometryEnvelope
    inSR=4326
    outFields=OBJECTID,COMMONNAME
    outSR=3857
    returnDistinctValues=false
    returnGeometry=false
    returnM=true
    returnZ=true
    spatialRel=esriSpatialRelEnvelopeIntersects
    where=1=1
SdkRequestCapture: ← code=200
  body: {"objectIdFieldName":"OBJECTID",…,"features":[
    {"attributes":{"OBJECTID":61961,"COMMONNAME":"Gifford Pinchot National Forest"}},
    {"attributes":{"OBJECTID":61964,"COMMONNAME":"Mt. Hood National Forest"}},
    {"attributes":{"OBJECTID":61974,"COMMONNAME":"Columbia River Gorge National Scenic Area"}},
    {"attributes":{"OBJECTID":61972,"COMMONNAME":"Willamette National Forest"}}
  ]}
SdkBugReproducer: returnGeometry=false → 0 feature(s) in 248ms (REST baseline 4)

 

The server returned 4 features. The SDK delivered 0 features to its caller.

With returnGeometry=true flipped (next run, ~200 ms later), the SDK delivered all 4 features:

SdkBugReproducer: returnGeometry=true → 4 feature(s) in 254ms (REST baseline 4)
  OBJECTID=61961  COMMONNAME=Gifford Pinchot National Forest
  OBJECTID=61964  COMMONNAME=Mt. Hood National Forest
  OBJECTID=61972  COMMONNAME=Willamette National Forest
  OBJECTID=61974  COMMONNAME=Columbia River Gorge National Scenic Area

 

0 Kudos
0 Replies