[Python] serve netcdf via WCS protiocol with python and mapserver

Discussão em 'Python' iniciado por Stack, Março 11, 2025.

  1. Stack

    Stack Membro Participativo

    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:eek:ws="http://www.opengis.net/ows/2.0" xmlns:eek:gc="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>epi@epi.com</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.

    Thanks for any advice!

    Continue reading...

Compartilhe esta Página