Проблема линковки с GDAL

Ответить
wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Проблема линковки с GDAL

Сообщение wowka1319 » 07 фев 2014, 12:15

Использую Qt Creator + MinGW 4.4.0 с GDAL 1.10.1 (собранный VC++ 2005).
Связка работает, проверял на этом примере с сайта:

Код: Выделить всё

#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()

int main()
{
GDALDataset *poDataset;

GDALAllRegister();

poDataset = (GDALDataset *) GDALOpen( "C:/TEST.tiff", GA_ReadOnly );
if( poDataset == NULL )
{
std::cout << "FAIL\n";
}
else
{
std::cout << "OK\n";
}
return 0;
}


При этом к линкеру я добавляю библиотеку "gdal_i", и все собирается. Но вот с этим кодом (ниже) линкер ругается, что не может найти реализации некоторых методов (перечислены на рисунке).

Код: Выделить всё

#define VECTOR
#define RASTER

#define APPROX
#define APRROX_MAXERROR 0.125

#define MULTI

#include "cpl_conv.h" // for CPLMalloc()
#include "gdal_priv.h"
#include "ogrsf_frmts.h"
#include "ogr_api.h"
#include "gdalwarper.h"

//производный класс для перепроецирования фигуры обрезки
class CutlineTransformer : public OGRCoordinateTransformation
{
public:

void *hSrcImageTransformer;

virtual OGRSpatialReference *GetSourceCS() { return NULL; }
virtual OGRSpatialReference *GetTargetCS() { return NULL; }

virtual int Transform( int nCount,
double *x, double *y, double *z = NULL ) {
int nResult;

int *pabSuccess = (int *) CPLCalloc(sizeof(int),nCount);
nResult = TransformEx( nCount, x, y, z, pabSuccess );
CPLFree( pabSuccess );

return nResult;
}

virtual int TransformEx( int nCount,
double *x, double *y, double *z = NULL,
int *pabSuccess = NULL ) {
return GDALGenImgProjTransform( hSrcImageTransformer, TRUE,
nCount, x, y, z, pabSuccess );
}
};

int main(int argc, char **argv)
{
//настроим переменные окружения GDAL
CPLSetConfigOption( "GDAL_FILENAME_IS_UTF8", "NO" );
CPLSetConfigOption( "GDAL_DATA", "D:/work/gis-lab/conf/files/gdal-1.9.2/gdal_data" );
CPLSetConfigOption( "CPL_DEBUG", "ON" );
CPLSetConfigOption( "CPL_TIMESTAMP", "ON" );
CPLSetConfigOption( "CPL_LOG_ERRORS", "ON" );

//создадим выходную СК
OGRSpatialReference oDstSpaRef(SRS_WKT_WGS84);
OGRErr eErr = oDstSpaRef.SetUTM(37, 1);

//создадим обрезающую геометрию
double dfPM = oDstSpaRef.GetProjParm("central_meridian");
OGRLinearRing ring;
double dfWidth = 35;
ring.addPoint(dfPM - dfWidth, -89);
ring.addPoint(dfPM - dfWidth, 89);
ring.addPoint(dfPM + dfWidth, 89);
ring.addPoint(dfPM + dfWidth, -89);
ring.closeRings();

OGRPolygon* pCutPoly = new OGRPolygon();
pCutPoly->addRing(&ring);
pCutPoly->flattenTo2D();
pCutPoly->assignSpatialReference(new OGRSpatialReference(SRS_WKT_WGS84));
pCutPoly->segmentize(1);

OGRGeometry* pCutGeom = static_cast<OGRGeometry*>(pCutPoly);

//определим выходной охват
OGRGeometry* pCutGeomDst = pCutGeom->clone();
pCutGeomDst->transformTo(&oDstSpaRef);
OGREnvelope DstEnv;
pCutGeomDst->getEnvelope(&DstEnv);

#ifdef RASTER
//загрузка драйверов поддержки растровых форматов
GDALAllRegister();

//открытие рабочего набора
GDALDataset *poSrcDataset = (GDALDataset *) GDALOpen( "/vsizip/D:/work/gis-lab/conf/files/data/TrueMarble.4km.10800x5400.tif.zip/TrueMarble.4km.10800x5400.tif", GA_ReadOnly );
if( NULL == poSrcDataset )
{
const char* err = CPLGetLastErrorMsg();
printf( "Open failed.%s\n", err );
exit( 1 );
}

//получаем СК из файла
OGRSpatialReference SrcSpaRef( poSrcDataset->GetProjectionRef() );
char* pszSpaRefDef(NULL);
if( SrcSpaRef.exportToPrettyWkt(&pszSpaRefDef) == OGRERR_NONE)
{
printf(pszSpaRefDef);
printf("\n");
CPLFree( pszSpaRefDef );
}

char **papszTO = NULL;

if( oDstSpaRef.exportToWkt(&pszSpaRefDef) == OGRERR_NONE)
{
papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSpaRefDef );
CPLFree( pszSpaRefDef );
}

//создание выходного растра
GDALDriver* poDriver = poSrcDataset->GetDriver();
GDALRasterBand *poGDALRasterBand = poSrcDataset->GetRasterBand(1);

if(NULL == poGDALRasterBand)
{
printf( "Band get failed\n" );
exit( 1 );
}
GDALDataType eDT = poGDALRasterBand->GetRasterDataType();

CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" );
void* hTransformArg = GDALCreateGenImgProjTransformer2( poSrcDataset, NULL, papszTO );
GDALTransformerInfo* psInfo = (GDALTransformerInfo*)hTransformArg;

double adfThisGeoTransform[6];
double adfExtent[4];
int nThisPixels, nThisLines;

//оцениваемы размеры выходного файла
if( GDALSuggestedWarpOutput2( poSrcDataset, psInfo->pfnTransform, hTransformArg, adfThisGeoTransform, &nThisPixels, &nThisLines, adfExtent, 0 ) != CE_None )
{
printf( "Suggest Output failed\n" );
exit( 1 );
}

//корректируем размер согласно обрезающей фигуры
adfThisGeoTransform[0] = DstEnv.MinX;
adfThisGeoTransform[3] = DstEnv.MaxY;

int nPixels = (int) ((DstEnv.MaxX - DstEnv.MinX) / adfThisGeoTransform[1] + 0.5);
int nLines = (int) ((DstEnv.MaxY - DstEnv.MinY) / -adfThisGeoTransform[5] + 0.5);

GDALDataset *poDstDataset = poDriver->Create("D:/work/gis-lab/conf/files/data/test.tif", nPixels, nLines, poSrcDataset->GetRasterCount(), eDT, NULL );
if( NULL == poDstDataset )
{
printf( "Create Output failed\n" );
exit( 1 );
}

GDALSetGenImgProjTransformerDstGeoTransform( hTransformArg, adfThisGeoTransform);

char* dstSrs;
oDstSpaRef.exportToWkt(&dstSrs);
poDstDataset->SetProjection( dstSrs );
poDstDataset->SetGeoTransform( adfThisGeoTransform );

#ifdef APPROX
hTransformArg = GDALCreateApproxTransformer( GDALGenImgProjTransform, hTransformArg, APRROX_MAXERROR);
GDALTransformerFunc pfnTransformer = GDALApproxTransform;
#else //APPROX
GDALTransformerFunc pfnTransformer = GDALGenImgProjTransform;
#endif //APPROX

//подготовка обрезающей фигуры
papszTO = CSLSetNameValue( papszTO, "INSERT_CENTER_LONG", "FALSE" );

CutlineTransformer oTransformer;
oTransformer.hSrcImageTransformer = GDALCreateGenImgProjTransformer2( poSrcDataset, NULL, papszTO );

pCutGeomDst->transform((OGRCoordinateTransformation*)&oTransformer);
char* pszWKT = NULL;
if(pCutGeomDst->exportToWkt(&pszWKT) != OGRERR_NONE )
{
const char* err = CPLGetLastErrorMsg();
printf( "Open failed.%s\n", err );
exit( 1 );
}


//создание и настройка Warp
GDALWarpOptions *psWO = GDALCreateWarpOptions();
psWO->papszWarpOptions = CSLSetNameValue(psWO->papszWarpOptions, "INIT_DEST", "0");

psWO->papszWarpOptions = CSLSetNameValue( psWO->papszWarpOptions, "CUTLINE", pszWKT );
CPLFree( pszWKT );

psWO->eWorkingDataType = eDT;
psWO->eResampleAlg = GRA_Bilinear;

psWO->hSrcDS = poSrcDataset;
psWO->hDstDS = poDstDataset;

psWO->pfnTransformer = pfnTransformer;
psWO->pTransformerArg = hTransformArg;

psWO->pfnProgress = GDALTermProgress;
psWO->nBandCount = poSrcDataset->GetRasterCount();

psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));

for(int i = 0; i < psWO->nBandCount; ++i )
{
psWO->panSrcBands = i+1;
psWO->panDstBands = i+1;
}

//выполнение Warp
GDALWarpOperation oWO;
if( oWO.Initialize( psWO ) == CE_None )
{
#ifdef MULTI
if( oWO.ChunkAndWarpMulti( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None)
#else //MULTI
if( oWO.ChunkAndWarpImage( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None)
#endif //MULTI
{
const char* err = CPLGetLastErrorMsg();
printf( "Warp failed.%s\n", err );
exit( 1 );
}
}

GDALDestroyWarpOptions( psWO );
CSLDestroy( papszTO );

//выгрузка драйверов поддержки растровых форматов
GDALDestroyDriverManager();
#endif //RASTER

#ifdef VECTOR
//загрузка драйверов поддержки векторных форматов
OGRRegisterAll();

//выведем список драйверов которые поддерживает GDAL
for(size_t i = 0; i < OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount(); ++i)
{
OGRSFDriver *pDrv = OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i);
const char* pszDrvName = pDrv->GetName();
printf(pszDrvName);
printf("\n");
}


//откроем тестовый векторный файл
OGRDataSource *poDS = OGRSFDriverRegistrar::Open( "/vsizip/D:/work/gis-lab/conf/files/data/ne_50m_admin_0_countries_lakes.zip/ne_50m_admin_0_countries_lakes.shp", FALSE );
if( NULL == poDS )
{
const char* err = CPLGetLastErrorMsg();
printf( "Open failed.%s\n", err );
exit( 1 );
}

OGRLayer *pSrcLayer = poDS->GetLayer(0);
if( NULL == pSrcLayer )
{
const char* err = CPLGetLastErrorMsg();
printf( "Open failed.%s\n", err );
exit( 1 );
}

//выведем текущую проекцию
OGRSpatialReference* pSrcSpaRef = pSrcLayer->GetSpatialRef();
if( NULL == pSrcSpaRef )
{
const char* err = CPLGetLastErrorMsg();
printf( "Open failed.%s\n", err );
exit( 1 );
}

char* pSpaRefDef(NULL);
if( pSrcSpaRef->exportToPrettyWkt(&pSpaRefDef) == OGRERR_NONE)
{
printf(pSpaRefDef);
CPLFree( pSpaRefDef );
}

//создание выходного файла

OGRSFDriver *poVecDriver = poDS->GetDriver();
if( NULL == poVecDriver )
{
printf( "Driver not available.\n");
exit( 1 );
}

//создаем выходной OGRDataSource
OGRDataSource *poDstDS = poVecDriver->CreateDataSource( "D:/work/gis-lab/conf/files/data/test.shp", NULL );
if( NULL == poDstDS )
{
printf( "Creation of output file failed.\n" );
exit( 1 );
}

//создаем выходной OGRLayer
OGRLayer *poDstLayer = poDstDS->CreateLayer( "test", oDstSpaRef.Clone(), pSrcLayer->GetGeomType(), NULL );
if( poDstLayer == NULL )
{
printf( "Layer creation failed.\n" );
exit( 1 );
}

//добавляем поля
OGRFeatureDefn* poFields = pSrcLayer->GetLayerDefn();
for(size_t i = 0; i < poFields->GetFieldCount(); ++i)
{
OGRFieldDefn *pField = poFields->GetFieldDefn(i);
if( poDstLayer->CreateField( pField ) != OGRERR_NONE )
{
printf("Error create the output layer '%s'! OGR error: %s", CPLGetLastErrorMsg());
exit( 1 );
}
}

//обрезаем и перепроецируем
OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pSrcSpaRef, &oDstSpaRef);
if(poCT)
{
OGRFeature* pSrcFeature;
while((pSrcFeature = pSrcLayer->GetNextFeature()) != NULL)
{
OGRGeometry *pSrcGeom = pSrcFeature->GetGeometryRef();
if(pSrcGeom)
{
OGRGeometry* pDstGeom = pSrcGeom->Intersection(pCutGeom);
if(pDstGeom && pDstGeom->transform(poCT) == OGRERR_NONE)
{
OGRFeature *poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
OGRFeatureDefn* pSrcFeatureDefn = pSrcFeature->GetDefnRef();
for(size_t j = 0; j < pSrcFeatureDefn->GetFieldCount(); ++j)
{
poDstFeature->SetField(j, pSrcFeature->GetRawFieldRef(j));
}
poDstFeature->SetGeometryDirectly(pDstGeom);

if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
{
printf( "Failed to create feature in shapefile.\n" );
exit( 1 );
}

OGRFeature::DestroyFeature( poDstFeature );
}
}
}

OCTDestroyCoordinateTransformation(poCT);
}

OGRDataSource::DestroyDataSource( poDS );

OGRDataSource::DestroyDataSource( poDstDS );

//выгрузка драйверов поддержки векторных форматов
OGRCleanupAll();
#endif //VECTOR

return 0;
}


Вопрос: что ему не хватает, какие либы нужно линковать еще?
Вложения
gdal_linker_error.png
Вывод ошибки линкера
gdal_linker_error.png (148.64 КБ) 4109 просмотров
Последний раз редактировалось wowka1319 07 фев 2014, 13:03, всего редактировалось 1 раз.

wowka1319
Участник
Сообщения: 93
Зарегистрирован: 04 дек 2013, 02:14
Репутация: 1

Re: Проблема линковки с GDAL

Сообщение wowka1319 » 07 фев 2014, 13:00

пробовал слинковать со всеми идущими с GDAL/ORG либами:
agg.lib, cairo.lib, cfitsio.lib, fontconfig.lib, freetype239.lib, freetype2411.lib, freexl.lib, freexl_i.lib, fribidi.lib, ftgl.lib, gd.lib, gdal_i.lib, geos.lib, geos_c.lib, giflib.lib, harfbuzz.lib, hdf5.lib, hdf5dll.lib, hdf5_hl.lib, hdfdll.lib, iconv.lib, libcurl_imp.lib, libeay32.lib, libecwj2.lib, libexpat.lib, libfcgi.lib, libjbig.lib, libjpeg.lib, libkmlbase.lib, libkmlconvenience.lib, libkmldom.lib, libkmlengine.lib, libkmlregionator.lib, libkmlxsd.lib, libming.lib, libmysql.lib, libpng.lib, libpq.lib, libpqdll.lib, libsvg-cairo.lib, libsvg.lib, libtiff_i.lib, libxml2.lib, mfhdfdll.lib, minizip.lib, netcdf.lib, openjp2.lib, openjpeg.lib, openjpegstatic.lib, pdflib.lib, pixman-1.lib, poppler.lib, proj.lib, proj_i.lib, spatialite.lib, spatialite_i.lib, sqlite3_i.lib, ssleay32.lib, szip.lib, vld.lib, xdrdll.lib, xerces-c_2.lib, zdll.lib, zlib.lib
но толку 0. Что со всеми, что только с одним gdal_i.lib - один результат.

Может действительно проблема с gdal_i.lib. В таком случает я попрошу кого-нибудь (у кого есть или кто сможет собрать сам) динамическую библиотеку для MinGW "gdal110.dll" (можно старее, но чтоб код выше работал) и статическую для нее "gdal_i.a" (хотя вроде можно без нее).

Ответить

Вернуться в «GDAL/OGR»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 7 гостей