[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [labplot] /: 1. Added NetCDF as import format
From:       Stefan Gerlach <stefan.gerlach () uni-konstanz ! de>
Date:       2015-05-31 18:01:56
Message-ID: E1Yz7Ya-0000Nj-Kh () scm ! kde ! org
[Download RAW message or body]

Git commit fc0a3f92354e4bcccc76a0c194be1b85c8a87575 by Stefan Gerlach.
Committed on 31/05/2015 at 18:00.
Pushed by sgerlach into branch 'master'.

1. Added NetCDF as import format
2. Added NetCDF filter for NetCDF file handling
3. Parser for NetCDF files added

M  +22   -11   CMakeLists.txt
M  +1    -1    ChangeLog
M  +1    -0    INSTALL
M  +5    -2    src/CMakeLists.txt
M  +1    -1    src/backend/datasources/FileDataSource.cpp
A  +506  -0    src/backend/datasources/filters/NetCDFFilter.cpp     [License: GPL \
(v2+)] A  +73   -0    src/backend/datasources/filters/NetCDFFilter.h     [License: \
GPL (v2+)] A  +85   -0    src/backend/datasources/filters/NetCDFFilterPrivate.h     \
[License: GPL (v2+)] M  +59   -6    src/kdefrontend/datasources/ImportFileWidget.cpp
M  +2    -0    src/kdefrontend/datasources/ImportFileWidget.h
A  +41   -0    src/kdefrontend/datasources/NetCDFOptionsWidget.cpp     [License: GPL \
(v2+)] A  +45   -0    src/kdefrontend/datasources/NetCDFOptionsWidget.h     [License: \
GPL (v2+)] A  +48   -0    src/kdefrontend/ui/datasources/netcdfoptionswidget.ui

http://commits.kde.org/labplot/fc0a3f92354e4bcccc76a0c194be1b85c8a87575

diff --git a/CMakeLists.txt b/CMakeLists.txt
index aff4795..ce7d2ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -80,17 +80,28 @@ ELSE (HDF5_FOUND)
 ENDIF (HDF5_FOUND)
 
 # ### NETCDF #####################################
-# FIND_LIBRARY(NETCDF_LIBRARY
-#   NAMES netcdf
-# )
-# IF(NETCDF_LIBRARY)
-# MESSAGE ("-- Found NETCDF library: ${NETCDF_LIBRARY}")
-# add_definitions (-DHAVE_NETCDF=1)
-# ELSE(NETCDF_LIBRARY)
-# MESSAGE ("-- NETCDF library NOT FOUND!")
-# SET(NETCDF_LIBRARY "")
-# ENDIF(NETCDF_LIBRARY)
-#  
+FIND_LIBRARY(NETCDF_LIBRARY netcdf
+	PATHS
+	/usr/lib
+	/usr/local/lib
+)
+FIND_PATH (NETCDF_INCLUDE_DIR netcdf.h
+	/usr/include/
+	/usr/local/include/
+)
+IF (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+	SET (NETCDF_FOUND TRUE)
+ELSE (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+	SET (NETCDF_FOUND FALSE)
+	SET (NETCDF_LIBRARY "")
+ENDIF (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+IF (NETCDF_FOUND)
+	MESSAGE (STATUS "Found Network Common Data Format (NetCDF) Library: \
${NETCDF_INCLUDE_DIR} ${NETCDF_LIBRARY}") +	add_definitions (-DHAVE_NETCDF=1)
+ELSE (NETCDF_FOUND)
+	MESSAGE (STATUS "Network Common Data Format (NetCDF) Library not found.")
+ENDIF (NETCDF_FOUND)
+  
 # ### CDF #####################################
 # FIND_LIBRARY(CDF_LIBRARY
 #   NAMES cdf
diff --git a/ChangeLog b/ChangeLog
index a676496..5c41ea1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@
 New features:
 	* New Matrix view for handling matrix data
 	* Import of binary, image and HDF data into spreadsheet or matrix
-	* Visual HDF parser to view content of files and import data sets
+	* Visual HDF and NetCDF parser to view content of files and import data sets
 	* Preview of all supported file types in import dialog
 	* Transparently import compressed data files
 	* In xy-curve the points may not be connected by the line if there are NANs \
                in-between. This behaviour is controlled by the parameter "skip gaps"
diff --git a/INSTALL b/INSTALL
index 4771760..608df2e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -3,6 +3,7 @@ LabPlot requires
 	* GSL version 1.15 or higher
 optional
 	* HDF5 1.8 or higher
+	* NetCDF 3 or higher
 
 ===============================================================================
 To build LabPlot just execute
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c02b85a..3bfb8d1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,10 +20,11 @@ set(GUI_SOURCES
 	${KDEFRONTEND_DIR}/datasources/AsciiMatrixOptionsWidget.cpp
 	${KDEFRONTEND_DIR}/datasources/BinaryOptionsWidget.cpp
 	${KDEFRONTEND_DIR}/datasources/HDFOptionsWidget.cpp
+	${KDEFRONTEND_DIR}/datasources/FileInfoDialog.cpp
 	${KDEFRONTEND_DIR}/datasources/ImageOptionsWidget.cpp
 	${KDEFRONTEND_DIR}/datasources/ImportFileWidget.cpp
 	${KDEFRONTEND_DIR}/datasources/ImportFileDialog.cpp
-	${KDEFRONTEND_DIR}/datasources/FileInfoDialog.cpp
+	${KDEFRONTEND_DIR}/datasources/NetCDFOptionsWidget.cpp
 	${KDEFRONTEND_DIR}/dockwidgets/AxisDock.cpp
 	${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotDock.cpp
 	${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotLegendDock.cpp
@@ -64,6 +65,7 @@ set(UI_SOURCES
 	${KDEFRONTEND_DIR}/ui/datasources/hdfoptionswidget.ui
 	${KDEFRONTEND_DIR}/ui/datasources/imageoptionswidget.ui
 	${KDEFRONTEND_DIR}/ui/datasources/importfilewidget.ui
+	${KDEFRONTEND_DIR}/ui/datasources/netcdfoptionswidget.ui
 	${KDEFRONTEND_DIR}/ui/dockwidgets/axisdock.ui
 	${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotdock.ui
 	${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotlegenddock.ui
@@ -124,6 +126,7 @@ set(BACKEND_SOURCES
 	${BACKEND_DIR}/datasources/filters/BinaryFilter.cpp
 	${BACKEND_DIR}/datasources/filters/HDFFilter.cpp
 	${BACKEND_DIR}/datasources/filters/ImageFilter.cpp
+	${BACKEND_DIR}/datasources/filters/NetCDFFilter.cpp
 	${BACKEND_DIR}/gsl/ExpressionParser.cpp
  	${BACKEND_DIR}/gsl/parser.tab.c
 	${BACKEND_DIR}/matrix/Matrix.cpp
@@ -176,7 +179,7 @@ set(LABPLOT_SRCS ${GUI_SOURCES} ${PLOTS_SOURCES})
 INCLUDE_DIRECTORIES(. ${GSL_INCLUDE_DIR} ${GSL_INCLUDEDIR}/..)
 kde4_add_ui_files(LABPLOT_SRCS ${UI_SOURCES})
 kde4_add_executable(labplot2 ${LABPLOT_SRCS} ${BACKEND_SOURCES} \
                ${DATASOURCES_SOURCES} ${COMMONFRONTEND_SOURCES} ${TOOLS_SOURCES})
-target_link_libraries(labplot2 ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${GSL_LIBRARIES} \
${GSL_CBLAS_LIBRARIES} ${HDF5_LIBRARY}) +target_link_libraries(labplot2 \
${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES} \
${HDF5_LIBRARY} ${NETCDF_LIBRARY})  # ${OPJ_LIBRARY}
 
 ############## installation ################################
diff --git a/src/backend/datasources/FileDataSource.cpp \
b/src/backend/datasources/FileDataSource.cpp index 967bb0d..7102e67 100644
--- a/src/backend/datasources/FileDataSource.cpp
+++ b/src/backend/datasources/FileDataSource.cpp
@@ -105,7 +105,7 @@ QStringList FileDataSource::fileTypes(){
 		<< i18n("Binary data")
 		<< i18n("Image")
 		<< i18n("Hierarchical Data Format (HDF)")
-//		<< "NetCDF"
+		<< i18n("Network Common Data Format (NetCDF)")
 //		<< "CDF"
 //		<< "FITS"
 //		<< i18n("Sound")
diff --git a/src/backend/datasources/filters/NetCDFFilter.cpp \
b/src/backend/datasources/filters/NetCDFFilter.cpp new file mode 100644
index 0000000..5278ab3
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilter.cpp
@@ -0,0 +1,506 @@
+/***************************************************************************
+File                 : NetCDFFilter.cpp
+Project              : LabPlot
+Description          : NetCDF I/O-filter
+--------------------------------------------------------------------
+Copyright            : (C) 2015 by Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*  This program is free software; you can redistribute it and/or modify   *
+*  it under the terms of the GNU General Public License as published by   *
+*  the Free Software Foundation; either version 2 of the License, or      *
+*  (at your option) any later version.                                    *
+*                                                                         *
+*  This program is distributed in the hope that it will be useful,        *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+*  GNU General Public License for more details.                           *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program; if not, write to the Free Software           *
+*   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
+*   Boston, MA  02110-1301  USA                                           *
+*                                                                         *
+***************************************************************************/
+#include "backend/datasources/filters/NetCDFFilter.h"
+#include "backend/datasources/filters/NetCDFFilterPrivate.h"
+#include "backend/datasources/FileDataSource.h"
+#include "backend/core/column/Column.h"
+
+#include <math.h>
+
+#include <QFile>
+#include <QTextStream>
+#include <QDebug>
+#include <KLocale>
+#include <KIcon>
+
+/*!
+	\class NetCDFFilter
+	\brief Manages the import/export of data from/to a NetCDF file.
+
+	\ingroup datasources
+*/
+NetCDFFilter::NetCDFFilter():AbstractFileFilter(), d(new NetCDFFilterPrivate(this)){
+
+}
+
+NetCDFFilter::~NetCDFFilter(){
+	delete d;
+}
+
+/*!
+  parses the content of the file \c fileName.
+*/
+void NetCDFFilter::parse(const QString & fileName, QTreeWidgetItem* rootItem){
+	d->parse(fileName, rootItem);
+}
+
+/*!
+  reads the content of the data set \c dataSet from file \c fileName.
+*/
+/*QString NetCDFFilter::readCurrentDataSet(const QString & fileName, \
AbstractDataSource* dataSource, AbstractFileFilter::ImportMode importMode,  int \
lines){ +	return d->readCurrentDataSet(fileName, dataSource, importMode, lines);
+}*/
+
+/*!
+  reads the content of the file \c fileName to the data source \c dataSource.
+*/
+void NetCDFFilter::read(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode){ +	d->read(fileName, dataSource, \
importMode); +}
+
+/*!
+writes the content of the data source \c dataSource to the file \c fileName.
+*/
+void NetCDFFilter::write(const QString & fileName, AbstractDataSource* dataSource){
+ 	d->write(fileName, dataSource);
+// 	emit()
+}
+
+///////////////////////////////////////////////////////////////////////
+/*!
+  loads the predefined filter settings for \c filterName
+*/
+void NetCDFFilter::loadFilterSettings(const QString& filterName){
+    Q_UNUSED(filterName);
+}
+
+/*!
+  saves the current settings as a new filter with the name \c filterName
+*/
+void NetCDFFilter::saveFilterSettings(const QString& filterName) const{
+    Q_UNUSED(filterName);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/*void NetCDFFilter::setCurrentDataSet(QString ds){
+	d->currentDataSet = ds;
+}
+
+QString NetCDFFilter::currentDataSet() const{
+	return d->currentDataSet;
+}*/
+
+void NetCDFFilter::setStartRow(const int s) {
+        d->startRow = s;
+}
+
+int NetCDFFilter::startRow() const{
+        return d->startRow;
+}
+
+void NetCDFFilter::setEndRow(const int e) {
+        d->endRow = e;
+}
+
+int NetCDFFilter::endRow() const{
+        return d->endRow;
+}
+
+void NetCDFFilter::setStartColumn(const int c){
+	d->startColumn=c;
+}
+
+int NetCDFFilter::startColumn() const{
+	return d->startColumn;
+}
+
+void NetCDFFilter::setEndColumn(const int c){
+	d->endColumn=c;
+}
+
+int NetCDFFilter::endColumn() const{
+	return d->endColumn;
+}
+
+void NetCDFFilter::setAutoModeEnabled(bool b){
+	d->autoModeEnabled = b;
+}
+
+bool NetCDFFilter::isAutoModeEnabled() const{
+	return d->autoModeEnabled;
+}
+//#####################################################################
+//################### Private implementation ##########################
+//#####################################################################
+
+NetCDFFilterPrivate::NetCDFFilterPrivate(NetCDFFilter* owner) : 
+	q(owner),startRow(1), endRow(-1),startColumn(1),endColumn(-1) {
+}
+
+#ifdef HAVE_NETCDF
+void NetCDFFilterPrivate::handleError(int status, QString function) {
+	if (status != NC_NOERR) {
+		qDebug()<<"ERROR:"<<function<<"() - "<<nc_strerror(status);
+	}
+}
+
+QString NetCDFFilterPrivate::translateDataType(nc_type type) {
+	QString typeString;
+
+	switch(type) {
+	case NC_BYTE:
+		typeString="BYTE";
+		break;
+	case NC_UBYTE:
+		typeString="UBYTE";
+		break;
+	case NC_CHAR:
+		typeString="CHAR";
+		break;
+	case NC_SHORT:
+		typeString="SHORT";
+		break;
+	case NC_USHORT:
+		typeString="USHORT";
+		break;
+	case NC_INT:
+		typeString="INT";
+		break;
+	case NC_UINT:
+		typeString="UINT";
+		break;
+//	case NC_LONG:
+//		typeString="LONG";
+//		break;
+	case NC_INT64:
+		typeString="INT64";
+		break;
+	case NC_UINT64:
+		typeString="UINT64";
+		break;
+	case NC_FLOAT:
+		typeString="FLOAT";
+		break;
+	case NC_DOUBLE:
+		typeString="DOUBLE";
+		break;
+	case NC_STRING:
+		typeString="STRING";
+		break;
+	default:
+		typeString="UNKNOWN";
+	}
+
+	return typeString;
+}
+
+void NetCDFFilterPrivate::scanAttrs(int ncid, int varid, int nattr, QTreeWidgetItem* \
parentItem) { +	int status;
+
+	char name[NC_MAX_NAME + 1];
+	nc_type type;
+	size_t len;
+	for(int i=0;i<nattr;i++) {
+		status = nc_inq_attname(ncid,varid,i,name);
+		handleError(status,"nc_inq_attname");
+
+		status = nc_inq_att(ncid, varid, name, &type, &len);
+		handleError(status,"nc_inq_att");
+		qDebug()<<"	attr"<<i+1<<": name/type/len="<<name<<translateDataType(type)<<len;
+
+		//read attribute
+		QStringList valueString;
+		switch(type) {
+		case NC_BYTE: {
+			signed char *value = (signed char *)malloc(len*sizeof(signed char));
+			status = nc_get_att_schar(ncid, varid, name, value);
+			handleError(status,"nc_get_att_schar");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_UBYTE: {
+			unsigned char *value = (unsigned char *)malloc(len*sizeof(unsigned char));
+			status = nc_get_att_uchar(ncid, varid, name, value);
+			handleError(status,"nc_get_att_uchar");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_CHAR: {
+			char *value = (char *)malloc((len+1)*sizeof(char));
+			status = nc_get_att_text(ncid, varid, name, value);
+			handleError(status,"nc_get_att_text");
+			value[len]=0;
+			valueString<<value;
+			free(value);
+			break;
+		}
+		case NC_SHORT: {
+			short *value = (short *)malloc(len*sizeof(short));
+			status = nc_get_att_short(ncid, varid, name, value);
+			handleError(status,"nc_get_att_short");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_USHORT: {
+			unsigned short *value = (unsigned short *)malloc(len*sizeof(unsigned short));
+			status = nc_get_att_ushort(ncid, varid, name, value);
+			handleError(status,"nc_get_att_ushort");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_INT: {
+			int *value = (int *)malloc(len*sizeof(int));
+			status = nc_get_att_int(ncid, varid, name, value);
+			handleError(status,"nc_get_att_int");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_UINT: {
+			unsigned int *value = (unsigned int *)malloc(len*sizeof(unsigned int));
+			status = nc_get_att_uint(ncid, varid, name, value);
+			handleError(status,"nc_get_att_uint");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_INT64: {
+			long long *value = (long long *)malloc(len*sizeof(long long));
+			status = nc_get_att_longlong(ncid, varid, name, value);
+			handleError(status,"nc_get_att_longlong");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_UINT64: {
+			unsigned long long *value = (unsigned long long *)malloc(len*sizeof(unsigned long \
long)); +			status = nc_get_att_ulonglong(ncid, varid, name, value);
+			handleError(status,"nc_get_att_ulonglong");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_FLOAT: {
+			float *value = (float *)malloc(len*sizeof(float));
+			status = nc_get_att_float(ncid, varid, name, value);
+			handleError(status,"nc_get_att_float");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		case NC_DOUBLE: {
+			double *value = (double *)malloc(len*sizeof(double));
+			status = nc_get_att_double(ncid, varid, name, value);
+			handleError(status,"nc_get_att_double");
+			for(unsigned int l=0;l<len;l++)
+				valueString<<QString::number(value[l]);
+			free(value);
+			break;
+		}
+		default:
+			valueString<<"not supported";
+		}
+
+		QStringList props;
+		props<<translateDataType(type)<<" ("<<QString::number(len)<<")";
+		QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")<<valueString.join(", ")); \
+		attrItem->setIcon(0,QIcon(KIcon("accessories-calculator"))); \
+		parentItem->addChild(attrItem); +	}
+}
+
+void NetCDFFilterPrivate::scanDims(int ncid, int ndims, QTreeWidgetItem* parentItem) \
{ +	int status;
+
+	int ulid;
+	status = nc_inq_unlimdim(ncid,&ulid);
+	handleError(status,"nc_inq_att");
+
+	char name[NC_MAX_NAME + 1];
+	size_t len;
+	for(int i=0;i<ndims;i++) {
+		status = nc_inq_dim(ncid, i, name, &len);
+		handleError(status,"nc_inq_att");
+		qDebug()<<"	dim"<<i+1<<": name/len="<<name<<len;
+		
+		QStringList props;
+		props<<"length = "<<QString::number(len);
+		QString value;
+		if(i == ulid)
+			value="unlimited";
+		QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")<<value); \
+		attrItem->setIcon(0,QIcon(KIcon("accessories-calculator"))); \
+		parentItem->addChild(attrItem); +	}
+}
+
+void NetCDFFilterPrivate::scanVars(int ncid, int nvars, QTreeWidgetItem* parentItem) \
{ +	int status;
+
+	char name[NC_MAX_NAME + 1];
+	nc_type type;
+	int ndims, nattrs;
+	int dimids[NC_MAX_VAR_DIMS];
+
+	for(int i=0;i<nvars;i++) {
+		status = nc_inq_var(ncid, i, name, &type, &ndims, dimids, &nattrs);
+		handleError(status,"nc_inq_att");
+
+		qDebug()<<"	var"<<i+1<<": name/type="<<name<<translateDataType(type);
+		qDebug()<<"		ndims/nattr"<<ndims<<nattrs;
+
+		QStringList props;
+		props<<translateDataType(type);
+		char dname[NC_MAX_NAME + 1];
+		size_t dlen;
+		for(int j=0;j<ndims;j++) {
+			status = nc_inq_dim(ncid, dimids[j], dname, &dlen);
+			if(j==0)
+				props<<" ("<<QString::number(dlen);
+			else
+				props<<"x"<<QString::number(dlen);
+		}
+		props<<")";
+
+		QTreeWidgetItem *varItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")); \
+		varItem->setIcon(0,QIcon(KIcon("x-office-spreadsheet"))); \
+		varItem->setBackground(0,QBrush(QColor(192,255,192))); \
+		parentItem->addChild(varItem); +
+		scanAttrs(ncid,i,nattrs,varItem);
+	}
+}
+#endif
+
+/*!
+    parses the content of the file \c fileName and fill the tree using rootItem.
+*/
+void NetCDFFilterPrivate::parse(const QString & fileName, QTreeWidgetItem* rootItem) \
{ +#ifdef HAVE_NETCDF
+	QByteArray bafileName = fileName.toLatin1();
+
+	int status, ncid;
+	status = nc_open(bafileName.data(), NC_NOWRITE, &ncid);
+	handleError(status,"nc_open");
+	
+	int ndims, nvars, nattr, uldid;
+	status = nc_inq(ncid, &ndims, &nvars, &nattr, &uldid);
+	handleError(status,"nc_inq");
+	qDebug()<<" nattr/ndims/nvars ="<<nattr<<ndims<<nvars;
+
+	QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Attributes")); +	attrItem->setIcon(0,QIcon(KIcon("folder")));
+	rootItem->addChild(attrItem);
+	scanAttrs(ncid,NC_GLOBAL,nattr,attrItem);
+
+	QTreeWidgetItem *dimItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Dimensions")); +	dimItem->setIcon(0,QIcon(KIcon("folder")));
+	rootItem->addChild(dimItem);
+	scanDims(ncid,ndims,dimItem);
+
+	QTreeWidgetItem *varItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Variables")); +	varItem->setIcon(0,QIcon(KIcon("folder")));
+	rootItem->addChild(varItem);
+	scanVars(ncid,nvars,varItem);
+
+	//TODO: scan NetCDF file
+#else
+	Q_UNUSED(fileName)
+	Q_UNUSED(rootItem)
+#endif
+}
+
+/*!
+    reads the content of the file \c fileName to the data source \c dataSource.
+    Uses the settings defined in the data source.
+*/
+void NetCDFFilterPrivate::read(const QString & fileName, AbstractDataSource* \
dataSource, AbstractFileFilter::ImportMode mode){ +	Q_UNUSED(fileName);
+	Q_UNUSED(dataSource);
+	Q_UNUSED(mode);
+	//TODO
+
+/*	if(currentDataSet.isEmpty()) {
+		qDebug()<<" No data set selected";
+		return;
+	}
+
+#ifdef QT_DEBUG
+	else
+		qDebug()<<" current data set ="<<currentDataSet;
+#endif
+*/
+//	readCurrentDataSet(fileName,dataSource,mode);
+}
+
+/*!
+    writes the content of \c dataSource to the file \c fileName.
+*/
+void NetCDFFilterPrivate::write(const QString & fileName, AbstractDataSource* \
dataSource){ +	Q_UNUSED(fileName);
+	Q_UNUSED(dataSource);
+	//TODO
+}
+
+//##############################################################################
+//##################  Serialization/Deserialization  ###########################
+//##############################################################################
+
+/*!
+  Saves as XML.
+ */
+void NetCDFFilter::save(QXmlStreamWriter* writer) const {
+	writer->writeStartElement("hdfFilter");
+	writer->writeAttribute("autoMode", QString::number(d->autoModeEnabled) );
+	writer->writeEndElement();
+}
+
+/*!
+  Loads from XML.
+*/
+bool NetCDFFilter::load(XmlStreamReader* reader) {
+	if(!reader->isStartElement() || reader->name() != "hdfFilter"){
+		reader->raiseError(i18n("no hdf filter element found"));
+		return false;
+	}
+
+	QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is \
used"); +	QXmlStreamAttributes attribs = reader->attributes();
+
+	// read attributes
+	QString str = attribs.value("autoMode").toString();
+	if(str.isEmpty())
+		reader->raiseWarning(attributeWarning.arg("'autoMode'"));
+	else
+		d->autoModeEnabled = str.toInt();
+
+	return true;
+}
diff --git a/src/backend/datasources/filters/NetCDFFilter.h \
b/src/backend/datasources/filters/NetCDFFilter.h new file mode 100644
index 0000000..245e0f5
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilter.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+File                 : NetCDFFilter.h
+Project              : LabPlot
+Description          : NetCDF I/O-filter
+--------------------------------------------------------------------
+Copyright            : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+*                                                                         *
+*  This program is free software; you can redistribute it and/or modify   *
+*  it under the terms of the GNU General Public License as published by   *
+*  the Free Software Foundation; either version 2 of the License, or      *
+*  (at your option) any later version.                                    *
+*                                                                         *
+*  This program is distributed in the hope that it will be useful,        *
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+*  GNU General Public License for more details.                           *
+*                                                                         *
+*   You should have received a copy of the GNU General Public License     *
+*   along with this program; if not, write to the Free Software           *
+*   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
+*   Boston, MA  02110-1301  USA                                           *
+*                                                                         *
+***************************************************************************/
+#ifndef NETCDFFILTER_H
+#define NETCDFFILTER_H
+
+#include <QStringList>
+#include <QTreeWidgetItem>
+#include "backend/datasources/filters/AbstractFileFilter.h"
+
+class NetCDFFilterPrivate;
+class NetCDFFilter : public AbstractFileFilter{
+	Q_OBJECT
+
+  public:
+
+	NetCDFFilter();
+	~NetCDFFilter();
+
+	void parse(const QString & fileName, QTreeWidgetItem* rootItem);
+	void read(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace); +//	QString \
readCurrentDataSet(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace, int lines=-1); \
+	void write(const QString & fileName, AbstractDataSource* dataSource); +
+	void loadFilterSettings(const QString&);
+	void saveFilterSettings(const QString&) const;
+
+/*	void setCurrentDataSet(const QString);
+	QString currentDataSet() const;
+*/
+	void setStartRow(const int);
+	int startRow() const;
+	void setEndRow(const int);
+	int endRow() const;
+	void setStartColumn(const int);
+	int startColumn() const;
+	void setEndColumn(const int);
+	int endColumn() const;
+
+	void setAutoModeEnabled(const bool);
+	bool isAutoModeEnabled() const;
+
+	virtual void save(QXmlStreamWriter*) const;
+	virtual bool load(XmlStreamReader*);
+  private:
+	NetCDFFilterPrivate* const d;
+	friend class NetCDFFilterPrivate;
+};
+
+#endif
diff --git a/src/backend/datasources/filters/NetCDFFilterPrivate.h \
b/src/backend/datasources/filters/NetCDFFilterPrivate.h new file mode 100644
index 0000000..ab9c178
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilterPrivate.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+File                 : NetCDFFilterPrivate.h
+Project              : LabPlot
+Description          : Private implementation class for NetCDFFilter.
+--------------------------------------------------------------------
+Copyright            : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the Free Software           *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
+ *   Boston, MA  02110-1301  USA                                           *
+ *                                                                         *
+ ***************************************************************************/
+#ifndef NETCDFFILTERPRIVATE_H
+#define NETCDFFILTERPRIVATE_H
+
+#ifdef HAVE_NETCDF
+#include <netcdf.h>
+#endif
+
+class AbstractDataSource;
+
+class NetCDFFilterPrivate {
+
+	public:
+		explicit NetCDFFilterPrivate(NetCDFFilter*);
+
+		void parse(const QString & fileName, QTreeWidgetItem* rootItem);
+		void read(const QString & fileName, AbstractDataSource* dataSource,
+					AbstractFileFilter::ImportMode importMode = AbstractFileFilter::Replace);
+		//QString readCurrentDataSet(const QString & fileName, AbstractDataSource* \
dataSource, AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace, \
int lines=-1); +		void write(const QString & fileName, AbstractDataSource* \
dataSource); +
+		const NetCDFFilter* q;
+
+		//QString currentDataSet;
+		int startRow;
+		int endRow;
+		int startColumn;
+		int endColumn;
+		bool autoModeEnabled;
+
+	private:
+		//const static int MAXNAMELENGTH=1024;
+		//QList<unsigned long> multiLinkList;	// used to find hard links
+#ifdef HAVE_NETCDF
+		void handleError(int status, QString function);
+		QString translateDataType(nc_type type);
+		void scanAttrs(int ncid, int varid, int nattr, QTreeWidgetItem* parentItem);
+		void scanDims(int ncid, int ndims, QTreeWidgetItem* parentItem);
+		void scanVars(int ncid, int nvars, QTreeWidgetItem* parentItem);
+/*		QString translateHDFOrder(H5T_order_t);
+		QString translateHDFType(hid_t);
+		QString translateHDFClass(H5T_class_t);
+		QStringList readHDFCompound(hid_t tid);
+		template <typename T> QStringList readHDFData1D(hid_t dataset, hid_t type, int \
rows, int lines, QVector<double> *dataPointer=NULL); +		QStringList \
readHDFCompoundData1D(hid_t dataset, hid_t tid, int rows, int lines,QVector< \
QVector<double>* >& dataPointer); +		template <typename T> QStringList \
readHDFData2D(hid_t dataset, hid_t ctype, int rows, int cols, int lines, QVector< \
QVector<double>* >& dataPointer); +		QStringList readHDFCompoundData2D(hid_t dataset, \
hid_t tid, int rows, int cols, int lines); +		QStringList readHDFAttr(hid_t aid);
+		QStringList scanHDFAttrs(hid_t oid);
+		QStringList readHDFDataType(hid_t tid);
+		QStringList readHDFPropertyList(hid_t pid);
+		void scanHDFDataType(hid_t tid, char *dataTypeName,  QTreeWidgetItem* parentItem);
+		void scanHDFLink(hid_t gid, char *linkName,  QTreeWidgetItem* parentItem);
+		void scanHDFDataSet(hid_t dsid, char *dataSetName,  QTreeWidgetItem* parentItem);
+		void scanHDFGroup(hid_t gid, char *groupName, QTreeWidgetItem* parentItem);
+*/
+#endif
+};
+
+#endif
diff --git a/src/kdefrontend/datasources/ImportFileWidget.cpp \
b/src/kdefrontend/datasources/ImportFileWidget.cpp index 10e66e6..3e02051 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.cpp
+++ b/src/kdefrontend/datasources/ImportFileWidget.cpp
@@ -33,6 +33,7 @@ Copyright            : (C) 2009-2012 Alexander Semke \
(alexander.semke@web.de)  #include "backend/datasources/filters/AsciiFilter.h"
 #include "backend/datasources/filters/BinaryFilter.h"
 #include "backend/datasources/filters/HDFFilter.h"
+#include "backend/datasources/filters/NetCDFFilter.h"
 #include "backend/datasources/filters/ImageFilter.h"
 
 #include <QInputDialog>
@@ -85,21 +86,30 @@ ImportFileWidget::ImportFileWidget(QWidget* parent) : \
QWidget(parent) {  
 	QWidget* hdfw=new QWidget(0);
 	hdfOptionsWidget.setupUi(hdfw);
-	QStringList headers;
-	headers<<i18n("Name")<<i18n("Link")<<i18n("Type")<<i18n("Properties")<<i18n("Attributes");
                
-	hdfOptionsWidget.twContent->setHeaderLabels(headers);
+	QStringList hdfheaders;
+	hdfheaders<<i18n("Name")<<i18n("Link")<<i18n("Type")<<i18n("Properties")<<i18n("Attributes");
 +	hdfOptionsWidget.twContent->setHeaderLabels(hdfheaders);
 	// link and type column are filled but we don't need to show it
 	hdfOptionsWidget.twContent->hideColumn(1);
 	hdfOptionsWidget.twContent->hideColumn(2);
 	ui.swOptions->insertWidget(FileDataSource::HDF, hdfw);
 
+	QWidget* netcdfw=new QWidget(0);
+	netcdfOptionsWidget.setupUi(netcdfw);
+	QStringList headers;
+	headers<<i18n("Name")<<i18n("Properties")<<i18n("Values");
+	netcdfOptionsWidget.twContent->setHeaderLabels(headers);
+	ui.swOptions->insertWidget(FileDataSource::NETCDF, netcdfw);
+
 	// default filter
 	ui.swOptions->setCurrentIndex(FileDataSource::Ascii);
 	// disable items
-	//ui.cbFileType->setItemData(FileDataSource::Image, 0, Qt::UserRole - 1);
 #ifndef HAVE_HDF5
 	ui.cbFileType->setItemData(FileDataSource::HDF, 0, Qt::UserRole - 1);
 #endif
+#ifndef HAVE_NETCDF
+	ui.cbFileType->setItemData(FileDataSource::NETCDF, 0, Qt::UserRole - 1);
+#endif
 
 	ui.gbOptions->hide();
 
@@ -145,6 +155,8 @@ ImportFileWidget::ImportFileWidget(QWidget* parent) : \
QWidget(parent) {  // HDF data
 	connect( hdfOptionsWidget.twContent, SIGNAL(itemActivated(QTreeWidgetItem*,int)), \
SLOT(hdfTreeWidgetItemSelected(QTreeWidgetItem*,int)) );  
+	// NetCDF data
+
 	//general settings
 	ui.cbFileType->setCurrentIndex(conf.readEntry("Type", 0));
 	ui.kleFileName->setText(conf.readEntry("LastImportedFile", ""));
@@ -184,7 +196,7 @@ ImportFileWidget::~ImportFileWidget() {
 	// image data
 	conf.writeEntry("ImportFormat", imageOptionsWidget.cbImportFormat->currentIndex());
 
-	//HDF data
+	//HDF/NetCDF data
 	// nothing
 }
 
@@ -313,6 +325,23 @@ AbstractFileFilter* ImportFileWidget::currentFileFilter() const{
 		return filter;
 		break;
 	}
+	case FileDataSource::NETCDF: {
+		NetCDFFilter* filter = new NetCDFFilter();
+ 		if ( ui.cbFilter->currentIndex()==0 ){	//"automatic"
+			filter->setAutoModeEnabled(true);
+ 		}else if ( ui.cbFilter->currentIndex()==1 ){ //"custom"
+			filter->setAutoModeEnabled(false);
+		} else {
+// 			filter->setFilterName( ui.cbFilter->currentText() );
+		}
+		filter->setStartRow( ui.sbStartRow->value() );
+		filter->setEndRow( ui.sbEndRow->value() );
+		filter->setStartColumn( ui.sbStartColumn->value() );
+		filter->setEndColumn( ui.sbEndColumn->value() );
+
+		return filter;
+		break;
+	}
 	default: 
 		qDebug()<<"Unknown file type!";	
 	}
@@ -420,6 +449,24 @@ void ImportFileWidget::fileNameChanged(const QString& name) {
 			hdfOptionsWidget.twContent->expandAll();
 			hdfOptionsWidget.twContent->resizeColumnToContents(0);
 			hdfOptionsWidget.twContent->resizeColumnToContents(3);
+		} else if (info.contains(("NetCDF Data Format"))) {
+			debug="detected NetCDF file";
+			ui.cbFileType->setCurrentIndex(FileDataSource::NETCDF);
+
+			// update NetCDF tree widget using current selected file
+			netcdfOptionsWidget.twContent->clear();
+			netcdfOptionsWidget.leDataSet->clear();
+
+			QString fileName = ui.kleFileName->text();
+			QFileInfo fileInfo(fileName);
+			QTreeWidgetItem *rootItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<fileInfo.baseName()); +			NetCDFFilter *filter = (NetCDFFilter \
*)this->currentFileFilter(); +			filter->parse(fileName, rootItem);
+			netcdfOptionsWidget.twContent->insertTopLevelItem(0,rootItem);
+			netcdfOptionsWidget.twContent->expandAll();
+			netcdfOptionsWidget.twContent->resizeColumnToContents(0);
+			netcdfOptionsWidget.twContent->resizeColumnToContents(1);
+			
 		} else {
 			debug="probably BINARY file";
 			ui.cbFileType->setCurrentIndex(FileDataSource::Binary);
@@ -479,7 +526,8 @@ void ImportFileWidget::fileTypeChanged(int fileType) {
 		ui.sbEndColumn->hide();
 		break;
 	}
-	case FileDataSource::HDF: {
+	case FileDataSource::HDF:
+	case FileDataSource::NETCDF: {
 		break;
 	}	
 	case FileDataSource::Image: {
@@ -594,6 +642,11 @@ void ImportFileWidget::refreshPreview(){
 		importedText = filter->readCurrentDataSet(fileName,NULL,AbstractFileFilter::Replace,lines);
  break;
 	}
+	case FileDataSource::NETCDF: {
+		NetCDFFilter *filter = (NetCDFFilter *)this->currentFileFilter();
+		//TODO: importedText = \
filter->readCurrentDataSet(fileName,NULL,AbstractFileFilter::Replace,lines); \
+		break; +	}
 	default:
 		importedText += "Unknown file type";
 	}
diff --git a/src/kdefrontend/datasources/ImportFileWidget.h \
b/src/kdefrontend/datasources/ImportFileWidget.h index 206f7ad..23c7579 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.h
+++ b/src/kdefrontend/datasources/ImportFileWidget.h
@@ -35,6 +35,7 @@
 #include "BinaryOptionsWidget.h"
 #include "HDFOptionsWidget.h"
 #include "ImageOptionsWidget.h"
+#include "NetCDFOptionsWidget.h"
 
 class FileDataSource;
 class AbstractFileFilter;
@@ -59,6 +60,7 @@ private:
 	Ui::BinaryOptionsWidget binaryOptionsWidget;
 	Ui::HDFOptionsWidget hdfOptionsWidget;
 	Ui::ImageOptionsWidget imageOptionsWidget;
+	Ui::NetCDFOptionsWidget netcdfOptionsWidget;
 
 private slots:
 	void fileNameChanged(const QString&);
diff --git a/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp \
b/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp new file mode 100644
index 0000000..11f2dd3
--- /dev/null
+++ b/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+File                 : NetCDFOptionsWidget.cpp
+Project              : LabPlot
+Description          : widget providing options for the import of NetCDF data
+--------------------------------------------------------------------
+Copyright            : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the Free Software           *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
+ *   Boston, MA  02110-1301  USA                                           *
+ *                                                                         *
+ ***************************************************************************/
+#include "NetCDFOptionsWidget.h"
+
+ /*!
+	\class NetCDFOptionsWidget
+	\brief Widget providing options for the import of NetCDF data
+
+	\ingroup kdefrontend
+ */
+
+NetCDFOptionsWidget::NetCDFOptionsWidget(QWidget* parent) : QWidget(parent) {
+	ui.setupUi(this);
+}
+
+NetCDFOptionsWidget::~NetCDFOptionsWidget() {
+}
diff --git a/src/kdefrontend/datasources/NetCDFOptionsWidget.h \
b/src/kdefrontend/datasources/NetCDFOptionsWidget.h new file mode 100644
index 0000000..5642e68
--- /dev/null
+++ b/src/kdefrontend/datasources/NetCDFOptionsWidget.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+File                 : NetCDFOptionsWidget.h
+Project              : LabPlot
+Description          : widget providing options for the import of NetCDF data
+--------------------------------------------------------------------
+Copyright            : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+
+**************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the Free Software           *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
+ *   Boston, MA  02110-1301  USA                                           *
+ *                                                                         *
+ ***************************************************************************/
+#ifndef NETCDFOPTIONSWIDGET_H
+#define NETCDFOPTIONSWIDGET_H
+
+#include "ui_netcdfoptionswidget.h"
+
+
+class NetCDFOptionsWidget : public QWidget{
+    Q_OBJECT
+
+public:
+	explicit NetCDFOptionsWidget(QWidget*);
+	~NetCDFOptionsWidget();
+
+private:
+	Ui::NetCDFOptionsWidget ui;
+};
+
+#endif
diff --git a/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui \
b/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui new file mode 100644
index 0000000..157abef
--- /dev/null
+++ b/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NetCDFOptionsWidget</class>
+ <widget class="QWidget" name="NetCDFOptionsWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>613</width>
+    <height>505</height>
+   </rect>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="lDataSet">
+       <property name="text">
+        <string>Data set:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="leDataSet">
+       <property name="toolTip">
+        <string>Selected data set</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <widget class="QTreeWidget" name="twContent">
+     <property name="toolTip">
+      <string>Shows the content of a NetCDF file</string>
+     </property>
+     <column>
+      <property name="text">
+       <string notr="true">1</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic