diff --git a/data/rivm-rio/aps2raster/2015091611_no2.tif b/data/rivm-rio/aps2raster/2015091611_no2.tif new file mode 100644 index 0000000..10f00b0 Binary files /dev/null and b/data/rivm-rio/aps2raster/2015091611_no2.tif differ diff --git a/data/rivm-rio/aps2raster/2015091611_o3.tif b/data/rivm-rio/aps2raster/2015091611_o3.tif new file mode 100644 index 0000000..d621329 Binary files /dev/null and b/data/rivm-rio/aps2raster/2015091611_o3.tif differ diff --git a/data/rivm-rio/aps2raster/2015091611_pm10.tif b/data/rivm-rio/aps2raster/2015091611_pm10.tif new file mode 100644 index 0000000..88d895c Binary files /dev/null and b/data/rivm-rio/aps2raster/2015091611_pm10.tif differ diff --git a/src/rivm-rio/aps2raster-all.sh b/src/rivm-rio/aps2raster-all.sh new file mode 100755 index 0000000..9ae4161 --- /dev/null +++ b/src/rivm-rio/aps2raster-all.sh @@ -0,0 +1,3 @@ +./aps2raster.py ../../data/rivm-rio/output/2015091611_no2.aps ../../data/rivm-rio/aps2raster/2015091611_no2.tif +./aps2raster.py ../../data/rivm-rio/output/2015091611_o3.aps ../../data/rivm-rio/aps2raster/2015091611_o3.tif +./aps2raster.py ../../data/rivm-rio/output/2015091611_pm10.aps ../../data/rivm-rio/aps2raster/2015091611_pm10.tif diff --git a/src/rivm-rio/aps2raster.py b/src/rivm-rio/aps2raster.py index cde4dd7..8804011 100755 --- a/src/rivm-rio/aps2raster.py +++ b/src/rivm-rio/aps2raster.py @@ -11,12 +11,17 @@ # APS metadata provide input parameters for the GDAL functions, in particular the origin and # pixelsize. Projection is fixed at the Dutch EPSG:28992 (RD) projection. Although the APS # data are floats, they are rounded and converted to ints (0-255) in order to fit into the GeoTIFF. -# Negative values in the APS data like -999.0 are assumed to be 0 (TODO: maybe GDAL.NO_DATA later). +# Negative values in the APS data like -999.0 are assumed to be No Data values. +# +# This utility depends on the GDAL and NumPy Python libraries. +# +# Usage: python aps2raster.py import sys -import gdal,osr +import gdal, osr import numpy as np -def array2raster(out_file, origin, pixel_width, pixel_height, array, epsg_code): + +def array2raster(out_file, origin, pixel_width, pixel_height, array, meta, epsg_code): cols = array.shape[1] rows = array.shape[0] origin_x = origin[0] @@ -33,7 +38,13 @@ def array2raster(out_file, origin, pixel_width, pixel_height, array, epsg_code): # Write array data to first rasterband out_band = out_raster.GetRasterBand(1) + out_band.SetUnitType('ug/m3') out_band.SetNoDataValue(-999) + + metadata = { + 'name': 'concentration' + } + out_band.SetMetadata(metadata) out_band.WriteArray(array) # Project @@ -44,16 +55,23 @@ def array2raster(out_file, origin, pixel_width, pixel_height, array, epsg_code): # Writeout out_band.FlushCache() + def parse_aps_meta(meta_line): # APS Header - # Y M D H C unit sys comment format proj orig_x orig_y cols rows pix_w pix_h + # Y M D H C unit sys comment format proj orig_x orig_y cols rows pix_w pix_h # 15 9 16 10 NO2 ug/m3 RIO uurwaarden f7.1 1 0.000 620.000 70 80 4.000 4.000 + # Slice the string first as the "comment" field may have multiple words + # Becomes like '15 9 16 10 NO2 ug/m3 1 0.000 620.000 70 80 4.000 4.000' + meta_line_1 = meta_line[0:34] + meta_line_2 = meta_line[75:] + + meta_line_min = meta_line_1 + meta_line_2 # Remove excess whitespace - meta_line = " ".join(meta_line.split()) + meta_line_min = " ".join(meta_line_min.split()) # Now split with single whitespace - meta_arr = meta_line.split(' ') + meta_arr = meta_line_min.split(' ') # Build-up dict from array, do conversions where needed meta = dict() @@ -64,9 +82,9 @@ def parse_aps_meta(meta_line): meta['hour'] = int(meta_arr[3]) meta['component'] = meta_arr[4] meta['unit'] = meta_arr[5] - meta['system'] = meta_arr[6] - meta['comment'] = meta_arr[7] - meta['cell_format'] = meta_arr[8] + # meta['system'] = meta_arr[6] + # meta['comment'] = meta_arr[7] + # meta['cell_format'] = meta_arr[8] # Code voor coordinatenstelsel # 1. Amersfoortse coordinaten @@ -74,19 +92,21 @@ def parse_aps_meta(meta_line): # 3. Projectie op 50 NB (shifted pole) 4. projectie op 60 NB (shifted pole) 5. EMEP-coordinaten # 6. IE-coordinaten (EMEP/2.) # 7. OECD-coordinaten (EMEP/3.) - meta['projection'] = int(meta_arr[9]) + meta['projection'] = int(meta_arr[6]) # Upper left of upper left pixel - meta['origin_x'] = float(meta_arr[10])*1000 - meta['origin_y'] = float(meta_arr[11])*1000 + meta['origin_x'] = float(meta_arr[7]) * 1000 + meta['origin_y'] = float(meta_arr[8]) * 1000 - meta['columns'] = int(meta_arr[12]) - meta['rows'] = int(meta_arr[13]) - meta['pixel_width'] = float(meta_arr[14])*1000 - meta['pixel_height'] = float(meta_arr[15])*1000 + meta['columns'] = int(meta_arr[9]) + meta['rows'] = int(meta_arr[10]) + meta['pixel_width'] = float(meta_arr[11]) * 1000 + meta['pixel_height'] = float(meta_arr[12]) * 1000 + meta['meta'] = meta_line return meta + def read_aps_file(file_path): file = open(file_path, 'r') @@ -112,11 +132,12 @@ def read_aps_file(file_path): return meta, raster_array + if __name__ == "__main__": args = sys.argv - in_file = args[1] # '../../data/rivm-rio/output/2015091611_no2.aps' - out_file = args[2] # 'aps_no2.tif' + in_file = args[1] # '../../data/rivm-rio/output/2015091611_no2.aps' + out_file = args[2] # '../../data/rivm-rio/aps2raster/2015091611_no2.tif' aps_meta, aps_array = read_aps_file(in_file) origin = (aps_meta['origin_x'], aps_meta['origin_y'], 0) @@ -138,5 +159,5 @@ def read_aps_file(file_path): # aps_list = aps_array.tolist() # Convert to raster file - array2raster(out_file, origin, pixel_width, pixel_height, aps_array, 28992) + array2raster(out_file, origin, pixel_width, pixel_height, aps_array, aps_meta, 28992) diff --git a/src/rivm-rio/sld/aps_03.sld b/src/rivm-rio/sld/aps_03.sld new file mode 100644 index 0000000..009e073 --- /dev/null +++ b/src/rivm-rio/sld/aps_03.sld @@ -0,0 +1,30 @@ + + + + rivm_aps_o3 + + rivm_aps_o3 + rivm_aps_o3 + Style for RIVM APS raster O3 + + Feature + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/rivm-rio/sld/aps_no2.sld b/src/rivm-rio/sld/aps_no2.sld index f009394..5df1da0 100644 --- a/src/rivm-rio/sld/aps_no2.sld +++ b/src/rivm-rio/sld/aps_no2.sld @@ -13,14 +13,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/rivm-rio/sld/aps_pm10.sld b/src/rivm-rio/sld/aps_pm10.sld new file mode 100644 index 0000000..7c8dfe1 --- /dev/null +++ b/src/rivm-rio/sld/aps_pm10.sld @@ -0,0 +1,30 @@ + + + + rivm_aps_pm10 + + rivm_aps_pm10 + rivm_aps_pm10 + Style for RIVM APS raster PM10 + + Feature + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/heronviewer/config/Layout.js b/www/heronviewer/config/Layout.js index 110d940..e7abf3d 100644 --- a/www/heronviewer/config/Layout.js +++ b/www/heronviewer/config/Layout.js @@ -19,7 +19,7 @@ Heron.options.urls = Heron.scratch.urls; // Create end interval date from current date for timeseries slider config. Heron.date = new Date(); -Heron.date.setHours(Heron.date.getHours()-1); +Heron.date.setHours(Heron.date.getHours() - 1); Heron.date.setMinutes(0); Heron.date.setSeconds(0); Heron.date.setMilliseconds(0); @@ -27,7 +27,7 @@ Heron.date.setMilliseconds(0); Heron.date = Heron.date.toISOString(); Heron.cdate = new Date(); -Heron.cdate.setHours(Heron.cdate.getHours()-3); +Heron.cdate.setHours(Heron.cdate.getHours() - 3); Heron.cdate.setMinutes(0); Heron.cdate.setSeconds(0); Heron.cdate.setMilliseconds(0); @@ -180,6 +180,13 @@ Heron.layout = { // layer sources defaultSourceType: "gxp_wmssource", sources: { + rivm_wms: { + ptype: "gxp_wmssource", + url: 'http://geodata.rivm.nl/geoserver/ows?', + version: "1.1.1", + title: 'RIVM WMS', + owsPreviewStrategies: ['getlegendgraphic'] // or 'no preview available' if empty array + }, rivm_inspire_wms: { ptype: "gxp_wmssource", url: 'http://inspire.rivm.nl/geoserver/wms?', @@ -187,6 +194,14 @@ Heron.layout = { title: 'RIVM INSPIRE WMS', owsPreviewStrategies: ['getlegendgraphic'] // or 'no preview available' if empty array }, + + //geonovum_sospilot_wms: { + // ptype: "gxp_wmssource", + // url: 'http://sensors.geonovum.nl/gs/sensors/wms?', + // version: "1.1.1", + // title: 'Geonovum SOSPilot WMS', + // owsPreviewStrategies: ['getlegendgraphic'] // or 'no preview available' if empty array + //}, pdok_bagviewer_wms: { ptype: "gxp_wmssource", url: Heron.options.urls.PDOK + '/bagviewer/wms', @@ -194,6 +209,13 @@ Heron.layout = { title: 'PDOK BAG WMS', owsPreviewStrategies: ['getlegendgraphic'] // or 'no preview available' if empty array }, + pdok_bestuurlijkegrenzen_wms: { + ptype: "gxp_wmssource", + url: Heron.options.urls.PDOK + '/bestuurlijkegrenzen/wms', + version: "1.1.0", + title: 'PDOK Bestuurlijke Grenzen WMS', + owsPreviewStrategies: ['getlegendgraphic'] // or 'no preview available' if empty array + }, pdok_bagviewer_wfs: { ptype: "gxp_wfssource", url: Heron.options.urls.PDOK + '/bagviewer/wfs', @@ -201,22 +223,15 @@ Heron.layout = { title: 'PDOK BAG WFS', owsPreviewStrategies: ['randomcolor'] // or 'no preview available' if empty array }, - pdok_nwbspoorwegen_wfs: { - ptype: "gxp_wfssource", - url: Heron.options.urls.PDOK + '/nwbspoorwegen/wfs', - version: "1.1.0", - title: 'PDOK NWB Spoorwegen WFS', - owsPreviewStrategies: ['randomcolor'] // or 'no preview available' if empty array - }, - pdok_tms: { + map5_tms: { ptype: "gxp_tmssource", - url: Heron.options.urls.PDOK + '/tms/', + url: 'http://s.map5.nl/map/gast/tms/1.0.0/', isBaseLayer: true, // default is true group: 'background' // 'background' or 'default', default value is 'background' }, - geodan_tms: { + pdok_tms: { ptype: "gxp_tmssource", - url: 'http://services.geodan.nl/tms/', + url: Heron.options.urls.PDOK + '/tms/', isBaseLayer: true, // default is true group: 'background' // 'background' or 'default', default value is 'background' } diff --git a/www/heronviewer/config/Map.js b/www/heronviewer/config/Map.js index 272a188..44f5c8c 100644 --- a/www/heronviewer/config/Map.js +++ b/www/heronviewer/config/Map.js @@ -938,6 +938,77 @@ Heron.options.map.layers = [ ), /* END SMARTEM */ + /* START APS2RASTER */ + + + /* + * RIVM: APS2RASTER TEST NO2 + */ + new OpenLayers.Layer.WMS( + "TEST - RIO APS NO2", + Heron.scratch.urls.SOSPILOT_OWS, + {layers: "rio_no2_2015091611", format: "image/png", transparent: true}, + { + isBaseLayer: false, singleTile: true, visibility: false, alpha: true, + featureInfoFormat: "application/vnd.ogc.gml", transitionEffect: 'resize', + metadata: { + wfs: { + protocol: 'fromWMSLayer', + outputFormat: 'GML2', + featurePrefix: 'sensors', + featureNS: 'http://sensors.geonovum.nl', + downloadFormats: Heron.options.wfs.downloadFormats + } + } + } + ), + + /* + * RIVM: APS2RASTER TEST O3 + */ + new OpenLayers.Layer.WMS( + "TEST - RIO APS O3", + Heron.scratch.urls.SOSPILOT_OWS, + {layers: "rio_o3_2015091611", format: "image/png", transparent: true}, + { + isBaseLayer: false, singleTile: true, visibility: false, alpha: true, + featureInfoFormat: "application/vnd.ogc.gml", transitionEffect: 'resize', + metadata: { + wfs: { + protocol: 'fromWMSLayer', + outputFormat: 'GML2', + featurePrefix: 'sensors', + featureNS: 'http://sensors.geonovum.nl', + downloadFormats: Heron.options.wfs.downloadFormats + } + } + } + ), + + /* + * RIVM: APS2RASTER TEST PM10 + */ + new OpenLayers.Layer.WMS( + "TEST - RIO APS PM10", + Heron.scratch.urls.SOSPILOT_OWS, + {layers: "rio_pm10_2015091611", format: "image/png", transparent: true}, + { + isBaseLayer: false, singleTile: true, visibility: false, alpha: true, + featureInfoFormat: "application/vnd.ogc.gml", transitionEffect: 'resize', + metadata: { + wfs: { + protocol: 'fromWMSLayer', + outputFormat: 'GML2', + featurePrefix: 'sensors', + featureNS: 'http://sensors.geonovum.nl', + downloadFormats: Heron.options.wfs.downloadFormats + } + } + } + ), + + /* END APS2RASTER */ + /* START GEONOVUM WEATHER */ @@ -1811,18 +1882,21 @@ Heron.options.layertree.tree = [ { text: 'Nitrogen Dioxide (NO2) - WMS', expanded: true, children: [ {nodeType: "gx_layer", layer: "RIVM - History NO2"}, - {nodeType: "gx_layer", layer: "Smart Emission - History NO2"} + {nodeType: "gx_layer", layer: "Smart Emission - History NO2"}, + {nodeType: "gx_layer", layer: "TEST - RIO APS NO2"} ] }, { text: 'Ozone (O3) - WMS', expanded: true, children: [ {nodeType: "gx_layer", layer: "RIVM - History O3"}, - {nodeType: "gx_layer", layer: "Smart Emission - History O3"} + {nodeType: "gx_layer", layer: "Smart Emission - History O3"}, + {nodeType: "gx_layer", layer: "TEST - RIO APS O3"} ] }, { text: 'Particulate Matter (PM10) - WMS', expanded: true, children: [ - {nodeType: "gx_layer", layer: "RIVM - History PM10"} + {nodeType: "gx_layer", layer: "RIVM - History PM10"}, + {nodeType: "gx_layer", layer: "TEST - RIO APS PM10"} ] }, @@ -1936,73 +2010,73 @@ Heron.options.layertree.tree = [ // } //] //}, - //{ - // text: 'PDOK', expanded: false, children: [ - // { - // text: 'BAG', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "BAG - Adressen", text: "BAG Adressen"}, - // {nodeType: "gx_layer", layer: "BAG - Woonplaatsen", text: "BAG Woonplaatsen"}, - // {nodeType: "gx_layer", layer: "BAG - Ligplaatsen", text: "BAG Ligplaatsen"}, - // {nodeType: "gx_layer", layer: "BAG - Standplaatsen", text: "BAG Standplaatsen"}, - // {nodeType: "gx_layer", layer: "BAG - Verblijfsobjecten", text: "BAG Verblijfsobjecten"}, - // {nodeType: "gx_layer", layer: "BAG - Panden", text: "BAG Panden"}, - // {nodeType: "gx_layer", layer: "BAG - Panden (WFS)", text: "BAG Panden (WFS)"} - // ] - // }, - // { - // text: 'Bestuurlijke Grenzen', expanded: false, children: [ - // /* {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Buurten", text: "Buurten" }, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Wijken", text: "Wijken" }, */ - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Gemeenten", text: "Gemeenten (WMS)"}, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Gemeenten (WFS)", text: "Gemeenten (WFS)"}, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Provincies", text: "Provincies"}, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Provincies (WFS)", text: "Provincies (WFS)"}, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Land", text: "Land"}, - // {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Land (WFS)", text: "Land (WFS)"} - // ] - // }, - // { - // text: 'Digitaal Topografisch Bestand (DTB)', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "DTB Vlakken"}, - // {nodeType: "gx_layer", layer: "DTB Lijnen"}, - // {nodeType: "gx_layer", layer: "DTB Punten"} - // ] - // }, - // { - // text: 'Actueel Hoogtebestand (AHN)', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "AHN2 0.5m Ruw"}, - // {nodeType: "gx_layer", layer: "AHN2 0.5m Geinterpoleerd"}, - // {nodeType: "gx_layer", layer: "AHN2 0.5m Niet Geinterpoleerd"}, - // {nodeType: "gx_layer", layer: "AHN2 5m"}, - // {nodeType: "gx_layer", layer: "AHN2 Bladindex"}, - // {nodeType: "gx_layer", layer: "AHN 25m", text: 'AHN1 25m (Oud)'} - // ] - // }, - // { - // text: 'Rijksdriehoeksmeting (RDInfo)', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "RD Info - Punten"}, - // {nodeType: "gx_layer", layer: "RD Info - Stations"} - // ] - // - // }, - // { - // text: 'Natuur & Mileu', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "Natura 2000"}, - // {nodeType: "gx_layer", layer: "Nationale Parken"}, - // {nodeType: "gx_layer", layer: "NOK 2010 - EHS"}, - // {nodeType: "gx_layer", layer: "NOK 2010 - RODS"}, - // {nodeType: "gx_layer", layer: "NOK 2010 - BBLBuitenbegrenzing", text: "NOK 2010 - BBLBuitenbegr."} - // ] - // } - //] - //}, - //{ - // text: 'RO Online', expanded: false, children: [ - // {nodeType: "gx_layer", layer: "RO Online Bestemmingsplannen", text: "Bestemmingsplannen (BP)"}, - // {nodeType: "gx_layer", layer: "RO Online Gem. Structuurvisie", text: "Gem. Structuurvisie (GSV),"}, - // {nodeType: "gx_layer", layer: "RO Online Prov. Structuurvisie", text: "Prov. Structuurvisie (PSV)"} - //] - //}, + { + text: 'PDOK', expanded: false, children: [ + { + text: 'BAG', expanded: false, children: [ + {nodeType: "gx_layer", layer: "BAG - Adressen", text: "BAG Adressen"}, + {nodeType: "gx_layer", layer: "BAG - Woonplaatsen", text: "BAG Woonplaatsen"}, + {nodeType: "gx_layer", layer: "BAG - Ligplaatsen", text: "BAG Ligplaatsen"}, + {nodeType: "gx_layer", layer: "BAG - Standplaatsen", text: "BAG Standplaatsen"}, + {nodeType: "gx_layer", layer: "BAG - Verblijfsobjecten", text: "BAG Verblijfsobjecten"}, + {nodeType: "gx_layer", layer: "BAG - Panden", text: "BAG Panden"}, + {nodeType: "gx_layer", layer: "BAG - Panden (WFS)", text: "BAG Panden (WFS)"} + ] + }, + { + text: 'Bestuurlijke Grenzen', expanded: false, children: [ + /* {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Buurten", text: "Buurten" }, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Wijken", text: "Wijken" }, */ + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Gemeenten", text: "Gemeenten (WMS)"}, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Gemeenten (WFS)", text: "Gemeenten (WFS)"}, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Provincies", text: "Provincies"}, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Provincies (WFS)", text: "Provincies (WFS)"}, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Land", text: "Land"}, + {nodeType: "gx_layer", layer: "Bestuurlijke Grenzen - Land (WFS)", text: "Land (WFS)"} + ] + }, + { + text: 'Digitaal Topografisch Bestand (DTB)', expanded: false, children: [ + {nodeType: "gx_layer", layer: "DTB Vlakken"}, + {nodeType: "gx_layer", layer: "DTB Lijnen"}, + {nodeType: "gx_layer", layer: "DTB Punten"} + ] + }, + { + text: 'Actueel Hoogtebestand (AHN)', expanded: false, children: [ + {nodeType: "gx_layer", layer: "AHN2 0.5m Ruw"}, + {nodeType: "gx_layer", layer: "AHN2 0.5m Geinterpoleerd"}, + {nodeType: "gx_layer", layer: "AHN2 0.5m Niet Geinterpoleerd"}, + {nodeType: "gx_layer", layer: "AHN2 5m"}, + {nodeType: "gx_layer", layer: "AHN2 Bladindex"}, + {nodeType: "gx_layer", layer: "AHN 25m", text: 'AHN1 25m (Oud)'} + ] + }, + { + text: 'Rijksdriehoeksmeting (RDInfo)', expanded: false, children: [ + {nodeType: "gx_layer", layer: "RD Info - Punten"}, + {nodeType: "gx_layer", layer: "RD Info - Stations"} + ] + + }, + { + text: 'Natuur & Mileu', expanded: false, children: [ + {nodeType: "gx_layer", layer: "Natura 2000"}, + {nodeType: "gx_layer", layer: "Nationale Parken"}, + {nodeType: "gx_layer", layer: "NOK 2010 - EHS"}, + {nodeType: "gx_layer", layer: "NOK 2010 - RODS"}, + {nodeType: "gx_layer", layer: "NOK 2010 - BBLBuitenbegrenzing", text: "NOK 2010 - BBLBuitenbegr."} + ] + } + ] + }, + { + text: 'RO Online', expanded: false, children: [ + {nodeType: "gx_layer", layer: "RO Online Bestemmingsplannen", text: "Bestemmingsplannen (BP)"}, + {nodeType: "gx_layer", layer: "RO Online Gem. Structuurvisie", text: "Gem. Structuurvisie (GSV),"}, + {nodeType: "gx_layer", layer: "RO Online Prov. Structuurvisie", text: "Prov. Structuurvisie (PSV)"} + ] + }, { text: 'Scratch folder', expanded: false, children: [ {nodeType: "gx_layer", layer: "Tekenlaag", text: "Drawing Layer"},