我终于设法为 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,它不需要改变。
任何意见,将不胜感激