1 diff -Nur bes-3.12.0/functions.orig/swath2grid/AbstractDataset.cpp bes-3.12.0/functions/swath2grid/AbstractDataset.cpp
2 --- bes-3.12.0/functions.orig/swath2grid/AbstractDataset.cpp 1970-01-01 01:00:00.000000000 +0100
3 +++ bes-3.12.0/functions/swath2grid/AbstractDataset.cpp 2014-03-03 15:47:38.046899595 +0100
5 +/******************************************************************************
6 + * $Id: AbstractDataset.cpp 2011-07-19 16:24:00Z $
8 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
9 + * for Earth Observation: Open Source Reference Implementation
10 + * Purpose: AbstractDataset implementation for providing an abstract data
11 + * model for multiple data source.
12 + * Author: Yuanzheng Shao, yshao3@gmu.edu
14 + ******************************************************************************
15 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
17 + * Permission is hereby granted, free of charge, to any person obtaining a
18 + * copy of this software and associated documentation files (the "Software"),
19 + * to deal in the Software without restriction, including without limitation
20 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 + * and/or sell copies of the Software, and to permit persons to whom the
22 + * Software is furnished to do so, subject to the following conditions:
24 + * The above copyright notice and this permission notice shall be included
25 + * in all copies or substantial portions of the Software.
27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 + * DEALINGS IN THE SOFTWARE.
34 + ****************************************************************************/
36 +#include "AbstractDataset.h"
38 +/************************************************************************/
39 +/* ==================================================================== */
40 +/* AbstractDataset */
41 +/* ==================================================================== */
42 +/************************************************************************/
45 + * \class AbstractDataset "AbstractDataset.h"
47 + * An abstract dataset encapsulating one or more raster bands, which is
48 + * based on GDALDataset, and add the support to metadata model: ISO 19115
49 + * and 1SO 19115 (2). A series of Fetch functions are provided for the
50 + * implementation of Web Coverage Service.
52 + * Use WCSTCreateDataset() to create a AbstractDataset for a named coverage
53 + * identifier and band list.
56 +/************************************************************************/
57 +/* AbstractDataset() */
58 +/************************************************************************/
59 +AbstractDataset::AbstractDataset()
63 +/************************************************************************/
64 +/* AbstractDataset() */
65 +/************************************************************************/
68 + * \brief Constructor of an AbstractDataset.
70 + * This is the accepted method of opening an abstract dataset and allocating
71 + * all resources associated with it.
74 +AbstractDataset::AbstractDataset(const string& id, vector<int> &rBandList) :
75 + ms_CoverageID(id), mv_BandList(rBandList)
79 +/************************************************************************/
80 +/* ~AbstractDataset() */
81 +/************************************************************************/
84 + * \brief Destroy an open AbstractDataset object.
86 + * This is the accepted method of closing a AbstractDataset dataset and
87 + * deallocating all resources associated with it.
90 +AbstractDataset::~AbstractDataset()
93 + GDALClose(maptr_DS.release());
96 +/************************************************************************/
97 +/* InitialDataset() */
98 +/************************************************************************/
101 + * \brief Initialize the data set.
103 + * This is the virtual function for initializing abstract dataste. The
104 + * subclasses of AbstarctDataset will call SetNativeCRS(), SetGeoTransform()
105 + * and SetGDALDataset() to initialize an abstarct dataset.
107 + * @param isSimple The WCS request type. When user executing a DescribeCoverage
108 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
110 + * @return CE_None on success or CE_Failure on failure.
113 +CPLErr AbstractDataset::InitialDataset(const int isSimple)
118 +/************************************************************************/
119 +/* GetGDALDataset() */
120 +/************************************************************************/
123 + * \brief Get the GDALDataset object from AbstarctDataset.
125 + * An AbstarctDataset encapsulating one GDALDataset. GetGDALDataset()
126 + * returns a GDALDatset object, which is used to fetch its information
127 + * through GDAL APIs.
129 + * @return GDALDatset object.
132 +GDALDataset* AbstractDataset::GetGDALDataset()
134 + return maptr_DS.get();
137 +/************************************************************************/
138 +/* SetGDALDataset() */
139 +/************************************************************************/
142 + * \brief Set the GDALDataset object to AbstarctDataset.
144 + * This is the virtual function for setting the abstract dataset by
145 + * calling GDAL functions.
147 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
148 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
150 + * @return CE_None on success or CE_Failure on failure.
153 +CPLErr AbstractDataset::SetGDALDataset(const int isSimple)
158 +/************************************************************************/
159 +/* GetNativeCRS() */
160 +/************************************************************************/
163 + * \brief Get the Native CRS of an AbstarctDataset.
165 + * The method will return the CRS obejct, which is an OGRSpatialReference
168 + * @return an OGRSpatialReference object corresponding the native CRS of
172 +const OGRSpatialReference& AbstractDataset::GetNativeCRS()
174 + return mo_NativeCRS;
177 +/************************************************************************/
178 +/* SetNativeCRS() */
179 +/************************************************************************/
182 + * \brief Set the Native CRS for an AbstarctDataset.
184 + * The method will set the CRS for an AbstractDataset as an native CRS. For
185 + * some served coverage, GDAL could not tell its native CRS, this method
186 + * should be called to set its native CRS.
188 + * @return CE_None on success or CE_Failure on failure.
191 +CPLErr AbstractDataset::SetNativeCRS()
193 + char* wktStr = (char*) maptr_DS->GetProjectionRef();
195 + if (wktStr && OGRERR_NONE == mo_NativeCRS.importFromWkt(&wktStr))
201 +/************************************************************************/
202 +/* SetGeoTransform() */
203 +/************************************************************************/
206 + * \brief Set the affine GeoTransform matrix for a coverage.
208 + * The method will set a GeoTransform matrix for a coverage. The method
209 + * GetGeoTransform of GDAL library will be called to get the matrix.
211 + * @return CE_None on success or CE_Failure on failure.
214 +CPLErr AbstractDataset::SetGeoTransform()
216 + if (CE_None != maptr_DS->GetGeoTransform(md_Geotransform))
219 + //Is the returned matrix correct? check the resolution values;
220 + if(md_Geotransform[2] == 0 && md_Geotransform[5] == 0)
223 + mb_GeoTransformSet = TRUE;
228 +/************************************************************************/
229 +/* GetGeoTransform() */
230 +/************************************************************************/
233 + * \brief Fetch the affine transformation coefficients.
235 + * Fetches the coefficients for transforming between pixel/line (P,L) raster
236 + * space, and projection coordinates (Xp,Yp) space.
239 + * Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
240 + * Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
243 + * In a north up image, padfTransform[1] is the pixel width, and
244 + * padfTransform[5] is the pixel height. The upper left corner of the
245 + * upper left pixel is at position (padfTransform[0],padfTransform[3]).
247 + * The default transform is (0,1,0,0,0,1) and should be returned even when
248 + * a CE_Failure error is returned, such as for formats that don't support
249 + * transformation to projection coordinates.
251 + * NOTE: GetGeoTransform() isn't expressive enough to handle the variety of
252 + * OGC Grid Coverages pixel/line to projection transformation schemes.
253 + * Eventually this method will be depreciated in favour of a more general
256 + * @param geoTrans an existing six double buffer into which the
257 + * transformation will be placed.
259 + * @return TRUE on success or FALSE on failure.
262 +int AbstractDataset::GetGeoTransform(double geoTrans[])
264 + if (!mb_GeoTransformSet)//Geo-Transform not setup in each data driver, then set default.
275 + memcpy(geoTrans, md_Geotransform, sizeof(double) * 6);
280 +/************************************************************************/
281 +/* GetCoverageID() */
282 +/************************************************************************/
285 + * \brief Fetch the identifier of a coverage.
287 + * The method will return the coverage identifier related to the abstarct
288 + * dataset. As to TRMM data, the coverage identifier likes:
289 + * TRMM:/Volumes/RAIDL1/GeoData/TRMM/TRMM_3B42_daily.2000.hdf:Daily
291 + * As to MODIS data, the coverage identifier likes:
292 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MOD15A2/2007/MYD15A2.A2007241.h12v09.005.2007256053902.hdf":MOD_Grid_MOD15A2:Lai_1km
294 + * @return the string of coverage identifier.
297 +string AbstractDataset::GetCoverageID()
299 + return ms_CoverageID;
302 +/************************************************************************/
303 +/* GetResourceFileName() */
304 +/************************************************************************/
307 + * \brief Fetch the resource file name of a coverage.
309 + * The method will return the full path corresponding the file contained
312 + * @return the string of resource file path.
315 +string AbstractDataset::GetResourceFileName()
317 + return ms_SrcFilename;
320 +/************************************************************************/
321 +/* GetDatasetName() */
322 +/************************************************************************/
325 + * \brief Fetch the dataset name of a coverage.
327 + * The method will return the data set name corresponding the file contained
328 + * coverage. For example, MOD09GQ data has the coverage identifier as following;
329 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
331 + * sur_refl_b01_1 is seemed as the dataset name.
333 + * @return the string of dataset name.
336 +string AbstractDataset::GetDatasetName()
338 + return ms_DatasetName;
341 +/************************************************************************/
342 +/* GetDataTypeName() */
343 +/************************************************************************/
346 + * \brief Fetch the dataset type name of a coverage.
348 + * The method will return the data set name corresponding the file contained
349 + * coverage. For example, MOD09GQ data has the coverage identifier as following;
350 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
352 + * MODIS_Grid_2D is seemed as the dataset type name.
354 + * @return the string of dataset type name.
357 +string AbstractDataset::GetDataTypeName()
359 + return ms_DataTypeName;
362 +/************************************************************************/
363 +/* GetDataTypeName() */
364 +/************************************************************************/
367 + * \brief Fetch the dataset description of a coverage.
369 + * The method will build a description for the coverage. The coverage
370 + * extent, dataset name, dataset type name will be contained in the
373 + * @return the string of dataset description.
376 +string AbstractDataset::GetDatasetDescription()
378 + //[15x2030x1354] Band JPEG2000 (16-bit unsigned integer)
381 + int nBandCount = maptr_DS->GetRasterCount();
383 + if (nBandCount > 1)
385 + aiDimSizes[0] = nBandCount;
386 + aiDimSizes[1] = GetImageYSize();
387 + aiDimSizes[2] = GetImageXSize();
388 + pszString = SPrintArray(GDT_UInt32, aiDimSizes, 3, "x");
392 + aiDimSizes[0] = GetImageYSize();
393 + aiDimSizes[1] = GetImageXSize();
394 + pszString = SPrintArray(GDT_UInt32, aiDimSizes, 2, "x");
397 + rtnBuf = "[" + pszString + "] " + ms_DatasetName + " " + ms_DataTypeName + " (" +
398 + GDALGetDataTypeName(maptr_DS->GetRasterBand(1)->GetRasterDataType()) + ")";
403 +/************************************************************************/
404 +/* GetNativeFormat() */
405 +/************************************************************************/
408 + * \brief Fetch the native format of a coverage.
410 + * The method will return the native format of a coverage. GDAL API
411 + * GDALGetDriverShortName() will be called to generate the format.
413 + * @return the string of dataset native format, in forms of GDAL Formats
414 + * Code. See http://gdal.org/formats_list.html for details.
417 +string AbstractDataset::GetNativeFormat()
419 + return ms_NativeFormat;
422 +/************************************************************************/
423 +/* IsbGeoTransformSet() */
424 +/************************************************************************/
427 + * \brief Determine whether set the affine geoTransform for a coverage.
429 + * The method will return the status of the affine GeoTransform matrix.
431 + * @return TRUE if set already or FALSE on failure..
434 +int AbstractDataset::IsbGeoTransformSet()
436 + return mb_GeoTransformSet;
439 +/************************************************************************/
440 +/* GetNativeBBox() */
441 +/************************************************************************/
444 + * \brief Fetch the bounding box of a coverage under the native CRS.
446 + * The method will fetch the bounding box of the coverage under native CRS.
447 + * The sequence of values stored in array is: xmin, xmax, ymin, ymax
449 + * @param bBox an existing four double buffer into which the
450 + * native bounding box values will be placed.
453 +void AbstractDataset::GetNativeBBox(double bBox[])
455 + if (mb_GeoTransformSet)
457 + bBox[0] = md_Geotransform[0];
458 + bBox[1] = bBox[0] + GetImageXSize() * md_Geotransform[1];
459 + bBox[3] = md_Geotransform[3];
460 + bBox[2] = bBox[3] + GetImageYSize() * md_Geotransform[5];
465 + bBox[1] = maptr_DS->GetRasterXSize() - 1;
467 + bBox[3] = maptr_DS->GetRasterYSize() - 1;
471 +/************************************************************************/
472 +/* GetGeoMinMax() */
473 +/************************************************************************/
476 + * \brief Fetch the bounding box of a coverage under EPSG:4326.
478 + * The method will fetch the bounding box of the coverage under EPSG:4326
479 + * CRS. The sequence of values stored in array is: xmin, xmax, ymin, ymax
481 + * @param bBox an existing four double buffer into which the geographic
482 + * bounding box values will be placed.
484 + * @return CE_None on success or CE_Failure on failure.
487 +CPLErr AbstractDataset::GetGeoMinMax(double geoMinMax[])
489 + if (!mb_GeoTransformSet)
491 + SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
492 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to get Geo-BoundingBox coordinates");
496 + geoMinMax[0] = md_Geotransform[0];
497 + geoMinMax[1] = geoMinMax[0] + GetImageXSize() * md_Geotransform[1];
498 + geoMinMax[3] = md_Geotransform[3];
499 + geoMinMax[2] = geoMinMax[3] + GetImageYSize() * md_Geotransform[5];
502 + if (mo_NativeCRS.IsGeographic() || Find_Compare_SubStr(ms_DataTypeName, "MODIS"))//for modis data
504 + geoMinMax[0] = (geoMinMax[0] >= -180.0) ? geoMinMax[0] : -180.0;
505 + geoMinMax[1] = (geoMinMax[1] <= 180.0) ? geoMinMax[1] : 180.0;
506 + geoMinMax[2] = (geoMinMax[2] >= -90.0) ? geoMinMax[2] : -90.0;
507 + geoMinMax[3] = (geoMinMax[3] <= 90.0) ? geoMinMax[3] : 90.0;
511 + OGRSpatialReference oGeoSRS;
512 + oGeoSRS.CopyGeogCSFrom(&mo_NativeCRS);
514 + My2DPoint llPt(geoMinMax[0], geoMinMax[2]);
515 + My2DPoint urPt(geoMinMax[1], geoMinMax[3]);
516 + if (CE_None != bBox_transFormmate(mo_NativeCRS, oGeoSRS, llPt, urPt))
518 + SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
519 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to transform bounding box coordinates to geographic coordinates.");
523 + geoMinMax[0] = llPt.mi_X;
524 + geoMinMax[1] = urPt.mi_X;
525 + geoMinMax[2] = llPt.mi_Y;
526 + geoMinMax[3] = urPt.mi_Y;
532 +/************************************************************************/
533 +/* GetImageXSize() */
534 +/************************************************************************/
537 + * \brief Fetch coverage width in pixels.
539 + * The method will return the width of coverage in pixels. GDAL API
540 + * GetRasterXSize() will be called to generate the width value.
542 + * @return the width in pixels of raster bands in this coverage.
545 +int AbstractDataset::GetImageXSize()
547 + return maptr_DS->GetRasterXSize();
550 +/************************************************************************/
551 +/* GetImageYSize() */
552 +/************************************************************************/
555 + * \brief Fetch coverage height in pixels.
557 + * The method will return the height of coverage in pixels. GDAL API
558 + * GetRasterYSize() will be called to generate the height value.
560 + * @return the height in pixels of raster bands in this coverage.
562 +int AbstractDataset::GetImageYSize()
564 + return maptr_DS->GetRasterYSize();
567 +/************************************************************************/
568 +/* GetCoverageBeginTime() */
569 +/************************************************************************/
572 + * \brief Fetch the begin date/time of a coverage.
574 + * The method will return the begin date/time of a coverage. For MODIS data,
575 + * each granule will cover a range of time; for TRMM data, the daily data
576 + * will cover a whole day, and monthly data will cover a whole month.
578 + * @return the string of begin date/time corresponding to the coverage.
581 +string AbstractDataset::GetCoverageBeginTime()
583 + return ms_CoverageBeginTime;
586 +/************************************************************************/
587 +/* GetCoverageBeginTime() */
588 +/************************************************************************/
591 + * \brief Fetch the end date/time of a coverage.
593 + * The method will return the end date/time of a coverage. For MODIS data,
594 + * each granule will cover a range of time; for TRMM data, the daily data
595 + * will cover a whole day, and monthly data will cover a whole month.
597 + * @return the string of end date/time corresponding to the coverage.
600 +string AbstractDataset::GetCoverageEndTime()
602 + return ms_CoverageEndTime;
605 +/************************************************************************/
606 +/* getCoverageSubType() */
607 +/************************************************************************/
610 + * \brief Fetch the coverage type.
612 + * The method will return the type of the coverage, such as
613 + * "ReferenceableDataset" and "RectifiedDataset".
615 + * @return the string of coverage type.
618 +string AbstractDataset::GetCoverageSubType()
620 + return ms_CoverageSubType;
623 +/************************************************************************/
624 +/* getFieldQuantityDef() */
625 +/************************************************************************/
628 + * \brief Fetch the field units of a coverage.
630 + * The method will return the field units of coverage. For example to
631 + * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, units equals
634 + * @return the string of coverage field units.
637 +string AbstractDataset::GetFieldQuantityDef()
639 + return ms_FieldQuantityDef;
642 +/************************************************************************/
643 +/* GetAllowValues() */
644 +/************************************************************************/
647 + * \brief Fetch the allow values of a coverage.
649 + * The method will return the valid range of a coverage. For example to
650 + * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, valid_range
651 + * equals to (-100, 16000).
653 + * @return the string of valid range of a coverage, in the forms of "min, max".
656 +string AbstractDataset::GetAllowValues()
658 + return ms_AllowRanges;
661 +/************************************************************************/
662 +/* GetISO19115Metadata() */
663 +/************************************************************************/
666 + * \brief Fetch the coverage metadata which is compliant to ISO 19115:2003
667 + * - GeoGraphic information -- Metadata; and ISO 19115(2):2009 - GeoGraphic
668 + * information -- Metadata -- Part 2.
670 + * The method will return the metadata of a coverage based on ISO 19115
671 + * and ISO 19115(2).
673 + * ISO 19115:2003 defines the schema required for
674 + * describing geographic information and services. It provides information
675 + * about the identification, the extent, the quality, the spatial and temporal
676 + * schema, spatial reference, and distribution of digital geographic data.
678 + * ISO 19115-2:2009 extends the existing geographic metadata standard by
679 + * defining the schema required for describing imagery and gridded data.
680 + * It provides information about the properties of the measuring equipment
681 + * used to acquire the data, the geometry of the measuring process employed
682 + * by the equipment, and the production process used to digitize the raw data.
683 + * This extension deals with metadata needed to describe the derivation of
684 + * geographic information from raw data, including the properties of the
685 + * measuring system, and the numerical methods and computational procedures
686 + * used in the derivation. The metadata required to address coverage data in
687 + * general is addressed sufficiently in the general part of ISO 19115.
689 + * @return the string of metadata of a coverage.
692 +string AbstractDataset::GetISO19115Metadata()
694 + return ms_ISO19115Metadata;
697 +/************************************************************************/
698 +/* GetCoverageArchiveTime() */
699 +/************************************************************************/
702 + * \brief Fetch the archive date/time of this dataset.
704 + * The method will return the archive date/time of dataset (granule).
706 + * @return The string of archive date/time.
709 +string AbstractDataset::GetCoverageArchiveTime()
711 + return ms_CoverageArchiveTime;
714 +/************************************************************************/
715 +/* GetCoveragePlatform() */
716 +/************************************************************************/
719 + * \brief Fetch the platform name of this dataset.
721 + * The method will return the platform name of dataset (granule).
723 + * @return The string of platform name.
726 +string AbstractDataset::GetCoveragePlatform()
728 + return ms_CoveragePlatform;
731 +/************************************************************************/
732 +/* GetCoverageInstrument() */
733 +/************************************************************************/
736 + * \brief Fetch the instrument name of this dataset.
738 + * The method will return the instrument name of dataset (granule).
740 + * @return The string of instrument name.
743 +string AbstractDataset::GetCoverageInstrument()
745 + return ms_CoverageInstrument;
748 +/************************************************************************/
749 +/* GetCoverageInstrument() */
750 +/************************************************************************/
753 + * \brief Fetch the sensor name of this dataset.
755 + * The method will return the sensor name of dataset (granule).
757 + * @return The string of sensor name.
760 +string AbstractDataset::GetCoverageSensor()
762 + return ms_CoverageSensor;
765 +/************************************************************************/
766 +/* GetImageBandCount() */
767 +/************************************************************************/
770 + * \brief Fetch the number of raster bands on this dataset.
772 + * The method will return the number of raster bands on this dataset. GDAL
773 + * API GetRasterCount() will be called to get the count number.
775 + * @return the number of raster bands on this dataset.
778 +int AbstractDataset::GetImageBandCount()
780 + return maptr_DS->GetRasterCount();
783 +/************************************************************************/
784 +/* getMissingValue() */
785 +/************************************************************************/
788 + * \brief Fetch the filled value (missing value) of a coverage.
790 + * The method will return the filled value of a coverage.
792 + * @return the value of filled value of a coverage.
795 +const double& AbstractDataset::GetMissingValue()
797 + return md_MissingValue;
800 +/************************************************************************/
801 +/* GetProjectionRef() */
802 +/************************************************************************/
805 + * \brief Fetch the native projection reference of a coverage.
807 + * The method will return the the native projection reference of a coverage.
809 + * @return the string of the native projection reference of a coverage.
812 +string AbstractDataset::GetProjectionRef()
814 + char* pszProjection = NULL;
815 + mo_NativeCRS.exportToWkt(&pszProjection);
816 + string tmpStr = pszProjection;
817 + CPLFree(pszProjection);
822 +/************************************************************************/
823 +/* SetMetaDataList() */
824 +/************************************************************************/
827 + * \brief Set the metadata list for this coverage based on dataset object.
829 + * The method will set the metadata list for the coverage based on its
830 + * corresponding GDALDataset object. Will be implemented in the subclasses
831 + * of AbstractDataset.
833 + * @param hSrc the GDALDataset object corresponding to coverage.
835 + * @return CE_Failure.
838 +CPLErr AbstractDataset::SetMetaDataList(GDALDataset* hSrc)
843 +/************************************************************************/
844 +/* GetMetaDataList() */
845 +/************************************************************************/
848 + * \brief Fetch the metadata list for this coverage.
850 + * The method will return the metadata list for the coverage.
852 + * @return the list of metadate.
855 +vector<string> AbstractDataset::GetMetaDataList()
857 + return mv_MetaDataList;
860 +/************************************************************************/
862 +/************************************************************************/
865 + * \brief Fetch the contained band list of request coverage.
867 + * The method will return the contained band list of request coverage.
869 + * @return the band array.
872 +vector<int> AbstractDataset::GetBandList()
874 + return mv_BandList;
877 +/************************************************************************/
878 +/* getNativeCRS_URN() */
879 +/************************************************************************/
882 + * \brief Fetch the native CRS code of coverage.
884 + * The method will return the native CRS code of coverage.
886 + * @return the string of the URN for native CRS of coverage.
889 +string AbstractDataset::GetNativeCRS_URN()
893 + if (mo_NativeCRS.IsProjected())
895 + const char* nativeAuthorityName =
896 + mo_NativeCRS.GetAuthorityName("PROJCS");
897 + const char* nativeAuthorityCode =
898 + mo_NativeCRS.GetAuthorityCode("PROJCS");
900 + urn = "urn:ogc:def:crs:";
902 + if (nativeAuthorityName && (EQUAL(nativeAuthorityName,"EPSG")
903 + || EQUAL(nativeAuthorityName,"OGP")
904 + || EQUAL(nativeAuthorityName,"OGC")))
905 + urn += (string) nativeAuthorityName + (string) ":6.3:";
907 + urn += "CSISS:0.0:";
909 + if (nativeAuthorityCode)
910 + urn += (string) nativeAuthorityCode;
914 + else if (mo_NativeCRS.IsGeographic())
916 + const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
917 + const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
919 + urn = "urn:ogc:def:crs:";
920 + if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
921 + || EQUAL(geoAuthorityName,"OGP")
922 + || EQUAL(geoAuthorityName,"OGC")))
923 + urn += (string) geoAuthorityName + (string) ":6.3:";
925 + urn += "CSISS:0.0:";
927 + if (geoAuthorityCode)
928 + urn += (string) geoAuthorityCode;
933 + urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
938 +/************************************************************************/
939 +/* GetGeoCRS_URN() */
940 +/************************************************************************/
943 + * \brief Fetch the Geographic CRS code of coverage.
945 + * The method will return the Geographic CRS code of coverage.
947 + * @return the URN for Geographic CRS of coverage.
950 +string AbstractDataset::GetGeoCRS_URN()
954 + if (mo_NativeCRS.IsProjected() || mo_NativeCRS.IsGeographic())
956 + const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
957 + const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
959 + urn = "urn:ogc:def:crs:";
960 + if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
961 + || EQUAL(geoAuthorityName,"OGP")
962 + || EQUAL(geoAuthorityName,"OGC")))
963 + urn += (string) geoAuthorityName + (string) ":6.3:";
965 + urn += "CSISS:0.0:";
967 + if (geoAuthorityCode)
968 + urn += (string) geoAuthorityCode;
974 + urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
979 +/************************************************************************/
980 +/* IsCrossingIDL() */
981 +/************************************************************************/
984 + * \brief Determine whether the extend of coverage cross the International
987 + * The method will return the status of whether the extend of coverage
988 + * cross the International Date Line (IDL).
990 + * @return the TRUE of the coverage extent cross the IDL, otherwise FALSE.
993 +int AbstractDataset::IsCrossingIDL()
995 + double bboxArray[4];
996 + GetNativeBBox(bboxArray);
998 + OGRSpatialReference latlonSRS;
999 + latlonSRS.SetWellKnownGeogCS("WGS84");
1000 + My2DPoint llPtex(bboxArray[0], bboxArray[2]);
1001 + My2DPoint urPtex(bboxArray[1], bboxArray[3]);
1002 + bBox_transFormmate(mo_NativeCRS, latlonSRS, llPtex, urPtex);
1004 + int bCrossCenter = false;
1005 + if(urPtex.mi_X < 0 && llPtex.mi_X > 0)
1006 + bCrossCenter = true;
1008 + return bCrossCenter;
1011 +/************************************************************************/
1012 +/* GetSuggestedWarpResolution() */
1013 +/************************************************************************/
1016 + * \brief Get the suggested warp option, method 1.
1018 + * @return CE_Failure if an error occurs, otherwise CE_None.
1021 +CPLErr AbstractDataset::GetSuggestedWarpResolution( OGRSpatialReference& dstCRS,
1022 + double adfDstGeoTransform[],
1026 + if (!dstCRS.IsProjected() && !dstCRS.IsGeographic())
1028 + adfDstGeoTransform[0] = 0;
1029 + adfDstGeoTransform[1] = 1;
1030 + adfDstGeoTransform[2] = 0;
1031 + adfDstGeoTransform[3] = 0;
1032 + adfDstGeoTransform[4] = 0;
1033 + adfDstGeoTransform[5] = 1;
1035 + nPixels = GetImageXSize();
1036 + nLines = GetImageYSize();
1039 + else if (dstCRS.IsSame(&mo_NativeCRS))
1041 + memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
1042 + nPixels = GetImageXSize();
1043 + nLines = GetImageYSize();
1048 + dstCRS.exportToWkt(&pszDstWKT);
1050 + mo_NativeCRS.exportToWkt(&pszSrcWKT);
1052 + void *hTransformArg = GDALCreateGenImgProjTransformer(maptr_DS.get(),
1053 + (const char*) pszSrcWKT, NULL, (const char*) pszDstWKT, TRUE, 1000.0, 0);
1054 + OGRFree(pszDstWKT);
1055 + OGRFree(pszSrcWKT);
1056 + if (hTransformArg == NULL)
1058 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
1059 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create GDAL GenImgProjTransformer.");
1061 + return CE_Failure;
1063 + /* -------------------------------------------------------------------- */
1064 + /* Get approximate output definition. */
1065 + /* -------------------------------------------------------------------- */
1066 + if (GDALSuggestedWarpOutput(maptr_DS.get(), GDALGenImgProjTransform,
1067 + hTransformArg, adfDstGeoTransform, &nPixels, &nLines) != CE_None)
1069 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
1070 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Computing Output Resolution.");
1072 + return CE_Failure;
1075 + GDALDestroyGenImgProjTransformer(hTransformArg);
1081 +/************************************************************************/
1082 +/* GetSuggestedWarpResolution2() */
1083 +/************************************************************************/
1086 + * \brief Get the suggested warp option, method 2.
1088 + * @return CE_Failure if an error occurs, otherwise CE_None.
1091 +CPLErr AbstractDataset::GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS,
1092 + double adfDstGeoTransform[],
1096 + if (dstCRS.IsLocal())
1098 + adfDstGeoTransform[0] = 0;
1099 + adfDstGeoTransform[1] = 1;
1100 + adfDstGeoTransform[2] = 0;
1101 + adfDstGeoTransform[3] = 0;
1102 + adfDstGeoTransform[4] = 0;
1103 + adfDstGeoTransform[5] = 1;
1105 + nPixels = GetImageXSize();
1106 + nLines = GetImageYSize();
1108 + else if (dstCRS.IsSame(&mo_NativeCRS))
1110 + memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
1111 + nPixels = GetImageXSize();
1112 + nLines = GetImageYSize();
1116 + double bboxArray[4];
1117 + GetNativeBBox(bboxArray);
1119 + My2DPoint llPt(bboxArray[0], bboxArray[2]);
1120 + My2DPoint urPt(bboxArray[1], bboxArray[3]);
1121 + if (CE_None != bBox_transFormmate(mo_NativeCRS, dstCRS, llPt, urPt))
1123 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution2()");
1124 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform bounding box Coordinate.");
1125 + return CE_Failure;
1128 + double xRes, yRes;
1129 + if(IsCrossingIDL())
1131 + yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
1132 + xRes = fabs((llPt.mi_X - urPt.mi_X) / GetImageXSize());
1133 + nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
1134 + nPixels = fabs((llPt.mi_X - urPt.mi_X) / xRes + 0.5);
1137 + xRes = (urPt.mi_X - llPt.mi_X) / GetImageXSize();
1138 + yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
1139 + nPixels = (urPt.mi_X - llPt.mi_X) / xRes + 0.5;
1140 + nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
1143 + xRes = MIN(xRes,yRes);
1144 + yRes = MIN(xRes,yRes);
1146 + adfDstGeoTransform[0] = llPt.mi_X;
1147 + adfDstGeoTransform[1] = xRes;
1148 + adfDstGeoTransform[2] = 0;
1149 + adfDstGeoTransform[3] = urPt.mi_Y;
1150 + adfDstGeoTransform[4] = 0;
1151 + adfDstGeoTransform[5] = -yRes;
1157 +/************************************************************************/
1158 +/* DatasetWarper() */
1159 +/************************************************************************/
1162 + * Wrap the dataset to a GDALDataset object based on input parameters.
1164 + * @return the warpped GDALDataset object.
1166 +/************************************************************************/
1167 +/* DatasetWarper() */
1168 +/************************************************************************/
1171 + * \brief Wrap the dataset to a GDALDataset object based on input parameters.
1173 + * @return GDALDatset object.
1176 +GDALDataset* AbstractDataset::DatasetWarper(int& IsRefDS,
1177 + OGRSpatialReference& dstCRS,
1178 + int& iDstRasterXsize,
1179 + int& iDstRasterYsize,
1180 + double pDstGeoTransform[],
1181 + GDALResampleAlg eResampleAlg)
1183 + OGRSpatialReference locCRS=dstCRS;
1184 + if (dstCRS.IsLocal())
1185 + locCRS=mo_NativeCRS;
1187 + if((mo_NativeCRS.IsSame(&locCRS) &&
1188 + iDstRasterXsize == maptr_DS->GetRasterXSize() &&
1189 + iDstRasterYsize == maptr_DS->GetRasterYSize())&&
1190 + CPLIsEqual(md_Geotransform[0],pDstGeoTransform[0])&&
1191 + CPLIsEqual(md_Geotransform[1],pDstGeoTransform[1])&&
1192 + CPLIsEqual(md_Geotransform[3],pDstGeoTransform[3])&&
1193 + CPLIsEqual(md_Geotransform[5],pDstGeoTransform[5]))
1196 + return maptr_DS.get();
1199 + char *sDstCRS_WKT;
1200 + locCRS.exportToWkt(&sDstCRS_WKT);
1202 + /* Create a memory data-set for re-projection */
1203 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
1205 + int nBand = maptr_DS->GetRasterCount();
1206 + GDALDataset* hMemDS = (GDALDataset*) GDALCreate(poDriver, "", iDstRasterXsize,
1207 + iDstRasterYsize, nBand, GDALGetRasterDataType(maptr_DS->GetRasterBand(1)), NULL);
1208 + if (NULL == hMemDS)
1210 + GDALClose(poDriver);
1211 + OGRFree(sDstCRS_WKT);
1215 + hMemDS->SetProjection(sDstCRS_WKT);
1216 + hMemDS->SetGeoTransform(pDstGeoTransform);
1218 + for (int i = 1; i <= nBand; i++)
1220 + hMemDS->GetRasterBand(i)->SetNoDataValue(md_MissingValue);
1223 + /* -------------------------------------------------------------------- */
1224 + /* Perform the re-projection. */
1225 + /* -------------------------------------------------------------------- */
1227 + mo_NativeCRS.exportToWkt(&srcWKT);
1228 + if (CE_None != GDALReprojectImage(maptr_DS.get(), srcWKT, hMemDS,
1229 + sDstCRS_WKT, eResampleAlg, 0, 0.125, NULL, NULL, NULL))
1231 + GDALClose(poDriver);
1232 + GDALClose(GDALDatasetH(hMemDS));
1233 + OGRFree(sDstCRS_WKT);
1238 + OGRFree(sDstCRS_WKT);
1243 diff -Nur bes-3.12.0/functions.orig/swath2grid/AbstractDataset.h bes-3.12.0/functions/swath2grid/AbstractDataset.h
1244 --- bes-3.12.0/functions.orig/swath2grid/AbstractDataset.h 1970-01-01 01:00:00.000000000 +0100
1245 +++ bes-3.12.0/functions/swath2grid/AbstractDataset.h 2014-03-03 15:47:38.050232928 +0100
1247 +/******************************************************************************
1248 + * $Id: AbstractDataset.h 2011-07-19 16:24:00Z $
1250 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
1251 + * for Earth Observation: Open Source Reference Implementation
1252 + * Purpose: AbstractDataset class definition
1253 + * Author: Yuanzheng Shao, yshao3@gmu.edu
1255 + ******************************************************************************
1256 + * * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
1258 + * Permission is hereby granted, free of charge, to any person obtaining a
1259 + * copy of this software and associated documentation files (the "Software"),
1260 + * to deal in the Software without restriction, including without limitation
1261 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1262 + * and/or sell copies of the Software, and to permit persons to whom the
1263 + * Software is furnished to do so, subject to the following conditions:
1265 + * The above copyright notice and this permission notice shall be included
1266 + * in all copies or substantial portions of the Software.
1268 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1269 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1270 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1271 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1272 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1273 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1274 + * DEALINGS IN THE SOFTWARE.
1275 + ****************************************************************************/
1277 +#ifndef ABSTRACTDATASET_H_
1278 +#define ABSTRACTDATASET_H_
1284 +#include <gdal_priv.h>
1285 +#include <gdalwarper.h>
1286 +#include <ogrsf_frmts.h>
1287 +#include <ogr_spatialref.h>
1288 +#include <cpl_conv.h>
1289 +#include <cpl_minixml.h>
1290 +#include <vrtdataset.h>
1292 +#include "wcsUtil.h"
1294 +using namespace std;
1296 +/* ******************************************************************** */
1297 +/* AbstractDataset */
1298 +/* ******************************************************************** */
1300 +//! Abstract dataset model definition. Based on GDAL dataset model.
1301 +class AbstractDataset {
1304 + auto_ptr<GDALDataset> maptr_DS;
1306 + // Coverage Information Related
1307 + string ms_CoverageID;
1308 + string ms_CoverageBeginTime;
1309 + string ms_CoverageEndTime;
1310 + string ms_CoverageSubType;
1311 + string ms_CoverageArchiveTime;
1312 + string ms_CoveragePlatform;
1313 + string ms_CoverageInstrument;
1314 + string ms_CoverageSensor;
1315 + string ms_SrcFilename;
1316 + string ms_DatasetName;
1317 + string ms_DataTypeName;
1318 + string ms_NativeFormat;
1319 + string ms_FieldQuantityDef;
1320 + string ms_AllowRanges;
1321 + string ms_ISO19115Metadata;
1323 + vector<int> mv_BandList;
1324 + vector<string> mv_MetaDataList;
1326 + double md_Geotransform[6];
1327 + double md_GeoMinMax[4]; // Order: xmin, xmax, ymin, ymax
1328 + double md_MissingValue;
1330 + int mb_GeoTransformSet;
1331 + int mb_IsVirtualDS;
1333 + OGRSpatialReference mo_NativeCRS;
1336 + AbstractDataset();
1337 + virtual CPLErr SetNativeCRS();
1338 + virtual CPLErr SetGeoTransform();
1339 + virtual CPLErr SetGDALDataset(const int isSimple = 0);
1340 + virtual CPLErr SetMetaDataList(GDALDataset*);
1343 + AbstractDataset(const string&, vector<int> &);
1344 + virtual ~AbstractDataset();
1346 + GDALDataset* GetGDALDataset();
1348 + // Virtual Functions Definition
1349 + virtual CPLErr InitialDataset(const int isSimple = 0);
1351 + // Fetch Function Related
1352 + const OGRSpatialReference& GetNativeCRS();
1353 + const double& GetMissingValue();
1354 + int GetGeoTransform(double geoTrans[]);
1355 + vector<string> GetMetaDataList();
1356 + vector<int> GetBandList();
1357 + void GetNativeBBox(double bBox[]);
1358 + CPLErr GetGeoMinMax(double geoMinMax[]);
1360 + int GetImageBandCount();
1361 + int GetImageXSize();
1362 + int GetImageYSize();
1363 + string GetResourceFileName();
1364 + string GetDatasetName();
1365 + string GetDataTypeName();
1366 + string GetNativeFormat();
1367 + string GetCoverageID();
1368 + string GetDatasetDescription();
1369 + string GetNativeCRS_URN();
1370 + string GetGeoCRS_URN();
1371 + string GetProjectionRef();
1372 + string GetCoverageBeginTime();
1373 + string GetCoverageEndTime();
1374 + string GetCoverageSubType();
1375 + string GetFieldQuantityDef();
1376 + string GetAllowValues();
1377 + string GetISO19115Metadata();
1378 + string GetCoverageArchiveTime();
1379 + string GetCoveragePlatform();
1380 + string GetCoverageInstrument();
1381 + string GetCoverageSensor();
1383 + // Fetch Variables Status Related
1384 + int IsbGeoTransformSet();
1385 + int IsCrossingIDL();
1387 + CPLErr GetSuggestedWarpResolution(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
1389 + CPLErr GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
1392 + GDALDataset* DatasetWarper(int& IsRefDS, OGRSpatialReference& dstCRS, int& iDstRasterXsize, int& iDstRasterYsize,
1393 + double pDstGeoTransform[], GDALResampleAlg eResampleAlg = GRA_NearestNeighbour);
1396 +#endif /*ABSTRACTDATASET_H_*/
1397 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
1398 --- bes-3.12.0/functions.orig/swath2grid/airs.nc.0.data.bescmd 1970-01-01 01:00:00.000000000 +0100
1399 +++ bes-3.12.0/functions/swath2grid/airs.nc.0.data.bescmd 2014-03-03 15:47:38.050232928 +0100
1401 +<?xml version="1.0" encoding="UTF-8"?>
1402 +<request reqID ="some_unique_value" >
1403 + <setContext name="dap_format">dap2</setContext>
1404 + <setContext name="xdap_accept">3.3</setContext>
1405 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
1407 + <container name="c">
1408 + <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
1411 + <get type="dods" definition="d"/>
1414 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
1415 --- bes-3.12.0/functions.orig/swath2grid/airs.nc.0.ddx.bescmd 1970-01-01 01:00:00.000000000 +0100
1416 +++ bes-3.12.0/functions/swath2grid/airs.nc.0.ddx.bescmd 2014-03-03 15:47:38.053566262 +0100
1418 +<?xml version="1.0" encoding="UTF-8"?>
1419 +<request reqID ="some_unique_value" >
1420 + <setContext name="dap_format">dap2</setContext>
1421 + <setContext name="xdap_accept">3.3</setContext>
1422 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
1424 + <container name="c">
1425 + <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
1428 + <get type="das" definition="d"/>
1431 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
1432 --- bes-3.12.0/functions.orig/swath2grid/airs.nc.1.err.bescmd 1970-01-01 01:00:00.000000000 +0100
1433 +++ bes-3.12.0/functions/swath2grid/airs.nc.1.err.bescmd 2014-03-03 15:47:38.043566262 +0100
1435 +<?xml version="1.0" encoding="UTF-8"?>
1436 +<request reqID ="some_unique_value" >
1437 + <setContext name="dap_format">dap2</setContext>
1438 + <setContext name="xdap_accept">3.3</setContext>
1439 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
1441 + <container name="c">
1442 + <constraint>swath2grid()</constraint>
1445 + <get type="dods" definition="d"/>
1448 diff -Nur bes-3.12.0/functions.orig/swath2grid/bes.conf.in bes-3.12.0/functions/swath2grid/bes.conf.in
1449 --- bes-3.12.0/functions.orig/swath2grid/bes.conf.in 1970-01-01 01:00:00.000000000 +0100
1450 +++ bes-3.12.0/functions/swath2grid/bes.conf.in 2014-03-03 15:47:38.050232928 +0100
1452 +BES.ServerAdministrator=root@null.dev
1455 +BES.Group=group_name
1457 +BES.LogName=./bes.log
1460 +BES.modules=dap,cmd,nc,h4,fong,fonc
1461 +BES.module.dap=@libdir@/bes/libdap_module.so
1462 +BES.module.cmd=@libdir@/bes/libdap_xml_module.so
1464 +BES.module.nc=@libdir@/bes/libnc_module.so
1465 +BES.module.h4=@libdir@/bes/libhdf4_module.so
1467 +BES.module.fong=@libdir@/bes/libfong_module.so
1468 +BES.module.fonc=@libdir@/bes/libfonc_module.so
1470 +BES.Catalog.catalog.RootDirectory=@abs_top_srcdir@
1471 +BES.Data.RootDirectory=/dev/null
1473 +BES.Catalog.catalog.TypeMatch=nc:.*.nc(.bz2|.gz|.Z)?$;h4:.*.(hdf|HDF|eos)(.bz2|.gz|.Z)?$;
1475 +BES.Catalog.catalog.Include=;
1476 +BES.Catalog.catalog.Exclude=^\..*;
1478 +BES.FollowSymLinks=No
1479 +BES.Catalog.catalog.FollowSymLinks=No
1481 +BES.ServerPort=10002
1484 +BES.CachePrefix=bes_cache
1487 +BES.Container.Persistence=strict
1489 +BES.Memory.GlobalArea.EmergencyPoolSize=1
1490 +BES.Memory.GlobalArea.MaximumHeapSize=20
1491 +BES.Memory.GlobalArea.Verbose=no
1492 +BES.Memory.GlobalArea.ControlHeap=no
1494 +BES.ProcessManagerMethod=multiple
1496 +BES.DefaultResponseMethod=POST
1498 +FONg.TempDirectory=@abs_top_srcdir@/tests
1500 diff -Nur bes-3.12.0/functions.orig/swath2grid/BoundingBox.cpp bes-3.12.0/functions/swath2grid/BoundingBox.cpp
1501 --- bes-3.12.0/functions.orig/swath2grid/BoundingBox.cpp 1970-01-01 01:00:00.000000000 +0100
1502 +++ bes-3.12.0/functions/swath2grid/BoundingBox.cpp 2014-03-03 15:47:38.050232928 +0100
1504 +/******************************************************************************
1505 + * $Id: BoundingBox.cpp 2011-07-19 16:24:00Z $
1507 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
1508 + * for Earth Observation: Open Source Reference Implementation
1509 + * Purpose: BoundingBox class implementation, enable transform bounding box
1510 + * between different CRS
1511 + * Author: Yuanzheng Shao, yshao3@gmu.edu
1513 + ******************************************************************************
1514 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
1516 + * Permission is hereby granted, free of charge, to any person obtaining a
1517 + * copy of this software and associated documentation files (the "Software"),
1518 + * to deal in the Software without restriction, including without limitation
1519 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1520 + * and/or sell copies of the Software, and to permit persons to whom the
1521 + * Software is furnished to do so, subject to the following conditions:
1523 + * The above copyright notice and this permission notice shall be included
1524 + * in all copies or substantial portions of the Software.
1526 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1527 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1528 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1529 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1530 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1531 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1532 + * DEALINGS IN THE SOFTWARE.
1533 + ****************************************************************************/
1536 +#include <iostream>
1538 +#include "BoundingBox.h"
1539 +#include "wcs_error.h"
1541 +using namespace std;
1543 +My2DPoint::~My2DPoint()
1548 +BoundingBox::BoundingBox()
1553 +BoundingBox::~BoundingBox()
1558 +BoundingBox BoundingBox::TransformWorkExtend(OGRSpatialReference &dstCRS, int &IsOK)
1560 + if (mo_CRS.IsSame(&dstCRS))
1566 + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&mo_CRS, &dstCRS);
1573 + double xdes = (mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
1575 + if (mo_CRS.IsGeographic()
1576 + && mo_UpperRightPT.mi_X < mo_LowerLeftPT.mi_X
1577 + && mo_LowerLeftPT.mi_X > 0 && mo_UpperRightPT.mi_X < 0)
1579 + xdes = (360 + mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
1584 + //up and down edge
1585 + for (double stepX = mo_LowerLeftPT.mi_X; stepX < mo_UpperRightPT.mi_X; stepX
1588 + x.push_back(stepX);
1589 + y.push_back(mo_UpperRightPT.mi_Y);
1590 + x.push_back(stepX);
1591 + y.push_back(mo_LowerLeftPT.mi_Y);
1593 + x.push_back(mo_UpperRightPT.mi_X);
1594 + y.push_back(mo_UpperRightPT.mi_Y);
1595 + x.push_back(mo_UpperRightPT.mi_X);
1596 + y.push_back(mo_LowerLeftPT.mi_Y);
1598 + double yMin = numeric_limits<double>::max();
1599 + double yMax = numeric_limits<double>::min();
1602 + vector<int> bSuccess;
1603 + vector<double> tmpX;
1604 + vector<double> tmpY;
1606 + for (unsigned int i = 0; i < x.size(); i++)
1608 + tmpX.push_back(x[i]);
1609 + tmpY.push_back(y[i]);
1610 + bSuccess.push_back(0);
1613 + poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
1615 + for (unsigned int n = 0; n < x.size(); n++)
1620 + yMin = MIN(yMin,tmpY[n]);
1621 + yMax = MAX(yMax,tmpY[n]);
1628 + OCTDestroyCoordinateTransformation(poCT);
1632 + //find xmin on left edge and xmax on right edge
1641 + tmpPTX[0] = mo_LowerLeftPT.mi_X;
1642 + tmpPTX[1] = mo_LowerLeftPT.mi_X;
1643 + tmpPTY[0] = mo_LowerLeftPT.mi_Y;
1644 + tmpPTY[1] = mo_UpperRightPT.mi_Y;
1646 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
1647 + if (isSucc[0] && isSucc[1])
1649 + xMin = MIN(tmpPTX[0],tmpPTX[1]);
1653 + OCTDestroyCoordinateTransformation(poCT);
1658 + tmpPTX[0] = mo_UpperRightPT.mi_X;
1659 + tmpPTX[1] = mo_UpperRightPT.mi_X;
1660 + tmpPTY[0] = mo_UpperRightPT.mi_Y;
1661 + tmpPTY[1] = mo_LowerLeftPT.mi_Y;
1663 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
1664 + if (isSucc[0] && isSucc[1])
1666 + xMax = MAX(tmpPTX[0],tmpPTX[1]);
1670 + OCTDestroyCoordinateTransformation(poCT);
1675 + BoundingBox bbox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
1677 + if (dstCRS.IsGeographic())
1680 + xMin = xMin - 360;
1682 + xMax = xMax - 360;
1686 + if (xMin <= -180.)
1690 + if (xMax <= -180.)
1698 + OCTDestroyCoordinateTransformation(poCT);
1700 + return BoundingBox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
1703 +BoundingBox BoundingBox::Transform(const double GeoTransform[])
1707 + llPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_LowerLeftPT.mi_X + GeoTransform[2] * mo_LowerLeftPT.mi_Y;
1708 + llPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_LowerLeftPT.mi_X + GeoTransform[5] * mo_LowerLeftPT.mi_Y;
1709 + urPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_UpperRightPT.mi_X + GeoTransform[2] * mo_UpperRightPT.mi_Y;
1710 + urPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_UpperRightPT.mi_X + GeoTransform[5] * mo_UpperRightPT.mi_Y;
1712 + return BoundingBox(llPt,urPt,mo_CRS);
1716 + * Transform Coordinates of lowercorner_left and upcorner_right
1717 + * lowLeft, upRight.
1718 + * the return value has considered the case of image area crossing 180/-180 longitude line,
1719 + * so lowLeft.x maybe bigger than upRight.x
1721 +CPLErr CPL_STDCALL bBox_transFormmate(OGRSpatialReference& oSrcCRS,
1722 + OGRSpatialReference& oDesCRS, My2DPoint& lowLeft, My2DPoint& upRight)
1724 + if (oSrcCRS.IsSame(&oDesCRS))
1727 + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&oSrcCRS, &oDesCRS);
1730 + SetWCS_ErrorLocator("bBox_transFormmate()");
1731 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create \"OGRCoordinateTransformation\"");
1732 + return CE_Failure;
1735 + double xdes = (upRight.mi_X - lowLeft.mi_X) / 100;
1736 + if (oSrcCRS.IsGeographic() && upRight.mi_X < lowLeft.mi_X && lowLeft.mi_X > 0 && upRight.mi_X < 0)
1738 + xdes = (360 + upRight.mi_X - lowLeft.mi_X) / 100;
1741 + vector<double> x, y;
1742 + //up and down edge
1743 + for (double stepX = lowLeft.mi_X; stepX < upRight.mi_X; stepX += xdes)
1745 + x.push_back(stepX);
1746 + y.push_back(upRight.mi_Y);
1747 + x.push_back(stepX);
1748 + y.push_back(lowLeft.mi_Y);
1750 + x.push_back(upRight.mi_X);
1751 + y.push_back(upRight.mi_Y);
1752 + x.push_back(upRight.mi_X);
1753 + y.push_back(lowLeft.mi_Y);
1755 + double yMin = numeric_limits<double>::max();
1756 + double yMax = -numeric_limits<double>::max();
1759 + vector<int> bSuccess;
1760 + vector<double> tmpX;
1761 + vector<double> tmpY;
1763 + for (unsigned int i = 0; i < x.size(); i++)
1765 + tmpX.push_back(x[i]);
1766 + tmpY.push_back(y[i]);
1767 + bSuccess.push_back(0);
1770 + poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
1772 + for (unsigned int n = 0; n < x.size(); n++)
1777 + yMin = MIN(yMin,tmpY[n]);
1778 + yMax = MAX(yMax,tmpY[n]);
1784 + OCTDestroyCoordinateTransformation(poCT);
1785 + SetWCS_ErrorLocator("bBox_transFormmate()");
1786 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
1787 + return CE_Failure;
1793 + //find xmin on left edge and xmax on right edge
1798 + tmpPTX[0] = lowLeft.mi_X;
1799 + tmpPTX[1] = lowLeft.mi_X;
1800 + tmpPTY[0] = upRight.mi_Y;
1801 + tmpPTY[1] = lowLeft.mi_Y;
1803 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
1804 + if (isOK[0] && isOK[1])
1806 + xMin = MIN(tmpPTX[0],tmpPTX[1]);
1810 + OCTDestroyCoordinateTransformation(poCT);
1811 + SetWCS_ErrorLocator("bBox_transFormmate()");
1812 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
1813 + return CE_Failure;
1816 + tmpPTX[0] = upRight.mi_X;
1817 + tmpPTX[1] = upRight.mi_X;
1818 + tmpPTY[0] = upRight.mi_Y;
1819 + tmpPTY[1] = lowLeft.mi_Y;
1821 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
1822 + if (isOK[0] && isOK[1])
1824 + xMax = MAX(tmpPTX[0],tmpPTX[1]);
1828 + SetWCS_ErrorLocator("bBox_transFormmate()");
1829 + OCTDestroyCoordinateTransformation(poCT);
1830 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
1831 + return CE_Failure;
1834 + lowLeft.mi_X = xMin;
1835 + lowLeft.mi_Y = yMin;
1836 + upRight.mi_X = xMax;
1837 + upRight.mi_Y = yMax;
1839 + if (oDesCRS.IsGeographic())
1842 + lowLeft.mi_X = xMin - 360;
1844 + upRight.mi_X = xMax - 360;
1846 + if (lowLeft.mi_X >= 180.)
1847 + lowLeft.mi_X = 180.;
1848 + if (lowLeft.mi_X <= -180.)
1849 + lowLeft.mi_X = -180.;
1850 + if (upRight.mi_X >= 180.)
1851 + upRight.mi_X = 180.;
1852 + if (upRight.mi_X <= -180.)
1853 + upRight.mi_X = -180.;
1855 + if (lowLeft.mi_Y <= -90.)
1856 + lowLeft.mi_Y = -90.;
1857 + if (upRight.mi_Y >= 90.)
1858 + upRight.mi_Y = 90.;
1860 + OCTDestroyCoordinateTransformation(poCT);
1864 diff -Nur bes-3.12.0/functions.orig/swath2grid/BoundingBox.h bes-3.12.0/functions/swath2grid/BoundingBox.h
1865 --- bes-3.12.0/functions.orig/swath2grid/BoundingBox.h 1970-01-01 01:00:00.000000000 +0100
1866 +++ bes-3.12.0/functions/swath2grid/BoundingBox.h 2014-03-03 15:47:38.053566262 +0100
1868 +/******************************************************************************
1869 + * $Id: BoundingBox.h 2011-07-19 16:24:00Z $
1871 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
1872 + * for Earth Observation: Open Source Reference Implementation
1873 + * Purpose: BoundingBox class definition
1874 + * Author: Yuanzheng Shao, yshao3@gmu.edu
1876 + ******************************************************************************
1877 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
1879 + * Permission is hereby granted, free of charge, to any person obtaining a
1880 + * copy of this software and associated documentation files (the "Software"),
1881 + * to deal in the Software without restriction, including without limitation
1882 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1883 + * and/or sell copies of the Software, and to permit persons to whom the
1884 + * Software is furnished to do so, subject to the following conditions:
1886 + * The above copyright notice and this permission notice shall be included
1887 + * in all copies or substantial portions of the Software.
1889 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1890 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1891 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1892 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1893 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1894 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1895 + * DEALINGS IN THE SOFTWARE.
1896 + ****************************************************************************/
1898 +#ifndef BOUNDINGBOX_H_
1899 +#define BOUNDINGBOX_H_
1902 +#include <ogr_spatialref.h>
1904 +#include <stdlib.h>
1906 +using namespace std;
1908 +/************************************************************************/
1909 +/* ==================================================================== */
1911 +/* ==================================================================== */
1912 +/************************************************************************/
1915 + * \class My2DPoint "BoundingBox.h"
1917 + * My2DPoint class is used to store the point coordinates.
1926 + virtual ~My2DPoint();
1934 + My2DPoint(const double& xx, const double& yy) :
1935 + mi_X(xx), mi_Y(yy)
1939 + My2DPoint(const My2DPoint& p) :
1940 + mi_X(p.mi_X), mi_Y(p.mi_Y)
1944 + My2DPoint& operator =(const My2DPoint& p)
1952 +/************************************************************************/
1953 +/* ==================================================================== */
1955 +/* ==================================================================== */
1956 +/************************************************************************/
1959 + * \class BoundingBox "BoundingBox.h"
1961 + * BoundingBox class is used to transform bounding box between different
1962 + * Coordinate Reference System.
1968 + My2DPoint mo_LowerLeftPT;
1969 + My2DPoint mo_UpperRightPT;
1970 + OGRSpatialReference mo_CRS;
1972 + BoundingBox(const My2DPoint& llpt, const My2DPoint& urpt, OGRSpatialReference& crs) :
1973 + mo_LowerLeftPT(llpt), mo_UpperRightPT(urpt), mo_CRS(crs)
1978 + BoundingBox(OGRSpatialReference& crs) :
1979 + mo_LowerLeftPT(0,0), mo_UpperRightPT(0,0), mo_CRS(crs)
1983 + BoundingBox& operator =(const BoundingBox& box)
1985 + mo_LowerLeftPT = box.mo_LowerLeftPT;
1986 + mo_UpperRightPT = box.mo_UpperRightPT;
1987 + mo_CRS = box.mo_CRS;
1992 + virtual ~BoundingBox();
1994 + BoundingBox Transform(OGRSpatialReference&, int&);
1995 + BoundingBox TransformWorkExtend(OGRSpatialReference&, int&);
1996 + BoundingBox Transform(const double*);
1999 +CPLErr CPL_DLL CPL_STDCALL bBox_transFormmate( OGRSpatialReference&,
2000 + OGRSpatialReference&,
2001 + My2DPoint& lowLeft,
2002 + My2DPoint& upRight);
2004 +#endif /* BOUNDINGBOX_H_ */
2005 diff -Nur bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.cpp bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp
2006 --- bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.cpp 1970-01-01 01:00:00.000000000 +0100
2007 +++ bes-3.12.0/functions/swath2grid/DAP_Dataset.cpp 2014-03-03 15:47:38.046899595 +0100
2010 +// -*- mode: c++; c-basic-offset:4 -*-
2012 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
2013 +// Access Protocol.
2015 +// Copyright (c) 2012 OPeNDAP, Inc.
2016 +// Author: James Gallagher <jgallagher@opendap.org>
2018 +// This library is free software; you can redistribute it and/or
2019 +// modify it under the terms of the GNU Lesser General Public
2020 +// License as published by the Free Software Foundation; either
2021 +// version 2.1 of the License, or (at your option) any later version.
2023 +// This library is distributed in the hope that it will be useful,
2024 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
2025 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2026 +// Lesser General Public License for more details.
2028 +// You should have received a copy of the GNU Lesser General Public
2029 +// License along with this library; if not, write to the Free Software
2030 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2032 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
2038 +#include "DAP_Dataset.h"
2042 +#include "Float64.h"
2044 +#include "ce_functions.h"
2048 +using namespace libdap;
2049 +using namespace std;
2052 +#define GOES_TIME_DEBUG FALSE
2057 +DAP_Dataset::DAP_Dataset()
2061 +/************************************************************************/
2062 +/* ~DAP_Dataset() */
2063 +/************************************************************************/
2066 + * \brief Destroy an open DAP_Dataset object.
2068 + * This is the accepted method of closing a DAP_Dataset dataset and
2069 + * deallocating all resources associated with it.
2072 +DAP_Dataset::~DAP_Dataset()
2076 +/************************************************************************/
2077 +/* DAP_Dataset() */
2078 +/************************************************************************/
2081 + * \brief Create an DAP_Dataset object.
2083 + * This is the accepted method of creating a DAP_Dataset object and
2084 + * allocating all resources associated with it.
2086 + * @param id The coverage identifier.
2088 + * @param rBandList The field list selected for this coverage. For TRMM
2089 + * daily data, the user could specify multiple days range in request.
2090 + * Each day is seemed as one field.
2092 + * @return A DAP_Dataset object.
2095 +DAP_Dataset::DAP_Dataset(const string& id, vector<int> &rBandList) :
2096 + AbstractDataset(id, rBandList)
2098 + md_MissingValue = 0;
2099 + mb_GeoTransformSet = FALSE;
2103 + * @brief Initialize a DAP Dataset using Array objects already read.
2108 +DAP_Dataset::DAP_Dataset(Array *src, Array *lat, Array *lon) :
2109 + AbstractDataset(), m_src(src), m_lat(lat), m_lon(lon)
2112 + // TODO Remove these?
2113 + DBG(cerr << "Registering GDAL drivers" << endl);
2114 + GDALAllRegister();
2118 + CPLSetErrorHandler(CPLQuietErrorHandler);
2120 + // Read this from the 'missing_value' or '_FillValue' attributes
2121 + string missing_value = m_src->get_attr_table().get_attr("missing_value");
2122 + if (missing_value.empty())
2123 + missing_value = m_src->get_attr_table().get_attr("_FillValue");
2125 + if (!missing_value.empty())
2126 + md_MissingValue = atof(missing_value.c_str());
2128 + md_MissingValue = 0;
2130 + mb_GeoTransformSet = FALSE;
2133 +/************************************************************************/
2134 +/* InitialDataset() */
2135 +/************************************************************************/
2138 + * \brief Initialize the GOES dataset with NetCDF format.
2140 + * This method is the implementation for initializing a GOES dataset with NetCDF format.
2141 + * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
2142 + * will be called to initialize an GOES dataset.
2144 + * @note To use this, call this method and then access the GDALDataset that
2145 + * contains the reprojected array using maptr_DS.get().
2147 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
2148 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
2150 + * @return CE_None on success or CE_Failure on failure.
2153 +CPLErr DAP_Dataset::InitialDataset(const int isSimple)
2155 + DBG(cerr << "In InitialDataset" << endl);
2157 + // Might break that operation out so the remap is a separate call
2158 + if (CE_None != SetNativeCRS() || CE_None != SetGeoTransform())
2159 + throw Error("Could not set the dataset native CRS or the GeoTransform.");
2161 + DBG(cerr << "Before SetGDALDataset" << endl);
2163 + if (CE_None != SetGDALDataset(isSimple)) {
2164 + GDALClose(maptr_DS.release());
2165 + throw Error("Could not reproject the dataset.");
2171 +/************************************************************************/
2172 +/* GetDAPArray() */
2173 +/************************************************************************/
2176 + * @brief Build a DAP Array from the GDALDataset
2178 +Array *DAP_Dataset::GetDAPArray()
2180 + DBG(cerr << "In GetDAPArray" << endl);
2181 + DBG(cerr << "maptr_DS: " << maptr_DS.get() << endl);
2182 + DBG(cerr << "raster band count: " << maptr_DS->GetRasterCount() << endl);
2184 + // There should be just one band
2185 + if (maptr_DS->GetRasterCount() != 1)
2186 + throw Error("In function swath2grid(), expected a single raster band.");
2188 + // Get the x and y dimensions of the raster band
2189 + int x = maptr_DS->GetRasterXSize();
2190 + int y = maptr_DS->GetRasterYSize();
2191 + GDALRasterBand *rb = maptr_DS->GetRasterBand(1);
2193 + throw Error("In function swath2grid(), could not access the raster data.");
2195 + // Since the DAP_Dataset code works with all data values as doubles,
2196 + // Assume the raster band has GDAL type GDT_Float64, but test anyway
2197 + if (GDT_Float64 != rb->GetRasterDataType())
2198 + throw Error("In function swath2grid(), expected raster data to be of type double.");
2200 + DBG(cerr << "Destination array will have dimensions: " << x << ", " << y << endl);
2202 + Array *a = new Array(m_src->name(), new Float64(m_src->name()));
2204 + // Make the result array have two dimensions
2205 + Array::Dim_iter i = m_src->dim_begin();
2207 + a->append_dim(x, m_src->dimension_name(i));
2210 + if (i == m_src->dim_end())
2211 + throw Error("In function swath2grid(), expected source array to have two dimensions (2).");
2213 + a->append_dim(y, m_src->dimension_name(i));
2215 + // Poke in the data values
2216 + /* RasterIO ( GDALRWFlag eRWFlag,
2224 + GDALDataType eBufType,
2228 + vector<double> data(x * y);
2229 + rb->RasterIO(GF_Read, 0, 0, x, y, &data[0], x, y, GDT_Float64, 0, 0);
2231 + // NB: set_value() copies into new storage
2232 + a->set_value(data, data.size());
2234 + // Now poke in some attributes
2235 + // TODO Make these CF attributes
2236 + string projection_info = maptr_DS->GetProjectionRef();
2237 + string gcp_projection_info = maptr_DS->GetGCPProjection();
2239 + // This sets the instance variable that holds the geotransform coefs. These
2240 + // are needed by the GetDAPGrid() method.
2241 + if (CE_None != maptr_DS->GetGeoTransform (m_geo_transform_coef))
2242 + throw Error("In function swath2grid(), could not access the geo transform data.");
2244 + DBG(cerr << "projection_info: " << projection_info << endl);
2245 + DBG(cerr << "gcp_projection_info: " << gcp_projection_info << endl);
2246 + DBG(cerr << "geo_transform coefs: " << double_to_string(m_geo_transform_coef[0]) << endl);
2248 + AttrTable &attr = a->get_attr_table();
2249 + attr.append_attr("projection", "String", projection_info);
2250 + attr.append_attr("gcp_projection", "String", gcp_projection_info);
2251 + for (unsigned int i = 0; i < sizeof(m_geo_transform_coef); ++i) {
2252 + attr.append_attr("geo_transform_coefs", "String", double_to_string(m_geo_transform_coef[i]));
2258 +/************************************************************************/
2260 +/************************************************************************/
2263 + * @brief Build a DAP Grid from the GDALDataset
2265 +Grid *DAP_Dataset::GetDAPGrid()
2267 + DBG(cerr << "In GetDAPGrid" << endl);
2269 + Array *a = GetDAPArray();
2270 + Array::Dim_iter i = a->dim_begin();
2271 + int lon_size = a->dimension_size(i);
2272 + int lat_size = a->dimension_size(++i);
2274 + Grid *g = new Grid(a->name());
2275 + g->add_var_nocopy(a, array);
2277 + // Add maps; assume lon, lat; only two dimensions
2278 + Array *lon = new Array("longitude", new Float64("longitude"));
2279 + lon->append_dim(lon_size);
2281 + vector<double> data(max(lon_size, lat_size)); // (re)use this for both lon and lat
2286 + // u,v --> x,y --> lon,lat
2287 + // The constants a, b, c, d are given by the 1, 2, 4, and 5 entries in the geotransform array.
2289 + if (m_geo_transform_coef[2] != 0)
2290 + throw Error("The transformed data's Geographic projection should not be rotated.");
2291 + for (int j = 0; j < lon_size; ++j) {
2292 + data[j] = m_geo_transform_coef[1] * j + m_geo_transform_coef[0];
2295 + // load (copy) values
2296 + lon->set_value(&data[0], lon_size);
2298 + g->add_var_nocopy(lon, maps);
2300 + // Now do the latitude map
2301 + Array *lat = new Array("latitude", new Float64("latitude"));
2302 + lat->append_dim(lat_size);
2304 + if (m_geo_transform_coef[4] != 0)
2305 + throw Error("The transformed data's Geographic projection should not be rotated.");
2306 + for (int k = 0; k < lat_size; ++k) {
2307 + data[k] = m_geo_transform_coef[5] * k + m_geo_transform_coef[3];
2310 + lat->set_value(&data[0], lat_size);
2311 + g->add_var_nocopy(lat, maps);
2316 +/************************************************************************/
2317 +/* SetNativeCRS() */
2318 +/************************************************************************/
2321 + * \brief Set the Native CRS for a GOES dataset.
2323 + * The method will set the CRS for a GOES dataset as an native CRS.
2325 + * Since the original GOES data adopt satellite CRS to recored its value,
2326 + * like MODIS swath data, each data point has its corresponding latitude
2327 + * and longitude value, those coordinates could be fetched in another two fields.
2329 + * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
2330 + * both the latitude and longitude are existed.
2332 + * @return CE_None on success or CE_Failure on failure.
2335 +CPLErr DAP_Dataset::SetNativeCRS()
2337 + DBG(cerr << "In SetNativeCRS" << endl);
2339 + mo_NativeCRS.SetWellKnownGeogCS("WGS84");
2344 +/************************************************************************/
2345 +/* SetGeoTransform() */
2346 +/************************************************************************/
2349 + * \brief Set the affine GeoTransform matrix for a GOES data.
2351 + * The method will set a GeoTransform matrix for a GOES data
2352 + * by parsing the coordinates values existed in longitude and latitude field.
2354 + * The CRS for the bounding box is EPSG:4326.
2356 + * @return CE_None on success or CE_Failure on failure.
2359 +CPLErr DAP_Dataset::SetGeoTransform()
2361 + DBG(cerr << "In SetGeoTransform" << endl);
2363 + // TODO Look at this; is this correct
2364 + // Assume the array is two dimensional
2365 + Array::Dim_iter i = m_src->dim_begin();
2367 + // ORIGINAL code; maybe wrong
2368 + int nXSize = m_src->dimension_size(i, true);
2369 + int nYSize = m_src->dimension_size(i + 1, true);
2371 + // Data are in row-major order, so the first dim is the Y-axis value
2372 + int nYSize = m_src->dimension_size(i, true);
2373 + int nXSize = m_src->dimension_size(i + 1, true);
2375 + mi_SrcImageXSize = nXSize;
2376 + mi_SrcImageYSize = nYSize;
2378 + SetGeoBBoxAndGCPs(nXSize, nYSize);
2380 + double resX, resY;
2381 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
2382 + resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
2384 + resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
2386 + resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (nYSize - 1);
2388 + double res = MIN(resX, resY);
2390 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
2391 + mi_RectifiedImageXSize = (int) ((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
2393 + mi_RectifiedImageXSize = (int) ((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
2395 + mi_RectifiedImageYSize = (int) fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
2397 + DBG(cerr << "Source image size: " << nXSize << ", " << nYSize << endl);
2398 + DBG(cerr << "Rectified image size: " << mi_RectifiedImageXSize << ", " << mi_RectifiedImageYSize << endl);
2400 + md_Geotransform[0] = mdSrcGeoMinX;
2401 + md_Geotransform[1] = res;
2402 + md_Geotransform[2] = 0;
2403 + md_Geotransform[3] = mdSrcGeoMaxY;
2404 + md_Geotransform[4] = 0;
2405 + md_Geotransform[5] = -res;
2406 + mb_GeoTransformSet = TRUE;
2411 +/************************************************************************/
2412 +/* SetGeoBBoxAndGCPs() */
2413 +/************************************************************************/
2416 + * \brief Set the native geographical bounding box and GCP array for a GOES data.
2418 + * The method will set the native geographical bounding box
2419 + * by comparing the coordinates values existed in longitude and latitude field.
2421 + * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
2423 + * @return CE_None on success or CE_Failure on failure.
2426 +void DAP_Dataset::SetGeoBBoxAndGCPs(int nXSize, int nYSize)
2428 + DBG(cerr << "In SetGeoBBoxAndGCPs" << endl);
2430 + // reuse the Dim_iter for both lat and lon arrays
2431 + Array::Dim_iter i = m_lat->dim_begin();
2432 + int nLatXSize = m_lat->dimension_size(i, true);
2433 + int nLatYSize = m_lat->dimension_size(i + 1, true);
2434 + i = m_lon->dim_begin();
2435 + int nLonXSize = m_lon->dimension_size(i, true);
2436 + int nLonYSize = m_lon->dimension_size(i + 1, true);
2438 + if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
2439 + throw Error("The size of latitude/longitude and data field does not match.");
2443 + * Re-sample Standards:
2445 + * (0, 500) every other one pixel
2446 + * [500, 1000) every other two pixels
2447 + * [1000,1500) every other three pixels
2448 + * [1500,2000) every other four pixels
2454 + //setResampleStandard(poVDS, xSpace, ySpace);
2456 + // TODO understand how GMU picked this value.
2457 + // xSpace and ySpace are the stride values for sampling in
2458 + // the x and y dimensions.
2459 + const int RESAMPLE_STANDARD = 500;
2461 + xSpace = int(nXSize / RESAMPLE_STANDARD) + 2;
2462 + ySpace = int(nYSize / RESAMPLE_STANDARD) + 2;
2467 + double *dataLat = extract_double_array(m_lat);
2468 + double *dataLon = extract_double_array(m_lon);
2470 + DBG(cerr << "Past lat/lon data read" << endl);
2474 + mdSrcGeoMinX = 360;
2475 + mdSrcGeoMaxX = -360;
2476 + mdSrcGeoMinY = 90;
2477 + mdSrcGeoMaxY = -90;
2479 + // Sample every other row and column
2486 + for (int iLine = 0; iLine < nYSize - ySpace; iLine += ySpace) {
2487 + for (int iPixel = 0; iPixel < nXSize - xSpace; iPixel += xSpace) {
2488 + double x = *(dataLon + (iLine * nYSize) + iPixel);
2489 + double y = *(dataLat + (iLine * nYSize) + iPixel);
2491 + if (isValidLongitude(x) && isValidLatitude(y)) {
2493 + snprintf(pChr, 64, "%d", ++nGCPs);
2494 + GDALInitGCPs(1, &gdalCGP);
2495 + gdalCGP.pszId = strdup(pChr);
2496 + gdalCGP.pszInfo = strdup("");
2497 + gdalCGP.dfGCPLine = iLine;
2498 + gdalCGP.dfGCPPixel = iPixel;
2499 + gdalCGP.dfGCPX = x;
2500 + gdalCGP.dfGCPY = y;
2502 + DBG2(cerr << "iLine, iPixel: " << iLine << ", " << iPixel << " --> x,y: " << x << ", " << y << endl);
2504 + gdalCGP.dfGCPZ = 0;
2505 + m_gdalGCPs.push_back(gdalCGP);
2507 + mdSrcGeoMinX = MIN(mdSrcGeoMinX, gdalCGP.dfGCPX);
2508 + mdSrcGeoMaxX = MAX(mdSrcGeoMaxX, gdalCGP.dfGCPX);
2509 + mdSrcGeoMinY = MIN(mdSrcGeoMinY, gdalCGP.dfGCPY);
2510 + mdSrcGeoMaxY = MAX(mdSrcGeoMaxY, gdalCGP.dfGCPY);
2524 + DBG(cerr << "Leaving SetGeoBBoxAndGCPs" << endl);
2527 +/************************************************************************/
2528 +/* SetGDALDataset() */
2529 +/************************************************************************/
2532 + * \brief Make a 'memory' dataset with one band
2534 + * @return CE_None on success or CE_Failure on failure.
2537 +CPLErr DAP_Dataset::SetGDALDataset(const int isSimple)
2539 + DBG(cerr << "In SetGDALDataset" << endl);
2541 + // NB: mi_RectifiedImageXSize & Y are set in SetGeoTransform()
2542 + GDALDataType eBandType = GDT_Float64;
2543 + // VRT, which was used in the original sample code, is not supported in this context, so I used MEM
2544 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
2546 + throw Error("Failed to get MEM driver (" + string(CPLGetLastErrorMsg()) + ").");
2549 + GDALDataset* satDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
2550 + 1, eBandType, NULL);
2551 + if (!satDataSet) {
2552 + GDALClose(poDriver);
2553 + throw Error("Failed to create MEM dataSet (" + string(CPLGetLastErrorMsg()) + ").");
2556 + GDALRasterBand *poBand = satDataSet->GetRasterBand(1);
2557 + poBand->SetNoDataValue(md_MissingValue);
2560 + double *data = extract_double_array(m_src);
2561 + if (CE_None != poBand->RasterIO(GF_Write, 0, 0, mi_RectifiedImageXSize, mi_RectifiedImageYSize, data,
2562 + mi_SrcImageXSize, mi_SrcImageYSize, eBandType, 0, 0)) {
2563 + GDALClose((GDALDatasetH) satDataSet);
2564 + throw Error("Failed to set satellite data band to MEM DataSet (" + string(CPLGetLastErrorMsg()) + ").");
2568 + //set GCPs for this VRTDataset
2569 + if (CE_None != SetGCPGeoRef4VRTDataset(satDataSet)) {
2570 + GDALClose((GDALDatasetH) satDataSet);
2571 + throw Error("Could not georeference the virtual dataset (" + string(CPLGetLastErrorMsg()) + ").");
2574 + DBG(cerr << "satDataSet: " << satDataSet << endl);
2576 + maptr_DS.reset(satDataSet);
2581 + return RectifyGOESDataSet();
2584 +/************************************************************************/
2585 +/* SetGCPGeoRef4VRTDataset() */
2586 +/************************************************************************/
2589 + * \brief Set the GCP array for the VRT dataset.
2591 + * This method is used to set the GCP array to created VRT dataset based on GDAL
2592 + * method SetGCPs().
2594 + * @param poVDS The VRT dataset.
2596 + * @return CE_None on success or CE_Failure on failure.
2599 +CPLErr DAP_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
2601 + char* psTargetSRS;
2602 + mo_NativeCRS.exportToWkt(&psTargetSRS);
2604 +#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
2605 + if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS)) {
2606 + OGRFree(psTargetSRS);
2607 + throw Error("Failed to set GCPs.");
2611 + if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
2613 + OGRFree( psTargetSRS );
2614 + throw Error("Failed to set GCPs.");
2619 + OGRFree(psTargetSRS);
2624 +/************************************************************************/
2625 +/* SetMetaDataList() */
2626 +/************************************************************************/
2629 + * \brief Set the metadata list for this coverage.
2631 + * The method will set the metadata list for the coverage based on its
2632 + * corresponding GDALDataset object.
2634 + * @param hSrc the GDALDataset object corresponding to coverage.
2636 + * @return CE_None on success or CE_Failure on failure.
2639 +CPLErr DAP_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
2643 + mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
2644 + mv_MetaDataList.push_back("unit=GVAR");
2645 + mv_MetaDataList.push_back("FillValue=0");
2646 + ms_FieldQuantityDef = "GVAR";
2647 + ms_AllowRanges = "0 65535";
2648 + ms_CoveragePlatform = "GOES-11";
2649 + ms_CoverageInstrument = "GOES-11";
2650 + ms_CoverageSensor = "Imager";
2656 +/************************************************************************/
2657 +/* GetGeoMinMax() */
2658 +/************************************************************************/
2661 + * \brief Get the min/max coordinates of laitutude and longitude.
2663 + * The method will fetch the min/max coordinates of laitutude and longitude.
2665 + * @param geoMinMax an existing four double buffer into which the
2666 + * native geographical bounding box values will be placed.
2668 + * @return CE_None on success or CE_Failure on failure.
2671 +CPLErr DAP_Dataset::GetGeoMinMax(double geoMinMax[])
2673 + if (!mb_GeoTransformSet)
2674 + return CE_Failure;
2676 + geoMinMax[0] = mdSrcGeoMinX;
2677 + geoMinMax[2] = mdSrcGeoMinY;
2678 + geoMinMax[1] = mdSrcGeoMaxX;
2679 + geoMinMax[3] = mdSrcGeoMaxY;
2684 +/************************************************************************/
2685 +/* RectifyGOESDataSet() */
2686 +/************************************************************************/
2689 + * \brief Convert the GOES dataset from satellite CRS project to grid CRS.
2691 + * The method will convert the GOES dataset from satellite CRS project to
2692 + * grid CRS based on GDAL API GDALReprojectImage;
2694 + * @return CE_None on success or CE_Failure on failure.
2697 +CPLErr DAP_Dataset::RectifyGOESDataSet()
2699 + DBG(cerr << "In RectifyGOESDataSet" << endl);
2702 + mo_NativeCRS.exportToWkt(&pszDstWKT);
2704 + GDALDriverH poDriver = GDALGetDriverByName("VRT"); // MEM
2705 + GDALDataset* rectDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
2706 + maptr_DS->GetRasterCount(), maptr_DS->GetRasterBand(1)->GetRasterDataType(), NULL);
2707 + if (NULL == rectDataSet) {
2708 + GDALClose(poDriver);
2709 + OGRFree(pszDstWKT);
2710 + throw Error("Failed to create \"MEM\" dataSet.");
2713 + rectDataSet->SetProjection(pszDstWKT);
2714 + rectDataSet->SetGeoTransform(md_Geotransform);
2716 + DBG(cerr << "rectDataSet: " << rectDataSet << endl);
2717 + DBG(cerr << "satDataSet: " << maptr_DS.get() << endl);
2719 + // FIXME Magic value of 0.125
2720 + if (CE_None != GDALReprojectImage(maptr_DS.get(), NULL, rectDataSet, pszDstWKT,
2721 + GRA_Lanczos /*GRA_NearestNeighbour*/, 0, 0.0/*0.125*/, NULL, NULL, NULL)) {
2722 + GDALClose(rectDataSet);
2723 + GDALClose(poDriver);
2724 + OGRFree(pszDstWKT);
2725 + throw Error("Failed to re-project satellite data from GCP CRS to geographical CRS.");
2728 + OGRFree(pszDstWKT);
2729 + GDALClose(maptr_DS.release());
2731 + maptr_DS.reset(rectDataSet);
2733 + DBG(cerr << "Leaving RectifyGOESDataSet" << endl);
2738 +} // namespace libdap
2739 diff -Nur bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.h bes-3.12.0/functions/swath2grid/DAP_Dataset.h
2740 --- bes-3.12.0/functions.orig/swath2grid/DAP_Dataset.h 1970-01-01 01:00:00.000000000 +0100
2741 +++ bes-3.12.0/functions/swath2grid/DAP_Dataset.h 2014-03-03 15:47:38.050232928 +0100
2744 +// -*- mode: c++; c-basic-offset:4 -*-
2746 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
2747 +// Access Protocol.
2749 +// Copyright (c) 2012 OPeNDAP, Inc.
2750 +// Author: James Gallagher <jgallagher@opendap.org>
2752 +// This library is free software; you can redistribute it and/or
2753 +// modify it under the terms of the GNU Lesser General Public
2754 +// License as published by the Free Software Foundation; either
2755 +// version 2.1 of the License, or (at your option) any later version.
2757 +// This library is distributed in the hope that it will be useful,
2758 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
2759 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2760 +// Lesser General Public License for more details.
2762 +// You should have received a copy of the GNU Lesser General Public
2763 +// License along with this library; if not, write to the Free Software
2764 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2766 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
2768 +#ifndef DAP_DATASET_H_
2769 +#define DAP_DATASET_H_
2772 +#include "AbstractDataset.h"
2773 +#include "wcsUtil.h"
2775 +using namespace std;
2782 +/************************************************************************/
2783 +/* ==================================================================== */
2785 +/* ==================================================================== */
2786 +/************************************************************************/
2788 +//! DAP_Dataset is a subclass of AbstractDataset, used to process NOAA GOES data.
2790 + * \class DAP_Dataset "DAP_Dataset.h"
2792 + * GOES satellites provide the kind of continuous monitoring necessary for
2793 + * intensive data analysis. They circle the Earth in a geosynchronous orbit,
2794 + * which means they orbit the equatorial plane of the Earth at a speed
2795 + * matching the Earth's rotation. This allows them to hover continuously
2796 + * over one position on the surface. The geosynchronous plane is about
2797 + * 35,800 km (22,300 miles) above the Earth, high enough to allow the
2798 + * satellites a full-disc view of the Earth. Because they stay above a
2799 + * fixed spot on the surface, they provide a constant vigil for the atmospheric
2800 + * "triggers" for severe weather conditions such as tornadoes, flash floods,
2801 + * hail storms, and hurricanes. When these conditions develop the GOES
2802 + * satellites are able to monitor storm development and track their movements.
2804 + * GOES satellite imagery is also used to estimate rainfall during
2805 + * the thunderstorms and hurricanes for flash flood warnings, as well
2806 + * as estimates snowfall accumulations and overall extent of snow cover.
2807 + * Such data help meteorologists issue winter storm warnings and spring
2808 + * snow melt advisories. Satellite sensors also detect ice fields and map
2809 + * the movements of sea and lake ice.
2811 + * For more inforamtion about NOAA GOES data, please access
2812 + * <a href=http://www.oso.noaa.gov/GOES/>http://www.oso.noaa.gov/GOES/</a>
2814 + * DAP_Dataset is a subclass of AbstractDataset, which is used to
2815 + * process GOES Imager and Sounder products.
2818 +class DAP_Dataset : public AbstractDataset {
2820 + string m_ncLatDataSetName;
2821 + string m_ncLonDataSetName;
2822 + string m_ncCoverageIDName;
2824 + // Instead of using names and opening files with GDAL,
2825 + // store pointers to Arrays read by the underlying DAP
2826 + // server constraint evaluator.
2831 + int mi_RectifiedImageXSize;
2832 + int mi_RectifiedImageYSize;
2833 + int mi_SrcImageXSize;
2834 + int mi_SrcImageYSize;
2836 + double mb_LatLonBBox[4];
2837 + double mdSrcGeoMinX;
2838 + double mdSrcGeoMinY;
2839 + double mdSrcGeoMaxX;
2840 + double mdSrcGeoMaxY;
2842 + // This is not set until GetDAPArray() is called.
2843 + double m_geo_transform_coef[6];
2845 + vector<GDAL_GCP> m_gdalGCPs;
2848 + CPLErr SetGCPGeoRef4VRTDataset(GDALDataset*);
2849 + void SetGeoBBoxAndGCPs(int xSize, int ySize);
2850 + CPLErr RectifyGOESDataSet();
2851 + CPLErr setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue);
2853 + int isValidLatitude(const double &lat)
2855 + return (lat >= -90 && lat <= 90);
2857 + int isValidLongitude(const double &lon)
2859 + return (lon >= -180 && lon <= 180);
2862 + virtual CPLErr SetGeoTransform();
2864 + virtual CPLErr SetMetaDataList(GDALDataset* hSrcDS); //TODO Remove
2866 + virtual CPLErr SetNativeCRS();
2867 + virtual CPLErr SetGDALDataset(const int isSimple = 0);
2868 + virtual CPLErr InitialDataset(const int isSimple = 0);
2869 + virtual CPLErr GetGeoMinMax(double geoMinMax[]);
2873 + DAP_Dataset(const string& id, vector<int> &rBandList);
2875 + // Added jhrg 11/23/12
2876 + DAP_Dataset(Array *src, Array *lat, Array *lon);
2877 + Array *GetDAPArray();
2878 + Grid *GetDAPGrid();
2880 + virtual ~DAP_Dataset();
2883 +} // namespace libdap
2884 +#endif /* DAP_DATASET_H_ */
2885 diff -Nur bes-3.12.0/functions.orig/swath2grid/Makefile.am bes-3.12.0/functions/swath2grid/Makefile.am
2886 --- bes-3.12.0/functions.orig/swath2grid/Makefile.am 1970-01-01 01:00:00.000000000 +0100
2887 +++ bes-3.12.0/functions/swath2grid/Makefile.am 2014-03-03 15:47:38.056899595 +0100
2890 +# Build libswath2grid, part of libdap.
2892 +AUTOMAKE_OPTIONS = foreign
2894 +AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) -I$(top_srcdir)/tests -I$(top_srcdir)/dispatch $(XML2_CFLAGS) $(CURL_CFLAGS)
2898 +AM_CPPFLAGS += $(CPPUNIT_CFLAGS)
2899 +AM_LDADD += $(CPPUNIT_LIBS)
2902 +# These are not used by automake but are often useful for certain types of
2903 +# debugging. The best way to use these is to run configure as:
2904 +# export CXXFLAGS='...'; ./configure --disable-shared
2905 +# the --disable-shared is not required, but it seems to help with debuggers.
2906 +CXXFLAGS_DEBUG = -g3 -O0 -Wall -W -Wcast-align -Werror
2907 +TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
2912 +# This determines what gets built by make check
2913 +check_PROGRAMS = $(UNIT_TESTS)
2915 +# This determines what gets run by 'make check.'
2916 +# Now (12/20/12) this fails; don't run until it works.
2917 +# TESTS = $(UNIT_TESTS)
2920 +noinst_LTLIBRARIES = libswath2grid.la
2922 +libswath2grid_la_SOURCES = $(SRCS) $(HDRS)
2923 +libswath2grid_la_CPPFLAGS = $(GDAL_CFLAGS) $(XML2_CFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) -I$(top_srcdir)/dispatch
2924 +libswath2grid_la_LDFLAGS =
2925 +libswath2grid_la_LIBADD = $(GDAL_LDFLAGS) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS)
2927 +SRCS = AbstractDataset.cpp wcs_error.cpp \
2928 +BoundingBox.cpp wcsUtil.cpp DAP_Dataset.cpp reproj_functions.cc
2930 +# NC_GOES_Dataset.cpp NC_GOES_Dataset.h
2932 +HDRS = AbstractDataset.h wcs_error.h \
2933 +BoundingBox.h wcsUtil.h DAP_Dataset.h reproj_functions.h
2936 +UNIT_TESTS = s2gTest
2943 + @echo "**********************************************************"
2944 + @echo "You must have cppunit 1.12.x or greater installed to run *"
2945 + @echo "check target in unit-tests directory *"
2946 + @echo "**********************************************************"
2950 +s2gTest_SOURCES = s2gTest.cc
2951 +s2gTest_CPPFLAGS = $(AM_CPPFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) $(GDAL_CFLAGS)
2952 +s2gTest_LDADD = -ltest-types libswath2grid.la $(AM_LDADD) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS) $(GDAL_LDFLAGS)
2957 + @echo "**********************************************************"
2958 + @echo "USING DAP "
2959 + @echo "DAP_CLIENT_CFLAGS: " $(DAP_CLIENT_CFLAGS)
2960 + @echo "DAP_SERVER_CFLAGS: " $(DAP_SERVER_CFLAGS)
2961 + @echo "DAP_CLIENT_LIBS: " $(DAP_CLIENT_LIBS)
2962 + @echo "DAP_SERVER_LIBS: " $(DAP_SERVER_LIBS)
2963 + @echo "**********************************************************"
2968 + @echo "**********************************************************"
2969 + @echo " Unable to locate DAP libraries!"
2970 + @echo "**********************************************************"
2978 + @echo "**********************************************************"
2979 + @echo "Using gdal. "
2980 + @echo "GDAL_CFLAGS: " $(GDAL_CFLAGS)
2981 + @echo "GDAL_LDFLAGS: " $(GDAL_LDFLAGS)
2982 + @echo "**********************************************************"
2987 + @echo "**********************************************************"
2988 + @echo "You must have gdal 12.15.12 or greater installed to run"
2989 + @echo "check target in unit-tests directory "
2990 + @echo "GDAL_VERSION: '$(GDAL_VERSION)'"
2991 + @echo "prefix: '$(prefix)'"
2992 + @echo "**********************************************************"
2995 diff -Nur bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.cpp bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.cpp
2996 --- bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.cpp 1970-01-01 01:00:00.000000000 +0100
2997 +++ bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.cpp 2014-03-03 15:47:38.053566262 +0100
2999 +/******************************************************************************
3000 + * $Id: TRMM_Dataset.cpp 2011-07-19 16:24:00Z $
3002 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
3003 + * for Earth Observation: Open Source Reference Implementation
3004 + * Purpose: NC_GOES_Dataset implementation for NOAA GOES data
3005 + * Author: Yuanzheng Shao, yshao3@gmu.edu
3007 + ******************************************************************************
3008 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
3010 + * Permission is hereby granted, free of charge, to any person obtaining a
3011 + * copy of this software and associated documentation files (the "Software"),
3012 + * to deal in the Software without restriction, including without limitation
3013 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3014 + * and/or sell copies of the Software, and to permit persons to whom the
3015 + * Software is furnished to do so, subject to the following conditions:
3017 + * The above copyright notice and this permission notice shall be included
3018 + * in all copies or substantial portions of the Software.
3020 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
3021 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3022 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
3023 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3024 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3025 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
3026 + * DEALINGS IN THE SOFTWARE.
3027 + ****************************************************************************/
3029 +#include "NC_GOES_Dataset.h"
3031 +using namespace std;
3033 +#define GOES_TIME_DEBUG FALSE
3035 +NC_GOES_Dataset::NC_GOES_Dataset()
3039 +/************************************************************************/
3040 +/* ~NC_GOES_Dataset() */
3041 +/************************************************************************/
3044 + * \brief Destroy an open NC_GOES_Dataset object.
3046 + * This is the accepted method of closing a NC_GOES_Dataset dataset and
3047 + * deallocating all resources associated with it.
3050 +NC_GOES_Dataset::~NC_GOES_Dataset()
3054 +/************************************************************************/
3055 +/* NC_GOES_Dataset() */
3056 +/************************************************************************/
3059 + * \brief Create an NC_GOES_Dataset object.
3061 + * This is the accepted method of creating a NC_GOES_Dataset object and
3062 + * allocating all resources associated with it.
3064 + * @param id The coverage identifier.
3066 + * @param rBandList The field list selected for this coverage. For TRMM
3067 + * daily data, the user could specify multiple days range in request.
3068 + * Each day is seemed as one field.
3070 + * @return A NC_GOES_Dataset object.
3073 +NC_GOES_Dataset::NC_GOES_Dataset(const string& id, vector<int> &rBandList) :
3074 + AbstractDataset(id, rBandList)
3076 + md_MissingValue = 0;
3077 + mb_GeoTransformSet = FALSE;
3080 +/************************************************************************/
3081 +/* InitialDataset() */
3082 +/************************************************************************/
3085 + * \brief Initialize the GOES dataset with NetCDF format.
3087 + * This method is the implementation for initializing a GOES dataset with NetCDF format.
3088 + * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
3089 + * will be called to initialize an GOES dataset.
3091 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
3092 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
3094 + * @return CE_None on success or CE_Failure on failure.
3097 +CPLErr NC_GOES_Dataset::InitialDataset(const int isSimple)
3099 + vector<string> strSet;
3100 + unsigned int n = CsvburstCpp(ms_CoverageID, strSet, ':');
3103 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
3104 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Incorrect coverage ID.");
3105 + return CE_Failure;
3108 + ms_DataTypeName = strSet[0] + ":" + strSet[1];
3109 + ms_SrcFilename = StrTrims(strSet[2], " \'\"");
3110 + ms_DatasetName = strSet[3];
3112 + m_ncLatDataSetName = "NETCDF:" + ms_SrcFilename + ":latitude";
3113 + m_ncLonDataSetName = "NETCDF:" + ms_SrcFilename + ":longitude";
3114 + m_ncCoverageIDName = strSet[1] + ":" + strSet[2] + ":" + strSet[3];
3116 + GDALDataset* pSrc = (GDALDataset*) GDALOpenShared(m_ncCoverageIDName.c_str(), GA_ReadOnly);
3119 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
3120 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open file \"%s\".", ms_SrcFilename.c_str());
3121 + return CE_Failure;
3124 + ms_NativeFormat = GDALGetDriverShortName(pSrc->GetDriver());
3127 + SetMetaDataList(pSrc);
3130 + unsigned int nBandCount = pSrc->GetRasterCount();
3131 + if (nBandCount < 1)
3134 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
3135 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The GOES file does not contain any raster band.");
3136 + return CE_Failure;
3139 + maptr_DS.reset(pSrc);
3141 + //set moNativeCRS and mGeoTransform
3142 + if (CE_None != SetNativeCRS() ||
3143 + CE_None != SetGeoTransform() ||
3144 + CE_None != SetGDALDataset(isSimple))
3146 + GDALClose(maptr_DS.release());
3147 + return CE_Failure;
3153 +/************************************************************************/
3154 +/* SetNativeCRS() */
3155 +/************************************************************************/
3158 + * \brief Set the Native CRS for a GOES dataset.
3160 + * The method will set the CRS for a GOES dataset as an native CRS.
3162 + * Since the original GOES data adopt satellite CRS to recored its value,
3163 + * like MODIS swath data, each data point has its corresponding latitude
3164 + * and longitude value, those coordinates could be fetched in another two fields.
3166 + * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
3167 + * both the latitude and longitude are existed.
3169 + * @return CE_None on success or CE_Failure on failure.
3172 +CPLErr NC_GOES_Dataset::SetNativeCRS()
3174 + if (CE_None == AbstractDataset::SetNativeCRS())
3177 + GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
3178 + GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
3180 + if(hLatDS == NULL) {
3181 + m_ncLatDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lat";
3182 + hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
3185 + if(hLonDS == NULL) {
3186 + m_ncLonDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lon";
3187 + hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
3190 + if (hLatDS == NULL || hLonDS == NULL)
3192 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetNativeCRS()");
3193 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open latitude/longitude sub-dataset.");
3194 + return CE_Failure;
3197 + mo_NativeCRS.SetWellKnownGeogCS("WGS84");
3199 + GDALClose(hLatDS);
3200 + GDALClose(hLonDS);
3205 +/************************************************************************/
3206 +/* SetGeoTransform() */
3207 +/************************************************************************/
3210 + * \brief Set the affine GeoTransform matrix for a GOES data.
3212 + * The method will set a GeoTransform matrix for a GOES data
3213 + * by parsing the coordinates values existed in longitude and latitude field.
3215 + * The CRS for the bounding box is EPSG:4326.
3217 + * @return CE_None on success or CE_Failure on failure.
3220 +CPLErr NC_GOES_Dataset::SetGeoTransform()
3222 + if (CE_None == AbstractDataset::SetGeoTransform())
3225 + if (CE_None != SetGeoBBoxAndGCPs(maptr_DS.get()))
3226 + return CE_Failure;
3228 + double resX, resY;
3229 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
3230 + resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
3232 + resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
3234 + resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (maptr_DS->GetRasterYSize() - 1);
3236 + double res = MIN(resX,resY);
3238 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
3239 + mi_RectifiedImageXSize = (int)((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
3241 + mi_RectifiedImageXSize = (int)((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
3243 + mi_RectifiedImageYSize = (int)fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
3245 + md_Geotransform[0] = mdSrcGeoMinX;
3246 + md_Geotransform[1] = res;
3247 + md_Geotransform[2] = 0;
3248 + md_Geotransform[3] = mdSrcGeoMaxY;
3249 + md_Geotransform[4] = 0;
3250 + md_Geotransform[5] = -res;
3251 + mb_GeoTransformSet = TRUE;
3256 +CPLErr NC_GOES_Dataset::setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue)
3258 + static int RESAMPLE_STANDARD = 500;
3259 + int nXSize = hSrcDS->GetRasterXSize();
3260 + int nYSize = hSrcDS->GetRasterYSize();
3262 + xRSValue = int(nXSize / RESAMPLE_STANDARD) + 2;
3263 + yRSValue = int(nYSize / RESAMPLE_STANDARD) + 2;
3268 +/************************************************************************/
3269 +/* SetGeoBBoxAndGCPs() */
3270 +/************************************************************************/
3273 + * \brief Set the native geographical bounding box and GCP array for a GOES data.
3275 + * The method will set the native geographical bounding box
3276 + * by comparing the coordinates values existed in longitude and latitude field.
3278 + * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
3280 + * @return CE_None on success or CE_Failure on failure.
3283 +CPLErr NC_GOES_Dataset::SetGeoBBoxAndGCPs(GDALDataset* poVDS)
3285 + GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
3286 + GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
3288 + int nXSize = poVDS->GetRasterXSize();
3289 + int nYSize = poVDS->GetRasterYSize();
3291 + mi_GoesSrcImageXSize = nXSize;
3292 + mi_GoesSrcImageYSize = nYSize;
3294 + int nLatXSize = hLatDS->GetRasterXSize();
3295 + int nLatYSize = hLatDS->GetRasterYSize();
3296 + int nLonXSize = hLonDS->GetRasterXSize();
3297 + int nLonYSize = hLonDS->GetRasterYSize();
3299 + if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
3301 + GDALClose(hLatDS);
3302 + GDALClose(hLonDS);
3304 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGeoBBoxAndGCPs()");
3305 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The size of latitude/longitude and data field does not match.");
3307 + return CE_Failure;
3311 + * Re-sample Standards:
3313 + * (0, 500) every other one pixel
3314 + * [500, 1000) every other two pixels
3315 + * [1000,1500) every other three pixels
3316 + * [1500,2000) every other four pixels
3322 + setResampleStandard(poVDS, xSpace, ySpace);
3327 + GDALRasterBand *poBandLat = hLatDS->GetRasterBand(1);
3328 + GDALRasterBand *poBandLon = hLonDS->GetRasterBand(1);
3329 + GDALDataType eDT = poBandLat->GetRasterDataType();
3330 + void *dataLat = NULL;
3331 + void *dataLon = NULL;
3333 + mdSrcGeoMinX = 360;
3334 + mdSrcGeoMaxX = -360;
3335 + mdSrcGeoMinY = 90;
3336 + mdSrcGeoMaxY = -90;
3340 + case GDT_Float32: //For GOES Imager and Sounder data
3342 + dataLat = (float *) CPLMalloc(nXSize * sizeof(float));
3343 + dataLon = (float *) CPLMalloc(nXSize * sizeof(float));
3345 + for (int iLine = 0; iLine < nYSize; iLine += ySpace)
3347 + if (iLine >= nYSize)
3348 + iLine = nYSize - 1;
3350 + poBandLat->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLat, nXSize, 1, GDT_Float32, 0, 0);
3351 + poBandLon->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLon, nXSize, 1, GDT_Float32, 0, 0);
3353 + for (int iPixel = 0; iPixel < nXSize; iPixel += xSpace)
3355 + if(iPixel >= nXSize)
3356 + iPixel = nXSize - 1;
3357 + double x = *((float *) dataLon + iPixel);
3358 + double y = *((float *) dataLat + iPixel);
3359 + if (isValidLongitude(x) && isValidLatitude(y))
3362 + sprintf(pChr, "%d", ++nGCPs);
3363 + GDALInitGCPs(1, &gdalCGP);
3364 + gdalCGP.pszId = strdup(pChr);
3365 + gdalCGP.pszInfo = strdup("");
3366 + gdalCGP.dfGCPLine = iLine;
3367 + gdalCGP.dfGCPPixel = iPixel;
3368 + gdalCGP.dfGCPX = x;
3369 + gdalCGP.dfGCPY = y;
3370 + gdalCGP.dfGCPZ = 0;
3371 + m_gdalGCPs.push_back(gdalCGP);
3372 + mdSrcGeoMinX = MIN(mdSrcGeoMinX,gdalCGP.dfGCPX );
3373 + mdSrcGeoMaxX = MAX(mdSrcGeoMaxX,gdalCGP.dfGCPX);
3374 + mdSrcGeoMinY = MIN(mdSrcGeoMinY,gdalCGP.dfGCPY);
3375 + mdSrcGeoMaxY = MAX(mdSrcGeoMaxY,gdalCGP.dfGCPY);
3380 + VSIFree((float *) dataLat);
3381 + VSIFree((float *) dataLon);
3389 + GDALClose(hLatDS);
3390 + GDALClose(hLonDS);
3396 +/************************************************************************/
3397 +/* SetGDALDataset() */
3398 +/************************************************************************/
3401 + * \brief Set the GDALDataset object to GOES Imager and Sounder dataset.
3403 + * This method is used to set the GOES Imager and Sounder dataset based on GDAL
3404 + * class VRTDataset.
3406 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
3407 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
3409 + * @return CE_None on success or CE_Failure on failure.
3412 +CPLErr NC_GOES_Dataset::SetGDALDataset(const int isSimple)
3414 + for(int i = 1; i <= maptr_DS->GetRasterCount(); ++i)
3415 + mv_BandList.push_back(i);
3417 + VRTDataset *poVDS = (VRTDataset *)VRTCreate(mi_RectifiedImageXSize, mi_RectifiedImageYSize);
3418 + if (poVDS == NULL)
3420 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGDALDataset()");
3421 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to create VRT DataSet.");
3422 + return CE_Failure;
3425 + VRTSourcedRasterBand *poVRTBand = NULL;
3426 + GDALRasterBand *poSrcBand = NULL;
3427 + GDALDataType eBandType;
3428 + for (unsigned int i = 0; i < mv_BandList.size(); i++)
3430 + poSrcBand = maptr_DS->GetRasterBand(mv_BandList[i]);
3431 + eBandType = poSrcBand->GetRasterDataType();
3432 + poVDS->AddBand(eBandType, NULL);
3433 + poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand(i + 1);
3434 + poVRTBand->SetNoDataValue(md_MissingValue);
3436 + if (CE_None != poVRTBand->AddSimpleSource(poSrcBand, 0, 0,
3437 + mi_RectifiedImageXSize, mi_RectifiedImageYSize, 0, 0,
3438 + mi_RectifiedImageXSize, mi_RectifiedImageYSize, NULL, md_MissingValue))
3440 + GDALClose((GDALDatasetH) poVDS);
3441 + SetWCS_ErrorLocator("NC_GOES_Dataset::setGDALDataset()");
3442 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Add Simple Source into VRT DataSet.");
3443 + return CE_Failure;
3447 + //set GCPs for this VRTDataset
3448 + if (CE_None != SetGCPGeoRef4VRTDataset(poVDS))
3450 + GDALClose((GDALDatasetH) poVDS);
3451 + return CE_Failure;
3454 + GDALClose(maptr_DS.release());
3455 + maptr_DS.reset(poVDS);
3460 + return RectifyGOESDataSet();
3463 +/************************************************************************/
3464 +/* SetGCPGeoRef4VRTDataset() */
3465 +/************************************************************************/
3468 + * \brief Set the GCP array for the VRT dataset.
3470 + * This method is used to set the GCP array to created VRT dataset based on GDAL
3471 + * method SetGCPs().
3473 + * @param poVDS The VRT dataset.
3475 + * @return CE_None on success or CE_Failure on failure.
3478 +CPLErr NC_GOES_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
3480 + char* psTargetSRS;
3481 + mo_NativeCRS.exportToWkt(&psTargetSRS);
3483 +#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
3484 + if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS))
3486 + OGRFree(psTargetSRS);
3487 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
3488 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to set GCPs.");
3490 + return CE_Failure;
3494 + if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
3496 + OGRFree( psTargetSRS );
3497 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
3498 + WCS_Error(CE_Failure,OGC_WCS_NoApplicableCode,"Failed to set GCPs.");
3500 + return CE_Failure;
3505 + OGRFree(psTargetSRS);
3510 +/************************************************************************/
3511 +/* SetMetaDataList() */
3512 +/************************************************************************/
3515 + * \brief Set the metadata list for this coverage.
3517 + * The method will set the metadata list for the coverage based on its
3518 + * corresponding GDALDataset object.
3520 + * @param hSrc the GDALDataset object corresponding to coverage.
3522 + * @return CE_None on success or CE_Failure on failure.
3525 +CPLErr NC_GOES_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
3527 + mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
3528 + mv_MetaDataList.push_back("unit=GVAR");
3529 + mv_MetaDataList.push_back("FillValue=0");
3530 + ms_FieldQuantityDef = "GVAR";
3531 + ms_AllowRanges = "0 65535";
3532 + ms_CoveragePlatform = "GOES-11";
3533 + ms_CoverageInstrument = "GOES-11";
3534 + ms_CoverageSensor = "Imager";
3539 +/************************************************************************/
3540 +/* GetGeoMinMax() */
3541 +/************************************************************************/
3544 + * \brief Get the min/max coordinates of laitutude and longitude.
3546 + * The method will fetch the min/max coordinates of laitutude and longitude.
3548 + * @param geoMinMax an existing four double buffer into which the
3549 + * native geographical bounding box values will be placed.
3551 + * @return CE_None on success or CE_Failure on failure.
3554 +CPLErr NC_GOES_Dataset::GetGeoMinMax(double geoMinMax[])
3556 + if (!mb_GeoTransformSet)
3557 + return CE_Failure;
3559 + geoMinMax[0] = mdSrcGeoMinX;
3560 + geoMinMax[2] = mdSrcGeoMinY;
3561 + geoMinMax[1] = mdSrcGeoMaxX;
3562 + geoMinMax[3] = mdSrcGeoMaxY;
3567 +/************************************************************************/
3568 +/* GetGeoMinMax() */
3569 +/************************************************************************/
3572 + * \brief Convert the GOES dataset from satellite CRS project to grid CRS.
3574 + * The method will convert the GOES dataset from satellite CRS project to
3575 + * grid CRS based on GDAL API GDALReprojectImage;
3577 + * @return CE_None on success or CE_Failure on failure.
3580 +CPLErr NC_GOES_Dataset::RectifyGOESDataSet()
3583 + mo_NativeCRS.exportToWkt(&pszDstWKT);
3585 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
3586 + GDALDataset* rectDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize,
3587 + mi_RectifiedImageYSize, maptr_DS->GetRasterCount(),
3588 + maptr_DS->GetRasterBand(1)->GetRasterDataType(), NULL);
3589 + if (NULL == rectDataSet)
3591 + GDALClose(poDriver);
3592 + OGRFree(pszDstWKT);
3593 + SetWCS_ErrorLocator("AbstractDataset::rectifyDataSet()");
3594 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode,
3595 + "Failed to create \"MEM\" dataSet.");
3597 + return CE_Failure;
3600 + rectDataSet->SetProjection(pszDstWKT);
3601 + rectDataSet->SetGeoTransform(md_Geotransform);
3603 + if (CE_None != GDALReprojectImage(maptr_DS.get(), NULL, rectDataSet,
3604 + pszDstWKT, GRA_NearestNeighbour, 0, 0.125, NULL, NULL, NULL))
3606 + GDALClose(rectDataSet);
3607 + GDALClose(poDriver);
3608 + OGRFree(pszDstWKT);
3609 + SetWCS_ErrorLocator("AbstractDataset::RectifyDataSet()");
3610 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode,
3611 + "Failed to re-project GOES data from satellite GCP CRS to geographical CRS.");
3613 + return CE_Failure;
3616 + OGRFree(pszDstWKT);
3617 + GDALClose(maptr_DS.release());
3619 + maptr_DS.reset(rectDataSet);
3624 diff -Nur bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.h bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.h
3625 --- bes-3.12.0/functions.orig/swath2grid/NC_GOES_Dataset.h 1970-01-01 01:00:00.000000000 +0100
3626 +++ bes-3.12.0/functions/swath2grid/NC_GOES_Dataset.h 2014-03-03 15:47:38.053566262 +0100
3628 +/******************************************************************************
3629 + * $Id: NC_GOES_Dataset.h 2011-07-19 16:24:00Z $
3631 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
3632 + * for Earth Observation: Open Source Reference Implementation
3633 + * Purpose: NC_GOES_Dataset class definition
3634 + * Author: Yuanzheng Shao, yshao3@gmu.edu
3636 + ******************************************************************************
3637 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
3639 + * Permission is hereby granted, free of charge, to any person obtaining a
3640 + * copy of this software and associated documentation files (the "Software"),
3641 + * to deal in the Software without restriction, including without limitation
3642 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3643 + * and/or sell copies of the Software, and to permit persons to whom the
3644 + * Software is furnished to do so, subject to the following conditions:
3646 + * The above copyright notice and this permission notice shall be included
3647 + * in all copies or substantial portions of the Software.
3649 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
3650 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3651 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
3652 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3653 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3654 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
3655 + * DEALINGS IN THE SOFTWARE.
3656 + ****************************************************************************/
3658 +#ifndef NC_GOES_DATASET_H_
3659 +#define NC_GOES_DATASET_H_
3662 +#include "AbstractDataset.h"
3663 +#include "wcsUtil.h"
3665 +using namespace std;
3667 +/************************************************************************/
3668 +/* ==================================================================== */
3669 +/* NC_GOES_Dataset */
3670 +/* ==================================================================== */
3671 +/************************************************************************/
3673 +//! NC_GOES_Dataset is a subclass of AbstractDataset, used to process NOAA GOES data.
3676 + * \class NC_GOES_Dataset "NC_GOES_Dataset.h"
3678 + * GOES satellites provide the kind of continuous monitoring necessary for
3679 + * intensive data analysis. They circle the Earth in a geosynchronous orbit,
3680 + * which means they orbit the equatorial plane of the Earth at a speed
3681 + * matching the Earth's rotation. This allows them to hover continuously
3682 + * over one position on the surface. The geosynchronous plane is about
3683 + * 35,800 km (22,300 miles) above the Earth, high enough to allow the
3684 + * satellites a full-disc view of the Earth. Because they stay above a
3685 + * fixed spot on the surface, they provide a constant vigil for the atmospheric
3686 + * "triggers" for severe weather conditions such as tornadoes, flash floods,
3687 + * hail storms, and hurricanes. When these conditions develop the GOES
3688 + * satellites are able to monitor storm development and track their movements.
3690 + * GOES satellite imagery is also used to estimate rainfall during
3691 + * the thunderstorms and hurricanes for flash flood warnings, as well
3692 + * as estimates snowfall accumulations and overall extent of snow cover.
3693 + * Such data help meteorologists issue winter storm warnings and spring
3694 + * snow melt advisories. Satellite sensors also detect ice fields and map
3695 + * the movements of sea and lake ice.
3697 + * For more inforamtion about NOAA GOES data, please access
3698 + * <a href=http://www.oso.noaa.gov/GOES/>http://www.oso.noaa.gov/GOES/</a>
3700 + * NC_GOES_Dataset is a subclass of AbstractDataset, which is used to
3701 + * process GOES Imager and Sounder products.
3704 +class NC_GOES_Dataset : public AbstractDataset
3707 + string m_ncLatDataSetName;
3708 + string m_ncLonDataSetName;
3709 + string m_ncCoverageIDName;
3710 + int mi_RectifiedImageXSize;
3711 + int mi_RectifiedImageYSize;
3712 + int mi_GoesSrcImageXSize;
3713 + int mi_GoesSrcImageYSize;
3715 + double mb_LatLonBBox[4];
3716 + double mdSrcGeoMinX;
3717 + double mdSrcGeoMinY;
3718 + double mdSrcGeoMaxX;
3719 + double mdSrcGeoMaxY;
3721 + vector<GDAL_GCP> m_gdalGCPs;
3724 + CPLErr SetGCPGeoRef4VRTDataset(GDALDataset* );
3725 + CPLErr SetGeoBBoxAndGCPs(GDALDataset* hSrcDS);
3726 + CPLErr RectifyGOESDataSet();
3727 + CPLErr setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue);
3729 + int isValidLatitude(const double &lat)
3731 + return (lat >= -90 && lat <= 90);
3733 + int isValidLongitude(const double &lon)
3735 + return (lon >= -180 && lon <= 180);
3738 + virtual CPLErr SetGeoTransform();
3739 + virtual CPLErr SetMetaDataList(GDALDataset* hSrcDS);
3740 + virtual CPLErr SetNativeCRS();
3741 + virtual CPLErr SetGDALDataset(const int isSimple=0);
3742 + virtual CPLErr InitialDataset(const int isSimple=0);
3743 + virtual CPLErr GetGeoMinMax(double geoMinMax[]);
3746 + NC_GOES_Dataset();
3747 + NC_GOES_Dataset(const string& id, vector<int> &rBandList);
3748 + virtual ~NC_GOES_Dataset();
3751 +#endif /* NC_GOES_DATASET_H_ */
3752 diff -Nur bes-3.12.0/functions.orig/swath2grid/reproj_functions.cc bes-3.12.0/functions/swath2grid/reproj_functions.cc
3753 --- bes-3.12.0/functions.orig/swath2grid/reproj_functions.cc 1970-01-01 01:00:00.000000000 +0100
3754 +++ bes-3.12.0/functions/swath2grid/reproj_functions.cc 2014-03-03 15:47:38.056899595 +0100
3756 +// -*- mode: c++; c-basic-offset:4 -*-
3758 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
3759 +// Access Protocol.
3761 +// Copyright (c) 2002,2003 OPeNDAP, Inc.
3762 +// Author: James Gallagher <jgallagher@opendap.org>
3764 +// This library is free software; you can redistribute it and/or
3765 +// modify it under the terms of the GNU Lesser General Public
3766 +// License as published by the Free Software Foundation; either
3767 +// version 2.1 of the License, or (at your option) any later version.
3769 +// This library is distributed in the hope that it will be useful,
3770 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
3771 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3772 +// Lesser General Public License for more details.
3774 +// You should have received a copy of the GNU Lesser General Public
3775 +// License along with this library; if not, write to the Free Software
3776 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3778 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
3780 +// (c) COPYRIGHT URI/MIT 1999
3781 +// Please read the full copyright statement in the file COPYRIGHT_URI.
3784 +// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
3787 +// These functions are used by the CE evaluator
3791 +#include "config.h"
3793 +#include <limits.h>
3796 +#include <cstdlib> // used by strtod()
3800 +#include <iostream>
3803 +#include <algorithm>
3806 +// #include <gdal.h>
3807 +// #include <gdal_priv.h>
3811 +#include "BaseType.h"
3820 +#include "DAP_Dataset.h"
3821 +#include "reproj_functions.h"
3823 +// We wrapped VC++ 6.x strtod() to account for a short coming
3824 +// in that function in regards to "NaN". I don't know if this
3825 +// still applies in more recent versions of that product.
3829 +double w32strtod(const char *, char **);
3832 +using namespace std;
3833 +//using namespace libdap;
3838 + * @todo The lat and lon arrays are passed in, but there's an assumption that the
3839 + * source data array and the two lat and lon arrays are the same shape. But the
3840 + * code does not actually test that.
3842 + * @todo Enable multiple bands paired with just the two lat/lon arrays? Not sure
3843 + * if that is a good idea...
3845 +void function_swath2array(int argc, BaseType * argv[], DDS &, BaseType **btpp)
3847 + DBG(cerr << "Entering function_swath2array..." << endl);
3849 + // Use the same documentation for both swath2array and swath2grid
3850 + string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
3851 + + "<function name=\"swath2array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid\">\n"
3852 + + "</function>\n";
3855 + Str *response = new Str("info");
3856 + response->set_value(info);
3861 + // TODO Add optional fourth arg that lets the caller say which datum to use;
3862 + // default to WGS84
3864 + throw Error("The function swath2array() requires three arguments. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3866 + Array *src = dynamic_cast<Array*>(argv[0]);
3868 + throw Error("The first argument to swath2array() must be a data array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3870 + Array *lat = dynamic_cast<Array*>(argv[1]);
3872 + throw Error("The second argument to swath2array() must be a latitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3874 + Array *lon = dynamic_cast<Array*>(argv[2]);
3876 + throw Error("The third argument to swath2array() must be a longitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3878 + // The args passed into the function using argv[] are deleted after the call.
3880 + DAP_Dataset ds(src, lat, lon);
3883 + ds.InitialDataset(0);
3885 + *btpp = ds.GetDAPArray();
3887 + catch (Error &e) {
3888 + DBG(cerr << "caught Error: " << e.get_error_message() << endl);
3892 + DBG(cerr << "caught unknown exception" << endl);
3900 + * @todo The lat and lon arrays are passed in, but there's an assumption that the
3901 + * source data array and the two lat and lon arrays are the same shape. But the
3902 + * code does not actually test that.
3904 + * @todo Enable multiple bands paired with just the two lat/lon arrays? Not sure
3905 + * if that is a good idea...
3907 +void function_swath2grid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
3909 + DBG(cerr << "Entering function_swath2grid..." << endl);
3911 + string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
3912 + + "<function name=\"swath2grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid\">\n"
3913 + + "</function>\n";
3916 + Str *response = new Str("info");
3917 + response->set_value(info);
3922 + // TODO Add optional fourth arg that lets the caller say which datum to use;
3923 + // default to WGS84
3925 + throw Error("The function swath2grid() requires three arguments. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3927 + Array *src = dynamic_cast<Array*>(argv[0]);
3929 + throw Error("The first argument to swath2grid() must be a data array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3931 + Array *lat = dynamic_cast<Array*>(argv[1]);
3933 + throw Error("The second argument to swath2grid() must be a latitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3935 + Array *lon = dynamic_cast<Array*>(argv[2]);
3937 + throw Error("The third argument to swath2grid() must be a longitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
3939 + // The args passed into the function using argv[] are deleted after the call.
3941 + DAP_Dataset ds(src, lat, lon);
3944 + ds.InitialDataset(0);
3946 + *btpp = ds.GetDAPGrid();
3948 + catch (Error &e) {
3949 + DBG(cerr << "caught Error: " << e.get_error_message() << endl);
3953 + DBG(cerr << "caught unknown exception" << endl);
3964 +} // namespace libdap
3965 diff -Nur bes-3.12.0/functions.orig/swath2grid/reproj_functions.h bes-3.12.0/functions/swath2grid/reproj_functions.h
3966 --- bes-3.12.0/functions.orig/swath2grid/reproj_functions.h 1970-01-01 01:00:00.000000000 +0100
3967 +++ bes-3.12.0/functions/swath2grid/reproj_functions.h 2014-03-03 15:47:38.043566262 +0100
3970 +// -*- mode: c++; c-basic-offset:4 -*-
3972 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
3973 +// Access Protocol.
3975 +// Copyright (c) 2002,2003 OPeNDAP, Inc.
3976 +// Author: James Gallagher <jgallagher@opendap.org>
3978 +// This library is free software; you can redistribute it and/or
3979 +// modify it under the terms of the GNU Lesser General Public
3980 +// License as published by the Free Software Foundation; either
3981 +// version 2.1 of the License, or (at your option) any later version.
3983 +// This library is distributed in the hope that it will be useful,
3984 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
3985 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3986 +// Lesser General Public License for more details.
3988 +// You should have received a copy of the GNU Lesser General Public
3989 +// License along with this library; if not, write to the Free Software
3990 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3992 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
3994 +// (c) COPYRIGHT URI/MIT 1999
3995 +// Please read the full copyright statement in the file COPYRIGHT_URI.
3998 +// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
4000 +// Declarations for CE functions.
4004 +#ifndef _reproj_functions_h
4005 +#define _reproj_functions_h
4007 +#include "BESAbstractModule.h"
4008 +#include "ServerFunction.h"
4009 +#include "ServerFunctionsList.h"
4013 +void function_swath2array(int argc, BaseType * argv[], DDS &, BaseType **btpp);
4014 +void function_swath2grid(int argc, BaseType * argv[], DDS &, BaseType **btpp);
4017 +class SwathToGrid: public libdap::ServerFunction {
4021 + setName("swath2grid");
4022 + setDescriptionString("This function echos back it's arguments as DAP data.");
4023 + setUsageString("swath2grid(dataArray, latitudeArray, longitudeArray)");
4024 + setRole("http://services.opendap.org/dap4/server-side-function/swath2grid");
4025 + setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
4026 + setFunction(libdap::function_swath2grid);
4027 + setVersion("1.0");
4029 + virtual ~SwathToGrid()
4035 +class SwathToArray: public libdap::ServerFunction {
4039 + setName("swath2array");
4040 + setDescriptionString("This function echos back it's arguments as DAP data.");
4041 + setUsageString("swath2array(dataArray, latitudeArray, longitudeArray)");
4042 + setRole("http://services.opendap.org/dap4/server-side-function/swath2array");
4043 + setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2array");
4044 + setFunction(libdap::function_swath2array);
4045 + setVersion("1.0");
4047 + virtual ~SwathToArray()
4054 +class ReProjectionFunctions: public BESAbstractModule {
4056 + ReProjectionFunctions()
4058 + libdap::ServerFunctionsList::TheList()->add_function(new libdap::SwathToGrid());
4060 + libdap::ServerFunctionsList::TheList()->add_function(new libdap::SwathToArray());
4063 + virtual ~ReProjectionFunctions()
4066 + virtual void initialize(const string &modname);
4067 + virtual void terminate(const string &modname);
4069 + virtual void dump(ostream &strm) const;
4075 +} // namespace libdap
4077 +#endif // _reproj_functions_h
4078 diff -Nur bes-3.12.0/functions.orig/swath2grid/s2gTest.cc bes-3.12.0/functions/swath2grid/s2gTest.cc
4079 --- bes-3.12.0/functions.orig/swath2grid/s2gTest.cc 1970-01-01 01:00:00.000000000 +0100
4080 +++ bes-3.12.0/functions/swath2grid/s2gTest.cc 2014-03-03 15:47:38.043566262 +0100
4083 +// -*- mode: c++; c-basic-offset:4 -*-
4085 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
4086 +// Access Protocol.
4088 +// Copyright (c) 2012 OPeNDAP, Inc.
4089 +// Author: James Gallagher <jgallagher@opendap.org>
4091 +// This library is free software; you can redistribute it and/or
4092 +// modify it under the terms of the GNU Lesser General Public
4093 +// License as published by the Free Software Foundation; either
4094 +// version 2.1 of the License, or (at your option) any later version.
4096 +// This library is distributed in the hope that it will be useful,
4097 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
4098 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4099 +// Lesser General Public License for more details.
4101 +// You should have received a copy of the GNU Lesser General Public
4102 +// License along with this library; if not, write to the Free Software
4103 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4105 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
4107 +// Tests for the AISResources class.
4109 +#include <cppunit/TextTestRunner.h>
4110 +#include <cppunit/extensions/TestFactoryRegistry.h>
4111 +#include <cppunit/extensions/HelperMacros.h>
4114 +//#define DODS_DEBUG2
4116 +#include "BaseType.h"
4120 +#include "reproj_functions.h"
4122 +#include "test/TestTypeFactory.h"
4127 +#define THREE_ARRAY_1_DDS "three_array_1.dds"
4128 +#define THREE_ARRAY_1_DAS "three_array_1.das"
4130 +using namespace CppUnit;
4131 +using namespace libdap;
4132 +using namespace std;
4134 +int test_variable_sleep_interval = 0;
4137 + * Splits the string on the passed char. Returns vector of substrings.
4138 + * TODO make this work on situations where multiple spaces doesn't hose the split()
4140 +static vector<string> &split(const string &s, char delim, vector<string> &elems) {
4141 + stringstream ss(s);
4143 + while (getline(ss, item, delim)) {
4144 + elems.push_back(item);
4150 + * Splits the string on the passed char. Returns vector of substrings.
4152 +static vector<string> split(const string &s, char delim = ' ') {
4153 + vector<string> elems;
4154 + return split(s, delim, elems);
4157 +class s2gTest:public TestFixture
4161 + TestTypeFactory btf;
4162 + ConstraintEvaluator ce;
4172 + dds = new DDS(&btf);
4173 + string dds_file = /*(string)TEST_SRC_DIR + "/" +*/ THREE_ARRAY_1_DDS ;
4174 + dds->parse(dds_file);
4176 + string das_file = /*(string)TEST_SRC_DIR + "/" +*/ THREE_ARRAY_1_DAS ;
4177 + das.parse(das_file);
4178 + dds->transfer_attributes(&das);
4180 + DBG(dds->print_xml(stderr, false, "noBlob"));
4182 + // Load values into the array variables
4183 + Array & t = dynamic_cast < Array & >(*dds->var("t"));
4184 + Array & lon = dynamic_cast < Array & >(*dds->var("lon"));
4185 + Array & lat = dynamic_cast < Array & >(*dds->var("lat"));
4187 + dods_float64 t_vals[10][10];
4188 + for (int i = 0; i < 10; ++i)
4189 + for (int j = 0; j < 10; ++j)
4190 + t_vals[i][j] = j + (i * 10);
4191 + t.set_value(&t_vals[0][0], 100);
4192 + t.set_read_p(true);
4194 + // Read real lat/lon values from a Level 1B file ascii dump
4195 + fstream input("AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz.ascii.txt", fstream::in);
4196 + if (input.eof() || input.fail())
4197 + throw Error("Could not open lat/lon data in SetUp.");
4198 + // Read a line of text to get to the start of the data.
4200 + getline(input, line);
4201 + if (input.eof() || input.fail())
4202 + throw Error("Could not read lat/lon data in SetUp.");
4204 + dods_float64 lon_vals[10][10];
4205 + for (int i = 0; i < 10; ++i) {
4206 + getline(input, line);
4207 + if (input.eof() || input.fail())
4208 + throw Error("Could not read lon data from row " + long_to_string(i) + " in SetUp.");
4209 + vector<string> vals = split(line, ',');
4210 + for (unsigned int j = 1; j < vals.size(); ++j) {
4211 + DBG2(cerr << "loading in lon value: " << vals[j] << "' " << atof(vals[j].c_str()) << endl;)
4212 + lon_vals[i][j-1] = atof(vals[j].c_str());
4215 + lon.set_value(&lon_vals[0][0], 100);
4216 + lon.set_read_p(true);
4218 + dods_float64 lat_vals[10][10];
4219 + for (int i = 0; i < 10; ++i) {
4220 + getline(input, line);
4221 + if (input.eof() || input.fail())
4222 + throw Error("Could not read lat data from row " + long_to_string(i) + " in SetUp.");
4223 + vector<string> vals = split(line, ',');
4224 + for (unsigned int j = 1; j < vals.size(); ++j) {
4225 + DBG2(cerr << "loading in lat value: " << vals[j] << "' " << atof(vals[j].c_str()) << endl;)
4226 + lat_vals[i][j-1] = atof(vals[j].c_str());
4229 + lat.set_value(&lat_vals[0][0], 100);
4230 + lat.set_read_p(true);
4233 + catch (Error & e) {
4234 + cerr << "SetUp (Error): " << e.get_error_message() << endl;
4237 + catch(std::exception &e) {
4238 + cerr << "SetUp (std::exception): " << e.what() << endl;
4245 + delete dds; dds = 0;
4248 + CPPUNIT_TEST_SUITE( s2gTest );
4250 + CPPUNIT_TEST(no_arguments_test);
4251 + CPPUNIT_TEST(array_return_test);
4252 + CPPUNIT_TEST(grid_return_test);
4254 + CPPUNIT_TEST_SUITE_END();
4256 + void no_arguments_test()
4259 + BaseType *btp = 0;
4260 + function_swath2array(0, 0, *dds, &btp);
4261 + CPPUNIT_ASSERT(true);
4263 + catch (Error &e) {
4264 + DBG(cerr << e.get_error_message() << endl);
4265 + CPPUNIT_ASSERT(!"no_arguments_test() should not have failed");
4269 + void array_return_test()
4272 + BaseType *argv[3];
4273 + argv[0] = dds->var("t");
4274 + argv[1] = dds->var("lon");
4275 + argv[2] = dds->var("lat");
4277 + BaseType *btp = 0;
4278 + function_swath2array(3, argv, *dds, &btp);
4280 + DBG(cerr << "btp->name(): " << btp->name() << endl);
4281 + CPPUNIT_ASSERT(btp->name() == "t");
4282 + CPPUNIT_ASSERT(btp->type() == dods_array_c);
4284 + // Extract data; I know it's 10x16 from debugging output
4285 + dods_float64 values[10][16];
4286 + Array *a = static_cast<Array*>(btp);
4287 + a->value(&values[0][0]);
4289 + catch (Error &e) {
4290 + DBG(cerr << e.get_error_message() << endl);
4291 + CPPUNIT_FAIL("array_return_test");
4296 + void one_argument_not_a_grid_test()
4299 + BaseType *argv[1];
4300 + argv[0] = dds->var("lat");
4301 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this, although it is not a grid");
4302 + BaseType *btp = 0;
4303 + function_grid(1, argv, *dds, &btp);
4304 + CPPUNIT_ASSERT(!"one_argument_not_a_grid_test() should have failed");
4306 + catch (Error &e) {
4307 + DBG(cerr << e.get_error_message() << endl);
4308 + CPPUNIT_ASSERT(true);
4312 + void map_not_in_grid_test()
4315 + BaseType *argv[2];
4316 + argv[0] = dds->var("a");
4317 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4318 + argv[1] = new Str("");
4319 + string expression = "3<second<=7";
4320 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4321 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4322 + BaseType *btp = 0;
4323 + function_grid(2, argv, *dds, &btp);
4324 + CPPUNIT_ASSERT(!"map_not_in_grid_test() should have failed");
4326 + catch (Error &e) {
4327 + DBG(cerr << e.get_error_message() << endl);
4328 + CPPUNIT_ASSERT(true);
4332 + void one_dim_grid_test()
4335 + BaseType *argv[2];
4336 + argv[0] = dds->var("a");
4337 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4338 + argv[1] = new Str("");
4339 + string expression = "3<first<=7";
4340 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4341 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4343 + BaseType *btp = 0;
4344 + function_grid(2, argv, *dds, &btp);
4345 + Grid &g = dynamic_cast<Grid&>(*btp);
4347 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
4348 + Array &m = dynamic_cast<Array&>(**g.map_begin());
4349 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
4350 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
4352 + catch (Error &e) {
4353 + DBG(cerr << e.get_error_message() << endl);
4354 + CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
4358 + void one_dim_grid_two_expressions_test()
4361 + BaseType *argv[3];
4362 + argv[0] = dds->var("a");
4363 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4365 + argv[1] = new Str("");
4366 + string expression = "first>3";
4367 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4368 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4370 + argv[2] = new Str("");
4371 + expression = "first<=7";
4372 + dynamic_cast<Str*>(argv[2])->val2buf(&expression);
4373 + dynamic_cast<Str*>(argv[2])->set_read_p(true);
4375 + //function_grid(3, argv, *dds);
4376 + BaseType *btp = 0;
4377 + function_grid(3, argv, *dds, &btp);
4378 + Grid &g = dynamic_cast<Grid&>(*btp);
4380 + //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
4381 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
4382 + Array &m = dynamic_cast<Array&>(**g.map_begin());
4383 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
4384 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
4386 + catch (Error &e) {
4387 + DBG(cerr << e.get_error_message() << endl);
4388 + CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
4392 + void one_dim_grid_descending_test()
4395 + BaseType *argv[2];
4396 + argv[0] = dds->var("b");
4397 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4398 + argv[1] = new Str("");
4399 + string expression = "3<first<=7";
4400 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4401 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4403 + BaseType *btp = 0;
4404 + function_grid(2, argv, *dds, &btp);
4405 + Grid &g = dynamic_cast<Grid&>(*btp);
4407 + //function_grid(2, argv, *dds);
4408 + //Grid &g = dynamic_cast<Grid&>(*function_grid(2, argv, *dds));
4409 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
4410 + Array &m = dynamic_cast<Array&>(**g.map_begin());
4411 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
4412 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
4414 + catch (Error &e) {
4415 + DBG(cerr << e.get_error_message() << endl);
4416 + CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
4420 + void one_dim_grid_two_expressions_descending_test()
4423 + BaseType *argv[3];
4424 + argv[0] = dds->var("b");
4425 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4427 + argv[1] = new Str("");
4428 + string expression = "first>3";
4429 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4430 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4432 + argv[2] = new Str("");
4433 + expression = "first<=7";
4434 + dynamic_cast<Str*>(argv[2])->val2buf(&expression);
4435 + dynamic_cast<Str*>(argv[2])->set_read_p(true);
4437 + BaseType *btp = 0;
4438 + function_grid(3, argv, *dds, &btp);
4439 + Grid &g = dynamic_cast<Grid&>(*btp);
4441 + //function_grid(3, argv, *dds);
4442 + //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
4443 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
4444 + Array &m = dynamic_cast<Array&>(**g.map_begin());
4445 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
4446 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
4448 + catch (Error &e) {
4449 + DBG(cerr << e.get_error_message() << endl);
4450 + CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
4454 + void one_dim_grid_noninclusive_values_test()
4457 + BaseType *argv[2];
4458 + argv[0] = dds->var("a");
4459 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4460 + argv[1] = new Str("");
4461 + string expression = "7<first<=3";
4462 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4463 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4465 + BaseType *btp = 0;
4466 + function_grid(2, argv, *dds, &btp);
4467 + //Grid &g = dynamic_cast<Grid&>(*btp);
4469 + // function_grid(2, argv, *dds);
4471 + CPPUNIT_ASSERT(!"one_dim_grid_noninclusive_values_test() should not have worked");
4473 + catch (Error &e) {
4474 + DBG(cerr << e.get_error_message() << endl);
4475 + CPPUNIT_ASSERT(true);
4479 + // grid() is not required to handle this case. This test is not used.
4480 + void values_outside_map_range_test()
4483 + BaseType *argv[2];
4484 + argv[0] = dds->var("a");
4485 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
4486 + argv[1] = new Str("");
4487 + string expression = "3<=first<20";
4488 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
4489 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
4491 + BaseType *btp = 0;
4492 + function_grid(2, argv, *dds, &btp);
4493 + //Grid &g = dynamic_cast<Grid&>(*btp);
4495 + // function_grid(2, argv, *dds);
4497 + CPPUNIT_ASSERT(!"values_outside_map_range_test() should not have worked");
4499 + catch (Error &e) {
4500 + DBG(cerr << e.get_error_message() << endl);
4501 + CPPUNIT_ASSERT(true);
4505 + // linear_scale tests
4506 + void linear_scale_args_test() {
4508 + BaseType *btp = 0;
4509 + function_linear_scale(0, 0, *dds, &btp);
4510 + CPPUNIT_ASSERT(true);
4512 + catch (Error &e) {
4513 + DBG(cerr << e.get_error_message() << endl);
4514 + CPPUNIT_ASSERT(!"linear_scale_args_test: should not throw Error");
4518 + void linear_scale_array_test() {
4520 + Array *a = dynamic_cast<Grid&>(*dds->var("a")).get_array();
4521 + CPPUNIT_ASSERT(a);
4522 + BaseType *argv[3];
4524 + argv[1] = new Float64("");
4525 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
4526 + argv[2] = new Float64("");
4527 + dynamic_cast<Float64*>(argv[2])->set_value(10);//b
4528 + BaseType *scaled = 0;
4529 + function_linear_scale(3, argv, *dds, &scaled);
4530 + CPPUNIT_ASSERT(scaled->type() == dods_array_c
4531 + && scaled->var()->type() == dods_float64_c);
4532 + double *values = extract_double_array(dynamic_cast<Array*>(scaled));
4533 + CPPUNIT_ASSERT(values[0] == 10);
4534 + CPPUNIT_ASSERT(values[1] == 10.1);
4535 + CPPUNIT_ASSERT(values[9] == 10.9);
4537 + catch (Error &e) {
4538 + DBG(cerr << e.get_error_message() << endl);
4539 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
4543 + void linear_scale_grid_test() {
4545 + Grid *g = dynamic_cast<Grid*>(dds->var("a"));
4546 + CPPUNIT_ASSERT(g);
4547 + BaseType *argv[3];
4549 + argv[1] = new Float64("");
4550 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);
4551 + argv[2] = new Float64("");
4552 + dynamic_cast<Float64*>(argv[2])->set_value(10);
4553 + BaseType *scaled = 0;
4554 + function_linear_scale(3, argv, *dds, &scaled);
4555 + CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
4556 + Grid *g_s = dynamic_cast<Grid*>(scaled);
4557 + CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
4558 + double *values = extract_double_array(g_s->get_array());
4559 + CPPUNIT_ASSERT(values[0] == 10);
4560 + CPPUNIT_ASSERT(values[1] == 10.1);
4561 + CPPUNIT_ASSERT(values[9] == 10.9);
4563 + catch (Error &e) {
4564 + DBG(cerr << e.get_error_message() << endl);
4565 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
4569 + void linear_scale_grid_attributes_test() {
4571 + Grid *g = dynamic_cast<Grid*>(dds->var("a"));
4572 + CPPUNIT_ASSERT(g);
4573 + BaseType *argv[1];
4575 + BaseType *scaled = 0;
4576 + function_linear_scale(1, argv, *dds, &scaled);
4577 + CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
4578 + Grid *g_s = dynamic_cast<Grid*>(scaled);
4579 + CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
4580 + double *values = extract_double_array(g_s->get_array());
4581 + CPPUNIT_ASSERT(values[0] == 10);
4582 + CPPUNIT_ASSERT(values[1] == 10.1);
4583 + CPPUNIT_ASSERT(values[9] == 10.9);
4585 + catch (Error &e) {
4586 + DBG(cerr << e.get_error_message() << endl);
4587 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
4591 + // This tests the case where attributes are not found
4592 + void linear_scale_grid_attributes_test2() {
4594 + Grid *g = dynamic_cast<Grid*>(dds->var("b"));
4595 + CPPUNIT_ASSERT(g);
4596 + BaseType *argv[1];
4598 + BaseType *btp = 0;
4599 + function_linear_scale(1, argv, *dds, &btp);
4600 + CPPUNIT_FAIL("Should not get here; no params passed and no attributes set for grid 'b'");
4602 + catch (Error &e) {
4603 + DBG(cerr << e.get_error_message() << endl);
4604 + CPPUNIT_ASSERT("Caught exception");
4608 + void linear_scale_scalar_test() {
4610 + Int32 *i = new Int32("linear_scale_test_int32");
4611 + CPPUNIT_ASSERT(i);
4613 + BaseType *argv[3];
4615 + argv[1] = new Float64("");
4616 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
4617 + argv[2] = new Float64("");
4618 + dynamic_cast<Float64*>(argv[2])->set_value(10);//b
4619 + BaseType *scaled = 0;
4620 + function_linear_scale(3, argv, *dds, &scaled);
4621 + CPPUNIT_ASSERT(scaled->type() == dods_float64_c);
4623 + CPPUNIT_ASSERT(dynamic_cast<Float64*>(scaled)->value() == 10.1);
4625 + catch (Error &e) {
4626 + DBG(cerr << e.get_error_message() << endl);
4627 + CPPUNIT_ASSERT(!"Error in linear_scale_scalar_test()");
4632 + void function_dap_1_test() {
4634 + Int32 *i = new Int32("function_dap_1_test_int32");
4635 + CPPUNIT_ASSERT(i);
4637 + BaseType *argv[1];
4640 + ConstraintEvaluator unused;
4641 + function_dap(1, argv, *dds, unused);
4643 + CPPUNIT_ASSERT(dds->get_dap_major() == 2);
4644 + CPPUNIT_ASSERT(dds->get_dap_minor() == 0);
4646 + catch (Error &e) {
4647 + DBG(cerr << e.get_error_message() << endl);
4648 + CPPUNIT_FAIL("Error in function_dap_1_test(): " + e.get_error_message());
4652 + void function_dap_2_test() {
4654 + Float64 *d = new Float64("function_dap_1_test_float64");
4655 + CPPUNIT_ASSERT(d);
4656 + d->set_value(3.2);
4657 + BaseType *argv[1];
4660 + ConstraintEvaluator unused;
4661 + function_dap(1, argv, *dds, unused);
4663 + CPPUNIT_ASSERT(dds->get_dap_major() == 3);
4664 + CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
4666 + catch (Error &e) {
4667 + DBG(cerr << e.get_error_message() << endl);
4668 + CPPUNIT_FAIL("Error in function_dap_2_test(): " + e.get_error_message());
4672 + void function_dap_3_test() {
4674 + cerr <<"In function_dap_3_test" << endl;
4675 + ConstraintEvaluator unused;
4676 + function_dap(0, 0, *dds, unused);
4678 + CPPUNIT_FAIL("Should have thrown an exception on no args");
4680 + catch (Error &e) {
4681 + DBG(cerr << e.get_error_message() << endl);
4682 + CPPUNIT_ASSERT("Pass: Caught exception");
4686 + void grid_return_test()
4689 + BaseType *argv[3];
4690 + argv[0] = dds->var("t");
4691 + argv[1] = dds->var("lon");
4692 + argv[2] = dds->var("lat");
4694 + cerr << "Input values:" << endl;
4695 + dods_float64 t_vals[10][10];
4696 + Array *a = static_cast<Array*>(argv[0]);
4697 + a->value(&t_vals[0][0]);
4698 + for (int i = 0; i < 10; ++i) {
4699 + for (int j = 0; j < 10; ++j) {
4700 + cerr << "t[" << i << "][" << j << "]: " << t_vals[i][j] << endl;
4704 + BaseType *btp = 0;
4705 + function_swath2grid(3, argv, *dds, &btp);
4707 + DBG(cerr << "btp->name(): " << btp->name() << endl);
4708 + CPPUNIT_ASSERT(btp->name() == "t");
4709 + CPPUNIT_ASSERT(btp->type() == dods_grid_c);
4711 + // Extract data; I know it's 10x16 from debugging output
4712 + dods_float64 values[10][16];
4713 + Grid *g = static_cast<Grid*>(btp);
4714 + g->get_array()->value(&values[0][0]);
4716 + Grid::Map_iter m = g->map_begin();
4717 + dods_float64 lat[10];
4718 + static_cast<Array*>(*m)->value(&lat[0]);
4721 + dods_float64 lon[16];
4722 + static_cast<Array*>(*m)->value(&lon[0]);
4724 + cerr << "Output values:" << endl;
4725 + for (int i = 0; i < 10; ++i) {
4726 + for (int j = 0; j < 16; ++j) {
4727 + cerr << "t[" << i << "][" << j << "] == lon: " << lon[j] << ", lat: " << lat[i] << " val: " << values[i][j] << endl;
4731 + catch (Error &e) {
4732 + DBG(cerr << e.get_error_message() << endl);
4733 + CPPUNIT_FAIL("array_return_test");
4738 +CPPUNIT_TEST_SUITE_REGISTRATION(s2gTest);
4741 +main( int, char** )
4743 + CppUnit::TextTestRunner runner;
4744 + runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
4746 + bool wasSuccessful = runner.run( "", false ) ;
4748 + return wasSuccessful ? 0 : 1;
4750 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/entries bes-3.12.0/functions/swath2grid/.svn/entries
4751 --- bes-3.12.0/functions.orig/swath2grid/.svn/entries 1970-01-01 01:00:00.000000000 +0100
4752 +++ bes-3.12.0/functions/swath2grid/.svn/entries 2014-03-03 15:47:34.366899750 +0100
4755 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/format bes-3.12.0/functions/swath2grid/.svn/format
4756 --- bes-3.12.0/functions.orig/swath2grid/.svn/format 1970-01-01 01:00:00.000000000 +0100
4757 +++ bes-3.12.0/functions/swath2grid/.svn/format 2014-03-03 15:47:34.366899750 +0100
4760 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/2c/2c1fb68452ecaa4ec099ab4ec2c2a3a62c6aa0d9.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/2c/2c1fb68452ecaa4ec099ab4ec2c2a3a62c6aa0d9.svn-base
4761 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/2c/2c1fb68452ecaa4ec099ab4ec2c2a3a62c6aa0d9.svn-base 1970-01-01 01:00:00.000000000 +0100
4762 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/2c/2c1fb68452ecaa4ec099ab4ec2c2a3a62c6aa0d9.svn-base 2014-03-03 15:47:37.593566281 +0100
4764 +/******************************************************************************
4765 + * $Id: wcs_error.cpp 2011-07-19 16:24:00Z $
4767 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
4768 + * for Earth Observation: Open Source Reference Implementation
4769 + * Purpose: WCS exception and error handler implementation, used to set
4770 + * the exception code and locator of WCS
4771 + * Author: Yuanzheng Shao, yshao3@gmu.edu
4773 + ******************************************************************************
4774 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
4776 + * Permission is hereby granted, free of charge, to any person obtaining a
4777 + * copy of this software and associated documentation files (the "Software"),
4778 + * to deal in the Software without restriction, including without limitation
4779 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4780 + * and/or sell copies of the Software, and to permit persons to whom the
4781 + * Software is furnished to do so, subject to the following conditions:
4783 + * The above copyright notice and this permission notice shall be included
4784 + * in all copies or substantial portions of the Software.
4786 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4787 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4788 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4789 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4790 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4791 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
4792 + * DEALINGS IN THE SOFTWARE.
4793 + ****************************************************************************/
4795 +#include "wcs_error.h"
4797 +static string WCS_ERROR_STRING="";
4798 +static string ERROR_LOCATOR="";
4799 +static string ExcptCodeText[] =
4801 + "OperationNotSupported",
4802 + "MissingParameterValue",
4803 + "InvalidParameterValue",
4804 + "VersionNegotiationFailed",
4805 + "InvalidUpdateSequence",
4806 + "OptionNotSupported",
4807 + "NoApplicableCode",
4809 + "InvalidAxisLabel",
4810 + "InvalidSubsetting"
4813 +static int WCS_IsSoapMessage_Transform = 0;
4815 +string CPL_STDCALL GetWCS_ErrorMsg()
4817 + return WCS_ERROR_STRING;
4820 +void CPL_STDCALL SetWCS_ErrorLocator(const char* loc)
4822 + ERROR_LOCATOR = loc;
4825 +void CPL_STDCALL WCS_ErrorHandler(CPLErr eErrClass,int err_no,const char *pszErrorMsg )
4827 + WCS_ERROR_STRING.clear();
4830 + if(err_no >= 300 && err_no <= 309)
4831 + ExcCode = ExcptCodeText[err_no - 300];
4833 + ExcCode = ExcptCodeText[6];
4835 + if(WCS_IsSoapMessage_Transform)
4837 + WCS_ERROR_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
4838 + WCS_ERROR_STRING += "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n";
4839 + WCS_ERROR_STRING += "<soap:Body>\n";
4840 + WCS_ERROR_STRING += "<ExceptionReport xmlns=\"http://www.opengis.net/ows\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
4841 + WCS_ERROR_STRING += "xsi:schemaLocation=\"http://www.opengis.net/ows/owsCommon.xsd\" version=\"0.3.20\" language=\"en\">\n";
4842 + WCS_ERROR_STRING += " <Exception exceptionCode=\"";
4843 + WCS_ERROR_STRING += ExcCode;
4844 + WCS_ERROR_STRING += "\" locator=\"";
4845 + WCS_ERROR_STRING += ERROR_LOCATOR;
4846 + WCS_ERROR_STRING += "\">\n";
4847 + WCS_ERROR_STRING += " <ExceptionText>" + string(pszErrorMsg) + "</ExceptionText>\n";
4848 + WCS_ERROR_STRING += " </Exception>\n";
4849 + WCS_ERROR_STRING += "</ExceptionReport>\n";
4850 + WCS_ERROR_STRING += "/soap:Body>\n";
4851 + WCS_ERROR_STRING += "/<soap:Envelope>\n";
4855 + WCS_ERROR_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
4856 + WCS_ERROR_STRING += "<ExceptionReport xmlns=\"http://www.opengis.net/ows\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
4857 + WCS_ERROR_STRING += "xsi:schemaLocation=\"http://www.opengis.net/ows/owsCommon.xsd\" version=\"0.3.20\" language=\"en\">\n";
4858 + WCS_ERROR_STRING += " <Exception exceptionCode=\"";
4859 + WCS_ERROR_STRING += ExcCode;
4860 + WCS_ERROR_STRING += "\" locator=\"";
4861 + WCS_ERROR_STRING += ERROR_LOCATOR;
4862 + WCS_ERROR_STRING += "\">\n";
4863 + WCS_ERROR_STRING += " <ExceptionText>" + string(pszErrorMsg) + "</ExceptionText>\n";
4864 + WCS_ERROR_STRING += " </Exception>\n";
4865 + WCS_ERROR_STRING += "</ExceptionReport>\n";
4871 +void WCST_SetSoapMsgTrns(int isSoap)
4873 + WCS_IsSoapMessage_Transform = isSoap;
4876 +int WCST_GetSoapMsgTrns()
4878 + return WCS_IsSoapMessage_Transform;
4880 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/37/3738e631c59c1f5cded9ac6457cfcb35d402dba7.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/37/3738e631c59c1f5cded9ac6457cfcb35d402dba7.svn-base
4881 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/37/3738e631c59c1f5cded9ac6457cfcb35d402dba7.svn-base 1970-01-01 01:00:00.000000000 +0100
4882 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/37/3738e631c59c1f5cded9ac6457cfcb35d402dba7.svn-base 2014-03-03 15:47:37.810232939 +0100
4884 +# three_array_1.dds
4886 +# Created on: Dec 12, 2012
4890 + Float64 t[10][10];
4891 + Float64 lon[10][10];
4892 + Float64 lat[10][10];
4894 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/54/5408a8ae104fd8000f1d7015e95b1848047c9f56.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/54/5408a8ae104fd8000f1d7015e95b1848047c9f56.svn-base
4895 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/54/5408a8ae104fd8000f1d7015e95b1848047c9f56.svn-base 1970-01-01 01:00:00.000000000 +0100
4896 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/54/5408a8ae104fd8000f1d7015e95b1848047c9f56.svn-base 2014-03-03 15:47:37.806899605 +0100
4898 +/******************************************************************************
4899 + * $Id: wcs_error.h 2011-07-19 16:24:00Z $
4901 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
4902 + * for Earth Observation: Open Source Reference Implementation
4903 + * Purpose: WCS exception and error handler definition
4904 + * Author: Yuanzheng Shao, yshao3@gmu.edu
4906 + ******************************************************************************
4907 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
4909 + * Permission is hereby granted, free of charge, to any person obtaining a
4910 + * copy of this software and associated documentation files (the "Software"),
4911 + * to deal in the Software without restriction, including without limitation
4912 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4913 + * and/or sell copies of the Software, and to permit persons to whom the
4914 + * Software is furnished to do so, subject to the following conditions:
4916 + * The above copyright notice and this permission notice shall be included
4917 + * in all copies or substantial portions of the Software.
4919 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4920 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4921 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4922 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4923 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4924 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
4925 + * DEALINGS IN THE SOFTWARE.
4926 + ****************************************************************************/
4928 +/************************************************************************
4929 + WCS Exception Code
4931 + See OGC Web Services Common Standard [OGC 06-121r9] for details
4932 + Table 27 — Standard exception codes and meanings
4933 + OperationNotSupported
4934 + MissingParameterValue
4935 + InvalidParameterValue
4936 + VersionNegotiationFailed
4937 + InvalidUpdateSequence
4938 + OptionNotSupported
4941 + See OGC® WCS 2.0 Interface Standard - Core [09-110r3] for details
4942 + Table 18 - Exception codes for GetCoverage operation
4947 +*************************************************************************/
4949 +#ifndef WCS_ERROR_H_
4950 +#define WCS_ERROR_H_
4952 +#include <cpl_error.h>
4955 +using namespace std;
4957 +#define OGC_WCS_OperationNotSupported 300
4958 +#define OGC_WCS_MissingParameterValue 301
4959 +#define OGC_WCS_InvalidParameterValue 302
4960 +#define OGC_WCS_VersionNegotiationFailed 303
4961 +#define OGC_WCS_InvalidUpdateSequence 304
4962 +#define OGC_WCS_OptionNotSupported 305
4963 +#define OGC_WCS_NoApplicableCode 306
4965 +#define OGC_WCS_NoSuchCoverage 307
4966 +#define OGC_WCS_InvalidAxisLabel 308
4967 +#define OGC_WCS_InvalidSubsetting 309
4969 +void CPL_DLL CPL_STDCALL WCS_Error(CPLErr, int, const char*, ...);
4970 +void CPL_DLL CPL_STDCALL SetWCS_ErrorLocator(const char* loc);
4971 +void CPL_DLL CPL_STDCALL WCS_ErrorHandler(CPLErr, int, const char*);
4972 +string CPL_DLL CPL_STDCALL GetWCS_ErrorMsg();
4974 +int WCST_GetSoapMsgTrns();
4975 +void WCST_SetSoapMsgTrns(int);
4977 +#define WCS_Error CPLError
4978 +#endif /* WCS_ERROR_H_ */
4979 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/55/552f5680f38631504c1a309d875c7bbbf2bc2492.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/55/552f5680f38631504c1a309d875c7bbbf2bc2492.svn-base
4980 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/55/552f5680f38631504c1a309d875c7bbbf2bc2492.svn-base 1970-01-01 01:00:00.000000000 +0100
4981 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/55/552f5680f38631504c1a309d875c7bbbf2bc2492.svn-base 2014-03-03 15:47:37.846899604 +0100
4984 +// -*- mode: c++; c-basic-offset:4 -*-
4986 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
4987 +// Access Protocol.
4989 +// Copyright (c) 2012 OPeNDAP, Inc.
4990 +// Author: James Gallagher <jgallagher@opendap.org>
4992 +// This library is free software; you can redistribute it and/or
4993 +// modify it under the terms of the GNU Lesser General Public
4994 +// License as published by the Free Software Foundation; either
4995 +// version 2.1 of the License, or (at your option) any later version.
4997 +// This library is distributed in the hope that it will be useful,
4998 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
4999 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5000 +// Lesser General Public License for more details.
5002 +// You should have received a copy of the GNU Lesser General Public
5003 +// License along with this library; if not, write to the Free Software
5004 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5006 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
5008 +#ifndef DAP_DATASET_H_
5009 +#define DAP_DATASET_H_
5012 +#include "AbstractDataset.h"
5013 +#include "wcsUtil.h"
5015 +using namespace std;
5022 +/************************************************************************/
5023 +/* ==================================================================== */
5025 +/* ==================================================================== */
5026 +/************************************************************************/
5028 +//! DAP_Dataset is a subclass of AbstractDataset, used to process NOAA GOES data.
5030 + * \class DAP_Dataset "DAP_Dataset.h"
5032 + * GOES satellites provide the kind of continuous monitoring necessary for
5033 + * intensive data analysis. They circle the Earth in a geosynchronous orbit,
5034 + * which means they orbit the equatorial plane of the Earth at a speed
5035 + * matching the Earth's rotation. This allows them to hover continuously
5036 + * over one position on the surface. The geosynchronous plane is about
5037 + * 35,800 km (22,300 miles) above the Earth, high enough to allow the
5038 + * satellites a full-disc view of the Earth. Because they stay above a
5039 + * fixed spot on the surface, they provide a constant vigil for the atmospheric
5040 + * "triggers" for severe weather conditions such as tornadoes, flash floods,
5041 + * hail storms, and hurricanes. When these conditions develop the GOES
5042 + * satellites are able to monitor storm development and track their movements.
5044 + * GOES satellite imagery is also used to estimate rainfall during
5045 + * the thunderstorms and hurricanes for flash flood warnings, as well
5046 + * as estimates snowfall accumulations and overall extent of snow cover.
5047 + * Such data help meteorologists issue winter storm warnings and spring
5048 + * snow melt advisories. Satellite sensors also detect ice fields and map
5049 + * the movements of sea and lake ice.
5051 + * For more inforamtion about NOAA GOES data, please access
5052 + * <a href=http://www.oso.noaa.gov/GOES/>http://www.oso.noaa.gov/GOES/</a>
5054 + * DAP_Dataset is a subclass of AbstractDataset, which is used to
5055 + * process GOES Imager and Sounder products.
5058 +class DAP_Dataset : public AbstractDataset {
5060 + string m_ncLatDataSetName;
5061 + string m_ncLonDataSetName;
5062 + string m_ncCoverageIDName;
5064 + // Instead of using names and opening files with GDAL,
5065 + // store pointers to Arrays read by the underlying DAP
5066 + // server constraint evaluator.
5071 + int mi_RectifiedImageXSize;
5072 + int mi_RectifiedImageYSize;
5073 + int mi_SrcImageXSize;
5074 + int mi_SrcImageYSize;
5076 + double mb_LatLonBBox[4];
5077 + double mdSrcGeoMinX;
5078 + double mdSrcGeoMinY;
5079 + double mdSrcGeoMaxX;
5080 + double mdSrcGeoMaxY;
5082 + // This is not set until GetDAPArray() is called.
5083 + double m_geo_transform_coef[6];
5085 + vector<GDAL_GCP> m_gdalGCPs;
5088 + CPLErr SetGCPGeoRef4VRTDataset(GDALDataset*);
5089 + void SetGeoBBoxAndGCPs(int xSize, int ySize);
5090 + CPLErr RectifyGOESDataSet();
5091 + CPLErr setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue);
5093 + int isValidLatitude(const double &lat)
5095 + return (lat >= -90 && lat <= 90);
5097 + int isValidLongitude(const double &lon)
5099 + return (lon >= -180 && lon <= 180);
5102 + virtual CPLErr SetGeoTransform();
5104 + virtual CPLErr SetMetaDataList(GDALDataset* hSrcDS); //TODO Remove
5106 + virtual CPLErr SetNativeCRS();
5107 + virtual CPLErr SetGDALDataset(const int isSimple = 0);
5108 + virtual CPLErr InitialDataset(const int isSimple = 0);
5109 + virtual CPLErr GetGeoMinMax(double geoMinMax[]);
5113 + DAP_Dataset(const string& id, vector<int> &rBandList);
5115 + // Added jhrg 11/23/12
5116 + DAP_Dataset(Array *src, Array *lat, Array *lon);
5117 + Array *GetDAPArray();
5118 + Grid *GetDAPGrid();
5120 + virtual ~DAP_Dataset();
5123 +} // namespace libdap
5124 +#endif /* DAP_DATASET_H_ */
5125 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/5c/5c131461ae16583ef4babcd3a87404f41769d430.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/5c/5c131461ae16583ef4babcd3a87404f41769d430.svn-base
5126 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/5c/5c131461ae16583ef4babcd3a87404f41769d430.svn-base 1970-01-01 01:00:00.000000000 +0100
5127 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/5c/5c131461ae16583ef4babcd3a87404f41769d430.svn-base 2014-03-03 15:47:37.633566281 +0100
5129 +/******************************************************************************
5130 + * $Id: AbstractDataset.cpp 2011-07-19 16:24:00Z $
5132 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
5133 + * for Earth Observation: Open Source Reference Implementation
5134 + * Purpose: AbstractDataset implementation for providing an abstract data
5135 + * model for multiple data source.
5136 + * Author: Yuanzheng Shao, yshao3@gmu.edu
5138 + ******************************************************************************
5139 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
5141 + * Permission is hereby granted, free of charge, to any person obtaining a
5142 + * copy of this software and associated documentation files (the "Software"),
5143 + * to deal in the Software without restriction, including without limitation
5144 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
5145 + * and/or sell copies of the Software, and to permit persons to whom the
5146 + * Software is furnished to do so, subject to the following conditions:
5148 + * The above copyright notice and this permission notice shall be included
5149 + * in all copies or substantial portions of the Software.
5151 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5152 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5153 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
5154 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5155 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
5156 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
5157 + * DEALINGS IN THE SOFTWARE.
5158 + ****************************************************************************/
5160 +#include "AbstractDataset.h"
5162 +/************************************************************************/
5163 +/* ==================================================================== */
5164 +/* AbstractDataset */
5165 +/* ==================================================================== */
5166 +/************************************************************************/
5169 + * \class AbstractDataset "AbstractDataset.h"
5171 + * An abstract dataset encapsulating one or more raster bands, which is
5172 + * based on GDALDataset, and add the support to metadata model: ISO 19115
5173 + * and 1SO 19115 (2). A series of Fetch functions are provided for the
5174 + * implementation of Web Coverage Service.
5176 + * Use WCSTCreateDataset() to create a AbstractDataset for a named coverage
5177 + * identifier and band list.
5180 +/************************************************************************/
5181 +/* AbstractDataset() */
5182 +/************************************************************************/
5183 +AbstractDataset::AbstractDataset()
5187 +/************************************************************************/
5188 +/* AbstractDataset() */
5189 +/************************************************************************/
5192 + * \brief Constructor of an AbstractDataset.
5194 + * This is the accepted method of opening an abstract dataset and allocating
5195 + * all resources associated with it.
5198 +AbstractDataset::AbstractDataset(const string& id, vector<int> &rBandList) :
5199 + ms_CoverageID(id), mv_BandList(rBandList)
5203 +/************************************************************************/
5204 +/* ~AbstractDataset() */
5205 +/************************************************************************/
5208 + * \brief Destroy an open AbstractDataset object.
5210 + * This is the accepted method of closing a AbstractDataset dataset and
5211 + * deallocating all resources associated with it.
5214 +AbstractDataset::~AbstractDataset()
5216 + if (maptr_DS.get())
5217 + GDALClose(maptr_DS.release());
5220 +/************************************************************************/
5221 +/* InitialDataset() */
5222 +/************************************************************************/
5225 + * \brief Initialize the data set.
5227 + * This is the virtual function for initializing abstract dataste. The
5228 + * subclasses of AbstarctDataset will call SetNativeCRS(), SetGeoTransform()
5229 + * and SetGDALDataset() to initialize an abstarct dataset.
5231 + * @param isSimple The WCS request type. When user executing a DescribeCoverage
5232 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
5234 + * @return CE_None on success or CE_Failure on failure.
5237 +CPLErr AbstractDataset::InitialDataset(const int isSimple)
5239 + return CE_Failure;
5242 +/************************************************************************/
5243 +/* GetGDALDataset() */
5244 +/************************************************************************/
5247 + * \brief Get the GDALDataset object from AbstarctDataset.
5249 + * An AbstarctDataset encapsulating one GDALDataset. GetGDALDataset()
5250 + * returns a GDALDatset object, which is used to fetch its information
5251 + * through GDAL APIs.
5253 + * @return GDALDatset object.
5256 +GDALDataset* AbstractDataset::GetGDALDataset()
5258 + return maptr_DS.get();
5261 +/************************************************************************/
5262 +/* SetGDALDataset() */
5263 +/************************************************************************/
5266 + * \brief Set the GDALDataset object to AbstarctDataset.
5268 + * This is the virtual function for setting the abstract dataset by
5269 + * calling GDAL functions.
5271 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
5272 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
5274 + * @return CE_None on success or CE_Failure on failure.
5277 +CPLErr AbstractDataset::SetGDALDataset(const int isSimple)
5279 + return CE_Failure;
5282 +/************************************************************************/
5283 +/* GetNativeCRS() */
5284 +/************************************************************************/
5287 + * \brief Get the Native CRS of an AbstarctDataset.
5289 + * The method will return the CRS obejct, which is an OGRSpatialReference
5292 + * @return an OGRSpatialReference object corresponding the native CRS of
5296 +const OGRSpatialReference& AbstractDataset::GetNativeCRS()
5298 + return mo_NativeCRS;
5301 +/************************************************************************/
5302 +/* SetNativeCRS() */
5303 +/************************************************************************/
5306 + * \brief Set the Native CRS for an AbstarctDataset.
5308 + * The method will set the CRS for an AbstractDataset as an native CRS. For
5309 + * some served coverage, GDAL could not tell its native CRS, this method
5310 + * should be called to set its native CRS.
5312 + * @return CE_None on success or CE_Failure on failure.
5315 +CPLErr AbstractDataset::SetNativeCRS()
5317 + char* wktStr = (char*) maptr_DS->GetProjectionRef();
5319 + if (wktStr && OGRERR_NONE == mo_NativeCRS.importFromWkt(&wktStr))
5322 + return CE_Failure;
5325 +/************************************************************************/
5326 +/* SetGeoTransform() */
5327 +/************************************************************************/
5330 + * \brief Set the affine GeoTransform matrix for a coverage.
5332 + * The method will set a GeoTransform matrix for a coverage. The method
5333 + * GetGeoTransform of GDAL library will be called to get the matrix.
5335 + * @return CE_None on success or CE_Failure on failure.
5338 +CPLErr AbstractDataset::SetGeoTransform()
5340 + if (CE_None != maptr_DS->GetGeoTransform(md_Geotransform))
5341 + return CE_Failure;
5343 + //Is the returned matrix correct? check the resolution values;
5344 + if(md_Geotransform[2] == 0 && md_Geotransform[5] == 0)
5345 + return CE_Failure;
5347 + mb_GeoTransformSet = TRUE;
5352 +/************************************************************************/
5353 +/* GetGeoTransform() */
5354 +/************************************************************************/
5357 + * \brief Fetch the affine transformation coefficients.
5359 + * Fetches the coefficients for transforming between pixel/line (P,L) raster
5360 + * space, and projection coordinates (Xp,Yp) space.
5363 + * Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
5364 + * Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
5367 + * In a north up image, padfTransform[1] is the pixel width, and
5368 + * padfTransform[5] is the pixel height. The upper left corner of the
5369 + * upper left pixel is at position (padfTransform[0],padfTransform[3]).
5371 + * The default transform is (0,1,0,0,0,1) and should be returned even when
5372 + * a CE_Failure error is returned, such as for formats that don't support
5373 + * transformation to projection coordinates.
5375 + * NOTE: GetGeoTransform() isn't expressive enough to handle the variety of
5376 + * OGC Grid Coverages pixel/line to projection transformation schemes.
5377 + * Eventually this method will be depreciated in favour of a more general
5380 + * @param geoTrans an existing six double buffer into which the
5381 + * transformation will be placed.
5383 + * @return TRUE on success or FALSE on failure.
5386 +int AbstractDataset::GetGeoTransform(double geoTrans[])
5388 + if (!mb_GeoTransformSet)//Geo-Transform not setup in each data driver, then set default.
5399 + memcpy(geoTrans, md_Geotransform, sizeof(double) * 6);
5404 +/************************************************************************/
5405 +/* GetCoverageID() */
5406 +/************************************************************************/
5409 + * \brief Fetch the identifier of a coverage.
5411 + * The method will return the coverage identifier related to the abstarct
5412 + * dataset. As to TRMM data, the coverage identifier likes:
5413 + * TRMM:/Volumes/RAIDL1/GeoData/TRMM/TRMM_3B42_daily.2000.hdf:Daily
5415 + * As to MODIS data, the coverage identifier likes:
5416 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MOD15A2/2007/MYD15A2.A2007241.h12v09.005.2007256053902.hdf":MOD_Grid_MOD15A2:Lai_1km
5418 + * @return the string of coverage identifier.
5421 +string AbstractDataset::GetCoverageID()
5423 + return ms_CoverageID;
5426 +/************************************************************************/
5427 +/* GetResourceFileName() */
5428 +/************************************************************************/
5431 + * \brief Fetch the resource file name of a coverage.
5433 + * The method will return the full path corresponding the file contained
5436 + * @return the string of resource file path.
5439 +string AbstractDataset::GetResourceFileName()
5441 + return ms_SrcFilename;
5444 +/************************************************************************/
5445 +/* GetDatasetName() */
5446 +/************************************************************************/
5449 + * \brief Fetch the dataset name of a coverage.
5451 + * The method will return the data set name corresponding the file contained
5452 + * coverage. For example, MOD09GQ data has the coverage identifier as following;
5453 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
5455 + * sur_refl_b01_1 is seemed as the dataset name.
5457 + * @return the string of dataset name.
5460 +string AbstractDataset::GetDatasetName()
5462 + return ms_DatasetName;
5465 +/************************************************************************/
5466 +/* GetDataTypeName() */
5467 +/************************************************************************/
5470 + * \brief Fetch the dataset type name of a coverage.
5472 + * The method will return the data set name corresponding the file contained
5473 + * coverage. For example, MOD09GQ data has the coverage identifier as following;
5474 + * HDF4_EOS:EOS_GRID:"/Volumes/RAIDL1/GeoData/MODISData/MOD09GQ/MOD09GQ.A2010001.h12v05.005.2010007003100.hdf":MODIS_Grid_2D:sur_refl_b01_1
5476 + * MODIS_Grid_2D is seemed as the dataset type name.
5478 + * @return the string of dataset type name.
5481 +string AbstractDataset::GetDataTypeName()
5483 + return ms_DataTypeName;
5486 +/************************************************************************/
5487 +/* GetDataTypeName() */
5488 +/************************************************************************/
5491 + * \brief Fetch the dataset description of a coverage.
5493 + * The method will build a description for the coverage. The coverage
5494 + * extent, dataset name, dataset type name will be contained in the
5497 + * @return the string of dataset description.
5500 +string AbstractDataset::GetDatasetDescription()
5502 + //[15x2030x1354] Band JPEG2000 (16-bit unsigned integer)
5504 + int aiDimSizes[3];
5505 + int nBandCount = maptr_DS->GetRasterCount();
5507 + if (nBandCount > 1)
5509 + aiDimSizes[0] = nBandCount;
5510 + aiDimSizes[1] = GetImageYSize();
5511 + aiDimSizes[2] = GetImageXSize();
5512 + pszString = SPrintArray(GDT_UInt32, aiDimSizes, 3, "x");
5516 + aiDimSizes[0] = GetImageYSize();
5517 + aiDimSizes[1] = GetImageXSize();
5518 + pszString = SPrintArray(GDT_UInt32, aiDimSizes, 2, "x");
5521 + rtnBuf = "[" + pszString + "] " + ms_DatasetName + " " + ms_DataTypeName + " (" +
5522 + GDALGetDataTypeName(maptr_DS->GetRasterBand(1)->GetRasterDataType()) + ")";
5527 +/************************************************************************/
5528 +/* GetNativeFormat() */
5529 +/************************************************************************/
5532 + * \brief Fetch the native format of a coverage.
5534 + * The method will return the native format of a coverage. GDAL API
5535 + * GDALGetDriverShortName() will be called to generate the format.
5537 + * @return the string of dataset native format, in forms of GDAL Formats
5538 + * Code. See http://gdal.org/formats_list.html for details.
5541 +string AbstractDataset::GetNativeFormat()
5543 + return ms_NativeFormat;
5546 +/************************************************************************/
5547 +/* IsbGeoTransformSet() */
5548 +/************************************************************************/
5551 + * \brief Determine whether set the affine geoTransform for a coverage.
5553 + * The method will return the status of the affine GeoTransform matrix.
5555 + * @return TRUE if set already or FALSE on failure..
5558 +int AbstractDataset::IsbGeoTransformSet()
5560 + return mb_GeoTransformSet;
5563 +/************************************************************************/
5564 +/* GetNativeBBox() */
5565 +/************************************************************************/
5568 + * \brief Fetch the bounding box of a coverage under the native CRS.
5570 + * The method will fetch the bounding box of the coverage under native CRS.
5571 + * The sequence of values stored in array is: xmin, xmax, ymin, ymax
5573 + * @param bBox an existing four double buffer into which the
5574 + * native bounding box values will be placed.
5577 +void AbstractDataset::GetNativeBBox(double bBox[])
5579 + if (mb_GeoTransformSet)
5581 + bBox[0] = md_Geotransform[0];
5582 + bBox[1] = bBox[0] + GetImageXSize() * md_Geotransform[1];
5583 + bBox[3] = md_Geotransform[3];
5584 + bBox[2] = bBox[3] + GetImageYSize() * md_Geotransform[5];
5589 + bBox[1] = maptr_DS->GetRasterXSize() - 1;
5591 + bBox[3] = maptr_DS->GetRasterYSize() - 1;
5595 +/************************************************************************/
5596 +/* GetGeoMinMax() */
5597 +/************************************************************************/
5600 + * \brief Fetch the bounding box of a coverage under EPSG:4326.
5602 + * The method will fetch the bounding box of the coverage under EPSG:4326
5603 + * CRS. The sequence of values stored in array is: xmin, xmax, ymin, ymax
5605 + * @param bBox an existing four double buffer into which the geographic
5606 + * bounding box values will be placed.
5608 + * @return CE_None on success or CE_Failure on failure.
5611 +CPLErr AbstractDataset::GetGeoMinMax(double geoMinMax[])
5613 + if (!mb_GeoTransformSet)
5615 + SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
5616 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to get Geo-BoundingBox coordinates");
5617 + return CE_Failure;
5620 + geoMinMax[0] = md_Geotransform[0];
5621 + geoMinMax[1] = geoMinMax[0] + GetImageXSize() * md_Geotransform[1];
5622 + geoMinMax[3] = md_Geotransform[3];
5623 + geoMinMax[2] = geoMinMax[3] + GetImageYSize() * md_Geotransform[5];
5626 + if (mo_NativeCRS.IsGeographic() || Find_Compare_SubStr(ms_DataTypeName, "MODIS"))//for modis data
5628 + geoMinMax[0] = (geoMinMax[0] >= -180.0) ? geoMinMax[0] : -180.0;
5629 + geoMinMax[1] = (geoMinMax[1] <= 180.0) ? geoMinMax[1] : 180.0;
5630 + geoMinMax[2] = (geoMinMax[2] >= -90.0) ? geoMinMax[2] : -90.0;
5631 + geoMinMax[3] = (geoMinMax[3] <= 90.0) ? geoMinMax[3] : 90.0;
5635 + OGRSpatialReference oGeoSRS;
5636 + oGeoSRS.CopyGeogCSFrom(&mo_NativeCRS);
5638 + My2DPoint llPt(geoMinMax[0], geoMinMax[2]);
5639 + My2DPoint urPt(geoMinMax[1], geoMinMax[3]);
5640 + if (CE_None != bBox_transFormmate(mo_NativeCRS, oGeoSRS, llPt, urPt))
5642 + SetWCS_ErrorLocator("AbstractDataset::getGeoMinMax()");
5643 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to transform bounding box coordinates to geographic coordinates.");
5644 + return CE_Failure;
5647 + geoMinMax[0] = llPt.mi_X;
5648 + geoMinMax[1] = urPt.mi_X;
5649 + geoMinMax[2] = llPt.mi_Y;
5650 + geoMinMax[3] = urPt.mi_Y;
5656 +/************************************************************************/
5657 +/* GetImageXSize() */
5658 +/************************************************************************/
5661 + * \brief Fetch coverage width in pixels.
5663 + * The method will return the width of coverage in pixels. GDAL API
5664 + * GetRasterXSize() will be called to generate the width value.
5666 + * @return the width in pixels of raster bands in this coverage.
5669 +int AbstractDataset::GetImageXSize()
5671 + return maptr_DS->GetRasterXSize();
5674 +/************************************************************************/
5675 +/* GetImageYSize() */
5676 +/************************************************************************/
5679 + * \brief Fetch coverage height in pixels.
5681 + * The method will return the height of coverage in pixels. GDAL API
5682 + * GetRasterYSize() will be called to generate the height value.
5684 + * @return the height in pixels of raster bands in this coverage.
5686 +int AbstractDataset::GetImageYSize()
5688 + return maptr_DS->GetRasterYSize();
5691 +/************************************************************************/
5692 +/* GetCoverageBeginTime() */
5693 +/************************************************************************/
5696 + * \brief Fetch the begin date/time of a coverage.
5698 + * The method will return the begin date/time of a coverage. For MODIS data,
5699 + * each granule will cover a range of time; for TRMM data, the daily data
5700 + * will cover a whole day, and monthly data will cover a whole month.
5702 + * @return the string of begin date/time corresponding to the coverage.
5705 +string AbstractDataset::GetCoverageBeginTime()
5707 + return ms_CoverageBeginTime;
5710 +/************************************************************************/
5711 +/* GetCoverageBeginTime() */
5712 +/************************************************************************/
5715 + * \brief Fetch the end date/time of a coverage.
5717 + * The method will return the end date/time of a coverage. For MODIS data,
5718 + * each granule will cover a range of time; for TRMM data, the daily data
5719 + * will cover a whole day, and monthly data will cover a whole month.
5721 + * @return the string of end date/time corresponding to the coverage.
5724 +string AbstractDataset::GetCoverageEndTime()
5726 + return ms_CoverageEndTime;
5729 +/************************************************************************/
5730 +/* getCoverageSubType() */
5731 +/************************************************************************/
5734 + * \brief Fetch the coverage type.
5736 + * The method will return the type of the coverage, such as
5737 + * "ReferenceableDataset" and "RectifiedDataset".
5739 + * @return the string of coverage type.
5742 +string AbstractDataset::GetCoverageSubType()
5744 + return ms_CoverageSubType;
5747 +/************************************************************************/
5748 +/* getFieldQuantityDef() */
5749 +/************************************************************************/
5752 + * \brief Fetch the field units of a coverage.
5754 + * The method will return the field units of coverage. For example to
5755 + * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, units equals
5758 + * @return the string of coverage field units.
5761 +string AbstractDataset::GetFieldQuantityDef()
5763 + return ms_FieldQuantityDef;
5766 +/************************************************************************/
5767 +/* GetAllowValues() */
5768 +/************************************************************************/
5771 + * \brief Fetch the allow values of a coverage.
5773 + * The method will return the valid range of a coverage. For example to
5774 + * MOD09GQ(collection name) sur_refl_b01_1(dataset name) data, valid_range
5775 + * equals to (-100, 16000).
5777 + * @return the string of valid range of a coverage, in the forms of "min, max".
5780 +string AbstractDataset::GetAllowValues()
5782 + return ms_AllowRanges;
5785 +/************************************************************************/
5786 +/* GetISO19115Metadata() */
5787 +/************************************************************************/
5790 + * \brief Fetch the coverage metadata which is compliant to ISO 19115:2003
5791 + * - GeoGraphic information -- Metadata; and ISO 19115(2):2009 - GeoGraphic
5792 + * information -- Metadata -- Part 2.
5794 + * The method will return the metadata of a coverage based on ISO 19115
5795 + * and ISO 19115(2).
5797 + * ISO 19115:2003 defines the schema required for
5798 + * describing geographic information and services. It provides information
5799 + * about the identification, the extent, the quality, the spatial and temporal
5800 + * schema, spatial reference, and distribution of digital geographic data.
5802 + * ISO 19115-2:2009 extends the existing geographic metadata standard by
5803 + * defining the schema required for describing imagery and gridded data.
5804 + * It provides information about the properties of the measuring equipment
5805 + * used to acquire the data, the geometry of the measuring process employed
5806 + * by the equipment, and the production process used to digitize the raw data.
5807 + * This extension deals with metadata needed to describe the derivation of
5808 + * geographic information from raw data, including the properties of the
5809 + * measuring system, and the numerical methods and computational procedures
5810 + * used in the derivation. The metadata required to address coverage data in
5811 + * general is addressed sufficiently in the general part of ISO 19115.
5813 + * @return the string of metadata of a coverage.
5816 +string AbstractDataset::GetISO19115Metadata()
5818 + return ms_ISO19115Metadata;
5821 +/************************************************************************/
5822 +/* GetCoverageArchiveTime() */
5823 +/************************************************************************/
5826 + * \brief Fetch the archive date/time of this dataset.
5828 + * The method will return the archive date/time of dataset (granule).
5830 + * @return The string of archive date/time.
5833 +string AbstractDataset::GetCoverageArchiveTime()
5835 + return ms_CoverageArchiveTime;
5838 +/************************************************************************/
5839 +/* GetCoveragePlatform() */
5840 +/************************************************************************/
5843 + * \brief Fetch the platform name of this dataset.
5845 + * The method will return the platform name of dataset (granule).
5847 + * @return The string of platform name.
5850 +string AbstractDataset::GetCoveragePlatform()
5852 + return ms_CoveragePlatform;
5855 +/************************************************************************/
5856 +/* GetCoverageInstrument() */
5857 +/************************************************************************/
5860 + * \brief Fetch the instrument name of this dataset.
5862 + * The method will return the instrument name of dataset (granule).
5864 + * @return The string of instrument name.
5867 +string AbstractDataset::GetCoverageInstrument()
5869 + return ms_CoverageInstrument;
5872 +/************************************************************************/
5873 +/* GetCoverageInstrument() */
5874 +/************************************************************************/
5877 + * \brief Fetch the sensor name of this dataset.
5879 + * The method will return the sensor name of dataset (granule).
5881 + * @return The string of sensor name.
5884 +string AbstractDataset::GetCoverageSensor()
5886 + return ms_CoverageSensor;
5889 +/************************************************************************/
5890 +/* GetImageBandCount() */
5891 +/************************************************************************/
5894 + * \brief Fetch the number of raster bands on this dataset.
5896 + * The method will return the number of raster bands on this dataset. GDAL
5897 + * API GetRasterCount() will be called to get the count number.
5899 + * @return the number of raster bands on this dataset.
5902 +int AbstractDataset::GetImageBandCount()
5904 + return maptr_DS->GetRasterCount();
5907 +/************************************************************************/
5908 +/* getMissingValue() */
5909 +/************************************************************************/
5912 + * \brief Fetch the filled value (missing value) of a coverage.
5914 + * The method will return the filled value of a coverage.
5916 + * @return the value of filled value of a coverage.
5919 +const double& AbstractDataset::GetMissingValue()
5921 + return md_MissingValue;
5924 +/************************************************************************/
5925 +/* GetProjectionRef() */
5926 +/************************************************************************/
5929 + * \brief Fetch the native projection reference of a coverage.
5931 + * The method will return the the native projection reference of a coverage.
5933 + * @return the string of the native projection reference of a coverage.
5936 +string AbstractDataset::GetProjectionRef()
5938 + char* pszProjection = NULL;
5939 + mo_NativeCRS.exportToWkt(&pszProjection);
5940 + string tmpStr = pszProjection;
5941 + CPLFree(pszProjection);
5946 +/************************************************************************/
5947 +/* SetMetaDataList() */
5948 +/************************************************************************/
5951 + * \brief Set the metadata list for this coverage based on dataset object.
5953 + * The method will set the metadata list for the coverage based on its
5954 + * corresponding GDALDataset object. Will be implemented in the subclasses
5955 + * of AbstractDataset.
5957 + * @param hSrc the GDALDataset object corresponding to coverage.
5959 + * @return CE_Failure.
5962 +CPLErr AbstractDataset::SetMetaDataList(GDALDataset* hSrc)
5964 + return CE_Failure;
5967 +/************************************************************************/
5968 +/* GetMetaDataList() */
5969 +/************************************************************************/
5972 + * \brief Fetch the metadata list for this coverage.
5974 + * The method will return the metadata list for the coverage.
5976 + * @return the list of metadate.
5979 +vector<string> AbstractDataset::GetMetaDataList()
5981 + return mv_MetaDataList;
5984 +/************************************************************************/
5985 +/* GetBandList() */
5986 +/************************************************************************/
5989 + * \brief Fetch the contained band list of request coverage.
5991 + * The method will return the contained band list of request coverage.
5993 + * @return the band array.
5996 +vector<int> AbstractDataset::GetBandList()
5998 + return mv_BandList;
6001 +/************************************************************************/
6002 +/* getNativeCRS_URN() */
6003 +/************************************************************************/
6006 + * \brief Fetch the native CRS code of coverage.
6008 + * The method will return the native CRS code of coverage.
6010 + * @return the string of the URN for native CRS of coverage.
6013 +string AbstractDataset::GetNativeCRS_URN()
6017 + if (mo_NativeCRS.IsProjected())
6019 + const char* nativeAuthorityName =
6020 + mo_NativeCRS.GetAuthorityName("PROJCS");
6021 + const char* nativeAuthorityCode =
6022 + mo_NativeCRS.GetAuthorityCode("PROJCS");
6024 + urn = "urn:ogc:def:crs:";
6026 + if (nativeAuthorityName && (EQUAL(nativeAuthorityName,"EPSG")
6027 + || EQUAL(nativeAuthorityName,"OGP")
6028 + || EQUAL(nativeAuthorityName,"OGC")))
6029 + urn += (string) nativeAuthorityName + (string) ":6.3:";
6031 + urn += "CSISS:0.0:";
6033 + if (nativeAuthorityCode)
6034 + urn += (string) nativeAuthorityCode;
6036 + urn += "80000000";
6038 + else if (mo_NativeCRS.IsGeographic())
6040 + const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
6041 + const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
6043 + urn = "urn:ogc:def:crs:";
6044 + if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
6045 + || EQUAL(geoAuthorityName,"OGP")
6046 + || EQUAL(geoAuthorityName,"OGC")))
6047 + urn += (string) geoAuthorityName + (string) ":6.3:";
6049 + urn += "CSISS:0.0:";
6051 + if (geoAuthorityCode)
6052 + urn += (string) geoAuthorityCode;
6054 + urn += "70000000";
6057 + urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
6062 +/************************************************************************/
6063 +/* GetGeoCRS_URN() */
6064 +/************************************************************************/
6067 + * \brief Fetch the Geographic CRS code of coverage.
6069 + * The method will return the Geographic CRS code of coverage.
6071 + * @return the URN for Geographic CRS of coverage.
6074 +string AbstractDataset::GetGeoCRS_URN()
6078 + if (mo_NativeCRS.IsProjected() || mo_NativeCRS.IsGeographic())
6080 + const char* geoAuthorityName = mo_NativeCRS.GetAuthorityName("GEOGCS");
6081 + const char* geoAuthorityCode = mo_NativeCRS.GetAuthorityCode("GEOGCS");
6083 + urn = "urn:ogc:def:crs:";
6084 + if (geoAuthorityName && (EQUAL(geoAuthorityName,"EPSG")
6085 + || EQUAL(geoAuthorityName,"OGP")
6086 + || EQUAL(geoAuthorityName,"OGC")))
6087 + urn += (string) geoAuthorityName + (string) ":6.3:";
6089 + urn += "CSISS:0.0:";
6091 + if (geoAuthorityCode)
6092 + urn += (string) geoAuthorityCode;
6094 + urn += "70000000";
6098 + urn = "urn:ogc:def:crs:OGC:0.0:imageCRS";
6103 +/************************************************************************/
6104 +/* IsCrossingIDL() */
6105 +/************************************************************************/
6108 + * \brief Determine whether the extend of coverage cross the International
6109 + * Date Line (IDL).
6111 + * The method will return the status of whether the extend of coverage
6112 + * cross the International Date Line (IDL).
6114 + * @return the TRUE of the coverage extent cross the IDL, otherwise FALSE.
6117 +int AbstractDataset::IsCrossingIDL()
6119 + double bboxArray[4];
6120 + GetNativeBBox(bboxArray);
6122 + OGRSpatialReference latlonSRS;
6123 + latlonSRS.SetWellKnownGeogCS("WGS84");
6124 + My2DPoint llPtex(bboxArray[0], bboxArray[2]);
6125 + My2DPoint urPtex(bboxArray[1], bboxArray[3]);
6126 + bBox_transFormmate(mo_NativeCRS, latlonSRS, llPtex, urPtex);
6128 + int bCrossCenter = false;
6129 + if(urPtex.mi_X < 0 && llPtex.mi_X > 0)
6130 + bCrossCenter = true;
6132 + return bCrossCenter;
6135 +/************************************************************************/
6136 +/* GetSuggestedWarpResolution() */
6137 +/************************************************************************/
6140 + * \brief Get the suggested warp option, method 1.
6142 + * @return CE_Failure if an error occurs, otherwise CE_None.
6145 +CPLErr AbstractDataset::GetSuggestedWarpResolution( OGRSpatialReference& dstCRS,
6146 + double adfDstGeoTransform[],
6150 + if (!dstCRS.IsProjected() && !dstCRS.IsGeographic())
6152 + adfDstGeoTransform[0] = 0;
6153 + adfDstGeoTransform[1] = 1;
6154 + adfDstGeoTransform[2] = 0;
6155 + adfDstGeoTransform[3] = 0;
6156 + adfDstGeoTransform[4] = 0;
6157 + adfDstGeoTransform[5] = 1;
6159 + nPixels = GetImageXSize();
6160 + nLines = GetImageYSize();
6163 + else if (dstCRS.IsSame(&mo_NativeCRS))
6165 + memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
6166 + nPixels = GetImageXSize();
6167 + nLines = GetImageYSize();
6172 + dstCRS.exportToWkt(&pszDstWKT);
6174 + mo_NativeCRS.exportToWkt(&pszSrcWKT);
6176 + void *hTransformArg = GDALCreateGenImgProjTransformer(maptr_DS.get(),
6177 + (const char*) pszSrcWKT, NULL, (const char*) pszDstWKT, TRUE, 1000.0, 0);
6178 + OGRFree(pszDstWKT);
6179 + OGRFree(pszSrcWKT);
6180 + if (hTransformArg == NULL)
6182 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
6183 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create GDAL GenImgProjTransformer.");
6185 + return CE_Failure;
6187 + /* -------------------------------------------------------------------- */
6188 + /* Get approximate output definition. */
6189 + /* -------------------------------------------------------------------- */
6190 + if (GDALSuggestedWarpOutput(maptr_DS.get(), GDALGenImgProjTransform,
6191 + hTransformArg, adfDstGeoTransform, &nPixels, &nLines) != CE_None)
6193 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution()");
6194 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Computing Output Resolution.");
6196 + return CE_Failure;
6199 + GDALDestroyGenImgProjTransformer(hTransformArg);
6205 +/************************************************************************/
6206 +/* GetSuggestedWarpResolution2() */
6207 +/************************************************************************/
6210 + * \brief Get the suggested warp option, method 2.
6212 + * @return CE_Failure if an error occurs, otherwise CE_None.
6215 +CPLErr AbstractDataset::GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS,
6216 + double adfDstGeoTransform[],
6220 + if (dstCRS.IsLocal())
6222 + adfDstGeoTransform[0] = 0;
6223 + adfDstGeoTransform[1] = 1;
6224 + adfDstGeoTransform[2] = 0;
6225 + adfDstGeoTransform[3] = 0;
6226 + adfDstGeoTransform[4] = 0;
6227 + adfDstGeoTransform[5] = 1;
6229 + nPixels = GetImageXSize();
6230 + nLines = GetImageYSize();
6232 + else if (dstCRS.IsSame(&mo_NativeCRS))
6234 + memcpy(adfDstGeoTransform, md_Geotransform, sizeof(double) * 6);
6235 + nPixels = GetImageXSize();
6236 + nLines = GetImageYSize();
6240 + double bboxArray[4];
6241 + GetNativeBBox(bboxArray);
6243 + My2DPoint llPt(bboxArray[0], bboxArray[2]);
6244 + My2DPoint urPt(bboxArray[1], bboxArray[3]);
6245 + if (CE_None != bBox_transFormmate(mo_NativeCRS, dstCRS, llPt, urPt))
6247 + SetWCS_ErrorLocator("AbstractDataset::GetSuggestedWarpResolution2()");
6248 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform bounding box Coordinate.");
6249 + return CE_Failure;
6252 + double xRes, yRes;
6253 + if(IsCrossingIDL())
6255 + yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
6256 + xRes = fabs((llPt.mi_X - urPt.mi_X) / GetImageXSize());
6257 + nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
6258 + nPixels = fabs((llPt.mi_X - urPt.mi_X) / xRes + 0.5);
6261 + xRes = (urPt.mi_X - llPt.mi_X) / GetImageXSize();
6262 + yRes = (urPt.mi_Y - llPt.mi_Y) / GetImageYSize();
6263 + nPixels = (urPt.mi_X - llPt.mi_X) / xRes + 0.5;
6264 + nLines = (urPt.mi_Y - llPt.mi_Y) / yRes + 0.5;
6267 + xRes = MIN(xRes,yRes);
6268 + yRes = MIN(xRes,yRes);
6270 + adfDstGeoTransform[0] = llPt.mi_X;
6271 + adfDstGeoTransform[1] = xRes;
6272 + adfDstGeoTransform[2] = 0;
6273 + adfDstGeoTransform[3] = urPt.mi_Y;
6274 + adfDstGeoTransform[4] = 0;
6275 + adfDstGeoTransform[5] = -yRes;
6281 +/************************************************************************/
6282 +/* DatasetWarper() */
6283 +/************************************************************************/
6286 + * Wrap the dataset to a GDALDataset object based on input parameters.
6288 + * @return the warpped GDALDataset object.
6290 +/************************************************************************/
6291 +/* DatasetWarper() */
6292 +/************************************************************************/
6295 + * \brief Wrap the dataset to a GDALDataset object based on input parameters.
6297 + * @return GDALDatset object.
6300 +GDALDataset* AbstractDataset::DatasetWarper(int& IsRefDS,
6301 + OGRSpatialReference& dstCRS,
6302 + int& iDstRasterXsize,
6303 + int& iDstRasterYsize,
6304 + double pDstGeoTransform[],
6305 + GDALResampleAlg eResampleAlg)
6307 + OGRSpatialReference locCRS=dstCRS;
6308 + if (dstCRS.IsLocal())
6309 + locCRS=mo_NativeCRS;
6311 + if((mo_NativeCRS.IsSame(&locCRS) &&
6312 + iDstRasterXsize == maptr_DS->GetRasterXSize() &&
6313 + iDstRasterYsize == maptr_DS->GetRasterYSize())&&
6314 + CPLIsEqual(md_Geotransform[0],pDstGeoTransform[0])&&
6315 + CPLIsEqual(md_Geotransform[1],pDstGeoTransform[1])&&
6316 + CPLIsEqual(md_Geotransform[3],pDstGeoTransform[3])&&
6317 + CPLIsEqual(md_Geotransform[5],pDstGeoTransform[5]))
6320 + return maptr_DS.get();
6323 + char *sDstCRS_WKT;
6324 + locCRS.exportToWkt(&sDstCRS_WKT);
6326 + /* Create a memory data-set for re-projection */
6327 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
6329 + int nBand = maptr_DS->GetRasterCount();
6330 + GDALDataset* hMemDS = (GDALDataset*) GDALCreate(poDriver, "", iDstRasterXsize,
6331 + iDstRasterYsize, nBand, GDALGetRasterDataType(maptr_DS->GetRasterBand(1)), NULL);
6332 + if (NULL == hMemDS)
6334 + GDALClose(poDriver);
6335 + OGRFree(sDstCRS_WKT);
6339 + hMemDS->SetProjection(sDstCRS_WKT);
6340 + hMemDS->SetGeoTransform(pDstGeoTransform);
6342 + for (int i = 1; i <= nBand; i++)
6344 + hMemDS->GetRasterBand(i)->SetNoDataValue(md_MissingValue);
6347 + /* -------------------------------------------------------------------- */
6348 + /* Perform the re-projection. */
6349 + /* -------------------------------------------------------------------- */
6351 + mo_NativeCRS.exportToWkt(&srcWKT);
6352 + if (CE_None != GDALReprojectImage(maptr_DS.get(), srcWKT, hMemDS,
6353 + sDstCRS_WKT, eResampleAlg, 0, 0.125, NULL, NULL, NULL))
6355 + GDALClose(poDriver);
6356 + GDALClose(GDALDatasetH(hMemDS));
6357 + OGRFree(sDstCRS_WKT);
6362 + OGRFree(sDstCRS_WKT);
6367 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/5c/5c3da4f5eaa9825bf8d68c07943d2343d2cf05e2.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/5c/5c3da4f5eaa9825bf8d68c07943d2343d2cf05e2.svn-base
6368 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/5c/5c3da4f5eaa9825bf8d68c07943d2343d2cf05e2.svn-base 1970-01-01 01:00:00.000000000 +0100
6369 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/5c/5c3da4f5eaa9825bf8d68c07943d2343d2cf05e2.svn-base 2014-03-03 15:47:37.810232939 +0100
6371 +/******************************************************************************
6372 + * $Id: AbstractDataset.h 2011-07-19 16:24:00Z $
6374 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
6375 + * for Earth Observation: Open Source Reference Implementation
6376 + * Purpose: AbstractDataset class definition
6377 + * Author: Yuanzheng Shao, yshao3@gmu.edu
6379 + ******************************************************************************
6380 + * * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
6382 + * Permission is hereby granted, free of charge, to any person obtaining a
6383 + * copy of this software and associated documentation files (the "Software"),
6384 + * to deal in the Software without restriction, including without limitation
6385 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
6386 + * and/or sell copies of the Software, and to permit persons to whom the
6387 + * Software is furnished to do so, subject to the following conditions:
6389 + * The above copyright notice and this permission notice shall be included
6390 + * in all copies or substantial portions of the Software.
6392 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6393 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6394 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
6395 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6396 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
6397 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
6398 + * DEALINGS IN THE SOFTWARE.
6399 + ****************************************************************************/
6401 +#ifndef ABSTRACTDATASET_H_
6402 +#define ABSTRACTDATASET_H_
6408 +#include <gdal_priv.h>
6409 +#include <gdalwarper.h>
6410 +#include <ogrsf_frmts.h>
6411 +#include <ogr_spatialref.h>
6412 +#include <cpl_conv.h>
6413 +#include <cpl_minixml.h>
6414 +#include <vrtdataset.h>
6416 +#include "wcsUtil.h"
6418 +using namespace std;
6420 +/* ******************************************************************** */
6421 +/* AbstractDataset */
6422 +/* ******************************************************************** */
6424 +//! Abstract dataset model definition. Based on GDAL dataset model.
6425 +class AbstractDataset {
6428 + auto_ptr<GDALDataset> maptr_DS;
6430 + // Coverage Information Related
6431 + string ms_CoverageID;
6432 + string ms_CoverageBeginTime;
6433 + string ms_CoverageEndTime;
6434 + string ms_CoverageSubType;
6435 + string ms_CoverageArchiveTime;
6436 + string ms_CoveragePlatform;
6437 + string ms_CoverageInstrument;
6438 + string ms_CoverageSensor;
6439 + string ms_SrcFilename;
6440 + string ms_DatasetName;
6441 + string ms_DataTypeName;
6442 + string ms_NativeFormat;
6443 + string ms_FieldQuantityDef;
6444 + string ms_AllowRanges;
6445 + string ms_ISO19115Metadata;
6447 + vector<int> mv_BandList;
6448 + vector<string> mv_MetaDataList;
6450 + double md_Geotransform[6];
6451 + double md_GeoMinMax[4]; // Order: xmin, xmax, ymin, ymax
6452 + double md_MissingValue;
6454 + int mb_GeoTransformSet;
6455 + int mb_IsVirtualDS;
6457 + OGRSpatialReference mo_NativeCRS;
6460 + AbstractDataset();
6461 + virtual CPLErr SetNativeCRS();
6462 + virtual CPLErr SetGeoTransform();
6463 + virtual CPLErr SetGDALDataset(const int isSimple = 0);
6464 + virtual CPLErr SetMetaDataList(GDALDataset*);
6467 + AbstractDataset(const string&, vector<int> &);
6468 + virtual ~AbstractDataset();
6470 + GDALDataset* GetGDALDataset();
6472 + // Virtual Functions Definition
6473 + virtual CPLErr InitialDataset(const int isSimple = 0);
6475 + // Fetch Function Related
6476 + const OGRSpatialReference& GetNativeCRS();
6477 + const double& GetMissingValue();
6478 + int GetGeoTransform(double geoTrans[]);
6479 + vector<string> GetMetaDataList();
6480 + vector<int> GetBandList();
6481 + void GetNativeBBox(double bBox[]);
6482 + CPLErr GetGeoMinMax(double geoMinMax[]);
6484 + int GetImageBandCount();
6485 + int GetImageXSize();
6486 + int GetImageYSize();
6487 + string GetResourceFileName();
6488 + string GetDatasetName();
6489 + string GetDataTypeName();
6490 + string GetNativeFormat();
6491 + string GetCoverageID();
6492 + string GetDatasetDescription();
6493 + string GetNativeCRS_URN();
6494 + string GetGeoCRS_URN();
6495 + string GetProjectionRef();
6496 + string GetCoverageBeginTime();
6497 + string GetCoverageEndTime();
6498 + string GetCoverageSubType();
6499 + string GetFieldQuantityDef();
6500 + string GetAllowValues();
6501 + string GetISO19115Metadata();
6502 + string GetCoverageArchiveTime();
6503 + string GetCoveragePlatform();
6504 + string GetCoverageInstrument();
6505 + string GetCoverageSensor();
6507 + // Fetch Variables Status Related
6508 + int IsbGeoTransformSet();
6509 + int IsCrossingIDL();
6511 + CPLErr GetSuggestedWarpResolution(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
6513 + CPLErr GetSuggestedWarpResolution2(OGRSpatialReference& dstCRS, double adfDstGeoTransform[], int &nPixels,
6516 + GDALDataset* DatasetWarper(int& IsRefDS, OGRSpatialReference& dstCRS, int& iDstRasterXsize, int& iDstRasterYsize,
6517 + double pDstGeoTransform[], GDALResampleAlg eResampleAlg = GRA_NearestNeighbour);
6520 +#endif /*ABSTRACTDATASET_H_*/
6521 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/60/603732a6a8a375d944ca25f03c7720f3d4f8e069.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/60/603732a6a8a375d944ca25f03c7720f3d4f8e069.svn-base
6522 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/60/603732a6a8a375d944ca25f03c7720f3d4f8e069.svn-base 1970-01-01 01:00:00.000000000 +0100
6523 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/60/603732a6a8a375d944ca25f03c7720f3d4f8e069.svn-base 2014-03-03 15:47:37.593566281 +0100
6525 +/******************************************************************************
\r
6526 + * $Id: wcsUtil.h 2011-07-19 16:24:00Z $
\r
6528 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
\r
6529 + * for Earth Observation: Open Source Reference Implementation
\r
6530 + * Purpose: WCS Utility Function definition
\r
6531 + * Author: Yuanzheng Shao, yshao3@gmu.edu
\r
6533 + ******************************************************************************
\r
6534 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
\r
6536 + * Permission is hereby granted, free of charge, to any person obtaining a
\r
6537 + * copy of this software and associated documentation files (the "Software"),
\r
6538 + * to deal in the Software without restriction, including without limitation
\r
6539 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
6540 + * and/or sell copies of the Software, and to permit persons to whom the
\r
6541 + * Software is furnished to do so, subject to the following conditions:
\r
6543 + * The above copyright notice and this permission notice shall be included
\r
6544 + * in all copies or substantial portions of the Software.
\r
6546 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
6547 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
6548 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
\r
6549 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
6550 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
6551 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
6552 + * DEALINGS IN THE SOFTWARE.
\r
6553 + ****************************************************************************/
\r
6555 +#ifndef WCSUTIL_H_
\r
6556 +#define WCSUTIL_H_
\r
6558 +#include <iostream>
\r
6559 +#include <fstream>
\r
6560 +#include <sstream>
\r
6561 +#include <vector>
\r
6562 +#include <stdlib.h>
\r
6563 +#include <time.h>
\r
6565 +#include <cpl_string.h>
\r
6566 +#include "wcs_error.h"
\r
6567 +#include "BoundingBox.h"
\r
6569 +using namespace std;
\r
6572 +#if defined(WIN32) || defined(WIN32CE)
\r
6573 +# define EQUALN(a,b,n) (strnicmp(a,b,n)==0)
\r
6574 +# define EQUAL(a,b) (stricmp(a,b)==0)
\r
6576 +# define EQUALN(a,b,n) (strncasecmp(a,b,n)==0)
\r
6577 +# define EQUAL(a,b) (strcasecmp(a,b)==0)
\r
6593 +#define DELIMITER "\\"
\r
6595 +#define DELIMITER "/"
\r
6598 +const int SHORT_NAME_LEN = 128;
\r
6599 +const int MAX_NAME_LEN = 512;
\r
6600 +const int MAX_LIST_LEN = 1024;
\r
6601 +const int MAX_LINE_LEN = 65536;
\r
6604 +// -----------------------------------------------------------------------
\r
6605 +// CGI (Common Gateway Interface) related class and functions
\r
6606 +// -----------------------------------------------------------------------
\r
6607 +enum CGI_METHOD_FLAG
\r
6609 + UN_KNOWN, HTTP_GET, HTTP_XML_POST
\r
6612 +/************************************************************************/
\r
6613 +/* ==================================================================== */
\r
6615 +/* ==================================================================== */
\r
6616 +/************************************************************************/
\r
6619 + * \class WCSCGI "wcsUtil.h"
\r
6621 + * WCSCGI class is used to acquire WCS request, both GET and POST method
\r
6622 + * are supported.
\r
6628 + string ms_CGIContent;
\r
6629 + CGI_METHOD_FLAG me_CGIMethod;
\r
6634 + me_CGIMethod = UN_KNOWN;
\r
6639 + string GetRqstContent()
\r
6641 + return ms_CGIContent;
\r
6644 + CGI_METHOD_FLAG GetCGImethod()
\r
6646 + return me_CGIMethod;
\r
6650 +/************************************************************************/
\r
6651 +/* ==================================================================== */
\r
6653 +/* ==================================================================== */
\r
6654 +/************************************************************************/
\r
6659 + vector<string> strings;
\r
6662 + StringList(const string& sstrings, const char delimiter);
\r
6663 + StringList(const string& sstrings, const string& delimiters);
\r
6666 + int indexof(string qstr);
\r
6668 + void add(string newstr)
\r
6670 + strings.push_back(newstr);
\r
6675 + strings.clear();
\r
6680 + return strings.size();
\r
6683 + string& operator [](int index)
\r
6685 + return strings[index];
\r
6688 + void append(StringList & s);
\r
6689 + void append(const string sstrings, const char delimiter);
\r
6690 + void append(const string sstrings, const string& delimiters);
\r
6692 + string toString()
\r
6695 + for (int i = 0; i < size(); i++)
\r
6696 + s += strings[i];
\r
6700 + string toString(const char delimiter)
\r
6703 + for (int i = 0; i < size(); i++)
\r
6704 + s += strings[i] + delimiter;
\r
6708 + string toString(const string& delimiters)
\r
6711 + for (int i = 0; i < size(); i++)
\r
6712 + s += strings[i] + delimiters;
\r
6721 + char buf[MAX_LINE_LEN];
\r
6726 + s.copy(buf, string::npos);
\r
6727 + buf[s.size()] = 0;
\r
6737 +/************************************************************************/
\r
6738 +/* ==================================================================== */
\r
6740 +/* ==================================================================== */
\r
6741 +/************************************************************************/
\r
6746 + string name, value;
\r
6748 + KVP& operator =(const KVP &id)
\r
6751 + value = id.value;
\r
6755 + KVP& operator =(const KVP *pid)
\r
6757 + name = pid->name;
\r
6758 + value = pid->value;
\r
6762 + KVP(string n, string v) :
\r
6763 + name(n), value(v)
\r
6767 + KVP(string namevaluepair);
\r
6771 +/************************************************************************/
\r
6772 +/* ==================================================================== */
\r
6774 +/* ==================================================================== */
\r
6775 +/************************************************************************/
\r
6780 + vector<KVP> m_kvps;
\r
6791 + KVPsReader(const string& urlStr, const char &tok);
\r
6793 + KVP& operator [](const int index)
\r
6795 + return m_kvps[index];
\r
6800 + return m_kvps.size();
\r
6803 + string getValue(const string &keyname);
\r
6804 + string getValue(const string &keyname, const string &defaultvalue);
\r
6805 + vector<string> getValues(const string &keyname);
\r
6808 +/************************************************************************/
\r
6809 +/* ==================================================================== */
\r
6811 +/* ==================================================================== */
\r
6812 +/************************************************************************/
\r
6816 + vector<KVP> kvps;
\r
6819 + CFGReader(const string &configfilename);
\r
6821 + KVP& operator [](const int index)
\r
6823 + return kvps[index];
\r
6828 + return kvps.size();
\r
6831 + string getValue(const string &keyname);
\r
6832 + string getValue(const string &keyname, const string &defaultvalue);
\r
6836 +// -----------------------------------------------------------------------
\r
6837 +// Extra Template Functions
\r
6838 +// Exchange() --- used to exchange values
\r
6839 +// convertToString() --- convert value to string
\r
6840 +// convertFromString --- convert string to values
\r
6841 +// -----------------------------------------------------------------------
\r
6842 +template<class T>
\r
6843 +static void Exchange(T & a, T & b)
\r
6851 +template <class T>
\r
6852 +static string convertToString(T &value)
\r
6854 + stringstream ss;
\r
6856 + string rtnstr = ss.str();
\r
6860 +template <class T>
\r
6861 +static void convertFromString(T &value, const string& s)
\r
6863 + stringstream ss(s);
\r
6868 +// -----------------------------------------------------------------------
\r
6869 +// Extra Utility Functions
\r
6870 +// -----------------------------------------------------------------------
\r
6873 +// String Operation Related
\r
6874 +int CPL_DLL CPL_STDCALL CsvburstCpp(const std::string& line, std::vector<std::string> &strSet, const char tok);
\r
6875 +int CPL_DLL CPL_STDCALL CsvburstComplexCpp(const string& line, vector<string> &strSet, const char* tok);
\r
6876 +int CPL_DLL CPL_STDCALL Find_Compare_SubStr(string line, string sub);
\r
6877 +void CPL_DLL CPL_STDCALL Strslip(const char* str, const char* arrStr[], const char leftdlm, const char rightdlm);
\r
6878 +string CPL_DLL CPL_STDCALL StrReplace(string& str, const string oldSubStr, const string newStr);
\r
6879 +string CPL_DLL CPL_STDCALL SPrintArray(GDALDataType eDataType, const void *paDataArray, int nValues, const char *pszDelimiter);
\r
6880 +string CPL_DLL CPL_STDCALL StrTrimHead(const string &str);
\r
6881 +string CPL_DLL CPL_STDCALL StrTrimTail(const string &str);
\r
6882 +string CPL_DLL CPL_STDCALL StrTrims(const std::string&, const char*);
\r
6883 +string CPL_DLL CPL_STDCALL StrTrim(const string &str);
\r
6885 +// Date Time Operation Related
\r
6886 +int CPL_DLL CPL_STDCALL CompareDateTime_GreaterThan(string time1, string time2);
\r
6887 +int CPL_DLL CPL_STDCALL ConvertDateTimeToSeconds(string datetime);
\r
6888 +string CPL_DLL CPL_STDCALL GetTimeString(int code);
\r
6890 +// Directory Operation Related
\r
6891 +CPLErr CPL_DLL CPL_STDCALL GetFileNameList(char* dir, std::vector<string> &strList);
\r
6892 +string CPL_DLL CPL_STDCALL MakeTempFile(string dir, string covID, string suffix);
\r
6893 +string CPL_DLL CPL_STDCALL GetUUID();
\r
6895 +// Request Parser Operation
\r
6896 +void CPL_DLL CPL_STDCALL GetSubSetTime(const string& subsetstr, vector<string> &subsetvalue);
\r
6897 +string CPL_DLL CPL_STDCALL GetSubSetLatLon(const string& subsetstr, vector<double> &subsetvalue);
\r
6898 +string CPL_DLL CPL_STDCALL GetSingleValue(const string& subsetstr);
\r
6900 +CPLErr CPL_DLL CPL_STDCALL GetTRMMBandList(string start, string end, std::vector<int> &bandList);
\r
6901 +void CPL_DLL CPL_STDCALL GetCornerPoints(const GDAL_GCP* &pGCPList, const int &nGCPs, My2DPoint& lowLeft, My2DPoint& upRight);
\r
6905 +#endif /*WCSUTIL_H_*/
\r
6906 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/6e/6e49290949c78333bcb94209de0ac91b27fca46c.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/6e/6e49290949c78333bcb94209de0ac91b27fca46c.svn-base
6907 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/6e/6e49290949c78333bcb94209de0ac91b27fca46c.svn-base 1970-01-01 01:00:00.000000000 +0100
6908 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/6e/6e49290949c78333bcb94209de0ac91b27fca46c.svn-base 2014-03-03 15:47:38.040232929 +0100
6910 +// -*- mode: c++; c-basic-offset:4 -*-
6912 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
6913 +// Access Protocol.
6915 +// Copyright (c) 2002,2003 OPeNDAP, Inc.
6916 +// Author: James Gallagher <jgallagher@opendap.org>
6918 +// This library is free software; you can redistribute it and/or
6919 +// modify it under the terms of the GNU Lesser General Public
6920 +// License as published by the Free Software Foundation; either
6921 +// version 2.1 of the License, or (at your option) any later version.
6923 +// This library is distributed in the hope that it will be useful,
6924 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
6925 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6926 +// Lesser General Public License for more details.
6928 +// You should have received a copy of the GNU Lesser General Public
6929 +// License along with this library; if not, write to the Free Software
6930 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6932 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
6934 +// (c) COPYRIGHT URI/MIT 1999
6935 +// Please read the full copyright statement in the file COPYRIGHT_URI.
6938 +// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
6941 +// These functions are used by the CE evaluator
6945 +#include "config.h"
6947 +#include <limits.h>
6950 +#include <cstdlib> // used by strtod()
6954 +#include <iostream>
6957 +#include <algorithm>
6960 +// #include <gdal.h>
6961 +// #include <gdal_priv.h>
6965 +#include "BaseType.h"
6974 +#include "DAP_Dataset.h"
6975 +#include "reproj_functions.h"
6977 +// We wrapped VC++ 6.x strtod() to account for a short coming
6978 +// in that function in regards to "NaN". I don't know if this
6979 +// still applies in more recent versions of that product.
6983 +double w32strtod(const char *, char **);
6986 +using namespace std;
6987 +//using namespace libdap;
6992 + * @todo The lat and lon arrays are passed in, but there's an assumption that the
6993 + * source data array and the two lat and lon arrays are the same shape. But the
6994 + * code does not actually test that.
6996 + * @todo Enable multiple bands paired with just the two lat/lon arrays? Not sure
6997 + * if that is a good idea...
6999 +void function_swath2array(int argc, BaseType * argv[], DDS &, BaseType **btpp)
7001 + DBG(cerr << "Entering function_swath2array..." << endl);
7003 + // Use the same documentation for both swath2array and swath2grid
7004 + string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
7005 + + "<function name=\"swath2array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid\">\n"
7006 + + "</function>\n";
7009 + Str *response = new Str("info");
7010 + response->set_value(info);
7015 + // TODO Add optional fourth arg that lets the caller say which datum to use;
7016 + // default to WGS84
7018 + throw Error("The function swath2array() requires three arguments. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7020 + Array *src = dynamic_cast<Array*>(argv[0]);
7022 + throw Error("The first argument to swath2array() must be a data array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7024 + Array *lat = dynamic_cast<Array*>(argv[1]);
7026 + throw Error("The second argument to swath2array() must be a latitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7028 + Array *lon = dynamic_cast<Array*>(argv[2]);
7030 + throw Error("The third argument to swath2array() must be a longitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7032 + // The args passed into the function using argv[] are deleted after the call.
7034 + DAP_Dataset ds(src, lat, lon);
7037 + ds.InitialDataset(0);
7039 + *btpp = ds.GetDAPArray();
7041 + catch (Error &e) {
7042 + DBG(cerr << "caught Error: " << e.get_error_message() << endl);
7046 + DBG(cerr << "caught unknown exception" << endl);
7054 + * @todo The lat and lon arrays are passed in, but there's an assumption that the
7055 + * source data array and the two lat and lon arrays are the same shape. But the
7056 + * code does not actually test that.
7058 + * @todo Enable multiple bands paired with just the two lat/lon arrays? Not sure
7059 + * if that is a good idea...
7061 +void function_swath2grid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
7063 + DBG(cerr << "Entering function_swath2grid..." << endl);
7065 + string info = string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
7066 + + "<function name=\"swath2grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid\">\n"
7067 + + "</function>\n";
7070 + Str *response = new Str("info");
7071 + response->set_value(info);
7076 + // TODO Add optional fourth arg that lets the caller say which datum to use;
7077 + // default to WGS84
7079 + throw Error("The function swath2grid() requires three arguments. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7081 + Array *src = dynamic_cast<Array*>(argv[0]);
7083 + throw Error("The first argument to swath2grid() must be a data array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7085 + Array *lat = dynamic_cast<Array*>(argv[1]);
7087 + throw Error("The second argument to swath2grid() must be a latitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7089 + Array *lon = dynamic_cast<Array*>(argv[2]);
7091 + throw Error("The third argument to swath2grid() must be a longitude array. See http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
7093 + // The args passed into the function using argv[] are deleted after the call.
7095 + DAP_Dataset ds(src, lat, lon);
7098 + ds.InitialDataset(0);
7100 + *btpp = ds.GetDAPGrid();
7102 + catch (Error &e) {
7103 + DBG(cerr << "caught Error: " << e.get_error_message() << endl);
7107 + DBG(cerr << "caught unknown exception" << endl);
7118 +} // namespace libdap
7119 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/70/709a0a2aa7313d6e4d90f84b63deb2616bfe3284.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/70/709a0a2aa7313d6e4d90f84b63deb2616bfe3284.svn-base
7120 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/70/709a0a2aa7313d6e4d90f84b63deb2616bfe3284.svn-base 1970-01-01 01:00:00.000000000 +0100
7121 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/70/709a0a2aa7313d6e4d90f84b63deb2616bfe3284.svn-base 2014-03-03 15:47:38.036899596 +0100
7123 +/******************************************************************************
\r
7124 + * $Id: wcsUtil.cpp 2011-07-19 16:24:00Z $
\r
7126 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
\r
7127 + * for Earth Observation: Open Source Reference Implementation
\r
7128 + * Purpose: WCS Utility Function implementation
\r
7129 + * Author: Yuanzheng Shao, yshao3@gmu.edu
\r
7131 + ******************************************************************************
\r
7132 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
\r
7134 + * Permission is hereby granted, free of charge, to any person obtaining a
\r
7135 + * copy of this software and associated documentation files (the "Software"),
\r
7136 + * to deal in the Software without restriction, including without limitation
\r
7137 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
7138 + * and/or sell copies of the Software, and to permit persons to whom the
\r
7139 + * Software is furnished to do so, subject to the following conditions:
\r
7141 + * The above copyright notice and this permission notice shall be included
\r
7142 + * in all copies or substantial portions of the Software.
\r
7144 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
7145 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
7146 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
\r
7147 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
7148 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
7149 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
7150 + * DEALINGS IN THE SOFTWARE.
\r
7151 + ****************************************************************************/
\r
7153 +#include <unistd.h>
\r
7154 +#include <dirent.h>
\r
7155 +#include <sys/stat.h>
\r
7156 +#include <stdexcept>
\r
7157 +#include <uuid/uuid.h>
\r
7158 +#include "wcsUtil.h"
\r
7159 +//#include "mfhdf.h"
\r
7161 +/************************************************************************/
\r
7163 +/************************************************************************/
\r
7166 + * \brief Used to get UUID string.
\r
7168 + * This method will return a UUID, such as: cd32eb56-412c-11e0-9cce-67750f871b94
\r
7170 + * @return A generated UUID string.
\r
7173 +string CPL_STDCALL GetUUID()
\r
7176 + uuid_generate(uuid);
\r
7177 + char uuidstr[36];
\r
7178 + uuid_unparse(uuid, uuidstr);
\r
7182 +/************************************************************************/
\r
7183 +/* SPrintArray() */
\r
7184 +/************************************************************************/
\r
7187 + * \brief Print a string based on coverage realted parameters.
\r
7189 + * This method will return a UUID, such as: cd32eb56-412c-11e0-9cce-67750f871b94
\r
7191 + * @return A generated UUID string.
\r
7194 +string CPL_STDCALL SPrintArray(GDALDataType eDataType, const void *paDataArray, int nValues, const char *pszDelimiter)
\r
7196 + char *pszString, *pszField;
\r
7197 + int i, iFieldSize, iStringSize;
\r
7199 + iFieldSize = 32 + strlen(pszDelimiter);
\r
7200 + pszField = (char *) CPLMalloc(iFieldSize + 1);
\r
7201 + iStringSize = nValues * iFieldSize + 1;
\r
7202 + pszString = (char *) CPLMalloc(iStringSize);
\r
7203 + memset(pszString, 0, iStringSize);
\r
7204 + for (i = 0; i < nValues; i++)
\r
7206 + switch (eDataType)
\r
7209 + sprintf(pszField, "%d%s", ((GByte *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7211 + case GDT_UInt16:
\r
7212 + sprintf(pszField, "%u%s", ((GUInt16 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7216 + sprintf(pszField, "%d%s", ((GInt16 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7218 + case GDT_UInt32:
\r
7219 + sprintf(pszField, "%u%s", ((GUInt32 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7222 + sprintf(pszField, "%d%s", ((GInt32 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7224 + case GDT_Float32:
\r
7225 + sprintf(pszField, "%.7g%s", ((float *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7227 + case GDT_Float64:
\r
7228 + sprintf(pszField, "%.15g%s", ((double *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
7231 + strcat(pszString, pszField);
\r
7234 + CPLFree(pszField);
\r
7236 + return string(pszString);
\r
7239 +/************************************************************************/
\r
7240 +/* StrTrimHead() */
\r
7241 +/************************************************************************/
\r
7244 + * \brief Trim s string's head.
\r
7246 + * This method will trim a string's head, remove the sapce and line break
\r
7247 + * in the head of a string.
\r
7249 + * @param str The string to be processed.
\r
7251 + * @return A head-trimmed string.
\r
7254 +string CPL_STDCALL StrTrimHead(const string &str)
\r
7256 + string::size_type p = 0;
\r
7257 + /* leading space? */
\r
7258 + while ((p < str.size()) && (str[p] == ' ' || str[p] == '\t' || str[p] == 13 || str[p] == 10))
\r
7260 + if (p >= str.size())
\r
7263 + return str.substr(p);
\r
7266 +/************************************************************************/
\r
7267 +/* StrTrimTail() */
\r
7268 +/************************************************************************/
\r
7271 + * \brief Trim s string's tail.
\r
7273 + * This method will trim a string's tail, remove the sapce and line break
\r
7274 + * in the tail of a string.
\r
7276 + * @param str The string to be processed.
\r
7278 + * @return A tail-trimmed string.
\r
7281 +string CPL_STDCALL StrTrimTail(const string &str)
\r
7283 + string::size_type p = str.size() - 1;
\r
7284 + while (p >= 0 && (str[p] == ' ' || str[p] == '\t' || str[p] == 13 || str[p] == 10))
\r
7289 + return str.substr(0, p + 1);
\r
7292 +/************************************************************************/
\r
7294 +/************************************************************************/
\r
7297 + * \brief Trim s string's head and tail.
\r
7299 + * This method will trim a string's head and tail, remove the sapce and
\r
7300 + * line break in both the head and end of a string.
\r
7302 + * @param str The string to be processed.
\r
7304 + * @return A trimmed string.
\r
7307 +string CPL_STDCALL StrTrim(const string &str)
\r
7309 + string s = StrTrimTail(str);
\r
7310 + return StrTrimHead(s);
\r
7313 +/************************************************************************/
\r
7315 +/************************************************************************/
\r
7318 + * \brief Trim s string's head and tail based on delimiter string.
\r
7320 + * This method will trim a string's head and tail based on delimiter
\r
7321 + * string, and return the trimmed string.
\r
7323 + * @param srcStr The string to be processed.
\r
7325 + * @param tok The delimiter string used to trim the string.
\r
7327 + * @return A trimmed string.
\r
7330 +string CPL_STDCALL StrTrims(const string& srcStr, const char* tok)
\r
7332 + if (srcStr.empty())
\r
7335 + string::size_type beginIdx, endIdx;
\r
7336 + beginIdx = srcStr.find_first_not_of(tok);
\r
7337 + endIdx = srcStr.find_last_not_of(tok);
\r
7339 + if (beginIdx != string::npos && endIdx != string::npos)
\r
7340 + return srcStr.substr(beginIdx, endIdx - beginIdx + 1);
\r
7345 +/************************************************************************/
\r
7347 +/************************************************************************/
\r
7350 + * \brief Slice a string and split it into an array.
\r
7352 + * This method will slice a string based on left and right delimiter, and then
\r
7353 + * split the slipped part into an array.
\r
7355 + * @param str The string to be processed, such as "longitude[15.5,23.5]"
\r
7357 + * @param arrStr The two dimension array to place the sliced results.
\r
7359 + * @param leftdlm The left delimiter used to slip the string, such as '['.
\r
7361 + * @param rightdlm The right delimiter used to slip the string, such as ']'.
\r
7364 +void CPL_STDCALL Strslip(const char* str, const char* arrStr[], const char leftdlm, const char rightdlm)
\r
7366 + char* pdest1 = 0;
\r
7367 + char* pdest2 = 0;
\r
7369 + arrStr[0] = str;
\r
7370 + pdest1 = (char*)strchr(str, leftdlm);
\r
7373 + arrStr[1] = str;
\r
7377 + pdest2 = (char*)strrchr(str, rightdlm);
\r
7381 + arrStr[1] = pdest1 + 1;
\r
7388 +/************************************************************************/
\r
7389 +/* CsvburstComplexCpp() */
\r
7390 +/************************************************************************/
\r
7393 + * \brief Slice a string based on single or multiple delimiter(s), and
\r
7394 + * then store the results to array.
\r
7396 + * This method will slice a string based on specified delimiter(s), and then
\r
7397 + * place the sliced string parts to a array.
\r
7399 + * @param line The string to be processed.
\r
7401 + * @param strSet The array to place the sliced results.
\r
7403 + * @param tok The delimiter string used to slice the string.
\r
7405 + * @return The size of the sliced parts.
\r
7408 +int CPL_STDCALL CsvburstComplexCpp(const string& line, vector<string> &strSet, const char *tok)
\r
7410 + if (line.empty() || line == "")
\r
7414 + string::size_type firstPos, idx;
\r
7416 + firstPos = idx = 0;
\r
7417 + idx = line.find_first_of(tok, firstPos);
\r
7419 + while (idx != string::npos)
\r
7421 + string tmpStr = StrTrim(line.substr(firstPos, (idx - firstPos)));
\r
7422 + if (!tmpStr.empty() && tmpStr != "")
\r
7423 + strSet.push_back(tmpStr);
\r
7425 + firstPos = idx + 1;
\r
7426 + if (firstPos == string::npos)
\r
7428 + idx = line.find_first_of(tok, firstPos);
\r
7431 + if (firstPos != string::npos)
\r
7433 + strSet.push_back(StrTrim(line.substr(firstPos)));
\r
7436 + return strSet.size();
\r
7439 +/************************************************************************/
\r
7440 +/* CsvburstCpp() */
\r
7441 +/************************************************************************/
\r
7444 + * \brief Slice a string based on single delimiter, and then store the results to array.
\r
7446 + * This method will slice a string based on specified single delimiter, and then
\r
7447 + * place the sliced string parts to a array.
\r
7449 + * @param line The string to be processed, such as "12,34,56".
\r
7451 + * @param strSet The array to place the sliced results.
\r
7453 + * @param tok The delimiter character used to slice the string, such as ','.
\r
7455 + * @return The size of the sliced parts.
\r
7458 +int CPL_STDCALL CsvburstCpp(const string& line, vector<string> &strSet, const char tok)
\r
7460 + if (line.empty() || line == "")
\r
7464 + string::size_type firstPos, idx;
\r
7465 + string::size_type panfuPos;
\r
7467 + firstPos = idx = 0;
\r
7469 + idx = line.find_first_of(tok, firstPos);
\r
7471 + while (idx != string::npos)
\r
7473 + if(line[idx-2] == '\"' || line[idx-2] == '\'')//Add By Yuanzheng Shao
\r
7475 + firstPos = idx + 1;
\r
7476 + if (firstPos == string::npos)
\r
7478 + panfuPos = idx-2;
\r
7479 + idx = line.find_first_of(tok, firstPos);
\r
7481 + string tmpStr = StrTrim(line.substr(panfuPos, (idx - panfuPos)));
\r
7482 + if (!tmpStr.empty() && tmpStr != "")
\r
7483 + strSet.push_back(tmpStr);
\r
7485 + firstPos = idx + 1;
\r
7486 + idx = line.find_first_of(tok, firstPos);
\r
7490 + string tmpStr = StrTrim(line.substr(firstPos, (idx - firstPos)));
\r
7491 + if (!tmpStr.empty() && tmpStr != "")
\r
7492 + strSet.push_back(tmpStr);
\r
7494 + firstPos = idx + 1;
\r
7495 + if (firstPos == string::npos)
\r
7497 + idx = line.find_first_of(tok, firstPos);
\r
7501 + if (firstPos != string::npos)
\r
7503 + strSet.push_back(StrTrim(line.substr(firstPos)));
\r
7506 + return strSet.size();
\r
7509 +/************************************************************************/
\r
7510 +/* Find_Compare_SubStr() */
\r
7511 +/************************************************************************/
\r
7514 + * \brief Find the substring in a string.
\r
7516 + * This method will find a substring in a string.
\r
7518 + * @param line The string to be processed.
\r
7520 + * @param sub The substring to be compared.
\r
7522 + * @return TRUE if find the substring, otherwise FALSE.
\r
7525 +int CPL_STDCALL Find_Compare_SubStr(string line, string sub)
\r
7527 + if (line.empty() || line == "" || sub.empty() || sub == "")
\r
7530 + for (unsigned int i = 0; i < line.size(); ++i)
\r
7532 + line[i] = (char) toupper((char) line[i]);
\r
7534 + for (unsigned int j = 0; j < sub.size(); ++j)
\r
7536 + sub[j] = (char) toupper((char) sub[j]);
\r
7539 + if (string::npos == line.find(sub))
\r
7545 +/************************************************************************/
\r
7546 +/* GetFileNameList() */
\r
7547 +/************************************************************************/
\r
7550 + * \brief Fetch the file name list under the specified directory.
\r
7552 + * This method will fetch the file name list under the specified directory,
\r
7553 + * and store the results to a array.
\r
7555 + * @param dir The directory name.
\r
7557 + * @param strList The array used to place the results.
\r
7559 + * @return CE_None on success or CE_Failure on failure.
\r
7562 +CPLErr CPL_STDCALL GetFileNameList(char* dir, vector<string> &strList)
\r
7564 + char pwdBuf[256];
\r
7565 + char *pwd=getcwd (pwdBuf, 256);
\r
7567 + struct dirent *entry;
\r
7568 + struct stat statbuf;
\r
7569 + if ((dp = opendir(dir)) == NULL)
\r
7571 + SetWCS_ErrorLocator("getFileNameList()");
\r
7572 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Open Director %s", dir);
\r
7573 + return CE_Failure;
\r
7576 + if (dir[strlen(dir) - 1] == '/')
\r
7577 + dir[strlen(dir) - 1] = '\0';
\r
7581 + while ((entry = readdir(dp)) != NULL)
\r
7583 + lstat(entry->d_name, &statbuf);
\r
7584 + if (S_ISDIR(statbuf.st_mode))
\r
7586 + /* Found a directory, but ignore . and .. */
\r
7587 + if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)
\r
7589 + /* Recurse at a new indent level */
\r
7590 + string subdir = dir;
\r
7591 + subdir = subdir + "/" + entry->d_name;
\r
7592 + GetFileNameList((char*)subdir.c_str(), strList);
\r
7594 + else if (S_ISREG(statbuf.st_mode))
\r
7596 + string fname = getcwd(NULL, 0);
\r
7597 + fname = fname + "/" + entry->d_name;
\r
7598 + strList.push_back(fname);
\r
7607 +/************************************************************************/
\r
7608 +/* Julian2Date() */
\r
7609 +/************************************************************************/
\r
7612 + * \brief Convert the Julian days to date string.
\r
7614 + * This method will convert the days of year to its date string (YYYY-MM-DD);
\r
7616 + * @param year The year of days.
\r
7618 + * @param days The Julian days.
\r
7620 + * @return The date string.
\r
7623 +string Julian2Date(int year, int days)
\r
7625 + bool leapyear = ((year%4==0 && year%100!=0) || year%400==0) ? true : false;
\r
7628 + int leapArr[24] = {1, 31, 32, 60, 61, 91, 92, 121, 122, 152, 153, 182, 183, 213, 214, 244,
\r
7629 + 245, 274, 275, 305, 306, 335, 336, 366};
\r
7630 + int unLeArr[24] = {1, 31, 32, 59, 60, 90, 91, 120, 121, 151, 152, 181, 182, 212, 213, 243,
\r
7631 + 244, 273, 274, 304, 305, 334, 335, 365};
\r
7634 + for (int i = 0; i < 24; i += 2) {
\r
7635 + if(days >= leapArr[i] && days <= leapArr[i+1]) {
\r
7636 + month = int(i/2) + 1;
\r
7637 + day = days - leapArr[i] + 1;
\r
7642 + for (int i=0; i < 24; i += 2) {
\r
7643 + if(days >= unLeArr[i] && days <= unLeArr[i+1]) {
\r
7644 + month = int(i/2) + 1;
\r
7645 + day = days - unLeArr[i] + 1;
\r
7651 + string monthStr = month<10 ? "0" + convertToString(month) : convertToString(month);
\r
7652 + string dayStr = day<10 ? "0" + convertToString(day) : convertToString(day);
\r
7654 + return convertToString(year) + "-" + monthStr + "-" + dayStr;
\r
7657 +/************************************************************************/
\r
7658 +/* GetTRMMBandList() */
\r
7659 +/************************************************************************/
\r
7662 + * \brief Fetch the day's list for TRMM data based on the range of date/time.
\r
7664 + * This method will find day's list for TRMM data based on specified date/time
\r
7665 + * range, and store the results to a array.
\r
7667 + * @param start The start date/time.
\r
7669 + * @param end The end date/time.
\r
7671 + * @param bandList The array used to place the results.
\r
7673 + * @return CE_None on success or CE_Failure on failure.
\r
7676 +CPLErr CPL_STDCALL GetTRMMBandList(string start, string end, std::vector<int> &bandList)
\r
7678 + //calculate 2000-06-01's days, start's days, end's days
\r
7679 + if(EQUAL(start.c_str(), "") && EQUAL(end.c_str(), ""))
\r
7682 + string june1str = start.substr(0, 4) + "-06-01";
\r
7683 + long int june1sec = ConvertDateTimeToSeconds(june1str);
\r
7684 + long int startsec = 0, endsec = 0;
\r
7686 + if(!EQUAL(start.c_str(), ""))
\r
7687 + startsec = ConvertDateTimeToSeconds(start);
\r
7688 + if(!EQUAL(end.c_str(), ""))
\r
7689 + endsec = ConvertDateTimeToSeconds(end);
\r
7691 + int sdays = (int)(startsec - june1sec)/(24*3600) + 1;
\r
7692 + int edays = (int)(endsec - june1sec)/(24*3600) + 1;
\r
7694 + sdays = (sdays < 0) ? 0 : sdays;
\r
7695 + edays = (edays < 0) ? sdays : edays;
\r
7697 + for(int i = sdays; i <= edays; i++)
\r
7698 + bandList.push_back(i);
\r
7704 +/************************************************************************/
\r
7705 +/* GetTimeString() */
\r
7706 +/************************************************************************/
\r
7709 + * \brief Fetch the current system time to a string.
\r
7711 + * This method will get the current system time, and convert it to a string.
\r
7712 + * The return date/time has two formats:
\r
7713 + * 1: YYYYMMDDHHMMSS
\r
7714 + * 2: YYYY-MM-DDTHH:MM:SSZ
\r
7716 + * @param code The return string's format.
\r
7718 + * @return The string corresponding to current system time.
\r
7721 +string GetTimeString(int code)
\r
7723 + struct tm* ptime;
\r
7726 + ptime = localtime(&now);
\r
7727 + int year = ptime->tm_year + 1900;
\r
7728 + int month = ptime->tm_mon + 1;
\r
7729 + int day = ptime->tm_mday;
\r
7730 + int hour = ptime->tm_hour;
\r
7731 + int minute = ptime->tm_min;
\r
7732 + int second = ptime->tm_sec;
\r
7733 + string ye, mo, da, ho, mi, se;
\r
7734 + ye = convertToString(year);
\r
7735 + mo = (month < 10) ? "0" + convertToString(month) : convertToString(month);
\r
7736 + da = (day < 10) ? "0" + convertToString(day) : convertToString(day);
\r
7737 + ho = (hour < 10) ? "0" + convertToString(hour) : convertToString(hour);
\r
7738 + mi = (minute < 10) ? "0" + convertToString(minute) : convertToString(minute);
\r
7739 + se = (second < 10) ? "0" + convertToString(second) : convertToString(second);
\r
7741 + string timestring;
\r
7744 + string part1 = ye + mo + da;
\r
7745 + string part2 = ho + mi + se;
\r
7746 + timestring = part1.append(part2);
\r
7748 + else if(code == 2)
\r
7750 + string part1 = ye + "-" + mo + "-" + da + "T";
\r
7751 + string part2 = ho + ":" + mi + ":" + se + "Z";
\r
7752 + timestring = part1.append(part2);
\r
7755 + return timestring;
\r
7758 +/************************************************************************/
\r
7759 +/* MakeTempFile() */
\r
7760 +/************************************************************************/
\r
7763 + * \brief Generate a temporary file path.
\r
7765 + * This method will generate a path for temporary file or output file,
\r
7766 + * which is based on coverage identifier.
\r
7768 + * @param dir The directory of the temporary file.
\r
7770 + * @param covID The coverage identifier.
\r
7772 + * @param suffix The suffix of the file format.
\r
7774 + * @return The full path of the temporary file.
\r
7777 +string MakeTempFile(string dir, string covID, string suffix)
\r
7779 + string sOutFileName;
\r
7781 + if (!dir.empty() && dir != "")
\r
7783 + if (dir[dir.length() - 1] != '/')
\r
7788 + if (!suffix.empty() && suffix != "")
\r
7790 + if (suffix[0] != '.')
\r
7791 + suffix = "." + suffix;
\r
7796 + sOutFileName = dir + GetUUID() + suffix;
\r
7798 + else if (EQUALN(covID.c_str(),"HDF4_EOS:EOS_SWATH:",19) ||
\r
7799 + EQUALN(covID.c_str(),"HDF4_EOS:EOS_GRID:",18) ||
\r
7800 + EQUALN(covID.c_str(),"HDF5:",5))
\r
7802 + vector<string> strSet;
\r
7803 + int n = CsvburstCpp(covID, strSet, ':');
\r
7804 + if(n == 5){//Terra&Aqua
\r
7805 + string srcFilePath = StrTrims(strSet[2], "\'\"");
\r
7806 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
7807 + string datasetname = StrTrims(strSet[4], "\'\"");
\r
7808 + datasetname = StrReplace(datasetname, " ", "_");
\r
7809 + sOutFileName = dir + srcFileName + "." + datasetname + "." + GetTimeString(1) + suffix;
\r
7810 + }else if(n == 3) {//Aura
\r
7811 + string srcFilePath = StrTrims(strSet[1], "\'\"");
\r
7812 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
7813 + string datasetname = StrTrims(strSet[2], "\'\"");
\r
7814 + datasetname = StrReplace(datasetname, "//", "");
\r
7815 + datasetname = StrReplace(datasetname, "/", "_");
\r
7816 + datasetname = StrReplace(datasetname, " ", "");
\r
7817 + sOutFileName = dir + srcFileName + "." + datasetname + "." + GetTimeString(1) + suffix;
\r
7819 + sOutFileName = dir + GetUUID() + suffix;
\r
7820 + }else if(EQUALN( covID.c_str(), "GOES:NetCDF:",12))
\r
7822 + vector<string> strSet;
\r
7823 + int n = CsvburstCpp(covID, strSet, ':');
\r
7825 + string srcFilePath = StrTrims(strSet[2], " \'\"");
\r
7826 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
7827 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
7829 + sOutFileName = dir + GetUUID() + suffix;
\r
7831 + else if(EQUALN(covID.c_str(),"GEOTIFF:",8))
\r
7833 + vector<string> strSet;
\r
7834 + int n = CsvburstCpp(covID, strSet, ':');
\r
7836 + string srcFilePath = StrTrims(strSet[1], " \'\"");
\r
7837 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
7838 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
7840 + sOutFileName = dir + GetUUID() + suffix;
\r
7842 + else if(EQUALN(covID.c_str(),"TRMM:",5))
\r
7844 + vector<string> strSet;
\r
7845 + int n = CsvburstCpp(covID, strSet, ':');
\r
7847 + string srcFilePath = StrTrims(strSet[1], " \'\"");
\r
7848 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
7849 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
7851 + sOutFileName = dir + GetUUID() + suffix;
\r
7854 + sOutFileName = dir + GetUUID() + suffix;
\r
7856 + return sOutFileName;
\r
7859 +/************************************************************************/
\r
7860 +/* StringList() */
\r
7861 +/************************************************************************/
\r
7864 + * \brief Constructor for StringList.
\r
7867 +StringList::StringList(const string& sstrings, const char delimiter)
\r
7869 + string str = sstrings + delimiter;
\r
7870 + string::size_type np, op = 0;
\r
7871 + while ((op < str.size())
\r
7872 + && ((np = str.find(delimiter, op)) != string::npos))
\r
7874 + add(str.substr(op, np - op));
\r
7879 +// -----------------------------------------------------------------------
\r
7880 +// string list constructor
\r
7881 +// -----------------------------------------------------------------------
\r
7882 +StringList::StringList(const string& sstrings, const string& delimiters)
\r
7884 + string str = sstrings + delimiters;
\r
7885 + string::size_type np, op = 0;
\r
7886 + while ((op < str.size()) && ((np = str.find(delimiters, op))
\r
7887 + != string::npos))
\r
7889 + add(str.substr(op, np - op));
\r
7890 + op = np + delimiters.length();
\r
7894 +// -----------------------------------------------------------------------
\r
7895 +// string list -- append
\r
7896 +// -----------------------------------------------------------------------
\r
7897 +void StringList::append(StringList & s)
\r
7899 + for (int i = 0; i < s.size(); i++)
\r
7903 +// -----------------------------------------------------------------------
\r
7904 +// string list -- append with delimiter
\r
7905 +// -----------------------------------------------------------------------
\r
7906 +void StringList::append(const string sstrings, const char delimiter)
\r
7908 + StringList n(sstrings, delimiter);
\r
7912 +// -----------------------------------------------------------------------
\r
7913 +// string list -- append with delimiters
\r
7914 +// -----------------------------------------------------------------------
\r
7915 +void StringList::append(const string sstrings, const string& delimiters)
\r
7917 + StringList n(sstrings, delimiters);
\r
7921 +// -----------------------------------------------------------------------
\r
7922 +// string list -- return the index for query string
\r
7923 +// -----------------------------------------------------------------------
\r
7924 +int StringList::indexof(string qstr)
\r
7926 + for (int i = 0; i < size(); i++)
\r
7928 + if (strings[i] == qstr)
\r
7934 +/************************************************************************/
\r
7936 +/************************************************************************/
\r
7939 + * \brief Constructor for KVP.
\r
7941 + * @param namevaluepair The key-value pair.
\r
7944 +KVP::KVP(string namevaluepair)
\r
7946 + StringList ss(namevaluepair, '=');
\r
7947 + if (ss.size() == 2)
\r
7949 + name = StrTrim(ss[0]);
\r
7950 + value = StrTrim(ss[1]);
\r
7954 + name = namevaluepair;
\r
7959 +/************************************************************************/
\r
7960 +/* CFGReader() */
\r
7961 +/************************************************************************/
\r
7964 + * \brief Constructor for CFGReader.
\r
7966 + * This method is used to load the configuration file for WCS. Each configuration
\r
7967 + * item looks like a key-value pair, CFGReader() will read the file to memory and
\r
7968 + * store the parameters to a KVP array.
\r
7970 + * @param configfilename The full path of the configuration file.
\r
7973 +CFGReader::CFGReader(const string &configfilename)
\r
7975 + ifstream cfgfile(configfilename.c_str());
\r
7978 + SetWCS_ErrorLocator("CFGReader");
\r
7979 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open configure file.");
\r
7980 + throw runtime_error("");
\r
7983 + char line[MAX_LINE_LEN];
\r
7984 + while (!cfgfile.eof())
\r
7986 + cfgfile.getline(line, MAX_LINE_LEN - 1, '\n');
\r
7987 + if (!cfgfile.fail())
\r
7989 + if (line[0] != '#')
\r
7992 + kvps.push_back(kvp);
\r
7997 + cfgfile.close();
\r
8000 +/************************************************************************/
\r
8002 +/************************************************************************/
\r
8005 + * \brief Fetch a configured item's value.
\r
8007 + * This method is used to fetch a items value from a configuration file.
\r
8009 + * @param keyname The item's name.
\r
8011 + * @return The result string.
\r
8014 +string CFGReader::getValue(const string &keyname)
\r
8016 + for (int i = 0; i < size(); i++)
\r
8018 + if (EQUAL(kvps[i].name.c_str(), keyname.c_str()))
\r
8019 + return kvps[i].value;
\r
8025 +/************************************************************************/
\r
8027 +/************************************************************************/
\r
8030 + * \brief Fetch a configured item's value, with default value.
\r
8032 + * This method is used to fetch a items value from a configuration file,
\r
8033 + * if not found, use the default value.
\r
8035 + * @param keyname The item's name.
\r
8037 + * @param defaultvalue The item's default value.
\r
8039 + * @return The result string.
\r
8042 +string CFGReader::getValue(const string &keyname, const string &defaultvalue)
\r
8044 + string ret = getValue(keyname);
\r
8045 + if (ret.empty() || ret == "")
\r
8046 + return defaultvalue;
\r
8051 +/************************************************************************/
\r
8053 +/************************************************************************/
\r
8056 + * \brief The entry point for CGI program.
\r
8058 + * This method is used to fetch CGI parameters. Supports both HTTP GET
\r
8059 + * and POST method. POST content could be KVPs and XML string, and GET
\r
8060 + * content must be KVPs.
\r
8062 + * @return CE_None on success or CE_Failure on failure.
\r
8065 +CPLErr WCSCGI::Run()
\r
8067 + /* get request parameters*/
\r
8068 + char *gm = getenv("REQUEST_METHOD");
\r
8071 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
8072 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Get \"REQUEST_METHOD\" Environment variable.");
\r
8073 + return CE_Failure;
\r
8076 + if (EQUAL(gm, "POST"))
\r
8077 + me_CGIMethod = HTTP_XML_POST;
\r
8078 + else if (EQUAL(gm, "GET"))
\r
8079 + me_CGIMethod = HTTP_GET;
\r
8081 + me_CGIMethod = UN_KNOWN;
\r
8083 + switch (me_CGIMethod)
\r
8085 + case HTTP_XML_POST:
\r
8087 + char* aString = getenv("CONTENT_LENGTH");
\r
8088 + if (NULL == aString || aString[0] == '\0')
\r
8090 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Get \"CONTENT_LENGTH\" Environment variable.");
\r
8091 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
8092 + return CE_Failure;
\r
8095 + unsigned int cLength = atoi(aString);
\r
8098 + cString.resize(cLength + 1);
\r
8100 + if (cLength != fread((char*) cString.c_str(), 1, cLength, stdin))
\r
8102 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
8103 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Read POST Data Stream from Internet.");
\r
8104 + return CE_Failure;
\r
8107 + cString = StrReplace(cString, "&s;", "%26");
\r
8108 + cString = StrReplace(cString, "&", "%26");
\r
8110 + string tmpStr = CPLUnescapeString(cString.c_str(), NULL, CPLES_URL);
\r
8111 + ms_CGIContent = CPLUnescapeString((char*) tmpStr.c_str(), NULL, CPLES_XML);
\r
8113 + string::size_type beginIdx, endIdx;
\r
8115 + beginIdx = ms_CGIContent.find("<?");
\r
8116 + endIdx = ms_CGIContent.rfind(">");
\r
8117 + //The post contents could be KVPs
\r
8118 + if (beginIdx != string::npos && endIdx != string::npos)
\r
8119 + ms_CGIContent = ms_CGIContent.substr(beginIdx, endIdx - beginIdx + 1);
\r
8124 + string tmpStr = getenv("QUERY_STRING");
\r
8125 + tmpStr = StrReplace(tmpStr, "&s;", "%26");
\r
8126 + tmpStr = StrReplace(tmpStr, "&", "%26");
\r
8127 + if (tmpStr.empty() || tmpStr == "")
\r
8129 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
8130 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "No \"QUERY_STRING\" Content.");
\r
8131 + return CE_Failure;
\r
8134 + ms_CGIContent = CPLUnescapeString((char*) tmpStr.c_str(), NULL, CPLES_URL);
\r
8139 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
8140 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Unkown \"REQUEST_METHOD\".");
\r
8141 + return CE_Failure;
\r
8148 +// -----------------------------------------------------------------------
\r
8149 +// KVPsReader constructor
\r
8150 +// -----------------------------------------------------------------------
\r
8151 +KVPsReader::KVPsReader(const string& urlStr, const char &tok)
\r
8153 + StringList strLit(urlStr, tok);
\r
8155 + for (int i = 0; i < strLit.size(); ++i)
\r
8157 + KVP kvp(StrTrim(strLit[i]));
\r
8158 + m_kvps.push_back(kvp);
\r
8162 +// -----------------------------------------------------------------------
\r
8163 +// KVPsReader get value function
\r
8164 +// -----------------------------------------------------------------------
\r
8165 +string KVPsReader::getValue(const string &keyname)
\r
8167 + for (unsigned int i = 0; i < m_kvps.size(); i++)
\r
8169 + if (EQUAL(m_kvps[i].name.c_str() , keyname.c_str()))
\r
8170 + return m_kvps[i].value;
\r
8176 +vector<string> KVPsReader::getValues(const string &keyname)
\r
8178 + vector<string> valuesList;
\r
8179 + for (unsigned int i = 0; i < m_kvps.size(); i++)
\r
8181 + if (EQUAL(m_kvps[i].name.c_str() , keyname.c_str()))
\r
8182 + valuesList.push_back(m_kvps[i].value);
\r
8184 + return valuesList;
\r
8187 +// -----------------------------------------------------------------------
\r
8188 +// KVPsReader get value function, with default value
\r
8189 +// -----------------------------------------------------------------------
\r
8190 +string KVPsReader::getValue(const string &keyname, const string &defaultvalue)
\r
8192 + string ret = getValue(keyname);
\r
8193 + if (ret.empty() || ret == "")
\r
8194 + return defaultvalue;
\r
8199 +/************************************************************************/
\r
8200 +/* StrReplace() */
\r
8201 +/************************************************************************/
\r
8204 + * \brief Replace a string.
\r
8206 + * This method is used to replace a string with specified substring.
\r
8208 + * @param str The string needs to be processed.
\r
8210 + * @param oldSubStr The substring needs to be replaced.
\r
8212 + * @param newStr The string will replace the oldSubStr.
\r
8214 + * @return The processed string.
\r
8217 +string CPL_STDCALL StrReplace(string& str, const string oldSubStr, const string newStr)
\r
8221 + string::size_type pos(0);
\r
8222 + if( ( pos = str.find(oldSubStr) ) != string::npos )
\r
8224 + str.replace( pos, oldSubStr.length(), newStr );
\r
8232 +/************************************************************************/
\r
8233 +/* GetSingleValue() */
\r
8234 +/************************************************************************/
\r
8237 + * \brief Get a single value from a special KVP part.
\r
8239 + * This method is used to get value from a special KVP part.
\r
8241 + * @param subsetstr The string needs to be processed, such as "subset=Long(11)".
\r
8243 + * @return The processed string, such as "11".
\r
8246 +string CPL_STDCALL GetSingleValue(const string& subsetstr)
\r
8248 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
8249 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
8251 + return StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 -1));
\r
8254 +/************************************************************************/
\r
8255 +/* GetSubSetLatLon() */
\r
8256 +/************************************************************************/
\r
8259 + * \brief Get a subset spatial extent in WCS 2.0 request.
\r
8261 + * This method is used to get values of spatial extent and place the values
\r
8262 + * in an array, and return the CRS code for the coordinates of the extent.
\r
8264 + * @param subsetstr The string needs to be processed,
\r
8265 + * such as "subset=Lat,http://www.opengis.net/def/crs/EPSG/0/4326(32,47)".
\r
8267 + * @param subsetvalue The array to place the spatial extent values.
\r
8269 + * @return The processed string, such as "EPSG:4326".
\r
8272 +string CPL_STDCALL GetSubSetLatLon(const string& subsetstr, vector<double> &subsetvalue)
\r
8274 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
8275 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
8277 + string value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 -1));
\r
8278 + vector<string> tmpV;
\r
8279 + CsvburstCpp(value, tmpV, ',');
\r
8281 + for(unsigned int i = 0; i < tmpV.size(); i++)
\r
8284 + convertFromString(curD, tmpV.at(i));
\r
8285 + subsetvalue.push_back(curD);
\r
8288 + string subsetProj;
\r
8289 + idx1 = subsetstr.find(',');
\r
8290 + idx2 = subsetstr.find('(');
\r
8291 + if(idx1 > idx2)
\r
8293 + subsetProj = "EPSG:4326";
\r
8297 + value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 - 1));
\r
8298 + if(value.find("http") != string::npos)
\r
8300 + string::size_type idx3 = value.find_last_of('/');
\r
8301 + subsetProj = "EPSG:" + value.substr(idx3 + 1);
\r
8305 + subsetProj = value;
\r
8310 + return subsetProj;
\r
8313 +//subset=phenomenonTime("2006-08-01","2006-08-22T09:22:00Z")&
\r
8314 +//subset=phenomenonTime("2006-08-01")&
\r
8315 +void CPL_STDCALL GetSubSetTime(const string& subsetstr, vector<string> &subsetvalue)
\r
8317 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
8318 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
8319 + string value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 - 1));
\r
8320 + string valueN = StrReplace(value, "\"", "");
\r
8321 + CsvburstCpp(valueN, subsetvalue, ',');
\r
8324 +//time type 1: 2006-08-22T09:22:00Z
\r
8325 +//time type 1: 2006-08-01
\r
8326 +int CPL_STDCALL CompareDateTime_GreaterThan(string time1, string time2)
\r
8328 + time_t retval1 = 0;
\r
8329 + time_t retval2 = 0;
\r
8331 + struct tm storage1 = {0,0,0,0,0,0,0,0,0};
\r
8332 + struct tm storage2 = {0,0,0,0,0,0,0,0,0};
\r
8334 + char *p1 = NULL;
\r
8335 + char *p2 = NULL;
\r
8337 + if(time1.find("T") != string::npos && time1.find("Z") != string::npos)
\r
8338 + p1 = (char *)strptime(time1.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage1);
\r
8340 + p1 = (char *)strptime(time1.c_str(), "%Y-%m-%d", &storage1);
\r
8342 + if(time2.find("T") != string::npos && time2.find("Z") != string::npos)
\r
8343 + p2 = (char *)strptime(time2.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage2);
\r
8345 + p2 = (char *)strptime(time2.c_str(), "%Y-%m-%d", &storage2);
\r
8347 + retval1 = mktime(&storage1);
\r
8348 + retval2 = mktime(&storage2);
\r
8350 + if(retval1 == retval2)
\r
8352 + else if(retval1 > retval2)
\r
8359 +int CPL_STDCALL ConvertDateTimeToSeconds(string datetime)
\r
8361 + time_t retval1 = 0;
\r
8362 + struct tm storage1 = {0,0,0,0,0,0,0,0,0};
\r
8363 + char *p1 = NULL;
\r
8365 + if(datetime.find("T") != string::npos && datetime.find("Z") != string::npos)
\r
8366 + p1 = (char *)strptime(datetime.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage1);
\r
8368 + p1 = (char *)strptime(datetime.c_str(), "%Y-%m-%d", &storage1);
\r
8370 + retval1 = mktime(&storage1);
\r
8375 +// -----------------------------------------------------------------------
\r
8376 +// Find lower-left and upper-right corner point coordinate
\r
8377 +// -----------------------------------------------------------------------
\r
8378 +void CPL_STDCALL GetCornerPoints(const GDAL_GCP* &pGCPList, const int &nGCPs, My2DPoint& lowLeft, My2DPoint& upRight)
\r
8380 + double xLeft = (numeric_limits<double>::max)();
\r
8381 + double xRight = -xLeft;
\r
8382 + double yLower = (numeric_limits<double>::max)();
\r
8383 + double yUpper = -yLower;
\r
8385 + for (int j = 0; j < nGCPs; j++)
\r
8387 + yUpper = MAX(yUpper,pGCPList[j].dfGCPY);
\r
8388 + yLower = MIN(yLower,pGCPList[j].dfGCPY);
\r
8389 + if(pGCPList[j].dfGCPX != -999)//test MOD021KM.A2000065.1900.005.2008235220315.hdf, error GCP X value (-999)
\r
8390 + xLeft = MIN(xLeft,pGCPList[j].dfGCPX);
\r
8391 + xRight = MAX(xRight,pGCPList[j].dfGCPX);
\r
8394 + lowLeft.mi_X = xLeft;
\r
8395 + lowLeft.mi_Y = yLower;
\r
8396 + upRight.mi_X = xRight;
\r
8397 + upRight.mi_Y = yUpper;
\r
8401 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/82/82ef297cba5eb92b8c25159c74318bee457c1f00.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/82/82ef297cba5eb92b8c25159c74318bee457c1f00.svn-base
8402 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/82/82ef297cba5eb92b8c25159c74318bee457c1f00.svn-base 1970-01-01 01:00:00.000000000 +0100
8403 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/82/82ef297cba5eb92b8c25159c74318bee457c1f00.svn-base 2014-03-03 15:47:37.983566265 +0100
8406 +# Build libswath2grid, part of libdap.
8408 +AUTOMAKE_OPTIONS = foreign
8410 +AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) -I$(top_srcdir)/tests -I$(top_srcdir)/dispatch $(XML2_CFLAGS) $(CURL_CFLAGS)
8414 +AM_CPPFLAGS += $(CPPUNIT_CFLAGS)
8415 +AM_LDADD += $(CPPUNIT_LIBS)
8418 +# These are not used by automake but are often useful for certain types of
8419 +# debugging. The best way to use these is to run configure as:
8420 +# export CXXFLAGS='...'; ./configure --disable-shared
8421 +# the --disable-shared is not required, but it seems to help with debuggers.
8422 +CXXFLAGS_DEBUG = -g3 -O0 -Wall -W -Wcast-align -Werror
8423 +TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
8428 +# This determines what gets built by make check
8429 +check_PROGRAMS = $(UNIT_TESTS)
8431 +# This determines what gets run by 'make check.'
8432 +# Now (12/20/12) this fails; don't run until it works.
8433 +# TESTS = $(UNIT_TESTS)
8436 +noinst_LTLIBRARIES = libswath2grid.la
8438 +libswath2grid_la_SOURCES = $(SRCS) $(HDRS)
8439 +libswath2grid_la_CPPFLAGS = $(GDAL_CFLAGS) $(XML2_CFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) -I$(top_srcdir)/dispatch
8440 +libswath2grid_la_LDFLAGS =
8441 +libswath2grid_la_LIBADD = $(GDAL_LDFLAGS) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS)
8443 +SRCS = AbstractDataset.cpp wcs_error.cpp \
8444 +BoundingBox.cpp wcsUtil.cpp DAP_Dataset.cpp reproj_functions.cc
8446 +# NC_GOES_Dataset.cpp NC_GOES_Dataset.h
8448 +HDRS = AbstractDataset.h wcs_error.h \
8449 +BoundingBox.h wcsUtil.h DAP_Dataset.h reproj_functions.h
8452 +UNIT_TESTS = s2gTest
8459 + @echo "**********************************************************"
8460 + @echo "You must have cppunit 1.12.x or greater installed to run *"
8461 + @echo "check target in unit-tests directory *"
8462 + @echo "**********************************************************"
8466 +s2gTest_SOURCES = s2gTest.cc
8467 +s2gTest_CPPFLAGS = $(AM_CPPFLAGS) $(DAP_SERVER_CFLAGS) $(DAP_CLIENT_CFLAGS) $(GDAL_CFLAGS)
8468 +s2gTest_LDADD = -ltest-types libswath2grid.la $(AM_LDADD) $(DAP_SERVER_LIBS) $(DAP_CLIENT_LIBS) $(GDAL_LDFLAGS)
8473 + @echo "**********************************************************"
8474 + @echo "USING DAP "
8475 + @echo "DAP_CLIENT_CFLAGS: " $(DAP_CLIENT_CFLAGS)
8476 + @echo "DAP_SERVER_CFLAGS: " $(DAP_SERVER_CFLAGS)
8477 + @echo "DAP_CLIENT_LIBS: " $(DAP_CLIENT_LIBS)
8478 + @echo "DAP_SERVER_LIBS: " $(DAP_SERVER_LIBS)
8479 + @echo "**********************************************************"
8484 + @echo "**********************************************************"
8485 + @echo " Unable to locate DAP libraries!"
8486 + @echo "**********************************************************"
8494 + @echo "**********************************************************"
8495 + @echo "Using gdal. "
8496 + @echo "GDAL_CFLAGS: " $(GDAL_CFLAGS)
8497 + @echo "GDAL_LDFLAGS: " $(GDAL_LDFLAGS)
8498 + @echo "**********************************************************"
8503 + @echo "**********************************************************"
8504 + @echo "You must have gdal 12.15.12 or greater installed to run"
8505 + @echo "check target in unit-tests directory "
8506 + @echo "GDAL_VERSION: '$(GDAL_VERSION)'"
8507 + @echo "prefix: '$(prefix)'"
8508 + @echo "**********************************************************"
8511 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/84/8411727990dab1414d2bd0e9918fa8c2350fea4b.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/84/8411727990dab1414d2bd0e9918fa8c2350fea4b.svn-base
8512 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/84/8411727990dab1414d2bd0e9918fa8c2350fea4b.svn-base 1970-01-01 01:00:00.000000000 +0100
8513 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/84/8411727990dab1414d2bd0e9918fa8c2350fea4b.svn-base 2014-03-03 15:47:37.400232956 +0100
8515 +<?xml version="1.0" encoding="UTF-8"?>
8516 +<request reqID ="some_unique_value" >
8517 + <setContext name="dap_format">dap2</setContext>
8518 + <setContext name="xdap_accept">3.3</setContext>
8519 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
8521 + <container name="c">
8522 + <constraint>swath2grid()</constraint>
8525 + <get type="dods" definition="d"/>
8528 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/84/84572441d00db760c377120e09ab68451d54d4a4.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/84/84572441d00db760c377120e09ab68451d54d4a4.svn-base
8529 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/84/84572441d00db760c377120e09ab68451d54d4a4.svn-base 1970-01-01 01:00:00.000000000 +0100
8530 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/84/84572441d00db760c377120e09ab68451d54d4a4.svn-base 2014-03-03 15:47:37.846899604 +0100
8532 +<?xml version="1.0" encoding="UTF-8"?>
8533 +<request reqID ="some_unique_value" >
8534 + <setContext name="dap_format">dap2</setContext>
8535 + <setContext name="xdap_accept">3.3</setContext>
8536 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
8538 + <container name="c">
8539 + <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
8542 + <get type="dods" definition="d"/>
8545 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a1/a171586f7cd3757d03bb9b30306a4d2e0b053077.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/a1/a171586f7cd3757d03bb9b30306a4d2e0b053077.svn-base
8546 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a1/a171586f7cd3757d03bb9b30306a4d2e0b053077.svn-base 1970-01-01 01:00:00.000000000 +0100
8547 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/a1/a171586f7cd3757d03bb9b30306a4d2e0b053077.svn-base 2014-03-03 15:47:37.590232948 +0100
8550 +// -*- mode: c++; c-basic-offset:4 -*-
8552 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
8553 +// Access Protocol.
8555 +// Copyright (c) 2012 OPeNDAP, Inc.
8556 +// Author: James Gallagher <jgallagher@opendap.org>
8558 +// This library is free software; you can redistribute it and/or
8559 +// modify it under the terms of the GNU Lesser General Public
8560 +// License as published by the Free Software Foundation; either
8561 +// version 2.1 of the License, or (at your option) any later version.
8563 +// This library is distributed in the hope that it will be useful,
8564 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
8565 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8566 +// Lesser General Public License for more details.
8568 +// You should have received a copy of the GNU Lesser General Public
8569 +// License along with this library; if not, write to the Free Software
8570 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
8572 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
8574 +// Tests for the AISResources class.
8576 +#include <cppunit/TextTestRunner.h>
8577 +#include <cppunit/extensions/TestFactoryRegistry.h>
8578 +#include <cppunit/extensions/HelperMacros.h>
8581 +//#define DODS_DEBUG2
8583 +#include "BaseType.h"
8587 +#include "reproj_functions.h"
8589 +#include "test/TestTypeFactory.h"
8594 +#define THREE_ARRAY_1_DDS "three_array_1.dds"
8595 +#define THREE_ARRAY_1_DAS "three_array_1.das"
8597 +using namespace CppUnit;
8598 +using namespace libdap;
8599 +using namespace std;
8601 +int test_variable_sleep_interval = 0;
8604 + * Splits the string on the passed char. Returns vector of substrings.
8605 + * TODO make this work on situations where multiple spaces doesn't hose the split()
8607 +static vector<string> &split(const string &s, char delim, vector<string> &elems) {
8608 + stringstream ss(s);
8610 + while (getline(ss, item, delim)) {
8611 + elems.push_back(item);
8617 + * Splits the string on the passed char. Returns vector of substrings.
8619 +static vector<string> split(const string &s, char delim = ' ') {
8620 + vector<string> elems;
8621 + return split(s, delim, elems);
8624 +class s2gTest:public TestFixture
8628 + TestTypeFactory btf;
8629 + ConstraintEvaluator ce;
8639 + dds = new DDS(&btf);
8640 + string dds_file = /*(string)TEST_SRC_DIR + "/" +*/ THREE_ARRAY_1_DDS ;
8641 + dds->parse(dds_file);
8643 + string das_file = /*(string)TEST_SRC_DIR + "/" +*/ THREE_ARRAY_1_DAS ;
8644 + das.parse(das_file);
8645 + dds->transfer_attributes(&das);
8647 + DBG(dds->print_xml(stderr, false, "noBlob"));
8649 + // Load values into the array variables
8650 + Array & t = dynamic_cast < Array & >(*dds->var("t"));
8651 + Array & lon = dynamic_cast < Array & >(*dds->var("lon"));
8652 + Array & lat = dynamic_cast < Array & >(*dds->var("lat"));
8654 + dods_float64 t_vals[10][10];
8655 + for (int i = 0; i < 10; ++i)
8656 + for (int j = 0; j < 10; ++j)
8657 + t_vals[i][j] = j + (i * 10);
8658 + t.set_value(&t_vals[0][0], 100);
8659 + t.set_read_p(true);
8661 + // Read real lat/lon values from a Level 1B file ascii dump
8662 + fstream input("AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz.ascii.txt", fstream::in);
8663 + if (input.eof() || input.fail())
8664 + throw Error("Could not open lat/lon data in SetUp.");
8665 + // Read a line of text to get to the start of the data.
8667 + getline(input, line);
8668 + if (input.eof() || input.fail())
8669 + throw Error("Could not read lat/lon data in SetUp.");
8671 + dods_float64 lon_vals[10][10];
8672 + for (int i = 0; i < 10; ++i) {
8673 + getline(input, line);
8674 + if (input.eof() || input.fail())
8675 + throw Error("Could not read lon data from row " + long_to_string(i) + " in SetUp.");
8676 + vector<string> vals = split(line, ',');
8677 + for (unsigned int j = 1; j < vals.size(); ++j) {
8678 + DBG2(cerr << "loading in lon value: " << vals[j] << "' " << atof(vals[j].c_str()) << endl;)
8679 + lon_vals[i][j-1] = atof(vals[j].c_str());
8682 + lon.set_value(&lon_vals[0][0], 100);
8683 + lon.set_read_p(true);
8685 + dods_float64 lat_vals[10][10];
8686 + for (int i = 0; i < 10; ++i) {
8687 + getline(input, line);
8688 + if (input.eof() || input.fail())
8689 + throw Error("Could not read lat data from row " + long_to_string(i) + " in SetUp.");
8690 + vector<string> vals = split(line, ',');
8691 + for (unsigned int j = 1; j < vals.size(); ++j) {
8692 + DBG2(cerr << "loading in lat value: " << vals[j] << "' " << atof(vals[j].c_str()) << endl;)
8693 + lat_vals[i][j-1] = atof(vals[j].c_str());
8696 + lat.set_value(&lat_vals[0][0], 100);
8697 + lat.set_read_p(true);
8700 + catch (Error & e) {
8701 + cerr << "SetUp (Error): " << e.get_error_message() << endl;
8704 + catch(std::exception &e) {
8705 + cerr << "SetUp (std::exception): " << e.what() << endl;
8712 + delete dds; dds = 0;
8715 + CPPUNIT_TEST_SUITE( s2gTest );
8717 + CPPUNIT_TEST(no_arguments_test);
8718 + CPPUNIT_TEST(array_return_test);
8719 + CPPUNIT_TEST(grid_return_test);
8721 + CPPUNIT_TEST_SUITE_END();
8723 + void no_arguments_test()
8726 + BaseType *btp = 0;
8727 + function_swath2array(0, 0, *dds, &btp);
8728 + CPPUNIT_ASSERT(true);
8730 + catch (Error &e) {
8731 + DBG(cerr << e.get_error_message() << endl);
8732 + CPPUNIT_ASSERT(!"no_arguments_test() should not have failed");
8736 + void array_return_test()
8739 + BaseType *argv[3];
8740 + argv[0] = dds->var("t");
8741 + argv[1] = dds->var("lon");
8742 + argv[2] = dds->var("lat");
8744 + BaseType *btp = 0;
8745 + function_swath2array(3, argv, *dds, &btp);
8747 + DBG(cerr << "btp->name(): " << btp->name() << endl);
8748 + CPPUNIT_ASSERT(btp->name() == "t");
8749 + CPPUNIT_ASSERT(btp->type() == dods_array_c);
8751 + // Extract data; I know it's 10x16 from debugging output
8752 + dods_float64 values[10][16];
8753 + Array *a = static_cast<Array*>(btp);
8754 + a->value(&values[0][0]);
8756 + catch (Error &e) {
8757 + DBG(cerr << e.get_error_message() << endl);
8758 + CPPUNIT_FAIL("array_return_test");
8763 + void one_argument_not_a_grid_test()
8766 + BaseType *argv[1];
8767 + argv[0] = dds->var("lat");
8768 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this, although it is not a grid");
8769 + BaseType *btp = 0;
8770 + function_grid(1, argv, *dds, &btp);
8771 + CPPUNIT_ASSERT(!"one_argument_not_a_grid_test() should have failed");
8773 + catch (Error &e) {
8774 + DBG(cerr << e.get_error_message() << endl);
8775 + CPPUNIT_ASSERT(true);
8779 + void map_not_in_grid_test()
8782 + BaseType *argv[2];
8783 + argv[0] = dds->var("a");
8784 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8785 + argv[1] = new Str("");
8786 + string expression = "3<second<=7";
8787 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8788 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8789 + BaseType *btp = 0;
8790 + function_grid(2, argv, *dds, &btp);
8791 + CPPUNIT_ASSERT(!"map_not_in_grid_test() should have failed");
8793 + catch (Error &e) {
8794 + DBG(cerr << e.get_error_message() << endl);
8795 + CPPUNIT_ASSERT(true);
8799 + void one_dim_grid_test()
8802 + BaseType *argv[2];
8803 + argv[0] = dds->var("a");
8804 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8805 + argv[1] = new Str("");
8806 + string expression = "3<first<=7";
8807 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8808 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8810 + BaseType *btp = 0;
8811 + function_grid(2, argv, *dds, &btp);
8812 + Grid &g = dynamic_cast<Grid&>(*btp);
8814 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
8815 + Array &m = dynamic_cast<Array&>(**g.map_begin());
8816 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
8817 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
8819 + catch (Error &e) {
8820 + DBG(cerr << e.get_error_message() << endl);
8821 + CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
8825 + void one_dim_grid_two_expressions_test()
8828 + BaseType *argv[3];
8829 + argv[0] = dds->var("a");
8830 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8832 + argv[1] = new Str("");
8833 + string expression = "first>3";
8834 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8835 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8837 + argv[2] = new Str("");
8838 + expression = "first<=7";
8839 + dynamic_cast<Str*>(argv[2])->val2buf(&expression);
8840 + dynamic_cast<Str*>(argv[2])->set_read_p(true);
8842 + //function_grid(3, argv, *dds);
8843 + BaseType *btp = 0;
8844 + function_grid(3, argv, *dds, &btp);
8845 + Grid &g = dynamic_cast<Grid&>(*btp);
8847 + //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
8848 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
8849 + Array &m = dynamic_cast<Array&>(**g.map_begin());
8850 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
8851 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
8853 + catch (Error &e) {
8854 + DBG(cerr << e.get_error_message() << endl);
8855 + CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
8859 + void one_dim_grid_descending_test()
8862 + BaseType *argv[2];
8863 + argv[0] = dds->var("b");
8864 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8865 + argv[1] = new Str("");
8866 + string expression = "3<first<=7";
8867 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8868 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8870 + BaseType *btp = 0;
8871 + function_grid(2, argv, *dds, &btp);
8872 + Grid &g = dynamic_cast<Grid&>(*btp);
8874 + //function_grid(2, argv, *dds);
8875 + //Grid &g = dynamic_cast<Grid&>(*function_grid(2, argv, *dds));
8876 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
8877 + Array &m = dynamic_cast<Array&>(**g.map_begin());
8878 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
8879 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
8881 + catch (Error &e) {
8882 + DBG(cerr << e.get_error_message() << endl);
8883 + CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
8887 + void one_dim_grid_two_expressions_descending_test()
8890 + BaseType *argv[3];
8891 + argv[0] = dds->var("b");
8892 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8894 + argv[1] = new Str("");
8895 + string expression = "first>3";
8896 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8897 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8899 + argv[2] = new Str("");
8900 + expression = "first<=7";
8901 + dynamic_cast<Str*>(argv[2])->val2buf(&expression);
8902 + dynamic_cast<Str*>(argv[2])->set_read_p(true);
8904 + BaseType *btp = 0;
8905 + function_grid(3, argv, *dds, &btp);
8906 + Grid &g = dynamic_cast<Grid&>(*btp);
8908 + //function_grid(3, argv, *dds);
8909 + //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
8910 + //Grid &g = dynamic_cast<Grid&>(*argv[0]);
8911 + Array &m = dynamic_cast<Array&>(**g.map_begin());
8912 + CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
8913 + CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
8915 + catch (Error &e) {
8916 + DBG(cerr << e.get_error_message() << endl);
8917 + CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
8921 + void one_dim_grid_noninclusive_values_test()
8924 + BaseType *argv[2];
8925 + argv[0] = dds->var("a");
8926 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8927 + argv[1] = new Str("");
8928 + string expression = "7<first<=3";
8929 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8930 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8932 + BaseType *btp = 0;
8933 + function_grid(2, argv, *dds, &btp);
8934 + //Grid &g = dynamic_cast<Grid&>(*btp);
8936 + // function_grid(2, argv, *dds);
8938 + CPPUNIT_ASSERT(!"one_dim_grid_noninclusive_values_test() should not have worked");
8940 + catch (Error &e) {
8941 + DBG(cerr << e.get_error_message() << endl);
8942 + CPPUNIT_ASSERT(true);
8946 + // grid() is not required to handle this case. This test is not used.
8947 + void values_outside_map_range_test()
8950 + BaseType *argv[2];
8951 + argv[0] = dds->var("a");
8952 + CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
8953 + argv[1] = new Str("");
8954 + string expression = "3<=first<20";
8955 + dynamic_cast<Str*>(argv[1])->val2buf(&expression);
8956 + dynamic_cast<Str*>(argv[1])->set_read_p(true);
8958 + BaseType *btp = 0;
8959 + function_grid(2, argv, *dds, &btp);
8960 + //Grid &g = dynamic_cast<Grid&>(*btp);
8962 + // function_grid(2, argv, *dds);
8964 + CPPUNIT_ASSERT(!"values_outside_map_range_test() should not have worked");
8966 + catch (Error &e) {
8967 + DBG(cerr << e.get_error_message() << endl);
8968 + CPPUNIT_ASSERT(true);
8972 + // linear_scale tests
8973 + void linear_scale_args_test() {
8975 + BaseType *btp = 0;
8976 + function_linear_scale(0, 0, *dds, &btp);
8977 + CPPUNIT_ASSERT(true);
8979 + catch (Error &e) {
8980 + DBG(cerr << e.get_error_message() << endl);
8981 + CPPUNIT_ASSERT(!"linear_scale_args_test: should not throw Error");
8985 + void linear_scale_array_test() {
8987 + Array *a = dynamic_cast<Grid&>(*dds->var("a")).get_array();
8988 + CPPUNIT_ASSERT(a);
8989 + BaseType *argv[3];
8991 + argv[1] = new Float64("");
8992 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
8993 + argv[2] = new Float64("");
8994 + dynamic_cast<Float64*>(argv[2])->set_value(10);//b
8995 + BaseType *scaled = 0;
8996 + function_linear_scale(3, argv, *dds, &scaled);
8997 + CPPUNIT_ASSERT(scaled->type() == dods_array_c
8998 + && scaled->var()->type() == dods_float64_c);
8999 + double *values = extract_double_array(dynamic_cast<Array*>(scaled));
9000 + CPPUNIT_ASSERT(values[0] == 10);
9001 + CPPUNIT_ASSERT(values[1] == 10.1);
9002 + CPPUNIT_ASSERT(values[9] == 10.9);
9004 + catch (Error &e) {
9005 + DBG(cerr << e.get_error_message() << endl);
9006 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
9010 + void linear_scale_grid_test() {
9012 + Grid *g = dynamic_cast<Grid*>(dds->var("a"));
9013 + CPPUNIT_ASSERT(g);
9014 + BaseType *argv[3];
9016 + argv[1] = new Float64("");
9017 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);
9018 + argv[2] = new Float64("");
9019 + dynamic_cast<Float64*>(argv[2])->set_value(10);
9020 + BaseType *scaled = 0;
9021 + function_linear_scale(3, argv, *dds, &scaled);
9022 + CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
9023 + Grid *g_s = dynamic_cast<Grid*>(scaled);
9024 + CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
9025 + double *values = extract_double_array(g_s->get_array());
9026 + CPPUNIT_ASSERT(values[0] == 10);
9027 + CPPUNIT_ASSERT(values[1] == 10.1);
9028 + CPPUNIT_ASSERT(values[9] == 10.9);
9030 + catch (Error &e) {
9031 + DBG(cerr << e.get_error_message() << endl);
9032 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
9036 + void linear_scale_grid_attributes_test() {
9038 + Grid *g = dynamic_cast<Grid*>(dds->var("a"));
9039 + CPPUNIT_ASSERT(g);
9040 + BaseType *argv[1];
9042 + BaseType *scaled = 0;
9043 + function_linear_scale(1, argv, *dds, &scaled);
9044 + CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
9045 + Grid *g_s = dynamic_cast<Grid*>(scaled);
9046 + CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
9047 + double *values = extract_double_array(g_s->get_array());
9048 + CPPUNIT_ASSERT(values[0] == 10);
9049 + CPPUNIT_ASSERT(values[1] == 10.1);
9050 + CPPUNIT_ASSERT(values[9] == 10.9);
9052 + catch (Error &e) {
9053 + DBG(cerr << e.get_error_message() << endl);
9054 + CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
9058 + // This tests the case where attributes are not found
9059 + void linear_scale_grid_attributes_test2() {
9061 + Grid *g = dynamic_cast<Grid*>(dds->var("b"));
9062 + CPPUNIT_ASSERT(g);
9063 + BaseType *argv[1];
9065 + BaseType *btp = 0;
9066 + function_linear_scale(1, argv, *dds, &btp);
9067 + CPPUNIT_FAIL("Should not get here; no params passed and no attributes set for grid 'b'");
9069 + catch (Error &e) {
9070 + DBG(cerr << e.get_error_message() << endl);
9071 + CPPUNIT_ASSERT("Caught exception");
9075 + void linear_scale_scalar_test() {
9077 + Int32 *i = new Int32("linear_scale_test_int32");
9078 + CPPUNIT_ASSERT(i);
9080 + BaseType *argv[3];
9082 + argv[1] = new Float64("");
9083 + dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
9084 + argv[2] = new Float64("");
9085 + dynamic_cast<Float64*>(argv[2])->set_value(10);//b
9086 + BaseType *scaled = 0;
9087 + function_linear_scale(3, argv, *dds, &scaled);
9088 + CPPUNIT_ASSERT(scaled->type() == dods_float64_c);
9090 + CPPUNIT_ASSERT(dynamic_cast<Float64*>(scaled)->value() == 10.1);
9092 + catch (Error &e) {
9093 + DBG(cerr << e.get_error_message() << endl);
9094 + CPPUNIT_ASSERT(!"Error in linear_scale_scalar_test()");
9099 + void function_dap_1_test() {
9101 + Int32 *i = new Int32("function_dap_1_test_int32");
9102 + CPPUNIT_ASSERT(i);
9104 + BaseType *argv[1];
9107 + ConstraintEvaluator unused;
9108 + function_dap(1, argv, *dds, unused);
9110 + CPPUNIT_ASSERT(dds->get_dap_major() == 2);
9111 + CPPUNIT_ASSERT(dds->get_dap_minor() == 0);
9113 + catch (Error &e) {
9114 + DBG(cerr << e.get_error_message() << endl);
9115 + CPPUNIT_FAIL("Error in function_dap_1_test(): " + e.get_error_message());
9119 + void function_dap_2_test() {
9121 + Float64 *d = new Float64("function_dap_1_test_float64");
9122 + CPPUNIT_ASSERT(d);
9123 + d->set_value(3.2);
9124 + BaseType *argv[1];
9127 + ConstraintEvaluator unused;
9128 + function_dap(1, argv, *dds, unused);
9130 + CPPUNIT_ASSERT(dds->get_dap_major() == 3);
9131 + CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
9133 + catch (Error &e) {
9134 + DBG(cerr << e.get_error_message() << endl);
9135 + CPPUNIT_FAIL("Error in function_dap_2_test(): " + e.get_error_message());
9139 + void function_dap_3_test() {
9141 + cerr <<"In function_dap_3_test" << endl;
9142 + ConstraintEvaluator unused;
9143 + function_dap(0, 0, *dds, unused);
9145 + CPPUNIT_FAIL("Should have thrown an exception on no args");
9147 + catch (Error &e) {
9148 + DBG(cerr << e.get_error_message() << endl);
9149 + CPPUNIT_ASSERT("Pass: Caught exception");
9153 + void grid_return_test()
9156 + BaseType *argv[3];
9157 + argv[0] = dds->var("t");
9158 + argv[1] = dds->var("lon");
9159 + argv[2] = dds->var("lat");
9161 + cerr << "Input values:" << endl;
9162 + dods_float64 t_vals[10][10];
9163 + Array *a = static_cast<Array*>(argv[0]);
9164 + a->value(&t_vals[0][0]);
9165 + for (int i = 0; i < 10; ++i) {
9166 + for (int j = 0; j < 10; ++j) {
9167 + cerr << "t[" << i << "][" << j << "]: " << t_vals[i][j] << endl;
9171 + BaseType *btp = 0;
9172 + function_swath2grid(3, argv, *dds, &btp);
9174 + DBG(cerr << "btp->name(): " << btp->name() << endl);
9175 + CPPUNIT_ASSERT(btp->name() == "t");
9176 + CPPUNIT_ASSERT(btp->type() == dods_grid_c);
9178 + // Extract data; I know it's 10x16 from debugging output
9179 + dods_float64 values[10][16];
9180 + Grid *g = static_cast<Grid*>(btp);
9181 + g->get_array()->value(&values[0][0]);
9183 + Grid::Map_iter m = g->map_begin();
9184 + dods_float64 lat[10];
9185 + static_cast<Array*>(*m)->value(&lat[0]);
9188 + dods_float64 lon[16];
9189 + static_cast<Array*>(*m)->value(&lon[0]);
9191 + cerr << "Output values:" << endl;
9192 + for (int i = 0; i < 10; ++i) {
9193 + for (int j = 0; j < 16; ++j) {
9194 + cerr << "t[" << i << "][" << j << "] == lon: " << lon[j] << ", lat: " << lat[i] << " val: " << values[i][j] << endl;
9198 + catch (Error &e) {
9199 + DBG(cerr << e.get_error_message() << endl);
9200 + CPPUNIT_FAIL("array_return_test");
9205 +CPPUNIT_TEST_SUITE_REGISTRATION(s2gTest);
9208 +main( int, char** )
9210 + CppUnit::TextTestRunner runner;
9211 + runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
9213 + bool wasSuccessful = runner.run( "", false ) ;
9215 + return wasSuccessful ? 0 : 1;
9217 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a3/a3f498cd850e8312c27336b44b772bc06e45db56.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/a3/a3f498cd850e8312c27336b44b772bc06e45db56.svn-base
9218 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a3/a3f498cd850e8312c27336b44b772bc06e45db56.svn-base 1970-01-01 01:00:00.000000000 +0100
9219 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/a3/a3f498cd850e8312c27336b44b772bc06e45db56.svn-base 2014-03-03 15:47:37.810232939 +0100
9221 +# three_array_1.das
9223 +# Created on: Dec 12, 2012
9231 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a4/a48ca81df02968d388c1aff08bdb983200a5cb0f.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/a4/a48ca81df02968d388c1aff08bdb983200a5cb0f.svn-base
9232 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/a4/a48ca81df02968d388c1aff08bdb983200a5cb0f.svn-base 1970-01-01 01:00:00.000000000 +0100
9233 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/a4/a48ca81df02968d388c1aff08bdb983200a5cb0f.svn-base 2014-03-03 15:47:37.980232932 +0100
9235 +<?xml version="1.0" encoding="UTF-8"?>
9236 +<request reqID ="some_unique_value" >
9237 + <setContext name="dap_format">dap2</setContext>
9238 + <setContext name="xdap_accept">3.3</setContext>
9239 + <setContainer name="c" space="catalog">/data/nc/OWS_9_Data/AIRS_570672/AIRS_AQUA_L1B_BRIGHTNESS_20101026_1617.nc.gz</setContainer>
9241 + <container name="c">
9242 + <constraint>swath2grid(topog,Latitude,Longitude)</constraint>
9245 + <get type="das" definition="d"/>
9248 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/bc/bceeadf67b7c887a5453ff7cc4e625483701f4e3.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/bc/bceeadf67b7c887a5453ff7cc4e625483701f4e3.svn-base
9249 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/bc/bceeadf67b7c887a5453ff7cc4e625483701f4e3.svn-base 1970-01-01 01:00:00.000000000 +0100
9250 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/bc/bceeadf67b7c887a5453ff7cc4e625483701f4e3.svn-base 2014-03-03 15:47:37.403566289 +0100
9253 +// -*- mode: c++; c-basic-offset:4 -*-
9255 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
9256 +// Access Protocol.
9258 +// Copyright (c) 2002,2003 OPeNDAP, Inc.
9259 +// Author: James Gallagher <jgallagher@opendap.org>
9261 +// This library is free software; you can redistribute it and/or
9262 +// modify it under the terms of the GNU Lesser General Public
9263 +// License as published by the Free Software Foundation; either
9264 +// version 2.1 of the License, or (at your option) any later version.
9266 +// This library is distributed in the hope that it will be useful,
9267 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
9268 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9269 +// Lesser General Public License for more details.
9271 +// You should have received a copy of the GNU Lesser General Public
9272 +// License along with this library; if not, write to the Free Software
9273 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
9275 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
9277 +// (c) COPYRIGHT URI/MIT 1999
9278 +// Please read the full copyright statement in the file COPYRIGHT_URI.
9281 +// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
9283 +// Declarations for CE functions.
9287 +#ifndef _reproj_functions_h
9288 +#define _reproj_functions_h
9290 +#include "BESAbstractModule.h"
9291 +#include "ServerFunction.h"
9292 +#include "ServerFunctionsList.h"
9296 +void function_swath2array(int argc, BaseType * argv[], DDS &, BaseType **btpp);
9297 +void function_swath2grid(int argc, BaseType * argv[], DDS &, BaseType **btpp);
9300 +class SwathToGrid: public libdap::ServerFunction {
9304 + setName("swath2grid");
9305 + setDescriptionString("This function echos back it's arguments as DAP data.");
9306 + setUsageString("swath2grid(dataArray, latitudeArray, longitudeArray)");
9307 + setRole("http://services.opendap.org/dap4/server-side-function/swath2grid");
9308 + setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2grid");
9309 + setFunction(libdap::function_swath2grid);
9310 + setVersion("1.0");
9312 + virtual ~SwathToGrid()
9318 +class SwathToArray: public libdap::ServerFunction {
9322 + setName("swath2array");
9323 + setDescriptionString("This function echos back it's arguments as DAP data.");
9324 + setUsageString("swath2array(dataArray, latitudeArray, longitudeArray)");
9325 + setRole("http://services.opendap.org/dap4/server-side-function/swath2array");
9326 + setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#swath2array");
9327 + setFunction(libdap::function_swath2array);
9328 + setVersion("1.0");
9330 + virtual ~SwathToArray()
9337 +class ReProjectionFunctions: public BESAbstractModule {
9339 + ReProjectionFunctions()
9341 + libdap::ServerFunctionsList::TheList()->add_function(new libdap::SwathToGrid());
9343 + libdap::ServerFunctionsList::TheList()->add_function(new libdap::SwathToArray());
9346 + virtual ~ReProjectionFunctions()
9349 + virtual void initialize(const string &modname);
9350 + virtual void terminate(const string &modname);
9352 + virtual void dump(ostream &strm) const;
9358 +} // namespace libdap
9360 +#endif // _reproj_functions_h
9361 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/bd/bd5bb3aeffa01d2e79bad1eba81402eb23ce33cd.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/bd/bd5bb3aeffa01d2e79bad1eba81402eb23ce33cd.svn-base
9362 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/bd/bd5bb3aeffa01d2e79bad1eba81402eb23ce33cd.svn-base 1970-01-01 01:00:00.000000000 +0100
9363 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/bd/bd5bb3aeffa01d2e79bad1eba81402eb23ce33cd.svn-base 2014-03-03 15:47:37.976899599 +0100
9365 +/******************************************************************************
9366 + * $Id: BoundingBox.h 2011-07-19 16:24:00Z $
9368 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
9369 + * for Earth Observation: Open Source Reference Implementation
9370 + * Purpose: BoundingBox class definition
9371 + * Author: Yuanzheng Shao, yshao3@gmu.edu
9373 + ******************************************************************************
9374 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
9376 + * Permission is hereby granted, free of charge, to any person obtaining a
9377 + * copy of this software and associated documentation files (the "Software"),
9378 + * to deal in the Software without restriction, including without limitation
9379 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9380 + * and/or sell copies of the Software, and to permit persons to whom the
9381 + * Software is furnished to do so, subject to the following conditions:
9383 + * The above copyright notice and this permission notice shall be included
9384 + * in all copies or substantial portions of the Software.
9386 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9387 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9388 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
9389 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9390 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9391 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9392 + * DEALINGS IN THE SOFTWARE.
9393 + ****************************************************************************/
9395 +#ifndef BOUNDINGBOX_H_
9396 +#define BOUNDINGBOX_H_
9399 +#include <ogr_spatialref.h>
9401 +#include <stdlib.h>
9403 +using namespace std;
9405 +/************************************************************************/
9406 +/* ==================================================================== */
9408 +/* ==================================================================== */
9409 +/************************************************************************/
9412 + * \class My2DPoint "BoundingBox.h"
9414 + * My2DPoint class is used to store the point coordinates.
9423 + virtual ~My2DPoint();
9431 + My2DPoint(const double& xx, const double& yy) :
9432 + mi_X(xx), mi_Y(yy)
9436 + My2DPoint(const My2DPoint& p) :
9437 + mi_X(p.mi_X), mi_Y(p.mi_Y)
9441 + My2DPoint& operator =(const My2DPoint& p)
9449 +/************************************************************************/
9450 +/* ==================================================================== */
9452 +/* ==================================================================== */
9453 +/************************************************************************/
9456 + * \class BoundingBox "BoundingBox.h"
9458 + * BoundingBox class is used to transform bounding box between different
9459 + * Coordinate Reference System.
9465 + My2DPoint mo_LowerLeftPT;
9466 + My2DPoint mo_UpperRightPT;
9467 + OGRSpatialReference mo_CRS;
9469 + BoundingBox(const My2DPoint& llpt, const My2DPoint& urpt, OGRSpatialReference& crs) :
9470 + mo_LowerLeftPT(llpt), mo_UpperRightPT(urpt), mo_CRS(crs)
9475 + BoundingBox(OGRSpatialReference& crs) :
9476 + mo_LowerLeftPT(0,0), mo_UpperRightPT(0,0), mo_CRS(crs)
9480 + BoundingBox& operator =(const BoundingBox& box)
9482 + mo_LowerLeftPT = box.mo_LowerLeftPT;
9483 + mo_UpperRightPT = box.mo_UpperRightPT;
9484 + mo_CRS = box.mo_CRS;
9489 + virtual ~BoundingBox();
9491 + BoundingBox Transform(OGRSpatialReference&, int&);
9492 + BoundingBox TransformWorkExtend(OGRSpatialReference&, int&);
9493 + BoundingBox Transform(const double*);
9496 +CPLErr CPL_DLL CPL_STDCALL bBox_transFormmate( OGRSpatialReference&,
9497 + OGRSpatialReference&,
9498 + My2DPoint& lowLeft,
9499 + My2DPoint& upRight);
9501 +#endif /* BOUNDINGBOX_H_ */
9502 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/d2/d2f2e54b019cc687d4f25e9e0e840b3d0e0cdaec.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/d2/d2f2e54b019cc687d4f25e9e0e840b3d0e0cdaec.svn-base
9503 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/d2/d2f2e54b019cc687d4f25e9e0e840b3d0e0cdaec.svn-base 1970-01-01 01:00:00.000000000 +0100
9504 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/d2/d2f2e54b019cc687d4f25e9e0e840b3d0e0cdaec.svn-base 2014-03-03 15:47:37.846899604 +0100
9506 +BES.ServerAdministrator=root@null.dev
9509 +BES.Group=group_name
9511 +BES.LogName=./bes.log
9514 +BES.modules=dap,cmd,nc,h4,fong,fonc
9515 +BES.module.dap=@libdir@/bes/libdap_module.so
9516 +BES.module.cmd=@libdir@/bes/libdap_xml_module.so
9518 +BES.module.nc=@libdir@/bes/libnc_module.so
9519 +BES.module.h4=@libdir@/bes/libhdf4_module.so
9521 +BES.module.fong=@libdir@/bes/libfong_module.so
9522 +BES.module.fonc=@libdir@/bes/libfonc_module.so
9524 +BES.Catalog.catalog.RootDirectory=@abs_top_srcdir@
9525 +BES.Data.RootDirectory=/dev/null
9527 +BES.Catalog.catalog.TypeMatch=nc:.*.nc(.bz2|.gz|.Z)?$;h4:.*.(hdf|HDF|eos)(.bz2|.gz|.Z)?$;
9529 +BES.Catalog.catalog.Include=;
9530 +BES.Catalog.catalog.Exclude=^\..*;
9532 +BES.FollowSymLinks=No
9533 +BES.Catalog.catalog.FollowSymLinks=No
9535 +BES.ServerPort=10002
9538 +BES.CachePrefix=bes_cache
9541 +BES.Container.Persistence=strict
9543 +BES.Memory.GlobalArea.EmergencyPoolSize=1
9544 +BES.Memory.GlobalArea.MaximumHeapSize=20
9545 +BES.Memory.GlobalArea.Verbose=no
9546 +BES.Memory.GlobalArea.ControlHeap=no
9548 +BES.ProcessManagerMethod=multiple
9550 +BES.DefaultResponseMethod=POST
9552 +FONg.TempDirectory=@abs_top_srcdir@/tests
9554 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/d9/d934c25630e184bf0b7bcaf42ac44a390652631c.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/d9/d934c25630e184bf0b7bcaf42ac44a390652631c.svn-base
9555 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/d9/d934c25630e184bf0b7bcaf42ac44a390652631c.svn-base 1970-01-01 01:00:00.000000000 +0100
9556 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/d9/d934c25630e184bf0b7bcaf42ac44a390652631c.svn-base 2014-03-03 15:47:37.843566270 +0100
9558 +/******************************************************************************
9559 + * $Id: BoundingBox.cpp 2011-07-19 16:24:00Z $
9561 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
9562 + * for Earth Observation: Open Source Reference Implementation
9563 + * Purpose: BoundingBox class implementation, enable transform bounding box
9564 + * between different CRS
9565 + * Author: Yuanzheng Shao, yshao3@gmu.edu
9567 + ******************************************************************************
9568 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
9570 + * Permission is hereby granted, free of charge, to any person obtaining a
9571 + * copy of this software and associated documentation files (the "Software"),
9572 + * to deal in the Software without restriction, including without limitation
9573 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9574 + * and/or sell copies of the Software, and to permit persons to whom the
9575 + * Software is furnished to do so, subject to the following conditions:
9577 + * The above copyright notice and this permission notice shall be included
9578 + * in all copies or substantial portions of the Software.
9580 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9581 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9582 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
9583 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9584 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9585 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9586 + * DEALINGS IN THE SOFTWARE.
9587 + ****************************************************************************/
9590 +#include <iostream>
9592 +#include "BoundingBox.h"
9593 +#include "wcs_error.h"
9595 +using namespace std;
9597 +My2DPoint::~My2DPoint()
9602 +BoundingBox::BoundingBox()
9607 +BoundingBox::~BoundingBox()
9612 +BoundingBox BoundingBox::TransformWorkExtend(OGRSpatialReference &dstCRS, int &IsOK)
9614 + if (mo_CRS.IsSame(&dstCRS))
9620 + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&mo_CRS, &dstCRS);
9627 + double xdes = (mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
9629 + if (mo_CRS.IsGeographic()
9630 + && mo_UpperRightPT.mi_X < mo_LowerLeftPT.mi_X
9631 + && mo_LowerLeftPT.mi_X > 0 && mo_UpperRightPT.mi_X < 0)
9633 + xdes = (360 + mo_UpperRightPT.mi_X - mo_LowerLeftPT.mi_X) / 100;
9638 + //up and down edge
9639 + for (double stepX = mo_LowerLeftPT.mi_X; stepX < mo_UpperRightPT.mi_X; stepX
9642 + x.push_back(stepX);
9643 + y.push_back(mo_UpperRightPT.mi_Y);
9644 + x.push_back(stepX);
9645 + y.push_back(mo_LowerLeftPT.mi_Y);
9647 + x.push_back(mo_UpperRightPT.mi_X);
9648 + y.push_back(mo_UpperRightPT.mi_Y);
9649 + x.push_back(mo_UpperRightPT.mi_X);
9650 + y.push_back(mo_LowerLeftPT.mi_Y);
9652 + double yMin = numeric_limits<double>::max();
9653 + double yMax = numeric_limits<double>::min();
9656 + vector<int> bSuccess;
9657 + vector<double> tmpX;
9658 + vector<double> tmpY;
9660 + for (unsigned int i = 0; i < x.size(); i++)
9662 + tmpX.push_back(x[i]);
9663 + tmpY.push_back(y[i]);
9664 + bSuccess.push_back(0);
9667 + poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
9669 + for (unsigned int n = 0; n < x.size(); n++)
9674 + yMin = MIN(yMin,tmpY[n]);
9675 + yMax = MAX(yMax,tmpY[n]);
9682 + OCTDestroyCoordinateTransformation(poCT);
9686 + //find xmin on left edge and xmax on right edge
9695 + tmpPTX[0] = mo_LowerLeftPT.mi_X;
9696 + tmpPTX[1] = mo_LowerLeftPT.mi_X;
9697 + tmpPTY[0] = mo_LowerLeftPT.mi_Y;
9698 + tmpPTY[1] = mo_UpperRightPT.mi_Y;
9700 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
9701 + if (isSucc[0] && isSucc[1])
9703 + xMin = MIN(tmpPTX[0],tmpPTX[1]);
9707 + OCTDestroyCoordinateTransformation(poCT);
9712 + tmpPTX[0] = mo_UpperRightPT.mi_X;
9713 + tmpPTX[1] = mo_UpperRightPT.mi_X;
9714 + tmpPTY[0] = mo_UpperRightPT.mi_Y;
9715 + tmpPTY[1] = mo_LowerLeftPT.mi_Y;
9717 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isSucc);
9718 + if (isSucc[0] && isSucc[1])
9720 + xMax = MAX(tmpPTX[0],tmpPTX[1]);
9724 + OCTDestroyCoordinateTransformation(poCT);
9729 + BoundingBox bbox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
9731 + if (dstCRS.IsGeographic())
9734 + xMin = xMin - 360;
9736 + xMax = xMax - 360;
9740 + if (xMin <= -180.)
9744 + if (xMax <= -180.)
9752 + OCTDestroyCoordinateTransformation(poCT);
9754 + return BoundingBox(My2DPoint(xMin, yMin), My2DPoint(xMax, yMax), dstCRS);
9757 +BoundingBox BoundingBox::Transform(const double GeoTransform[])
9761 + llPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_LowerLeftPT.mi_X + GeoTransform[2] * mo_LowerLeftPT.mi_Y;
9762 + llPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_LowerLeftPT.mi_X + GeoTransform[5] * mo_LowerLeftPT.mi_Y;
9763 + urPt.mi_X = GeoTransform[0] + GeoTransform[1] * mo_UpperRightPT.mi_X + GeoTransform[2] * mo_UpperRightPT.mi_Y;
9764 + urPt.mi_Y = GeoTransform[3] + GeoTransform[4] * mo_UpperRightPT.mi_X + GeoTransform[5] * mo_UpperRightPT.mi_Y;
9766 + return BoundingBox(llPt,urPt,mo_CRS);
9770 + * Transform Coordinates of lowercorner_left and upcorner_right
9771 + * lowLeft, upRight.
9772 + * the return value has considered the case of image area crossing 180/-180 longitude line,
9773 + * so lowLeft.x maybe bigger than upRight.x
9775 +CPLErr CPL_STDCALL bBox_transFormmate(OGRSpatialReference& oSrcCRS,
9776 + OGRSpatialReference& oDesCRS, My2DPoint& lowLeft, My2DPoint& upRight)
9778 + if (oSrcCRS.IsSame(&oDesCRS))
9781 + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&oSrcCRS, &oDesCRS);
9784 + SetWCS_ErrorLocator("bBox_transFormmate()");
9785 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Create \"OGRCoordinateTransformation\"");
9786 + return CE_Failure;
9789 + double xdes = (upRight.mi_X - lowLeft.mi_X) / 100;
9790 + if (oSrcCRS.IsGeographic() && upRight.mi_X < lowLeft.mi_X && lowLeft.mi_X > 0 && upRight.mi_X < 0)
9792 + xdes = (360 + upRight.mi_X - lowLeft.mi_X) / 100;
9795 + vector<double> x, y;
9796 + //up and down edge
9797 + for (double stepX = lowLeft.mi_X; stepX < upRight.mi_X; stepX += xdes)
9799 + x.push_back(stepX);
9800 + y.push_back(upRight.mi_Y);
9801 + x.push_back(stepX);
9802 + y.push_back(lowLeft.mi_Y);
9804 + x.push_back(upRight.mi_X);
9805 + y.push_back(upRight.mi_Y);
9806 + x.push_back(upRight.mi_X);
9807 + y.push_back(lowLeft.mi_Y);
9809 + double yMin = numeric_limits<double>::max();
9810 + double yMax = -numeric_limits<double>::max();
9813 + vector<int> bSuccess;
9814 + vector<double> tmpX;
9815 + vector<double> tmpY;
9817 + for (unsigned int i = 0; i < x.size(); i++)
9819 + tmpX.push_back(x[i]);
9820 + tmpY.push_back(y[i]);
9821 + bSuccess.push_back(0);
9824 + poCT->TransformEx(x.size(), &tmpX[0], &tmpY[0], NULL, &bSuccess[0]);
9826 + for (unsigned int n = 0; n < x.size(); n++)
9831 + yMin = MIN(yMin,tmpY[n]);
9832 + yMax = MAX(yMax,tmpY[n]);
9838 + OCTDestroyCoordinateTransformation(poCT);
9839 + SetWCS_ErrorLocator("bBox_transFormmate()");
9840 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
9841 + return CE_Failure;
9847 + //find xmin on left edge and xmax on right edge
9852 + tmpPTX[0] = lowLeft.mi_X;
9853 + tmpPTX[1] = lowLeft.mi_X;
9854 + tmpPTY[0] = upRight.mi_Y;
9855 + tmpPTY[1] = lowLeft.mi_Y;
9857 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
9858 + if (isOK[0] && isOK[1])
9860 + xMin = MIN(tmpPTX[0],tmpPTX[1]);
9864 + OCTDestroyCoordinateTransformation(poCT);
9865 + SetWCS_ErrorLocator("bBox_transFormmate()");
9866 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
9867 + return CE_Failure;
9870 + tmpPTX[0] = upRight.mi_X;
9871 + tmpPTX[1] = upRight.mi_X;
9872 + tmpPTY[0] = upRight.mi_Y;
9873 + tmpPTY[1] = lowLeft.mi_Y;
9875 + poCT->TransformEx(2, tmpPTX, tmpPTY, NULL, isOK);
9876 + if (isOK[0] && isOK[1])
9878 + xMax = MAX(tmpPTX[0],tmpPTX[1]);
9882 + SetWCS_ErrorLocator("bBox_transFormmate()");
9883 + OCTDestroyCoordinateTransformation(poCT);
9884 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Transform Coordinates");
9885 + return CE_Failure;
9888 + lowLeft.mi_X = xMin;
9889 + lowLeft.mi_Y = yMin;
9890 + upRight.mi_X = xMax;
9891 + upRight.mi_Y = yMax;
9893 + if (oDesCRS.IsGeographic())
9896 + lowLeft.mi_X = xMin - 360;
9898 + upRight.mi_X = xMax - 360;
9900 + if (lowLeft.mi_X >= 180.)
9901 + lowLeft.mi_X = 180.;
9902 + if (lowLeft.mi_X <= -180.)
9903 + lowLeft.mi_X = -180.;
9904 + if (upRight.mi_X >= 180.)
9905 + upRight.mi_X = 180.;
9906 + if (upRight.mi_X <= -180.)
9907 + upRight.mi_X = -180.;
9909 + if (lowLeft.mi_Y <= -90.)
9910 + lowLeft.mi_Y = -90.;
9911 + if (upRight.mi_Y >= 90.)
9912 + upRight.mi_Y = 90.;
9914 + OCTDestroyCoordinateTransformation(poCT);
9918 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/db/dbe4c7bb62ab52db2ffe9a04dcc82422b69d5bff.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/db/dbe4c7bb62ab52db2ffe9a04dcc82422b69d5bff.svn-base
9919 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/db/dbe4c7bb62ab52db2ffe9a04dcc82422b69d5bff.svn-base 1970-01-01 01:00:00.000000000 +0100
9920 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/db/dbe4c7bb62ab52db2ffe9a04dcc82422b69d5bff.svn-base 2014-03-03 15:47:37.980232932 +0100
9922 +/******************************************************************************
9923 + * $Id: NC_GOES_Dataset.h 2011-07-19 16:24:00Z $
9925 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
9926 + * for Earth Observation: Open Source Reference Implementation
9927 + * Purpose: NC_GOES_Dataset class definition
9928 + * Author: Yuanzheng Shao, yshao3@gmu.edu
9930 + ******************************************************************************
9931 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
9933 + * Permission is hereby granted, free of charge, to any person obtaining a
9934 + * copy of this software and associated documentation files (the "Software"),
9935 + * to deal in the Software without restriction, including without limitation
9936 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9937 + * and/or sell copies of the Software, and to permit persons to whom the
9938 + * Software is furnished to do so, subject to the following conditions:
9940 + * The above copyright notice and this permission notice shall be included
9941 + * in all copies or substantial portions of the Software.
9943 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9944 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9945 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
9946 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9947 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9948 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9949 + * DEALINGS IN THE SOFTWARE.
9950 + ****************************************************************************/
9952 +#ifndef NC_GOES_DATASET_H_
9953 +#define NC_GOES_DATASET_H_
9956 +#include "AbstractDataset.h"
9957 +#include "wcsUtil.h"
9959 +using namespace std;
9961 +/************************************************************************/
9962 +/* ==================================================================== */
9963 +/* NC_GOES_Dataset */
9964 +/* ==================================================================== */
9965 +/************************************************************************/
9967 +//! NC_GOES_Dataset is a subclass of AbstractDataset, used to process NOAA GOES data.
9970 + * \class NC_GOES_Dataset "NC_GOES_Dataset.h"
9972 + * GOES satellites provide the kind of continuous monitoring necessary for
9973 + * intensive data analysis. They circle the Earth in a geosynchronous orbit,
9974 + * which means they orbit the equatorial plane of the Earth at a speed
9975 + * matching the Earth's rotation. This allows them to hover continuously
9976 + * over one position on the surface. The geosynchronous plane is about
9977 + * 35,800 km (22,300 miles) above the Earth, high enough to allow the
9978 + * satellites a full-disc view of the Earth. Because they stay above a
9979 + * fixed spot on the surface, they provide a constant vigil for the atmospheric
9980 + * "triggers" for severe weather conditions such as tornadoes, flash floods,
9981 + * hail storms, and hurricanes. When these conditions develop the GOES
9982 + * satellites are able to monitor storm development and track their movements.
9984 + * GOES satellite imagery is also used to estimate rainfall during
9985 + * the thunderstorms and hurricanes for flash flood warnings, as well
9986 + * as estimates snowfall accumulations and overall extent of snow cover.
9987 + * Such data help meteorologists issue winter storm warnings and spring
9988 + * snow melt advisories. Satellite sensors also detect ice fields and map
9989 + * the movements of sea and lake ice.
9991 + * For more inforamtion about NOAA GOES data, please access
9992 + * <a href=http://www.oso.noaa.gov/GOES/>http://www.oso.noaa.gov/GOES/</a>
9994 + * NC_GOES_Dataset is a subclass of AbstractDataset, which is used to
9995 + * process GOES Imager and Sounder products.
9998 +class NC_GOES_Dataset : public AbstractDataset
10001 + string m_ncLatDataSetName;
10002 + string m_ncLonDataSetName;
10003 + string m_ncCoverageIDName;
10004 + int mi_RectifiedImageXSize;
10005 + int mi_RectifiedImageYSize;
10006 + int mi_GoesSrcImageXSize;
10007 + int mi_GoesSrcImageYSize;
10009 + double mb_LatLonBBox[4];
10010 + double mdSrcGeoMinX;
10011 + double mdSrcGeoMinY;
10012 + double mdSrcGeoMaxX;
10013 + double mdSrcGeoMaxY;
10015 + vector<GDAL_GCP> m_gdalGCPs;
10018 + CPLErr SetGCPGeoRef4VRTDataset(GDALDataset* );
10019 + CPLErr SetGeoBBoxAndGCPs(GDALDataset* hSrcDS);
10020 + CPLErr RectifyGOESDataSet();
10021 + CPLErr setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue);
10023 + int isValidLatitude(const double &lat)
10025 + return (lat >= -90 && lat <= 90);
10027 + int isValidLongitude(const double &lon)
10029 + return (lon >= -180 && lon <= 180);
10032 + virtual CPLErr SetGeoTransform();
10033 + virtual CPLErr SetMetaDataList(GDALDataset* hSrcDS);
10034 + virtual CPLErr SetNativeCRS();
10035 + virtual CPLErr SetGDALDataset(const int isSimple=0);
10036 + virtual CPLErr InitialDataset(const int isSimple=0);
10037 + virtual CPLErr GetGeoMinMax(double geoMinMax[]);
10040 + NC_GOES_Dataset();
10041 + NC_GOES_Dataset(const string& id, vector<int> &rBandList);
10042 + virtual ~NC_GOES_Dataset();
10045 +#endif /* NC_GOES_DATASET_H_ */
10046 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/ed/ed878e0243e84e5e05dc18b0ec24d13ce9146358.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/ed/ed878e0243e84e5e05dc18b0ec24d13ce9146358.svn-base
10047 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/ed/ed878e0243e84e5e05dc18b0ec24d13ce9146358.svn-base 1970-01-01 01:00:00.000000000 +0100
10048 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/ed/ed878e0243e84e5e05dc18b0ec24d13ce9146358.svn-base 2014-03-03 15:47:37.806899605 +0100
10051 +// -*- mode: c++; c-basic-offset:4 -*-
10053 +// This file is part of libdap, A C++ implementation of the OPeNDAP Data
10054 +// Access Protocol.
10056 +// Copyright (c) 2012 OPeNDAP, Inc.
10057 +// Author: James Gallagher <jgallagher@opendap.org>
10059 +// This library is free software; you can redistribute it and/or
10060 +// modify it under the terms of the GNU Lesser General Public
10061 +// License as published by the Free Software Foundation; either
10062 +// version 2.1 of the License, or (at your option) any later version.
10064 +// This library is distributed in the hope that it will be useful,
10065 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
10066 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10067 +// Lesser General Public License for more details.
10069 +// You should have received a copy of the GNU Lesser General Public
10070 +// License along with this library; if not, write to the Free Software
10071 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10073 +// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
10075 +#include <cstdlib>
10077 +#define DODS_DEBUG
10079 +#include "DAP_Dataset.h"
10081 +#include "Array.h"
10083 +#include "Float64.h"
10085 +#include "ce_functions.h"
10087 +#include "debug.h"
10089 +using namespace libdap;
10090 +using namespace std;
10093 +#define GOES_TIME_DEBUG FALSE
10096 +namespace libdap {
10098 +DAP_Dataset::DAP_Dataset()
10102 +/************************************************************************/
10103 +/* ~DAP_Dataset() */
10104 +/************************************************************************/
10107 + * \brief Destroy an open DAP_Dataset object.
10109 + * This is the accepted method of closing a DAP_Dataset dataset and
10110 + * deallocating all resources associated with it.
10113 +DAP_Dataset::~DAP_Dataset()
10117 +/************************************************************************/
10118 +/* DAP_Dataset() */
10119 +/************************************************************************/
10122 + * \brief Create an DAP_Dataset object.
10124 + * This is the accepted method of creating a DAP_Dataset object and
10125 + * allocating all resources associated with it.
10127 + * @param id The coverage identifier.
10129 + * @param rBandList The field list selected for this coverage. For TRMM
10130 + * daily data, the user could specify multiple days range in request.
10131 + * Each day is seemed as one field.
10133 + * @return A DAP_Dataset object.
10136 +DAP_Dataset::DAP_Dataset(const string& id, vector<int> &rBandList) :
10137 + AbstractDataset(id, rBandList)
10139 + md_MissingValue = 0;
10140 + mb_GeoTransformSet = FALSE;
10144 + * @brief Initialize a DAP Dataset using Array objects already read.
10149 +DAP_Dataset::DAP_Dataset(Array *src, Array *lat, Array *lon) :
10150 + AbstractDataset(), m_src(src), m_lat(lat), m_lon(lon)
10153 + // TODO Remove these?
10154 + DBG(cerr << "Registering GDAL drivers" << endl);
10155 + GDALAllRegister();
10156 + OGRRegisterAll();
10159 + CPLSetErrorHandler(CPLQuietErrorHandler);
10161 + // Read this from the 'missing_value' or '_FillValue' attributes
10162 + string missing_value = m_src->get_attr_table().get_attr("missing_value");
10163 + if (missing_value.empty())
10164 + missing_value = m_src->get_attr_table().get_attr("_FillValue");
10166 + if (!missing_value.empty())
10167 + md_MissingValue = atof(missing_value.c_str());
10169 + md_MissingValue = 0;
10171 + mb_GeoTransformSet = FALSE;
10174 +/************************************************************************/
10175 +/* InitialDataset() */
10176 +/************************************************************************/
10179 + * \brief Initialize the GOES dataset with NetCDF format.
10181 + * This method is the implementation for initializing a GOES dataset with NetCDF format.
10182 + * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
10183 + * will be called to initialize an GOES dataset.
10185 + * @note To use this, call this method and then access the GDALDataset that
10186 + * contains the reprojected array using maptr_DS.get().
10188 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
10189 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
10191 + * @return CE_None on success or CE_Failure on failure.
10194 +CPLErr DAP_Dataset::InitialDataset(const int isSimple)
10196 + DBG(cerr << "In InitialDataset" << endl);
10198 + // Might break that operation out so the remap is a separate call
10199 + if (CE_None != SetNativeCRS() || CE_None != SetGeoTransform())
10200 + throw Error("Could not set the dataset native CRS or the GeoTransform.");
10202 + DBG(cerr << "Before SetGDALDataset" << endl);
10204 + if (CE_None != SetGDALDataset(isSimple)) {
10205 + GDALClose(maptr_DS.release());
10206 + throw Error("Could not reproject the dataset.");
10212 +/************************************************************************/
10213 +/* GetDAPArray() */
10214 +/************************************************************************/
10217 + * @brief Build a DAP Array from the GDALDataset
10219 +Array *DAP_Dataset::GetDAPArray()
10221 + DBG(cerr << "In GetDAPArray" << endl);
10222 + DBG(cerr << "maptr_DS: " << maptr_DS.get() << endl);
10223 + DBG(cerr << "raster band count: " << maptr_DS->GetRasterCount() << endl);
10225 + // There should be just one band
10226 + if (maptr_DS->GetRasterCount() != 1)
10227 + throw Error("In function swath2grid(), expected a single raster band.");
10229 + // Get the x and y dimensions of the raster band
10230 + int x = maptr_DS->GetRasterXSize();
10231 + int y = maptr_DS->GetRasterYSize();
10232 + GDALRasterBand *rb = maptr_DS->GetRasterBand(1);
10234 + throw Error("In function swath2grid(), could not access the raster data.");
10236 + // Since the DAP_Dataset code works with all data values as doubles,
10237 + // Assume the raster band has GDAL type GDT_Float64, but test anyway
10238 + if (GDT_Float64 != rb->GetRasterDataType())
10239 + throw Error("In function swath2grid(), expected raster data to be of type double.");
10241 + DBG(cerr << "Destination array will have dimensions: " << x << ", " << y << endl);
10243 + Array *a = new Array(m_src->name(), new Float64(m_src->name()));
10245 + // Make the result array have two dimensions
10246 + Array::Dim_iter i = m_src->dim_begin();
10248 + a->append_dim(x, m_src->dimension_name(i));
10251 + if (i == m_src->dim_end())
10252 + throw Error("In function swath2grid(), expected source array to have two dimensions (2).");
10254 + a->append_dim(y, m_src->dimension_name(i));
10256 + // Poke in the data values
10257 + /* RasterIO ( GDALRWFlag eRWFlag,
10265 + GDALDataType eBufType,
10269 + vector<double> data(x * y);
10270 + rb->RasterIO(GF_Read, 0, 0, x, y, &data[0], x, y, GDT_Float64, 0, 0);
10272 + // NB: set_value() copies into new storage
10273 + a->set_value(data, data.size());
10275 + // Now poke in some attributes
10276 + // TODO Make these CF attributes
10277 + string projection_info = maptr_DS->GetProjectionRef();
10278 + string gcp_projection_info = maptr_DS->GetGCPProjection();
10280 + // This sets the instance variable that holds the geotransform coefs. These
10281 + // are needed by the GetDAPGrid() method.
10282 + if (CE_None != maptr_DS->GetGeoTransform (m_geo_transform_coef))
10283 + throw Error("In function swath2grid(), could not access the geo transform data.");
10285 + DBG(cerr << "projection_info: " << projection_info << endl);
10286 + DBG(cerr << "gcp_projection_info: " << gcp_projection_info << endl);
10287 + DBG(cerr << "geo_transform coefs: " << double_to_string(m_geo_transform_coef[0]) << endl);
10289 + AttrTable &attr = a->get_attr_table();
10290 + attr.append_attr("projection", "String", projection_info);
10291 + attr.append_attr("gcp_projection", "String", gcp_projection_info);
10292 + for (unsigned int i = 0; i < sizeof(m_geo_transform_coef); ++i) {
10293 + attr.append_attr("geo_transform_coefs", "String", double_to_string(m_geo_transform_coef[i]));
10299 +/************************************************************************/
10300 +/* GetDAPGrid() */
10301 +/************************************************************************/
10304 + * @brief Build a DAP Grid from the GDALDataset
10306 +Grid *DAP_Dataset::GetDAPGrid()
10308 + DBG(cerr << "In GetDAPGrid" << endl);
10310 + Array *a = GetDAPArray();
10311 + Array::Dim_iter i = a->dim_begin();
10312 + int lon_size = a->dimension_size(i);
10313 + int lat_size = a->dimension_size(++i);
10315 + Grid *g = new Grid(a->name());
10316 + g->add_var_nocopy(a, array);
10318 + // Add maps; assume lon, lat; only two dimensions
10319 + Array *lon = new Array("longitude", new Float64("longitude"));
10320 + lon->append_dim(lon_size);
10322 + vector<double> data(max(lon_size, lat_size)); // (re)use this for both lon and lat
10324 + // Compute values
10327 + // u,v --> x,y --> lon,lat
10328 + // The constants a, b, c, d are given by the 1, 2, 4, and 5 entries in the geotransform array.
10330 + if (m_geo_transform_coef[2] != 0)
10331 + throw Error("The transformed data's Geographic projection should not be rotated.");
10332 + for (int j = 0; j < lon_size; ++j) {
10333 + data[j] = m_geo_transform_coef[1] * j + m_geo_transform_coef[0];
10336 + // load (copy) values
10337 + lon->set_value(&data[0], lon_size);
10339 + g->add_var_nocopy(lon, maps);
10341 + // Now do the latitude map
10342 + Array *lat = new Array("latitude", new Float64("latitude"));
10343 + lat->append_dim(lat_size);
10345 + if (m_geo_transform_coef[4] != 0)
10346 + throw Error("The transformed data's Geographic projection should not be rotated.");
10347 + for (int k = 0; k < lat_size; ++k) {
10348 + data[k] = m_geo_transform_coef[5] * k + m_geo_transform_coef[3];
10351 + lat->set_value(&data[0], lat_size);
10352 + g->add_var_nocopy(lat, maps);
10357 +/************************************************************************/
10358 +/* SetNativeCRS() */
10359 +/************************************************************************/
10362 + * \brief Set the Native CRS for a GOES dataset.
10364 + * The method will set the CRS for a GOES dataset as an native CRS.
10366 + * Since the original GOES data adopt satellite CRS to recored its value,
10367 + * like MODIS swath data, each data point has its corresponding latitude
10368 + * and longitude value, those coordinates could be fetched in another two fields.
10370 + * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
10371 + * both the latitude and longitude are existed.
10373 + * @return CE_None on success or CE_Failure on failure.
10376 +CPLErr DAP_Dataset::SetNativeCRS()
10378 + DBG(cerr << "In SetNativeCRS" << endl);
10380 + mo_NativeCRS.SetWellKnownGeogCS("WGS84");
10385 +/************************************************************************/
10386 +/* SetGeoTransform() */
10387 +/************************************************************************/
10390 + * \brief Set the affine GeoTransform matrix for a GOES data.
10392 + * The method will set a GeoTransform matrix for a GOES data
10393 + * by parsing the coordinates values existed in longitude and latitude field.
10395 + * The CRS for the bounding box is EPSG:4326.
10397 + * @return CE_None on success or CE_Failure on failure.
10400 +CPLErr DAP_Dataset::SetGeoTransform()
10402 + DBG(cerr << "In SetGeoTransform" << endl);
10404 + // TODO Look at this; is this correct
10405 + // Assume the array is two dimensional
10406 + Array::Dim_iter i = m_src->dim_begin();
10408 + // ORIGINAL code; maybe wrong
10409 + int nXSize = m_src->dimension_size(i, true);
10410 + int nYSize = m_src->dimension_size(i + 1, true);
10412 + // Data are in row-major order, so the first dim is the Y-axis value
10413 + int nYSize = m_src->dimension_size(i, true);
10414 + int nXSize = m_src->dimension_size(i + 1, true);
10416 + mi_SrcImageXSize = nXSize;
10417 + mi_SrcImageYSize = nYSize;
10419 + SetGeoBBoxAndGCPs(nXSize, nYSize);
10421 + double resX, resY;
10422 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
10423 + resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
10425 + resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (nXSize - 1);
10427 + resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (nYSize - 1);
10429 + double res = MIN(resX, resY);
10431 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
10432 + mi_RectifiedImageXSize = (int) ((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
10434 + mi_RectifiedImageXSize = (int) ((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
10436 + mi_RectifiedImageYSize = (int) fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
10438 + DBG(cerr << "Source image size: " << nXSize << ", " << nYSize << endl);
10439 + DBG(cerr << "Rectified image size: " << mi_RectifiedImageXSize << ", " << mi_RectifiedImageYSize << endl);
10441 + md_Geotransform[0] = mdSrcGeoMinX;
10442 + md_Geotransform[1] = res;
10443 + md_Geotransform[2] = 0;
10444 + md_Geotransform[3] = mdSrcGeoMaxY;
10445 + md_Geotransform[4] = 0;
10446 + md_Geotransform[5] = -res;
10447 + mb_GeoTransformSet = TRUE;
10452 +/************************************************************************/
10453 +/* SetGeoBBoxAndGCPs() */
10454 +/************************************************************************/
10457 + * \brief Set the native geographical bounding box and GCP array for a GOES data.
10459 + * The method will set the native geographical bounding box
10460 + * by comparing the coordinates values existed in longitude and latitude field.
10462 + * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
10464 + * @return CE_None on success or CE_Failure on failure.
10467 +void DAP_Dataset::SetGeoBBoxAndGCPs(int nXSize, int nYSize)
10469 + DBG(cerr << "In SetGeoBBoxAndGCPs" << endl);
10471 + // reuse the Dim_iter for both lat and lon arrays
10472 + Array::Dim_iter i = m_lat->dim_begin();
10473 + int nLatXSize = m_lat->dimension_size(i, true);
10474 + int nLatYSize = m_lat->dimension_size(i + 1, true);
10475 + i = m_lon->dim_begin();
10476 + int nLonXSize = m_lon->dimension_size(i, true);
10477 + int nLonYSize = m_lon->dimension_size(i + 1, true);
10479 + if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
10480 + throw Error("The size of latitude/longitude and data field does not match.");
10484 + * Re-sample Standards:
10486 + * (0, 500) every other one pixel
10487 + * [500, 1000) every other two pixels
10488 + * [1000,1500) every other three pixels
10489 + * [1500,2000) every other four pixels
10495 + //setResampleStandard(poVDS, xSpace, ySpace);
10497 + // TODO understand how GMU picked this value.
10498 + // xSpace and ySpace are the stride values for sampling in
10499 + // the x and y dimensions.
10500 + const int RESAMPLE_STANDARD = 500;
10502 + xSpace = int(nXSize / RESAMPLE_STANDARD) + 2;
10503 + ySpace = int(nYSize / RESAMPLE_STANDARD) + 2;
10508 + double *dataLat = extract_double_array(m_lat);
10509 + double *dataLon = extract_double_array(m_lon);
10511 + DBG(cerr << "Past lat/lon data read" << endl);
10515 + mdSrcGeoMinX = 360;
10516 + mdSrcGeoMaxX = -360;
10517 + mdSrcGeoMinY = 90;
10518 + mdSrcGeoMaxY = -90;
10520 + // Sample every other row and column
10525 + GDAL_GCP gdalCGP;
10527 + for (int iLine = 0; iLine < nYSize - ySpace; iLine += ySpace) {
10528 + for (int iPixel = 0; iPixel < nXSize - xSpace; iPixel += xSpace) {
10529 + double x = *(dataLon + (iLine * nYSize) + iPixel);
10530 + double y = *(dataLat + (iLine * nYSize) + iPixel);
10532 + if (isValidLongitude(x) && isValidLatitude(y)) {
10534 + snprintf(pChr, 64, "%d", ++nGCPs);
10535 + GDALInitGCPs(1, &gdalCGP);
10536 + gdalCGP.pszId = strdup(pChr);
10537 + gdalCGP.pszInfo = strdup("");
10538 + gdalCGP.dfGCPLine = iLine;
10539 + gdalCGP.dfGCPPixel = iPixel;
10540 + gdalCGP.dfGCPX = x;
10541 + gdalCGP.dfGCPY = y;
10543 + DBG2(cerr << "iLine, iPixel: " << iLine << ", " << iPixel << " --> x,y: " << x << ", " << y << endl);
10545 + gdalCGP.dfGCPZ = 0;
10546 + m_gdalGCPs.push_back(gdalCGP);
10548 + mdSrcGeoMinX = MIN(mdSrcGeoMinX, gdalCGP.dfGCPX);
10549 + mdSrcGeoMaxX = MAX(mdSrcGeoMaxX, gdalCGP.dfGCPX);
10550 + mdSrcGeoMinY = MIN(mdSrcGeoMinY, gdalCGP.dfGCPY);
10551 + mdSrcGeoMaxY = MAX(mdSrcGeoMaxY, gdalCGP.dfGCPY);
10557 + delete[] dataLat;
10558 + delete[] dataLon;
10562 + delete[] dataLat;
10563 + delete[] dataLon;
10565 + DBG(cerr << "Leaving SetGeoBBoxAndGCPs" << endl);
10568 +/************************************************************************/
10569 +/* SetGDALDataset() */
10570 +/************************************************************************/
10573 + * \brief Make a 'memory' dataset with one band
10575 + * @return CE_None on success or CE_Failure on failure.
10578 +CPLErr DAP_Dataset::SetGDALDataset(const int isSimple)
10580 + DBG(cerr << "In SetGDALDataset" << endl);
10582 + // NB: mi_RectifiedImageXSize & Y are set in SetGeoTransform()
10583 + GDALDataType eBandType = GDT_Float64;
10584 + // VRT, which was used in the original sample code, is not supported in this context, so I used MEM
10585 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
10587 + throw Error("Failed to get MEM driver (" + string(CPLGetLastErrorMsg()) + ").");
10590 + GDALDataset* satDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
10591 + 1, eBandType, NULL);
10592 + if (!satDataSet) {
10593 + GDALClose(poDriver);
10594 + throw Error("Failed to create MEM dataSet (" + string(CPLGetLastErrorMsg()) + ").");
10597 + GDALRasterBand *poBand = satDataSet->GetRasterBand(1);
10598 + poBand->SetNoDataValue(md_MissingValue);
10601 + double *data = extract_double_array(m_src);
10602 + if (CE_None != poBand->RasterIO(GF_Write, 0, 0, mi_RectifiedImageXSize, mi_RectifiedImageYSize, data,
10603 + mi_SrcImageXSize, mi_SrcImageYSize, eBandType, 0, 0)) {
10604 + GDALClose((GDALDatasetH) satDataSet);
10605 + throw Error("Failed to set satellite data band to MEM DataSet (" + string(CPLGetLastErrorMsg()) + ").");
10609 + //set GCPs for this VRTDataset
10610 + if (CE_None != SetGCPGeoRef4VRTDataset(satDataSet)) {
10611 + GDALClose((GDALDatasetH) satDataSet);
10612 + throw Error("Could not georeference the virtual dataset (" + string(CPLGetLastErrorMsg()) + ").");
10615 + DBG(cerr << "satDataSet: " << satDataSet << endl);
10617 + maptr_DS.reset(satDataSet);
10622 + return RectifyGOESDataSet();
10625 +/************************************************************************/
10626 +/* SetGCPGeoRef4VRTDataset() */
10627 +/************************************************************************/
10630 + * \brief Set the GCP array for the VRT dataset.
10632 + * This method is used to set the GCP array to created VRT dataset based on GDAL
10633 + * method SetGCPs().
10635 + * @param poVDS The VRT dataset.
10637 + * @return CE_None on success or CE_Failure on failure.
10640 +CPLErr DAP_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
10642 + char* psTargetSRS;
10643 + mo_NativeCRS.exportToWkt(&psTargetSRS);
10645 +#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
10646 + if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS)) {
10647 + OGRFree(psTargetSRS);
10648 + throw Error("Failed to set GCPs.");
10652 + if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
10654 + OGRFree( psTargetSRS );
10655 + throw Error("Failed to set GCPs.");
10660 + OGRFree(psTargetSRS);
10665 +/************************************************************************/
10666 +/* SetMetaDataList() */
10667 +/************************************************************************/
10670 + * \brief Set the metadata list for this coverage.
10672 + * The method will set the metadata list for the coverage based on its
10673 + * corresponding GDALDataset object.
10675 + * @param hSrc the GDALDataset object corresponding to coverage.
10677 + * @return CE_None on success or CE_Failure on failure.
10680 +CPLErr DAP_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
10684 + mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
10685 + mv_MetaDataList.push_back("unit=GVAR");
10686 + mv_MetaDataList.push_back("FillValue=0");
10687 + ms_FieldQuantityDef = "GVAR";
10688 + ms_AllowRanges = "0 65535";
10689 + ms_CoveragePlatform = "GOES-11";
10690 + ms_CoverageInstrument = "GOES-11";
10691 + ms_CoverageSensor = "Imager";
10697 +/************************************************************************/
10698 +/* GetGeoMinMax() */
10699 +/************************************************************************/
10702 + * \brief Get the min/max coordinates of laitutude and longitude.
10704 + * The method will fetch the min/max coordinates of laitutude and longitude.
10706 + * @param geoMinMax an existing four double buffer into which the
10707 + * native geographical bounding box values will be placed.
10709 + * @return CE_None on success or CE_Failure on failure.
10712 +CPLErr DAP_Dataset::GetGeoMinMax(double geoMinMax[])
10714 + if (!mb_GeoTransformSet)
10715 + return CE_Failure;
10717 + geoMinMax[0] = mdSrcGeoMinX;
10718 + geoMinMax[2] = mdSrcGeoMinY;
10719 + geoMinMax[1] = mdSrcGeoMaxX;
10720 + geoMinMax[3] = mdSrcGeoMaxY;
10725 +/************************************************************************/
10726 +/* RectifyGOESDataSet() */
10727 +/************************************************************************/
10730 + * \brief Convert the GOES dataset from satellite CRS project to grid CRS.
10732 + * The method will convert the GOES dataset from satellite CRS project to
10733 + * grid CRS based on GDAL API GDALReprojectImage;
10735 + * @return CE_None on success or CE_Failure on failure.
10738 +CPLErr DAP_Dataset::RectifyGOESDataSet()
10740 + DBG(cerr << "In RectifyGOESDataSet" << endl);
10743 + mo_NativeCRS.exportToWkt(&pszDstWKT);
10745 + GDALDriverH poDriver = GDALGetDriverByName("VRT"); // MEM
10746 + GDALDataset* rectDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize, mi_RectifiedImageYSize,
10747 + maptr_DS->GetRasterCount(), maptr_DS->GetRasterBand(1)->GetRasterDataType(), NULL);
10748 + if (NULL == rectDataSet) {
10749 + GDALClose(poDriver);
10750 + OGRFree(pszDstWKT);
10751 + throw Error("Failed to create \"MEM\" dataSet.");
10754 + rectDataSet->SetProjection(pszDstWKT);
10755 + rectDataSet->SetGeoTransform(md_Geotransform);
10757 + DBG(cerr << "rectDataSet: " << rectDataSet << endl);
10758 + DBG(cerr << "satDataSet: " << maptr_DS.get() << endl);
10760 + // FIXME Magic value of 0.125
10761 + if (CE_None != GDALReprojectImage(maptr_DS.get(), NULL, rectDataSet, pszDstWKT,
10762 + GRA_Lanczos /*GRA_NearestNeighbour*/, 0, 0.0/*0.125*/, NULL, NULL, NULL)) {
10763 + GDALClose(rectDataSet);
10764 + GDALClose(poDriver);
10765 + OGRFree(pszDstWKT);
10766 + throw Error("Failed to re-project satellite data from GCP CRS to geographical CRS.");
10769 + OGRFree(pszDstWKT);
10770 + GDALClose(maptr_DS.release());
10772 + maptr_DS.reset(rectDataSet);
10774 + DBG(cerr << "Leaving RectifyGOESDataSet" << endl);
10779 +} // namespace libdap
10780 diff -Nur bes-3.12.0/functions.orig/swath2grid/.svn/pristine/ee/eed03539b992d9d129c49278cfb7203c371bfd39.svn-base bes-3.12.0/functions/swath2grid/.svn/pristine/ee/eed03539b992d9d129c49278cfb7203c371bfd39.svn-base
10781 --- bes-3.12.0/functions.orig/swath2grid/.svn/pristine/ee/eed03539b992d9d129c49278cfb7203c371bfd39.svn-base 1970-01-01 01:00:00.000000000 +0100
10782 +++ bes-3.12.0/functions/swath2grid/.svn/pristine/ee/eed03539b992d9d129c49278cfb7203c371bfd39.svn-base 2014-03-03 15:47:37.976899599 +0100
10784 +/******************************************************************************
10785 + * $Id: TRMM_Dataset.cpp 2011-07-19 16:24:00Z $
10787 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
10788 + * for Earth Observation: Open Source Reference Implementation
10789 + * Purpose: NC_GOES_Dataset implementation for NOAA GOES data
10790 + * Author: Yuanzheng Shao, yshao3@gmu.edu
10792 + ******************************************************************************
10793 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
10795 + * Permission is hereby granted, free of charge, to any person obtaining a
10796 + * copy of this software and associated documentation files (the "Software"),
10797 + * to deal in the Software without restriction, including without limitation
10798 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10799 + * and/or sell copies of the Software, and to permit persons to whom the
10800 + * Software is furnished to do so, subject to the following conditions:
10802 + * The above copyright notice and this permission notice shall be included
10803 + * in all copies or substantial portions of the Software.
10805 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10806 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10807 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
10808 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10809 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
10810 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
10811 + * DEALINGS IN THE SOFTWARE.
10812 + ****************************************************************************/
10814 +#include "NC_GOES_Dataset.h"
10816 +using namespace std;
10818 +#define GOES_TIME_DEBUG FALSE
10820 +NC_GOES_Dataset::NC_GOES_Dataset()
10824 +/************************************************************************/
10825 +/* ~NC_GOES_Dataset() */
10826 +/************************************************************************/
10829 + * \brief Destroy an open NC_GOES_Dataset object.
10831 + * This is the accepted method of closing a NC_GOES_Dataset dataset and
10832 + * deallocating all resources associated with it.
10835 +NC_GOES_Dataset::~NC_GOES_Dataset()
10839 +/************************************************************************/
10840 +/* NC_GOES_Dataset() */
10841 +/************************************************************************/
10844 + * \brief Create an NC_GOES_Dataset object.
10846 + * This is the accepted method of creating a NC_GOES_Dataset object and
10847 + * allocating all resources associated with it.
10849 + * @param id The coverage identifier.
10851 + * @param rBandList The field list selected for this coverage. For TRMM
10852 + * daily data, the user could specify multiple days range in request.
10853 + * Each day is seemed as one field.
10855 + * @return A NC_GOES_Dataset object.
10858 +NC_GOES_Dataset::NC_GOES_Dataset(const string& id, vector<int> &rBandList) :
10859 + AbstractDataset(id, rBandList)
10861 + md_MissingValue = 0;
10862 + mb_GeoTransformSet = FALSE;
10865 +/************************************************************************/
10866 +/* InitialDataset() */
10867 +/************************************************************************/
10870 + * \brief Initialize the GOES dataset with NetCDF format.
10872 + * This method is the implementation for initializing a GOES dataset with NetCDF format.
10873 + * Within this method, SetNativeCRS(), SetGeoTransform() and SetGDALDataset()
10874 + * will be called to initialize an GOES dataset.
10876 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
10877 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
10879 + * @return CE_None on success or CE_Failure on failure.
10882 +CPLErr NC_GOES_Dataset::InitialDataset(const int isSimple)
10884 + vector<string> strSet;
10885 + unsigned int n = CsvburstCpp(ms_CoverageID, strSet, ':');
10888 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
10889 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Incorrect coverage ID.");
10890 + return CE_Failure;
10893 + ms_DataTypeName = strSet[0] + ":" + strSet[1];
10894 + ms_SrcFilename = StrTrims(strSet[2], " \'\"");
10895 + ms_DatasetName = strSet[3];
10897 + m_ncLatDataSetName = "NETCDF:" + ms_SrcFilename + ":latitude";
10898 + m_ncLonDataSetName = "NETCDF:" + ms_SrcFilename + ":longitude";
10899 + m_ncCoverageIDName = strSet[1] + ":" + strSet[2] + ":" + strSet[3];
10901 + GDALDataset* pSrc = (GDALDataset*) GDALOpenShared(m_ncCoverageIDName.c_str(), GA_ReadOnly);
10902 + if (pSrc == NULL)
10904 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
10905 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open file \"%s\".", ms_SrcFilename.c_str());
10906 + return CE_Failure;
10909 + ms_NativeFormat = GDALGetDriverShortName(pSrc->GetDriver());
10912 + SetMetaDataList(pSrc);
10915 + unsigned int nBandCount = pSrc->GetRasterCount();
10916 + if (nBandCount < 1)
10919 + SetWCS_ErrorLocator("NC_GOES_Dataset::InitialDataset()");
10920 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The GOES file does not contain any raster band.");
10921 + return CE_Failure;
10924 + maptr_DS.reset(pSrc);
10926 + //set moNativeCRS and mGeoTransform
10927 + if (CE_None != SetNativeCRS() ||
10928 + CE_None != SetGeoTransform() ||
10929 + CE_None != SetGDALDataset(isSimple))
10931 + GDALClose(maptr_DS.release());
10932 + return CE_Failure;
10938 +/************************************************************************/
10939 +/* SetNativeCRS() */
10940 +/************************************************************************/
10943 + * \brief Set the Native CRS for a GOES dataset.
10945 + * The method will set the CRS for a GOES dataset as an native CRS.
10947 + * Since the original GOES data adopt satellite CRS to recored its value,
10948 + * like MODIS swath data, each data point has its corresponding latitude
10949 + * and longitude value, those coordinates could be fetched in another two fields.
10951 + * The native CRS for GOES Imager and Sounder data is assigned to EPSG:4326 if
10952 + * both the latitude and longitude are existed.
10954 + * @return CE_None on success or CE_Failure on failure.
10957 +CPLErr NC_GOES_Dataset::SetNativeCRS()
10959 + if (CE_None == AbstractDataset::SetNativeCRS())
10962 + GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
10963 + GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
10965 + if(hLatDS == NULL) {
10966 + m_ncLatDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lat";
10967 + hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
10970 + if(hLonDS == NULL) {
10971 + m_ncLonDataSetName = "NETCDF:\"" + ms_SrcFilename + "\":lon";
10972 + hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
10975 + if (hLatDS == NULL || hLonDS == NULL)
10977 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetNativeCRS()");
10978 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open latitude/longitude sub-dataset.");
10979 + return CE_Failure;
10982 + mo_NativeCRS.SetWellKnownGeogCS("WGS84");
10984 + GDALClose(hLatDS);
10985 + GDALClose(hLonDS);
10990 +/************************************************************************/
10991 +/* SetGeoTransform() */
10992 +/************************************************************************/
10995 + * \brief Set the affine GeoTransform matrix for a GOES data.
10997 + * The method will set a GeoTransform matrix for a GOES data
10998 + * by parsing the coordinates values existed in longitude and latitude field.
11000 + * The CRS for the bounding box is EPSG:4326.
11002 + * @return CE_None on success or CE_Failure on failure.
11005 +CPLErr NC_GOES_Dataset::SetGeoTransform()
11007 + if (CE_None == AbstractDataset::SetGeoTransform())
11010 + if (CE_None != SetGeoBBoxAndGCPs(maptr_DS.get()))
11011 + return CE_Failure;
11013 + double resX, resY;
11014 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
11015 + resX = (360 + mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
11017 + resX = (mdSrcGeoMaxX - mdSrcGeoMinX) / (maptr_DS->GetRasterXSize() - 1);
11019 + resY = (mdSrcGeoMaxY - mdSrcGeoMinY) / (maptr_DS->GetRasterYSize() - 1);
11021 + double res = MIN(resX,resY);
11023 + if (mdSrcGeoMinX > mdSrcGeoMaxX && mdSrcGeoMinX > 0 && mdSrcGeoMaxX < 0)
11024 + mi_RectifiedImageXSize = (int)((360 + mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
11026 + mi_RectifiedImageXSize = (int)((mdSrcGeoMaxX - mdSrcGeoMinX) / res) + 1;
11028 + mi_RectifiedImageYSize = (int)fabs((mdSrcGeoMaxY - mdSrcGeoMinY) / res) + 1;
11030 + md_Geotransform[0] = mdSrcGeoMinX;
11031 + md_Geotransform[1] = res;
11032 + md_Geotransform[2] = 0;
11033 + md_Geotransform[3] = mdSrcGeoMaxY;
11034 + md_Geotransform[4] = 0;
11035 + md_Geotransform[5] = -res;
11036 + mb_GeoTransformSet = TRUE;
11041 +CPLErr NC_GOES_Dataset::setResampleStandard(GDALDataset* hSrcDS, int& xRSValue, int& yRSValue)
11043 + static int RESAMPLE_STANDARD = 500;
11044 + int nXSize = hSrcDS->GetRasterXSize();
11045 + int nYSize = hSrcDS->GetRasterYSize();
11047 + xRSValue = int(nXSize / RESAMPLE_STANDARD) + 2;
11048 + yRSValue = int(nYSize / RESAMPLE_STANDARD) + 2;
11053 +/************************************************************************/
11054 +/* SetGeoBBoxAndGCPs() */
11055 +/************************************************************************/
11058 + * \brief Set the native geographical bounding box and GCP array for a GOES data.
11060 + * The method will set the native geographical bounding box
11061 + * by comparing the coordinates values existed in longitude and latitude field.
11063 + * @param poVDS The GDAL dataset returned by calling GDALOpen() method.
11065 + * @return CE_None on success or CE_Failure on failure.
11068 +CPLErr NC_GOES_Dataset::SetGeoBBoxAndGCPs(GDALDataset* poVDS)
11070 + GDALDataset* hLatDS = (GDALDataset*) GDALOpen(m_ncLatDataSetName.c_str(), GA_ReadOnly);
11071 + GDALDataset* hLonDS = (GDALDataset*) GDALOpen(m_ncLonDataSetName.c_str(), GA_ReadOnly);
11073 + int nXSize = poVDS->GetRasterXSize();
11074 + int nYSize = poVDS->GetRasterYSize();
11076 + mi_GoesSrcImageXSize = nXSize;
11077 + mi_GoesSrcImageYSize = nYSize;
11079 + int nLatXSize = hLatDS->GetRasterXSize();
11080 + int nLatYSize = hLatDS->GetRasterYSize();
11081 + int nLonXSize = hLonDS->GetRasterXSize();
11082 + int nLonYSize = hLonDS->GetRasterYSize();
11084 + if (nXSize != nLatXSize || nLatXSize != nLonXSize || nYSize != nLatYSize || nLatYSize != nLonYSize)
11086 + GDALClose(hLatDS);
11087 + GDALClose(hLonDS);
11089 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGeoBBoxAndGCPs()");
11090 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "The size of latitude/longitude and data field does not match.");
11092 + return CE_Failure;
11096 + * Re-sample Standards:
11098 + * (0, 500) every other one pixel
11099 + * [500, 1000) every other two pixels
11100 + * [1000,1500) every other three pixels
11101 + * [1500,2000) every other four pixels
11107 + setResampleStandard(poVDS, xSpace, ySpace);
11110 + GDAL_GCP gdalCGP;
11112 + GDALRasterBand *poBandLat = hLatDS->GetRasterBand(1);
11113 + GDALRasterBand *poBandLon = hLonDS->GetRasterBand(1);
11114 + GDALDataType eDT = poBandLat->GetRasterDataType();
11115 + void *dataLat = NULL;
11116 + void *dataLon = NULL;
11118 + mdSrcGeoMinX = 360;
11119 + mdSrcGeoMaxX = -360;
11120 + mdSrcGeoMinY = 90;
11121 + mdSrcGeoMaxY = -90;
11125 + case GDT_Float32: //For GOES Imager and Sounder data
11127 + dataLat = (float *) CPLMalloc(nXSize * sizeof(float));
11128 + dataLon = (float *) CPLMalloc(nXSize * sizeof(float));
11130 + for (int iLine = 0; iLine < nYSize; iLine += ySpace)
11132 + if (iLine >= nYSize)
11133 + iLine = nYSize - 1;
11135 + poBandLat->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLat, nXSize, 1, GDT_Float32, 0, 0);
11136 + poBandLon->RasterIO(GF_Read, 0, iLine, nXSize, 1, dataLon, nXSize, 1, GDT_Float32, 0, 0);
11138 + for (int iPixel = 0; iPixel < nXSize; iPixel += xSpace)
11140 + if(iPixel >= nXSize)
11141 + iPixel = nXSize - 1;
11142 + double x = *((float *) dataLon + iPixel);
11143 + double y = *((float *) dataLat + iPixel);
11144 + if (isValidLongitude(x) && isValidLatitude(y))
11147 + sprintf(pChr, "%d", ++nGCPs);
11148 + GDALInitGCPs(1, &gdalCGP);
11149 + gdalCGP.pszId = strdup(pChr);
11150 + gdalCGP.pszInfo = strdup("");
11151 + gdalCGP.dfGCPLine = iLine;
11152 + gdalCGP.dfGCPPixel = iPixel;
11153 + gdalCGP.dfGCPX = x;
11154 + gdalCGP.dfGCPY = y;
11155 + gdalCGP.dfGCPZ = 0;
11156 + m_gdalGCPs.push_back(gdalCGP);
11157 + mdSrcGeoMinX = MIN(mdSrcGeoMinX,gdalCGP.dfGCPX );
11158 + mdSrcGeoMaxX = MAX(mdSrcGeoMaxX,gdalCGP.dfGCPX);
11159 + mdSrcGeoMinY = MIN(mdSrcGeoMinY,gdalCGP.dfGCPY);
11160 + mdSrcGeoMaxY = MAX(mdSrcGeoMaxY,gdalCGP.dfGCPY);
11165 + VSIFree((float *) dataLat);
11166 + VSIFree((float *) dataLon);
11174 + GDALClose(hLatDS);
11175 + GDALClose(hLonDS);
11181 +/************************************************************************/
11182 +/* SetGDALDataset() */
11183 +/************************************************************************/
11186 + * \brief Set the GDALDataset object to GOES Imager and Sounder dataset.
11188 + * This method is used to set the GOES Imager and Sounder dataset based on GDAL
11189 + * class VRTDataset.
11191 + * @param isSimple the WCS request type. When user executing a DescribeCoverage
11192 + * request, isSimple is set to 1, and for GetCoverage, is set to 0.
11194 + * @return CE_None on success or CE_Failure on failure.
11197 +CPLErr NC_GOES_Dataset::SetGDALDataset(const int isSimple)
11199 + for(int i = 1; i <= maptr_DS->GetRasterCount(); ++i)
11200 + mv_BandList.push_back(i);
11202 + VRTDataset *poVDS = (VRTDataset *)VRTCreate(mi_RectifiedImageXSize, mi_RectifiedImageYSize);
11203 + if (poVDS == NULL)
11205 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGDALDataset()");
11206 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to create VRT DataSet.");
11207 + return CE_Failure;
11210 + VRTSourcedRasterBand *poVRTBand = NULL;
11211 + GDALRasterBand *poSrcBand = NULL;
11212 + GDALDataType eBandType;
11213 + for (unsigned int i = 0; i < mv_BandList.size(); i++)
11215 + poSrcBand = maptr_DS->GetRasterBand(mv_BandList[i]);
11216 + eBandType = poSrcBand->GetRasterDataType();
11217 + poVDS->AddBand(eBandType, NULL);
11218 + poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand(i + 1);
11219 + poVRTBand->SetNoDataValue(md_MissingValue);
11221 + if (CE_None != poVRTBand->AddSimpleSource(poSrcBand, 0, 0,
11222 + mi_RectifiedImageXSize, mi_RectifiedImageYSize, 0, 0,
11223 + mi_RectifiedImageXSize, mi_RectifiedImageYSize, NULL, md_MissingValue))
11225 + GDALClose((GDALDatasetH) poVDS);
11226 + SetWCS_ErrorLocator("NC_GOES_Dataset::setGDALDataset()");
11227 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Add Simple Source into VRT DataSet.");
11228 + return CE_Failure;
11232 + //set GCPs for this VRTDataset
11233 + if (CE_None != SetGCPGeoRef4VRTDataset(poVDS))
11235 + GDALClose((GDALDatasetH) poVDS);
11236 + return CE_Failure;
11239 + GDALClose(maptr_DS.release());
11240 + maptr_DS.reset(poVDS);
11245 + return RectifyGOESDataSet();
11248 +/************************************************************************/
11249 +/* SetGCPGeoRef4VRTDataset() */
11250 +/************************************************************************/
11253 + * \brief Set the GCP array for the VRT dataset.
11255 + * This method is used to set the GCP array to created VRT dataset based on GDAL
11256 + * method SetGCPs().
11258 + * @param poVDS The VRT dataset.
11260 + * @return CE_None on success or CE_Failure on failure.
11263 +CPLErr NC_GOES_Dataset::SetGCPGeoRef4VRTDataset(GDALDataset* poVDS)
11265 + char* psTargetSRS;
11266 + mo_NativeCRS.exportToWkt(&psTargetSRS);
11268 +#if (__GNUC__ >=4 && __GNUC_MINOR__ > 1)
11269 + if (CE_None != poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*) (m_gdalGCPs.data()), psTargetSRS))
11271 + OGRFree(psTargetSRS);
11272 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
11273 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to set GCPs.");
11275 + return CE_Failure;
11279 + if(CE_None!=poVDS->SetGCPs(m_gdalGCPs.size(), (GDAL_GCP*)&m_gdalGCPs[0], psTargetSRS))
11281 + OGRFree( psTargetSRS );
11282 + SetWCS_ErrorLocator("NC_GOES_Dataset::SetGCPGeoRef4VRTDataset()");
11283 + WCS_Error(CE_Failure,OGC_WCS_NoApplicableCode,"Failed to set GCPs.");
11285 + return CE_Failure;
11290 + OGRFree(psTargetSRS);
11295 +/************************************************************************/
11296 +/* SetMetaDataList() */
11297 +/************************************************************************/
11300 + * \brief Set the metadata list for this coverage.
11302 + * The method will set the metadata list for the coverage based on its
11303 + * corresponding GDALDataset object.
11305 + * @param hSrc the GDALDataset object corresponding to coverage.
11307 + * @return CE_None on success or CE_Failure on failure.
11310 +CPLErr NC_GOES_Dataset::SetMetaDataList(GDALDataset* hSrcDS)
11312 + mv_MetaDataList.push_back("Product_Description=The data was created by GMU WCS from NOAA GOES satellite data.");
11313 + mv_MetaDataList.push_back("unit=GVAR");
11314 + mv_MetaDataList.push_back("FillValue=0");
11315 + ms_FieldQuantityDef = "GVAR";
11316 + ms_AllowRanges = "0 65535";
11317 + ms_CoveragePlatform = "GOES-11";
11318 + ms_CoverageInstrument = "GOES-11";
11319 + ms_CoverageSensor = "Imager";
11324 +/************************************************************************/
11325 +/* GetGeoMinMax() */
11326 +/************************************************************************/
11329 + * \brief Get the min/max coordinates of laitutude and longitude.
11331 + * The method will fetch the min/max coordinates of laitutude and longitude.
11333 + * @param geoMinMax an existing four double buffer into which the
11334 + * native geographical bounding box values will be placed.
11336 + * @return CE_None on success or CE_Failure on failure.
11339 +CPLErr NC_GOES_Dataset::GetGeoMinMax(double geoMinMax[])
11341 + if (!mb_GeoTransformSet)
11342 + return CE_Failure;
11344 + geoMinMax[0] = mdSrcGeoMinX;
11345 + geoMinMax[2] = mdSrcGeoMinY;
11346 + geoMinMax[1] = mdSrcGeoMaxX;
11347 + geoMinMax[3] = mdSrcGeoMaxY;
11352 +/************************************************************************/
11353 +/* GetGeoMinMax() */
11354 +/************************************************************************/
11357 + * \brief Convert the GOES dataset from satellite CRS project to grid CRS.
11359 + * The method will convert the GOES dataset from satellite CRS project to
11360 + * grid CRS based on GDAL API GDALReprojectImage;
11362 + * @return CE_None on success or CE_Failure on failure.
11365 +CPLErr NC_GOES_Dataset::RectifyGOESDataSet()
11368 + mo_NativeCRS.exportToWkt(&pszDstWKT);
11370 + GDALDriverH poDriver = GDALGetDriverByName("MEM");
11371 + GDALDataset* rectDataSet = (GDALDataset*) GDALCreate(poDriver, "", mi_RectifiedImageXSize,
11372 + mi_RectifiedImageYSize, maptr_DS->GetRasterCount(),
11373 + maptr_DS->GetRasterBand(1)->GetRasterDataType(), NULL);
11374 + if (NULL == rectDataSet)
11376 + GDALClose(poDriver);
11377 + OGRFree(pszDstWKT);
11378 + SetWCS_ErrorLocator("AbstractDataset::rectifyDataSet()");
11379 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode,
11380 + "Failed to create \"MEM\" dataSet.");
11382 + return CE_Failure;
11385 + rectDataSet->SetProjection(pszDstWKT);
11386 + rectDataSet->SetGeoTransform(md_Geotransform);
11388 + if (CE_None != GDALReprojectImage(maptr_DS.get(), NULL, rectDataSet,
11389 + pszDstWKT, GRA_NearestNeighbour, 0, 0.125, NULL, NULL, NULL))
11391 + GDALClose(rectDataSet);
11392 + GDALClose(poDriver);
11393 + OGRFree(pszDstWKT);
11394 + SetWCS_ErrorLocator("AbstractDataset::RectifyDataSet()");
11395 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode,
11396 + "Failed to re-project GOES data from satellite GCP CRS to geographical CRS.");
11398 + return CE_Failure;
11401 + OGRFree(pszDstWKT);
11402 + GDALClose(maptr_DS.release());
11404 + maptr_DS.reset(rectDataSet);
11409 Binarne pliki bes-3.12.0/functions.orig/swath2grid/.svn/wc.db i bes-3.12.0/functions/swath2grid/.svn/wc.db ró¿ni± siê
11410 diff -Nur bes-3.12.0/functions.orig/swath2grid/three_array_1.das bes-3.12.0/functions/swath2grid/three_array_1.das
11411 --- bes-3.12.0/functions.orig/swath2grid/three_array_1.das 1970-01-01 01:00:00.000000000 +0100
11412 +++ bes-3.12.0/functions/swath2grid/three_array_1.das 2014-03-03 15:47:38.046899595 +0100
11414 +# three_array_1.das
11416 +# Created on: Dec 12, 2012
11424 diff -Nur bes-3.12.0/functions.orig/swath2grid/three_array_1.dds bes-3.12.0/functions/swath2grid/three_array_1.dds
11425 --- bes-3.12.0/functions.orig/swath2grid/three_array_1.dds 1970-01-01 01:00:00.000000000 +0100
11426 +++ bes-3.12.0/functions/swath2grid/three_array_1.dds 2014-03-03 15:47:38.050232928 +0100
11428 +# three_array_1.dds
11430 +# Created on: Dec 12, 2012
11434 + Float64 t[10][10];
11435 + Float64 lon[10][10];
11436 + Float64 lat[10][10];
11438 diff -Nur bes-3.12.0/functions.orig/swath2grid/wcs_error.cpp bes-3.12.0/functions/swath2grid/wcs_error.cpp
11439 --- bes-3.12.0/functions.orig/swath2grid/wcs_error.cpp 1970-01-01 01:00:00.000000000 +0100
11440 +++ bes-3.12.0/functions/swath2grid/wcs_error.cpp 2014-03-03 15:47:38.046899595 +0100
11442 +/******************************************************************************
11443 + * $Id: wcs_error.cpp 2011-07-19 16:24:00Z $
11445 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
11446 + * for Earth Observation: Open Source Reference Implementation
11447 + * Purpose: WCS exception and error handler implementation, used to set
11448 + * the exception code and locator of WCS
11449 + * Author: Yuanzheng Shao, yshao3@gmu.edu
11451 + ******************************************************************************
11452 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
11454 + * Permission is hereby granted, free of charge, to any person obtaining a
11455 + * copy of this software and associated documentation files (the "Software"),
11456 + * to deal in the Software without restriction, including without limitation
11457 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11458 + * and/or sell copies of the Software, and to permit persons to whom the
11459 + * Software is furnished to do so, subject to the following conditions:
11461 + * The above copyright notice and this permission notice shall be included
11462 + * in all copies or substantial portions of the Software.
11464 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11465 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11466 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
11467 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11468 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
11469 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11470 + * DEALINGS IN THE SOFTWARE.
11471 + ****************************************************************************/
11473 +#include "wcs_error.h"
11475 +static string WCS_ERROR_STRING="";
11476 +static string ERROR_LOCATOR="";
11477 +static string ExcptCodeText[] =
11479 + "OperationNotSupported",
11480 + "MissingParameterValue",
11481 + "InvalidParameterValue",
11482 + "VersionNegotiationFailed",
11483 + "InvalidUpdateSequence",
11484 + "OptionNotSupported",
11485 + "NoApplicableCode",
11486 + "NoSuchCoverage",
11487 + "InvalidAxisLabel",
11488 + "InvalidSubsetting"
11491 +static int WCS_IsSoapMessage_Transform = 0;
11493 +string CPL_STDCALL GetWCS_ErrorMsg()
11495 + return WCS_ERROR_STRING;
11498 +void CPL_STDCALL SetWCS_ErrorLocator(const char* loc)
11500 + ERROR_LOCATOR = loc;
11503 +void CPL_STDCALL WCS_ErrorHandler(CPLErr eErrClass,int err_no,const char *pszErrorMsg )
11505 + WCS_ERROR_STRING.clear();
11508 + if(err_no >= 300 && err_no <= 309)
11509 + ExcCode = ExcptCodeText[err_no - 300];
11511 + ExcCode = ExcptCodeText[6];
11513 + if(WCS_IsSoapMessage_Transform)
11515 + WCS_ERROR_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
11516 + WCS_ERROR_STRING += "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n";
11517 + WCS_ERROR_STRING += "<soap:Body>\n";
11518 + WCS_ERROR_STRING += "<ExceptionReport xmlns=\"http://www.opengis.net/ows\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
11519 + WCS_ERROR_STRING += "xsi:schemaLocation=\"http://www.opengis.net/ows/owsCommon.xsd\" version=\"0.3.20\" language=\"en\">\n";
11520 + WCS_ERROR_STRING += " <Exception exceptionCode=\"";
11521 + WCS_ERROR_STRING += ExcCode;
11522 + WCS_ERROR_STRING += "\" locator=\"";
11523 + WCS_ERROR_STRING += ERROR_LOCATOR;
11524 + WCS_ERROR_STRING += "\">\n";
11525 + WCS_ERROR_STRING += " <ExceptionText>" + string(pszErrorMsg) + "</ExceptionText>\n";
11526 + WCS_ERROR_STRING += " </Exception>\n";
11527 + WCS_ERROR_STRING += "</ExceptionReport>\n";
11528 + WCS_ERROR_STRING += "/soap:Body>\n";
11529 + WCS_ERROR_STRING += "/<soap:Envelope>\n";
11533 + WCS_ERROR_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
11534 + WCS_ERROR_STRING += "<ExceptionReport xmlns=\"http://www.opengis.net/ows\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
11535 + WCS_ERROR_STRING += "xsi:schemaLocation=\"http://www.opengis.net/ows/owsCommon.xsd\" version=\"0.3.20\" language=\"en\">\n";
11536 + WCS_ERROR_STRING += " <Exception exceptionCode=\"";
11537 + WCS_ERROR_STRING += ExcCode;
11538 + WCS_ERROR_STRING += "\" locator=\"";
11539 + WCS_ERROR_STRING += ERROR_LOCATOR;
11540 + WCS_ERROR_STRING += "\">\n";
11541 + WCS_ERROR_STRING += " <ExceptionText>" + string(pszErrorMsg) + "</ExceptionText>\n";
11542 + WCS_ERROR_STRING += " </Exception>\n";
11543 + WCS_ERROR_STRING += "</ExceptionReport>\n";
11549 +void WCST_SetSoapMsgTrns(int isSoap)
11551 + WCS_IsSoapMessage_Transform = isSoap;
11554 +int WCST_GetSoapMsgTrns()
11556 + return WCS_IsSoapMessage_Transform;
11558 diff -Nur bes-3.12.0/functions.orig/swath2grid/wcs_error.h bes-3.12.0/functions/swath2grid/wcs_error.h
11559 --- bes-3.12.0/functions.orig/swath2grid/wcs_error.h 1970-01-01 01:00:00.000000000 +0100
11560 +++ bes-3.12.0/functions/swath2grid/wcs_error.h 2014-03-03 15:47:38.046899595 +0100
11562 +/******************************************************************************
11563 + * $Id: wcs_error.h 2011-07-19 16:24:00Z $
11565 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
11566 + * for Earth Observation: Open Source Reference Implementation
11567 + * Purpose: WCS exception and error handler definition
11568 + * Author: Yuanzheng Shao, yshao3@gmu.edu
11570 + ******************************************************************************
11571 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
11573 + * Permission is hereby granted, free of charge, to any person obtaining a
11574 + * copy of this software and associated documentation files (the "Software"),
11575 + * to deal in the Software without restriction, including without limitation
11576 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11577 + * and/or sell copies of the Software, and to permit persons to whom the
11578 + * Software is furnished to do so, subject to the following conditions:
11580 + * The above copyright notice and this permission notice shall be included
11581 + * in all copies or substantial portions of the Software.
11583 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11584 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11585 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
11586 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11587 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
11588 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11589 + * DEALINGS IN THE SOFTWARE.
11590 + ****************************************************************************/
11592 +/************************************************************************
11593 + WCS Exception Code
11595 + See OGC Web Services Common Standard [OGC 06-121r9] for details
11596 + Table 27 — Standard exception codes and meanings
11597 + OperationNotSupported
11598 + MissingParameterValue
11599 + InvalidParameterValue
11600 + VersionNegotiationFailed
11601 + InvalidUpdateSequence
11602 + OptionNotSupported
11605 + See OGC® WCS 2.0 Interface Standard - Core [09-110r3] for details
11606 + Table 18 - Exception codes for GetCoverage operation
11609 + InvalidSubsetting
11611 +*************************************************************************/
11613 +#ifndef WCS_ERROR_H_
11614 +#define WCS_ERROR_H_
11616 +#include <cpl_error.h>
11619 +using namespace std;
11621 +#define OGC_WCS_OperationNotSupported 300
11622 +#define OGC_WCS_MissingParameterValue 301
11623 +#define OGC_WCS_InvalidParameterValue 302
11624 +#define OGC_WCS_VersionNegotiationFailed 303
11625 +#define OGC_WCS_InvalidUpdateSequence 304
11626 +#define OGC_WCS_OptionNotSupported 305
11627 +#define OGC_WCS_NoApplicableCode 306
11629 +#define OGC_WCS_NoSuchCoverage 307
11630 +#define OGC_WCS_InvalidAxisLabel 308
11631 +#define OGC_WCS_InvalidSubsetting 309
11633 +void CPL_DLL CPL_STDCALL WCS_Error(CPLErr, int, const char*, ...);
11634 +void CPL_DLL CPL_STDCALL SetWCS_ErrorLocator(const char* loc);
11635 +void CPL_DLL CPL_STDCALL WCS_ErrorHandler(CPLErr, int, const char*);
11636 +string CPL_DLL CPL_STDCALL GetWCS_ErrorMsg();
11638 +int WCST_GetSoapMsgTrns();
11639 +void WCST_SetSoapMsgTrns(int);
11641 +#define WCS_Error CPLError
11642 +#endif /* WCS_ERROR_H_ */
11643 diff -Nur bes-3.12.0/functions.orig/swath2grid/wcsUtil.cpp bes-3.12.0/functions/swath2grid/wcsUtil.cpp
11644 --- bes-3.12.0/functions.orig/swath2grid/wcsUtil.cpp 1970-01-01 01:00:00.000000000 +0100
11645 +++ bes-3.12.0/functions/swath2grid/wcsUtil.cpp 2014-03-03 15:47:38.056899595 +0100
11647 +/******************************************************************************
\r
11648 + * $Id: wcsUtil.cpp 2011-07-19 16:24:00Z $
\r
11650 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
\r
11651 + * for Earth Observation: Open Source Reference Implementation
\r
11652 + * Purpose: WCS Utility Function implementation
\r
11653 + * Author: Yuanzheng Shao, yshao3@gmu.edu
\r
11655 + ******************************************************************************
\r
11656 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
\r
11658 + * Permission is hereby granted, free of charge, to any person obtaining a
\r
11659 + * copy of this software and associated documentation files (the "Software"),
\r
11660 + * to deal in the Software without restriction, including without limitation
\r
11661 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
11662 + * and/or sell copies of the Software, and to permit persons to whom the
\r
11663 + * Software is furnished to do so, subject to the following conditions:
\r
11665 + * The above copyright notice and this permission notice shall be included
\r
11666 + * in all copies or substantial portions of the Software.
\r
11668 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
11669 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
11670 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
\r
11671 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
11672 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
11673 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
11674 + * DEALINGS IN THE SOFTWARE.
\r
11675 + ****************************************************************************/
\r
11677 +#include <unistd.h>
\r
11678 +#include <dirent.h>
\r
11679 +#include <sys/stat.h>
\r
11680 +#include <stdexcept>
\r
11681 +#include <uuid/uuid.h>
\r
11682 +#include "wcsUtil.h"
\r
11683 +//#include "mfhdf.h"
\r
11685 +/************************************************************************/
\r
11687 +/************************************************************************/
\r
11690 + * \brief Used to get UUID string.
\r
11692 + * This method will return a UUID, such as: cd32eb56-412c-11e0-9cce-67750f871b94
\r
11694 + * @return A generated UUID string.
\r
11697 +string CPL_STDCALL GetUUID()
\r
11700 + uuid_generate(uuid);
\r
11701 + char uuidstr[36];
\r
11702 + uuid_unparse(uuid, uuidstr);
\r
11703 + return uuidstr;
\r
11706 +/************************************************************************/
\r
11707 +/* SPrintArray() */
\r
11708 +/************************************************************************/
\r
11711 + * \brief Print a string based on coverage realted parameters.
\r
11713 + * This method will return a UUID, such as: cd32eb56-412c-11e0-9cce-67750f871b94
\r
11715 + * @return A generated UUID string.
\r
11718 +string CPL_STDCALL SPrintArray(GDALDataType eDataType, const void *paDataArray, int nValues, const char *pszDelimiter)
\r
11720 + char *pszString, *pszField;
\r
11721 + int i, iFieldSize, iStringSize;
\r
11723 + iFieldSize = 32 + strlen(pszDelimiter);
\r
11724 + pszField = (char *) CPLMalloc(iFieldSize + 1);
\r
11725 + iStringSize = nValues * iFieldSize + 1;
\r
11726 + pszString = (char *) CPLMalloc(iStringSize);
\r
11727 + memset(pszString, 0, iStringSize);
\r
11728 + for (i = 0; i < nValues; i++)
\r
11730 + switch (eDataType)
\r
11733 + sprintf(pszField, "%d%s", ((GByte *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11735 + case GDT_UInt16:
\r
11736 + sprintf(pszField, "%u%s", ((GUInt16 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11738 + case GDT_Int16:
\r
11740 + sprintf(pszField, "%d%s", ((GInt16 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11742 + case GDT_UInt32:
\r
11743 + sprintf(pszField, "%u%s", ((GUInt32 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11745 + case GDT_Int32:
\r
11746 + sprintf(pszField, "%d%s", ((GInt32 *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11748 + case GDT_Float32:
\r
11749 + sprintf(pszField, "%.7g%s", ((float *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11751 + case GDT_Float64:
\r
11752 + sprintf(pszField, "%.15g%s", ((double *) paDataArray)[i], (i < nValues - 1) ? pszDelimiter : "");
\r
11755 + strcat(pszString, pszField);
\r
11758 + CPLFree(pszField);
\r
11760 + return string(pszString);
\r
11763 +/************************************************************************/
\r
11764 +/* StrTrimHead() */
\r
11765 +/************************************************************************/
\r
11768 + * \brief Trim s string's head.
\r
11770 + * This method will trim a string's head, remove the sapce and line break
\r
11771 + * in the head of a string.
\r
11773 + * @param str The string to be processed.
\r
11775 + * @return A head-trimmed string.
\r
11778 +string CPL_STDCALL StrTrimHead(const string &str)
\r
11780 + string::size_type p = 0;
\r
11781 + /* leading space? */
\r
11782 + while ((p < str.size()) && (str[p] == ' ' || str[p] == '\t' || str[p] == 13 || str[p] == 10))
\r
11784 + if (p >= str.size())
\r
11787 + return str.substr(p);
\r
11790 +/************************************************************************/
\r
11791 +/* StrTrimTail() */
\r
11792 +/************************************************************************/
\r
11795 + * \brief Trim s string's tail.
\r
11797 + * This method will trim a string's tail, remove the sapce and line break
\r
11798 + * in the tail of a string.
\r
11800 + * @param str The string to be processed.
\r
11802 + * @return A tail-trimmed string.
\r
11805 +string CPL_STDCALL StrTrimTail(const string &str)
\r
11807 + string::size_type p = str.size() - 1;
\r
11808 + while (p >= 0 && (str[p] == ' ' || str[p] == '\t' || str[p] == 13 || str[p] == 10))
\r
11813 + return str.substr(0, p + 1);
\r
11816 +/************************************************************************/
\r
11818 +/************************************************************************/
\r
11821 + * \brief Trim s string's head and tail.
\r
11823 + * This method will trim a string's head and tail, remove the sapce and
\r
11824 + * line break in both the head and end of a string.
\r
11826 + * @param str The string to be processed.
\r
11828 + * @return A trimmed string.
\r
11831 +string CPL_STDCALL StrTrim(const string &str)
\r
11833 + string s = StrTrimTail(str);
\r
11834 + return StrTrimHead(s);
\r
11837 +/************************************************************************/
\r
11838 +/* StrTrims() */
\r
11839 +/************************************************************************/
\r
11842 + * \brief Trim s string's head and tail based on delimiter string.
\r
11844 + * This method will trim a string's head and tail based on delimiter
\r
11845 + * string, and return the trimmed string.
\r
11847 + * @param srcStr The string to be processed.
\r
11849 + * @param tok The delimiter string used to trim the string.
\r
11851 + * @return A trimmed string.
\r
11854 +string CPL_STDCALL StrTrims(const string& srcStr, const char* tok)
\r
11856 + if (srcStr.empty())
\r
11859 + string::size_type beginIdx, endIdx;
\r
11860 + beginIdx = srcStr.find_first_not_of(tok);
\r
11861 + endIdx = srcStr.find_last_not_of(tok);
\r
11863 + if (beginIdx != string::npos && endIdx != string::npos)
\r
11864 + return srcStr.substr(beginIdx, endIdx - beginIdx + 1);
\r
11869 +/************************************************************************/
\r
11871 +/************************************************************************/
\r
11874 + * \brief Slice a string and split it into an array.
\r
11876 + * This method will slice a string based on left and right delimiter, and then
\r
11877 + * split the slipped part into an array.
\r
11879 + * @param str The string to be processed, such as "longitude[15.5,23.5]"
\r
11881 + * @param arrStr The two dimension array to place the sliced results.
\r
11883 + * @param leftdlm The left delimiter used to slip the string, such as '['.
\r
11885 + * @param rightdlm The right delimiter used to slip the string, such as ']'.
\r
11888 +void CPL_STDCALL Strslip(const char* str, const char* arrStr[], const char leftdlm, const char rightdlm)
\r
11890 + char* pdest1 = 0;
\r
11891 + char* pdest2 = 0;
\r
11893 + arrStr[0] = str;
\r
11894 + pdest1 = (char*)strchr(str, leftdlm);
\r
11897 + arrStr[1] = str;
\r
11901 + pdest2 = (char*)strrchr(str, rightdlm);
\r
11905 + arrStr[1] = pdest1 + 1;
\r
11906 + *pdest1 = '\0';
\r
11907 + *pdest2 = '\0';
\r
11912 +/************************************************************************/
\r
11913 +/* CsvburstComplexCpp() */
\r
11914 +/************************************************************************/
\r
11917 + * \brief Slice a string based on single or multiple delimiter(s), and
\r
11918 + * then store the results to array.
\r
11920 + * This method will slice a string based on specified delimiter(s), and then
\r
11921 + * place the sliced string parts to a array.
\r
11923 + * @param line The string to be processed.
\r
11925 + * @param strSet The array to place the sliced results.
\r
11927 + * @param tok The delimiter string used to slice the string.
\r
11929 + * @return The size of the sliced parts.
\r
11932 +int CPL_STDCALL CsvburstComplexCpp(const string& line, vector<string> &strSet, const char *tok)
\r
11934 + if (line.empty() || line == "")
\r
11937 + strSet.clear();
\r
11938 + string::size_type firstPos, idx;
\r
11940 + firstPos = idx = 0;
\r
11941 + idx = line.find_first_of(tok, firstPos);
\r
11943 + while (idx != string::npos)
\r
11945 + string tmpStr = StrTrim(line.substr(firstPos, (idx - firstPos)));
\r
11946 + if (!tmpStr.empty() && tmpStr != "")
\r
11947 + strSet.push_back(tmpStr);
\r
11949 + firstPos = idx + 1;
\r
11950 + if (firstPos == string::npos)
\r
11952 + idx = line.find_first_of(tok, firstPos);
\r
11955 + if (firstPos != string::npos)
\r
11957 + strSet.push_back(StrTrim(line.substr(firstPos)));
\r
11960 + return strSet.size();
\r
11963 +/************************************************************************/
\r
11964 +/* CsvburstCpp() */
\r
11965 +/************************************************************************/
\r
11968 + * \brief Slice a string based on single delimiter, and then store the results to array.
\r
11970 + * This method will slice a string based on specified single delimiter, and then
\r
11971 + * place the sliced string parts to a array.
\r
11973 + * @param line The string to be processed, such as "12,34,56".
\r
11975 + * @param strSet The array to place the sliced results.
\r
11977 + * @param tok The delimiter character used to slice the string, such as ','.
\r
11979 + * @return The size of the sliced parts.
\r
11982 +int CPL_STDCALL CsvburstCpp(const string& line, vector<string> &strSet, const char tok)
\r
11984 + if (line.empty() || line == "")
\r
11987 + strSet.clear();
\r
11988 + string::size_type firstPos, idx;
\r
11989 + string::size_type panfuPos;
\r
11991 + firstPos = idx = 0;
\r
11993 + idx = line.find_first_of(tok, firstPos);
\r
11995 + while (idx != string::npos)
\r
11997 + if(line[idx-2] == '\"' || line[idx-2] == '\'')//Add By Yuanzheng Shao
\r
11999 + firstPos = idx + 1;
\r
12000 + if (firstPos == string::npos)
\r
12002 + panfuPos = idx-2;
\r
12003 + idx = line.find_first_of(tok, firstPos);
\r
12005 + string tmpStr = StrTrim(line.substr(panfuPos, (idx - panfuPos)));
\r
12006 + if (!tmpStr.empty() && tmpStr != "")
\r
12007 + strSet.push_back(tmpStr);
\r
12009 + firstPos = idx + 1;
\r
12010 + idx = line.find_first_of(tok, firstPos);
\r
12014 + string tmpStr = StrTrim(line.substr(firstPos, (idx - firstPos)));
\r
12015 + if (!tmpStr.empty() && tmpStr != "")
\r
12016 + strSet.push_back(tmpStr);
\r
12018 + firstPos = idx + 1;
\r
12019 + if (firstPos == string::npos)
\r
12021 + idx = line.find_first_of(tok, firstPos);
\r
12025 + if (firstPos != string::npos)
\r
12027 + strSet.push_back(StrTrim(line.substr(firstPos)));
\r
12030 + return strSet.size();
\r
12033 +/************************************************************************/
\r
12034 +/* Find_Compare_SubStr() */
\r
12035 +/************************************************************************/
\r
12038 + * \brief Find the substring in a string.
\r
12040 + * This method will find a substring in a string.
\r
12042 + * @param line The string to be processed.
\r
12044 + * @param sub The substring to be compared.
\r
12046 + * @return TRUE if find the substring, otherwise FALSE.
\r
12049 +int CPL_STDCALL Find_Compare_SubStr(string line, string sub)
\r
12051 + if (line.empty() || line == "" || sub.empty() || sub == "")
\r
12054 + for (unsigned int i = 0; i < line.size(); ++i)
\r
12056 + line[i] = (char) toupper((char) line[i]);
\r
12058 + for (unsigned int j = 0; j < sub.size(); ++j)
\r
12060 + sub[j] = (char) toupper((char) sub[j]);
\r
12063 + if (string::npos == line.find(sub))
\r
12069 +/************************************************************************/
\r
12070 +/* GetFileNameList() */
\r
12071 +/************************************************************************/
\r
12074 + * \brief Fetch the file name list under the specified directory.
\r
12076 + * This method will fetch the file name list under the specified directory,
\r
12077 + * and store the results to a array.
\r
12079 + * @param dir The directory name.
\r
12081 + * @param strList The array used to place the results.
\r
12083 + * @return CE_None on success or CE_Failure on failure.
\r
12086 +CPLErr CPL_STDCALL GetFileNameList(char* dir, vector<string> &strList)
\r
12088 + char pwdBuf[256];
\r
12089 + char *pwd=getcwd (pwdBuf, 256);
\r
12091 + struct dirent *entry;
\r
12092 + struct stat statbuf;
\r
12093 + if ((dp = opendir(dir)) == NULL)
\r
12095 + SetWCS_ErrorLocator("getFileNameList()");
\r
12096 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Open Director %s", dir);
\r
12097 + return CE_Failure;
\r
12100 + if (dir[strlen(dir) - 1] == '/')
\r
12101 + dir[strlen(dir) - 1] = '\0';
\r
12105 + while ((entry = readdir(dp)) != NULL)
\r
12107 + lstat(entry->d_name, &statbuf);
\r
12108 + if (S_ISDIR(statbuf.st_mode))
\r
12110 + /* Found a directory, but ignore . and .. */
\r
12111 + if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)
\r
12113 + /* Recurse at a new indent level */
\r
12114 + string subdir = dir;
\r
12115 + subdir = subdir + "/" + entry->d_name;
\r
12116 + GetFileNameList((char*)subdir.c_str(), strList);
\r
12118 + else if (S_ISREG(statbuf.st_mode))
\r
12120 + string fname = getcwd(NULL, 0);
\r
12121 + fname = fname + "/" + entry->d_name;
\r
12122 + strList.push_back(fname);
\r
12128 + return CE_None;
\r
12131 +/************************************************************************/
\r
12132 +/* Julian2Date() */
\r
12133 +/************************************************************************/
\r
12136 + * \brief Convert the Julian days to date string.
\r
12138 + * This method will convert the days of year to its date string (YYYY-MM-DD);
\r
12140 + * @param year The year of days.
\r
12142 + * @param days The Julian days.
\r
12144 + * @return The date string.
\r
12147 +string Julian2Date(int year, int days)
\r
12149 + bool leapyear = ((year%4==0 && year%100!=0) || year%400==0) ? true : false;
\r
12150 + int month, day;
\r
12152 + int leapArr[24] = {1, 31, 32, 60, 61, 91, 92, 121, 122, 152, 153, 182, 183, 213, 214, 244,
\r
12153 + 245, 274, 275, 305, 306, 335, 336, 366};
\r
12154 + int unLeArr[24] = {1, 31, 32, 59, 60, 90, 91, 120, 121, 151, 152, 181, 182, 212, 213, 243,
\r
12155 + 244, 273, 274, 304, 305, 334, 335, 365};
\r
12158 + for (int i = 0; i < 24; i += 2) {
\r
12159 + if(days >= leapArr[i] && days <= leapArr[i+1]) {
\r
12160 + month = int(i/2) + 1;
\r
12161 + day = days - leapArr[i] + 1;
\r
12166 + for (int i=0; i < 24; i += 2) {
\r
12167 + if(days >= unLeArr[i] && days <= unLeArr[i+1]) {
\r
12168 + month = int(i/2) + 1;
\r
12169 + day = days - unLeArr[i] + 1;
\r
12175 + string monthStr = month<10 ? "0" + convertToString(month) : convertToString(month);
\r
12176 + string dayStr = day<10 ? "0" + convertToString(day) : convertToString(day);
\r
12178 + return convertToString(year) + "-" + monthStr + "-" + dayStr;
\r
12181 +/************************************************************************/
\r
12182 +/* GetTRMMBandList() */
\r
12183 +/************************************************************************/
\r
12186 + * \brief Fetch the day's list for TRMM data based on the range of date/time.
\r
12188 + * This method will find day's list for TRMM data based on specified date/time
\r
12189 + * range, and store the results to a array.
\r
12191 + * @param start The start date/time.
\r
12193 + * @param end The end date/time.
\r
12195 + * @param bandList The array used to place the results.
\r
12197 + * @return CE_None on success or CE_Failure on failure.
\r
12200 +CPLErr CPL_STDCALL GetTRMMBandList(string start, string end, std::vector<int> &bandList)
\r
12202 + //calculate 2000-06-01's days, start's days, end's days
\r
12203 + if(EQUAL(start.c_str(), "") && EQUAL(end.c_str(), ""))
\r
12204 + return CE_None;
\r
12206 + string june1str = start.substr(0, 4) + "-06-01";
\r
12207 + long int june1sec = ConvertDateTimeToSeconds(june1str);
\r
12208 + long int startsec = 0, endsec = 0;
\r
12210 + if(!EQUAL(start.c_str(), ""))
\r
12211 + startsec = ConvertDateTimeToSeconds(start);
\r
12212 + if(!EQUAL(end.c_str(), ""))
\r
12213 + endsec = ConvertDateTimeToSeconds(end);
\r
12215 + int sdays = (int)(startsec - june1sec)/(24*3600) + 1;
\r
12216 + int edays = (int)(endsec - june1sec)/(24*3600) + 1;
\r
12218 + sdays = (sdays < 0) ? 0 : sdays;
\r
12219 + edays = (edays < 0) ? sdays : edays;
\r
12221 + for(int i = sdays; i <= edays; i++)
\r
12222 + bandList.push_back(i);
\r
12224 + return CE_None;
\r
12228 +/************************************************************************/
\r
12229 +/* GetTimeString() */
\r
12230 +/************************************************************************/
\r
12233 + * \brief Fetch the current system time to a string.
\r
12235 + * This method will get the current system time, and convert it to a string.
\r
12236 + * The return date/time has two formats:
\r
12237 + * 1: YYYYMMDDHHMMSS
\r
12238 + * 2: YYYY-MM-DDTHH:MM:SSZ
\r
12240 + * @param code The return string's format.
\r
12242 + * @return The string corresponding to current system time.
\r
12245 +string GetTimeString(int code)
\r
12247 + struct tm* ptime;
\r
12250 + ptime = localtime(&now);
\r
12251 + int year = ptime->tm_year + 1900;
\r
12252 + int month = ptime->tm_mon + 1;
\r
12253 + int day = ptime->tm_mday;
\r
12254 + int hour = ptime->tm_hour;
\r
12255 + int minute = ptime->tm_min;
\r
12256 + int second = ptime->tm_sec;
\r
12257 + string ye, mo, da, ho, mi, se;
\r
12258 + ye = convertToString(year);
\r
12259 + mo = (month < 10) ? "0" + convertToString(month) : convertToString(month);
\r
12260 + da = (day < 10) ? "0" + convertToString(day) : convertToString(day);
\r
12261 + ho = (hour < 10) ? "0" + convertToString(hour) : convertToString(hour);
\r
12262 + mi = (minute < 10) ? "0" + convertToString(minute) : convertToString(minute);
\r
12263 + se = (second < 10) ? "0" + convertToString(second) : convertToString(second);
\r
12265 + string timestring;
\r
12268 + string part1 = ye + mo + da;
\r
12269 + string part2 = ho + mi + se;
\r
12270 + timestring = part1.append(part2);
\r
12272 + else if(code == 2)
\r
12274 + string part1 = ye + "-" + mo + "-" + da + "T";
\r
12275 + string part2 = ho + ":" + mi + ":" + se + "Z";
\r
12276 + timestring = part1.append(part2);
\r
12279 + return timestring;
\r
12282 +/************************************************************************/
\r
12283 +/* MakeTempFile() */
\r
12284 +/************************************************************************/
\r
12287 + * \brief Generate a temporary file path.
\r
12289 + * This method will generate a path for temporary file or output file,
\r
12290 + * which is based on coverage identifier.
\r
12292 + * @param dir The directory of the temporary file.
\r
12294 + * @param covID The coverage identifier.
\r
12296 + * @param suffix The suffix of the file format.
\r
12298 + * @return The full path of the temporary file.
\r
12301 +string MakeTempFile(string dir, string covID, string suffix)
\r
12303 + string sOutFileName;
\r
12305 + if (!dir.empty() && dir != "")
\r
12307 + if (dir[dir.length() - 1] != '/')
\r
12312 + if (!suffix.empty() && suffix != "")
\r
12314 + if (suffix[0] != '.')
\r
12315 + suffix = "." + suffix;
\r
12318 + if(covID == "")
\r
12320 + sOutFileName = dir + GetUUID() + suffix;
\r
12322 + else if (EQUALN(covID.c_str(),"HDF4_EOS:EOS_SWATH:",19) ||
\r
12323 + EQUALN(covID.c_str(),"HDF4_EOS:EOS_GRID:",18) ||
\r
12324 + EQUALN(covID.c_str(),"HDF5:",5))
\r
12326 + vector<string> strSet;
\r
12327 + int n = CsvburstCpp(covID, strSet, ':');
\r
12328 + if(n == 5){//Terra&Aqua
\r
12329 + string srcFilePath = StrTrims(strSet[2], "\'\"");
\r
12330 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
12331 + string datasetname = StrTrims(strSet[4], "\'\"");
\r
12332 + datasetname = StrReplace(datasetname, " ", "_");
\r
12333 + sOutFileName = dir + srcFileName + "." + datasetname + "." + GetTimeString(1) + suffix;
\r
12334 + }else if(n == 3) {//Aura
\r
12335 + string srcFilePath = StrTrims(strSet[1], "\'\"");
\r
12336 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
12337 + string datasetname = StrTrims(strSet[2], "\'\"");
\r
12338 + datasetname = StrReplace(datasetname, "//", "");
\r
12339 + datasetname = StrReplace(datasetname, "/", "_");
\r
12340 + datasetname = StrReplace(datasetname, " ", "");
\r
12341 + sOutFileName = dir + srcFileName + "." + datasetname + "." + GetTimeString(1) + suffix;
\r
12343 + sOutFileName = dir + GetUUID() + suffix;
\r
12344 + }else if(EQUALN( covID.c_str(), "GOES:NetCDF:",12))
\r
12346 + vector<string> strSet;
\r
12347 + int n = CsvburstCpp(covID, strSet, ':');
\r
12349 + string srcFilePath = StrTrims(strSet[2], " \'\"");
\r
12350 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
12351 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
12353 + sOutFileName = dir + GetUUID() + suffix;
\r
12355 + else if(EQUALN(covID.c_str(),"GEOTIFF:",8))
\r
12357 + vector<string> strSet;
\r
12358 + int n = CsvburstCpp(covID, strSet, ':');
\r
12360 + string srcFilePath = StrTrims(strSet[1], " \'\"");
\r
12361 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
12362 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
12364 + sOutFileName = dir + GetUUID() + suffix;
\r
12366 + else if(EQUALN(covID.c_str(),"TRMM:",5))
\r
12368 + vector<string> strSet;
\r
12369 + int n = CsvburstCpp(covID, strSet, ':');
\r
12371 + string srcFilePath = StrTrims(strSet[1], " \'\"");
\r
12372 + string srcFileName = string(CPLGetBasename(srcFilePath.c_str()));
\r
12373 + sOutFileName = dir + srcFileName + "." + GetTimeString(1) + suffix;
\r
12375 + sOutFileName = dir + GetUUID() + suffix;
\r
12378 + sOutFileName = dir + GetUUID() + suffix;
\r
12380 + return sOutFileName;
\r
12383 +/************************************************************************/
\r
12384 +/* StringList() */
\r
12385 +/************************************************************************/
\r
12388 + * \brief Constructor for StringList.
\r
12391 +StringList::StringList(const string& sstrings, const char delimiter)
\r
12393 + string str = sstrings + delimiter;
\r
12394 + string::size_type np, op = 0;
\r
12395 + while ((op < str.size())
\r
12396 + && ((np = str.find(delimiter, op)) != string::npos))
\r
12398 + add(str.substr(op, np - op));
\r
12403 +// -----------------------------------------------------------------------
\r
12404 +// string list constructor
\r
12405 +// -----------------------------------------------------------------------
\r
12406 +StringList::StringList(const string& sstrings, const string& delimiters)
\r
12408 + string str = sstrings + delimiters;
\r
12409 + string::size_type np, op = 0;
\r
12410 + while ((op < str.size()) && ((np = str.find(delimiters, op))
\r
12411 + != string::npos))
\r
12413 + add(str.substr(op, np - op));
\r
12414 + op = np + delimiters.length();
\r
12418 +// -----------------------------------------------------------------------
\r
12419 +// string list -- append
\r
12420 +// -----------------------------------------------------------------------
\r
12421 +void StringList::append(StringList & s)
\r
12423 + for (int i = 0; i < s.size(); i++)
\r
12427 +// -----------------------------------------------------------------------
\r
12428 +// string list -- append with delimiter
\r
12429 +// -----------------------------------------------------------------------
\r
12430 +void StringList::append(const string sstrings, const char delimiter)
\r
12432 + StringList n(sstrings, delimiter);
\r
12436 +// -----------------------------------------------------------------------
\r
12437 +// string list -- append with delimiters
\r
12438 +// -----------------------------------------------------------------------
\r
12439 +void StringList::append(const string sstrings, const string& delimiters)
\r
12441 + StringList n(sstrings, delimiters);
\r
12445 +// -----------------------------------------------------------------------
\r
12446 +// string list -- return the index for query string
\r
12447 +// -----------------------------------------------------------------------
\r
12448 +int StringList::indexof(string qstr)
\r
12450 + for (int i = 0; i < size(); i++)
\r
12452 + if (strings[i] == qstr)
\r
12458 +/************************************************************************/
\r
12460 +/************************************************************************/
\r
12463 + * \brief Constructor for KVP.
\r
12465 + * @param namevaluepair The key-value pair.
\r
12468 +KVP::KVP(string namevaluepair)
\r
12470 + StringList ss(namevaluepair, '=');
\r
12471 + if (ss.size() == 2)
\r
12473 + name = StrTrim(ss[0]);
\r
12474 + value = StrTrim(ss[1]);
\r
12478 + name = namevaluepair;
\r
12483 +/************************************************************************/
\r
12484 +/* CFGReader() */
\r
12485 +/************************************************************************/
\r
12488 + * \brief Constructor for CFGReader.
\r
12490 + * This method is used to load the configuration file for WCS. Each configuration
\r
12491 + * item looks like a key-value pair, CFGReader() will read the file to memory and
\r
12492 + * store the parameters to a KVP array.
\r
12494 + * @param configfilename The full path of the configuration file.
\r
12497 +CFGReader::CFGReader(const string &configfilename)
\r
12499 + ifstream cfgfile(configfilename.c_str());
\r
12502 + SetWCS_ErrorLocator("CFGReader");
\r
12503 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to open configure file.");
\r
12504 + throw runtime_error("");
\r
12507 + char line[MAX_LINE_LEN];
\r
12508 + while (!cfgfile.eof())
\r
12510 + cfgfile.getline(line, MAX_LINE_LEN - 1, '\n');
\r
12511 + if (!cfgfile.fail())
\r
12513 + if (line[0] != '#')
\r
12516 + kvps.push_back(kvp);
\r
12521 + cfgfile.close();
\r
12524 +/************************************************************************/
\r
12525 +/* getValue() */
\r
12526 +/************************************************************************/
\r
12529 + * \brief Fetch a configured item's value.
\r
12531 + * This method is used to fetch a items value from a configuration file.
\r
12533 + * @param keyname The item's name.
\r
12535 + * @return The result string.
\r
12538 +string CFGReader::getValue(const string &keyname)
\r
12540 + for (int i = 0; i < size(); i++)
\r
12542 + if (EQUAL(kvps[i].name.c_str(), keyname.c_str()))
\r
12543 + return kvps[i].value;
\r
12549 +/************************************************************************/
\r
12550 +/* getValue() */
\r
12551 +/************************************************************************/
\r
12554 + * \brief Fetch a configured item's value, with default value.
\r
12556 + * This method is used to fetch a items value from a configuration file,
\r
12557 + * if not found, use the default value.
\r
12559 + * @param keyname The item's name.
\r
12561 + * @param defaultvalue The item's default value.
\r
12563 + * @return The result string.
\r
12566 +string CFGReader::getValue(const string &keyname, const string &defaultvalue)
\r
12568 + string ret = getValue(keyname);
\r
12569 + if (ret.empty() || ret == "")
\r
12570 + return defaultvalue;
\r
12575 +/************************************************************************/
\r
12577 +/************************************************************************/
\r
12580 + * \brief The entry point for CGI program.
\r
12582 + * This method is used to fetch CGI parameters. Supports both HTTP GET
\r
12583 + * and POST method. POST content could be KVPs and XML string, and GET
\r
12584 + * content must be KVPs.
\r
12586 + * @return CE_None on success or CE_Failure on failure.
\r
12589 +CPLErr WCSCGI::Run()
\r
12591 + /* get request parameters*/
\r
12592 + char *gm = getenv("REQUEST_METHOD");
\r
12593 + if (NULL == gm)
\r
12595 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
12596 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Get \"REQUEST_METHOD\" Environment variable.");
\r
12597 + return CE_Failure;
\r
12600 + if (EQUAL(gm, "POST"))
\r
12601 + me_CGIMethod = HTTP_XML_POST;
\r
12602 + else if (EQUAL(gm, "GET"))
\r
12603 + me_CGIMethod = HTTP_GET;
\r
12605 + me_CGIMethod = UN_KNOWN;
\r
12607 + switch (me_CGIMethod)
\r
12609 + case HTTP_XML_POST:
\r
12611 + char* aString = getenv("CONTENT_LENGTH");
\r
12612 + if (NULL == aString || aString[0] == '\0')
\r
12614 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Get \"CONTENT_LENGTH\" Environment variable.");
\r
12615 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
12616 + return CE_Failure;
\r
12619 + unsigned int cLength = atoi(aString);
\r
12621 + string cString;
\r
12622 + cString.resize(cLength + 1);
\r
12624 + if (cLength != fread((char*) cString.c_str(), 1, cLength, stdin))
\r
12626 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
12627 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Failed to Read POST Data Stream from Internet.");
\r
12628 + return CE_Failure;
\r
12631 + cString = StrReplace(cString, "&s;", "%26");
\r
12632 + cString = StrReplace(cString, "&", "%26");
\r
12634 + string tmpStr = CPLUnescapeString(cString.c_str(), NULL, CPLES_URL);
\r
12635 + ms_CGIContent = CPLUnescapeString((char*) tmpStr.c_str(), NULL, CPLES_XML);
\r
12637 + string::size_type beginIdx, endIdx;
\r
12639 + beginIdx = ms_CGIContent.find("<?");
\r
12640 + endIdx = ms_CGIContent.rfind(">");
\r
12641 + //The post contents could be KVPs
\r
12642 + if (beginIdx != string::npos && endIdx != string::npos)
\r
12643 + ms_CGIContent = ms_CGIContent.substr(beginIdx, endIdx - beginIdx + 1);
\r
12648 + string tmpStr = getenv("QUERY_STRING");
\r
12649 + tmpStr = StrReplace(tmpStr, "&s;", "%26");
\r
12650 + tmpStr = StrReplace(tmpStr, "&", "%26");
\r
12651 + if (tmpStr.empty() || tmpStr == "")
\r
12653 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
12654 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "No \"QUERY_STRING\" Content.");
\r
12655 + return CE_Failure;
\r
12658 + ms_CGIContent = CPLUnescapeString((char*) tmpStr.c_str(), NULL, CPLES_URL);
\r
12663 + SetWCS_ErrorLocator("WCSCGI::Run()");
\r
12664 + WCS_Error(CE_Failure, OGC_WCS_NoApplicableCode, "Unkown \"REQUEST_METHOD\".");
\r
12665 + return CE_Failure;
\r
12669 + return CE_None;
\r
12672 +// -----------------------------------------------------------------------
\r
12673 +// KVPsReader constructor
\r
12674 +// -----------------------------------------------------------------------
\r
12675 +KVPsReader::KVPsReader(const string& urlStr, const char &tok)
\r
12677 + StringList strLit(urlStr, tok);
\r
12679 + for (int i = 0; i < strLit.size(); ++i)
\r
12681 + KVP kvp(StrTrim(strLit[i]));
\r
12682 + m_kvps.push_back(kvp);
\r
12686 +// -----------------------------------------------------------------------
\r
12687 +// KVPsReader get value function
\r
12688 +// -----------------------------------------------------------------------
\r
12689 +string KVPsReader::getValue(const string &keyname)
\r
12691 + for (unsigned int i = 0; i < m_kvps.size(); i++)
\r
12693 + if (EQUAL(m_kvps[i].name.c_str() , keyname.c_str()))
\r
12694 + return m_kvps[i].value;
\r
12700 +vector<string> KVPsReader::getValues(const string &keyname)
\r
12702 + vector<string> valuesList;
\r
12703 + for (unsigned int i = 0; i < m_kvps.size(); i++)
\r
12705 + if (EQUAL(m_kvps[i].name.c_str() , keyname.c_str()))
\r
12706 + valuesList.push_back(m_kvps[i].value);
\r
12708 + return valuesList;
\r
12711 +// -----------------------------------------------------------------------
\r
12712 +// KVPsReader get value function, with default value
\r
12713 +// -----------------------------------------------------------------------
\r
12714 +string KVPsReader::getValue(const string &keyname, const string &defaultvalue)
\r
12716 + string ret = getValue(keyname);
\r
12717 + if (ret.empty() || ret == "")
\r
12718 + return defaultvalue;
\r
12723 +/************************************************************************/
\r
12724 +/* StrReplace() */
\r
12725 +/************************************************************************/
\r
12728 + * \brief Replace a string.
\r
12730 + * This method is used to replace a string with specified substring.
\r
12732 + * @param str The string needs to be processed.
\r
12734 + * @param oldSubStr The substring needs to be replaced.
\r
12736 + * @param newStr The string will replace the oldSubStr.
\r
12738 + * @return The processed string.
\r
12741 +string CPL_STDCALL StrReplace(string& str, const string oldSubStr, const string newStr)
\r
12745 + string::size_type pos(0);
\r
12746 + if( ( pos = str.find(oldSubStr) ) != string::npos )
\r
12748 + str.replace( pos, oldSubStr.length(), newStr );
\r
12756 +/************************************************************************/
\r
12757 +/* GetSingleValue() */
\r
12758 +/************************************************************************/
\r
12761 + * \brief Get a single value from a special KVP part.
\r
12763 + * This method is used to get value from a special KVP part.
\r
12765 + * @param subsetstr The string needs to be processed, such as "subset=Long(11)".
\r
12767 + * @return The processed string, such as "11".
\r
12770 +string CPL_STDCALL GetSingleValue(const string& subsetstr)
\r
12772 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
12773 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
12775 + return StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 -1));
\r
12778 +/************************************************************************/
\r
12779 +/* GetSubSetLatLon() */
\r
12780 +/************************************************************************/
\r
12783 + * \brief Get a subset spatial extent in WCS 2.0 request.
\r
12785 + * This method is used to get values of spatial extent and place the values
\r
12786 + * in an array, and return the CRS code for the coordinates of the extent.
\r
12788 + * @param subsetstr The string needs to be processed,
\r
12789 + * such as "subset=Lat,http://www.opengis.net/def/crs/EPSG/0/4326(32,47)".
\r
12791 + * @param subsetvalue The array to place the spatial extent values.
\r
12793 + * @return The processed string, such as "EPSG:4326".
\r
12796 +string CPL_STDCALL GetSubSetLatLon(const string& subsetstr, vector<double> &subsetvalue)
\r
12798 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
12799 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
12801 + string value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 -1));
\r
12802 + vector<string> tmpV;
\r
12803 + CsvburstCpp(value, tmpV, ',');
\r
12805 + for(unsigned int i = 0; i < tmpV.size(); i++)
\r
12808 + convertFromString(curD, tmpV.at(i));
\r
12809 + subsetvalue.push_back(curD);
\r
12812 + string subsetProj;
\r
12813 + idx1 = subsetstr.find(',');
\r
12814 + idx2 = subsetstr.find('(');
\r
12815 + if(idx1 > idx2)
\r
12817 + subsetProj = "EPSG:4326";
\r
12821 + value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 - 1));
\r
12822 + if(value.find("http") != string::npos)
\r
12824 + string::size_type idx3 = value.find_last_of('/');
\r
12825 + subsetProj = "EPSG:" + value.substr(idx3 + 1);
\r
12829 + subsetProj = value;
\r
12834 + return subsetProj;
\r
12837 +//subset=phenomenonTime("2006-08-01","2006-08-22T09:22:00Z")&
\r
12838 +//subset=phenomenonTime("2006-08-01")&
\r
12839 +void CPL_STDCALL GetSubSetTime(const string& subsetstr, vector<string> &subsetvalue)
\r
12841 + string::size_type idx1 = subsetstr.find_last_of('(');
\r
12842 + string::size_type idx2 = subsetstr.find_last_of(')');
\r
12843 + string value = StrTrim(subsetstr.substr(idx1 + 1, idx2 - idx1 - 1));
\r
12844 + string valueN = StrReplace(value, "\"", "");
\r
12845 + CsvburstCpp(valueN, subsetvalue, ',');
\r
12848 +//time type 1: 2006-08-22T09:22:00Z
\r
12849 +//time type 1: 2006-08-01
\r
12850 +int CPL_STDCALL CompareDateTime_GreaterThan(string time1, string time2)
\r
12852 + time_t retval1 = 0;
\r
12853 + time_t retval2 = 0;
\r
12855 + struct tm storage1 = {0,0,0,0,0,0,0,0,0};
\r
12856 + struct tm storage2 = {0,0,0,0,0,0,0,0,0};
\r
12858 + char *p1 = NULL;
\r
12859 + char *p2 = NULL;
\r
12861 + if(time1.find("T") != string::npos && time1.find("Z") != string::npos)
\r
12862 + p1 = (char *)strptime(time1.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage1);
\r
12864 + p1 = (char *)strptime(time1.c_str(), "%Y-%m-%d", &storage1);
\r
12866 + if(time2.find("T") != string::npos && time2.find("Z") != string::npos)
\r
12867 + p2 = (char *)strptime(time2.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage2);
\r
12869 + p2 = (char *)strptime(time2.c_str(), "%Y-%m-%d", &storage2);
\r
12871 + retval1 = mktime(&storage1);
\r
12872 + retval2 = mktime(&storage2);
\r
12874 + if(retval1 == retval2)
\r
12876 + else if(retval1 > retval2)
\r
12883 +int CPL_STDCALL ConvertDateTimeToSeconds(string datetime)
\r
12885 + time_t retval1 = 0;
\r
12886 + struct tm storage1 = {0,0,0,0,0,0,0,0,0};
\r
12887 + char *p1 = NULL;
\r
12889 + if(datetime.find("T") != string::npos && datetime.find("Z") != string::npos)
\r
12890 + p1 = (char *)strptime(datetime.c_str(), "%Y-%m-%dT%H:%M:%SZ", &storage1);
\r
12892 + p1 = (char *)strptime(datetime.c_str(), "%Y-%m-%d", &storage1);
\r
12894 + retval1 = mktime(&storage1);
\r
12896 + return retval1;
\r
12899 +// -----------------------------------------------------------------------
\r
12900 +// Find lower-left and upper-right corner point coordinate
\r
12901 +// -----------------------------------------------------------------------
\r
12902 +void CPL_STDCALL GetCornerPoints(const GDAL_GCP* &pGCPList, const int &nGCPs, My2DPoint& lowLeft, My2DPoint& upRight)
\r
12904 + double xLeft = (numeric_limits<double>::max)();
\r
12905 + double xRight = -xLeft;
\r
12906 + double yLower = (numeric_limits<double>::max)();
\r
12907 + double yUpper = -yLower;
\r
12909 + for (int j = 0; j < nGCPs; j++)
\r
12911 + yUpper = MAX(yUpper,pGCPList[j].dfGCPY);
\r
12912 + yLower = MIN(yLower,pGCPList[j].dfGCPY);
\r
12913 + if(pGCPList[j].dfGCPX != -999)//test MOD021KM.A2000065.1900.005.2008235220315.hdf, error GCP X value (-999)
\r
12914 + xLeft = MIN(xLeft,pGCPList[j].dfGCPX);
\r
12915 + xRight = MAX(xRight,pGCPList[j].dfGCPX);
\r
12918 + lowLeft.mi_X = xLeft;
\r
12919 + lowLeft.mi_Y = yLower;
\r
12920 + upRight.mi_X = xRight;
\r
12921 + upRight.mi_Y = yUpper;
\r
12925 diff -Nur bes-3.12.0/functions.orig/swath2grid/wcsUtil.h bes-3.12.0/functions/swath2grid/wcsUtil.h
12926 --- bes-3.12.0/functions.orig/swath2grid/wcsUtil.h 1970-01-01 01:00:00.000000000 +0100
12927 +++ bes-3.12.0/functions/swath2grid/wcsUtil.h 2014-03-03 15:47:38.043566262 +0100
12929 +/******************************************************************************
\r
12930 + * $Id: wcsUtil.h 2011-07-19 16:24:00Z $
\r
12932 + * Project: The Open Geospatial Consortium (OGC) Web Coverage Service (WCS)
\r
12933 + * for Earth Observation: Open Source Reference Implementation
\r
12934 + * Purpose: WCS Utility Function definition
\r
12935 + * Author: Yuanzheng Shao, yshao3@gmu.edu
\r
12937 + ******************************************************************************
\r
12938 + * Copyright (c) 2011, Liping Di <ldi@gmu.edu>, Yuanzheng Shao <yshao3@gmu.edu>
\r
12940 + * Permission is hereby granted, free of charge, to any person obtaining a
\r
12941 + * copy of this software and associated documentation files (the "Software"),
\r
12942 + * to deal in the Software without restriction, including without limitation
\r
12943 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
12944 + * and/or sell copies of the Software, and to permit persons to whom the
\r
12945 + * Software is furnished to do so, subject to the following conditions:
\r
12947 + * The above copyright notice and this permission notice shall be included
\r
12948 + * in all copies or substantial portions of the Software.
\r
12950 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
\r
12951 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
12952 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
\r
12953 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
12954 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
12955 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
12956 + * DEALINGS IN THE SOFTWARE.
\r
12957 + ****************************************************************************/
\r
12959 +#ifndef WCSUTIL_H_
\r
12960 +#define WCSUTIL_H_
\r
12962 +#include <iostream>
\r
12963 +#include <fstream>
\r
12964 +#include <sstream>
\r
12965 +#include <vector>
\r
12966 +#include <stdlib.h>
\r
12967 +#include <time.h>
\r
12969 +#include <cpl_string.h>
\r
12970 +#include "wcs_error.h"
\r
12971 +#include "BoundingBox.h"
\r
12973 +using namespace std;
\r
12976 +#if defined(WIN32) || defined(WIN32CE)
\r
12977 +# define EQUALN(a,b,n) (strnicmp(a,b,n)==0)
\r
12978 +# define EQUAL(a,b) (stricmp(a,b)==0)
\r
12980 +# define EQUALN(a,b,n) (strncasecmp(a,b,n)==0)
\r
12981 +# define EQUAL(a,b) (strcasecmp(a,b)==0)
\r
12997 +#define DELIMITER "\\"
\r
12999 +#define DELIMITER "/"
\r
13002 +const int SHORT_NAME_LEN = 128;
\r
13003 +const int MAX_NAME_LEN = 512;
\r
13004 +const int MAX_LIST_LEN = 1024;
\r
13005 +const int MAX_LINE_LEN = 65536;
\r
13008 +// -----------------------------------------------------------------------
\r
13009 +// CGI (Common Gateway Interface) related class and functions
\r
13010 +// -----------------------------------------------------------------------
\r
13011 +enum CGI_METHOD_FLAG
\r
13013 + UN_KNOWN, HTTP_GET, HTTP_XML_POST
\r
13016 +/************************************************************************/
\r
13017 +/* ==================================================================== */
\r
13019 +/* ==================================================================== */
\r
13020 +/************************************************************************/
\r
13023 + * \class WCSCGI "wcsUtil.h"
\r
13025 + * WCSCGI class is used to acquire WCS request, both GET and POST method
\r
13026 + * are supported.
\r
13032 + string ms_CGIContent;
\r
13033 + CGI_METHOD_FLAG me_CGIMethod;
\r
13038 + me_CGIMethod = UN_KNOWN;
\r
13043 + string GetRqstContent()
\r
13045 + return ms_CGIContent;
\r
13048 + CGI_METHOD_FLAG GetCGImethod()
\r
13050 + return me_CGIMethod;
\r
13054 +/************************************************************************/
\r
13055 +/* ==================================================================== */
\r
13056 +/* StringList */
\r
13057 +/* ==================================================================== */
\r
13058 +/************************************************************************/
\r
13060 +class StringList
\r
13063 + vector<string> strings;
\r
13066 + StringList(const string& sstrings, const char delimiter);
\r
13067 + StringList(const string& sstrings, const string& delimiters);
\r
13068 + StringList(){ }
\r
13070 + int indexof(string qstr);
\r
13072 + void add(string newstr)
\r
13074 + strings.push_back(newstr);
\r
13079 + strings.clear();
\r
13084 + return strings.size();
\r
13087 + string& operator [](int index)
\r
13089 + return strings[index];
\r
13092 + void append(StringList & s);
\r
13093 + void append(const string sstrings, const char delimiter);
\r
13094 + void append(const string sstrings, const string& delimiters);
\r
13096 + string toString()
\r
13099 + for (int i = 0; i < size(); i++)
\r
13100 + s += strings[i];
\r
13104 + string toString(const char delimiter)
\r
13107 + for (int i = 0; i < size(); i++)
\r
13108 + s += strings[i] + delimiter;
\r
13112 + string toString(const string& delimiters)
\r
13115 + for (int i = 0; i < size(); i++)
\r
13116 + s += strings[i] + delimiters;
\r
13125 + char buf[MAX_LINE_LEN];
\r
13130 + s.copy(buf, string::npos);
\r
13131 + buf[s.size()] = 0;
\r
13141 +/************************************************************************/
\r
13142 +/* ==================================================================== */
\r
13144 +/* ==================================================================== */
\r
13145 +/************************************************************************/
\r
13150 + string name, value;
\r
13152 + KVP& operator =(const KVP &id)
\r
13154 + name = id.name;
\r
13155 + value = id.value;
\r
13159 + KVP& operator =(const KVP *pid)
\r
13161 + name = pid->name;
\r
13162 + value = pid->value;
\r
13166 + KVP(string n, string v) :
\r
13167 + name(n), value(v)
\r
13171 + KVP(string namevaluepair);
\r
13175 +/************************************************************************/
\r
13176 +/* ==================================================================== */
\r
13177 +/* KVPsReader */
\r
13178 +/* ==================================================================== */
\r
13179 +/************************************************************************/
\r
13181 +class KVPsReader
\r
13184 + vector<KVP> m_kvps;
\r
13195 + KVPsReader(const string& urlStr, const char &tok);
\r
13197 + KVP& operator [](const int index)
\r
13199 + return m_kvps[index];
\r
13204 + return m_kvps.size();
\r
13207 + string getValue(const string &keyname);
\r
13208 + string getValue(const string &keyname, const string &defaultvalue);
\r
13209 + vector<string> getValues(const string &keyname);
\r
13212 +/************************************************************************/
\r
13213 +/* ==================================================================== */
\r
13215 +/* ==================================================================== */
\r
13216 +/************************************************************************/
\r
13220 + vector<KVP> kvps;
\r
13223 + CFGReader(const string &configfilename);
\r
13225 + KVP& operator [](const int index)
\r
13227 + return kvps[index];
\r
13232 + return kvps.size();
\r
13235 + string getValue(const string &keyname);
\r
13236 + string getValue(const string &keyname, const string &defaultvalue);
\r
13240 +// -----------------------------------------------------------------------
\r
13241 +// Extra Template Functions
\r
13242 +// Exchange() --- used to exchange values
\r
13243 +// convertToString() --- convert value to string
\r
13244 +// convertFromString --- convert string to values
\r
13245 +// -----------------------------------------------------------------------
\r
13246 +template<class T>
\r
13247 +static void Exchange(T & a, T & b)
\r
13255 +template <class T>
\r
13256 +static string convertToString(T &value)
\r
13258 + stringstream ss;
\r
13260 + string rtnstr = ss.str();
\r
13264 +template <class T>
\r
13265 +static void convertFromString(T &value, const string& s)
\r
13267 + stringstream ss(s);
\r
13272 +// -----------------------------------------------------------------------
\r
13273 +// Extra Utility Functions
\r
13274 +// -----------------------------------------------------------------------
\r
13277 +// String Operation Related
\r
13278 +int CPL_DLL CPL_STDCALL CsvburstCpp(const std::string& line, std::vector<std::string> &strSet, const char tok);
\r
13279 +int CPL_DLL CPL_STDCALL CsvburstComplexCpp(const string& line, vector<string> &strSet, const char* tok);
\r
13280 +int CPL_DLL CPL_STDCALL Find_Compare_SubStr(string line, string sub);
\r
13281 +void CPL_DLL CPL_STDCALL Strslip(const char* str, const char* arrStr[], const char leftdlm, const char rightdlm);
\r
13282 +string CPL_DLL CPL_STDCALL StrReplace(string& str, const string oldSubStr, const string newStr);
\r
13283 +string CPL_DLL CPL_STDCALL SPrintArray(GDALDataType eDataType, const void *paDataArray, int nValues, const char *pszDelimiter);
\r
13284 +string CPL_DLL CPL_STDCALL StrTrimHead(const string &str);
\r
13285 +string CPL_DLL CPL_STDCALL StrTrimTail(const string &str);
\r
13286 +string CPL_DLL CPL_STDCALL StrTrims(const std::string&, const char*);
\r
13287 +string CPL_DLL CPL_STDCALL StrTrim(const string &str);
\r
13289 +// Date Time Operation Related
\r
13290 +int CPL_DLL CPL_STDCALL CompareDateTime_GreaterThan(string time1, string time2);
\r
13291 +int CPL_DLL CPL_STDCALL ConvertDateTimeToSeconds(string datetime);
\r
13292 +string CPL_DLL CPL_STDCALL GetTimeString(int code);
\r
13294 +// Directory Operation Related
\r
13295 +CPLErr CPL_DLL CPL_STDCALL GetFileNameList(char* dir, std::vector<string> &strList);
\r
13296 +string CPL_DLL CPL_STDCALL MakeTempFile(string dir, string covID, string suffix);
\r
13297 +string CPL_DLL CPL_STDCALL GetUUID();
\r
13299 +// Request Parser Operation
\r
13300 +void CPL_DLL CPL_STDCALL GetSubSetTime(const string& subsetstr, vector<string> &subsetvalue);
\r
13301 +string CPL_DLL CPL_STDCALL GetSubSetLatLon(const string& subsetstr, vector<double> &subsetvalue);
\r
13302 +string CPL_DLL CPL_STDCALL GetSingleValue(const string& subsetstr);
\r
13304 +CPLErr CPL_DLL CPL_STDCALL GetTRMMBandList(string start, string end, std::vector<int> &bandList);
\r
13305 +void CPL_DLL CPL_STDCALL GetCornerPoints(const GDAL_GCP* &pGCPList, const int &nGCPs, My2DPoint& lowLeft, My2DPoint& upRight);
\r
13309 +#endif /*WCSUTIL_H_*/
\r