WFS 2.0: unqualified property names and silently ignored service errors in beta191

Hi Ben,

I found two issues in WfsV2AsyncFeatureSource in ThinkGeo.Core
15.0.0-beta191
when requesting adv:AX_Bahnstrecke from this public WFS:

https://geoservices.bayern.de/wfs/v1/ogc_atkis_basisdlm.cgi

The service uses urn:ogc:def:crs:EPSG::25832. Its geometry property is
adv:position, inherited through the feature’s base type and declared as
gml:CurvePropertyType.

The SDK includes the adv namespace binding in its GetFeature requests, but
sends unqualified property names such as propertyname=position. Bayern rejects
that with an HTTP-200 OWS ExceptionReport:

  • Exception code: ErrorInPropertyName
  • Locator: GetFeature
  • Reason:

Prefix ‘’ in qname ‘position’ is unknown (FeatureTypeContext: adv:AX_Bahnstrecke).

Here is a minimal HTTP reproduction:

curl --get 'https://geoservices.bayern.de/wfs/v1/ogc_atkis_basisdlm.cgi' \
  --data-urlencode 'SERVICE=WFS' \
  --data-urlencode 'VERSION=2.0.0' \
  --data-urlencode 'REQUEST=GetFeature' \
  --data-urlencode 'TYPENAMES=adv:AX_Bahnstrecke' \
  --data-urlencode 'NAMESPACES=xmlns(adv,http://www.adv-online.de/namespaces/adv/gid/7.1)' \
  --data-urlencode 'srsName=urn:ogc:def:crs:EPSG::25832' \
  --data-urlencode 'propertyname=position' \
  --data-urlencode 'STARTINDEX=0' \
  --data-urlencode 'COUNT=2'

Changing only propertyname=position to propertyname=adv:position returns two
valid line features. Omitting propertyname also works. I verified the same
failure/success comparison with this BBOX added:

725800,5565900,726500,5567100,urn:ogc:def:crs:EPSG::25832

The second issue is error handling: the SDK parser searches for wfs:member
without first checking for an OWS exception. It therefore treats the rejected
request as an empty feature collection instead of throwing. LastXmlResponse
contains the exception document.

This is the minimal SDK example to reproduce the request and inspect its response:

using System;
using System.Threading;
using ThinkGeo.Core;

var source = new WfsV2AsyncFeatureSource(
    "https://geoservices.bayern.de/wfs/v1/ogc_atkis_basisdlm.cgi",
    "adv:AX_Bahnstrecke") { WfsAxisOrder = WfsAxisOrder.XY };
try
{
    await source.OpenAsync(CancellationToken.None);
    string request = source.GetRequestUrl(null, 2);
    Console.WriteLine(request);
    var page = await source.GetFeaturesAsync(request, CancellationToken.None);
    Console.WriteLine(page.Features.Count);
    Console.WriteLine(source.LastXmlResponse);
}
finally
{
    await source.CloseAsync(CancellationToken.None);
}

I verified the HTTP responses on September 30, 2026, and inspected the beta191
assembly to trace request construction and response parsing. I have not run the
standalone C# example above. The unqualified property construction also applies
to BBOX queries; requesting no attribute columns still includes the unqualified
geometry property.

Could you please fix both cases?

  1. Qualify GetFeature property references using their schema namespaces, including
    inherited geometry and attribute properties, while preserving the column names
    exposed to callers.
  2. Throw an exception containing the service error when an OWS/WFS exception
    document is returned, including HTTP-200 responses, instead of returning empty
    data.

Thanks!

Hi Julian,

Thanks for the report! It’s been fixed in beta193, give it a shot.

Thanks,
Ben

Hi Ben,

Thanks! With ThinkGeo.Core 15.0.0-beta193, the property names are now
qualified and the service exception is propagated correctly. However,
adv:AX_Bahnstrecke still fails against the same Bayern WFS:

https://geoservices.bayern.de/wfs/v1/ogc_atkis_basisdlm.cgi

The failure has moved to an inherited property included in the generated
PROPERTYNAME list:

ErrorInPropertyName (locator: unknown)
InternalExceptionCode: iiErrorInPropertyName
The PropertyName "adv:inversZu_dientZurDarstellungVon_AX_Gestaltung3D" is not valid for the selection of Properties in the query for FeatureType "adv:AX_Bahnstrecke", because it does not comply to the schema or there is no SQL mapping configurated for this property.

The property actually appears in DescribeFeatureType, on AA_ObjektType, as
an optional gml:ReferenceType. The SDK is not inventing it; the service advertises
it but rejects an explicit selection of it.

This minimal request reproduces the rejection:

curl --get 'https://geoservices.bayern.de/wfs/v1/ogc_atkis_basisdlm.cgi' \
  --data-urlencode 'SERVICE=WFS' \
  --data-urlencode 'VERSION=2.0.0' \
  --data-urlencode 'REQUEST=GetFeature' \
  --data-urlencode 'TYPENAMES=adv:AX_Bahnstrecke' \
  --data-urlencode 'NAMESPACES=xmlns(adv,http://www.adv-online.de/namespaces/adv/gid/7.1)' \
  --data-urlencode 'propertyname=adv:position,adv:inversZu_dientZurDarstellungVon_AX_Gestaltung3D' \
  --data-urlencode 'COUNT=2'

I checked these variants against the live service on October 1:

Property selection Result
Both properties above HTTP 200 with the exception above
Only adv:position Two valid line features
No PROPERTYNAME parameter Two valid line features, including attributes

Inspection of the beta193 assembly shows that GetRequestUrl(null, 2) still
builds an explicit list from all discovered columns, which includes this rejected
property. The same C# reproduction from my previous post therefore reaches this
next service error through GetFeaturesAsync.

Could the default all-properties request omit PROPERTYNAME, allowing the
service to return its default feature content, instead of expanding every schema
property into an explicit selection? Alternatively, is there a supported SDK
option to request that behavior? Explicit column selection should still be
available when the caller asks for particular attributes.

Thanks!

GPU follow-up: AddGeometry rejected on a native projected grid in beta193

With the ThinkGeo 15.0.0-beta193 packages, applying a style containing an
InMemoryGeometrySource to a native projected GPU map throws this exception:

This map's coordinates are on a projected grid (-4500000, 0) - (5500000, 10000000), and a data overlay reaches the engine through a conversion whose target is web mercator. Its values would be laid down on a plane the map is not on - drawn, in the wrong place, and without complaint. Data overlays are available on a mercator map.

The vector tiles and geometry coordinates already use EPSG:25832. The geometry
source has no projection converter. This is independent of the WFS request error.

The SDK setup to check is:

  1. Create a FeatureSourceVectorTileSource with
    new RectangleShape(0, 10000000, 1000000, 0) and GeographyUnit.Meter, and use
    its scales for the map. The SDK squares these bounds to the extent in the error.
  2. Register an EPSG:25832 feature source and translate its layer with
    FeatureLayerTranslator.Translate(layer, source, source.TileMatrixSet.GetScales()).
  3. Build a MapStyle with AddFeatureLayer(translation) and attach it through
    GpuBasemap.
  4. Apply a fresh style containing the same translated layer plus
    style.AddGeometry(new InMemoryGeometrySource()) through SetStyleAsync.

Inspection of the installed assembly shows that the guard rejects any nonempty
list of data-overlay registrations on a non-Mercator grid. It checks the number
of registrations, not their geometry contents or whether a conversion is needed.
AddGeometry adds a registration to that list, even for an empty geometry source.

The exception was observed on Windows; the isolated steps above are based on
assembly inspection and have not yet been run as a standalone reproduction.

Should AddGeometry support coordinates already in the native map grid? If a
different API is required for dynamic geometry on projected maps, could you point
us to it? We need to retain EPSG:25832 throughout, including highlights.

Thanks!

Hi Julian,

Both of these are answered.

The property list. Asking for the whole feature now means not naming anything: PROPERTYNAME is left out and the service returns its default content, which is what you suggested. A genuine column subset is still spelled out, so explicit selection is unchanged, and there is no option to set. Fixed in 15.0.0-beta197 — against your service GetRequestUrl(null, 2) returns the two features, and a bounding box query returns four with all their attributes.

One thing worth knowing for your own code: a styled layer draw only ever asked for the columns its styles need, which is already a subset, so that path was never sending the list the service refuses. It was the all-properties requests — GetRequestUrl, GetFeaturesInsideBoundingBoxAsync with no column list, and ReturningColumnsType.AllColumns.

AddGeometry on a projected map. That one is already in beta194, so an upgrade covers it. Your reading of beta193 is right — the guard counted registrations. It now asks what coordinate system each side is on, but both halves have to say:

var grid = TileMatrixSet.CreateTileMatrixSet(
    512, new RectangleShape(0, 10000000, 1000000, 0), new Projection(25832), 20);

var tiles = new FeatureSourceVectorTileSource(grid);
var selection = new InMemoryGeometrySource(new Projection(25832));
style.AddGeometry(selection);

A source that names no system is still taken to be web mercator and refused on a projected map, but now by name, telling you which two disagree.

Thanks,
Ben

Sweet, looks great, thanks!

That’s awesome! :+1: