1 : /******************************************************************************
2 : * $Id: vrtrasterband.cpp 19814 2010-06-07 21:41:58Z rouault $
3 : *
4 : * Project: Virtual GDAL Datasets
5 : * Purpose: Implementation of VRTRasterBand
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "vrtdataset.h"
31 : #include "cpl_minixml.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: vrtrasterband.cpp 19814 2010-06-07 21:41:58Z rouault $");
35 :
36 : /************************************************************************/
37 : /* ==================================================================== */
38 : /* VRTRasterBand */
39 : /* ==================================================================== */
40 : /************************************************************************/
41 :
42 : /************************************************************************/
43 : /* VRTRasterBand() */
44 : /************************************************************************/
45 :
46 464 : VRTRasterBand::VRTRasterBand()
47 :
48 : {
49 464 : Initialize( 0, 0 );
50 464 : }
51 :
52 : /************************************************************************/
53 : /* Initialize() */
54 : /************************************************************************/
55 :
56 928 : void VRTRasterBand::Initialize( int nXSize, int nYSize )
57 :
58 : {
59 928 : poDS = NULL;
60 928 : nBand = 0;
61 928 : eAccess = GA_ReadOnly;
62 928 : eDataType = GDT_Byte;
63 :
64 928 : nRasterXSize = nXSize;
65 928 : nRasterYSize = nYSize;
66 :
67 928 : nBlockXSize = MIN(128,nXSize);
68 928 : nBlockYSize = MIN(128,nYSize);
69 :
70 928 : bNoDataValueSet = FALSE;
71 928 : bHideNoDataValue = FALSE;
72 928 : dfNoDataValue = -10000.0;
73 928 : poColorTable = NULL;
74 928 : eColorInterp = GCI_Undefined;
75 :
76 928 : pszUnitType = NULL;
77 928 : papszCategoryNames = NULL;
78 928 : dfOffset = 0.0;
79 928 : dfScale = 1.0;
80 :
81 928 : psSavedHistograms = NULL;
82 928 : }
83 :
84 : /************************************************************************/
85 : /* ~VRTRasterBand() */
86 : /************************************************************************/
87 :
88 464 : VRTRasterBand::~VRTRasterBand()
89 :
90 : {
91 464 : CPLFree( pszUnitType );
92 :
93 464 : if( poColorTable != NULL )
94 10 : delete poColorTable;
95 :
96 464 : CSLDestroy( papszCategoryNames );
97 464 : if( psSavedHistograms != NULL )
98 0 : CPLDestroyXMLNode( psSavedHistograms );
99 464 : }
100 :
101 : /************************************************************************/
102 : /* CopyCommonInfoFrom() */
103 : /* */
104 : /* Copy common metadata, pixel descriptions, and color */
105 : /* interpretation from the provided source band. */
106 : /************************************************************************/
107 :
108 70 : CPLErr VRTRasterBand::CopyCommonInfoFrom( GDALRasterBand * poSrcBand )
109 :
110 : {
111 : int bSuccess;
112 : double dfNoData;
113 :
114 70 : SetMetadata( poSrcBand->GetMetadata() );
115 70 : SetColorTable( poSrcBand->GetColorTable() );
116 70 : SetColorInterpretation(poSrcBand->GetColorInterpretation());
117 70 : if( strlen(poSrcBand->GetDescription()) > 0 )
118 0 : SetDescription( poSrcBand->GetDescription() );
119 70 : dfNoData = poSrcBand->GetNoDataValue( &bSuccess );
120 70 : if( bSuccess )
121 1 : SetNoDataValue( dfNoData );
122 :
123 70 : SetOffset( poSrcBand->GetOffset() );
124 70 : SetScale( poSrcBand->GetScale() );
125 70 : SetCategoryNames( poSrcBand->GetCategoryNames() );
126 70 : if( !EQUAL(poSrcBand->GetUnitType(),"") )
127 1 : SetUnitType( poSrcBand->GetUnitType() );
128 :
129 70 : return CE_None;
130 : }
131 :
132 : /************************************************************************/
133 : /* SetMetadata() */
134 : /************************************************************************/
135 :
136 : CPLErr VRTRasterBand::SetMetadata( char **papszMetadata,
137 70 : const char *pszDomain )
138 :
139 : {
140 70 : ((VRTDataset *) poDS)->SetNeedsFlush();
141 :
142 70 : return GDALRasterBand::SetMetadata( papszMetadata, pszDomain );
143 : }
144 :
145 : /************************************************************************/
146 : /* SetMetadataItem() */
147 : /************************************************************************/
148 :
149 : CPLErr VRTRasterBand::SetMetadataItem( const char *pszName,
150 : const char *pszValue,
151 10 : const char *pszDomain )
152 :
153 : {
154 10 : ((VRTDataset *) poDS)->SetNeedsFlush();
155 :
156 10 : if( EQUAL(pszName,"HideNoDataValue") )
157 : {
158 0 : bHideNoDataValue = CSLTestBoolean( pszValue );
159 0 : return CE_None;
160 : }
161 : else
162 10 : return GDALRasterBand::SetMetadataItem( pszName, pszValue, pszDomain );
163 : }
164 :
165 : /************************************************************************/
166 : /* GetUnitType() */
167 : /************************************************************************/
168 :
169 192 : const char *VRTRasterBand::GetUnitType()
170 :
171 : {
172 192 : if( pszUnitType == NULL )
173 189 : return "";
174 : else
175 3 : return pszUnitType;
176 : }
177 :
178 : /************************************************************************/
179 : /* SetUnitType() */
180 : /************************************************************************/
181 :
182 287 : CPLErr VRTRasterBand::SetUnitType( const char *pszNewValue )
183 :
184 : {
185 287 : ((VRTDataset *) poDS)->SetNeedsFlush();
186 :
187 287 : CPLFree( pszUnitType );
188 :
189 287 : if( pszNewValue == NULL )
190 286 : pszUnitType = NULL;
191 : else
192 1 : pszUnitType = CPLStrdup(pszNewValue);
193 :
194 287 : return CE_None;
195 : }
196 :
197 : /************************************************************************/
198 : /* GetOffset() */
199 : /************************************************************************/
200 :
201 192 : double VRTRasterBand::GetOffset( int *pbSuccess )
202 :
203 : {
204 192 : if( pbSuccess != NULL )
205 187 : *pbSuccess = TRUE;
206 :
207 192 : return dfOffset;
208 : }
209 :
210 : /************************************************************************/
211 : /* SetOffset() */
212 : /************************************************************************/
213 :
214 356 : CPLErr VRTRasterBand::SetOffset( double dfNewOffset )
215 :
216 : {
217 356 : ((VRTDataset *) poDS)->SetNeedsFlush();
218 :
219 356 : dfOffset = dfNewOffset;
220 356 : return CE_None;
221 : }
222 :
223 : /************************************************************************/
224 : /* GetScale() */
225 : /************************************************************************/
226 :
227 192 : double VRTRasterBand::GetScale( int *pbSuccess )
228 :
229 : {
230 192 : if( pbSuccess != NULL )
231 98 : *pbSuccess = TRUE;
232 :
233 192 : return dfScale;
234 : }
235 :
236 : /************************************************************************/
237 : /* SetScale() */
238 : /************************************************************************/
239 :
240 356 : CPLErr VRTRasterBand::SetScale( double dfNewScale )
241 :
242 : {
243 356 : ((VRTDataset *) poDS)->SetNeedsFlush();
244 :
245 356 : dfScale = dfNewScale;
246 356 : return CE_None;
247 : }
248 :
249 : /************************************************************************/
250 : /* GetCategoryNames() */
251 : /************************************************************************/
252 :
253 10 : char **VRTRasterBand::GetCategoryNames()
254 :
255 : {
256 10 : return papszCategoryNames;
257 : }
258 :
259 : /************************************************************************/
260 : /* SetCategoryNames() */
261 : /************************************************************************/
262 :
263 70 : CPLErr VRTRasterBand::SetCategoryNames( char ** papszNewNames )
264 :
265 : {
266 70 : ((VRTDataset *) poDS)->SetNeedsFlush();
267 :
268 70 : CSLDestroy( papszCategoryNames );
269 70 : papszCategoryNames = CSLDuplicate( papszNewNames );
270 :
271 70 : return CE_None;
272 : }
273 :
274 : /************************************************************************/
275 : /* XMLInit() */
276 : /************************************************************************/
277 :
278 : CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree,
279 286 : const char *pszVRTPath )
280 :
281 : {
282 : /* -------------------------------------------------------------------- */
283 : /* Validate a bit. */
284 : /* -------------------------------------------------------------------- */
285 286 : if( psTree == NULL || psTree->eType != CXT_Element
286 : || !EQUAL(psTree->pszValue,"VRTRasterBand") )
287 : {
288 : CPLError( CE_Failure, CPLE_AppDefined,
289 0 : "Invalid node passed to VRTRasterBand::XMLInit()." );
290 0 : return CE_Failure;
291 : }
292 :
293 : /* -------------------------------------------------------------------- */
294 : /* Set the band if provided as an attribute. */
295 : /* -------------------------------------------------------------------- */
296 286 : if( CPLGetXMLValue( psTree, "band", NULL) != NULL )
297 286 : nBand = atoi(CPLGetXMLValue( psTree, "band", "0"));
298 :
299 : /* -------------------------------------------------------------------- */
300 : /* Set the band if provided as an attribute. */
301 : /* -------------------------------------------------------------------- */
302 286 : const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL);
303 286 : if( pszDataType != NULL )
304 : {
305 286 : eDataType = GDALGetDataTypeByName(pszDataType);
306 : }
307 :
308 : /* -------------------------------------------------------------------- */
309 : /* Apply any band level metadata. */
310 : /* -------------------------------------------------------------------- */
311 286 : oMDMD.XMLInit( psTree, TRUE );
312 :
313 : /* -------------------------------------------------------------------- */
314 : /* Collect various other items of metadata. */
315 : /* -------------------------------------------------------------------- */
316 286 : SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
317 :
318 286 : if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
319 44 : SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
320 :
321 286 : if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL )
322 0 : bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) );
323 :
324 286 : SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) );
325 :
326 286 : SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
327 286 : SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );
328 :
329 286 : if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
330 : {
331 165 : const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
332 165 : SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp));
333 : }
334 :
335 : /* -------------------------------------------------------------------- */
336 : /* Category names. */
337 : /* -------------------------------------------------------------------- */
338 286 : if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
339 : {
340 : CPLXMLNode *psEntry;
341 :
342 0 : CSLDestroy( papszCategoryNames );
343 0 : papszCategoryNames = NULL;
344 :
345 0 : for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
346 : psEntry != NULL; psEntry = psEntry->psNext )
347 : {
348 0 : if( psEntry->eType != CXT_Element
349 : || !EQUAL(psEntry->pszValue,"Category")
350 : || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
351 0 : continue;
352 :
353 : papszCategoryNames = CSLAddString( papszCategoryNames,
354 0 : (psEntry->psChild) ? psEntry->psChild->pszValue : "");
355 : }
356 : }
357 :
358 : /* -------------------------------------------------------------------- */
359 : /* Collect a color table. */
360 : /* -------------------------------------------------------------------- */
361 286 : if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
362 : {
363 : CPLXMLNode *psEntry;
364 3 : GDALColorTable oTable;
365 3 : int iEntry = 0;
366 :
367 517 : for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
368 : psEntry != NULL; psEntry = psEntry->psNext )
369 : {
370 : GDALColorEntry sCEntry;
371 :
372 514 : sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
373 514 : sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
374 514 : sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
375 514 : sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));
376 :
377 514 : oTable.SetColorEntry( iEntry++, &sCEntry );
378 : }
379 :
380 3 : SetColorTable( &oTable );
381 : }
382 :
383 : /* -------------------------------------------------------------------- */
384 : /* Histograms */
385 : /* -------------------------------------------------------------------- */
386 286 : CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
387 286 : if( psHist != NULL )
388 : {
389 0 : CPLXMLNode *psNext = psHist->psNext;
390 0 : psHist->psNext = NULL;
391 :
392 0 : psSavedHistograms = CPLCloneXMLTree( psHist );
393 0 : psHist->psNext = psNext;
394 : }
395 :
396 : /* ==================================================================== */
397 : /* Overviews */
398 : /* ==================================================================== */
399 : CPLXMLNode *psNode;
400 :
401 1448 : for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext )
402 : {
403 1162 : if( psNode->eType != CXT_Element
404 : || !EQUAL(psNode->pszValue,"Overview") )
405 1159 : continue;
406 :
407 : /* -------------------------------------------------------------------- */
408 : /* Prepare filename. */
409 : /* -------------------------------------------------------------------- */
410 3 : char *pszSrcDSName = NULL;
411 3 : CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename");
412 : const char *pszFilename =
413 3 : psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL;
414 :
415 3 : if( pszFilename == NULL )
416 : {
417 : CPLError( CE_Warning, CPLE_AppDefined,
418 0 : "Missing <SourceFilename> element in Overview." );
419 0 : return CE_Failure;
420 : }
421 :
422 3 : if( pszVRTPath != NULL
423 : && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) )
424 : {
425 : pszSrcDSName = CPLStrdup(
426 0 : CPLProjectRelativeFilename( pszVRTPath, pszFilename ) );
427 : }
428 : else
429 3 : pszSrcDSName = CPLStrdup( pszFilename );
430 :
431 : /* -------------------------------------------------------------------- */
432 : /* Get the raster band. */
433 : /* -------------------------------------------------------------------- */
434 3 : int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1"));
435 :
436 3 : apoOverviews.resize( apoOverviews.size() + 1 );
437 6 : apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName;
438 3 : apoOverviews[apoOverviews.size()-1].nBand = nSrcBand;
439 :
440 3 : CPLFree( pszSrcDSName );
441 : }
442 :
443 286 : return CE_None;
444 : }
445 :
446 : /************************************************************************/
447 : /* SerializeToXML() */
448 : /************************************************************************/
449 :
450 117 : CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath )
451 :
452 : {
453 : CPLXMLNode *psTree;
454 :
455 117 : psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" );
456 :
457 : /* -------------------------------------------------------------------- */
458 : /* Various kinds of metadata. */
459 : /* -------------------------------------------------------------------- */
460 : CPLXMLNode *psMD;
461 :
462 : CPLSetXMLValue( psTree, "#dataType",
463 117 : GDALGetDataTypeName( GetRasterDataType() ) );
464 :
465 117 : if( nBand > 0 )
466 117 : CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) );
467 :
468 117 : psMD = oMDMD.Serialize();
469 117 : if( psMD != NULL )
470 31 : CPLAddXMLChild( psTree, psMD );
471 :
472 117 : if( strlen(GetDescription()) > 0 )
473 0 : CPLSetXMLValue( psTree, "Description", GetDescription() );
474 :
475 117 : if( bNoDataValueSet )
476 : {
477 4 : if (CPLIsNan(dfNoDataValue))
478 0 : CPLSetXMLValue( psTree, "NoDataValue", "nan");
479 : else
480 : CPLSetXMLValue( psTree, "NoDataValue",
481 4 : CPLSPrintf( "%.14E", dfNoDataValue ) );
482 : }
483 :
484 117 : if( bHideNoDataValue )
485 : CPLSetXMLValue( psTree, "HideNoDataValue",
486 0 : CPLSPrintf( "%d", bHideNoDataValue ) );
487 :
488 117 : if( pszUnitType != NULL )
489 0 : CPLSetXMLValue( psTree, "UnitType", pszUnitType );
490 :
491 117 : if( dfOffset != 0.0 )
492 : CPLSetXMLValue( psTree, "Offset",
493 0 : CPLSPrintf( "%.16g", dfOffset ) );
494 :
495 117 : if( dfScale != 1.0 )
496 : CPLSetXMLValue( psTree, "Scale",
497 0 : CPLSPrintf( "%.16g", dfScale ) );
498 :
499 117 : if( eColorInterp != GCI_Undefined )
500 : CPLSetXMLValue( psTree, "ColorInterp",
501 44 : GDALGetColorInterpretationName( eColorInterp ) );
502 :
503 : /* -------------------------------------------------------------------- */
504 : /* Category names. */
505 : /* -------------------------------------------------------------------- */
506 117 : if( papszCategoryNames != NULL )
507 : {
508 : CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
509 0 : "CategoryNames" );
510 :
511 0 : for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ )
512 : {
513 : CPLCreateXMLElementAndValue( psCT_XML, "Category",
514 0 : papszCategoryNames[iEntry] );
515 : }
516 : }
517 :
518 : /* -------------------------------------------------------------------- */
519 : /* Histograms. */
520 : /* -------------------------------------------------------------------- */
521 117 : if( psSavedHistograms != NULL )
522 0 : CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) );
523 :
524 : /* -------------------------------------------------------------------- */
525 : /* Color Table. */
526 : /* -------------------------------------------------------------------- */
527 117 : if( poColorTable != NULL )
528 : {
529 : CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
530 2 : "ColorTable" );
531 :
532 260 : for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount();
533 : iEntry++ )
534 : {
535 : GDALColorEntry sEntry;
536 : CPLXMLNode *psEntry_XML = CPLCreateXMLNode( psCT_XML, CXT_Element,
537 258 : "Entry" );
538 :
539 258 : poColorTable->GetColorEntryAsRGB( iEntry, &sEntry );
540 :
541 258 : CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) );
542 258 : CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) );
543 258 : CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) );
544 258 : CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) );
545 : }
546 : }
547 :
548 117 : return psTree;
549 : }
550 :
551 : /************************************************************************/
552 : /* SetNoDataValue() */
553 : /************************************************************************/
554 :
555 55 : CPLErr VRTRasterBand::SetNoDataValue( double dfNewValue )
556 :
557 : {
558 55 : bNoDataValueSet = TRUE;
559 55 : dfNoDataValue = dfNewValue;
560 :
561 55 : ((VRTDataset *)poDS)->SetNeedsFlush();
562 :
563 55 : return CE_None;
564 : }
565 :
566 : /************************************************************************/
567 : /* GetNoDataValue() */
568 : /************************************************************************/
569 :
570 336 : double VRTRasterBand::GetNoDataValue( int *pbSuccess )
571 :
572 : {
573 336 : if( pbSuccess )
574 306 : *pbSuccess = bNoDataValueSet && !bHideNoDataValue;
575 :
576 336 : return dfNoDataValue;
577 : }
578 :
579 : /************************************************************************/
580 : /* SetColorTable() */
581 : /************************************************************************/
582 :
583 79 : CPLErr VRTRasterBand::SetColorTable( GDALColorTable *poTableIn )
584 :
585 : {
586 79 : if( poColorTable != NULL )
587 : {
588 0 : delete poColorTable;
589 0 : poColorTable = NULL;
590 : }
591 :
592 79 : if( poTableIn )
593 : {
594 10 : poColorTable = poTableIn->Clone();
595 10 : eColorInterp = GCI_PaletteIndex;
596 : }
597 :
598 79 : ((VRTDataset *)poDS)->SetNeedsFlush();
599 :
600 79 : return CE_None;
601 : }
602 :
603 : /************************************************************************/
604 : /* GetColorTable() */
605 : /************************************************************************/
606 :
607 251 : GDALColorTable *VRTRasterBand::GetColorTable()
608 :
609 : {
610 251 : return poColorTable;
611 : }
612 :
613 : /************************************************************************/
614 : /* SetColorInterpretation() */
615 : /************************************************************************/
616 :
617 275 : CPLErr VRTRasterBand::SetColorInterpretation( GDALColorInterp eInterpIn )
618 :
619 : {
620 275 : ((VRTDataset *)poDS)->SetNeedsFlush();
621 :
622 275 : eColorInterp = eInterpIn;
623 :
624 275 : return CE_None;
625 : }
626 :
627 : /************************************************************************/
628 : /* GetColorInterpretation() */
629 : /************************************************************************/
630 :
631 233 : GDALColorInterp VRTRasterBand::GetColorInterpretation()
632 :
633 : {
634 233 : return eColorInterp;
635 : }
636 :
637 : /************************************************************************/
638 : /* GetHistogram() */
639 : /************************************************************************/
640 :
641 : CPLErr VRTRasterBand::GetHistogram( double dfMin, double dfMax,
642 : int nBuckets, int * panHistogram,
643 : int bIncludeOutOfRange, int bApproxOK,
644 : GDALProgressFunc pfnProgress,
645 0 : void *pProgressData )
646 :
647 : {
648 : /* -------------------------------------------------------------------- */
649 : /* Check if we have a matching histogram. */
650 : /* -------------------------------------------------------------------- */
651 : CPLXMLNode *psHistItem;
652 :
653 : psHistItem = PamFindMatchingHistogram( psSavedHistograms,
654 : dfMin, dfMax, nBuckets,
655 0 : bIncludeOutOfRange, bApproxOK );
656 0 : if( psHistItem != NULL )
657 : {
658 0 : int *panTempHist = NULL;
659 :
660 0 : if( PamParseHistogram( psHistItem, &dfMin, &dfMax, &nBuckets,
661 : &panTempHist,
662 : &bIncludeOutOfRange, &bApproxOK ) )
663 : {
664 0 : memcpy( panHistogram, panTempHist, sizeof(int) * nBuckets );
665 0 : CPLFree( panTempHist );
666 0 : return CE_None;
667 : }
668 : }
669 :
670 : /* -------------------------------------------------------------------- */
671 : /* We don't have an existing histogram matching the request, so */
672 : /* generate one manually. */
673 : /* -------------------------------------------------------------------- */
674 : CPLErr eErr;
675 :
676 : eErr = GDALRasterBand::GetHistogram( dfMin, dfMax,
677 : nBuckets, panHistogram,
678 : bIncludeOutOfRange, bApproxOK,
679 0 : pfnProgress, pProgressData );
680 :
681 : /* -------------------------------------------------------------------- */
682 : /* Save an XML description of this histogram. */
683 : /* -------------------------------------------------------------------- */
684 0 : if( eErr == CE_None )
685 : {
686 : CPLXMLNode *psXMLHist;
687 :
688 : psXMLHist = PamHistogramToXMLTree( dfMin, dfMax, nBuckets,
689 : panHistogram,
690 0 : bIncludeOutOfRange, bApproxOK );
691 0 : if( psXMLHist != NULL )
692 : {
693 0 : ((VRTDataset *) poDS)->SetNeedsFlush();
694 :
695 0 : if( psSavedHistograms == NULL )
696 : psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
697 0 : "Histograms" );
698 :
699 0 : CPLAddXMLChild( psSavedHistograms, psXMLHist );
700 : }
701 : }
702 :
703 0 : return eErr;
704 : }
705 :
706 : /************************************************************************/
707 : /* SetDefaultHistogram() */
708 : /************************************************************************/
709 :
710 : CPLErr VRTRasterBand::SetDefaultHistogram( double dfMin, double dfMax,
711 0 : int nBuckets, int *panHistogram)
712 :
713 : {
714 : CPLXMLNode *psNode;
715 :
716 : /* -------------------------------------------------------------------- */
717 : /* Do we have a matching histogram we should replace? */
718 : /* -------------------------------------------------------------------- */
719 : psNode = PamFindMatchingHistogram( psSavedHistograms,
720 : dfMin, dfMax, nBuckets,
721 0 : TRUE, TRUE );
722 0 : if( psNode != NULL )
723 : {
724 : /* blow this one away */
725 0 : CPLRemoveXMLChild( psSavedHistograms, psNode );
726 0 : CPLDestroyXMLNode( psNode );
727 : }
728 :
729 : /* -------------------------------------------------------------------- */
730 : /* Translate into a histogram XML tree. */
731 : /* -------------------------------------------------------------------- */
732 : CPLXMLNode *psHistItem;
733 :
734 : psHistItem = PamHistogramToXMLTree( dfMin, dfMax, nBuckets,
735 0 : panHistogram, TRUE, FALSE );
736 :
737 : /* -------------------------------------------------------------------- */
738 : /* Insert our new default histogram at the front of the */
739 : /* histogram list so that it will be the default histogram. */
740 : /* -------------------------------------------------------------------- */
741 0 : ((VRTDataset *) poDS)->SetNeedsFlush();
742 :
743 0 : if( psSavedHistograms == NULL )
744 : psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
745 0 : "Histograms" );
746 :
747 0 : psHistItem->psNext = psSavedHistograms->psChild;
748 0 : psSavedHistograms->psChild = psHistItem;
749 :
750 0 : return CE_None;
751 : }
752 :
753 : /************************************************************************/
754 : /* GetDefaultHistogram() */
755 : /************************************************************************/
756 :
757 : CPLErr
758 : VRTRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax,
759 : int *pnBuckets, int **ppanHistogram,
760 : int bForce,
761 : GDALProgressFunc pfnProgress,
762 0 : void *pProgressData )
763 :
764 : {
765 0 : if( psSavedHistograms != NULL )
766 : {
767 : CPLXMLNode *psXMLHist;
768 :
769 0 : for( psXMLHist = psSavedHistograms->psChild;
770 : psXMLHist != NULL; psXMLHist = psXMLHist->psNext )
771 : {
772 : int bApprox, bIncludeOutOfRange;
773 :
774 0 : if( psXMLHist->eType != CXT_Element
775 : || !EQUAL(psXMLHist->pszValue,"HistItem") )
776 : continue;
777 :
778 0 : if( PamParseHistogram( psXMLHist, pdfMin, pdfMax, pnBuckets,
779 : ppanHistogram, &bIncludeOutOfRange,
780 : &bApprox ) )
781 0 : return CE_None;
782 : else
783 0 : return CE_Failure;
784 : }
785 : }
786 :
787 : return GDALRasterBand::GetDefaultHistogram( pdfMin, pdfMax, pnBuckets,
788 : ppanHistogram, bForce,
789 0 : pfnProgress,pProgressData);
790 : }
791 :
792 : /************************************************************************/
793 : /* GetFileList() */
794 : /************************************************************************/
795 :
796 : void VRTRasterBand::GetFileList(char*** ppapszFileList, int *pnSize,
797 4 : int *pnMaxSize, CPLHashSet* hSetFiles)
798 : {
799 4 : for( unsigned int iOver = 0; iOver < apoOverviews.size(); iOver++ )
800 : {
801 0 : CPLString &osFilename = apoOverviews[iOver].osFilename;
802 :
803 : /* -------------------------------------------------------------------- */
804 : /* Is the filename even a real filesystem object? */
805 : /* -------------------------------------------------------------------- */
806 : VSIStatBufL sStat;
807 0 : if( VSIStatL( osFilename, &sStat ) != 0 )
808 0 : return;
809 :
810 : /* -------------------------------------------------------------------- */
811 : /* Is it already in the list ? */
812 : /* -------------------------------------------------------------------- */
813 0 : if( CPLHashSetLookup(hSetFiles, osFilename) != NULL )
814 0 : return;
815 :
816 : /* -------------------------------------------------------------------- */
817 : /* Grow array if necessary */
818 : /* -------------------------------------------------------------------- */
819 0 : if (*pnSize + 1 >= *pnMaxSize)
820 : {
821 0 : *pnMaxSize = 2 + 2 * (*pnMaxSize);
822 : *ppapszFileList = (char **) CPLRealloc(
823 0 : *ppapszFileList, sizeof(char*) * (*pnMaxSize) );
824 : }
825 :
826 : /* -------------------------------------------------------------------- */
827 : /* Add the string to the list */
828 : /* -------------------------------------------------------------------- */
829 0 : (*ppapszFileList)[*pnSize] = CPLStrdup(osFilename);
830 0 : (*ppapszFileList)[(*pnSize + 1)] = NULL;
831 0 : CPLHashSetInsert(hSetFiles, (*ppapszFileList)[*pnSize]);
832 :
833 0 : (*pnSize) ++;
834 : }
835 : }
836 :
837 : /************************************************************************/
838 : /* GetOverviewCount() */
839 : /************************************************************************/
840 :
841 99 : int VRTRasterBand::GetOverviewCount()
842 :
843 : {
844 99 : if( apoOverviews.size() > 0 )
845 4 : return apoOverviews.size();
846 : else
847 95 : return GDALRasterBand::GetOverviewCount();
848 : }
849 :
850 : /************************************************************************/
851 : /* GetOverview() */
852 : /************************************************************************/
853 :
854 36 : GDALRasterBand *VRTRasterBand::GetOverview( int iOverview )
855 :
856 : {
857 36 : if( apoOverviews.size() > 0 )
858 : {
859 2 : if( iOverview < 0 || iOverview >= (int) apoOverviews.size() )
860 0 : return NULL;
861 :
862 2 : if( apoOverviews[iOverview].poBand == NULL
863 : && !apoOverviews[iOverview].bTriedToOpen )
864 : {
865 2 : apoOverviews[iOverview].bTriedToOpen = TRUE;
866 :
867 : GDALDataset *poSrcDS = (GDALDataset *)
868 2 : GDALOpenShared( apoOverviews[iOverview].osFilename, GA_ReadOnly );
869 :
870 2 : if( poSrcDS == NULL )
871 0 : return NULL;
872 :
873 : apoOverviews[iOverview].poBand = poSrcDS->GetRasterBand(
874 2 : apoOverviews[iOverview].nBand );
875 :
876 2 : if (apoOverviews[iOverview].poBand == NULL)
877 : {
878 0 : GDALClose( (GDALDatasetH)poSrcDS );
879 : }
880 : }
881 :
882 2 : return apoOverviews[iOverview].poBand;
883 : }
884 : else
885 34 : return GDALRasterBand::GetOverview( iOverview );
886 : }
887 :
888 : /************************************************************************/
889 : /* SetDescription() */
890 : /************************************************************************/
891 :
892 286 : void VRTRasterBand::SetDescription(const char* pszDescription)
893 :
894 : {
895 286 : ((VRTDataset *)poDS)->SetNeedsFlush();
896 :
897 286 : GDALRasterBand::SetDescription(pszDescription);
898 286 : }
|