Skip to content

Instantly share code, notes, and snippets.

@epifanio
Created March 13, 2025 22:36
Show Gist options
  • Save epifanio/fab3c38861c2b4cd984e1196f6df2fed to your computer and use it in GitHub Desktop.
Save epifanio/fab3c38861c2b4cd984e1196f6df2fed to your computer and use it in GitHub Desktop.
MAP
NAME "Example MapServer WCS Multipart Issue"
CONFIG "MS_ERRORFILE" "stderr"
IMAGETYPE png
EXTENT 190365.000 444075.000 190465.000 444175.000
UNITS meters
MAXSIZE 4000
STATUS ON
DEBUG 5
WEB
METADATA
"ows_enable_request" "*"
"ows_fees" "NONE"
"ows_contactorganization" "Unknown"
"ows_schemas_location" "http://schemas.opengis.net"
"ows_service_onlineresource" "https://wms.wps.met.no/get_wcs/test/wcs"
"ows_contactperson" "ContactCenter Unknown"
"ows_contactposition" "pointOfContact"
"ows_contactvoicetelephone" ""
"ows_contactfacsimiletelephone" ""
"ows_addresstype" ""
"ows_address" ""
"ows_city" "City"
"ows_stateorprovince" ""
"ows_postcode" ""
"ows_country" "Country"
"ows_contactelectronicmailaddress" "[email protected]"
"ows_hoursofservice" ""
"ows_contactinstructions" ""
"ows_role" ""
"ows_srs" "EPSG:4326 EPSG:3857 EPSG:4258 CRS:84"
"ows_accessconstraints" "otherRestrictions;http://creativecommons.org/publicdomain/mark/1.0"
END
END
RESOLUTION 96
DEFRESOLUTION 96
PROJECTION
"init=epsg:28992"
END
OUTPUTFORMAT
NAME "GEOTIFF_FLOAT32"
DRIVER "GDAL/GTiff"
MIMETYPE "image/tiff"
IMAGEMODE FLOAT32
EXTENSION "tif"
FORMATOPTION "NULLVALUE=3.402823466385289e+38"
FORMATOPTION "COMPRESS=DEFLATE"
FORMATOPTION "PREDICTOR=3"
FORMATOPTION "RESAMPLING=bilinear"
END # OUTPUTFORMAT
WEB
IMAGEPATH "/app/data/"
IMAGEURL "/app/data/"
METADATA
"ows_title" "Example MapServer WCS Multipart Issue"
"wcs_label" "Example MapServer WCS Multipart Issue"
"wcs_name" "Example MapServer WCS Multipart Issue"
"ows_abstract" "Abstract"
"wcs_description" "Abstract"
"wcs_fees" "NONE"
"wcs_keywordlist" ""
"wcs_metadatalink_type" "TC211"
"wcs_metadatalink_format" "application/vnd.ogc.csw.GetRecordByIdResponse_xml"
"wcs_metadatalink_href" "http://www.example.com?service=CSW&request=GetRecordById&version=2.0.2&outputSchema=http://www.isotc211.org/2005/gmd&elementSetName=full&ID=2d5d70b2-5b83-49c9-bf41-08413657a670"
"wcs_onlineresource" "https://wms.wps.met.no/get_wcs/test/wcs"
"ows_inspire_capabilities" "url"
"ows_languages" "dut"
"ows_inspire_dsid_code" "d3a939fa-2d2b-4eeb-8b23-14a5113b83eb"
"ows_inspire_dsid_ns" "http://example.com/"
"ows_inspire_metadataurl_format" "application/vnd.ogc.csw.GetRecordByIdResponse_xml"
"ows_inspire_metadataurl_href" "http:/www.example.com/geonetwork/srv/dut/csw-inspire?service=CSW&request=GetRecordById&version=2.0.2&outputSchema=http://www.isotc211.org/2005/gmd&elementSetName=full&ID=2d5d70b2-5b83-49c9-bf41-08413657a670"
END # METADATA
END # WEB
LAYER
NAME coverage
METADATA
"wcs_name" "coverage"
"wcs_label" "Title" # label describecoverage/1.0.0
"wcs_description" "Title" # title describecoverage/1.1.0, description describecoverage/1.0.0 - N.B. description en label zijn gelijk in describecoverage/1.1.0 lijkt bug in mapserver te zijn
"wcs_abstract" "Abstract" # abstract describecoverage/1.1.0
"wcs_srs" "EPSG:28992"
"wcs_extent" "190365.000 444075.000 190465.000 444175.000"
"wcs_resolution" "0.5 0.5"
"wcs_rangeset_name" "Rangeset Name" ### required to support DescribeCoverage request
"wcs_rangeset_label" "rangeset_label" ### required to support DescribeCoverage request
"wcs_formats" "GEOTIFF_FLOAT32"
"wcs_imagemode" "FLOAT32"
"wcs_bandcount" "1"
"wcs_band_names" "band_name"
"wcs_significant_figures" "1"
"hoogte_band_uom" "m"
"hoogte_band_definition" "http://example.com/phenomenon/definition"
"hoogte_band_description" "Band description"
"hoogte_interval" "0 200"
END # METADATA
TYPE RASTER ### required
STATUS ON
DATA /app/data/data.tif
PROCESSING "RESAMPLE=BILINEAR"
PROJECTION
"init=epsg:28992"
END # PROJECTION
END # LAYER
END # MAP
import owslib
from owslib.wcs import WebCoverageService
wcs = WebCoverageService('https://wms.wps.met.no/get_wcs/test/wcs',
version='1.0.0')
cov_id = 'coverage'
coverage = wcs.contents[cov_id]
coverage.supportedFormats
crs = "http://www.opengis.net/def/crs/EPSG/0/28992"
bbox = (190365, 444075, 190465, 444175)
response = wcs.getCoverage(
identifier=cov_id,
crs='urn:ogc:def:crs:EPSG::28992',
bbox=bbox,
resx=0.5, resy=0.5,
format=coverage.supportedFormats[0])
with open('coverage3.tif', 'wb') as file:
file.write(response.read())
from osgeo import gdal
# import aioredis
import redis
from fastapi import Request, APIRouter, Query, HTTPException
from fastapi.responses import HTMLResponse, FileResponse, Response
import os
import sys
import logging
import logging.config
import yaml
import io
import mapscript
import xml.dom.minidom
import json
from urllib.parse import urlparse, parse_qs
sys.path.append('/app')
router = APIRouter()
# Load logging configuration from YAML file
with open('/app/logging.yaml', 'r') as file:
config = yaml.safe_load(file.read())
logging.config.dictConfig(config)
# Create logger
logger = logging.getLogger()
@router.get('/get_wms_template/wms', response_class=Response)
async def get_wms_template(full_request: Request):
print('hoi!')
map_object = mapscript.mapObj('/app/data/s2.map')
print(map_object)
logging.debug(f"map_object: {map_object}")
logging.debug(f"full_request: {full_request.query_params}")
ows_req = mapscript.OWSRequest()
ows_req.type = mapscript.MS_GET_REQUEST
if os.getenv('DEBUG') == '1':
logging.debug(f"full_request.query_params: {full_request.query_params}")
try:
ows_req.loadParamsFromURL(str(full_request.query_params))
except mapscript.MapServerError:
ows_req = mapscript.OWSRequest()
ows_req.type = mapscript.MS_GET_REQUEST
pass
if not full_request.query_params or ows_req.NumParams == 1:
if os.getenv('DEBUG') == '1':
logging.debug("Query params are empty. Force getcapabilities")
ows_req.setParameter("SERVICE", "WMS")
ows_req.setParameter("VERSION", "1.3.0")
ows_req.setParameter("REQUEST", "GetCapabilities")
else:
if os.getenv('DEBUG') == '1':
logging.debug(f"ALL query params: {str(full_request.query_params)}")
if os.getenv('DEBUG') == '1':
print(f"NumParams: {ows_req.NumParams}")
print(f"TYPE: {ows_req.type}")
if ows_req.getValueByName('REQUEST') != 'GetCapabilities':
mapscript.msIO_installStdoutToBuffer()
map_object.OWSDispatch( ows_req )
content_type = mapscript.msIO_stripStdoutBufferContentType()
result = mapscript.msIO_getStdoutBufferBytes()
else:
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map_object.OWSDispatch(ows_req)
if dispatch_status != mapscript.MS_SUCCESS:
if os.getenv('DEBUG') == '1':
logging.debug(f"DISPATCH status: {dispatch_status}")
content_type = mapscript.msIO_stripStdoutBufferContentType()
mapscript.msIO_stripStdoutBufferContentHeaders()
_result = mapscript.msIO_getStdoutBufferBytes()
if os.getenv('DEBUG') == '1':
print(f"content_type: {content_type}")
if content_type == 'application/vnd.ogc.wms_xml; charset=UTF-8':
content_type = 'text/xml'
dom = xml.dom.minidom.parseString(_result)
result = dom.toprettyxml(indent="", newl="")
return Response(result, media_type=content_type)
@router.get('/get_wcs/{data_id}/wcs', response_class=Response)
async def get_wcs(data_id: str, full_request: Request):
logging.debug(f"REQUEST URL: \n {full_request.url} \n")
map_object = mapscript.mapObj('/app/data/service.map')
layer = dict(full_request.query_params).get("LAYER")
layers = dict(full_request.query_params).get("LAYERS")
netloc = os.environ.get("NETLOC_ADDRESS", full_request.url.netloc)
scheme = os.environ.get("NETLOC_SCHEME", full_request.url.scheme)
ows_req = mapscript.OWSRequest()
ows_req.type = mapscript.MS_GET_REQUEST
try:
ows_req.loadParamsFromURL(str(full_request.query_params))
except mapscript.MapServerError:
logging.debug("loadParamsFromURL failed")
ows_req = mapscript.OWSRequest()
ows_req.type = mapscript.MS_GET_REQUEST
pass
if not full_request.query_params or ows_req.NumParams == 1:
logging.debug("Query params are empty. Force getcapabilities")
ows_req.setParameter("SERVICE", "WCS")
ows_req.setParameter("VERSION", "1.0.0")
ows_req.setParameter("REQUEST", "GetCapabilities")
else:
logging.debug(f"OWS REQUEST TYPE: {ows_req.type}")
logging.debug("Query params:")
logging.debug(f"NumParams: {ows_req.NumParams}")
for i in range(ows_req.NumParams):
logging.debug(f"{ows_req.getName(i)}: {ows_req.getValue(i)}")
if ows_req.getValueByName('REQUEST') not in ['GetCapabilities', 'DescribeCoverage', 'GetCoverage']:
logging.debug(f"got request: {ows_req.getValueByName('REQUEST')}")
dom = xml.dom.minidom.parseString(f"<p>{ows_req.getValueByName('REQUEST')}</p>")
result = dom.toprettyxml(indent="", newl="")
logging.debug(f"\n")
return Response(result, media_type='text/xml')
elif ows_req.getValueByName('REQUEST') == 'DescribeCoverage':
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map_object.OWSDispatch(ows_req)
if dispatch_status != mapscript.MS_SUCCESS:
logging.debug(f"DISPATCH status: {dispatch_status}")
content_type = mapscript.msIO_stripStdoutBufferContentType()
mapscript.msIO_stripStdoutBufferContentHeaders()
_result = mapscript.msIO_getStdoutBufferBytes()
if content_type == 'application/vnd.ogc.wms_xml; charset=UTF-8':
content_type = 'text/xml'
logging.debug(f"content_type: {content_type}")
dom = xml.dom.minidom.parseString(_result)
result = dom.toprettyxml(indent="", newl="")
logging.debug(f"\n")
return Response(result, media_type=content_type)
elif ows_req.getValueByName('REQUEST') == 'GetCoverage':
format =ows_req.getValueByName('FORMAT')
print(format)
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map_object.OWSDispatch(ows_req)
result = mapscript.msIO_getStdoutBufferBytes()
content_type = media_type="image/tiff"
# mapscript.msIO_stripStdoutBufferContentType()
print(content_type)
return Response(result, media_type=content_type)
else:
mapscript.msIO_installStdoutToBuffer()
dispatch_status = map_object.OWSDispatch(ows_req)
if dispatch_status != mapscript.MS_SUCCESS:
logging.debug(f"DISPATCH status: {dispatch_status}")
content_type = mapscript.msIO_stripStdoutBufferContentType()
mapscript.msIO_stripStdoutBufferContentHeaders()
_result = mapscript.msIO_getStdoutBufferBytes()
if content_type == 'application/vnd.ogc.wms_xml; charset=UTF-8':
content_type = 'text/xml'
logging.debug(f"content_type: {content_type}")
dom = xml.dom.minidom.parseString(_result)
result = dom.toprettyxml(indent="", newl="")
logging.debug(f"\n")
return Response(result, media_type=content_type)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment