Geoserver – How to Put Together a WFS GetFeature Query

geoservergetfeaturewfs

I am new with WFS and GeoServer.

My goal is to search objects on a GeoServer via WFS.

To get started, I use the documentation. I already have problems at the beginning.


The request

http://localhost/geoserver/wfs?service=wfs&
  version=1.1.0&
  request=GetCapabilities

shows me the following in the browser Firefox:

GeoServer Web Feature ServiceThis is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.WFSWMSGEOSERVERWFS1.1.0NONENONEThe Ancient GeographersClaudius PtolomaeusChief GeographerAlexandriaEgyptclaudius.ptolomaeus@gmail.com1.0.01.1.0text/xmlServiceIdentificationServiceProviderOperationsMetadataFeatureTypeListFilter_Capabilitiestext/xml; subtype=gml/3.1.1resultshitstext/xml; subtype=gml/3.1.1GML2KMLSHAPE-ZIPapplication/gml+xml; version=3.2application/jsonapplication/vnd.google-earth.kml xmlapplication/vnd.google-earth.kml+xmlcsvgml3gml32jsontext/xml; subtype=gml/2.1.2text/xml; subtype=gml/3.22ALLSOMEresultshitstext/xml; subtype=gml/3.1.1GML2KMLSHAPE-ZIPapplication/gml+xml; version=3.2application/jsonapplication/vnd.google-earth.kml xmlapplication/vnd.google-earth.kml+xmlcsvgml3gml32jsontext/xml; subtype=gml/2.1.2text/xml; subtype=gml/3.2text/xml; subtype=gml/3.1.1GenerateNewUseExistingReplaceDuplicateALLSOMEQueryInsertUpdateDeleteLockgml:Envelopegml:Pointgml:LineStringgml:PolygonLessThanGreaterThanLessThanEqualToGreaterThanEqualToEqualToNotEqualToLikeBetweenNullCheckabsabs_2abs_3abs_4acosAddCoveragesAffineAggregateAreaarea2AreaGridasinatanatan2attributeCountBandMergeBandSelectBarnesSurfacebetweenboundaryboundaryDimensionboundedByBoundsbufferBufferFeatureCollectionbufferWithSegmentsCategorizeceilcentroidclassifyClassifyByRangeClipCollectGeometriesCollection_AverageCollection_BoundsCollection_CountCollection_MaxCollection_MedianCollection_MinCollection_NearestCollection_SumCollection_UniqueConcatenatecontainsContourcontrastconvertconvexHullConvolveCoveragecosCountCoverageClassStatsCropCoveragecrossesdarkendateDifferencedateFormatdateParsedesaturatedifferencedimensiondisjointdisjoint3Ddistancedistance3Ddouble2boolendAngleendPointenvenvelopeEqualAreaEqualIntervalequalsExactequalsExactToleranceequalToexpexteriorRingFeatureFeatureClassStatsfloorgeometrygeometryTypegeomFromWKTgeomLengthgetGeometryNgetXgetYgetzgrayscalegreaterEqualThangreaterThanGridHeatmaphslidIEEEremainderif_then_elseinin10in2in3in4in5in6in7in8in9InclusionFeatureCollectionint2bboolint2ddoubleinteriorPointinteriorRingNInterpolateintersectionIntersectionFeatureCollectionintersectsintersects3DisClosedisCoverageisEmptyisInstanceOfisLikeisNullisometricisRingisSimpleisValidisWithinDistanceisWithinDistance3DJenksJifflejsonPointerlengthlessEqualThanlessThanlightenlistlistMultiplylogLRSGeocodeLRSMeasureLRSSegmentmaxmax_2max_3max_4minmin_2min_3min_4mincircleminimumdiameterminrectanglemixmoduloMultiplyCoveragesNearestNormalizeCoveragenotnotEqualTonumberFormatnumberFormat2numGeometriesnumInteriorRingnumPointsoctagonalenvelopeoffsetoverlapsparameterparseBooleanparseDoubleparseIntparseLongpgNearestpiPointBufferspointNPointStackerPolygonExtractionpowpropertyPropertyExistsQuantileQueryrandomRangeLookupRasterAsPointCollectionRasterZonalStatisticsRasterZonalStatistics2RecodeRectangularCliprelaterelatePatternReprojectrescaleToPixelsrintroundround_2roundDoublesaturateScaleCoveragesetCRSshadeSimplifysinSnapspinsqrtStandardDeviationstartAnglestartPointstrAbbreviatestrCapitalizestrConcatstrDefaultIfBlankstrEndsWithstrEqualsIgnoreCasestrIndexOfstringTemplatestrLastIndexOfstrLengthstrMatchesstrPositionstrReplacestrStartsWithstrStripAccentsstrSubstringstrSubstringStartstrToLowerCasestrToUpperCasestrTrimstrTrim2strURLEncodeStyleCoveragesymDifferencetantinttoDegreestoRadianstouchestoWKTTransformTransparencyFillunionUnionFeatureCollectionUniqueUniqueIntervalVectorToRasterVectorZonalStatisticsverticeswithin

I was expecting to see what features I could use here.


The request

    http://localhost/geoserver/wfs?service=wfs&version=2.0.0&
  request=DescribeFeatureType

shows me the following in an editor

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs/2.0" elementFormDefault="qualified" targetNamespace="http://www.opengis.net/gml/3.2">

I expected a list of the feature types available.


Next I tried

    http://localhost/geoserver/wfs?
  service=wfs&
  version=2.0.0&
  request=GetFeature&
  typeNames=namespace:featuretype

that returned me

Unknown namespace [namespace]

And last but not least I tried with names I expected as namespace and featuretype

   http://localhost/geoserver/wfs?
  service=wfs&
  version=2.0.0&
  request=GetFeature&
  typeNames=JAN_ALKIS:flur

This tells me the following in the browser

Feature type JAN_ALKIS:flur unknown

How do I find out how to put together a WFS GetFeature query?

Edit:

The request

http://localhost/geoserver/wfs?service=wfs&
  version=1.1.0&
  request=GetCapabilities

shows me the following in the browser Chrome:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wfs:WFS_Capabilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:KRE_ALKIS="KRE_ALIKS" xmlns:KRE_KANAL="KRE_KANAL" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://172.16.206.128:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd" updateSequence="654">
<ows:ServiceIdentification>
<ows:Title>GeoServer Web Feature Service</ows:Title>
<ows:Abstract>
This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.
</ows:Abstract>
<ows:Keywords>
<ows:Keyword>WFS</ows:Keyword>
<ows:Keyword>WMS</ows:Keyword>
<ows:Keyword>GEOSERVER</ows:Keyword>
</ows:Keywords>
.....

enter image description here

Best Answer

You need a browser that is capable of displaying XML to be able to get into this - I recommend Chrome or Firefox. Clearly your getCapabilities request has been striped of the tags that make it meaningful. On a local instance I get an 86kB file that starts:

<wfs:WFS_Capabilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:tiger="http://www.census.gov" xmlns:nurc="http://www.nurc.nato.int" xmlns:sde="http://geoserver.sf.net" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:topp="http://www.openplans.org/topp" xmlns:sf="http://www.openplans.org/spearfish" xmlns:zoomstack="http://ianturton.com/zoomstack" xmlns:osopen_zoomstack="http://ianturton.com/osopen_zoomstack" xmlns:rasters="http://rasters" xmlns:osm="http://ianturton.com/osm" xmlns:osdata="http://os.uk/data" xmlns:osopen="http://ianturton.com/osopen" xmlns:ian="http://ianturton.com/ian" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd" updateSequence="7100">
  <ows:ServiceIdentification>
    <ows:Title>GeoServer Web Feature Service</ows:Title>
    <ows:Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</ows:Abstract>
    <ows:Keywords>
      <ows:Keyword>WFS</ows:Keyword>
      <ows:Keyword>WMS</ows:Keyword>
      <ows:Keyword>GEOSERVER</ows:Keyword>
    </ows:Keywords>
    <ows:ServiceType>WFS</ows:ServiceType>
    <ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion>

Which just tells me that this is a WFS, it's version 1.1.0 and if you are lucky tells you who owns this server (usually this is Claudius Ptolomaeus who is in charge of much of the worlds GeoSpatial infrastructure).

There are then sections that tell you (or a client program) what requests the service will answer, we can usually skip over these unless we want to do something odd. Basically, the only ones we ever care about are getCapabilities (which we've already used), describeFeatureType and getFeature.

The rest of the file is a list of available FeatureTypes (or layers) that we can ask questions about. For example:

<FeatureType xmlns:topp="http://www.openplans.org/topp">
  <Name>topp:tasmania_roads</Name>
  <Title>Tasmania roads</Title>
  <Abstract>Main Tasmania roads</Abstract>
  <ows:Keywords>
    <ows:Keyword>Roads</ows:Keyword>
    <ows:Keyword>Tasmania</ows:Keyword>
  </ows:Keywords>
  <DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS>
  <ows:WGS84BoundingBox>
    <ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner>
    <ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner>
  </ows:WGS84BoundingBox>
</FeatureType>

This gives me a name (topp:tasmainia_roads), hopefully some other human readable data like a title, abstract and keywords (don't hold your breath hoping for these though), a note of the Spatial Reference System (SRS or projection) the data is in (lat/lon degrees here) and finally, the WGS84 bounding box of the data set (again this might just be the whole world on lazy sites).

So to simply request some data I can make a request like:

http://localhost:8080/geoserver/wfs?service=wfs&request=GetFeature&version=1.1.0&typeName=topp:tasmania_roads

where I specify the service (WFS), request type (GetFeature), the version number (1.1.0) and the typeName I'm interested in (topp:tasmania_roads) exactly as given in the capabilities document. This gives me a screen full of XML (GML to be specific).

<?xml version="1.0" encoding="UTF-8"?>                                          
<wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:topp="http://www.openplans.org/topp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numberOfFeatures="14" timeStamp="2019-12-06T15:54:59.071Z" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd http://www.openplans.org/topp http://localhost:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp%3Atasmania_roads">
  <gml:featureMembers>                                                          
    <topp:tasmania_roads gml:id="tasmania_roads.1">                             
      <topp:the_geom>                                                           
        <gml:MultiLineString srsName="urn:x-ogc:def:crs:EPSG:4326" srsDimension="3">
          <gml:lineStringMember>                                                
            <gml:LineString>                                                    
              <gml:posList>-41.241 146.469 -41.241 -41.251 146.575 -41.251 -41.255 146.64 -41.255 -41.332 146.766 -41.332 -41.344 146.794 -41.344 -41.363 146.822 -41.363 -41.38 146.863 -41.38 -41.379 146.9 -41.379 -41.378 146.93 -41.378 -41.356 147.008 -41.356 -41.363 147.098 -41.363</gml:posList>
            </gml:LineString>                                                   
          </gml:lineStringMember>                                               
        </gml:MultiLineString>                                                  
      </topp:the_geom>                                                          
      <topp:TYPE>street</topp:TYPE>                                             
    </topp:tasmania_roads>                                                      
    <topp:tasmania_roads gml:id="tasmania_roads.2">

If however, we wanted to know what the "schema" or FeatureType of a layer was before we grabbed all the data then we could make a DescribeFeatureType request using a URL like:

http://localhost:8080/geoserver/wfs?service=WFS&request=DescribeFeatureType&version=1.1.0&typeName=topp:tasmania_roads

Everything is exactly the same as the GetFeature request except the request which is changed to DescribeFeatureType. This returns:

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:topp="http://www.openplans.org/topp" elementFormDefault="qualified" targetNamespace="http://www.openplans.org/topp">
  <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://localhost:8080/geoserver/schemas/gml/3.1.1/base/gml.xsd"/>
  <xsd:complexType name="tasmania_roadsType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="the_geom" nillable="true" type="gml:MultiLineStringPropertyType"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="TYPE" nillable="true" type="xsd:string"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="tasmania_roads" substitutionGroup="gml:_Feature" type="topp:tasmania_roadsType"/>
</xsd:schema>

Which tells us (or our client) to expect Features with two attributes "the_geom" (a MultiLineString) and "TYPE" (a String). Both attributes are optional (minOccurs=0) and could be NULL (nillable="true").

Note

In all the URLs the keywords (request, version, typeName) are case insensitive while the parameters are not - so reQueSt=WFS will work, typeName=TOPP:TASMANIA_Roads will not.

Related Question