WFS Feature Extractor avatar

WFS Feature Extractor

Pricing

from $0.35 / 1,000 features

Go to Apify Store
WFS Feature Extractor

WFS Feature Extractor

Point at ANY classic OGC WFS 2.0/1.1 service (GeoServer, MapServer, deegree, QGIS-Server) behind national & city SDIs. Reads GetCapabilities, pages GetFeature by bbox/CQL, returns flat feature rows (geometry, lon/lat, computed bbox, properties, SRS) from GeoJSON OR GML. Pay per feature.

Pricing

from $0.35 / 1,000 features

Rating

0.0

(0)

Developer

Datamule

Datamule

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Point at ANY classic OGC WFS service and get clean, flat feature rows.

This actor is a generic runner for the classic OGC Web Feature Service (WFS) protocol — versions 2.0.0 and 1.1.0 (with a 1.0.0 courtesy fallback). Classic WFS is the older, still-ubiquitous XML vector-feature standard: GetCapabilitiesGetFeature. It is distinct from the modern JSON-native "OGC API - Features" — if your service exposes /collections/{id}/items JSON, use an OGC API Features extractor instead; this one speaks the classic SERVICE=WFS&REQUEST=GetFeature XML protocol that tens of thousands of GeoServer, MapServer, deegree, QGIS-Server and MapProxy deployments (national mapping agencies, city GIS portals, INSPIRE / national SDIs) still serve.

One actor turns any of them into structured rows — no per-site scraper.

What it does

  1. Reads GetCapabilities and parses the FeatureTypeList catalog (name, title, default CRS, advertised output formats).
  2. Pages GetFeature for each requested (or every advertised) feature type, using COUNT/STARTINDEX paging on 2.0.0.
  3. Negotiates the wire format: it prefers a GeoJSON format the type advertises, and falls back to the server-default GML — which it fully parses (GML 3.2 / 3.1.1 / 2.x; Point, LineString, Polygon and Multi* geometries) into the same normalized row shape. The GeoJSON path and the GML path yield identical coordinates.
  4. Normalizes axis order — the classic WFS/GML trap. GeoJSON is lon/lat by spec; GML coordinate order depends on the CRS, so for the well-known geographic CRSs (EPSG:4326 and friends) the parser swaps to lon/lat and flags geoAxisSwapped: true, while CRS84 and projected CRSs (e.g. EPSG:28992) are kept verbatim. Every row records its declared srs so nothing is ambiguous.

Modes

  • Discovery — leave Feature type name(s) empty (or turn on List feature types only): the actor emits one row per advertised feature type (name, title, abstract, default CRS, supported output formats). A cheap map of what the service serves.
  • Extract — set one or more Feature type name(s) (e.g. ms:cities, bag:pand) and optionally a BBOX, a CQL_FILTER, an OGC XML Filter, or an output srsName.

Input

FieldDescription
WFS service URL (required)Base URL the service answers GetCapabilities on, e.g. https://demo.mapserver.org/cgi-bin/wfs. Any pre-existing query (?map=…) is preserved.
Feature type name(s)One or more type names. Empty → discovery mode.
List feature types onlyDiscovery: list the catalog, fetch no features.
WFS versionPreferred version (2.0.0 / 1.1.0 / 1.0.0); auto-negotiated.
Bounding box (BBOX)Spatial filter, e.g. -60,-40,-50,-30,urn:ogc:def:crs:EPSG::4326.
CQL filterGeoServer/MapServer CQL_FILTER, e.g. POPULATION > 1000000.
OGC XML filterRaw <fes:Filter> for the standards-based FILTER param.
Output format overrideForce an OUTPUTFORMAT token; default auto-negotiates.
Output SRS (srsName)Request features reprojected to a CRS, e.g. EPSG:3857.
Max features (total)Cap across all pages/types. One billable event per feature.
Page sizeServer-side page size per request.
Extra query parametersVendor-specific passthrough (JSON object).
Bearer token / Extra headersOptional auth for gated deployments. Never logged.

Output

One row per feature, with a normalized shape regardless of the source wire format:

{
"_endpoint": "https://demo.mapserver.org/cgi-bin/wfs",
"_wfsVersion": "2.0.0",
"_outputFormat": "geojson",
"featureType": "cities",
"featureId": "cities.8338",
"geometryType": "Point",
"longitude": -58.6725,
"latitude": -34.5875,
"bbox": [-58.6725, -34.5875, -58.6725, -34.5875],
"srs": "urn:ogc:def:crs:OGC:1.3:CRS84",
"geoAxisSwapped": false,
"propertyKeys": ["NAME", "POPULATION"],
"propertyCount": 2,
"geometry": { "type": "Point", "coordinates": [-58.6725, -34.5875] },
"properties": { "POPULATION": 12116379, "NAME": "Buenos Aires" },
"sourceUrl": "https://demo.mapserver.org/cgi-bin/wfs?SERVICE=WFS&…",
"raw": { }
}

Discovery rows carry _outputFormat: "capabilities", title, abstract, defaultCrs and outputFormats instead.

Resilience

Per-type, like a batch harvester: a feature type that errors (HTTP 4xx/5xx, a timeout, a WFS ExceptionReport, or an unparseable body) is a skip-with-warning and the run continues. If a GeoJSON request fails, the type is retried once as server-default GML. A run where every requested type fails exits non-zero (91) so nothing broken ships. A reachable type that genuinely has no matching features yields 0 rows and a clean exit — the actor never fabricates rows.

Pricing

Pay-per-event: one feature charge per emitted row.

Example

Extract the three most-populous world cities from the OSGeo MapServer demo:

{
"wfsUrl": "https://demo.mapserver.org/cgi-bin/wfs",
"typeNames": ["cities"],
"cqlFilter": "POPULATION > 10000000",
"maxFeatures": 3
}