[packages/bes] - started update to 3.17.0 - removed obsolete missing,gdal patches - sed calls on bes.conf replaced
qboosh
qboosh at pld-linux.org
Sun Mar 27 22:45:55 CEST 2016
commit 63c689277f5aa37d6336c2b2d973b0c18f383d8d
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date: Sun Mar 27 22:45:49 2016 +0200
- started update to 3.17.0
- removed obsolete missing,gdal patches
- sed calls on bes.conf replaced by conf patch
- added configure,link patches
- release 0.1 (still WIP, just saving current state; todo: subpackages for modules merged into bes)
bes-conf.patch | 46 +
bes-configure.patch | 43 +
bes-gdal.patch | 21 -
bes-link.patch | 13 +
bes-missing.patch | 13309 --------------------------------------------------
bes.spec | 188 +-
6 files changed, 265 insertions(+), 13355 deletions(-)
---
diff --git a/bes.spec b/bes.spec
index c1469f8..3063ac4 100644
--- a/bes.spec
+++ b/bes.spec
@@ -1,27 +1,37 @@
Summary: OPeNDAP Back End Server software framework
Summary(pl.UTF-8): Szkielet OPeNDAP Back End Server (serwera backendu OPeNDAP)
Name: bes
-Version: 3.13.2
-Release: 2
+Version: 3.17.0
+Release: 0.1
License: LGPL v2.1+
Group: Libraries
Source0: http://www.opendap.org/pub/source/%{name}-%{version}.tar.gz
-# Source0-md5: bef8f57a6c0be8798b8dd09462e5526e
-Patch0: %{name}-missing.patch
-Patch1: %{name}-gdal.patch
+# Source0-md5: 4534a887fe752cb30f20a09bda058fd1
+Patch0: %{name}-conf.patch
+Patch1: %{name}-configure.patch
+Patch2: %{name}-link.patch
URL: http://opendap.org/
-BuildRequires: autoconf >= 2.61
+BuildRequires: autoconf >= 2.63
BuildRequires: automake >= 1:1.10
BuildRequires: bison
BuildRequires: bzip2-devel
%{?with_tests:BuildRequires: cppunit-devel >= 1.12.0}
+BuildRequires: cfitsio-devel
BuildRequires: gdal-devel >= 1.10.0
-BuildRequires: libdap-devel >= 3.12.0
+BuildRequires: gridfields-devel >= 1.0.5
+BuildRequires: hdf-devel >= 4
+BuildRequires: hdf-eos-devel >= 2
+BuildRequires: hdf5-devel
+BuildRequires: libdap-devel >= 3.17.0
+BuildRequires: libicu-devel >= 3.6
BuildRequires: libstdc++-devel
BuildRequires: libtool >= 2:1.5
BuildRequires: libwrap-devel
+BuildRequires: libuuid-devel
BuildRequires: libxml2-devel >= 1:2.6.16
+BuildRequires: openjpeg2-devel >= 2
BuildRequires: openssl-devel
+BuildRequires: perl-base
BuildRequires: pkgconfig
BuildRequires: readline-devel
BuildRequires: sed >= 4.0
@@ -65,7 +75,7 @@ dodawania mechanizmów raportujących, uchwytów inicjujących itd.
Summary: Shared OPeNDAP Back End Server libraries
Summary(pl.UTF-8): Biblioteki współdzielone serwera backendu OPeNDAP
Group: Libraries
-Requires: libdap >= 3.12.0
+Requires: libdap >= 3.17.0
%description libs
Shared OPeNDAP Back End Server libraries.
@@ -105,20 +115,7 @@ Statyczne biblioteki serwera backendu OPeNDAP.
%setup -q
%patch0 -p1
%patch1 -p1
-
-%{__sed} -i \
- -e 's:=/tmp:=/var/cache/bes:' \
- -e 's:=.*/bes\.log:=/var/log/bes/bes.log:' \
- -e 's:=.*/lib/bes:=%{_libdir}/bes:' \
- -e 's:=.*/share/bes:=%{_datadir}/bes:' \
- -e 's:=.*/share/hyrax:=%{_datadir}/hyrax:' \
- -e 's:=/full/path/to/serverside/certificate/file.pem:=/etc/pki/bes/cacerts/file.pem:' \
- -e 's:=/full/path/to/serverside/key/file.pem:=/etc/pki/bes/public/file.pem:' \
- -e 's:=/full/path/to/clientside/certificate/file.pem:=/etc/pki/bes/cacerts/file.pem:' \
- -e 's:=/full/path/to/clientside/key/file.pem:=/etc/pki/bes/public/file.pem:' \
- -e 's:=user_name:=bes:' \
- -e 's:=group_name:=bes:' \
- dispatch/bes/bes.conf
+%patch2 -p1
%build
%{__libtoolize}
@@ -127,6 +124,8 @@ Statyczne biblioteki serwera backendu OPeNDAP.
%{__autoheader}
%{__automake}
%configure \
+ CURL=/usr/bin/curl \
+ --with-hdfeos2="" \
--with-libwrap
%{__make}
@@ -134,15 +133,13 @@ Statyczne biblioteki serwera backendu OPeNDAP.
%install
rm -rf $RPM_BUILD_ROOT
-install -d $RPM_BUILD_ROOT{/etc/rc.d/init.d,/etc/pki/bes/{cacerts,public}} \
+install -d $RPM_BUILD_ROOT/etc/pki/bes/{cacerts,certs,public} \
$RPM_BUILD_ROOT{/var/cache/bes,/var/log/bes} \
$RPM_BUILD_ROOT%{_datadir}/hyrax/data
%{__make} -j1 install \
DESTDIR=$RPM_BUILD_ROOT
-%{__mv} $RPM_BUILD_ROOT%{_bindir}/besd $RPM_BUILD_ROOT/etc/rc.d/init.d
-
%{__rm} $RPM_BUILD_ROOT%{_libdir}/bes/*.{la,a}
# obsoleted by pkg-config
%{__rm} $RPM_BUILD_ROOT%{_libdir}/libbes*.la
@@ -181,6 +178,7 @@ fi
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/functions.conf
%dir /etc/pki/bes
%dir /etc/pki/bes/cacerts
+%dir /etc/pki/bes/certs
%dir /etc/pki/bes/public
%attr(754,root,root) /etc/rc.d/init.d/besd
%dir %{_datadir}/hyrax
@@ -190,6 +188,146 @@ fi
%attr(775,bes,bes) %dir /var/run/bes
%{systemdtmpfilesdir}/bes.conf
+# [opendap-csv_handler]
+#%doc modules/csv_handler/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/csv.conf
+%attr(755,root,root) %{_libdir}/bes/libcsv_module.so
+%dir %{_datadir}/hyrax/data/csv
+%{_datadir}/hyrax/data/csv/temperature.csv
+
+# [opendap-fileout_gdal]
+#%doc modules/fileout_gdal/{ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/fong.conf
+%attr(755,root,root) %{_libdir}/bes/libfong_module.so
+
+# [opendap-fileout_netcdf]
+#%doc modules/fileout_netcdf/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/fonc.conf
+%attr(755,root,root) %{_libdir}/bes/libfonc_module.so
+
+# [opendap-fits_handler]
+#%doc modules/fits_handler/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/fits.conf
+%attr(755,root,root) %{_libdir}/bes/libfits_module.so
+%dir %{_datadir}/hyrax/data/fits
+%{_datadir}/hyrax/data/fits/*.fts
+
+# [opendap-freeform_handler]
+#%doc modules/freeform_handler/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/ff.conf
+%attr(755,root,root) %{_libdir}/bes/libff_module.so
+%dir %{_datadir}/hyrax/data/ff
+%{_datadir}/hyrax/data/ff/*.dat
+%{_datadir}/hyrax/data/ff/*.dat.das
+%{_datadir}/hyrax/data/ff/*.fmt
+
+# [opendap-gateway_module]
+#%doc modules/gateway_module/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/gateway.conf
+%attr(755,root,root) %{_libdir}/bes/libgateway_module.so
+
+# [opendap-gdal_handler]
+#%doc modules/gdal_handler/{ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/gdal.conf
+%attr(755,root,root) %{_libdir}/bes/libgdal_module.so
+%dir %{_datadir}/hyrax/data/gdal
+%{_datadir}/hyrax/data/gdal/*.wind.grb.bz2
+%{_datadir}/hyrax/data/gdal/*.jp2
+%{_datadir}/hyrax/data/gdal/*.jpg
+%{_datadir}/hyrax/data/gdal/*.lgo
+%{_datadir}/hyrax/data/gdal/*.tif
+%{_datadir}/hyrax/data/gdal/*.txt
+%{_datadir}/hyrax/data/gdal/*.TIF
+%doc %{_datadir}/hyrax/data/gdal/README
+
+# [opendap-hdf4_handler]
+#%doc modules/hdf4_handler/{COPYRIGHT_URI,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/h4.conf
+%attr(755,root,root) %{_libdir}/bes/libhdf4_module.so
+%dir %{_datadir}/hyrax/data/hdf4
+%{_datadir}/hyrax/data/hdf4/*.HDF.gz
+%{_datadir}/hyrax/data/hdf4/*.hdf.gz
+%{_datadir}/hyrax/data/hdf4/grid_1_2d.hdf
+
+# [opendap-hdf5_handler]
+#%doc modules/hdf5_handler/{ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/h5.conf
+%attr(755,root,root) %{_libdir}/bes/libhdf5_module.so
+%dir %{_datadir}/hyrax/data/hdf5
+%{_datadir}/hyrax/data/hdf5/grid_1_2d.h5
+
+# [opendap-ncml_module]
+#%doc modules/ncml_module/{COPYRIGHT,ChangeLog,NEWS,README}
+%attr(755,root,root) %{_libdir}/bes/libncml_module.so
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/ncml.conf
+#XXX %dir %{_datadir}/hyrax/data/nc
+%{_datadir}/hyrax/data/nc/jan.nc
+%{_datadir}/hyrax/data/nc/feb.nc
+%dir %{_datadir}/hyrax/data/ncml
+%{_datadir}/hyrax/data/ncml/fnoc1.nc
+%{_datadir}/hyrax/data/ncml/*.ncml
+%dir %{_datadir}/hyrax/data/ncml/agg
+%{_datadir}/hyrax/data/ncml/agg/*.ncml
+%dir %{_datadir}/hyrax/data/ncml/agg/dated
+%{_datadir}/hyrax/data/ncml/agg/dated/*.nc
+%dir %{_datadir}/hyrax/data/ncml/agg/grids
+%{_datadir}/hyrax/data/ncml/agg/grids/*.hdf
+
+# [opendap-netcdf_handler]
+#%doc modules/netcdf_handler/{COPYRIGHT,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/nc.conf
+%attr(755,root,root) %{_libdir}/bes/libnc_module.so
+# XXX dir here? (see module_ncml)
+%dir %{_datadir}/hyrax/data/nc
+%{_datadir}/hyrax/data/nc/bears.nc
+%{_datadir}/hyrax/data/nc/bears.nc.das
+%{_datadir}/hyrax/data/nc/coads_climatology.nc
+%{_datadir}/hyrax/data/nc/fnoc1.das
+%{_datadir}/hyrax/data/nc/fnoc1.nc
+%{_datadir}/hyrax/data/nc/fnoc1.nc.html
+%{_datadir}/hyrax/data/nc/zero_length_array.nc
+
+# [opendap-ugrid_functions]
+#%doc modules/ugrid_functions/{ChangeLog,INSTALL,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/ugrid_functions.conf
+%attr(755,root,root) %{_libdir}/bes/libugrid_functions.so
+%dir %{_datadir}/hyrax/data/ugrids
+%{_datadir}/hyrax/data/ugrids/ugrid_test_*.nc
+
+# [opendap-xml_data_handler]
+#%doc modules/xml_data_handler/{ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/xml_data_handler.conf
+%attr(755,root,root) %{_libdir}/bes/libxml_data_module.so
+
+# [dap-server]
+#%doc modules/dap-server/{COPYRIGHT_*,ChangeLog,NEWS,README}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/dap-server.conf
+%attr(755,root,root) %{_libdir}/bes/libascii_module.so
+%attr(755,root,root) %{_libdir}/bes/libusage_module.so
+%attr(755,root,root) %{_libdir}/bes/libwww_module.so
+%{_datadir}/bes/dap-server_help.*
+
+# (fileout_json - new module)
+#%doc modules/fileout_json/{ChangeLog,NEWS}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/fojson.conf
+%attr(755,root,root) %{_libdir}/bes/libfojson_module.so
+
+# (w10n_handler - new module)
+#%doc modules/w10n_handler/{ChangeLog,NEWS}
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/w10n.conf
+%attr(755,root,root) %{_libdir}/bes/libw10n_handler.so
+
+#%doc dapreader/README
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/bes/modules/dapreader.conf
+%dir %{_datadir}/hyrax/data/dapreader
+%{_datadir}/hyrax/data/dapreader/fnoc1.das
+%{_datadir}/hyrax/data/dapreader/fnoc1.data
+%{_datadir}/hyrax/data/dapreader/fnoc1.dds
+%dir %{_datadir}/hyrax/data/dapreader/dap4
+%{_datadir}/hyrax/data/dapreader/dap4/dap4.html
+%{_datadir}/hyrax/data/dapreader/dap4/D4-xml
+%{_datadir}/hyrax/data/dapreader/dap4/dmr-testsuite
+
%files libs
%defattr(644,root,root,755)
%doc NEWS README*
diff --git a/bes-conf.patch b/bes-conf.patch
new file mode 100644
index 0000000..3428919
--- /dev/null
+++ b/bes-conf.patch
@@ -0,0 +1,46 @@
+--- bes-3.17.0/dispatch/bes/bes.conf.in.orig 2016-02-09 18:53:55.761483829 +0100
++++ bes-3.17.0/dispatch/bes/bes.conf.in 2016-03-26 07:13:37.425428037 +0100
+@@ -19,12 +19,12 @@
+ # number sign (#).
+ # For example: BES.User=#172
+
+-BES.User=user_name
+-BES.Group=group_name
++BES.User=bes
++BES.Group=bes
+
+ # Where should the BES keep its log file?
+
+-BES.LogName=@prefix@/var/bes.log
++BES.LogName=/var/log/bes/bes.log
+ BES.LogVerbose=no
+
+ # Set the value of BES.Catalog.catalog.RootDirectory to the root
+@@ -53,7 +53,7 @@
+ # easy to see what's in the cache at any given time, even when it's a
+ # directory like /tmp that's used by many programs.
+
+-BES.UncompressCache.dir=/tmp
++BES.UncompressCache.dir=/var/cache/bes
+ BES.UncompressCache.prefix=uncompress_cache
+ BES.UncompressCache.size=500
+
+@@ -118,12 +118,12 @@
+ BES.ServerSecure=no
+
+ # BES.ServerSecurePort=10003
+-# BES.ServerCertFile=/full/path/to/serverside/certificate/file.pem
+-# BES.ServerCertAuthFile=/full/path/to/serverside/certificate/authority/file.pem
+-# BES.ServerKeyFile=/full/path/to/serverside/key/file.pem
+-# BES.ClientCertFile=/full/path/to/clientside/certificate/file.pem
+-# BES.ClientCertAuthFile=/full/path/to/clientside/certificate/authority/file.pem
+-# BES.ClientKeyFile=/full/path/to/clientside/key/file.pem
++# BES.ServerCertFile=/etc/pki/bes/certs/server.pem
++# BES.ServerCertAuthFile=/etc/pki/bes/cacerts/server.pem
++# BES.ServerKeyFile=/etc/pki/bes/public/server.pem
++# BES.ClientCertFile=/etc/pki/bes/certs/client.pem
++# BES.ClientCertAuthFile=/etc/pki/bes/cacerts/client.pem
++# BES.ClientKeyFile=/etc/pki/bes/public/client.pem
+
+ # Help file locations, for text, html, and xml versions
+
diff --git a/bes-configure.patch b/bes-configure.patch
new file mode 100644
index 0000000..e5f6b6c
--- /dev/null
+++ b/bes-configure.patch
@@ -0,0 +1,43 @@
+--- bes-3.17.0/configure.ac.orig 2016-02-03 19:37:02.308179475 +0100
++++ bes-3.17.0/configure.ac 2016-03-26 09:16:06.978452939 +0100
+@@ -406,7 +406,6 @@
+ [with_openjpeg_prefix=$ac_bes_dependencies_prefix])
+
+ save_LIBS=$LIBS
+-LIBS="-L$with_openjpeg_prefix/lib $LIBS"
+ AC_CHECK_LIB(openjp2, opj_version, [OPENJPEG_FOUND="yes"], [OPENJPEG_FOUND="no"], [-lm])
+ LIBS=$save_LIBS
+
+@@ -457,12 +456,12 @@
+
+
+ ac_cfits_save_LDFLAGS="$LDFLAGS"
+-LDFLAGS="$LDFLAGS -L$CFITS_PATH_LIBDIR"
++AS_IF([test -n "$CFITS_PATH_LIBDIR"],[LDFLAGS="$LDFLAGS -L$CFITS_PATH_LIBDIR"])
+ AC_CHECK_LIB(cfitsio, fits_is_url_absolute,
+
+ [ac_cfits_ok='yes'
+ CFITS_LIBS="-lcfitsio"
+-CFITS_LDFLAGS="-L${CFITS_PATH_LIBDIR}"
++AS_IF([test -n "$CFITS_PATH_LIBDIR"], [CFITS_LDFLAGS="-L${CFITS_PATH_LIBDIR}"], [CFITS_LDFLAGS=""])
+ AC_SUBST([CFITS_LDFLAGS])
+ AC_SUBST([CFITS_LIBS])],
+
+@@ -474,7 +473,7 @@
+ CFITS_CPPFLAGS=
+ ac_cfits_h='no'
+ ac_cfits_save_CPPFLAGS="$CPPFLAGS"
+-CPPFLAGS="$CPPFLAGS -I$CFITS_PATH_INC"
++AS_IF([test -n "$CFITS_PATH_INC"], [CPPFLAGS="$CPPFLAGS -I$CFITS_PATH_INC"])
+ AC_CHECK_HEADERS([fitsio.h],
+ [ac_cfits_h='yes'],
+ [ac_cfits_h='no']
+@@ -482,7 +481,7 @@
+ CPPFLAGS=$ac_cfits_save_CPPFLAGS
+
+ AS_IF([test "$ac_cfits_h" = 'yes' ],
+- [CFITS_CPPFLAGS="-I$CFITS_PATH_INC"]
++ [AS_IF([test -n "$CFITS_PATH_INC"], [CFITS_CPPFLAGS="-I$CFITS_PATH_INC"], [CFITS_CPPFLAGS=""])]
+ )
+ AC_SUBST([CFITS_CPPFLAGS])
+
diff --git a/bes-gdal.patch b/bes-gdal.patch
deleted file mode 100644
index 0160393..0000000
--- a/bes-gdal.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- bes-3.12.0/conf/ax_lib_gdal.m4.orig 2013-09-12 00:22:22.000000000 +0200
-+++ bes-3.12.0/conf/ax_lib_gdal.m4 2014-03-03 15:25:45.416954681 +0100
-@@ -83,7 +83,7 @@
- dnl
-
- gdal_version_req=ifelse([$1], [], [], [$1])
-- if test "$found_gdal" = "yes" -a -n "$gdal_version_req"; then
-+ if test "$found_gdal" != "no" -a -n "$gdal_version_req"; then
-
- AC_MSG_CHECKING([if GDAL version is >= $gdal_version_req])
-
---- bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp.orig 2014-03-03 15:50:13.366893077 +0100
-+++ bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp 2014-03-03 16:41:14.653431275 +0100
-@@ -33,7 +33,6 @@
- #include "Grid.h"
- #include "Float64.h"
-
--#include "ce_functions.h"
- #include "util.h"
- #include "debug.h"
-
diff --git a/bes-link.patch b/bes-link.patch
new file mode 100644
index 0000000..1a1d461
--- /dev/null
+++ b/bes-link.patch
@@ -0,0 +1,13 @@
+--- bes-3.17.0/xmlcommand/Makefile.am.orig 2015-04-05 05:21:13.799709287 +0200
++++ bes-3.17.0/xmlcommand/Makefile.am 2016-03-26 11:56:07.188050055 +0100
+@@ -27,9 +27,7 @@
+
+ libbes_xml_command_la_SOURCES = $(SRCS) $(HDRS)
+ libbes_xml_command_la_LDFLAGS = -version-info $(LIBXMLCOMMAND_VERSION)
+-libbes_xml_command_la_LIBADD =
+-
+-# ../dispatch/libbes_dispatch.la $(XML2_LIBS)
++libbes_xml_command_la_LIBADD = ../dispatch/libbes_dispatch.la $(XML2_LIBS)
+
+ libdap_xml_module_la_SOURCES = $(DAP_SRCS) $(DAP_HDRS)
+ libdap_xml_module_la_LDFLAGS = -avoid-version -module
diff --git a/bes-missing.patch b/bes-missing.patch
deleted file mode 100644
index 74aa6b3..0000000
--- a/bes-missing.patch
+++ /dev/null
@@ -1,13309 +0,0 @@
-diff -Nur bes-3.12.0/functions.orig/swath2grid/AbstractDataset.cpp bes-3.12.0/functions/swath2grid/AbstractDataset.cpp
---- bes-3.12.0/functions.orig/swath2grid/AbstractDataset.cpp 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/AbstractDataset.cpp 2014-03-03 15:47:38.046899595 +0100
-@@ -0,0 +1,1238 @@
-+/******************************************************************************
-+ * $Id: AbstractDataset.cpp 2011-07-19 16:24:00Z $
-+ *
-+ * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
-+ * for Earth Observation: Open Source Reference Implementation
-+ * Purpose: AbstractDataset implementation for providing an abstract data
-+ * model for multiple data source.
-+ * Author: Yuanzheng Shao, yshao3 at gmu.edu
-+ *
-+ ******************************************************************************
-+ * Copyright (c) 2011, Liping Di <ldi at gmu.edu>, Yuanzheng Shao <yshao3 at gmu.edu>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ ****************************************************************************/
-+
-+#include "AbstractDataset.h"
-+
-+/************************************************************************/
-+/* ==================================================================== */
-+/* AbstractDataset */
-+/* ==================================================================== */
-+/************************************************************************/
-+
-+/**
-+ * \class AbstractDataset "AbstractDataset.h"
-+ *
-+ * An abstract dataset encapsulating one or more raster bands, which is
-+ * based on GDALDataset, and add the support to metadata model: ISO 19115
-+ * and 1SO 19115 (2). A series of Fetch functions are provided for the
-+ * implementation of Web Coverage Service.
-+ *
-+ * Use WCSTCreateDataset() to create a AbstractDataset for a named coverage
-+ * identifier and band list.
-+ */
-+
-+/************************************************************************/
-+/* AbstractDataset() */
-+/************************************************************************/
-+AbstractDataset::AbstractDataset()
-+{
-+}
-+
-+/************************************************************************/
-+/* AbstractDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Constructor of an AbstractDataset.
-+ *
-+ * This is the accepted method of opening an abstract dataset and allocating
-+ * all resources associated with it.
-+ */
-+
-+AbstractDataset::AbstractDataset(const string& id, vector<int> &rBandList) :
-+ ms_CoverageID(id), mv_BandList(rBandList)
-+{
-+}
-+
-+/************************************************************************/
-+/* ~AbstractDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Destroy an open AbstractDataset object.
-+ *
-+ * This is the accepted method of closing a AbstractDataset dataset and
-+ * deallocating all resources associated with it.
-+ */
-+
-+AbstractDataset::~AbstractDataset()
-+{
-+ if (maptr_DS.get())
-+ GDALClose(maptr_DS.release());
-+}
-+
-+/************************************************************************/
-+/* InitialDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Initialize the data set.
-+ *
-+ * This is the virtual function for initializing abstract dataste. The
-+ * subclasses of AbstarctDataset will call SetNativeCRS(), SetGeoTransform()
-+ * and SetGDALDataset() to initialize an abstarct dataset.
-+ *
-+ * @param isSimple The WCS request type. When user executing a DescribeCoverage
-+ * request, isSimple is set to 1, and for GetCoverage, is set to 0.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr AbstractDataset::InitialDataset(const int isSimple)
-+{
-+ return CE_Failure;
-+}
-+
-+/************************************************************************/
-+/* GetGDALDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the GDALDataset object from AbstarctDataset.
-+ *
-+ * An AbstarctDataset encapsulating one GDALDataset. GetGDALDataset()
-+ * returns a GDALDatset object, which is used to fetch its information
-+ * through GDAL APIs.
-+ *
-+ * @return GDALDatset object.
-+ */
-+
-+GDALDataset* AbstractDataset::GetGDALDataset()
-+{
-+ return maptr_DS.get();
-+}
-+
-+/************************************************************************/
-+/* SetGDALDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the GDALDataset object to AbstarctDataset.
-+ *
-+ * This is the virtual function for setting the abstract dataset by
-+ * calling GDAL functions.
-+ *
-+ * @param isSimple the WCS request type. When user executing a DescribeCoverage
-+ * request, isSimple is set to 1, and for GetCoverage, is set to 0.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr AbstractDataset::SetGDALDataset(const int isSimple)
-+{
-+ return CE_Failure;
-+}
-+
-+/************************************************************************/
-+/* GetNativeCRS() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the Native CRS of an AbstarctDataset.
-+ *
-+ * The method will return the CRS obejct, which is an OGRSpatialReference
-+ * object.
-+ *
-+ * @return an OGRSpatialReference object corresponding the native CRS of
-+ * coverage.
-+ */
-+
-+const OGRSpatialReference& AbstractDataset::GetNativeCRS()
-+{
-+ return mo_NativeCRS;
-+}
-+
-+/************************************************************************/
-+/* SetNativeCRS() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the Native CRS for an AbstarctDataset.
-+ *
-+ * The method will set the CRS for an AbstractDataset as an native CRS. For
-+ * some served coverage, GDAL could not tell its native CRS, this method
-+ * should be called to set its native CRS.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr AbstractDataset::SetNativeCRS()
-+{
-+ char* wktStr = (char*) maptr_DS->GetProjectionRef();
-+
-+ if (wktStr && OGRERR_NONE == mo_NativeCRS.importFromWkt(&wktStr))
-+ return CE_None;
-+
-+ return CE_Failure;
-+}
-+
-+/************************************************************************/
-+/* SetGeoTransform() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the affine GeoTransform matrix for a coverage.
-+ *
-+ * The method will set a GeoTransform matrix for a coverage. The method
-+ * GetGeoTransform of GDAL library will be called to get the matrix.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr AbstractDataset::SetGeoTransform()
-+{
-+ if (CE_None != maptr_DS->GetGeoTransform(md_Geotransform))
-+ return CE_Failure;
-+
-+ //Is the returned matrix correct? check the resolution values;
-+ if(md_Geotransform[2] == 0 && md_Geotransform[5] == 0)
-+ return CE_Failure;
-+
-+ mb_GeoTransformSet = TRUE;
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* GetGeoTransform() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the affine transformation coefficients.
-+ *
-+ * Fetches the coefficients for transforming between pixel/line (P,L) raster
-+ * space, and projection coordinates (Xp,Yp) space.
-+ *
-+ * \code
-+ * Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
-+ * Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
-+ * \endcode
-+ *
-+ * In a north up image, padfTransform[1] is the pixel width, and
-+ * padfTransform[5] is the pixel height. The upper left corner of the
-+ * upper left pixel is at position (padfTransform[0],padfTransform[3]).
-+ *
-+ * The default transform is (0,1,0,0,0,1) and should be returned even when
-+ * a CE_Failure error is returned, such as for formats that don't support
-+ * transformation to projection coordinates.
-+ *
-+ * NOTE: GetGeoTransform() isn't expressive enough to handle the variety of
-+ * OGC Grid Coverages pixel/line to projection transformation schemes.
-+ * Eventually this method will be depreciated in favour of a more general
-+ * scheme.
-+ *
-+ * @param geoTrans an existing six double buffer into which the
-+ * transformation will be placed.
-+ *
-+ * @return TRUE on success or FALSE on failure.
-+ */
-+
-+int AbstractDataset::GetGeoTransform(double geoTrans[])
-+{
-+ if (!mb_GeoTransformSet)//Geo-Transform not setup in each data driver, then set default.
-+ {
-+ geoTrans[0]=0.0;
-+ geoTrans[0]=1.0;
-+ geoTrans[0]=0.0;
-+ geoTrans[0]=0.0;
-+ geoTrans[0]=0.0;
-+ geoTrans[0]=1.0;
-+ return FALSE;
-+ }
-+
-+ memcpy(geoTrans, md_Geotransform, sizeof(double) * 6);
-+
-+ return TRUE;
-+}
-+
-+/************************************************************************/
-+/* GetCoverageID() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the identifier of a coverage.
-+ *
-+ * The method will return the coverage identifier related to the abstarct
-+ * dataset. As to TRMM data, the coverage identifier likes:
-+ * TRMM:/Volumes/RAIDL1/GeoData/TRMM/TRMM_3B42_daily.2000.hdf:Daily
-+ *
-+ * As to MODIS data, the coverage identifier likes:
-+ * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MOD15A2/2007/MYD15A2.A2007241.h12v09.005.2007256053902.hdf":MOD_Grid_MOD15A2:Lai_1km
-+ *
-+ * @return the string of coverage identifier.
-+ */
-+
-+string AbstractDataset::GetCoverageID()
-+{
-+ return ms_CoverageID;
-+}
-+
-+/************************************************************************/
-+/* GetResourceFileName() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the resource file name of a coverage.
-+ *
-+ * The method will return the full path corresponding the file contained
-+ * coverage.
-+ *
-+ * @return the string of resource file path.
-+ */
-+
-+string AbstractDataset::GetResourceFileName()
-+{
-+ return ms_SrcFilename;
-+}
-+
-+/************************************************************************/
-+/* GetDatasetName() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the dataset name of a coverage.
-+ *
-+ * The method will return the data set name corresponding the file contained
-+ * coverage. For example, MOD09GQ data has the coverage identifier as following;
-+ * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
-+ *
-+ * sur_refl_b01_1 is seemed as the dataset name.
-+ *
-+ * @return the string of dataset name.
-+ */
-+
-+string AbstractDataset::GetDatasetName()
-+{
-+ return ms_DatasetName;
-+}
-+
-+/************************************************************************/
-+/* GetDataTypeName() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the dataset type name of a coverage.
-+ *
-+ * The method will return the data set name corresponding the file contained
-+ * coverage. For example, MOD09GQ data has the coverage identifier as following;
-+ * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
-+ *
-+ * MODIS_Grid_2D is seemed as the dataset type name.
-+ *
-+ * @return the string of dataset type name.
-+ */
-+
-+string AbstractDataset::GetDataTypeName()
-+{
-+ return ms_DataTypeName;
-+}
-+
-+/************************************************************************/
-+/* GetDataTypeName() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the dataset description of a coverage.
-+ *
-+ * The method will build a description for the coverage. The coverage
-+ * extent, dataset name, dataset type name will be contained in the
-+ * description,
-+ *
-+ * @return the string of dataset description.
-+ */
-+
-+string AbstractDataset::GetDatasetDescription()
-+{
-+ //[15x2030x1354] Band JPEG2000 (16-bit unsigned integer)
-+ string rtnBuf;
-+ int aiDimSizes[3];
-+ int nBandCount = maptr_DS->GetRasterCount();
-+ string pszString;
-+ if (nBandCount > 1)
-+ {
-+ aiDimSizes[0] = nBandCount;
-+ aiDimSizes[1] = GetImageYSize();
-+ aiDimSizes[2] = GetImageXSize();
-+ pszString = SPrintArray(GDT_UInt32, aiDimSizes, 3, "x");
-+ }
-+ else
-+ {
-+ aiDimSizes[0] = GetImageYSize();
-+ aiDimSizes[1] = GetImageXSize();
-+ pszString = SPrintArray(GDT_UInt32, aiDimSizes, 2, "x");
-+ }
-+
-+ rtnBuf = "[" + pszString + "] " + ms_DatasetName + " " + ms_DataTypeName + " (" +
-+ GDALGetDataTypeName(maptr_DS->GetRasterBand(1)->GetRasterDataType()) + ")";
-+
-+ return rtnBuf;
-+}
-+
-+/************************************************************************/
-+/* GetNativeFormat() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the native format of a coverage.
-+ *
-+ * The method will return the native format of a coverage. GDAL API
-+ * GDALGetDriverShortName() will be called to generate the format.
-+ *
-+ * @return the string of dataset native format, in forms of GDAL Formats
-+ * Code. See http://gdal.org/formats_list.html for details.
-+ */
-+
-+string AbstractDataset::GetNativeFormat()
-+{
-+ return ms_NativeFormat;
-+}
-+
-+/************************************************************************/
-+/* IsbGeoTransformSet() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Determine whether set the affine geoTransform for a coverage.
-+ *
-+ * The method will return the status of the affine GeoTransform matrix.
-+ *
-+ * @return TRUE if set already or FALSE on failure..
-+ */
-+
-+int AbstractDataset::IsbGeoTransformSet()
-+{
-+ return mb_GeoTransformSet;
-+}
-+
-+/************************************************************************/
-+/* GetNativeBBox() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the bounding box of a coverage under the native CRS.
-+ *
-+ * The method will fetch the bounding box of the coverage under native CRS.
-+ * The sequence of values stored in array is: xmin, xmax, ymin, ymax
-+ *
-+ * @param bBox an existing four double buffer into which the
-+ * native bounding box values will be placed.
-+ */
-+
-+void AbstractDataset::GetNativeBBox(double bBox[])
-+{
-+ if (mb_GeoTransformSet)
-+ {
-+ bBox[0] = md_Geotransform[0];
-+ bBox[1] = bBox[0] + GetImageXSize() * md_Geotransform[1];
-+ bBox[3] = md_Geotransform[3];
-+ bBox[2] = bBox[3] + GetImageYSize() * md_Geotransform[5];
-+ }
-+ else
-+ {
-+ bBox[0] = 0;
-+ bBox[1] = maptr_DS->GetRasterXSize() - 1;
-+ bBox[2] = 0;
-+ bBox[3] = maptr_DS->GetRasterYSize() - 1;
-+ }
-+}
-+
-+/************************************************************************/
-+/* GetGeoMinMax() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the bounding box of a coverage under EPSG:4326.
-+ *
-+ * The method will fetch the bounding box of the coverage under EPSG:4326
-+ * CRS. The sequence of values stored in array is: xmin, xmax, ymin, ymax
-+ *
-+ * @param bBox an existing four double buffer into which the geographic
-+ * bounding box values will be placed.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr AbstractDataset::GetGeoMinMax(double geoMinMax[])
-+{
-+ if (!mb_GeoTransformSet)
-+ {
-+ SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to get Geo-BoundingBox coordinates");
-+ return CE_Failure;
-+ }
-+
-+ geoMinMax[0] = md_Geotransform[0];
-+ geoMinMax[1] = geoMinMax[0] + GetImageXSize() * md_Geotransform[1];
-+ geoMinMax[3] = md_Geotransform[3];
-+ geoMinMax[2] = geoMinMax[3] + GetImageYSize() * md_Geotransform[5];
-+
-+
-+ if (mo_NativeCRS.IsGeographic() || Find_Compare_SubStr(ms_DataTypeName, "MODIS"))//for modis data
-+ {
-+ geoMinMax[0] = (geoMinMax[0] >= -180.0) ? geoMinMax[0] : -180.0;
-+ geoMinMax[1] = (geoMinMax[1] <= 180.0) ? geoMinMax[1] : 180.0;
-+ geoMinMax[2] = (geoMinMax[2] >= -90.0) ? geoMinMax[2] : -90.0;
-+ geoMinMax[3] = (geoMinMax[3] <= 90.0) ? geoMinMax[3] : 90.0;
-+ return CE_None;
-+ }
-+
-+ OGRSpatialReference oGeoSRS;
-+ oGeoSRS.CopyGeogCSFrom(&mo_NativeCRS);
-+
-+ My2DPoint llPt(geoMinMax[0], geoMinMax[2]);
-+ My2DPoint urPt(geoMinMax[1], geoMinMax[3]);
-+ if (CE_None != bBox_transFormmate(mo_NativeCRS, oGeoSRS, llPt, urPt))
-+ {
-+ SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to transform bounding box coordinates to geographic coordinates.");
-+ return CE_Failure;
-+ }
-+
-+ geoMinMax[0] = llPt.mi_X;
-+ geoMinMax[1] = urPt.mi_X;
-+ geoMinMax[2] = llPt.mi_Y;
-+ geoMinMax[3] = urPt.mi_Y;
-+
-+ return CE_None;
-+}
-+
-+
-+/************************************************************************/
-+/* GetImageXSize() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch coverage width in pixels.
-+ *
-+ * The method will return the width of coverage in pixels. GDAL API
-+ * GetRasterXSize() will be called to generate the width value.
-+ *
-+ * @return the width in pixels of raster bands in this coverage.
-+ */
-+
-+int AbstractDataset::GetImageXSize()
-+{
-+ return maptr_DS->GetRasterXSize();
-+}
-+
-+/************************************************************************/
-+/* GetImageYSize() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch coverage height in pixels.
-+ *
-+ * The method will return the height of coverage in pixels. GDAL API
-+ * GetRasterYSize() will be called to generate the height value.
-+ *
-+ * @return the height in pixels of raster bands in this coverage.
-+ */
-+int AbstractDataset::GetImageYSize()
-+{
-+ return maptr_DS->GetRasterYSize();
-+}
-+
-+/************************************************************************/
-+/* GetCoverageBeginTime() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the begin date/time of a coverage.
-+ *
-+ * The method will return the begin date/time of a coverage. For MODIS data,
-+ * each granule will cover a range of time; for TRMM data, the daily data
-+ * will cover a whole day, and monthly data will cover a whole month.
-+ *
-+ * @return the string of begin date/time corresponding to the coverage.
-+ */
-+
-+string AbstractDataset::GetCoverageBeginTime()
-+{
-+ return ms_CoverageBeginTime;
-+}
-+
-+/************************************************************************/
-+/* GetCoverageBeginTime() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the end date/time of a coverage.
-+ *
-+ * The method will return the end date/time of a coverage. For MODIS data,
-+ * each granule will cover a range of time; for TRMM data, the daily data
-+ * will cover a whole day, and monthly data will cover a whole month.
-+ *
-+ * @return the string of end date/time corresponding to the coverage.
-+ */
-+
-+string AbstractDataset::GetCoverageEndTime()
-+{
-+ return ms_CoverageEndTime;
-+}
-+
-+/************************************************************************/
-+/* getCoverageSubType() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the coverage type.
-+ *
-+ * The method will return the type of the coverage, such as
-+ * "ReferenceableDataset" and "RectifiedDataset".
-+ *
-+ * @return the string of coverage type.
-+ */
-+
-+string AbstractDataset::GetCoverageSubType()
-+{
-+ return ms_CoverageSubType;
-+}
-+
-+/************************************************************************/
-+/* getFieldQuantityDef() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the field units of a coverage.
-+ *
-+ * The method will return the field units of coverage. For example to
-+ * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, units equals
-+ * to reflectance.
-+ *
-+ * @return the string of coverage field units.
-+ */
-+
-+string AbstractDataset::GetFieldQuantityDef()
-+{
-+ return ms_FieldQuantityDef;
-+}
-+
-+/************************************************************************/
-+/* GetAllowValues() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the allow values of a coverage.
-+ *
-+ * The method will return the valid range of a coverage. For example to
-+ * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, valid_range
-+ * equals to (-100, 16000).
-+ *
-+ * @return the string of valid range of a coverage, in the forms of "min, max".
-+ */
-+
-+string AbstractDataset::GetAllowValues()
-+{
-+ return ms_AllowRanges;
-+}
-+
-+/************************************************************************/
-+/* GetISO19115Metadata() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the coverage metadata which is compliant to ISO 19115:2003
-+ * - GeoGraphic information -- Metadata; and ISO 19115(2):2009 - GeoGraphic
-+ * information -- Metadata -- Part 2.
-+ *
-+ * The method will return the metadata of a coverage based on ISO 19115
-+ * and ISO 19115(2).
-+ *
-+ * ISO 19115:2003 defines the schema required for
-+ * describing geographic information and services. It provides information
-+ * about the identification, the extent, the quality, the spatial and temporal
-+ * schema, spatial reference, and distribution of digital geographic data.
-+ *
-+ * ISO 19115-2:2009 extends the existing geographic metadata standard by
-+ * defining the schema required for describing imagery and gridded data.
-+ * It provides information about the properties of the measuring equipment
-+ * used to acquire the data, the geometry of the measuring process employed
-+ * by the equipment, and the production process used to digitize the raw data.
-+ * This extension deals with metadata needed to describe the derivation of
-+ * geographic information from raw data, including the properties of the
-+ * measuring system, and the numerical methods and computational procedures
-+ * used in the derivation. The metadata required to address coverage data in
-+ * general is addressed sufficiently in the general part of ISO 19115.
-+ *
-+ * @return the string of metadata of a coverage.
-+ */
-+
-+string AbstractDataset::GetISO19115Metadata()
-+{
-+ return ms_ISO19115Metadata;
-+}
-+
-+/************************************************************************/
-+/* GetCoverageArchiveTime() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the archive date/time of this dataset.
-+ *
-+ * The method will return the archive date/time of dataset (granule).
-+ *
-+ * @return The string of archive date/time.
-+ */
-+
-+string AbstractDataset::GetCoverageArchiveTime()
-+{
-+ return ms_CoverageArchiveTime;
-+}
-+
-+/************************************************************************/
-+/* GetCoveragePlatform() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the platform name of this dataset.
-+ *
-+ * The method will return the platform name of dataset (granule).
-+ *
-+ * @return The string of platform name.
-+ */
-+
-+string AbstractDataset::GetCoveragePlatform()
-+{
-+ return ms_CoveragePlatform;
-+}
-+
-+/************************************************************************/
-+/* GetCoverageInstrument() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the instrument name of this dataset.
-+ *
-+ * The method will return the instrument name of dataset (granule).
-+ *
-+ * @return The string of instrument name.
-+ */
-+
-+string AbstractDataset::GetCoverageInstrument()
-+{
-+ return ms_CoverageInstrument;
-+}
-+
-+/************************************************************************/
-+/* GetCoverageInstrument() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the sensor name of this dataset.
-+ *
-+ * The method will return the sensor name of dataset (granule).
-+ *
-+ * @return The string of sensor name.
-+ */
-+
-+string AbstractDataset::GetCoverageSensor()
-+{
-+ return ms_CoverageSensor;
-+}
-+
-+/************************************************************************/
-+/* GetImageBandCount() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the number of raster bands on this dataset.
-+ *
-+ * The method will return the number of raster bands on this dataset. GDAL
-+ * API GetRasterCount() will be called to get the count number.
-+ *
-+ * @return the number of raster bands on this dataset.
-+ */
-+
-+int AbstractDataset::GetImageBandCount()
-+{
-+ return maptr_DS->GetRasterCount();
-+}
-+
-+/************************************************************************/
-+/* getMissingValue() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the filled value (missing value) of a coverage.
-+ *
-+ * The method will return the filled value of a coverage.
-+ *
-+ * @return the value of filled value of a coverage.
-+ */
-+
-+const double& AbstractDataset::GetMissingValue()
-+{
-+ return md_MissingValue;
-+}
-+
-+/************************************************************************/
-+/* GetProjectionRef() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the native projection reference of a coverage.
-+ *
-+ * The method will return the the native projection reference of a coverage.
-+ *
-+ * @return the string of the native projection reference of a coverage.
-+ */
-+
-+string AbstractDataset::GetProjectionRef()
-+{
-+ char* pszProjection = NULL;
-+ mo_NativeCRS.exportToWkt(&pszProjection);
-+ string tmpStr = pszProjection;
-+ CPLFree(pszProjection);
-+
-+ return tmpStr;
-+}
-+
-+/************************************************************************/
-+/* SetMetaDataList() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the metadata list for this coverage based on dataset object.
-+ *
-+ * The method will set the metadata list for the coverage based on its
-+ * corresponding GDALDataset object. Will be implemented in the subclasses
-+ * of AbstractDataset.
-+ *
-+ * @param hSrc the GDALDataset object corresponding to coverage.
-+ *
-+ * @return CE_Failure.
-+ */
-+
-+CPLErr AbstractDataset::SetMetaDataList(GDALDataset* hSrc)
-+{
-+ return CE_Failure;
-+}
-+
-+/************************************************************************/
-+/* GetMetaDataList() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the metadata list for this coverage.
-+ *
-+ * The method will return the metadata list for the coverage.
-+ *
-+ * @return the list of metadate.
-+ */
-+
-+vector<string> AbstractDataset::GetMetaDataList()
-+{
-+ return mv_MetaDataList;
-+}
-+
-+/************************************************************************/
-+/* GetBandList() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the contained band list of request coverage.
-+ *
-+ * The method will return the contained band list of request coverage.
-+ *
-+ * @return the band array.
-+ */
-+
-+vector<int> AbstractDataset::GetBandList()
-+{
-+ return mv_BandList;
-+}
-+
-+/************************************************************************/
-+/* getNativeCRS_URN() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the native CRS code of coverage.
-+ *
-+ * The method will return the native CRS code of coverage.
-+ *
-+ * @return the string of the URN for native CRS of coverage.
-+ */
-+
-+string AbstractDataset::GetNativeCRS_URN()
-+{
-+ string urn;
-+
-+ if (mo_NativeCRS.IsProjected())
-+ {
-+ const char* nativeAuthorityName =
-+ mo_NativeCRS.GetAuthorityName("PROJCS");
-+ const char* nativeAuthorityCode =
-+ mo_NativeCRS.GetAuthorityCode("PROJCS");
-+
-+ urn = "urn:ogc:def:crs:";
-+
-+ if (nativeAuthorityName && (EQUAL(nativeAuthorityName,"EPSG")
-+ || EQUAL(nativeAuthorityName,"OGP")
-+ || EQUAL(nativeAuthorityName,"OGC")))
-+ urn += (string) nativeAuthorityName + (string) ":6.3:";
-+ else
-+ urn += "CSISS:0.0:";
-+
-+ if (nativeAuthorityCode)
-+ urn += (string) nativeAuthorityCode;
-+ else
-+ urn += "80000000";
-+ }
-+ else if (mo_NativeCRS.IsGeographic())
-+ {
-+ const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
-+ const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
-+
-+ urn = "urn:ogc:def:crs:";
-+ if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
-+ || EQUAL(geoAuthorityName,"OGP")
-+ || EQUAL(geoAuthorityName,"OGC")))
-+ urn += (string) geoAuthorityName + (string) ":6.3:";
-+ else
-+ urn += "CSISS:0.0:";
-+
-+ if (geoAuthorityCode)
-+ urn += (string) geoAuthorityCode;
-+ else
-+ urn += "70000000";
-+ }
-+ else
-+ urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
-+
-+ return urn;
-+}
-+
-+/************************************************************************/
-+/* GetGeoCRS_URN() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Fetch the Geographic CRS code of coverage.
-+ *
-+ * The method will return the Geographic CRS code of coverage.
-+ *
-+ * @return the URN for Geographic CRS of coverage.
-+ */
-+
-+string AbstractDataset::GetGeoCRS_URN()
-+{
-+ string urn;
-+
-+ if (mo_NativeCRS.IsProjected() || mo_NativeCRS.IsGeographic())
-+ {
-+ const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
-+ const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
-+
-+ urn = "urn:ogc:def:crs:";
-+ if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
-+ || EQUAL(geoAuthorityName,"OGP")
-+ || EQUAL(geoAuthorityName,"OGC")))
-+ urn += (string) geoAuthorityName + (string) ":6.3:";
-+ else
-+ urn += "CSISS:0.0:";
-+
-+ if (geoAuthorityCode)
-+ urn += (string) geoAuthorityCode;
-+ else
-+ urn += "70000000";
-+
-+ }
-+ else
-+ urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
-+
-+ return urn;
-+}
-+
-+/************************************************************************/
-+/* IsCrossingIDL() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Determine whether the extend of coverage cross the International
-+ * Date Line (IDL).
-+ *
-+ * The method will return the status of whether the extend of coverage
-+ * cross the International Date Line (IDL).
-+ *
-+ * @return the TRUE of the coverage extent cross the IDL, otherwise FALSE.
-+ */
-+
-+int AbstractDataset::IsCrossingIDL()
-+{
-+ double bboxArray[4];
-+ GetNativeBBox(bboxArray);
-+
-+ OGRSpatialReference latlonSRS;
-+ latlonSRS.SetWellKnownGeogCS("WGS84");
-+ My2DPoint llPtex(bboxArray[0], bboxArray[2]);
-+ My2DPoint urPtex(bboxArray[1], bboxArray[3]);
-+ bBox_transFormmate(mo_NativeCRS, latlonSRS, llPtex, urPtex);
-+
-+ int bCrossCenter = false;
-+ if(urPtex.mi_X < 0 && llPtex.mi_X > 0)
-+ bCrossCenter = true;
-+
-+ return bCrossCenter;
-+}
-+
-+/************************************************************************/
-+/* GetSuggestedWarpResolution() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the suggested warp option, method 1.
-+ *
-+ * @return CE_Failure if an error occurs, otherwise CE_None.
-+ */
-+
-+CPLErr AbstractDataset::GetSuggestedWarpResolution( OGRSpatialReference& dstCRS,
-+ double adfDstGeoTransform[],
-+ int &nPixels,
-+ int &nLines)
-+{
-+ if (!dstCRS.IsProjected() && !dstCRS.IsGeographic())
-+ {
-+ adfDstGeoTransform[0] = 0;
-+ adfDstGeoTransform[1] = 1;
-+ adfDstGeoTransform[2] = 0;
-+ adfDstGeoTransform[3] = 0;
-+ adfDstGeoTransform[4] = 0;
-+ adfDstGeoTransform[5] = 1;
-+
-+ nPixels = GetImageXSize();
-+ nLines = GetImageYSize();
-+
-+ }
-+ else if (dstCRS.IsSame(&mo_NativeCRS))
-+ {
-+ memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
-+ nPixels = GetImageXSize();
-+ nLines = GetImageYSize();
-+ }
-+ else
-+ {
-+ char *pszDstWKT;
-+ dstCRS.exportToWkt(&pszDstWKT);
-+ char *pszSrcWKT;
-+ mo_NativeCRS.exportToWkt(&pszSrcWKT);
-+
-+ void *hTransformArg = GDALCreateGenImgProjTransformer(maptr_DS.get(),
-+ (const char*) pszSrcWKT, NULL, (const char*) pszDstWKT, TRUE, 1000.0, 0);
-+ OGRFree(pszDstWKT);
-+ OGRFree(pszSrcWKT);
-+ if (hTransformArg == NULL)
-+ {
-+ SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create GDAL GenImgProjTransformer.");
-+
-+ return CE_Failure;
-+ }
-+ /* -------------------------------------------------------------------- */
-+ /* Get approximate output definition. */
-+ /* -------------------------------------------------------------------- */
-+ if (GDALSuggestedWarpOutput(maptr_DS.get(), GDALGenImgProjTransform,
-+ hTransformArg, adfDstGeoTransform, &nPixels, &nLines) != CE_None)
-+ {
-+ SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Computing Output Resolution.");
-+
-+ return CE_Failure;
-+ }
-+
-+ GDALDestroyGenImgProjTransformer(hTransformArg);
-+ }
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* GetSuggestedWarpResolution2() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the suggested warp option, method 2.
-+ *
-+ * @return CE_Failure if an error occurs, otherwise CE_None.
-+ */
-+
-+CPLErr AbstractDataset::GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS,
-+ double adfDstGeoTransform[],
-+ int &nPixels,
-+ int &nLines)
-+{
-+ if (dstCRS.IsLocal())
-+ {
-+ adfDstGeoTransform[0] = 0;
-+ adfDstGeoTransform[1] = 1;
-+ adfDstGeoTransform[2] = 0;
-+ adfDstGeoTransform[3] = 0;
-+ adfDstGeoTransform[4] = 0;
-+ adfDstGeoTransform[5] = 1;
-+
-+ nPixels = GetImageXSize();
-+ nLines = GetImageYSize();
-+ }
-+ else if (dstCRS.IsSame(&mo_NativeCRS))
-+ {
-+ memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
-+ nPixels = GetImageXSize();
-+ nLines = GetImageYSize();
-+ }
-+ else
-+ {
-+ double bboxArray[4];
-+ GetNativeBBox(bboxArray);
-+
-+ My2DPoint llPt(bboxArray[0], bboxArray[2]);
-+ My2DPoint urPt(bboxArray[1], bboxArray[3]);
-+ if (CE_None != bBox_transFormmate(mo_NativeCRS, dstCRS, llPt, urPt))
-+ {
-+ SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution2()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform bounding box Coordinate.");
-+ return CE_Failure;
-+ }
-+
-+ double xRes, yRes;
-+ if(IsCrossingIDL())
-+ {
-+ yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
-+ xRes = fabs((llPt.mi_X - urPt.mi_X) / GetImageXSize());
-+ nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
-+ nPixels = fabs((llPt.mi_X - urPt.mi_X) / xRes + 0.5);
-+ }else
-+ {
-+ xRes = (urPt.mi_X - llPt.mi_X) / GetImageXSize();
-+ yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
-+ nPixels = (urPt.mi_X - llPt.mi_X) / xRes + 0.5;
-+ nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
-+ }
-+
-+ xRes = MIN(xRes,yRes);
-+ yRes = MIN(xRes,yRes);
-+
-+ adfDstGeoTransform[0] = llPt.mi_X;
-+ adfDstGeoTransform[1] = xRes;
-+ adfDstGeoTransform[2] = 0;
-+ adfDstGeoTransform[3] = urPt.mi_Y;
-+ adfDstGeoTransform[4] = 0;
-+ adfDstGeoTransform[5] = -yRes;
-+ }
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* DatasetWarper() */
-+/************************************************************************/
-+
-+/**
-+ * Wrap the dataset to a GDALDataset object based on input parameters.
-+ *
-+ * @return the warpped GDALDataset object.
-+ */
-+/************************************************************************/
-+/* DatasetWarper() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Wrap the dataset to a GDALDataset object based on input parameters.
-+ *
-+ * @return GDALDatset object.
-+ */
-+
-+GDALDataset* AbstractDataset::DatasetWarper(int& IsRefDS,
-+ OGRSpatialReference& dstCRS,
-+ int& iDstRasterXsize,
-+ int& iDstRasterYsize,
-+ double pDstGeoTransform[],
-+ GDALResampleAlg eResampleAlg)
-+{
-+ OGRSpatialReference locCRS=dstCRS;
-+ if (dstCRS.IsLocal())
-+ locCRS=mo_NativeCRS;
-+
-+ if((mo_NativeCRS.IsSame(&locCRS) &&
-+ iDstRasterXsize == maptr_DS->GetRasterXSize() &&
-+ iDstRasterYsize == maptr_DS->GetRasterYSize())&&
-+ CPLIsEqual(md_Geotransform[0],pDstGeoTransform[0])&&
-+ CPLIsEqual(md_Geotransform[1],pDstGeoTransform[1])&&
-+ CPLIsEqual(md_Geotransform[3],pDstGeoTransform[3])&&
-+ CPLIsEqual(md_Geotransform[5],pDstGeoTransform[5]))
-+ {
-+ IsRefDS = TRUE;
-+ return maptr_DS.get();
-+ }
-+
-+ char *sDstCRS_WKT;
-+ locCRS.exportToWkt(&sDstCRS_WKT);
-+
-+ /* Create a memory data-set for re-projection */
-+ GDALDriverH poDriver = GDALGetDriverByName("MEM");
-+
-+ int nBand = maptr_DS->GetRasterCount();
-+ GDALDataset* hMemDS = (GDALDataset*) GDALCreate(poDriver, "", iDstRasterXsize,
-+ iDstRasterYsize, nBand, GDALGetRasterDataType(maptr_DS->GetRasterBand(1)), NULL);
-+ if (NULL == hMemDS)
-+ {
-+ GDALClose(poDriver);
-+ OGRFree(sDstCRS_WKT);
-+ return NULL;
-+ }
-+
-+ hMemDS->SetProjection(sDstCRS_WKT);
-+ hMemDS->SetGeoTransform(pDstGeoTransform);
-+
-+ for (int i = 1; i <= nBand; i++)
-+ {
-+ hMemDS->GetRasterBand(i)->SetNoDataValue(md_MissingValue);
-+ }
-+
-+ /* -------------------------------------------------------------------- */
-+ /* Perform the re-projection. */
-+ /* -------------------------------------------------------------------- */
-+ char *srcWKT;
-+ mo_NativeCRS.exportToWkt(&srcWKT);
-+ if (CE_None != GDALReprojectImage(maptr_DS.get(), srcWKT, hMemDS,
-+ sDstCRS_WKT, eResampleAlg, 0, 0.125, NULL, NULL, NULL))
-+ {
-+ GDALClose(poDriver);
-+ GDALClose(GDALDatasetH(hMemDS));
-+ OGRFree(sDstCRS_WKT);
-+ OGRFree(srcWKT);
-+ return NULL;
-+ }
-+ IsRefDS = FALSE;
-+ OGRFree(sDstCRS_WKT);
-+ OGRFree(srcWKT);
-+
-+ return hMemDS;
-+}
-diff -Nur bes-3.12.0/functions.orig/swath2grid/AbstractDataset.h bes-3.12.0/functions/swath2grid/AbstractDataset.h
---- bes-3.12.0/functions.orig/swath2grid/AbstractDataset.h 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/AbstractDataset.h 2014-03-03 15:47:38.050232928 +0100
-@@ -0,0 +1,150 @@
-+/******************************************************************************
-+ * $Id: AbstractDataset.h 2011-07-19 16:24:00Z $
-+ *
-+ * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
-+ * for Earth Observation: Open Source Reference Implementation
-+ * Purpose: AbstractDataset class definition
-+ * Author: Yuanzheng Shao, yshao3 at gmu.edu
-+ *
-+ ******************************************************************************
-+ * * Copyright (c) 2011, Liping Di <ldi at gmu.edu>, Yuanzheng Shao <yshao3 at gmu.edu>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ ****************************************************************************/
-+
-+#ifndef ABSTRACTDATASET_H_
-+#define ABSTRACTDATASET_H_
-+
-+#include <vector>
-+#include <memory>
-+
-+#include <gdal.h>
-+#include <gdal_priv.h>
-+#include <gdalwarper.h>
-+#include <ogrsf_frmts.h>
-+#include <ogr_spatialref.h>
-+#include <cpl_conv.h>
-+#include <cpl_minixml.h>
-+#include <vrtdataset.h>
-+
-+#include "wcsUtil.h"
-+
-+using namespace std;
-+
-+/* ******************************************************************** */
-+/* AbstractDataset */
-+/* ******************************************************************** */
-+
-+//! Abstract dataset model definition. Based on GDAL dataset model.
-+class AbstractDataset {
-+
-+protected:
-+ auto_ptr<GDALDataset> maptr_DS;
-+
-+ // Coverage Information Related
-+ string ms_CoverageID;
-+ string ms_CoverageBeginTime;
-+ string ms_CoverageEndTime;
-+ string ms_CoverageSubType;
-+ string ms_CoverageArchiveTime;
-+ string ms_CoveragePlatform;
-+ string ms_CoverageInstrument;
-+ string ms_CoverageSensor;
-+ string ms_SrcFilename;
-+ string ms_DatasetName;
-+ string ms_DataTypeName;
-+ string ms_NativeFormat;
-+ string ms_FieldQuantityDef;
-+ string ms_AllowRanges;
-+ string ms_ISO19115Metadata;
-+
-+ vector<int> mv_BandList;
-+ vector<string> mv_MetaDataList;
-+
-+ double md_Geotransform[6];
-+ double md_GeoMinMax[4]; // Order: xmin, xmax, ymin, ymax
-+ double md_MissingValue;
-+
-+ int mb_GeoTransformSet;
-+ int mb_IsVirtualDS;
-+
-+ OGRSpatialReference mo_NativeCRS;
-+
-+protected:
-+ AbstractDataset();
-+ virtual CPLErr SetNativeCRS();
-+ virtual CPLErr SetGeoTransform();
-+ virtual CPLErr SetGDALDataset(const int isSimple = 0);
-+ virtual CPLErr SetMetaDataList(GDALDataset*);
-+
-+public:
-+ AbstractDataset(const string&, vector<int> &);
-+ virtual ~AbstractDataset();
-+
-+ GDALDataset* GetGDALDataset();
-+
-+ // Virtual Functions Definition
-+ virtual CPLErr InitialDataset(const int isSimple = 0);
-+
-+ // Fetch Function Related
-+ const OGRSpatialReference& GetNativeCRS();
-+ const double& GetMissingValue();
-+ int GetGeoTransform(double geoTrans[]);
-+ vector<string> GetMetaDataList();
-+ vector<int> GetBandList();
-+ void GetNativeBBox(double bBox[]);
-+ CPLErr GetGeoMinMax(double geoMinMax[]);
-+
-+ int GetImageBandCount();
-+ int GetImageXSize();
-+ int GetImageYSize();
-+ string GetResourceFileName();
-+ string GetDatasetName();
-+ string GetDataTypeName();
-+ string GetNativeFormat();
-+ string GetCoverageID();
-+ string GetDatasetDescription();
-+ string GetNativeCRS_URN();
-+ string GetGeoCRS_URN();
-+ string GetProjectionRef();
-+ string GetCoverageBeginTime();
-+ string GetCoverageEndTime();
-+ string GetCoverageSubType();
-+ string GetFieldQuantityDef();
-+ string GetAllowValues();
-+ string GetISO19115Metadata();
-+ string GetCoverageArchiveTime();
-+ string GetCoveragePlatform();
-+ string GetCoverageInstrument();
-+ string GetCoverageSensor();
-+
-+ // Fetch Variables Status Related
-+ int IsbGeoTransformSet();
-+ int IsCrossingIDL();
-+
-+ CPLErr GetSuggestedWarpResolution(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
-+ int &nLines);
-+ CPLErr GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
-+ int &nLines);
-+
-+ GDALDataset* DatasetWarper(int& IsRefDS, OGRSpatialReference& dstCRS, int& iDstRasterXsize, int& iDstRasterYsize,
-+ double pDstGeoTransform[], GDALResampleAlg eResampleAlg = GRA_NearestNeighbour);
-+};
-+
-+#endif /*ABSTRACTDATASET_H_*/
-diff -Nur bes-3.12.0/functions.orig/swath2grid/airs.nc.0.data.bescmd bes-3.12.0/functions/swath2grid/airs.nc.0.data.bescmd
---- bes-3.12.0/functions.orig/swath2grid/airs.nc.0.data.bescmd 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/airs.nc.0.data.bescmd 2014-03-03 15:47:38.050232928 +0100
-@@ -0,0 +1,13 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<request reqID ="some_unique_value" >
-+ <setContext name="dap_format">dap2</setContext>
-+ <setContext name="xdap_accept">3.3</setContext>
-+ <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
-+ <define name="d">
-+ <container name="c">
-+ <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
-+ </container>
-+ </define>
-+ <get type="dods" definition="d"/>
-+</request>
-+
-diff -Nur bes-3.12.0/functions.orig/swath2grid/airs.nc.0.ddx.bescmd bes-3.12.0/functions/swath2grid/airs.nc.0.ddx.bescmd
---- bes-3.12.0/functions.orig/swath2grid/airs.nc.0.ddx.bescmd 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/airs.nc.0.ddx.bescmd 2014-03-03 15:47:38.053566262 +0100
-@@ -0,0 +1,13 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<request reqID ="some_unique_value" >
-+ <setContext name="dap_format">dap2</setContext>
-+ <setContext name="xdap_accept">3.3</setContext>
-+ <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
-+ <define name="d">
-+ <container name="c">
-+ <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
-+ </container>
-+ </define>
-+ <get type="das" definition="d"/>
-+</request>
-+
-diff -Nur bes-3.12.0/functions.orig/swath2grid/airs.nc.1.err.bescmd bes-3.12.0/functions/swath2grid/airs.nc.1.err.bescmd
---- bes-3.12.0/functions.orig/swath2grid/airs.nc.1.err.bescmd 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/airs.nc.1.err.bescmd 2014-03-03 15:47:38.043566262 +0100
-@@ -0,0 +1,13 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<request reqID ="some_unique_value" >
-+ <setContext name="dap_format">dap2</setContext>
-+ <setContext name="xdap_accept">3.3</setContext>
-+ <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
-+ <define name="d">
-+ <container name="c">
-+ <constraint>swath2grid()</constraint>
-+ </container>
-+ </define>
-+ <get type="dods" definition="d"/>
-+</request>
-+
-diff -Nur bes-3.12.0/functions.orig/swath2grid/bes.conf.in bes-3.12.0/functions/swath2grid/bes.conf.in
---- bes-3.12.0/functions.orig/swath2grid/bes.conf.in 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/bes.conf.in 2014-03-03 15:47:38.050232928 +0100
-@@ -0,0 +1,48 @@
-+BES.ServerAdministrator=root at null.dev
-+
-+BES.User=user_name
-+BES.Group=group_name
-+
-+BES.LogName=./bes.log
-+BES.LogVerbose=no
-+
-+BES.modules=dap,cmd,nc,h4,fong,fonc
-+BES.module.dap=@libdir@/bes/libdap_module.so
-+BES.module.cmd=@libdir@/bes/libdap_xml_module.so
-+
-+BES.module.nc=@libdir@/bes/libnc_module.so
-+BES.module.h4=@libdir@/bes/libhdf4_module.so
-+
-+BES.module.fong=@libdir@/bes/libfong_module.so
-+BES.module.fonc=@libdir@/bes/libfonc_module.so
-+
-+BES.Catalog.catalog.RootDirectory=@abs_top_srcdir@
-+BES.Data.RootDirectory=/dev/null
-+
-+BES.Catalog.catalog.TypeMatch=nc:.*.nc(.bz2|.gz|.Z)?$;h4:.*.(hdf|HDF|eos)(.bz2|.gz|.Z)?$;
-+
-+BES.Catalog.catalog.Include=;
-+BES.Catalog.catalog.Exclude=^\..*;
-+
-+BES.FollowSymLinks=No
-+BES.Catalog.catalog.FollowSymLinks=No
-+
-+BES.ServerPort=10002
-+
-+BES.CacheDir=/tmp
-+BES.CachePrefix=bes_cache
-+BES.CacheSize=500
-+
-+BES.Container.Persistence=strict
-+
-+BES.Memory.GlobalArea.EmergencyPoolSize=1
-+BES.Memory.GlobalArea.MaximumHeapSize=20
-+BES.Memory.GlobalArea.Verbose=no
-+BES.Memory.GlobalArea.ControlHeap=no
-+
-+BES.ProcessManagerMethod=multiple
-+
-+BES.DefaultResponseMethod=POST
-+
-+FONg.TempDirectory=@abs_top_srcdir@/tests
-+
-diff -Nur bes-3.12.0/functions.orig/swath2grid/BoundingBox.cpp bes-3.12.0/functions/swath2grid/BoundingBox.cpp
---- bes-3.12.0/functions.orig/swath2grid/BoundingBox.cpp 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/BoundingBox.cpp 2014-03-03 15:47:38.050232928 +0100
-@@ -0,0 +1,360 @@
-+/******************************************************************************
-+ * $Id: BoundingBox.cpp 2011-07-19 16:24:00Z $
-+ *
-+ * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
-+ * for Earth Observation: Open Source Reference Implementation
-+ * Purpose: BoundingBox class implementation, enable transform bounding box
-+ * between different CRS
-+ * Author: Yuanzheng Shao, yshao3 at gmu.edu
-+ *
-+ ******************************************************************************
-+ * Copyright (c) 2011, Liping Di <ldi at gmu.edu>, Yuanzheng Shao <yshao3 at gmu.edu>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ ****************************************************************************/
-+
-+#include <vector>
-+#include <iostream>
-+
-+#include "BoundingBox.h"
-+#include "wcs_error.h"
-+
-+using namespace std;
-+
-+My2DPoint::~My2DPoint()
-+{
-+
-+}
-+
-+BoundingBox::BoundingBox()
-+{
-+
-+}
-+
-+BoundingBox::~BoundingBox()
-+{
-+
-+}
-+
-+BoundingBox BoundingBox::TransformWorkExtend(OGRSpatialReference &dstCRS, int &IsOK)
-+{
-+ if (mo_CRS.IsSame(&dstCRS))
-+ {
-+ IsOK = TRUE;
-+ return *this;
-+ }
-+
-+ OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&mo_CRS, &dstCRS);
-+ if (poCT == NULL)
-+ {
-+ IsOK = FALSE;
-+ return *this;
-+ }
-+
-+ double xdes = (mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
-+
-+ if (mo_CRS.IsGeographic()
-+ && mo_UpperRightPT.mi_X < mo_LowerLeftPT.mi_X
-+ && mo_LowerLeftPT.mi_X > 0 && mo_UpperRightPT.mi_X < 0)
-+ {
-+ xdes = (360 + mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
-+ }
-+
-+ vector<double> x;
-+ vector<double> y;
-+ //up and down edge
-+ for (double stepX = mo_LowerLeftPT.mi_X; stepX < mo_UpperRightPT.mi_X; stepX
-+ += xdes)
-+ {
-+ x.push_back(stepX);
-+ y.push_back(mo_UpperRightPT.mi_Y);
-+ x.push_back(stepX);
-+ y.push_back(mo_LowerLeftPT.mi_Y);
-+ }
-+ x.push_back(mo_UpperRightPT.mi_X);
-+ y.push_back(mo_UpperRightPT.mi_Y);
-+ x.push_back(mo_UpperRightPT.mi_X);
-+ y.push_back(mo_LowerLeftPT.mi_Y);
-+
-+ double yMin = numeric_limits<double>::max();
-+ double yMax = numeric_limits<double>::min();
-+
-+ int k = 0;
-+ vector<int> bSuccess;
-+ vector<double> tmpX;
-+ vector<double> tmpY;
-+
-+ for (unsigned int i = 0; i < x.size(); i++)
-+ {
-+ tmpX.push_back(x[i]);
-+ tmpY.push_back(y[i]);
-+ bSuccess.push_back(0);
-+ }
-+
-+ poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
-+
-+ for (unsigned int n = 0; n < x.size(); n++)
-+ {
-+ if (bSuccess[n])
-+ {
-+ ++k;
-+ yMin = MIN(yMin,tmpY[n]);
-+ yMax = MAX(yMax,tmpY[n]);
-+ }
-+ }
-+
-+ if (k < 80)
-+ {
-+ IsOK = FALSE;
-+ OCTDestroyCoordinateTransformation(poCT);
-+ return *this;
-+ }
-+
-+ //find xmin on left edge and xmax on right edge
-+ double xMin;
-+ double xMax;
-+
-+ double tmpPTX[2];
-+ double tmpPTY[2];
-+
-+ int isSucc[2];
-+
-+ tmpPTX[0] = mo_LowerLeftPT.mi_X;
-+ tmpPTX[1] = mo_LowerLeftPT.mi_X;
-+ tmpPTY[0] = mo_LowerLeftPT.mi_Y;
-+ tmpPTY[1] = mo_UpperRightPT.mi_Y;
-+
-+ poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
-+ if (isSucc[0] && isSucc[1])
-+ {
-+ xMin = MIN(tmpPTX[0],tmpPTX[1]);
-+ }
-+ else
-+ {
-+ OCTDestroyCoordinateTransformation(poCT);
-+ IsOK = FALSE;
-+ return *this;
-+ }
-+
-+ tmpPTX[0] = mo_UpperRightPT.mi_X;
-+ tmpPTX[1] = mo_UpperRightPT.mi_X;
-+ tmpPTY[0] = mo_UpperRightPT.mi_Y;
-+ tmpPTY[1] = mo_LowerLeftPT.mi_Y;
-+
-+ poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
-+ if (isSucc[0] && isSucc[1])
-+ {
-+ xMax = MAX(tmpPTX[0],tmpPTX[1]);
-+ }
-+ else
-+ {
-+ OCTDestroyCoordinateTransformation(poCT);
-+ IsOK = FALSE;
-+ return *this;
-+ }
-+
-+ BoundingBox bbox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
-+
-+ if (dstCRS.IsGeographic())
-+ {
-+ if (xMin > 180)
-+ xMin = xMin - 360;
-+ if (xMax > 180)
-+ xMax = xMax - 360;
-+
-+ if (xMin >= 180.)
-+ xMin = 180.;
-+ if (xMin <= -180.)
-+ xMin = -180.;
-+ if (xMax >= 180.)
-+ xMax = 180.;
-+ if (xMax <= -180.)
-+ xMax = -180.;
-+
-+ if (yMin < 0.)
-+ yMin = 0.;
-+ if (yMax > 90.)
-+ yMax = 90.;
-+ }
-+ OCTDestroyCoordinateTransformation(poCT);
-+ IsOK = TRUE;
-+ return BoundingBox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
-+}
-+
-+BoundingBox BoundingBox::Transform(const double GeoTransform[])
-+{
-+ My2DPoint llPt;
-+ My2DPoint urPt;
-+ llPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_LowerLeftPT.mi_X + GeoTransform[2] * mo_LowerLeftPT.mi_Y;
-+ llPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_LowerLeftPT.mi_X + GeoTransform[5] * mo_LowerLeftPT.mi_Y;
-+ urPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_UpperRightPT.mi_X + GeoTransform[2] * mo_UpperRightPT.mi_Y;
-+ urPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_UpperRightPT.mi_X + GeoTransform[5] * mo_UpperRightPT.mi_Y;
-+
-+ return BoundingBox(llPt,urPt,mo_CRS);
-+}
-+
-+/**
-+ * Transform Coordinates of lowercorner_left and upcorner_right
-+ * lowLeft, upRight.
-+ * the return value has considered the case of image area crossing 180/-180 longitude line,
-+ * so lowLeft.x maybe bigger than upRight.x
-+ */
-+CPLErr CPL_STDCALL bBox_transFormmate(OGRSpatialReference& oSrcCRS,
-+ OGRSpatialReference& oDesCRS, My2DPoint& lowLeft, My2DPoint& upRight)
-+{
-+ if (oSrcCRS.IsSame(&oDesCRS))
-+ return CE_None;
-+
-+ OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&oSrcCRS, &oDesCRS);
-+ if (poCT == NULL)
-+ {
-+ SetWCS_ErrorLocator("bBox_transFormmate()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create \"OGRCoordinateTransformation\"");
-+ return CE_Failure;
-+ }
-+
-+ double xdes = (upRight.mi_X - lowLeft.mi_X) / 100;
-+ if (oSrcCRS.IsGeographic() && upRight.mi_X < lowLeft.mi_X && lowLeft.mi_X > 0 && upRight.mi_X < 0)
-+ {
-+ xdes = (360 + upRight.mi_X - lowLeft.mi_X) / 100;
-+ }
-+
-+ vector<double> x, y;
-+ //up and down edge
-+ for (double stepX = lowLeft.mi_X; stepX < upRight.mi_X; stepX += xdes)
-+ {
-+ x.push_back(stepX);
-+ y.push_back(upRight.mi_Y);
-+ x.push_back(stepX);
-+ y.push_back(lowLeft.mi_Y);
-+ }
-+ x.push_back(upRight.mi_X);
-+ y.push_back(upRight.mi_Y);
-+ x.push_back(upRight.mi_X);
-+ y.push_back(lowLeft.mi_Y);
-+
-+ double yMin = numeric_limits<double>::max();
-+ double yMax = -numeric_limits<double>::max();
-+
-+ int k = 0;
-+ vector<int> bSuccess;
-+ vector<double> tmpX;
-+ vector<double> tmpY;
-+
-+ for (unsigned int i = 0; i < x.size(); i++)
-+ {
-+ tmpX.push_back(x[i]);
-+ tmpY.push_back(y[i]);
-+ bSuccess.push_back(0);
-+ }
-+
-+ poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
-+
-+ for (unsigned int n = 0; n < x.size(); n++)
-+ {
-+ if (bSuccess[n])
-+ {
-+ ++k;
-+ yMin = MIN(yMin,tmpY[n]);
-+ yMax = MAX(yMax,tmpY[n]);
-+ }
-+ }
-+
-+ if (k < 80)
-+ {
-+ OCTDestroyCoordinateTransformation(poCT);
-+ SetWCS_ErrorLocator("bBox_transFormmate()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
-+ return CE_Failure;
-+ }
-+
-+ double xMin;
-+ double xMax;
-+
-+ //find xmin on left edge and xmax on right edge
-+ double tmpPTX[2];
-+ double tmpPTY[2];
-+ int isOK[2];
-+
-+ tmpPTX[0] = lowLeft.mi_X;
-+ tmpPTX[1] = lowLeft.mi_X;
-+ tmpPTY[0] = upRight.mi_Y;
-+ tmpPTY[1] = lowLeft.mi_Y;
-+
-+ poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
-+ if (isOK[0] && isOK[1])
-+ {
-+ xMin = MIN(tmpPTX[0],tmpPTX[1]);
-+ }
-+ else
-+ {
-+ OCTDestroyCoordinateTransformation(poCT);
-+ SetWCS_ErrorLocator("bBox_transFormmate()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
-+ return CE_Failure;
-+ }
-+
-+ tmpPTX[0] = upRight.mi_X;
-+ tmpPTX[1] = upRight.mi_X;
-+ tmpPTY[0] = upRight.mi_Y;
-+ tmpPTY[1] = lowLeft.mi_Y;
-+
-+ poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
-+ if (isOK[0] && isOK[1])
-+ {
-+ xMax = MAX(tmpPTX[0],tmpPTX[1]);
-+ }
-+ else
-+ {
-+ SetWCS_ErrorLocator("bBox_transFormmate()");
-+ OCTDestroyCoordinateTransformation(poCT);
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
-+ return CE_Failure;
-+ }
-+
-+ lowLeft.mi_X = xMin;
-+ lowLeft.mi_Y = yMin;
-+ upRight.mi_X = xMax;
-+ upRight.mi_Y = yMax;
-+
-+ if (oDesCRS.IsGeographic())
-+ {
-+ if (xMin > 180)
-+ lowLeft.mi_X = xMin - 360;
-+ if (xMax > 180)
-+ upRight.mi_X = xMax - 360;
-+
-+ if (lowLeft.mi_X >= 180.)
-+ lowLeft.mi_X = 180.;
-+ if (lowLeft.mi_X <= -180.)
-+ lowLeft.mi_X = -180.;
-+ if (upRight.mi_X >= 180.)
-+ upRight.mi_X = 180.;
-+ if (upRight.mi_X <= -180.)
-+ upRight.mi_X = -180.;
-+
-+ if (lowLeft.mi_Y <= -90.)
-+ lowLeft.mi_Y = -90.;
-+ if (upRight.mi_Y >= 90.)
-+ upRight.mi_Y = 90.;
-+ }
-+ OCTDestroyCoordinateTransformation(poCT);
-+
-+ return CE_None;
-+}
-diff -Nur bes-3.12.0/functions.orig/swath2grid/BoundingBox.h bes-3.12.0/functions/swath2grid/BoundingBox.h
---- bes-3.12.0/functions.orig/swath2grid/BoundingBox.h 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/BoundingBox.h 2014-03-03 15:47:38.053566262 +0100
-@@ -0,0 +1,137 @@
-+/******************************************************************************
-+ * $Id: BoundingBox.h 2011-07-19 16:24:00Z $
-+ *
-+ * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
-+ * for Earth Observation: Open Source Reference Implementation
-+ * Purpose: BoundingBox class definition
-+ * Author: Yuanzheng Shao, yshao3 at gmu.edu
-+ *
-+ ******************************************************************************
-+ * Copyright (c) 2011, Liping Di <ldi at gmu.edu>, Yuanzheng Shao <yshao3 at gmu.edu>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ ****************************************************************************/
-+
-+#ifndef BOUNDINGBOX_H_
-+#define BOUNDINGBOX_H_
-+
-+#include <gdal.h>
-+#include <ogr_spatialref.h>
-+#include <limits>
-+#include <stdlib.h>
-+
-+using namespace std;
-+
-+/************************************************************************/
-+/* ==================================================================== */
-+/* My2DPoint */
-+/* ==================================================================== */
-+/************************************************************************/
-+
-+/**
-+ * \class My2DPoint "BoundingBox.h"
-+ *
-+ * My2DPoint class is used to store the point coordinates.
-+ */
-+
-+class My2DPoint
-+{
-+public:
-+ double mi_X;
-+ double mi_Y;
-+
-+ virtual ~My2DPoint();
-+
-+ My2DPoint()
-+ {
-+ mi_X = 0;
-+ mi_Y = 0;
-+ }
-+
-+ My2DPoint(const double& xx, const double& yy) :
-+ mi_X(xx), mi_Y(yy)
-+ {
-+ }
-+
-+ My2DPoint(const My2DPoint& p) :
-+ mi_X(p.mi_X), mi_Y(p.mi_Y)
-+ {
-+ }
-+
-+ My2DPoint& operator =(const My2DPoint& p)
-+ {
-+ mi_X = p.mi_X;
-+ mi_Y = p.mi_Y;
-+ return *this;
-+ }
-+};
-+
-+/************************************************************************/
-+/* ==================================================================== */
-+/* BoundingBox */
-+/* ==================================================================== */
-+/************************************************************************/
-+
-+/**
-+ * \class BoundingBox "BoundingBox.h"
-+ *
-+ * BoundingBox class is used to transform bounding box between different
-+ * Coordinate Reference System.
-+ */
-+
-+class BoundingBox
-+{
-+public:
-+ My2DPoint mo_LowerLeftPT;
-+ My2DPoint mo_UpperRightPT;
-+ OGRSpatialReference mo_CRS;
-+
-+ BoundingBox(const My2DPoint& llpt, const My2DPoint& urpt, OGRSpatialReference& crs) :
-+ mo_LowerLeftPT(llpt), mo_UpperRightPT(urpt), mo_CRS(crs)
-+ {
-+
-+ }
-+
-+ BoundingBox(OGRSpatialReference& crs) :
-+ mo_LowerLeftPT(0,0), mo_UpperRightPT(0,0), mo_CRS(crs)
-+ {
-+
-+ }
-+ BoundingBox& operator =(const BoundingBox& box)
-+ {
-+ mo_LowerLeftPT = box.mo_LowerLeftPT;
-+ mo_UpperRightPT = box.mo_UpperRightPT;
-+ mo_CRS = box.mo_CRS;
-+ return *this;
-+ }
-+
-+ BoundingBox();
-+ virtual ~BoundingBox();
-+
-+ BoundingBox Transform(OGRSpatialReference&, int&);
-+ BoundingBox TransformWorkExtend(OGRSpatialReference&, int&);
-+ BoundingBox Transform(const double*);
-+};
-+
-+CPLErr CPL_DLL CPL_STDCALL bBox_transFormmate( OGRSpatialReference&,
-+ OGRSpatialReference&,
-+ My2DPoint& lowLeft,
-+ My2DPoint& upRight);
-+
-+#endif /* BOUNDINGBOX_H_ */
-diff -Nur bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.cpp bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp
---- bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.cpp 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp 2014-03-03 15:47:38.046899595 +0100
-@@ -0,0 +1,730 @@
-+
-+// -*- mode: c++; c-basic-offset:4 -*-
-+
-+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
-+// Access Protocol.
-+
-+// Copyright (c) 2012 OPeNDAP, Inc.
-+// Author: James Gallagher <jgallagher at opendap.org>
-+//
-+// This library is free software; you can redistribute it and/or
-+// modify it under the terms of the GNU Lesser General Public
-+// License as published by the Free Software Foundation; either
-+// version 2.1 of the License, or (at your option) any later version.
-+//
-+// This library 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
-+// Lesser General Public License for more details.
-+//
-+// You should have received a copy of the GNU Lesser General Public
-+// License along with this library; if not, write to the Free Software
-+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+//
-+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
-+
-+#include <cstdlib>
-+
-+#define DODS_DEBUG
-+
-+#include "DAP_Dataset.h"
-+
-+#include "Array.h"
-+#include "Grid.h"
-+#include "Float64.h"
-+
-+#include "ce_functions.h"
-+#include "util.h"
-+#include "debug.h"
-+
-+using namespace libdap;
-+using namespace std;
-+
-+#if 0
-+#define GOES_TIME_DEBUG FALSE
-+#endif
-+
-+namespace libdap {
-+
-+DAP_Dataset::DAP_Dataset()
-+{
-+}
-+
-+/************************************************************************/
-+/* ~DAP_Dataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Destroy an open DAP_Dataset object.
-+ *
-+ * This is the accepted method of closing a DAP_Dataset dataset and
-+ * deallocating all resources associated with it.
-+ */
-+
-+DAP_Dataset::~DAP_Dataset()
-+{
-+}
-+
-+/************************************************************************/
-+/* DAP_Dataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Create an DAP_Dataset object.
-+ *
-+ * This is the accepted method of creating a DAP_Dataset object and
-+ * allocating all resources associated with it.
-+ *
-+ * @param id The coverage identifier.
-+ *
-+ * @param rBandList The field list selected for this coverage. For TRMM
-+ * daily data, the user could specify multiple days range in request.
-+ * Each day is seemed as one field.
-+ *
-+ * @return A DAP_Dataset object.
-+ */
-+
-+DAP_Dataset::DAP_Dataset(const string& id, vector<int> &rBandList) :
-+ AbstractDataset(id, rBandList)
-+{
-+ md_MissingValue = 0;
-+ mb_GeoTransformSet = FALSE;
-+}
-+
-+/**
-+ * @brief Initialize a DAP Dataset using Array objects already read.
-+ *
-+ *
-+ */
-+
-+DAP_Dataset::DAP_Dataset(Array *src, Array *lat, Array *lon) :
-+ AbstractDataset(), m_src(src), m_lat(lat), m_lon(lon)
-+{
-+#if 1
-+ // TODO Remove these?
-+ DBG(cerr << "Registering GDAL drivers" << endl);
-+ GDALAllRegister();
-+ OGRRegisterAll();
-+#endif
-+
-+ CPLSetErrorHandler(CPLQuietErrorHandler);
-+
-+ // Read this from the 'missing_value' or '_FillValue' attributes
-+ string missing_value = m_src->get_attr_table().get_attr("missing_value");
-+ if (missing_value.empty())
-+ missing_value = m_src->get_attr_table().get_attr("_FillValue");
-+
-+ if (!missing_value.empty())
-+ md_MissingValue = atof(missing_value.c_str());
-+ else
-+ md_MissingValue = 0;
-+
-+ mb_GeoTransformSet = FALSE;
-+}
-+
-+/************************************************************************/
-+/* InitialDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Initialize the GOES dataset with NetCDF format.
-+
-+ * This method is the implementation for initializing a GOES dataset with NetCDF format.
-+ * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
-+ * will be called to initialize an GOES dataset.
-+ *
-+ * @note To use this, call this method and then access the GDALDataset that
-+ * contains the reprojected array using maptr_DS.get().
-+ *
-+ * @param isSimple the WCS request type. When user executing a DescribeCoverage
-+ * request, isSimple is set to 1, and for GetCoverage, is set to 0.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::InitialDataset(const int isSimple)
-+{
-+ DBG(cerr << "In InitialDataset" << endl);
-+
-+ // Might break that operation out so the remap is a separate call
-+ if (CE_None != SetNativeCRS() || CE_None != SetGeoTransform())
-+ throw Error("Could not set the dataset native CRS or the GeoTransform.");
-+
-+ DBG(cerr << "Before SetGDALDataset" << endl);
-+
-+ if (CE_None != SetGDALDataset(isSimple)) {
-+ GDALClose(maptr_DS.release());
-+ throw Error("Could not reproject the dataset.");
-+ }
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* GetDAPArray() */
-+/************************************************************************/
-+
-+/**
-+ * @brief Build a DAP Array from the GDALDataset
-+ */
-+Array *DAP_Dataset::GetDAPArray()
-+{
-+ DBG(cerr << "In GetDAPArray" << endl);
-+ DBG(cerr << "maptr_DS: " << maptr_DS.get() << endl);
-+ DBG(cerr << "raster band count: " << maptr_DS->GetRasterCount() << endl);
-+
-+ // There should be just one band
-+ if (maptr_DS->GetRasterCount() != 1)
-+ throw Error("In function swath2grid(), expected a single raster band.");
-+
-+ // Get the x and y dimensions of the raster band
-+ int x = maptr_DS->GetRasterXSize();
-+ int y = maptr_DS->GetRasterYSize();
-+ GDALRasterBand *rb = maptr_DS->GetRasterBand(1);
-+ if (!rb)
-+ throw Error("In function swath2grid(), could not access the raster data.");
-+
-+ // Since the DAP_Dataset code works with all data values as doubles,
-+ // Assume the raster band has GDAL type GDT_Float64, but test anyway
-+ if (GDT_Float64 != rb->GetRasterDataType())
-+ throw Error("In function swath2grid(), expected raster data to be of type double.");
-+
-+ DBG(cerr << "Destination array will have dimensions: " << x << ", " << y << endl);
-+
-+ Array *a = new Array(m_src->name(), new Float64(m_src->name()));
-+
-+ // Make the result array have two dimensions
-+ Array::Dim_iter i = m_src->dim_begin();
-+
-+ a->append_dim(x, m_src->dimension_name(i));
-+ ++i;
-+
-+ if (i == m_src->dim_end())
-+ throw Error("In function swath2grid(), expected source array to have two dimensions (2).");
-+
-+ a->append_dim(y, m_src->dimension_name(i));
-+
-+ // Poke in the data values
-+ /* RasterIO ( GDALRWFlag eRWFlag,
-+ int nXOff,
-+ int nYOff,
-+ int nXSize,
-+ int nYSize,
-+ void * pData,
-+ int nBufXSize,
-+ int nBufYSize,
-+ GDALDataType eBufType,
-+ int nPixelSpace,
-+ int nLineSpace
-+ ) */
-+ vector<double> data(x * y);
-+ rb->RasterIO(GF_Read, 0, 0, x, y, &data[0], x, y, GDT_Float64, 0, 0);
-+
-+ // NB: set_value() copies into new storage
-+ a->set_value(data, data.size());
-+
-+ // Now poke in some attributes
-+ // TODO Make these CF attributes
-+ string projection_info = maptr_DS->GetProjectionRef();
-+ string gcp_projection_info = maptr_DS->GetGCPProjection();
-+
-+ // This sets the instance variable that holds the geotransform coefs. These
-+ // are needed by the GetDAPGrid() method.
-+ if (CE_None != maptr_DS->GetGeoTransform (m_geo_transform_coef))
-+ throw Error("In function swath2grid(), could not access the geo transform data.");
-+
-+ DBG(cerr << "projection_info: " << projection_info << endl);
-+ DBG(cerr << "gcp_projection_info: " << gcp_projection_info << endl);
-+ DBG(cerr << "geo_transform coefs: " << double_to_string(m_geo_transform_coef[0]) << endl);
-+
-+ AttrTable &attr = a->get_attr_table();
-+ attr.append_attr("projection", "String", projection_info);
-+ attr.append_attr("gcp_projection", "String", gcp_projection_info);
-+ for (unsigned int i = 0; i < sizeof(m_geo_transform_coef); ++i) {
-+ attr.append_attr("geo_transform_coefs", "String", double_to_string(m_geo_transform_coef[i]));
-+ }
-+
-+ return a;
-+}
-+
-+/************************************************************************/
-+/* GetDAPGrid() */
-+/************************************************************************/
-+
-+/**
-+ * @brief Build a DAP Grid from the GDALDataset
-+ */
-+Grid *DAP_Dataset::GetDAPGrid()
-+{
-+ DBG(cerr << "In GetDAPGrid" << endl);
-+
-+ Array *a = GetDAPArray();
-+ Array::Dim_iter i = a->dim_begin();
-+ int lon_size = a->dimension_size(i);
-+ int lat_size = a->dimension_size(++i);
-+
-+ Grid *g = new Grid(a->name());
-+ g->add_var_nocopy(a, array);
-+
-+ // Add maps; assume lon, lat; only two dimensions
-+ Array *lon = new Array("longitude", new Float64("longitude"));
-+ lon->append_dim(lon_size);
-+
-+ vector<double> data(max(lon_size, lat_size)); // (re)use this for both lon and lat
-+
-+ // Compute values
-+ // u = a*x + b*y
-+ // v = c*x + d*y
-+ // u,v --> x,y --> lon,lat
-+ // The constants a, b, c, d are given by the 1, 2, 4, and 5 entries in the geotransform array.
-+
-+ if (m_geo_transform_coef[2] != 0)
-+ throw Error("The transformed data's Geographic projection should not be rotated.");
-+ for (int j = 0; j < lon_size; ++j) {
-+ data[j] = m_geo_transform_coef[1] * j + m_geo_transform_coef[0];
-+ }
-+
-+ // load (copy) values
-+ lon->set_value(&data[0], lon_size);
-+ // Set the map
-+ g->add_var_nocopy(lon, maps);
-+
-+ // Now do the latitude map
-+ Array *lat = new Array("latitude", new Float64("latitude"));
-+ lat->append_dim(lat_size);
-+
-+ if (m_geo_transform_coef[4] != 0)
-+ throw Error("The transformed data's Geographic projection should not be rotated.");
-+ for (int k = 0; k < lat_size; ++k) {
-+ data[k] = m_geo_transform_coef[5] * k + m_geo_transform_coef[3];
-+ }
-+
-+ lat->set_value(&data[0], lat_size);
-+ g->add_var_nocopy(lat, maps);
-+
-+ return g;
-+}
-+
-+/************************************************************************/
-+/* SetNativeCRS() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the Native CRS for a GOES dataset.
-+ *
-+ * The method will set the CRS for a GOES dataset as an native CRS.
-+ *
-+ * Since the original GOES data adopt satellite CRS to recored its value,
-+ * like MODIS swath data, each data point has its corresponding latitude
-+ * and longitude value, those coordinates could be fetched in another two fields.
-+ *
-+ * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
-+ * both the latitude and longitude are existed.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::SetNativeCRS()
-+{
-+ DBG(cerr << "In SetNativeCRS" << endl);
-+
-+ mo_NativeCRS.SetWellKnownGeogCS("WGS84");
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetGeoTransform() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the affine GeoTransform matrix for a GOES data.
-+ *
-+ * The method will set a GeoTransform matrix for a GOES data
-+ * by parsing the coordinates values existed in longitude and latitude field.
-+ *
-+ * The CRS for the bounding box is EPSG:4326.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::SetGeoTransform()
-+{
-+ DBG(cerr << "In SetGeoTransform" << endl);
-+
-+ // TODO Look at this; is this correct
-+ // Assume the array is two dimensional
-+ Array::Dim_iter i = m_src->dim_begin();
-+#if 0
-+ // ORIGINAL code; maybe wrong
-+ int nXSize = m_src->dimension_size(i, true);
-+ int nYSize = m_src->dimension_size(i + 1, true);
-+#endif
-+ // Data are in row-major order, so the first dim is the Y-axis value
-+ int nYSize = m_src->dimension_size(i, true);
-+ int nXSize = m_src->dimension_size(i + 1, true);
-+
-+ mi_SrcImageXSize = nXSize;
-+ mi_SrcImageYSize = nYSize;
-+
-+ SetGeoBBoxAndGCPs(nXSize, nYSize);
-+
-+ double resX, resY;
-+ if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
-+ resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
-+ else
-+ resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
-+
-+ resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (nYSize - 1);
-+
-+ double res = MIN(resX, resY);
-+
-+ if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
-+ mi_RectifiedImageXSize = (int) ((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
-+ else
-+ mi_RectifiedImageXSize = (int) ((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
-+
-+ mi_RectifiedImageYSize = (int) fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
-+
-+ DBG(cerr << "Source image size: " << nXSize << ", " << nYSize << endl);
-+ DBG(cerr << "Rectified image size: " << mi_RectifiedImageXSize << ", " << mi_RectifiedImageYSize << endl);
-+
-+ md_Geotransform[0] = mdSrcGeoMinX;
-+ md_Geotransform[1] = res;
-+ md_Geotransform[2] = 0;
-+ md_Geotransform[3] = mdSrcGeoMaxY;
-+ md_Geotransform[4] = 0;
-+ md_Geotransform[5] = -res;
-+ mb_GeoTransformSet = TRUE;
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetGeoBBoxAndGCPs() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the native geographical bounding box and GCP array for a GOES data.
-+ *
-+ * The method will set the native geographical bounding box
-+ * by comparing the coordinates values existed in longitude and latitude field.
-+ *
-+ * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+void DAP_Dataset::SetGeoBBoxAndGCPs(int nXSize, int nYSize)
-+{
-+ DBG(cerr << "In SetGeoBBoxAndGCPs" << endl);
-+
-+ // reuse the Dim_iter for both lat and lon arrays
-+ Array::Dim_iter i = m_lat->dim_begin();
-+ int nLatXSize = m_lat->dimension_size(i, true);
-+ int nLatYSize = m_lat->dimension_size(i + 1, true);
-+ i = m_lon->dim_begin();
-+ int nLonXSize = m_lon->dimension_size(i, true);
-+ int nLonYSize = m_lon->dimension_size(i + 1, true);
-+
-+ if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
-+ throw Error("The size of latitude/longitude and data field does not match.");
-+
-+#if 0
-+ /*
-+ * Re-sample Standards:
-+ * Height | Width
-+ * (0, 500) every other one pixel
-+ * [500, 1000) every other two pixels
-+ * [1000,1500) every other three pixels
-+ * [1500,2000) every other four pixels
-+ * ... ...
-+ */
-+
-+ int xSpace = 1;
-+ int ySpace = 1;
-+ //setResampleStandard(poVDS, xSpace, ySpace);
-+
-+ // TODO understand how GMU picked this value.
-+ // xSpace and ySpace are the stride values for sampling in
-+ // the x and y dimensions.
-+ const int RESAMPLE_STANDARD = 500;
-+
-+ xSpace = int(nXSize / RESAMPLE_STANDARD) + 2;
-+ ySpace = int(nYSize / RESAMPLE_STANDARD) + 2;
-+#endif
-+
-+ m_lat->read();
-+ m_lon->read();
-+ double *dataLat = extract_double_array(m_lat);
-+ double *dataLon = extract_double_array(m_lon);
-+
-+ DBG(cerr << "Past lat/lon data read" << endl);
-+
-+ try {
-+
-+ mdSrcGeoMinX = 360;
-+ mdSrcGeoMaxX = -360;
-+ mdSrcGeoMinY = 90;
-+ mdSrcGeoMaxY = -90;
-+
-+ // Sample every other row and column
-+ int xSpace = 2;
-+ int ySpace = 2;
-+
-+ int nGCPs = 0;
-+ GDAL_GCP gdalCGP;
-+
-+ for (int iLine = 0; iLine < nYSize - ySpace; iLine += ySpace) {
-+ for (int iPixel = 0; iPixel < nXSize - xSpace; iPixel += xSpace) {
-+ double x = *(dataLon + (iLine * nYSize) + iPixel);
-+ double y = *(dataLat + (iLine * nYSize) + iPixel);
-+
-+ if (isValidLongitude(x) && isValidLatitude(y)) {
-+ char pChr[64];
-+ snprintf(pChr, 64, "%d", ++nGCPs);
-+ GDALInitGCPs(1, &gdalCGP);
-+ gdalCGP.pszId = strdup(pChr);
-+ gdalCGP.pszInfo = strdup("");
-+ gdalCGP.dfGCPLine = iLine;
-+ gdalCGP.dfGCPPixel = iPixel;
-+ gdalCGP.dfGCPX = x;
-+ gdalCGP.dfGCPY = y;
-+
-+ DBG2(cerr << "iLine, iPixel: " << iLine << ", " << iPixel << " --> x,y: " << x << ", " << y << endl);
-+
-+ gdalCGP.dfGCPZ = 0;
-+ m_gdalGCPs.push_back(gdalCGP);
-+
-+ mdSrcGeoMinX = MIN(mdSrcGeoMinX, gdalCGP.dfGCPX);
-+ mdSrcGeoMaxX = MAX(mdSrcGeoMaxX, gdalCGP.dfGCPX);
-+ mdSrcGeoMinY = MIN(mdSrcGeoMinY, gdalCGP.dfGCPY);
-+ mdSrcGeoMaxY = MAX(mdSrcGeoMaxY, gdalCGP.dfGCPY);
-+ }
-+ }
-+ }
-+ }
-+ catch (...) {
-+ delete[] dataLat;
-+ delete[] dataLon;
-+ throw;
-+ }
-+
-+ delete[] dataLat;
-+ delete[] dataLon;
-+
-+ DBG(cerr << "Leaving SetGeoBBoxAndGCPs" << endl);
-+}
-+
-+/************************************************************************/
-+/* SetGDALDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Make a 'memory' dataset with one band
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::SetGDALDataset(const int isSimple)
-+{
-+ DBG(cerr << "In SetGDALDataset" << endl);
-+
-+ // NB: mi_RectifiedImageXSize & Y are set in SetGeoTransform()
-+ GDALDataType eBandType = GDT_Float64;
-+ // VRT, which was used in the original sample code, is not supported in this context, so I used MEM
-+ GDALDriverH poDriver = GDALGetDriverByName("MEM");
-+ if (!poDriver) {
-+ throw Error("Failed to get MEM driver (" + string(CPLGetLastErrorMsg()) + ").");
-+ }
-+
-+ GDALDataset* satDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
-+ 1, eBandType, NULL);
-+ if (!satDataSet) {
-+ GDALClose(poDriver);
-+ throw Error("Failed to create MEM dataSet (" + string(CPLGetLastErrorMsg()) + ").");
-+ }
-+
-+ GDALRasterBand *poBand = satDataSet->GetRasterBand(1);
-+ poBand->SetNoDataValue(md_MissingValue);
-+
-+ m_src->read();
-+ double *data = extract_double_array(m_src);
-+ if (CE_None != poBand->RasterIO(GF_Write, 0, 0, mi_RectifiedImageXSize, mi_RectifiedImageYSize, data,
-+ mi_SrcImageXSize, mi_SrcImageYSize, eBandType, 0, 0)) {
-+ GDALClose((GDALDatasetH) satDataSet);
-+ throw Error("Failed to set satellite data band to MEM DataSet (" + string(CPLGetLastErrorMsg()) + ").");
-+ }
-+ delete[] data;
-+
-+ //set GCPs for this VRTDataset
-+ if (CE_None != SetGCPGeoRef4VRTDataset(satDataSet)) {
-+ GDALClose((GDALDatasetH) satDataSet);
-+ throw Error("Could not georeference the virtual dataset (" + string(CPLGetLastErrorMsg()) + ").");
-+ }
-+
-+ DBG(cerr << "satDataSet: " << satDataSet << endl);
-+
-+ maptr_DS.reset(satDataSet);
-+
-+ if (isSimple)
-+ return CE_None;
-+
-+ return RectifyGOESDataSet();
-+}
-+
-+/************************************************************************/
-+/* SetGCPGeoRef4VRTDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the GCP array for the VRT dataset.
-+ *
-+ * This method is used to set the GCP array to created VRT dataset based on GDAL
-+ * method SetGCPs().
-+ *
-+ * @param poVDS The VRT dataset.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
-+{
-+ char* psTargetSRS;
-+ mo_NativeCRS.exportToWkt(&psTargetSRS);
-+
-+#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
-+ if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS)) {
-+ OGRFree(psTargetSRS);
-+ throw Error("Failed to set GCPs.");
-+ }
-+#else
-+ {
-+ if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
-+ {
-+ OGRFree( psTargetSRS );
-+ throw Error("Failed to set GCPs.");
-+ }
-+ }
-+#endif
-+
-+ OGRFree(psTargetSRS);
-+
-+ return CE_None;
-+}
-+#if 0
-+/************************************************************************/
-+/* SetMetaDataList() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the metadata list for this coverage.
-+ *
-+ * The method will set the metadata list for the coverage based on its
-+ * corresponding GDALDataset object.
-+ *
-+ * @param hSrc the GDALDataset object corresponding to coverage.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
-+{
-+ // TODO Remove
-+#if 0
-+ mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
-+ mv_MetaDataList.push_back("unit=GVAR");
-+ mv_MetaDataList.push_back("FillValue=0");
-+ ms_FieldQuantityDef = "GVAR";
-+ ms_AllowRanges = "0 65535";
-+ ms_CoveragePlatform = "GOES-11";
-+ ms_CoverageInstrument = "GOES-11";
-+ ms_CoverageSensor = "Imager";
-+#endif
-+
-+ return CE_None;
-+}
-+#endif
-+/************************************************************************/
-+/* GetGeoMinMax() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the min/max coordinates of laitutude and longitude.
-+ *
-+ * The method will fetch the min/max coordinates of laitutude and longitude.
-+ *
-+ * @param geoMinMax an existing four double buffer into which the
-+ * native geographical bounding box values will be placed.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::GetGeoMinMax(double geoMinMax[])
-+{
-+ if (!mb_GeoTransformSet)
-+ return CE_Failure;
-+
-+ geoMinMax[0] = mdSrcGeoMinX;
-+ geoMinMax[2] = mdSrcGeoMinY;
-+ geoMinMax[1] = mdSrcGeoMaxX;
-+ geoMinMax[3] = mdSrcGeoMaxY;
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* RectifyGOESDataSet() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Convert the GOES dataset from satellite CRS project to grid CRS.
-+ *
-+ * The method will convert the GOES dataset from satellite CRS project to
-+ * grid CRS based on GDAL API GDALReprojectImage;
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr DAP_Dataset::RectifyGOESDataSet()
-+{
-+ DBG(cerr << "In RectifyGOESDataSet" << endl);
-+
-+ char *pszDstWKT;
-+ mo_NativeCRS.exportToWkt(&pszDstWKT);
-+
-+ GDALDriverH poDriver = GDALGetDriverByName("VRT"); // MEM
-+ GDALDataset* rectDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
-+ maptr_DS->GetRasterCount(), maptr_DS->GetRasterBand(1)->GetRasterDataType(), NULL);
-+ if (NULL == rectDataSet) {
-+ GDALClose(poDriver);
-+ OGRFree(pszDstWKT);
-+ throw Error("Failed to create \"MEM\" dataSet.");
-+ }
-+
-+ rectDataSet->SetProjection(pszDstWKT);
-+ rectDataSet->SetGeoTransform(md_Geotransform);
-+
-+ DBG(cerr << "rectDataSet: " << rectDataSet << endl);
-+ DBG(cerr << "satDataSet: " << maptr_DS.get() << endl);
-+
-+ // FIXME Magic value of 0.125
-+ if (CE_None != GDALReprojectImage(maptr_DS.get(), NULL, rectDataSet, pszDstWKT,
-+ GRA_Lanczos /*GRA_NearestNeighbour*/, 0, 0.0/*0.125*/, NULL, NULL, NULL)) {
-+ GDALClose(rectDataSet);
-+ GDALClose(poDriver);
-+ OGRFree(pszDstWKT);
-+ throw Error("Failed to re-project satellite data from GCP CRS to geographical CRS.");
-+ }
-+
-+ OGRFree(pszDstWKT);
-+ GDALClose(maptr_DS.release());
-+
-+ maptr_DS.reset(rectDataSet);
-+
-+ DBG(cerr << "Leaving RectifyGOESDataSet" << endl);
-+
-+ return CE_None;
-+}
-+
-+} // namespace libdap
-diff -Nur bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.h bes-3.12.0/functions/swath2grid/DAP_Dataset.h
---- bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.h 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/DAP_Dataset.h 2014-03-03 15:47:38.050232928 +0100
-@@ -0,0 +1,142 @@
-+
-+// -*- mode: c++; c-basic-offset:4 -*-
-+
-+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
-+// Access Protocol.
-+
-+// Copyright (c) 2012 OPeNDAP, Inc.
-+// Author: James Gallagher <jgallagher at opendap.org>
-+//
-+// This library is free software; you can redistribute it and/or
-+// modify it under the terms of the GNU Lesser General Public
-+// License as published by the Free Software Foundation; either
-+// version 2.1 of the License, or (at your option) any later version.
-+//
-+// This library 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
-+// Lesser General Public License for more details.
-+//
-+// You should have received a copy of the GNU Lesser General Public
-+// License along with this library; if not, write to the Free Software
-+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-+//
-+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
-+
-+#ifndef DAP_DATASET_H_
-+#define DAP_DATASET_H_
-+
-+#include <string>
-+#include "AbstractDataset.h"
-+#include "wcsUtil.h"
-+
-+using namespace std;
-+
-+namespace libdap {
-+
-+class Array;
-+class Grid;
-+
-+/************************************************************************/
-+/* ==================================================================== */
-+/* DAP_Dataset */
-+/* ==================================================================== */
-+/************************************************************************/
-+
-+//! DAP_Dataset is a subclass of AbstractDataset, used to process NOAA GOES data.
-+/**
-+ * \class DAP_Dataset "DAP_Dataset.h"
-+ *
-+ * GOES satellites provide the kind of continuous monitoring necessary for
-+ * intensive data analysis. They circle the Earth in a geosynchronous orbit,
-+ * which means they orbit the equatorial plane of the Earth at a speed
-+ * matching the Earth's rotation. This allows them to hover continuously
-+ * over one position on the surface. The geosynchronous plane is about
-+ * 35,800 km (22,300 miles) above the Earth, high enough to allow the
-+ * satellites a full-disc view of the Earth. Because they stay above a
-+ * fixed spot on the surface, they provide a constant vigil for the atmospheric
-+ * "triggers" for severe weather conditions such as tornadoes, flash floods,
-+ * hail storms, and hurricanes. When these conditions develop the GOES
-+ * satellites are able to monitor storm development and track their movements.
-+ *
-+ * GOES satellite imagery is also used to estimate rainfall during
-+ * the thunderstorms and hurricanes for flash flood warnings, as well
-+ * as estimates snowfall accumulations and overall extent of snow cover.
-+ * Such data help meteorologists issue winter storm warnings and spring
-+ * snow melt advisories. Satellite sensors also detect ice fields and map
-+ * the movements of sea and lake ice.
-+ *
-+ * For more inforamtion about NOAA GOES data, please access
-+ * <a href=http://www.oso.noaa.gov/GOES/>http://www.oso.noaa.gov/GOES/</a>
-+ *
-+ * DAP_Dataset is a subclass of AbstractDataset, which is used to
-+ * process GOES Imager and Sounder products.
-+ */
-+
-+class DAP_Dataset : public AbstractDataset {
-+protected:
-+ string m_ncLatDataSetName;
-+ string m_ncLonDataSetName;
-+ string m_ncCoverageIDName;
-+
-+ // Instead of using names and opening files with GDAL,
-+ // store pointers to Arrays read by the underlying DAP
-+ // server constraint evaluator.
-+ Array *m_src;
-+ Array *m_lat;
-+ Array *m_lon;
-+
-+ int mi_RectifiedImageXSize;
-+ int mi_RectifiedImageYSize;
-+ int mi_SrcImageXSize;
-+ int mi_SrcImageYSize;
-+
-+ double mb_LatLonBBox[4];
-+ double mdSrcGeoMinX;
-+ double mdSrcGeoMinY;
-+ double mdSrcGeoMaxX;
-+ double mdSrcGeoMaxY;
-+
-+ // This is not set until GetDAPArray() is called.
-+ double m_geo_transform_coef[6];
-+
-+ vector<GDAL_GCP> m_gdalGCPs;
-+
-+public:
-+ CPLErr SetGCPGeoRef4VRTDataset(GDALDataset*);
-+ void SetGeoBBoxAndGCPs(int xSize, int ySize);
-+ CPLErr RectifyGOESDataSet();
-+ CPLErr setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue);
-+
-+ int isValidLatitude(const double &lat)
-+ {
-+ return (lat >= -90 && lat <= 90);
-+ }
-+ int isValidLongitude(const double &lon)
-+ {
-+ return (lon >= -180 && lon <= 180);
-+ }
-+
-+ virtual CPLErr SetGeoTransform();
-+#if 0
-+ virtual CPLErr SetMetaDataList(GDALDataset* hSrcDS); //TODO Remove
-+#endif
-+ virtual CPLErr SetNativeCRS();
-+ virtual CPLErr SetGDALDataset(const int isSimple = 0);
-+ virtual CPLErr InitialDataset(const int isSimple = 0);
-+ virtual CPLErr GetGeoMinMax(double geoMinMax[]);
-+
-+public:
-+ DAP_Dataset();
-+ DAP_Dataset(const string& id, vector<int> &rBandList);
-+
-+ // Added jhrg 11/23/12
-+ DAP_Dataset(Array *src, Array *lat, Array *lon);
-+ Array *GetDAPArray();
-+ Grid *GetDAPGrid();
-+
-+ virtual ~DAP_Dataset();
-+};
-+
-+} // namespace libdap
-+#endif /* DAP_DATASET_H_ */
-diff -Nur bes-3.12.0/functions.orig/swath2grid/Makefile.am bes-3.12.0/functions/swath2grid/Makefile.am
---- bes-3.12.0/functions.orig/swath2grid/Makefile.am 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/Makefile.am 2014-03-03 15:47:38.056899595 +0100
-@@ -0,0 +1,106 @@
-+
-+# Build libswath2grid, part of libdap.
-+
-+AUTOMAKE_OPTIONS = foreign
-+
-+AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) -I$(top_srcdir)/tests -I$(top_srcdir)/dispatch $(XML2_CFLAGS) $(CURL_CFLAGS)
-+AM_LDADD =
-+
-+if CPPUNIT
-+AM_CPPFLAGS += $(CPPUNIT_CFLAGS)
-+AM_LDADD += $(CPPUNIT_LIBS)
-+endif
-+
-+# These are not used by automake but are often useful for certain types of
-+# debugging. The best way to use these is to run configure as:
-+# export CXXFLAGS='...'; ./configure --disable-shared
-+# the --disable-shared is not required, but it seems to help with debuggers.
-+CXXFLAGS_DEBUG = -g3 -O0 -Wall -W -Wcast-align -Werror
-+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
-+
-+# SUBDIRS =
-+# DIST_SUBDIRS =
-+
-+# This determines what gets built by make check
-+check_PROGRAMS = $(UNIT_TESTS)
-+
-+# This determines what gets run by 'make check.'
-+# Now (12/20/12) this fails; don't run until it works.
-+# TESTS = $(UNIT_TESTS)
-+
-+
-+noinst_LTLIBRARIES = libswath2grid.la
-+
-+libswath2grid_la_SOURCES = $(SRCS) $(HDRS)
-+libswath2grid_la_CPPFLAGS = $(GDAL_CFLAGS) $(XML2_CFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) -I$(top_srcdir)/dispatch
-+libswath2grid_la_LDFLAGS =
-+libswath2grid_la_LIBADD = $(GDAL_LDFLAGS) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS)
-+
-+SRCS = AbstractDataset.cpp wcs_error.cpp \
-+BoundingBox.cpp wcsUtil.cpp DAP_Dataset.cpp reproj_functions.cc
-+
-+# NC_GOES_Dataset.cpp NC_GOES_Dataset.h
-+
-+HDRS = AbstractDataset.h wcs_error.h \
-+BoundingBox.h wcsUtil.h DAP_Dataset.h reproj_functions.h
-+
-+if CPPUNIT
-+UNIT_TESTS = s2gTest
-+
-+else
-+UNIT_TESTS =
-+
-+check-local:
-+ @echo ""
-+ @echo "**********************************************************"
-+ @echo "You must have cppunit 1.12.x or greater installed to run *"
-+ @echo "check target in unit-tests directory *"
-+ @echo "**********************************************************"
-+ @echo ""
-+endif
-+
-+s2gTest_SOURCES = s2gTest.cc
-+s2gTest_CPPFLAGS = $(AM_CPPFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) $(GDAL_CFLAGS)
-+s2gTest_LDADD = -ltest-types libswath2grid.la $(AM_LDADD) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS) $(GDAL_LDFLAGS)
-+
-+if LIBDAP
-+check-dap:
-+ @echo ""
-+ @echo "**********************************************************"
-+ @echo "USING DAP "
-+ @echo "DAP_CLIENT_CFLAGS: " $(DAP_CLIENT_CFLAGS)
-+ @echo "DAP_SERVER_CFLAGS: " $(DAP_SERVER_CFLAGS)
-+ @echo "DAP_CLIENT_LIBS: " $(DAP_CLIENT_LIBS)
-+ @echo "DAP_SERVER_LIBS: " $(DAP_SERVER_LIBS)
-+ @echo "**********************************************************"
-+ @echo ""
-+else
-+check-dap:
-+ @echo ""
-+ @echo "**********************************************************"
-+ @echo " Unable to locate DAP libraries!"
-+ @echo "**********************************************************"
-+ @echo ""
-+endif
-+
-+
-+if GDAL_FOUND
-+check-gdal:
-+ @echo ""
-+ @echo "**********************************************************"
-+ @echo "Using gdal. "
-+ @echo "GDAL_CFLAGS: " $(GDAL_CFLAGS)
-+ @echo "GDAL_LDFLAGS: " $(GDAL_LDFLAGS)
-+ @echo "**********************************************************"
-+ @echo ""
-+else
-+check-gdal:
-+ @echo ""
-+ @echo "**********************************************************"
-+ @echo "You must have gdal 12.15.12 or greater installed to run"
-+ @echo "check target in unit-tests directory "
-+ @echo "GDAL_VERSION: '$(GDAL_VERSION)'"
-+ @echo "prefix: '$(prefix)'"
-+ @echo "**********************************************************"
-+ @echo ""
-+endif
-diff -Nur bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.cpp bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.cpp
---- bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.cpp 1970-01-01 01:00:00.000000000 +0100
-+++ bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.cpp 2014-03-03 15:47:38.053566262 +0100
-@@ -0,0 +1,625 @@
-+/******************************************************************************
-+ * $Id: TRMM_Dataset.cpp 2011-07-19 16:24:00Z $
-+ *
-+ * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
-+ * for Earth Observation: Open Source Reference Implementation
-+ * Purpose: NC_GOES_Dataset implementation for NOAA GOES data
-+ * Author: Yuanzheng Shao, yshao3 at gmu.edu
-+ *
-+ ******************************************************************************
-+ * Copyright (c) 2011, Liping Di <ldi at gmu.edu>, Yuanzheng Shao <yshao3 at gmu.edu>
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included
-+ * in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+ * DEALINGS IN THE SOFTWARE.
-+ ****************************************************************************/
-+
-+#include "NC_GOES_Dataset.h"
-+
-+using namespace std;
-+
-+#define GOES_TIME_DEBUG FALSE
-+
-+NC_GOES_Dataset::NC_GOES_Dataset()
-+{
-+}
-+
-+/************************************************************************/
-+/* ~NC_GOES_Dataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Destroy an open NC_GOES_Dataset object.
-+ *
-+ * This is the accepted method of closing a NC_GOES_Dataset dataset and
-+ * deallocating all resources associated with it.
-+ */
-+
-+NC_GOES_Dataset::~NC_GOES_Dataset()
-+{
-+}
-+
-+/************************************************************************/
-+/* NC_GOES_Dataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Create an NC_GOES_Dataset object.
-+ *
-+ * This is the accepted method of creating a NC_GOES_Dataset object and
-+ * allocating all resources associated with it.
-+ *
-+ * @param id The coverage identifier.
-+ *
-+ * @param rBandList The field list selected for this coverage. For TRMM
-+ * daily data, the user could specify multiple days range in request.
-+ * Each day is seemed as one field.
-+ *
-+ * @return A NC_GOES_Dataset object.
-+ */
-+
-+NC_GOES_Dataset::NC_GOES_Dataset(const string& id, vector<int> &rBandList) :
-+ AbstractDataset(id, rBandList)
-+{
-+ md_MissingValue = 0;
-+ mb_GeoTransformSet = FALSE;
-+}
-+
-+/************************************************************************/
-+/* InitialDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Initialize the GOES dataset with NetCDF format.
-+
-+ * This method is the implementation for initializing a GOES dataset with NetCDF format.
-+ * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
-+ * will be called to initialize an GOES dataset.
-+ *
-+ * @param isSimple the WCS request type. When user executing a DescribeCoverage
-+ * request, isSimple is set to 1, and for GetCoverage, is set to 0.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::InitialDataset(const int isSimple)
-+{
-+ vector<string> strSet;
-+ unsigned int n = CsvburstCpp(ms_CoverageID, strSet, ':');
-+ if (n != 4)
-+ {
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Incorrect coverage ID.");
-+ return CE_Failure;
-+ }
-+
-+ ms_DataTypeName = strSet[0] + ":" + strSet[1];
-+ ms_SrcFilename = StrTrims(strSet[2], " \'\"");
-+ ms_DatasetName = strSet[3];
-+
-+ m_ncLatDataSetName = "NETCDF:" + ms_SrcFilename + ":latitude";
-+ m_ncLonDataSetName = "NETCDF:" + ms_SrcFilename + ":longitude";
-+ m_ncCoverageIDName = strSet[1] + ":" + strSet[2] + ":" + strSet[3];
-+
-+ GDALDataset* pSrc = (GDALDataset*) GDALOpenShared(m_ncCoverageIDName.c_str(), GA_ReadOnly);
-+ if (pSrc == NULL)
-+ {
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open file \"%s\".", ms_SrcFilename.c_str());
-+ return CE_Failure;
-+ }
-+
-+ ms_NativeFormat = GDALGetDriverShortName(pSrc->GetDriver());
-+
-+ //setmetalist
-+ SetMetaDataList(pSrc);
-+
-+ //set noValue
-+ unsigned int nBandCount = pSrc->GetRasterCount();
-+ if (nBandCount < 1)
-+ {
-+ GDALClose(pSrc);
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The GOES file does not contain any raster band.");
-+ return CE_Failure;
-+ }
-+
-+ maptr_DS.reset(pSrc);
-+
-+ //set moNativeCRS and mGeoTransform
-+ if (CE_None != SetNativeCRS() ||
-+ CE_None != SetGeoTransform() ||
-+ CE_None != SetGDALDataset(isSimple))
-+ {
-+ GDALClose(maptr_DS.release());
-+ return CE_Failure;
-+ }
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetNativeCRS() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the Native CRS for a GOES dataset.
-+ *
-+ * The method will set the CRS for a GOES dataset as an native CRS.
-+ *
-+ * Since the original GOES data adopt satellite CRS to recored its value,
-+ * like MODIS swath data, each data point has its corresponding latitude
-+ * and longitude value, those coordinates could be fetched in another two fields.
-+ *
-+ * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
-+ * both the latitude and longitude are existed.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetNativeCRS()
-+{
-+ if (CE_None == AbstractDataset::SetNativeCRS())
-+ return CE_None;
-+
-+ GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
-+ GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
-+
-+ if(hLatDS == NULL) {
-+ m_ncLatDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lat";
-+ hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
-+ }
-+
-+ if(hLonDS == NULL) {
-+ m_ncLonDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lon";
-+ hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
-+ }
-+
-+ if (hLatDS == NULL || hLonDS == NULL)
-+ {
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::SetNativeCRS()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open latitude/longitude sub-dataset.");
-+ return CE_Failure;
-+ }
-+
-+ mo_NativeCRS.SetWellKnownGeogCS("WGS84");
-+
-+ GDALClose(hLatDS);
-+ GDALClose(hLonDS);
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetGeoTransform() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the affine GeoTransform matrix for a GOES data.
-+ *
-+ * The method will set a GeoTransform matrix for a GOES data
-+ * by parsing the coordinates values existed in longitude and latitude field.
-+ *
-+ * The CRS for the bounding box is EPSG:4326.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetGeoTransform()
-+{
-+ if (CE_None == AbstractDataset::SetGeoTransform())
-+ return CE_None;
-+
-+ if (CE_None != SetGeoBBoxAndGCPs(maptr_DS.get()))
-+ return CE_Failure;
-+
-+ double resX, resY;
-+ if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
-+ resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
-+ else
-+ resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
-+
-+ resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (maptr_DS->GetRasterYSize() - 1);
-+
-+ double res = MIN(resX,resY);
-+
-+ if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
-+ mi_RectifiedImageXSize = (int)((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
-+ else
-+ mi_RectifiedImageXSize = (int)((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
-+
-+ mi_RectifiedImageYSize = (int)fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
-+
-+ md_Geotransform[0] = mdSrcGeoMinX;
-+ md_Geotransform[1] = res;
-+ md_Geotransform[2] = 0;
-+ md_Geotransform[3] = mdSrcGeoMaxY;
-+ md_Geotransform[4] = 0;
-+ md_Geotransform[5] = -res;
-+ mb_GeoTransformSet = TRUE;
-+
-+ return CE_None;
-+}
-+
-+CPLErr NC_GOES_Dataset::setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue)
-+{
-+ static int RESAMPLE_STANDARD = 500;
-+ int nXSize = hSrcDS->GetRasterXSize();
-+ int nYSize = hSrcDS->GetRasterYSize();
-+
-+ xRSValue = int(nXSize / RESAMPLE_STANDARD) + 2;
-+ yRSValue = int(nYSize / RESAMPLE_STANDARD) + 2;
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetGeoBBoxAndGCPs() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the native geographical bounding box and GCP array for a GOES data.
-+ *
-+ * The method will set the native geographical bounding box
-+ * by comparing the coordinates values existed in longitude and latitude field.
-+ *
-+ * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetGeoBBoxAndGCPs(GDALDataset* poVDS)
-+{
-+ GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
-+ GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
-+
-+ int nXSize = poVDS->GetRasterXSize();
-+ int nYSize = poVDS->GetRasterYSize();
-+
-+ mi_GoesSrcImageXSize = nXSize;
-+ mi_GoesSrcImageYSize = nYSize;
-+
-+ int nLatXSize = hLatDS->GetRasterXSize();
-+ int nLatYSize = hLatDS->GetRasterYSize();
-+ int nLonXSize = hLonDS->GetRasterXSize();
-+ int nLonYSize = hLonDS->GetRasterYSize();
-+
-+ if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
-+ {
-+ GDALClose(hLatDS);
-+ GDALClose(hLonDS);
-+
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::SetGeoBBoxAndGCPs()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The size of latitude/longitude and data field does not match.");
-+
-+ return CE_Failure;
-+ }
-+
-+ /*
-+ * Re-sample Standards:
-+ * Height | Width
-+ * (0, 500) every other one pixel
-+ * [500, 1000) every other two pixels
-+ * [1000,1500) every other three pixels
-+ * [1500,2000) every other four pixels
-+ * ... ...
-+ */
-+
-+ int xSpace = 1;
-+ int ySpace = 1;
-+ setResampleStandard(poVDS, xSpace, ySpace);
-+
-+ int nGCPs = 0;
-+ GDAL_GCP gdalCGP;
-+
-+ GDALRasterBand *poBandLat = hLatDS->GetRasterBand(1);
-+ GDALRasterBand *poBandLon = hLonDS->GetRasterBand(1);
-+ GDALDataType eDT = poBandLat->GetRasterDataType();
-+ void *dataLat = NULL;
-+ void *dataLon = NULL;
-+
-+ mdSrcGeoMinX = 360;
-+ mdSrcGeoMaxX = -360;
-+ mdSrcGeoMinY = 90;
-+ mdSrcGeoMaxY = -90;
-+
-+ switch (eDT)
-+ {
-+ case GDT_Float32: //For GOES Imager and Sounder data
-+ {
-+ dataLat = (float *) CPLMalloc(nXSize * sizeof(float));
-+ dataLon = (float *) CPLMalloc(nXSize * sizeof(float));
-+
-+ for (int iLine = 0; iLine < nYSize; iLine += ySpace)
-+ {
-+ if (iLine >= nYSize)
-+ iLine = nYSize - 1;
-+
-+ poBandLat->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLat, nXSize, 1, GDT_Float32, 0, 0);
-+ poBandLon->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLon, nXSize, 1, GDT_Float32, 0, 0);
-+
-+ for (int iPixel = 0; iPixel < nXSize; iPixel += xSpace)
-+ {
-+ if(iPixel >= nXSize)
-+ iPixel = nXSize - 1;
-+ double x = *((float *) dataLon + iPixel);
-+ double y = *((float *) dataLat + iPixel);
-+ if (isValidLongitude(x) && isValidLatitude(y))
-+ {
-+ char pChr[64];
-+ sprintf(pChr, "%d", ++nGCPs);
-+ GDALInitGCPs(1, &gdalCGP);
-+ gdalCGP.pszId = strdup(pChr);
-+ gdalCGP.pszInfo = strdup("");
-+ gdalCGP.dfGCPLine = iLine;
-+ gdalCGP.dfGCPPixel = iPixel;
-+ gdalCGP.dfGCPX = x;
-+ gdalCGP.dfGCPY = y;
-+ gdalCGP.dfGCPZ = 0;
-+ m_gdalGCPs.push_back(gdalCGP);
-+ mdSrcGeoMinX = MIN(mdSrcGeoMinX,gdalCGP.dfGCPX );
-+ mdSrcGeoMaxX = MAX(mdSrcGeoMaxX,gdalCGP.dfGCPX);
-+ mdSrcGeoMinY = MIN(mdSrcGeoMinY,gdalCGP.dfGCPY);
-+ mdSrcGeoMaxY = MAX(mdSrcGeoMaxY,gdalCGP.dfGCPY);
-+ }
-+ }
-+ }
-+
-+ VSIFree((float *) dataLat);
-+ VSIFree((float *) dataLon);
-+ }
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ GDALClose(hLatDS);
-+ GDALClose(hLonDS);
-+
-+ return CE_None;
-+}
-+
-+
-+/************************************************************************/
-+/* SetGDALDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the GDALDataset object to GOES Imager and Sounder dataset.
-+ *
-+ * This method is used to set the GOES Imager and Sounder dataset based on GDAL
-+ * class VRTDataset.
-+ *
-+ * @param isSimple the WCS request type. When user executing a DescribeCoverage
-+ * request, isSimple is set to 1, and for GetCoverage, is set to 0.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetGDALDataset(const int isSimple)
-+{
-+ for(int i = 1; i <= maptr_DS->GetRasterCount(); ++i)
-+ mv_BandList.push_back(i);
-+
-+ VRTDataset *poVDS = (VRTDataset *)VRTCreate(mi_RectifiedImageXSize, mi_RectifiedImageYSize);
-+ if (poVDS == NULL)
-+ {
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::SetGDALDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to create VRT DataSet.");
-+ return CE_Failure;
-+ }
-+
-+ VRTSourcedRasterBand *poVRTBand = NULL;
-+ GDALRasterBand *poSrcBand = NULL;
-+ GDALDataType eBandType;
-+ for (unsigned int i = 0; i < mv_BandList.size(); i++)
-+ {
-+ poSrcBand = maptr_DS->GetRasterBand(mv_BandList[i]);
-+ eBandType = poSrcBand->GetRasterDataType();
-+ poVDS->AddBand(eBandType, NULL);
-+ poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand(i + 1);
-+ poVRTBand->SetNoDataValue(md_MissingValue);
-+
-+ if (CE_None != poVRTBand->AddSimpleSource(poSrcBand, 0, 0,
-+ mi_RectifiedImageXSize, mi_RectifiedImageYSize, 0, 0,
-+ mi_RectifiedImageXSize, mi_RectifiedImageYSize, NULL, md_MissingValue))
-+ {
-+ GDALClose((GDALDatasetH) poVDS);
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::setGDALDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Add Simple Source into VRT DataSet.");
-+ return CE_Failure;
-+ }
-+ }
-+
-+ //set GCPs for this VRTDataset
-+ if (CE_None != SetGCPGeoRef4VRTDataset(poVDS))
-+ {
-+ GDALClose((GDALDatasetH) poVDS);
-+ return CE_Failure;
-+ }
-+
-+ GDALClose(maptr_DS.release());
-+ maptr_DS.reset(poVDS);
-+
-+ if (isSimple)
-+ return CE_None;
-+
-+ return RectifyGOESDataSet();
-+}
-+
-+/************************************************************************/
-+/* SetGCPGeoRef4VRTDataset() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the GCP array for the VRT dataset.
-+ *
-+ * This method is used to set the GCP array to created VRT dataset based on GDAL
-+ * method SetGCPs().
-+ *
-+ * @param poVDS The VRT dataset.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
-+{
-+ char* psTargetSRS;
-+ mo_NativeCRS.exportToWkt(&psTargetSRS);
-+
-+#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
-+ if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS))
-+ {
-+ OGRFree(psTargetSRS);
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
-+ WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to set GCPs.");
-+
-+ return CE_Failure;
-+ }
-+#else
-+ {
-+ if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
-+ {
-+ OGRFree( psTargetSRS );
-+ SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
-+ WCS_Error(CE_Failure,OGC_WCS_NoApplicableCode,"Failed to set GCPs.");
-+
-+ return CE_Failure;
-+ }
-+ }
-+#endif
-+
-+ OGRFree(psTargetSRS);
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* SetMetaDataList() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Set the metadata list for this coverage.
-+ *
-+ * The method will set the metadata list for the coverage based on its
-+ * corresponding GDALDataset object.
-+ *
-+ * @param hSrc the GDALDataset object corresponding to coverage.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
-+
-+CPLErr NC_GOES_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
-+{
-+ mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
-+ mv_MetaDataList.push_back("unit=GVAR");
-+ mv_MetaDataList.push_back("FillValue=0");
-+ ms_FieldQuantityDef = "GVAR";
-+ ms_AllowRanges = "0 65535";
-+ ms_CoveragePlatform = "GOES-11";
-+ ms_CoverageInstrument = "GOES-11";
-+ ms_CoverageSensor = "Imager";
-+
-+ return CE_None;
-+}
-+
-+/************************************************************************/
-+/* GetGeoMinMax() */
-+/************************************************************************/
-+
-+/**
-+ * \brief Get the min/max coordinates of laitutude and longitude.
-+ *
-+ * The method will fetch the min/max coordinates of laitutude and longitude.
-+ *
-+ * @param geoMinMax an existing four double buffer into which the
-+ * native geographical bounding box values will be placed.
-+ *
-+ * @return CE_None on success or CE_Failure on failure.
-+ */
<Skipped 9756 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/bes.git/commitdiff/63c689277f5aa37d6336c2b2d973b0c18f383d8d
More information about the pld-cvs-commit
mailing list