class GeoSN(GeoSnService): indicator = None def __init__(self, _path='/srv/www/htdocs/monitor_ogc_xml/'): self.path = _path self.toolbox = Toolbox() def update(self): results = [] ind_values = IndicatorValues('raster') #the raster value wcs_values = ind_values.getAllAvaliableServiceValues("wcs") #the wfs values wfs_values = ind_values.getAllAvaliableServiceValues("wfs") for x in wfs_values: values = x['values'] # get the possible rster extends for val in values: ind_id = val["id"] ind_name = val['ind_name'] ind_description = val['interpretation'].replace('"', "'").replace( "\n", "") times = val["times"] methodology = self.toolbox.clean_string(val["methodik"]) unit = val["unit"] # builder self.indicator = IoerIndicator(ind_id, ind_name, ind_description, times, "WFS", unit, methodology) results.append(self.__updateFile("wfs")) for w in wcs_values: values = w['values'] # get the possible rster extends for val in values: ind_id = val["id"] ind_name = val['ind_name'] ind_description = val['interpretation'].replace('"', "'").replace( "\n", "") times = val["times"] methodology = self.toolbox.clean_string(val["methodik"]) unit = val["unit"] # builder self.indicator = IoerIndicator(ind_id, ind_name, ind_description, times, "WMS/WCS", unit, methodology) results.append(self.__updateFile("wms")) results.append(self.__updateFile("wcs")) return results #private function def __updateFile(self, service): indicator_set = self.indicator file = os.path.join( self.path, "{}_{}.xml".format(indicator_set.get_id(), service)) app.logger.debug(file) print(file) # Todo nach Id parsen und diese erst verwenden wenn die URL überenstimmen try: with open(file, "r", encoding="utf-8") as fr: doc = xmltodict.parse(fr.read().replace("&", "&")) fr.close() # set the time stamp now = datetime.datetime.now() doc["gmd:MD_Metadata"]["gmd:dateStamp"][ "gco:Date"] = now.strftime("%Y-%m-%d") # set the indicator values doc_ind = doc["gmd:MD_Metadata"]["gmd:identificationInfo"][ "srv:SV_ServiceIdentification"] doc_ind["gmd:citation"]["gmd:CI_Citation"]["gmd:title"][ "gco:CharacterString"] = "{} {}".format( service.upper(), indicator_set.get_name()) doc_ind["gmd:citation"]["gmd:CI_Citation"]["gmd:date"][ "gmd:CI_Date"]["gmd:date"]["gco:date"] = now.strftime( "%Y-%m-%d") doc_ind["gmd:abstract"][ "gco:CharacterString"] = "{} Weitere Informationen unter http://www.ioer-monitor.de/index.php?id=44&ID_IND={}".format( indicator_set.get_description(), indicator_set.get_id()) # set the operations doc_op = doc["gmd:MD_Metadata"]["gmd:identificationInfo"][ "srv:SV_ServiceIdentification"]["srv:containsOperations"] # parse for the urls and update them for op in doc_op: # extract id from the url node_op = op["srv:SV_OperationMetadata"][ "srv:operationName"]["gco:CharacterString"].get( "#text") url = "https://monitor.ioer.de/cgi-bin/{}?MAP={}_{}".format( service, indicator_set.get_id(), service) #build get capabilities URL if node_op == 'GetCapabilities': url = "{}&service={}&VERSION=2.0.0&REQUEST=GetCapabilities".format( url, service) op["srv:SV_OperationMetadata"]["srv:connectPoint"][ "gmd:CI_OnlineResource"]["gmd:linkage"][ "gmd:URL"] = url with open(file, "w", encoding="utf-8") as fw: out = xmltodict.unparse(doc, pretty=True) fw.write(out.replace("&", "&")) fw.close() app.logger.debug("Update Service for {}".format( "https://monitor.ioer.de/cgi-bin/{}?MAP={}_{}".format( service, indicator_set.get_id(), service))) return self.indicator.toJSON() except IOError as e: app.logger.debug( "Missing service for: {}&service={}&VERSION=2.0.0&REQUEST=GetCapabilities" .format( "https://monitor.ioer.de/cgi-bin/{}?MAP={}_{}".format( service, indicator_set.get_id(), service), service)) return self.indicator.toJSON("I/O error({0})".format(e))
class WcsService(OgcService): indicator = None def __init__(self, path='/mapsrv_daten/detailviewer/wcs_mapfiles'): self.service = 'wcs' self.path = os.chdir(path) self.toolbox = Toolbox() def createAllServices(self): ind_values = IndicatorValues('raster') wcs_values = ind_values.getAllAvaliableServiceValues(self.service) results = [] for x in wcs_values: values = x['values'] # get the possible rster extends for val in values: ind_id = val["id"] ind_name = val['ind_name'] ind_description = val['interpretation'].replace('"', "'").replace( "\n", "") times = val["times"] methodology = self.toolbox.clean_string(val["methodik"]) unit = val["unit"] url_spatial_extend = '%s?values={"ind":{"id":"%s"},"format":{"id":"raster"},"query":"getSpatialExtend"}' % ( Config.URL_BACKEND_SORA, ind_id) extends_request = requests.get(url_spatial_extend) extends = json.loads(extends_request.text) # builder self.indicator = IoerIndicator(ind_id, ind_name, ind_description, times, extends, unit, methodology) results.append(self.__writeFile()) return results def createSingleService(self, indicator, file_path=None): self.indicator = indicator self.__writeFile(file_path) def __writeFile(self, file_path=None): try: # extract the times time_array = self.indicator.get_time().split(",") if file_path: file = codecs.open(file_path, 'w', "utf-8") else: file = codecs.open( 'wcs_{}.map'.format(self.indicator.get_id().upper()), 'w', "utf-8") header = ( "MAP\n" 'NAME "WCS {0}"\n' "STATUS ON \n" "EXTENT 4000000 2650000 4700000 3600000\n" "UNITS METERS \n" 'SHAPEPATH "../data" \n' 'FONTSET "../mapfiles/fonts/fonts.txt" \n' 'IMAGECOLOR 255 255 255 \n' 'CONFIG "MS_ERRORFILE" "/mapsrv_daten/detailviewer/log/ms_new_wcs_log.txt"\n' 'CONFIG "PROJ_LIB" "/usr/share/proj/"\n' 'MAXSIZE 8192\n'.format(self.indicator.get_name())) file.write(header) output_format = ("OUTPUTFORMAT\n" " NAME GTiff\n" ' DRIVER "GDAL/GTiff"\n' ' MIMETYPE "image/tiff"\n' ' IMAGEMODE FLOAT32\n' ' EXTENSION "tif"\n' ' FORMATOPTION "NULLVALUE=-9998.000"\n' ' FORMATOPTION "COMPRESS=LZW"\n' ' FORMATOPTION "FILENAME=result.tiff"\n' 'END\n' '\n' 'OUTPUTFORMAT\n' ' NAME AAIGRID\n' ' DRIVER "GDAL/AAIGRID"\n' ' MIMETYPE "image/x-aaigrid"\n' ' IMAGEMODE INT16\n' ' EXTENSION "grd"\n' ' FORMATOPTION "FILENAME=result.grd"\n' 'END\n') file.write(output_format) meta = ( 'CONFIG "PROJ_LIB" "/usr/share/proj/"\n' 'WEB\n' ' IMAGEPATH "/srv/www/htdocs/ms_tmp/"\n' ' IMAGEURL "/ms_tmp/"\n' ' METADATA\n' ' "wcs_title" "WCS {0}"\n' ' "wcs_abstract" "{1}"\n' ' "wcs_label" "{0}"\n' ' "wcs_description" "{2}"\n' ' "wcs_fees" "none"\n' ' "wcs_accessconstraints" "none"\n' ' "wcs_keywordlist" "WCS,{0}"\n' ' "wcs_address" "Weberplatz 1"\n' ' "wcs_city" "Dresden"\n' ' "wcs_stateorprovince" "Sachsen"\n' ' "wcs_postcode" "01217"\n' ' "wcs_country" "Deutschland"\n' ' "wcs_contactelectronicmailaddress" "*****@*****.**"\n' ' "wcs_contactperson" "Dr.-Ing. Gotthard Meinel"\n' ' "wcs_contactorganization" "Leibniz Institut für ökologische Raumentwicklung"\n' ' "wcs_contactposition" "Forschungsbereichsleiter"\n' ' "wcs_contactvoicetelephone" "0351/4679254"\n' ' "wcs_enable_request" "*"\n' ' "wcs_encoding" "UTF-8"\n' ' "wcs_rangeset_nullvalue" "-9998.000"\n' ' "wcs_formats" "GTiff"\n' ' "wcs_nilvalues" "-9998.000"\n' ' "ows_enable_request" "*"\n' ' END\n' 'END\n' 'PROJECTION\n' ' "init=epsg:3035"\n' 'END\n'.format(self.indicator.get_name(), self.indicator.get_methodogy(), self.indicator.get_description())) file.write(meta) ''' Create the single layer ''' for t in sorted(time_array): int_time = int(t) now = datetime.datetime.now() if int_time >= 2006 and int_time <= now.year: for s in self.indicator.get_spatial_extends(): layer = ( "Layer\n" ' NAME "{0}_{1}_{2}m"\n' ' METADATA\n' ' "wcs_label" "{0}_{1}_{2}m" \n' ' "wcs_rangeset_name" "{3}"\n' ' "wcs_description " "{4}"\n' ' "wcs_extent" "4005000.000000 2655000.000000 4695000.000000 3595000.000000"\n' ' "wcs_cellsize" "{2}"\n' ' END\n' ' TYPE RASTER\n' ' STATUS ON\n' ' DATA "./{1}/Raster {2} m/r{2}_{1}_{0}.tif"\n' ' PROJECTION\n' ' "init=epsg:3035"\n' ' END\n' 'END\n'.format(self.indicator.get_id(), t, s, self.indicator.get_name(), self.indicator.get_description())) file.write(layer) created_layer = self.indicator.toJSON() app.logger.debug( "Finished WMS_service for Indicator:\n {0}".format( created_layer)) file.write("END") except IOError as e: created_layer = self.indicator.toJSON("I/O error({0})".format(e)) app.logger.debug( "Error in create WMS_service for Indicator:\n {0}".format( created_layer)) return created_layer
class WfsService(OgcService): indicator = None def __init__(self, path='/mapsrv_daten/detailviewer/wfs_mapfiles'): self.service = 'wfs' self.path = os.chdir(path) self.toolbox = Toolbox() def createAllServices(self): ind_values = IndicatorValues('gebiete') wfs_values = ind_values.getAllAvaliableServiceValues(self.service) results = [] for x in wfs_values: values = x['values'] for val in values: ind_id = val["id"] ind_name = val['ind_name'] ind_description = val['interpretation'].replace( '"', "'").replace("\n", "").replace("°°°°", "\n").replace("°", " ") times = val["times"] spatial_extends = val["spatial_extends"] methodology = self.toolbox.clean_string( val["methodik"]).replace("°°°°", "\n").replace("°", " ") unit = val["unit"] #builder self.indicator = IoerIndicator(ind_id, ind_name, ind_description, times, spatial_extends, unit, methodology) results.append(self.__writeFile()) return results def createSingleService(self, Indicator, file_path=None): self.indicator = Indicator self.__writeFile(file_path) def __writeFile(self, file_path=None): try: # extract the times time_array = self.indicator.get_time().split(",") if file_path: file = codecs.open(file_path, 'w', "utf-8") else: file = codecs.open( 'wfs_{}.map'.format(self.indicator.get_id().upper()), 'w', "utf-8") ''' The following File is created by taking care of the documentation of the Mapserver: https://mapserver.org/ogc/wfs_server.html ''' header = ( 'MAP \n' 'NAME "WFS {0}"\n' 'STATUS ON\n' 'EXTENT 280371.03 5235855.50 921120.19 6101444.00\n' 'UNITS METERS\n' 'SHAPEPATH" ../data"\n' 'CONFIG "MS_ERRORFILE" "/mapsrv_daten/detailviewer/log/ms_new_wfs_log.txt"\n' 'CONFIG "PROJ_LIB" "/usr/share/proj/"\n' 'WEB\n' 'IMAGEPATH "/srv/www/htdocs/ms_tmp/"\n' 'IMAGEURL "/ms_tmp/"\n'.format(self.indicator.get_name())) file.write(header) meta = ( "WEB \n" ' IMAGEPATH "/srv/www/htdocs/ms_tmp/" \n' ' IMAGEURL "/ms_tmp/" \n' ' METADATA \n' ' "wfs_title" "WFS {0}" \n' ' "wfs_abstract" "{1}" \n' ' "wfs_label" "WFS {0}" \n' ' "wfs_description" "{2}" \n' ' "wfs_fees" "none" \n' ' "wfs_accessconstraints" "none" \n' ' "wfs_address" "Weberplatz 1" \n' ' "wfs_city" "Dresden" \n' ' "wfs_stateorprovince" "Sachsen" \n' ' "wfs_postcode" "01217" \n' ' "wfs_country" "Deutschland" \n' ' "wfs_contactelectronicmailaddress" "*****@*****.**" \n' ' "wfs_contactperson" "Dr.-Ing. Gotthard Meinel" \n' ' "wfs_contactorganization" "Leibniz Institut für Ökologische Raumentwicklung" \n' ' "wfs_contactposition" "Forschungsbereichsleiter" \n' ' "wfs_contactvoicetelephone" "0351/4679254" \n' ' "ows_role" "Erzeuger" \n' ' "wfs_enable_request" "*" \n' ' "wfs_encoding" "UTF-8" \n' ' "ows_enable_request" "*"\n' "END \n" "END \n".format(self.indicator.get_name(), self.indicator.get_description(), self.indicator.get_methodogy())) file.write(meta) projection = ("PROJECTION \n" ' "init=epsg:25832" \n' "END \n") file.write(projection) ''' Create the single layer ''' for t in sorted(time_array): int_time = int(t) # extract the geometry year url_geom_year = '{"ind":{"time":"%s"},"query":"getgeomyear"}' % ( t) geom_year_request = requests.post( Config.URL_BACKEND_MONITOR, data={'values': url_geom_year}) geom_year = json.loads(geom_year_request.text) if int_time > 2006: for s in self.indicator.get_spatial_extends(): int_s = int(self.indicator.get_spatial_extends()[s]) if int_s == 1: epsg = '25832' geometry = 'the_geom' # geometry column is different for timeshifts in the year 2000 # # only the default year in geometry database is active, so only one Projection used # if s != 'g50' or s != 'stt': # if int_time <= 2012: # epsg = '31467' sql = '{0} from (select g.gid, g.ags, g.{0}, g.gen, a."{1}" as value from vg250_{2}_{5}_grob g join basiskennzahlen_{3} a on g.ags = a."AGS" where a."{1}" >=-1) as subquery using unique gid using srid={4}'.format( geometry, self.indicator.get_id(), s, t, epsg, geom_year) layer = ( 'LAYER \n' ' NAME "{0}_{1}" \n' ' METADATA \n' ' "wfs_title" "{2} {1} an {0}" \n' ' "wfs_abstract" "{2} {1} an {0}" \n' ' "wfs_description " "{3}" \n' ' "wfs_srs" "epsg:{4}" \n' ' "gml_include_items" "all" \n' ' "wfs_enable_request" "*" \n' ' "gml_constants" "value-einheit,Indikatorname" \n' ' "gml_value-einheit_type" "string" \n' ' "gml_value-einheit_value" "{5}" \n' ' "gml_exclude_items" "gid" \n' ' "gml_Indikatorname_type" "string" \n' ' "gml_Indikatorname_value" "{2} {1}" \n' ' "gml_featureid" "id" \n' ' END \n' '\n' ' TYPE POLYGON \n' ' STATUS ON \n' ' CONNECTIONTYPE POSTGIS \n' ' CONNECTION "host=localhost port=5432 dbname=monitor_geodat user=monitor_svg_admin password=monitorsvgadmin" \n' " DATA '{6}' \n" ' \n' ' PROJECTION \n' ' "init=epsg:{4}" \n' ' END \n' 'END \n' '\n'.format(s, t, self.indicator.get_name(), self.indicator.get_description(), epsg, self.indicator.get_units(), sql)) file.write(layer) created_layer = self.indicator.toJSON() # app.logger.debug("Finished WFS_service for Indicator:\n {0}".format(created_layer)) file.write("END") except IOError as e: created_layer = self.indicator.toJSON("I/O error({0})".format(e)) app.logger.debug( "Error in create WFS_service for Indicator:\n {0}".format( created_layer)) return created_layer
class WmsService(OgcService): indicator = None def __init__(self, path='/mapsrv_daten/detailviewer/wms_mapfiles'): self.service = 'wms' self.path = path self.toolbox = Toolbox() def getQuantil(self, id, width, year): quantile = [] # server path # quantile_path = "data/{0}/Raster {1} m/r{1}_{0}_{2}_quantile.txt".format(year,width,id) quantile_path = "data\\{0}\\Raster {1} m\\r{1}_{0}_{2}_quantile.txt".format( year, width, id) if "wms_mapfiles" in self.path: path = self.path.replace("wms_mapfiles", quantile_path) elif "wms_monitor" in self.path: path = self.path.replace("wms_monitor", quantile_path) try: with open(path) as quantile_csv: csv_reader = csv.reader(quantile_csv, delimiter=";") for row in csv_reader: quantile.append(row) # remove unneccessary values quantile = quantile[(len(quantile) - 1)] # get the classes class_number = quantile[0].split(":") quantile[0] = 0.0 quantile = [float(x) for x in quantile] return {"class_number": int(class_number[0]), "values": quantile} except: return False def createAllServices(self): ind_values = IndicatorValues('raster') wms_values = ind_values.getAllAvaliableServiceValues(self.service) results = [] for x in wms_values: cat = x['cat_name'] cat = cat.replace("ä", "ae").replace("ö", "oe").replace("ü", "ue") values = x['values'] # get the possible rster extends for val in values: ind_id = val["id"] ind_name = val['ind_name'] ind_description = val['interpretation'].replace('"', "'").replace( "\n", "") times = val["times"] methodology = self.toolbox.clean_string(val["methodik"]) unit = val["unit"] colors = val["colors"] url_spatial_extend = '%s?values={"ind":{"id":"%s"},"format":{"id":"raster"},"query":"getSpatialExtend"}' % ( Config.URL_BACKEND_SORA, ind_id) extends_request = requests.get(url_spatial_extend) extends = json.loads(extends_request.text) # builder self.indicator = IoerIndicator(ind_id, ind_name, ind_description, times, extends, unit, methodology, colors, cat) results.append(self.__writeFile()) return results def createSingleService(self, Indicator, file_path=None): self.indicator = Indicator return (self.__writeFile(file_path)) ''' old version creates mapfiles for the old mapserver ''' def __writeFile(self, file_path=None, old_version=False): try: # extract the times time_array = self.indicator.get_time().split(",") # get quantile app.logger.debug("Indicator:\n {0}".format( self.indicator.toJSON())) classes = self.getQuantil(self.indicator.get_id(), self.indicator.get_spatial_extends()[0], time_array[0])["class_number"] colors = Color(self.indicator.get_colors()["min"], self.indicator.get_colors()["max"], classes) colorPalette = colors.buildColorPalette() os.chdir(self.path) if old_version: file = codecs.open( '{}_{}_100.map'.format(self.indicator.get_cat(), self.indicator.get_id().upper()), 'w', "utf-8") else: file = codecs.open( 'wms_{}.map'.format(self.indicator.get_id().lower()), 'w', "utf-8") header = ( "MAP\n" 'NAME "WMS {0}"\n' "STATUS ON\n" "EXTENT 4000000 2650000 4700000 3600000\n" "UNITS METERS\n" 'SHAPEPATH "../data"\n' 'FONTSET "../mapfiles/fonts/fonts.txt"\n' "IMAGECOLOR 255 255 255\n" 'CONFIG "MS_ERRORFILE" "/mapsrv_daten/detailviewer/log/ms_log.txt"\n' 'CONFIG "PROJ_LIB" "/usr/share/proj/"\n\n'.format( self.indicator.get_name())) file.write(header) meta = ( "WEB\n" 'IMAGEPATH "/srv/www/htdocs/ms_tmp/"\n' 'IMAGEURL "/ms_tmp/"\n' ' METADATA\n' ' "wms_title" "wms {0}"\n' ' "wms_abstract" "{1}"\n' ' "wms_label" "{0}"\n' ' "wms_description" "{2}"\n' ' "wms_fees" "none"\n' ' "wms_accessconstraints" "none"\n' ' "wms_keywordlist" "wms,{0}"\n' ' "wms_address" "Weberplatz 1"\n' ' "wms_city" "Dresden"\n' ' "wms_stateorprovince" "Sachsen"\n' ' "wms_postcode" "01217"\n' ' "wms_country" "Deutschland"\n' ' "wms_contactelectronicmailaddress" "*****@*****.**"\n' ' "wms_contactperson" "Dr.-Ing. Gotthard Meinel"\n' ' "wms_contactorganization" "Leibniz Institut für ökologische Raumentwicklung"\n' ' "wms_contactposition" "Forschungsbereichsleiter"\n' ' "wms_contactvoicetelephone" "0351/4679254"\n' ' "wms_feature_info_mime_type" "text/html" \n' ' "wms_enable_request" "*"\n' ' "wms_encoding" "UTF-8"\n' ' "ows_enable_request" "*"\n' ' END\n' 'END\n\n' 'PROJECTION\n' ' "init=epsg:3035"\n' 'END\n\n'.format(self.indicator.get_name(), self.indicator.get_methodogy(), self.indicator.get_description())) file.write(meta) legend = ( "LEGEND\n" " STATUS ON\n" " KEYSIZE 18 12\n" " LABEL\n" " TYPE BITMAP\n" " SIZE MEDIUM\n" " COLOR 0 0 89\n" " END\n" ' TEMPLATE "/mapsrv_daten/detailviewer/mapfiles/legend.html"\n' "END\n\n") file.write(legend) for t in sorted(time_array): int_time = int(t) now = datetime.datetime.now() if int_time >= 2006 and int_time <= now.year: for s in self.indicator.get_spatial_extends(): layer = ( "LAYER\n" ' NAME "{0}_{1}_{2}m"\n' " METADATA\n" ' "wms_title" "{0}_{1}_{2}m"\n' ' "wms_extent" "4000000 2650000 4700000 3600000"\n' ' "wms_srs" "epsg:25832 epsg:25833 epsg:31466 epsg:31467 epsg:31468 epsg:31469 epsg:3034 epsg:3035 epsg:3044 epsg:3857 epsg:4258 epsg:4326"\n' ' "wms_feature_info_mime_type" "text/html" \n' ' END\n' ' TYPE RASTER\n' ' STATUS ON\n' ' PROJECTION\n' ' "init=epsg:3035"\n' ' END\n' ' PROCESSING "SCALE=-1,101"\n' ' PROCESSING "RESAMPLE=NEAREST"\n' ' DATA "./{1}/Raster {2} m/r{2}_{1}_{0}.tif"\n' ' TEMPLATE "template.html"\n' ' TOLERANCE 0\n' ' TOLERANCEUNITS pixels\n\n'.format( self.indicator.get_id(), t, s)) file.write(layer) try: quantile = self.getQuantil(self.indicator.get_id(), s, t)["values"] max = quantile[(len(quantile) - 1)] i = 0 for x in quantile: i += 1 if i < (len(quantile) - 1) and x != max: min = x after = quantile[i] color = colorPalette[i] elif x == max: min = quantile[(len(quantile) - 2)] after = max color = colorPalette[classes] wms_class = ( ' CLASS \n' ' NAME "> {0} bis {1} "\n' ' EXPRESSION ([pixel] > {0} and [pixel] <= {1})\n' ' STYLE\n' ' COLOR "{2}"\n' ' END\n' ' END\n'.format(min, after, color)) file.write(wms_class) except: print( "no quantil are avaliable for {}_{}_{}".format( self.indicator.get_id(), s, t)) file.write("END\n\n") created_layer = self.indicator.toJSON() app.logger.debug( "Finished WMS_service for Indicator:\n {0}".format( created_layer)) file.write("END") except IOError as e: created_layer = self.indicator.toJSON("I/O error({0})".format(e)) app.logger.debug( "Error in create WMS_service for Indicator:\n {0}".format( created_layer)) except: created_layer = self.indicator.toJSON( "I/O error({0})".format("Spatial Extend not defined")) app.logger.debug( "Error in create WMS_service for Indicator:\n {0}".format( created_layer)) return created_layer