0

我终于设法为 ios 构建了 gdal。我想开发一个应用程序,它将处理来自 geotiff 文件的高程数据。

构建成功后,我做了一个简单的应用程序来测试静态库,但是我得到了一个奇怪的运行时错误:

图片

我的代码基于 gdallocationinfo 应用程序,如果我在一个简单的命令行项目中使用它就可以工作,但我无法让它在 iOS 项目中工作。

@interface ViewController ()

@end

@implementation ViewController


typedef struct {
    int x;
    int y;
} point;



/************************************************************************/
/*                             SanitizeSRS                              */
/************************************************************************/

char *SanitizeSRS( const char *pszUserInput )

{
OGRSpatialReferenceH hSRS;
char *pszResult = NULL;

CPLErrorReset();

hSRS = OSRNewSpatialReference( NULL );
if( OSRSetFromUserInput( hSRS, pszUserInput ) == OGRERR_NONE )
    OSRExportToWkt( hSRS, &pszResult );
else
{
    CPLError( CE_Failure, CPLE_AppDefined,
             "Translating source or target SRS failed:\n%s",
             pszUserInput );
    exit( 1 );
}

OSRDestroySpatialReference( hSRS );

return pszResult;
}


 /************************************************************************/
 /*                       LocationTransform                              */
/************************************************************************/
// transdorm a given coordinate to pixel/line values



point locationTransform( char* file, char* x, char* y )

{
const char         *pszLocX = NULL, *pszLocY = NULL;
const char         *pszSrcFilename = NULL;
char               *pszSourceSRS = NULL;
std::vector<int>   anBandList;


GDALDatasetH  hDataset;


pszSrcFilename = file;

GDALAllRegister();

hDataset = GDALOpen( pszSrcFilename, GA_ReadOnly );
if( hDataset == NULL )
{
    exit(1);
}

GDALDriverH   hDriver;
double        adfGeoTransform[6];

hDriver = GDALGetDatasetDriver( hDataset );
/*
 printf( "Driver: %s/%s\n",
 GDALGetDriverShortName( hDriver ),
 GDALGetDriverLongName( hDriver ) );
 */
/*
 printf( "Size is %dx%dx%d\n",
 GDALGetRasterXSize( hDataset ),
 GDALGetRasterYSize( hDataset ),
 GDALGetRasterCount( hDataset ) );
 */

if( GDALGetProjectionRef( hDataset ) != NULL )
    // printf( "Projection is `%s'\n", GDALGetProjectionRef( hDataset ) );

    GDALGetGeoTransform( hDataset, adfGeoTransform );


GDALRasterBandH hBand;
int             nBlockXSize, nBlockYSize;
int             bGotMin, bGotMax;
double          adfMinMax[2];

hBand = GDALGetRasterBand( hDataset, 1 );
GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
/*
 printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
 nBlockXSize, nBlockYSize,
 GDALGetDataTypeName(GDALGetRasterDataType(hBand)),
 GDALGetColorInterpretationName(
 GDALGetRasterColorInterpretation(hBand)) );
 */
adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin );
adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax );
if( ! (bGotMin && bGotMax) )
    GDALComputeRasterMinMax( hBand, TRUE, adfMinMax );
/*
 printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
 */
if( GDALGetOverviewCount(hBand) > 0 )
    printf( "Band has %d overviews.\n", GDALGetOverviewCount(hBand));

if( GDALGetRasterColorTable( hBand ) != NULL )
    printf( "Band has a color table with %d entries.\n",
           GDALGetColorEntryCount(
                                  GDALGetRasterColorTable( hBand ) ) );




CPLFree(pszSourceSRS);
pszSourceSRS = CPLStrdup("-geoloc");
pszSourceSRS = SanitizeSRS("WGS84");

pszLocX = x;


pszLocY = y;


/* -------------------------------------------------------------------- */
/*      Open source file.                                               */
/* -------------------------------------------------------------------- */
GDALDatasetH hSrcDS = NULL;

hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
if( hSrcDS == NULL )
    exit( 1 );


/* -------------------------------------------------------------------- */
/*      Turn the location into a pixel and line location.               */
/* -------------------------------------------------------------------- */

double dfGeoX;
double dfGeoY;
CPLString osXML;

dfGeoX = CPLAtof(pszLocX);
dfGeoY = CPLAtof(pszLocY);

int iPixel, iLine;


double  adfInvGeoTransform[6];



GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform );

iPixel = (int) floor(
                     adfInvGeoTransform[0]
                     + adfInvGeoTransform[1] * dfGeoX
                     + adfInvGeoTransform[2] * dfGeoY );
iLine = (int) floor(
                    adfInvGeoTransform[3]
                    + adfInvGeoTransform[4] * dfGeoX
                    + adfInvGeoTransform[5] * dfGeoY );




printf("%i",iPixel);
printf("\n %i", iLine);

point p;
p.x = iPixel;
p.y= iLine;

return p;
}



 /************************************************************************/
 /*                          locationinfo()                              */
 /************************************************************************/

int locationinfo( char* file, char* x, char* y )

{
const char         *pszLocX = NULL, *pszLocY = NULL;
const char         *pszSrcFilename = NULL;
char               *pszSourceSRS = NULL;
std::vector<int>   anBandList;
bool               bAsXML = false, bLIFOnly = false;
bool               bQuiet = false, bValOnly = false;
int                nOverview = -1;

GDALAllRegister();
/*
 argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
 if( argc < 1 )
 exit( -argc );

 /* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
int i;




pszSrcFilename = file;

CPLFree(pszSourceSRS);
pszSourceSRS = CPLStrdup("-geoloc");
pszSourceSRS = SanitizeSRS("WGS84");

pszLocX = x;


pszLocY = y;



if( pszSrcFilename == NULL || (pszLocX != NULL && pszLocY == NULL) )
    return -1;

/* -------------------------------------------------------------------- */
/*      Open source file.                                               */
/* -------------------------------------------------------------------- */
GDALDatasetH hSrcDS = NULL;

hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
if( hSrcDS == NULL )
    exit( 1 );

/* -------------------------------------------------------------------- */
/*      Setup coordinate transformation, if required                    */
/* -------------------------------------------------------------------- */
OGRSpatialReferenceH hSrcSRS = NULL, hTrgSRS = NULL;
OGRCoordinateTransformationH hCT = NULL;
//    if( pszSourceSRS != NULL && !EQUAL(pszSourceSRS,"-geoloc") )
//    {
//
//        hSrcSRS = OSRNewSpatialReference( pszSourceSRS );
//        hTrgSRS = OSRNewSpatialReference( GDALGetProjectionRef( hSrcDS ) );
//
//        hCT = OCTNewCoordinateTransformation( hSrcSRS, hTrgSRS );
//        if( hCT == NULL )
//            exit( 1 );
//    }

/* -------------------------------------------------------------------- */
/*      If no bands were requested, we will query them all.             */
/* -------------------------------------------------------------------- */
if( anBandList.size() == 0 )
{
    for( i = 0; i < GDALGetRasterCount( hSrcDS ); i++ )
        anBandList.push_back( i+1 );
}

/* -------------------------------------------------------------------- */
/*      Turn the location into a pixel and line location.               */
/* -------------------------------------------------------------------- */
int inputAvailable = 1;
double dfGeoX;
double dfGeoY;
CPLString osXML;

if( pszLocX == NULL && pszLocY == NULL )
{
    if (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2)
    {
        inputAvailable = 0;
    }
}
else
{
    dfGeoX = CPLAtof(pszLocX);
    dfGeoY = CPLAtof(pszLocY);
}

while (inputAvailable)
{
    int iPixel, iLine;

    if (hCT)
    {
        if( !OCTTransform( hCT, 1, &dfGeoX, &dfGeoY, NULL ) )
            exit( 1 );
    }

    if( pszSourceSRS != NULL )
    {
        double adfGeoTransform[6], adfInvGeoTransform[6];

        if( GDALGetGeoTransform( hSrcDS, adfGeoTransform ) != CE_None )
            exit( 1 );

        GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform );

        iPixel = (int) floor(
                             adfInvGeoTransform[0]
                             + adfInvGeoTransform[1] * dfGeoX
                             + adfInvGeoTransform[2] * dfGeoY );
        iLine = (int) floor(
                            adfInvGeoTransform[3]
                            + adfInvGeoTransform[4] * dfGeoX
                            + adfInvGeoTransform[5] * dfGeoY );
    }
    else
    {
        iPixel = (int) floor(dfGeoX);
        iLine  = (int) floor(dfGeoY);
    }

    /* -------------------------------------------------------------------- */
    /*      Prepare report.                                                 */
    /* -------------------------------------------------------------------- */
    CPLString osLine;

    if( bAsXML )
    {
        osLine.Printf( "<Report pixel=\"%d\" line=\"%d\">",
                      iPixel, iLine );
        osXML += osLine;
    }
    else if( !bQuiet )
    {
        printf( "Report:\n" );
        printf( "  Location: (%dP,%dL)\n", iPixel, iLine );
    }

    int bPixelReport = TRUE;

    if( iPixel < 0 || iLine < 0
       || iPixel >= GDALGetRasterXSize( hSrcDS )
       || iLine  >= GDALGetRasterYSize( hSrcDS ) )
    {
        if( bAsXML )
            osXML += "<Alert>Location is off this file! No further details to report.</Alert>";
        else if( bValOnly )
            printf("\n");
        else if( !bQuiet )
            printf( "\nLocation is off this file! No further details to report.\n");
        bPixelReport = FALSE;
    }

    /* -------------------------------------------------------------------- */
    /*      Process each band.                                              */
    /* -------------------------------------------------------------------- */
    for( i = 0; bPixelReport && i < (int) anBandList.size(); i++ )
    {
        GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, anBandList[i] );

        int iPixelToQuery = iPixel;
        int iLineToQuery = iLine;

        if (nOverview >= 0 && hBand != NULL)
        {
            GDALRasterBandH hOvrBand = GDALGetOverview(hBand, nOverview);
            if (hOvrBand != NULL)
            {
                int nOvrXSize = GDALGetRasterBandXSize(hOvrBand);
                int nOvrYSize = GDALGetRasterBandYSize(hOvrBand);
                iPixelToQuery = (int)(0.5 + 1.0 * iPixel / GDALGetRasterXSize( hSrcDS ) * nOvrXSize);
                iLineToQuery = (int)(0.5 + 1.0 * iLine / GDALGetRasterYSize( hSrcDS ) * nOvrYSize);
                if (iPixelToQuery >= nOvrXSize)
                    iPixelToQuery = nOvrXSize - 1;
                if (iLineToQuery >= nOvrYSize)
                    iLineToQuery = nOvrYSize - 1;
            }
            else
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Cannot get overview %d of band %d",
                         nOverview + 1, anBandList[i] );
            }
            hBand = hOvrBand;
        }

        if (hBand == NULL)
            continue;

        if( bAsXML )
        {
            osLine.Printf( "<BandReport band=\"%d\">", anBandList[i] );
            osXML += osLine;
        }
        else if( !bQuiet )
        {
            printf( "  Band %d:\n", anBandList[i] );
        }

        /* -------------------------------------------------------------------- */
        /*      Request location info for this location.  It is possible        */
        /*      only the VRT driver actually supports this.                     */
        /* -------------------------------------------------------------------- */
        CPLString osItem;

        osItem.Printf( "Pixel_%d_%d", iPixelToQuery, iLineToQuery );

        const char *pszLI = GDALGetMetadataItem( hBand, osItem, "LocationInfo");

        if( pszLI != NULL )
        {
            if( bAsXML )
                osXML += pszLI;
            else if( !bQuiet )
                printf( "    %s\n", pszLI );
            else if( bLIFOnly )
            {
                /* Extract all files, if any. */

                CPLXMLNode *psRoot = CPLParseXMLString( pszLI );

                if( psRoot != NULL
                   && psRoot->psChild != NULL
                   && psRoot->eType == CXT_Element
                   && EQUAL(psRoot->pszValue,"LocationInfo") )
                {
                    CPLXMLNode *psNode;

                    for( psNode = psRoot->psChild;
                        psNode != NULL;
                        psNode = psNode->psNext )
                    {
                        if( psNode->eType == CXT_Element
                           && EQUAL(psNode->pszValue,"File")
                           && psNode->psChild != NULL )
                        {
                            char* pszUnescaped = CPLUnescapeString(
                                                                   psNode->psChild->pszValue, NULL, CPLES_XML);
                            printf( "%s\n", pszUnescaped );
                            CPLFree(pszUnescaped);
                        }
                    }
                }
                CPLDestroyXMLNode( psRoot );
            }
        }

        /* -------------------------------------------------------------------- */
        /*      Report the pixel value of this band.                            */
        /* -------------------------------------------------------------------- */
        double adfPixel[2];

        if( GDALRasterIO( hBand, GF_Read, iPixelToQuery, iLineToQuery, 1, 1,
                         adfPixel, 1, 1, GDT_CFloat64, 0, 0) == CE_None )
        {
            CPLString osValue;

            if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) )
                osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] );
            else
            {
                printf("test_elotte\n");
                osValue.Printf( "%.15g", adfPixel[0] );
                printf("test_utana\n");
            }



            if( bAsXML )
            {
                osXML += "<Value>";
                osXML += osValue;
                osXML += "</Value>";
            }
            else if( !bQuiet )
                printf( "    Value: %s\n", osValue.c_str() );
            else if( bValOnly )
                printf( "%s\n", osValue.c_str() );

            // Report unscaled if we have scale/offset values.
            int bSuccess;

            double dfOffset = GDALGetRasterOffset( hBand, &bSuccess );
            double dfScale  = GDALGetRasterScale( hBand, &bSuccess );

            if( dfOffset != 0.0 || dfScale != 1.0 )
            {
                adfPixel[0] = adfPixel[0] * dfScale + dfOffset;
                adfPixel[1] = adfPixel[1] * dfScale + dfOffset;

                if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) )
                    osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] );
                else
                    osValue.Printf( "%.15g", adfPixel[0] );

                if( bAsXML )
                {
                    osXML += "<DescaledValue>";
                    osXML += osValue;
                    osXML += "</DescaledValue>";
                }
                else if( !bQuiet )
                    printf( "    Descaled Value: %s\n", osValue.c_str() );
            }
        }

        if( bAsXML )
            osXML += "</BandReport>";
    }

    osXML += "</Report>";

    if( (pszLocX != NULL && pszLocY != NULL)  ||
       (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) )
    {
        inputAvailable = 0;
    }

}

/* -------------------------------------------------------------------- */
/*      Finalize xml report and print.                                  */
/* -------------------------------------------------------------------- */
if( bAsXML )
{
    CPLXMLNode *psRoot;
    char *pszFormattedXML;


    psRoot = CPLParseXMLString( osXML );
    pszFormattedXML = CPLSerializeXMLTree( psRoot );
    CPLDestroyXMLNode( psRoot );

    printf( "%s", pszFormattedXML );
    CPLFree( pszFormattedXML );
}

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
if (hCT) {
    OSRDestroySpatialReference( hSrcSRS );
    OSRDestroySpatialReference( hTrgSRS );
    OCTDestroyCoordinateTransformation( hCT );
}

if (hSrcDS)
    GDALClose(hSrcDS);

GDALDumpOpenDatasets( stderr );
GDALDestroyDriverManager();
CPLFree(pszSourceSRS);

//    CSLDestroy( argv );

return 0;
}

- (void)viewDidLoad
{
[super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

char *pszFilename;

//pszFilename = "/Users/fulopbarna/Desktop/gdal/gdal_test/gdal_test/srtm_42_03.tif";
pszFilename = "/Users/wolwerine/Desktop/IPHONE_DEV/gdal/SRTM/srtm_42_03_crop.tif";

point testPoint;
//    locationTransform(pszFilename, "25.703888899", "45.60055556");
locationinfo(pszFilename, "25.703888899", "45.60055556");
printf("%i    %i",testPoint.x,testPoint.y);


printf("\n\n\n\n");

//locationinfo(pszFilename, "46.8", "26.23333");



}

我尝试在有和没有 64 位支持的情况下构建 gdal,它不需要改变。

任何意见,将不胜感激

4

1 回答 1

0

尝试以下步骤,它会给出一些提示,即释放了哪个对象。

转到编辑方案->“诊断”选项卡,然后单击“启用僵尸对象”

然后转到产品-> 配置文件。并在内存选项卡中选择僵尸。然后单击配置文件按钮。

然后检查崩溃。

于 2013-04-29T11:44:04.970 回答