Skip to content

Instantly share code, notes, and snippets.

@epifanio
Created March 25, 2025 14:36
Show Gist options
  • Save epifanio/a3c9c4550f1191be5d86c9025a8c4891 to your computer and use it in GitHub Desktop.
Save epifanio/a3c9c4550f1191be5d86c9025a8c4891 to your computer and use it in GitHub Desktop.
@router.get('/get_wms/{data_id}/wms', response_class=Response)
async def get_wms(data_id: str, full_request: Request):
S1_IW_LAYERS, S1_EW_LAYERS, S2_LAYERS, nbs_directory, sentinel_platforms, vrt_directory = set_sentinel_env()
logging.debug(f"REQUEST: {full_request}")
id = data_id # dict(full_request.query_params).get("id")
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)
if id is None and layer is None and layers is None:
raise HTTPException(status_code=404, detail="Missing required id or LAYER/s parameter")
# check if the datasource exists in redis
if id is None:
try:
id = layer.split('_')[0]
except AttributeError:
id = layers.split('_')[0]
# value = await redis.get(id)
# if value is None:
# sentinel_dict = get_sentinel_platform(id)
# async with redis.client() as conn:
# await conn.set(id, json.dumps(sentinel_dict))
# else:
# sentinel_dict = json.loads(value)
logging.debug(f"CALLING: redis_client.get(id) on {id}")
value = redis_client.get(id)
if value is None:
logging.debug(f"CALLING: get_sentinel_platform")
sentinel_dict = get_sentinel_platform(id)
if sentinel_dict is None:
raise HTTPException(status_code=404, detail=f"Resource: {id} - not found")
logging.debug(f"CALLING: redis_client.set(id, json.dumps(sentinel_dict)) on {id}")
redis_client.set(id, json.dumps(sentinel_dict))
else:
sentinel_dict = json.loads(value)
# logging.debug(f"sentinel_dict: {sentinel_dict}")
# if os.getenv('DEBUG') == '1':
# logging.debug(f"Sentinel dict: {sentinel_dict}")
if sentinel_dict is None:
if os.getenv('DEBUG') == '1':
logging.debug(f"resource: {id} - not found")
# check if redis has the following id as key and remove it
# value = await redis.get(id)
value = redis_client.get(id)
if value is not None:
logging.debug(f"removing resource: {id} from redis")
redis_client.delete(id)
raise HTTPException(status_code=404, detail=f"Resource: {id} - not found")
map_object = mapscript.mapObj()
map_object.name = "NBS"
map_object.web.metadata.set( "wms_title", f"{sentinel_dict[id]['title']}" )
map_object.web.metadata.set( "wms_abstract", f"{sentinel_dict[id]['abstract']}" )
map_object.web.metadata.set( "wms_enable_request", "*" )
map_object.web.metadata.set( "wms_keywordlist", "sentinel,earth observation,meteorology,atmosphere,climate,ocean,earth science" )
wms_api = os.getenv("WMS_API")
map_object.web.metadata.set( "wms_onlineresource", f"{wms_api}/get_wms/{id}/wms" )
platform = sentinel_dict[id]['platform']
if platform in ['S2A', 'S2B', 'S2C', 'S2D']:
layer_source_format = 'VRT'
for i in sentinel_dict[id][layer_source_format]:
if f"{id}_{i}_scaled.vrt" not in os.listdir(os.getenv("VRT_DIRECTORY")):
with open(f"{os.getenv('VRT_DIRECTORY')}/{id}_{i}_scaled.vrt", 'w') as f:
f.write(sentinel_dict[id][layer_source_format][i].get('VRT'))
if os.getenv('DEBUG') == '1':
logging.debug(f"Writing {id}_{i}_scaled.vrt")
else:
if os.getenv('DEBUG') == '1':
logging.debug(f"Found {id}_{i}_scaled.vrt")
else:
layer_source_format = 'GTIFF'
layer_info = sentinel_dict[id][layer_source_format][list(sentinel_dict[id][layer_source_format])[0]]
wms_srs = layer_info.get('SRS')
wms_projection = layer_info.get('proj4')
wms_extent = layer_info.get('geo_extent')
#map_object.setProjection(f"init={wms_srs}")
map_object.setProjection(f"init=epsg:4326")
map_object.setExtent(wms_extent[0],wms_extent[1],wms_extent[2],wms_extent[3])
#map_object.web.metadata.set( "wms_srs", wms_srs )
#map_object.web.metadata.set("wcs_enable_request", "*")
map_object.web.metadata.set("wms_srs", "EPSG:4326 CRS:84 EPSG:41001 EPSG:27700 EPSG:3408 EPSG:3409 EPSG:3857 EPSG:900913 EPSG:32661 EPSG:32761 EPSG:25833 EPSG:32628")
map_object.setSize(800, 600)
map_object.units = mapscript.MS_METERS
# map_object.setProjection("+proj=utm +zone=28 +ellps=WGS84 +units=m +no_defs")
# take the extent from the first layer
# extent = s2[list(s2.keys())[0]].get('extent')
logging.debug(f"Setting WMS request with: \n setProjection {wms_projection}, \n default wms_srs: {wms_srs}")
if platform in ['S2A', 'S2B', 'S2C', 'S2D']:
for i in sentinel_dict[id][layer_source_format]:
if f"{id}_{i}_scaled.vrt" not in os.listdir(os.getenv("VRT_DIRECTORY")):
with open(f"{os.getenv('VRT_DIRECTORY')}/{id}_{i}_scaled.vrt", 'w') as f:
f.write(sentinel_dict[id][layer_source_format][i].get('VRT'))
if os.getenv('DEBUG') == '1':
logging.debug(f"Writing {id}_{i}_scaled.vrt")
else:
if os.getenv('DEBUG') == '1':
logging.debug(f"Found {id}_{i}_scaled.vrt")
#
if os.getenv('DEBUG') == '1':
logging.debug(i)
layer = mapscript.layerObj()
#layer.setProjection("+proj=utm +zone=28 +ellps=WGS84 +units=m +no_defs")
# layer.setProjection('+init=epsg:32633')
#layer.setProjection(wms_projection)
layer.setProjection(f"init={wms_srs}")
layer.setExtent(wms_extent[0], wms_extent[1], wms_extent[2], wms_extent[3])
layer.status = 1
layer.data = f"{os.getenv('VRT_DIRECTORY')}/{id}_{i}_scaled.vrt"
layer.type = mapscript.MS_LAYER_RASTER
layer.name = f"{i}" # _{i}
# layer.metadata.set("wms_title", f"{sentinel_dict[id]['title']}_{i}")
#
layer.metadata.set("wms_title", f"Reflectance in band {i}")
layer.metadata.set("wms_abstract", f"Reflectance in band {i}")
layer.metadata.set("wcs_label", f"Reflectance in band {i}")
#layer.metadata.set("wcs_rangeset_name", "Range 1") ### required to support DescribeCoverage request
#layer.metadata.set("wcs_rangeset_label", "Label") ### required to support DescribeCoverage request
extent = sentinel_dict[id][layer_source_format][i].get('extent')
layer.metadata.set("wms_extent", f"{' '.join(map(str, extent))}")
layer.metadata.set("wms_layer_group", f"/{sentinel_dict[id]['title']}")
layer.metadata.set("wms_group_title", f"{sentinel_dict[id]['title']}")
# layer.metadata.set("wms_srs", f"{s2[i].get('SRS')}")
layer.metadata.set("wms_srs", "EPSG:4326 CRS:84 EPSG:41001 EPSG:27700 EPSG:3408 EPSG:3409 EPSG:3857 EPSG:900913 EPSG:32661 EPSG:5041 EPSG:32761 EPSG:25833 EPSG:32628")
map_object.insertLayer(layer)
for i in sentinel_dict[id]['ql']:
if os.getenv('DEBUG') == '1':
logging.debug(f"################################### {sentinel_dict[id]['ql']} {i}")
layer = mapscript.layerObj()
#layer.setProjection("+proj=utm +zone=28 +ellps=WGS84 +units=m +no_defs")
layer.status = 1
layer.data = sentinel_dict[id]['ql'][i]
layer.type = mapscript.MS_LAYER_RASTER
layer.name = f"{i}" # _{i}
layer.metadata.set("wms_title", f"{sentinel_dict[id]['title']}_{i}")
# layer.setProjection('+init=epsg:32633')
layer.setProjection(f"init={wms_srs}")
layer.setExtent(extent[0], extent[1], extent[2], extent[3])
layer.metadata.set("wms_title", f"{sentinel_s2_naming_mapping[i]['title']}")
layer.metadata.set("wms_abstract", f"{sentinel_s2_naming_mapping[i]['abstract']}")
# extent = s2[i].get('extent')
layer.metadata.set("wms_extent", f"{' '.join(map(str, extent))}")
layer.metadata.set("wms_layer_group", f"/composite")
layer.metadata.set("wms_group_title", f"Composite")
# layer.metadata.set("wms_srs", f"{s2[i].get('SRS')}")
layer.metadata.set("wms_srs", "EPSG:4326 CRS:84 EPSG:41001 EPSG:27700 EPSG:3408 EPSG:3409 EPSG:3857 EPSG:900913 EPSG:32661 EPSG:5041 EPSG:32761 EPSG:25833 EPSG:32628")
map_object.insertLayer(layer)
else:
for i in sentinel_dict[id]['ql']:
if os.getenv('DEBUG') == '1':
logging.debug(f"################################### {sentinel_dict[id]['ql']} {i}")
layer = mapscript.layerObj()
#layer.setProjection("+proj=utm +zone=28 +ellps=WGS84 +units=m +no_defs")
layer.setProjection('+init=epsg:32633')
#layer.setProjection(f"init={wms_srs}")
#layer.setExtent(extent[0], extent[1], extent[2], extent[3])
# { 'minx': 399955 , 'miny': 6890225 , 'maxx': 509755 , 'maxy': 7000025 }
logging.debug(f"so far so good")
layer.status = 1
layer.data = sentinel_dict[id]['ql'][i]
layer.type = mapscript.MS_LAYER_RASTER
layer.name = f"{i}"
layer.metadata.set("wms_title", f"{sentinel_s1_naming_mapping[i]['title']}")
layer.metadata.set("wms_abstract", f"{sentinel_s1_naming_mapping[i]['abstract']}")
# layer.metadata.set("wms_title", f"{sentinel_dict[id]['title']}_{i}")
# extent = s2[i].get('extent')
extent = sentinel_dict[id][layer_source_format][i].get('extent')
layer.metadata.set("wms_extent", f"{' '.join(map(str, extent))}")
layer.metadata.set("wms_layer_group", f"/composite")
layer.metadata.set("wms_group_title", f"Composite")
# layer.metadata.set("wms_srs", f"{s2[i].get('SRS')}")
layer.metadata.set("wms_srs", "EPSG:4326 CRS:84 EPSG:41001 EPSG:27700 EPSG:3408 EPSG:3409 EPSG:3857 EPSG:900913 EPSG:32661 EPSG:5041 EPSG:32761 EPSG:25833 EPSG:32628")
map_object.insertLayer(layer)
map_object.save(f"{os.getenv('VRT_DIRECTORY')}/{id}_{i}.map")
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="")
try:
logging.debug(f"Setting WMS request with: \n {dir(map_object)}, \n , EXTENT: {map_object.extent.toString()}, \n, PROJECTION: {map_object.getProjection()}")
except AttributeError:
print('failed logger')
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