<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>BR: Tutorial da API do GDAL</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- Gerado por Doxygen 1.6.2-20100208 --> <div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="index.html"><span>Página Principal</span></a></li> <li class="current"><a href="pages.html"><span>Páginas relacionadas</span></a></li> </ul> </div> </div> <div class="contents"> <h1><a class="anchor" id="gdal_tutorial_br">Tutorial da API do GDAL </a></h1><h2><a class="anchor" id="gdal_tutorial_open"> Abrindo um Arquivo</a></h2> <p>Antes de abrir um dataset raster suportado por GDAL é necessário registar os drivers, existe um driver para cada formato suportado e o registro dos driver é realizado normalmente com a função GDALAllRegister(). GDALAllRegister() registar todos os drivers conhecidos including os "plug-in", que são bilioteca dinâmicas, carregadas pelo método GDALDriverManager::AutoLoadDrivers(). Se por algum motivo uma aplicações necessetita limitar o conjunto de drivers seria útil verificar o código de <a href="gdalallregister.cpp.html">gdalallregister.cpp</a>.</p> <p>Uma vez que os drivers são registados, a aplicação deve chamar a função GDALOpen() para abrir dataset, passando o nome do dataset e a forma de acesso (GA_ReadOnly ou GA_Update).</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "gdal_priv.h"</span> <span class="keywordtype">int</span> main() { GDALDataset *poDataset; GDALAllRegister(); poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly ); <span class="keywordflow">if</span>( poDataset == NULL ) { ...; } </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "gdal.h"</span> <span class="keywordtype">int</span> main() { GDALDatasetH hDataset; GDALAllRegister(); hDataset = GDALOpen( pszFilename, GA_ReadOnly ); <span class="keywordflow">if</span>( hDataset == NULL ) { ...; } </pre></div><p>Em Python: </p> <div class="fragment"><pre class="fragment"> <span class="keyword">import</span> gdal from gdalconst <span class="keyword">import</span> * dataset = gdal.Open( filename, GA_ReadOnly ) <span class="keywordflow">if</span> dataset is None: ... </pre></div><p>Note que se GDALOpen() retornar NULL significa que ocorreu uma falhada, e que as mensagens de erro deverão ter sido emitidas através de CPLError(). Se você quiser controlar como os erros estão relatados revise a a documentação do usuário de função CPLError(). Em geral, todo o GDAL usa CPLError() para o relatório de erro. Note também que o pszFilename não necessita realmente ser o nome de uma arquivo físico (no entando geralmente é). A interpretação é dependente do driver, e pôde ser um URL, um nome de arquivo com os parâmetros adicionais adicionados na string para controlar a abertura do arquivo ou qualquer outra coisa. Tente por favor não limitar diálogos da seleção da arquivo de GDAL somente a selecionar arquivos físicos.</p> <h2><a class="anchor" id="gdal_tutorial_dataset"> Extraindo Informacoes do Arquivo</a></h2> <p>Como descrita em <a href="gdal_datamodel.html">GDAL Data Model</a>, um GDALDataset contem uma lista de bandas raster, todas pertencendo à uma mesma área, e tendo a mesma definição. Possui também um metadata, um sistema coordenado, uma transformação geográfica, tamanho do raster e várias outras informações.</p> <div class="fragment"><pre class="fragment"> adfGeoTransform[0] <span class="comment">/* top left x */</span> adfGeoTransform[1] <span class="comment">/* w-e pixel resolution */</span> adfGeoTransform[2] <span class="comment">/* rotation, 0 if image is "north up" */</span> adfGeoTransform[3] <span class="comment">/* top left y */</span> adfGeoTransform[4] <span class="comment">/* rotation, 0 if image is "north up" */</span> adfGeoTransform[5] <span class="comment">/* n-s pixel resolution */</span> </pre></div><p>Se nós quiséssemos imprimir alguma informação geral sobre a série de dados nós pudemos fazer o seguinte:</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> <span class="keywordtype">double</span> adfGeoTransform[6]; printf( <span class="stringliteral">"Driver: %s/%s\n"</span>, poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) ); printf( <span class="stringliteral">"Size is %dx%dx%d\n"</span>, poDataset->GetRasterXSize(), poDataset->GetRasterYSize(), poDataset->GetRasterCount() ); <span class="keywordflow">if</span>( poDataset->GetProjectionRef() != NULL ) printf( <span class="stringliteral">"Projection is `%s'\n"</span>, poDataset->GetProjectionRef() ); <span class="keywordflow">if</span>( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { printf( <span class="stringliteral">"Origin = (%.6f,%.6f)\n"</span>, adfGeoTransform[0], adfGeoTransform[3] ); printf( <span class="stringliteral">"Pixel Size = (%.6f,%.6f)\n"</span>, adfGeoTransform[1], adfGeoTransform[5] ); } </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> GDALDriverH hDriver; <span class="keywordtype">double</span> adfGeoTransform[6]; hDriver = GDALGetDatasetDriver( hDataset ); printf( <span class="stringliteral">"Driver: %s/%s\n"</span>, GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( <span class="stringliteral">"Size is %dx%dx%d\n"</span>, GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), GDALGetRasterCount( hDataset ) ); <span class="keywordflow">if</span>( GDALGetProjectionRef( hDataset ) != NULL ) printf( <span class="stringliteral">"Projection is `%s'\n"</span>, GDALGetProjectionRef( hDataset ) ); <span class="keywordflow">if</span>( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { printf( <span class="stringliteral">"Origin = (%.6f,%.6f)\n"</span>, adfGeoTransform[0], adfGeoTransform[3] ); printf( <span class="stringliteral">"Pixel Size = (%.6f,%.6f)\n"</span>, adfGeoTransform[1], adfGeoTransform[5] ); } </pre></div><p>Em Python: </p> <div class="fragment"><pre class="fragment"> print <span class="stringliteral">'Driver: '</span>, dataset.GetDriver().ShortName,<span class="charliteral">'/'</span>, \ dataset.GetDriver().LongName print <span class="stringliteral">'Size is '</span>,dataset.RasterXSize,<span class="charliteral">'x'</span>,dataset.RasterYSize, \ <span class="charliteral">'x'</span>,dataset.RasterCount print <span class="stringliteral">'Projection is '</span>,dataset.GetProjection() geotransform = dataset.GetGeoTransform() <span class="keywordflow">if</span> not geotransform is None: print <span class="stringliteral">'Origin = ('</span>,geotransform[0], <span class="charliteral">','</span>,geotransform[3],<span class="charliteral">')'</span> print <span class="stringliteral">'Pixel Size = ('</span>,geotransform[1], <span class="charliteral">','</span>,geotransform[5],<span class="charliteral">')'</span> </pre></div><h2><a class="anchor" id="gdal_tutorial_band"> Extraindo uma Banda Raster</a></h2> <p>Neste ponto o acesso aos dados da raster através de GDAL pode ser feito uma banda de cada vez. A Band também possui metadata, tamanho de block, tabelas da cor, e vário a outra informação disponível na classe GDALRasterBand. Os seguintes códigos buscam um objeto de GDALRasterBand da série de dados (numerada a partir de 1 em GetRasterCount()) e a exposições de algums informações sobre ela.</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> GDALRasterBand *poBand; <span class="keywordtype">int</span> nBlockXSize, nBlockYSize; <span class="keywordtype">int</span> bGotMin, bGotMax; <span class="keywordtype">double</span> adfMinMax[2]; poBand = poDataset->GetRasterBand( 1 ); poBand->GetBlockSize( &nBlockXSize, &nBlockYSize ); printf( <span class="stringliteral">"Block=%dx%d Type=%s, ColorInterp=%s\n"</span>, nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); adfMinMax[0] = poBand->GetMinimum( &bGotMin ); adfMinMax[1] = poBand->GetMaximum( &bGotMax ); <span class="keywordflow">if</span>( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( <span class="stringliteral">"Min=%.3fd, Max=%.3f\n"</span>, adfMinMax[0], adfMinMax[1] ); <span class="keywordflow">if</span>( poBand->GetOverviewCount() > 0 ) printf( <span class="stringliteral">"Band has %d overviews.\n"</span>, poBand->GetOverviewCount() ); <span class="keywordflow">if</span>( poBand->GetColorTable() != NULL ) printf( <span class="stringliteral">"Band has a color table with %d entries.\n"</span>, poBand->GetColorTable()->GetColorEntryCount() ); </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> GDALRasterBandH hBand; <span class="keywordtype">int</span> nBlockXSize, nBlockYSize; <span class="keywordtype">int</span> bGotMin, bGotMax; <span class="keywordtype">double</span> adfMinMax[2]; hBand = GDALGetRasterBand( hDataset, 1 ); GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( <span class="stringliteral">"Block=%dx%d Type=%s, ColorInterp=%s\n"</span>, nBlockXSize, nBlockYSize, GDALGetDataTypeName(GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); <span class="keywordflow">if</span>( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); printf( <span class="stringliteral">"Min=%.3fd, Max=%.3f\n"</span>, adfMinMax[0], adfMinMax[1] ); <span class="keywordflow">if</span>( GDALGetOverviewCount(hBand) > 0 ) printf( <span class="stringliteral">"Band has %d overviews.\n"</span>, GDALGetOverviewCount(hBand)); <span class="keywordflow">if</span>( GDALGetRasterColorTable( hBand ) != NULL ) printf( <span class="stringliteral">"Band has a color table with %d entries.\n"</span>, GDALGetColorEntryCount( GDALGetRasterColorTable( hBand ) ) ); </pre></div><p>In Python (note several bindings are missing): </p> <div class="fragment"><pre class="fragment"> band = dataset.GetRasterBand(1) print <span class="stringliteral">'Band Type='</span>,gdal.GetDataTypeName(band.DataType) min = band.GetMinimum() max = band.GetMaximum() <span class="keywordflow">if</span> min is not None and max is not None: (min,max) = ComputeRasterMinMax(1) print <span class="stringliteral">'Min=%.3f, Max=%.3f'</span> % (min,max) <span class="keywordflow">if</span> band.GetOverviewCount() > 0: print <span class="stringliteral">'Band has '</span>, band.GetOverviewCount(), <span class="stringliteral">' overviews.'</span> <span class="keywordflow">if</span> not band.GetRasterColorTable() is None: print <span class="stringliteral">'Band has a color table with '</span>, \ band.GetRasterColorTable().GetCount(), <span class="stringliteral">' entries.'</span> </pre></div><h2><a class="anchor" id="gdal_tutorial_read"> Lendo dato Raster</a></h2> <p>Há algumas maneiras diferentes de ler dados da raster, mas o mais comum é através do Método GDALRasterBand::RasterIO(). Este método tomará automaticamente cuidado da conversão do tipo de dados, amostragem e janela de dados requerida. O seguinte código lerá o primeiro scanline dos dados em um buffer em tamanho similar à quantidade lida, convertendo os valores para ponto flutuando como parte da operação:</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> <span class="keywordtype">float</span> *pafScanline; <span class="keywordtype">int</span> nXSize = poBand->GetXSize(); pafScanline = (<span class="keywordtype">float</span> *) CPLMalloc(<span class="keyword">sizeof</span>(<span class="keywordtype">float</span>)*nXSize); poBand->RasterIO( GF_Read, 0, 0, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> <span class="keywordtype">float</span> *pafScanline; <span class="keywordtype">int</span> nXSize = GDALGetRasterBandXSize( hBand ); pafScanline = (<span class="keywordtype">float</span> *) CPLMalloc(<span class="keyword">sizeof</span>(<span class="keywordtype">float</span>)*nXSize); GDALRasterIO( hBand, GF_Read, 0, 0, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0 ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> scanline = band.ReadRaster( 0, 0, band.XSize, 1, \ band.XSize, 1, GDT_Float32 ) </pre></div><p>Note que o scanline retornado é do tipo char*, e contem os bytes xsize*4 de dados binários brutos de ponto flutuando. Isto pode ser convertido em Python usando o módulo do <b>struct</b> da biblioteca padrão:</p> <div class="fragment"><pre class="fragment"> <span class="keyword">import</span> <span class="keyword">struct</span> tuple_of_floats = <span class="keyword">struct</span>.unpack(<span class="charliteral">'f'</span> * b2.XSize, scanline) </pre></div><p>A chamada de RasterIO espera os seguintes argumentos. </p> <div class="fragment"><pre class="fragment">CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag, <span class="keywordtype">int</span> nXOff, <span class="keywordtype">int</span> nYOff, <span class="keywordtype">int</span> nXSize, <span class="keywordtype">int</span> nYSize, <span class="keywordtype">void</span> * pData, <span class="keywordtype">int</span> nBufXSize, <span class="keywordtype">int</span> nBufYSize, GDALDataType eBufType, <span class="keywordtype">int</span> nPixelSpace, <span class="keywordtype">int</span> nLineSpace ) </pre></div><p>Note que a mesma chamada de RasterIO() poderá ler, ou gravar dependendo do valor de eRWFlag (GF_Read ou GF_Write). Os argumentos nXOff, nYOff, nXSize, nYSize descreve a janela de dados da raster para ler (ou para gravar). Não necessita ser coincidente com os limites da image embora o acesso pode ser mais eficiente se for.</p> <p>O pData é o buffer de memória para os dados que serão lidos ou gravados. O verdadeiro tipo de dado &eacute aquele passado por eBufType, tal como GDT_Float32, ou GDT_Byte. A chamada de RasterIO() cuidará de converter entre o tipo de dados do buffer e o tipo de dados da banda. Anotar que ao converter dados do ponto flutuando para o inteiro RasterIO arredonda para baixo, e ao converter de para fora dos limites de valores válidos para o tipo de saída, será escolhido o mais próximo valor possível. Isto implica, por exemplo, que os dados 16bit lidos em um buffer de GDT_Byte converterão todos os valores maiores de 255 para 255, os <b>dados não estão escalados!</b></p> <p>Os valores nBufXSize e nBufYSize descrevem o tamanho do buffer. Ao carregar dados na resolução completa os valores seria o mesmo que o tamanho da janela. Entretanto, para carregar uma vista de solução reduzida (overview) os valores podiam ser ajustado para menos do que a janela no arquivo. Neste caso o RasterIO() utilizará overview para fazer mais eficientemente o IO se as overview forem apropriadas.</p> <p>O nPixelSpace, e o nLineSpace são normalmente zero indicando que os valores default devem ser usados. Entretanto, podem ser usados controlar o acesso à dados da memória, permitindo a leitura em um buffer que contem dados intercalados (interleave) pixel por exemplo.</p> <h2><a class="anchor" id="gdal_tutorial_close"> Fechando o Dataset</a></h2> <p>Por favor tenha em mente que os objetos de GDALRasterBand estão possuídos por sua dataset, e nunca devem ser destruídos com o operador delete de C++. GDALDataset podem ser fechado chamando GDALClose() ou usando o operador delete no GDALDataset. Um ou outro resultado na finalização apropriada, e resolver gravações pendentes.</p> <h2><a class="anchor" id="gdal_tutorial_creation"> Tecnicas para criar arquivos</a></h2> <p>As arquivos em formatos suportados GDAL podem ser criadas se o driver do formato suportar a criação. Há duas técnicas gerais para criar arquivos, usando CreateCopy() e Create(). O método de CreateCopy chama o método CreateCopy() do driver do formato, e passar como parâmetro dataset que será copiado. O método criar chama o método Create() do driver, e então explicitamente grava todos os metadata, e dados da raster com as chamadas separadas. Todos os drivers que suportam criar arquivos novos suportam o método de CreateCopy(), mas somente algum sustentação o método Create().</p> <p>Para determinar se o driver de um formato suporta Create ou CreateCopy é necessário verificar o DCAP_CREATE e os metadata de DCAP_CREATECOPY no driver do formato objetam. Assegurar-se de que GDALAllRegister() tenha sido chamado antes de chamar GetDriverByName().</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "cpl_string.h"</span> ... <span class="keyword">const</span> <span class="keywordtype">char</span> *pszFormat = <span class="stringliteral">"GTiff"</span>; GDALDriver *poDriver; <span class="keywordtype">char</span> **papszMetadata; poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); <span class="keywordflow">if</span>( poDriver == NULL ) exit( 1 ); papszMetadata = poDriver->GetMetadata(); <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) ) printf( <span class="stringliteral">"Driver %s supports Create() method.\n"</span>, pszFormat ); <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) ) printf( <span class="stringliteral">"Driver %s supports CreateCopy() method.\n"</span>, pszFormat ); </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "cpl_string.h"</span> ... <span class="keyword">const</span> <span class="keywordtype">char</span> *pszFormat = <span class="stringliteral">"GTiff"</span>; GDALDriver hDriver = GDALGetDriverByName( pszFormat ); <span class="keywordtype">char</span> **papszMetadata; <span class="keywordflow">if</span>( hDriver == NULL ) exit( 1 ); papszMetadata = GDALGetMetadata( hDriver, NULL ); <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) ) printf( <span class="stringliteral">"Driver %s supports Create() method.\n"</span>, pszFormat ); <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) ) printf( <span class="stringliteral">"Driver %s supports CreateCopy() method.\n"</span>, pszFormat ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> format = <span class="stringliteral">"GTiff"</span> driver = gdal.GetDriverByName( format ) metadata = driver.GetMetadata() <span class="keywordflow">if</span> metadata.has_key(gdal.DCAP_CREATE) \ and metadata[gdal.DCAP_CREATE] == <span class="stringliteral">'YES'</span>: print <span class="stringliteral">'Driver %s supports Create() method.'</span> % format <span class="keywordflow">if</span> metadata.has_key(gdal.DCAP_CREATECOPY) \ and metadata[gdal.DCAP_CREATECOPY] == <span class="stringliteral">'YES'</span>: print <span class="stringliteral">'Driver %s supports CreateCopy() method.'</span> % format </pre></div><p>Note que um número de drivers são de leitura apenas e não suportarão Create() ou CreateCopy ().</p> <h2><a class="anchor" id="gdal_tutorial_createcopy"> Usando CreateCopy()</a></h2> <p>O GDALDriver:: O método de CreateCopy() pode ser usado razoavelmente simples enquanto a maioria de informação é coletada do dataset de entrada. Entretanto, inclui opções para passar a formato opções específicas da criação, e para relatar o progresso ao usuário enquanto uma cópia longa da série de dados ocorre. Uma cópia simples de uma arquivo nomeou o pszSrcFilename, a uma arquivo nova nomeada pszDstFilename usando opções de defeito em um formato cujo o driver fosse buscado previamente pudesse olhar como este:</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> GDALDataset *poSrcDS = (GDALDataset *) GDALOpen( pszSrcFilename, GA_ReadOnly ); GDALDataset *poDstDS; poDstDS = poDriver->CreateCopy( pszDstFilename, poSrcDS, FALSE, NULL, NULL, NULL ); <span class="keywordflow">if</span>( poDstDS != NULL ) <span class="keyword">delete</span> poDstDS; </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> GDALDatasetH hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly ); GDALDatasetH hDstDS; hDstDS = GDALCreateCopy( hDriver, pszDstFilename, hSrcDS, FALSE, NULL, NULL, NULL ); <span class="keywordflow">if</span>( hDstDS != NULL ) GDALClose( hDstDS ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> src_ds = gdal.Open( src_filename ) dst_ds = driver.CreateCopy( dst_filename, src_ds, 0 ) </pre></div><p>Note que o método de CreateCopy() retorna um dataset writeable, e que deve ser fechado corretamente à escrita completa e a nivelar a série de dados ao disco. No Python encaixotar isto ocorre automaticamente quando os "dst_ds" saem do espaço. O valor FALSO (ou 0) usado para a opção do bStrict imediatamente depois que o nome de arquivo do destino na chamada de CreateCopy() indica que a chamada de CreateCopy() deve proseguir sem um erro fatal mesmo se a série de dados do destino não puder ser criada para combinar exatamente a série de dados da entrada. Isto pôde ser porque o formato da saída não suporta o datatype do pixel do dataset de entrada, ou porque o destino não pode suportar a escrita que georeferencing por exemplo.</p> <p>Casos mais complexo pôdem envolver passar opções da criação, e usar um monitor predefinido do progresso como este:</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "cpl_string.h"</span> ... <span class="keywordtype">char</span> **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">"TILED"</span>, <span class="stringliteral">"YES"</span> ); papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">"COMPRESS"</span>, <span class="stringliteral">"PACKBITS"</span> ); poDstDS = poDriver->CreateCopy( pszDstFilename, poSrcDS, FALSE, papszOptions, GDALTermProgress, NULL ); <span class="keywordflow">if</span>( poDstDS != NULL ) <span class="keyword">delete</span> poDstDS; CSLDestroy( papszOptions ); </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "cpl_string.h"</span> ... <span class="keywordtype">char</span> **papszOptions = NULL; papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">"TILED"</span>, <span class="stringliteral">"YES"</span> ); papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">"COMPRESS"</span>, <span class="stringliteral">"PACKBITS"</span> ); hDstDS = GDALCreateCopy( hDriver, pszDstFilename, hSrcDS, FALSE, papszOptions, GDALTermProgres, NULL ); <span class="keywordflow">if</span>( hDstDS != NULL ) GDALClose( hDstDS ); CSLDestroy( papszOptions ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> src_ds = gdal.Open( src_filename ) dst_ds = driver.CreateCopy( dst_filename, src_ds, 0, [ <span class="stringliteral">'TILED=YES'</span>, <span class="stringliteral">'COMPRESS=PACKBITS'</span> ] ) </pre></div><h2><a class="anchor" id="gdal_tutorial_create"> Usando Create()</a></h2> <p>Em situações em que não se quer somente exportar um arquivo existente para uma arquivo novo, geralmente usa-se o método GDALDriver::Criar() (embora algumas opções interessantes são possíveis com o uso de arquivos virtuais ou de arquivos da em-memória). O método Create() examina uma lista de opções bem como o CreateCopy(), mas o tamanho da imagem, número das bandas e o tipo da banda deve ser fornecido explicitamente. </p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> GDALDataset *poDstDS; <span class="keywordtype">char</span> **papszOptions = NULL; poDstDS = poDriver->Create( pszDstFilename, 512, 512, 1, GDT_Byte, papszOptions ); </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> GDALDatasetH hDstDS; <span class="keywordtype">char</span> **papszOptions = NULL; hDstDS = GDALCreate( hDriver, pszDstFilename, 512, 512, 1, GDT_Byte, papszOptions ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> dst_ds = driver.Create( dst_filename, 512, 512, 1, gdal.GDT_Byte ) </pre></div><p>Uma vez que o dataset é criado com sucesso, todos os metadata apropriados devem ser gravados no arquivo. O que variará de acordo com o uso, mas um caso simples com projeção, do geotransform e da raster é mostrado a seguir:</p> <p>Em C++: </p> <div class="fragment"><pre class="fragment"> <span class="keywordtype">double</span> adfGeoTransform[6] = { 444720, 30, 0, 3751320, 0, -30 }; OGRSpatialReference oSRS; <span class="keywordtype">char</span> *pszSRS_WKT = NULL; GDALRasterBand *poBand; GByte abyRaster[512*512]; poDstDS->SetGeoTransform( adfGeoTransform ); oSRS.SetUTM( 11, TRUE ); oSRS.SetWellKnownGeogCS( <span class="stringliteral">"NAD27"</span> ); oSRS.exportToWkt( &pszSRS_WKT ); poDstDS->SetProjection( pszSRS_WKT ); CPLFree( pszSRS_WKT ); poBand = poDstDS->GetRasterBand(1); poBand->RasterIO( GF_Write, 0, 0, 512, 512, abyRaster, 512, 512, GDT_Byte, 0, 0 ); <span class="keyword">delete</span> poDstDS; </pre></div><p>Em C: </p> <div class="fragment"><pre class="fragment"> <span class="keywordtype">double</span> adfGeoTransform[6] = { 444720, 30, 0, 3751320, 0, -30 }; OGRSpatialReferenceH hSRS; <span class="keywordtype">char</span> *pszSRS_WKT = NULL; GDALRasterBandH hBand; GByte abyRaster[512*512]; GDALSetGeoTransform( hDstDS, adfGeoTransform ); hSRS = OSRNewSpatialReference( NULL ); OSRSetUTM( hSRS, 11, TRUE ); OSRSetWellKnownGeogCS( hSRS, <span class="stringliteral">"NAD27"</span> ); OSRExportToWkt( hSRS, &pszSRS_WKT ); OSRDestroySpatialReference( hSRS ); GDALSetProjection( hDstDS, pszSRS_WKT ); CPLFree( pszSRS_WKT ); hBand = GDALGetRasterBand( hDstDS, 1 ); GDALRasterIO( hBand, GF_Write, 0, 0, 512, 512, abyRaster, 512, 512, GDT_Byte, 0, 0 ); GDALClose( hDstDS ); </pre></div><p>Em Python:</p> <div class="fragment"><pre class="fragment"> <span class="keyword">import</span> Numeric, osr dst_ds.SetGeoTransform( [ 444720, 30, 0, 3751320, 0, -30 ] ) srs = osr.SpatialReference() srs.SetUTM( 11, 1 ) srs.SetWellKnownGeogCS( <span class="stringliteral">'NAD27'</span> ) dst_ds.SetProjection( srs.ExportToWkt() ) raster = Numeric.zeros( (512, 512) ) dst_ds.GetRasterBand(1).WriteArray( raster ) </pre></div> <p> $Id: gdal_tutorial_br.dox $ </p> </div> <hr> Generated for GDAL by <a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.6.2-20100208. </body> </html>