WSL/SLF GitLab Repository

Commit 92454269 authored by Mathias Bavay's avatar Mathias Bavay
Browse files

The CNRM plugin can now be enabled and properly works. Its documentation has...

The CNRM plugin can now be enabled and properly works. Its documentation has been updated and improved. The NetCDF plugin can now read DEMs using various schema/conventions and its documentation now matches the code. A few more MeteoGrids have been defined that are required for meteorological model outputs and for some future spatial interpolations (ISW_DIR, ISW_DIFF for example). The PNG plugin creates a few more EXIF fields in order to make it very easy to integrate in google earth (but it seems that google earth does not like indexed pngs). A bug computing the geolocalization of grids coming from NetCDF has been fixed (all grids were slightly off).
parent 1d18e439
......@@ -51,6 +51,10 @@
#include <meteoio/plugins/BormaIO.h>
#endif
#ifdef PLUGIN_CNRMIO
#include <meteoio/plugins/CNRMIO.h>
#endif
#ifdef PLUGIN_COSMOXMLIO
#include <meteoio/plugins/CosmoXMLIO.h>
#endif
......@@ -117,13 +121,14 @@ namespace mio {
* <tr><td>\subpage arc "ARC"</td><td>dem, landuse, grid2d</td><td>ESRI/ARC ascii grid files</td><td></td></tr>
* <tr><td>\subpage arps "ARPS"</td><td>dem, grid2d</td><td>ARPS ascii formatted grids</td><td></td></tr>
* <tr><td>\subpage borma "BORMA"</td><td>meteo</td><td>Borma xml meteo files</td><td><A HREF="http://libxmlplusplus.sourceforge.net/">libxml++</A></td></tr>
* <tr><td>\subpage cnrm "CNRM"</td><td>dem, grid2d, meteo</td><td>NetCDF meteorological timeseries following the <A HREF="http://www.cnrm.meteo.fr/?lang=en">CNRM</A> schema</td><td><A HREF="http://www.unidata.ucar.edu/downloads/netcdf/index.jsp">NetCDF-C library</A></td></tr>
* <tr><td>\subpage cosmoxml "COSMOXML"</td><td>meteo</td><td>MeteoSwiss COSMO's postprocessing XML format</td><td><A HREF="http://xmlsoft.org/">libxml2</A></td></tr>
* <tr><td>\subpage geotop "GEOTOP"</td><td>meteo</td><td>GeoTop meteo files</td><td></td></tr>
* <tr><td>\subpage grass "GRASS"</td><td>dem, landuse, grid2d</td><td>Grass grid files</td><td></td></tr>
* <tr><td>\subpage gribio "GRIB"</td><td>meteo, dem, grid2d</td><td>GRIB meteo grid files</td><td><A HREF="http://www.ecmwf.int/products/data/software/grib_api.html">grib-api</A></td></tr>
* <tr><td>\subpage gsn "GSN"</td><td>meteo</td><td>connects to the Global Sensor Network web service interface</td><td><A HREF="http://curl.haxx.se/libcurl/">libcurl</A></td></tr>
* <tr><td>\subpage imis "IMIS"</td><td>meteo</td><td>connects to the IMIS database</td><td><A HREF="http://docs.oracle.com/cd/B12037_01/appdev.101/b10778/introduction.htm">Oracle's OCCI library</A></td></tr>
* <tr><td>\subpage netcdf "NETCDF"</td><td>meteo, dem, grid2d</td><td>NetCDF grids and meteorological timeseries</td><td><A HREF="http://www.unidata.ucar.edu/downloads/netcdf/index.jsp">NetCDF-C library</A></td></tr>
* <tr><td>\subpage netcdf "NETCDF"</td><td>dem, grid2d</td><td>NetCDF grids</td><td><A HREF="http://www.unidata.ucar.edu/downloads/netcdf/index.jsp">NetCDF-C library</A></td></tr>
* <tr><td>\subpage pgmio "PGM"</td><td>dem, grid2d</td><td>PGM grid files</td><td></td></tr>
* <tr><td>\subpage pngio "PNG"</td><td>dem, grid2d</td><td>PNG grid files</td><td><A HREF="http://www.libpng.org/pub/png/libpng.html">libpng</A></td></tr>
* <tr><td>\subpage psqlio "PSQL"</td><td>meteo</td><td>connects to PostgreSQL database</td><td><A HREF="http://www.postgresql.org/">PostgreSQL</A>'s libpq</td></tr>
......@@ -212,6 +217,9 @@ IOInterface* IOHandler::getPlugin(const std::string& plugin_name) const
#ifdef PLUGIN_COSMOXMLIO
if (plugin_name == "COSMOXML") return new CosmoXMLIO(cfg);
#endif
#ifdef PLUGIN_CNRMIO
if (plugin_name == "CNRM") return new CNRMIO(cfg);
#endif
#ifdef PLUGIN_GSNIO
if (plugin_name == "GSN") return new GSNIO(cfg);
#endif
......
......@@ -36,15 +36,21 @@ bool MeteoGrids::initStaticData()
//the order must be the same as in the enum
paramname.push_back("TA");
paramname.push_back("RH");
paramname.push_back("QI");
paramname.push_back("TD");
paramname.push_back("VW");
paramname.push_back("DW");
paramname.push_back("VW_MAX");
paramname.push_back("ISWR");
paramname.push_back("RSWR");
paramname.push_back("ISW_DIFF");
paramname.push_back("ISW_DIR");
paramname.push_back("ILWR");
paramname.push_back("TAU_CLD");
paramname.push_back("HS");
paramname.push_back("HNW");
paramname.push_back("HNW_S");
paramname.push_back("HNW_L");
paramname.push_back("TSG");
paramname.push_back("TSS");
paramname.push_back("P");
......
......@@ -48,15 +48,21 @@ class MeteoGrids {
enum Parameters {firstparam=0,
TA=firstparam, ///< Air temperature
RH, ///< Relative humidity
QI, ///< Specific humidity
TD, ///< Dew Point temperature
VW, ///< Wind velocity
DW, ///< Wind direction
VW_MAX, ///< Maximum wind velocity
ISWR, ///< Incoming short wave radiation
RSWR, ///< Reflected short wave radiation
ISW_DIFF, ///< Incoming short wave, diffuse
ISW_DIR, ///< Incoming short wave, direct
ILWR, ///< Incoming long wave radiation
TAU_CLD, ///< Cloud transmissivity or ISWR/ISWR_clear_sky
HS, ///< Height of snow
HNW, ///< Water equivalent of precipitations, either solid or liquid
HNW_S, ///< Water equivalent of precipitations, solid
HNW_L, ///< Water equivalent of precipitations, liquid
TSG, ///< Temperature ground surface
TSS, ///< Temperature snow surface
P, ///< Air pressure
......
......@@ -32,21 +32,13 @@ namespace mio {
/**
* @page cnrm CNRM
* @section cnrm_format Format
* In order to promote creation, access and sharing of scientific data, the NetCDF format has been
* created as a machine-independent format. NetCDF (network Common Data Form) is therefore an interface
* for array-oriented data access and a library that provides an implementation of the interface. The
* <A HREF="http://www.unidata.ucar.edu/downloads/netcdf/index.jsp">NetCDF software</A> was developed
* at the <A HREF="http://www.unidata.ucar.edu/">Unidata Program Center</A> in Boulder, Colorado.
* The <A HREF="http://www.cnrm.meteo.fr/">CNRM</A> has built a schema on the NetCDF format
* to contain meteorological timeseries suitable for forcing snow models. The NetCDF (network Common Data Form)
* format has been created as a machine-independent format by the
* <A HREF="http://www.unidata.ucar.edu/">Unidata Program Center</A> in Boulder, Colorado. It is
* an interface for array-oriented data access and a library that provides an implementation of the interface.
* In order to graphicaly explore the content and structure of NetCDF files, you can use the
* <A REF="http://www.epic.noaa.gov/java/ncBrowse/">ncBrowse></A> java software.
*
* The <A HREF="http://cfconventions.org">conventions</A> for climate and forecast (CF) metadata
* are designed to promote the processing and sharing of netCDF files. The conventions define metadata
* that provide a definitive description of what the data represents, and the spatial and temporal properties of the data.
* This plugin follows such conventions as well as the naming extensions defined by the
* <A HREF="http://www.cnrm.meteo.fr/">CNRM</A>.
*
* *Put here the more informations about the standard format that is implemented*
* <A HREF="http://www.epic.noaa.gov/java/ncBrowse/">ncBrowse</A> java software.
*
* @section cnrm_units Units
*
......
This diff is collapsed.
......@@ -59,51 +59,35 @@ class NetCDFIO : public IOInterface {
virtual void write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameters& parameter, const Date& date);
private:
enum TimeUnit { seconds, hours, days };
enum Naming { cf, cnrm, ecmwf };
typedef struct ATTRIBUTES {
ATTRIBUTES() : var(), standard_name(), long_name(), units(), height(IOUtils::nodata) {};
ATTRIBUTES(const std::string& str1, const std::string& str2, const std::string& str3, const std::string& str4, const double& hgt)
: var(str1), standard_name(str2), long_name(str3), units(str4), height(hgt) {};
std::string var;
std::string standard_name;
std::string long_name;
std::string units;
double height;
} attributes;
void initAttributesMap(std::string schema, std::map<MeteoGrids::Parameters, attributes> &attr);
void parseInputOutputSection();
void create_parameters(const int& ncid, const int& did_time, const int& did_points, const size_t& number_of_records,
const size_t& number_of_stations, std::map<size_t, std::string>& map_param_name,
std::map<std::string, double*>& map_data_2D, std::map<std::string, int>& varid);
void create_meta_data(const int& ncid, const int& did, std::map<std::string, double*>& map_data_1D, std::map<std::string, int>& varid);
void get_parameters(const std::vector< std::vector<MeteoData> >& vecMeteo, std::map<size_t, std::string>& map_param_name,
std::map<std::string, double*>& map_data_1D, double*& dates);
void get_parameters(const int& ncid, std::map<std::string, size_t>& map_parameters, MeteoData& meteo_data);
size_t get_dates(const std::vector< std::vector<MeteoData> >& vecMeteo, double*& dates);
void copy_data(const size_t& number_of_stations, const size_t& number_of_records, const std::vector< std::vector<MeteoData> >& vecMeteo,
const std::map<size_t, std::string>& map_param_name, std::map<std::string, double*>& map_data_2D);
void copy_data(const int& ncid, const std::map<std::string, size_t>& map_parameters, const std::map<std::string, double*> map_data,
const size_t& number_of_stations, const size_t& number_of_records, std::vector< std::vector<MeteoData> >& vecMeteo);
void readData(const int& ncid, const size_t& index_start, const std::vector<Date>& vec_date, const std::map<std::string, size_t>& map_parameters,
const MeteoData& meteo_data, std::vector< std::vector<MeteoData> >& vecMeteo);
void readMetaData(const int& ncid, std::vector<StationData>& vecStation);
void get_meta_data_ids(const int& ncid, std::map<std::string, int>& map_vid);
std::string get_varname(const MeteoGrids::Parameters& parameter);
void get_indices(const int& ncid, const Date& dateStart, const Date& dateEnd, size_t& indexStart, size_t& indexEnd, std::vector<Date>& vecDate);
void calculate_offset(const std::string& units, NetCDFIO::TimeUnit& time_unit, Date& offset);
void check_consistency(const int& ncid, const Grid2DObject& grid, double*& lat_array, double*& lon_array,
int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
void read2DGrid_internal(Grid2DObject& grid_out, const std::string& full_name, const std::string& varname, const Date& date=Date());
int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
bool read2DGrid_internal(Grid2DObject& grid_out, const std::string& full_name, const std::string& varname, const Date& date=Date());
void write2DGrid_internal(const Grid2DObject& grid_in, const std::string& filename, const std::string& varname, const Date& date=Date());
void add_attributes_for_variable(const int& ncid, const int& varid, const std::string& varname);
//void add_attributes_for_variable(const int& ncid, const int& varid, const std::string& varname);
void create_latlon_dimensions(const int& ncid, const Grid2DObject& grid, int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
void create_time_dimension(const int& ncid, int& did_time, int& vid_time);
// Private variables
static const double plugin_nodata; //plugin specific nodata value, e.g. -999
static const double epsilon; //for numerical comparisons of double values
static const std::string cf_time, cf_units, cf_days, cf_hours, cf_seconds, cf_latitude, cf_longitude, cf_altitude, cf_ta, cf_rh, cf_p;
static const std::string cnrm_points, cnrm_latitude, cnrm_longitude, cnrm_altitude, cnrm_aspect, cnrm_slope, cnrm_ta, cnrm_rh, cnrm_vw, cnrm_dw, cnrm_qair;
static const std::string cnrm_co2air, cnrm_theorsw, cnrm_neb, cnrm_hnw, cnrm_snowf, cnrm_swr_direct, cnrm_swr_diffuse, cnrm_p, cnrm_ilwr, cnrm_timestep;
static const std::string ecmwf_ta, ecmwf_p, ecmwf_iswr, ecmwf_ilwr, ecmwf_hnw, ecmwf_u10, ecmwf_v10, ecmwf_td;
static std::map<std::string, size_t> paramname; ///<Associate a name with meteo parameters in Parameters
static std::map<std::string, std::string> map_name; ///Associate MeteoIO parameter names with CNRM parameter names
static const bool __init; ///<helper variable to enable the init of static collection data
static bool initStaticData();///<initialize the static map
static const std::string cf_time, cf_latitude, cf_longitude, cf_altitude;
const Config cfg;
std::map <MeteoGrids::Parameters, attributes> in_attributes, out_attributes;
std::string coordin, coordinparam, coordout, coordoutparam; //projection parameters
double in_dflt_TZ, out_dflt_TZ; //default time zones
bool in_strict, out_strict;
......
......@@ -717,11 +717,20 @@ void PNGIO::createMetadata(const Grid2DObject& grid)
metadata_key.push_back("Cellsize");
ss.str(""); ss << fixed << setprecision(2) << grid.cellsize;
metadata_text.push_back(ss.str());
metadata_key.push_back("Latitude");
ss.str(""); ss << fixed << setprecision(6) << lat;
metadata_key.push_back("LL_Latitude");
ss.str(""); ss << fixed << setprecision(7) << lat;
metadata_text.push_back(ss.str());
metadata_key.push_back("Longitude");
ss.str(""); ss << fixed << setprecision(6) << lon;
metadata_key.push_back("LL_Longitude");
ss.str(""); ss << fixed << setprecision(7) << lon;
metadata_text.push_back(ss.str());
Coords UR(grid.llcorner);
UR.moveByXY( grid.cellsize*static_cast<double>(grid.getNx()) , grid.cellsize*static_cast<double>(grid.getNy()) );
metadata_key.push_back("UR_Latitude");
ss.str(""); ss << fixed << setprecision(7) << UR.getLat();
metadata_text.push_back(ss.str());
metadata_key.push_back("UR_Longitude");
ss.str(""); ss << fixed << setprecision(7) << UR.getLon();
metadata_text.push_back(ss.str());
if(lat<0.) {
......
......@@ -435,17 +435,13 @@ void copy_grid(const std::string& coordin, const std::string& coordinparam, cons
{
double resampling_factor_x = IOUtils::nodata, resampling_factor_y=IOUtils::nodata;
const double cellsize = calculate_cellsize(latlen, lonlen, lat, lon, resampling_factor_x, resampling_factor_y);
const double cntr_lat = .5*(lat[0]+lat[latlen-1]);
const double cntr_lon = .5*(lon[0]+lon[lonlen-1]);
//computing lower left corner by using the center point as reference
mio::Coords cntr(coordin, coordinparam);
cntr.setLatLon(cntr_lat, cntr_lon, IOUtils::nodata);
cntr.moveByXY(-.5*(double)(lonlen-1)*cellsize, -.5*(double)(latlen-1)*cellsize);
cntr.setLatLon(cntr_lat, cntr_lon, IOUtils::nodata); //it will be moved to llcorner later, after correcting the aspect ratio
grid_out.set(lonlen, latlen, cellsize, cntr);
//Handle the case of llcorner/urcorner swapped
if (lat[0]<=lat[latlen-1]) {
for (size_t kk=0; kk < latlen; kk++) {
......@@ -470,10 +466,13 @@ void copy_grid(const std::string& coordin, const std::string& coordinparam, cons
}
}
}
if (resampling_factor_x != mio::IOUtils::nodata) {
grid_out.grid2D = mio::ResamplingAlgorithms2D::BilinearResampling(grid_out.grid2D, resampling_factor_x, resampling_factor_y);
}
//computing lower left corner by using the center point as reference, AFTER we corrected for the aspect ratio
grid_out.llcorner.moveByXY(-.5*(double)grid_out.getNx()*cellsize, -.5*(double)grid_out.getNy()*cellsize);
}
/* The Grid2DObject holds data and meta data for quadratic cells. However the NetCDF file
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment