I'd like to serve a NetCDF resource via WCS using MapServer Python bindings.
I borrowed a mapfile form the MapServer test suite wcs_netcdf_input_output.map
for which I adapted the wcs_onlineresource to point to my API endpoint "https://mydomain/get_wcs/test/wcs"
My API is based on FastAPI and the get_wcs method looks like:
@router.get('/get_wcs/{data_id}/wcs', response_class=Response)
async def get_wcs(data_id: str, full_request: Request):
print('hoi!')
map = mapscript.mapObj('/app/data/nc.map')
print(map)
ows_req = mapscript.OWSRequest()
ows_req.setParameter('service', 'wcs')
ows_req.setParameter('version', '2.0.0')
ows_req.setParameter('request', 'getcoverage')
ows_req.setParameter('coverageid', 'precipitation')
ows_req.setParameter('format', 'netCDF')
ows_req.type = mapscript.MS_GET_REQUEST
print(ows_req)
format = map.getOutputFormatByName("netCDF")
print(format)
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map.OWSDispatch(ows_req)
result = mapscript.msIO_getStdoutBufferBytes()
print(result)
content_type = mapscript.msIO_stripStdoutBufferContentType()
print(content_type)
#print('so far no errors')
#pass
ows_req.setParameter("REQUEST", "GetCapabilities")
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map.OWSDispatch(ows_req)
if dispatch_status != mapscript.MS_SUCCESS:
if os.getenv('DEBUG') == '1':
logging.debug(f"DISPATCH status: {dispatch_status}")
mapscript.msIO_stripStdoutBufferContentHeaders()
_result = mapscript.msIO_getStdoutBufferBytes()
content_type = 'text/xml'
dom = xml.dom.minidom.parseString(_result)
result_xml = dom.toprettyxml(indent="", newl="")
return Response(result_xml, media_type=content_type)
the result object seems to be some binary stream (which I guess is correct) but at this point I got lost, as I don't really know what to return, and how to handle the right request.
I then tried to resolve to a default GetCapabilities but the resulting XML (looks ok, info are read from the mapfile) but is not loaded/understood by QGIS (it looks like the following ) :
<?xml version="1.0" ?>
<wcs:Capabilities xmlns:wcs="http://www.opengis.net/wcs/2.0" xmlns:ows="http://www.opengis.net/ows/2.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmlcov="http://www.opengis.net/gmlcov/1.0" xmlns:swe="http://www.opengis.net/swe/2.0" xmlns:crs="http://www.opengis.net/wcs/crs/1.0" xmlns:int="http://www.opengis.net/wcs/interpolation/1.0" xsi:schemaLocation="http://www.opengis.net/wcs/2.0 http://schemas.opengis.net/wcs/2.0/wcsAll.xsd " version="2.0.0" updateSequence="2007-10-30T14:23:38Z">
<ows:ServiceIdentification>
<ows:Title>First Test Service</ows:Title>
<ows:Abstract>Test Abstract</ows:Abstract>
<ows:Keywords>
<ows:Keyword>keyword</ows:Keyword>
<ows:Keyword>list</ows:Keyword>
</ows:Keywords>
<ows:ServiceType codeSpace="OGC">OGC WCS</ows:ServiceType>
<ows:ServiceTypeVersion>2.0.1</ows:ServiceTypeVersion>
<ows:ServiceTypeVersion>1.1.1</ows:ServiceTypeVersion>
<ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
<ows:Profile>http://www.opengis.net/spec/WCS/2.0/conf/core</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_protocol-binding_get-kvp/1.0/conf/get-kvp</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_protocol-binding_post-xml/1.0/conf/post-xml</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/GMLCOV/1.0/conf/gml-coverage</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/GMLCOV/1.0/conf/multipart</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/GMLCOV/1.0/conf/special-format</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/GMLCOV_geotiff-coverages/1.0/conf/geotiff-coverage</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_service-extension_crs/1.0/conf/crs</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_service-extension_scaling/1.0/conf/scaling</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_service-extension_range-subsetting/1.0/conf/record-subsetting</ows:Profile>
<ows:Profile>http://www.opengis.net/spec/WCS_service-extension_interpolation/1.0/conf/interpolation</ows:Profile>
<ows:Fees>NONE</ows:Fees>
<ows:AccessConstraints>NONE</ows:AccessConstraints>
</ows:ServiceIdentification>
<ows:ServiceProvider>
<ows:ProviderName>OSGeo</ows:ProviderName>
<ows:ProviderSite xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs"/>
<ows:ServiceContact>
<ows:IndividualName>Name FamilyName</ows:IndividualName>
<ows:PositionName>Software Developer</ows:PositionName>
<ows:ContactInfo>
<ows:Phone>
<ows:Voice>(000) 000-0000</ows:Voice>
<ows:Facsimile>(000) 000-00000000</ows:Facsimile>
</ows:Phone>
<ows:Address>
<ows:DeliveryPoint>000 Xoxox Rd</ows:DeliveryPoint>
<ows:City>City</ows:City>
<ows:AdministrativeArea>Province</ows:AdministrativeArea>
<ows:PostalCode>xxx xxx</ows:PostalCode>
<ows:Country>World</ows:Country>
<ows:ElectronicMailAddress>[email protected]</ows:ElectronicMailAddress>
</ows:Address>
<ows:OnlineResource xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs"/>
<ows:HoursOfService>0800h - 1600h EST</ows:HoursOfService>
<ows:ContactInstructions>during hours of service</ows:ContactInstructions>
</ows:ContactInfo>
<ows:Role>staff</ows:Role>
</ows:ServiceContact>
</ows:ServiceProvider>
<ows:OperationsMetadata>
<ows:Operation name="GetCapabilities">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:type="simple" xlink:href="https://endpoint/get_wcs/test/wcs?"/>
<ows:Post xlink:type="simple" xlink:href="https://endpoint/get_wcs/test/wcs?">
<ows:Constraint name="PostEncoding">
<ows:AllowedValues>
<ows:Value>XML</ows:Value>
</ows:AllowedValues>
</ows:Constraint>
</ows:Post>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
<ows:Operation name="DescribeCoverage">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs?"/>
<ows:Post xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs?">
<ows:Constraint name="PostEncoding">
<ows:AllowedValues>
<ows:Value>XML</ows:Value>
</ows:AllowedValues>
</ows:Constraint>
</ows:Post>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
<ows:Operation name="GetCoverage">
<ows:DCP>
<ows:HTTP>
<ows:Get xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs?"/>
<ows:Post xlink:type="simple" xlink:href="https://wms.wps.met.no/get_wcs/test/wcs?">
<ows:Constraint name="PostEncoding">
<ows:AllowedValues>
<ows:Value>XML</ows:Value>
</ows:AllowedValues>
</ows:Constraint>
</ows:Post>
</ows:HTTP>
</ows:DCP>
</ows:Operation>
</ows:OperationsMetadata>
<wcs:ServiceMetadata>
<wcs:formatSupported>application/x-netCDF</wcs:formatSupported>
<wcs:Extension>
<int:InterpolationMetadata>
<int:InterpolationSupported>NEAREST</int:InterpolationSupported>
<int:InterpolationSupported>AVERAGE</int:InterpolationSupported>
<int:InterpolationSupported>BILINEAR</int:InterpolationSupported>
</int:InterpolationMetadata>
<crs:CrsMetadata>
<crs:crsSupported>http://www.opengis.net/def/crs/EPSG/0/4326</crs:crsSupported>
</crs:CrsMetadata>
</wcs:Extension>
</wcs:ServiceMetadata>
<wcs:Contents>
<wcs:CoverageSummary>
<wcs:CoverageId>precipitation</wcs:CoverageId>
<wcs:CoverageSubtype>RectifiedGridCoverage</wcs:CoverageSubtype>
<ows:Metadata xlink:type="simple" xlink:href="http://www.gdal.org/metadata_test_link.html"/>
</wcs:CoverageSummary>
</wcs:Contents>
</wcs:Capabilities>
My target is to load such layer (precipitation) into QGIS and be able to visualize/query the underling data. The test dataset was also borrowed from the MapServer test suite.