* Create vector contours from raster DEM. * * This algorithm is an implementation of "Marching squares" [1] that will * generate contour vectors for the input raster band on the requested set * of contour levels. The vector contours are written to the passed in OGR * vector layer. Also, a NODATA value may be specified to identify pixels * that should not be considered in contour line genera
| 567 | * @return CE_None on success or CE_Failure if an error occurs. |
| 568 | */ |
| 569 | CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer, |
| 570 | CSLConstList options, GDALProgressFunc pfnProgress, |
| 571 | void *pProgressArg) |
| 572 | { |
| 573 | VALIDATE_POINTER1(hBand, "GDALContourGenerateEx", CE_Failure); |
| 574 | |
| 575 | if (pfnProgress == nullptr) |
| 576 | pfnProgress = GDALDummyProgress; |
| 577 | |
| 578 | double contourInterval = 0.0; |
| 579 | const char *opt = CSLFetchNameValue(options, "LEVEL_INTERVAL"); |
| 580 | if (opt) |
| 581 | { |
| 582 | contourInterval = CPLAtof(opt); |
| 583 | // Written this way to catch NaN as well. |
| 584 | if (!(contourInterval > 0)) |
| 585 | { |
| 586 | CPLError(CE_Failure, CPLE_AppDefined, |
| 587 | "Invalid value for LEVEL_INTERVAL. Should be strictly " |
| 588 | "positive."); |
| 589 | return CE_Failure; |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | double contourBase = 0.0; |
| 594 | opt = CSLFetchNameValue(options, "LEVEL_BASE"); |
| 595 | if (opt) |
| 596 | { |
| 597 | contourBase = CPLAtof(opt); |
| 598 | } |
| 599 | |
| 600 | double expBase = 0.0; |
| 601 | opt = CSLFetchNameValue(options, "LEVEL_EXP_BASE"); |
| 602 | if (opt) |
| 603 | { |
| 604 | expBase = CPLAtof(opt); |
| 605 | } |
| 606 | |
| 607 | std::vector<double> fixedLevels; |
| 608 | opt = CSLFetchNameValue(options, "FIXED_LEVELS"); |
| 609 | if (opt) |
| 610 | { |
| 611 | const CPLStringList aosLevels( |
| 612 | CSLTokenizeStringComplex(opt, ",", FALSE, FALSE)); |
| 613 | fixedLevels.resize(aosLevels.size()); |
| 614 | for (size_t i = 0; i < fixedLevels.size(); i++) |
| 615 | { |
| 616 | // Handle min/max values |
| 617 | if (EQUAL(aosLevels[i], "MIN")) |
| 618 | { |
| 619 | fixedLevels[i] = std::numeric_limits<double>::lowest(); |
| 620 | } |
| 621 | else if (EQUAL(aosLevels[i], "MAX")) |
| 622 | { |
| 623 | fixedLevels[i] = std::numeric_limits<double>::max(); |
| 624 | } |
| 625 | else |
| 626 | { |
no test coverage detected