Sophie

Sophie

distrib > Fedora > 13 > i386 > by-pkgid > 7fd7c575020aa78a8e2e309ea8909f43 > files > 34

gdal-1.6.2-6.fc13.i686.rpm

<!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&nbsp;Principal</span></a></li>
      <li class="current"><a href="pages.html"><span>Páginas&nbsp;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 &eacute; necess&aacute;rio registar os drivers, existe um driver para cada formato suportado e o registro dos driver &eacute; realizado normalmente com a fun&ccedil;&atilde;o GDALAllRegister(). GDALAllRegister() registar todos os drivers conhecidos including os "plug-in", que s&atilde;o bilioteca din&acirc;micas, carregadas pelo m&eacute;todo GDALDriverManager::AutoLoadDrivers(). Se por algum motivo uma aplica&ccedil;&otilde;es necessetita limitar o conjunto de drivers seria &uacute;til verificar o c&oacute;digo de <a href="gdalallregister.cpp.html">gdalallregister.cpp</a>.</p>
<p>Uma vez que os drivers s&atilde;o registados, a aplica&ccedil;&atilde;o deve chamar a fun&ccedil;&atilde;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 &quot;gdal_priv.h&quot;</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 &quot;gdal.h&quot;</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&atilde;o ter sido emitidas atrav&eacute;s de CPLError(). Se voc&ecirc; quiser controlar como os erros est&atilde;o relatados revise a a documenta&ccedil;&atilde;o do usu&aacute;rio de fun&ccedil;&atilde;o CPLError(). Em geral, todo o GDAL usa CPLError() para o relat&oacute;rio de erro. Note tamb&eacute;m que o pszFilename n&atilde;o necessita realmente ser o nome de uma arquivo f&iacute;sico (no entando geralmente &eacute;). A interpreta&ccedil;&atilde;o &eacute; dependente do driver, e p&ocirc;de ser um URL, um nome de arquivo com os par&acirc;metros adicionais adicionados na string para controlar a abertura do arquivo ou qualquer outra coisa. Tente por favor n&atilde;o limitar di&aacute;logos da sele&ccedil;&atilde;o da arquivo de GDAL somente a selecionar arquivos f&iacute;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 &agrave; uma mesma &aacute;rea, e tendo a mesma defini&ccedil;&atilde;o. Possui tamb&eacute;m um metadata, um sistema coordenado, uma transforma&ccedil;&atilde;o geogr&aacute;fica, tamanho do raster e v&aacute;rias outras informa&ccedil;&otilde;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 &quot;north up&quot; */</span>
    adfGeoTransform[3] <span class="comment">/* top left y */</span>
    adfGeoTransform[4] <span class="comment">/* rotation, 0 if image is &quot;north up&quot; */</span>
    adfGeoTransform[5] <span class="comment">/* n-s pixel resolution */</span>
</pre></div><p>Se n&oacute;s quis&eacute;ssemos imprimir alguma informa&ccedil;&atilde;o geral sobre a s&eacute;rie de dados n&oacute;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">&quot;Driver: %s/%s\n&quot;</span>,
            poDataset-&gt;GetDriver()-&gt;GetDescription(), 
            poDataset-&gt;GetDriver()-&gt;GetMetadataItem( GDAL_DMD_LONGNAME ) );

    printf( <span class="stringliteral">&quot;Size is %dx%dx%d\n&quot;</span>, 
            poDataset-&gt;GetRasterXSize(), poDataset-&gt;GetRasterYSize(),
            poDataset-&gt;GetRasterCount() );

    <span class="keywordflow">if</span>( poDataset-&gt;GetProjectionRef()  != NULL )
        printf( <span class="stringliteral">&quot;Projection is `%s&#39;\n&quot;</span>, poDataset-&gt;GetProjectionRef() );

    <span class="keywordflow">if</span>( poDataset-&gt;GetGeoTransform( adfGeoTransform ) == CE_None )
    {
        printf( <span class="stringliteral">&quot;Origin = (%.6f,%.6f)\n&quot;</span>,
                adfGeoTransform[0], adfGeoTransform[3] );

        printf( <span class="stringliteral">&quot;Pixel Size = (%.6f,%.6f)\n&quot;</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">&quot;Driver: %s/%s\n&quot;</span>,
            GDALGetDriverShortName( hDriver ),
            GDALGetDriverLongName( hDriver ) );

    printf( <span class="stringliteral">&quot;Size is %dx%dx%d\n&quot;</span>,
            GDALGetRasterXSize( hDataset ), 
            GDALGetRasterYSize( hDataset ),
            GDALGetRasterCount( hDataset ) );

    <span class="keywordflow">if</span>( GDALGetProjectionRef( hDataset ) != NULL )
        printf( <span class="stringliteral">&quot;Projection is `%s&#39;\n&quot;</span>, GDALGetProjectionRef( hDataset ) );

    <span class="keywordflow">if</span>( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
    {
        printf( <span class="stringliteral">&quot;Origin = (%.6f,%.6f)\n&quot;</span>,
                adfGeoTransform[0], adfGeoTransform[3] );

        printf( <span class="stringliteral">&quot;Pixel Size = (%.6f,%.6f)\n&quot;</span>,
                adfGeoTransform[1], adfGeoTransform[5] );
    }
</pre></div><p>Em Python: </p>
<div class="fragment"><pre class="fragment">    print <span class="stringliteral">&#39;Driver: &#39;</span>, dataset.GetDriver().ShortName,<span class="charliteral">&#39;/&#39;</span>, \
          dataset.GetDriver().LongName
    print <span class="stringliteral">&#39;Size is &#39;</span>,dataset.RasterXSize,<span class="charliteral">&#39;x&#39;</span>,dataset.RasterYSize, \
          <span class="charliteral">&#39;x&#39;</span>,dataset.RasterCount
    print <span class="stringliteral">&#39;Projection is &#39;</span>,dataset.GetProjection()
    
    geotransform = dataset.GetGeoTransform()
    <span class="keywordflow">if</span> not geotransform is None:
        print <span class="stringliteral">&#39;Origin = (&#39;</span>,geotransform[0], <span class="charliteral">&#39;,&#39;</span>,geotransform[3],<span class="charliteral">&#39;)&#39;</span>
        print <span class="stringliteral">&#39;Pixel Size = (&#39;</span>,geotransform[1], <span class="charliteral">&#39;,&#39;</span>,geotransform[5],<span class="charliteral">&#39;)&#39;</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&eacute;s de GDAL pode ser feito uma banda de cada vez. A Band tamb&eacute;m possui metadata, tamanho de block, tabelas da cor, e v&aacute;rio a outra informa&ccedil;&atilde;o dispon&iacute;vel na classe GDALRasterBand. Os seguintes c&oacute;digos buscam um objeto de GDALRasterBand da s&eacute;rie de dados (numerada a partir de 1 em GetRasterCount()) e a exposi&ccedil;&otilde;es de algums informa&ccedil;&otilde;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-&gt;GetRasterBand( 1 );
        poBand-&gt;GetBlockSize( &amp;nBlockXSize, &amp;nBlockYSize );
        printf( <span class="stringliteral">&quot;Block=%dx%d Type=%s, ColorInterp=%s\n&quot;</span>,
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(poBand-&gt;GetRasterDataType()),
                GDALGetColorInterpretationName(
                    poBand-&gt;GetColorInterpretation()) );

        adfMinMax[0] = poBand-&gt;GetMinimum( &amp;bGotMin );
        adfMinMax[1] = poBand-&gt;GetMaximum( &amp;bGotMax );
        <span class="keywordflow">if</span>( ! (bGotMin &amp;&amp; bGotMax) )
            GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);

        printf( <span class="stringliteral">&quot;Min=%.3fd, Max=%.3f\n&quot;</span>, adfMinMax[0], adfMinMax[1] );
        
        <span class="keywordflow">if</span>( poBand-&gt;GetOverviewCount() &gt; 0 )
            printf( <span class="stringliteral">&quot;Band has %d overviews.\n&quot;</span>, poBand-&gt;GetOverviewCount() );

        <span class="keywordflow">if</span>( poBand-&gt;GetColorTable() != NULL )
            printf( <span class="stringliteral">&quot;Band has a color table with %d entries.\n&quot;</span>, 
                     poBand-&gt;GetColorTable()-&gt;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, &amp;nBlockXSize, &amp;nBlockYSize );
        printf( <span class="stringliteral">&quot;Block=%dx%d Type=%s, ColorInterp=%s\n&quot;</span>,
                nBlockXSize, nBlockYSize,
                GDALGetDataTypeName(GDALGetRasterDataType(hBand)),
                GDALGetColorInterpretationName(
                    GDALGetRasterColorInterpretation(hBand)) );

        adfMinMax[0] = GDALGetRasterMinimum( hBand, &amp;bGotMin );
        adfMinMax[1] = GDALGetRasterMaximum( hBand, &amp;bGotMax );
        <span class="keywordflow">if</span>( ! (bGotMin &amp;&amp; bGotMax) )
            GDALComputeRasterMinMax( hBand, TRUE, adfMinMax );

        printf( <span class="stringliteral">&quot;Min=%.3fd, Max=%.3f\n&quot;</span>, adfMinMax[0], adfMinMax[1] );
        
        <span class="keywordflow">if</span>( GDALGetOverviewCount(hBand) &gt; 0 )
            printf( <span class="stringliteral">&quot;Band has %d overviews.\n&quot;</span>, GDALGetOverviewCount(hBand));

        <span class="keywordflow">if</span>( GDALGetRasterColorTable( hBand ) != NULL )
            printf( <span class="stringliteral">&quot;Band has a color table with %d entries.\n&quot;</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">&#39;Band Type=&#39;</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">&#39;Min=%.3f, Max=%.3f&#39;</span> % (min,max)

        <span class="keywordflow">if</span> band.GetOverviewCount() &gt; 0:
            print <span class="stringliteral">&#39;Band has &#39;</span>, band.GetOverviewCount(), <span class="stringliteral">&#39; overviews.&#39;</span>

        <span class="keywordflow">if</span> not band.GetRasterColorTable() is None:
            print <span class="stringliteral">&#39;Band has a color table with &#39;</span>, \
            band.GetRasterColorTable().GetCount(), <span class="stringliteral">&#39; entries.&#39;</span>
</pre></div><h2><a class="anchor" id="gdal_tutorial_read">
Lendo dato Raster</a></h2>
<p>H&aacute; algumas maneiras diferentes de ler dados da raster, mas o mais comum &eacute; atrav&eacute;s do M&eacute;todo GDALRasterBand::RasterIO(). Este m&eacute;todo tomar&aacute; automaticamente cuidado da convers&atilde;o do tipo de dados, amostragem e janela de dados requerida. O seguinte c&oacute;digo ler&aacute; o primeiro scanline dos dados em um buffer em tamanho similar &agrave; quantidade lida, convertendo os valores para ponto flutuando como parte da opera&ccedil;&atilde;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-&gt;GetXSize();

        pafScanline = (<span class="keywordtype">float</span> *) CPLMalloc(<span class="keyword">sizeof</span>(<span class="keywordtype">float</span>)*nXSize);
        poBand-&gt;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 &eacute; do tipo char*, e contem os bytes xsize*4 de dados bin&aacute;rios brutos de ponto flutuando. Isto pode ser convertido em Python usando o m&oacute;dulo do <b>struct</b> da biblioteca padr&atilde;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">&#39;f&#39;</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&aacute; 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&atilde;o necessita ser coincidente com os limites da image embora o acesso pode ser mais eficiente se for.</p>
<p>O pData &eacute; o buffer de mem&oacute;ria para os dados que ser&atilde;o lidos ou gravados. O verdadeiro tipo de dado &amp;eacute aquele passado por eBufType, tal como GDT_Float32, ou GDT_Byte. A chamada de RasterIO() cuidar&aacute; 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&aacute;lidos para o tipo de sa&iacute;da, ser&aacute; escolhido o mais pr&oacute;ximo valor poss&iacute;vel. Isto implica, por exemplo, que os dados 16bit lidos em um buffer de GDT_Byte converter&atilde;o todos os valores maiores de 255 para 255, os <b>dados n&atilde;o est&atilde;o escalados!</b></p>
<p>Os valores nBufXSize e nBufYSize descrevem o tamanho do buffer. Ao carregar dados na resolu&ccedil;&atilde;o completa os valores seria o mesmo que o tamanho da janela. Entretanto, para carregar uma vista de solu&ccedil;&atilde;o reduzida (overview) os valores podiam ser ajustado para menos do que a janela no arquivo. Neste caso o RasterIO() utilizar&aacute; overview para fazer mais eficientemente o IO se as overview forem apropriadas.</p>
<p>O nPixelSpace, e o nLineSpace s&atilde;o normalmente zero indicando que os valores default devem ser usados. Entretanto, podem ser usados controlar o acesso &agrave; dados da mem&oacute;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&atilde;o possu&iacute;dos por sua dataset, e nunca devem ser destru&iacute;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&ccedil;&atilde;o apropriada, e resolver grava&ccedil;&otilde;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&ccedil;&atilde;o. H&aacute; duas t&eacute;cnicas gerais para criar arquivos, usando CreateCopy() e Create(). O m&eacute;todo de CreateCopy chama o m&eacute;todo CreateCopy() do driver do formato, e passar como par&acirc;metro dataset que ser&aacute; copiado. O m&eacute;todo criar chama o m&eacute;todo Create() do driver, e ent&atilde;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&eacute;todo de CreateCopy(), mas somente algum sustenta&ccedil;&atilde;o o m&eacute;todo Create().</p>
<p>Para determinar se o driver de um formato suporta Create ou CreateCopy &eacute; necess&aacute;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 &quot;cpl_string.h&quot;</span>
...
    <span class="keyword">const</span> <span class="keywordtype">char</span> *pszFormat = <span class="stringliteral">&quot;GTiff&quot;</span>;
    GDALDriver *poDriver;
    <span class="keywordtype">char</span> **papszMetadata;

    poDriver = GetGDALDriverManager()-&gt;GetDriverByName(pszFormat);

    <span class="keywordflow">if</span>( poDriver == NULL )
        exit( 1 );

    papszMetadata = poDriver-&gt;GetMetadata();
    <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
        printf( <span class="stringliteral">&quot;Driver %s supports Create() method.\n&quot;</span>, pszFormat );
    <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
        printf( <span class="stringliteral">&quot;Driver %s supports CreateCopy() method.\n&quot;</span>, pszFormat );
</pre></div><p>Em C: </p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &quot;cpl_string.h&quot;</span>
...
    <span class="keyword">const</span> <span class="keywordtype">char</span> *pszFormat = <span class="stringliteral">&quot;GTiff&quot;</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">&quot;Driver %s supports Create() method.\n&quot;</span>, pszFormat );
    <span class="keywordflow">if</span>( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
        printf( <span class="stringliteral">&quot;Driver %s supports CreateCopy() method.\n&quot;</span>, pszFormat );
</pre></div><p>Em Python:</p>
<div class="fragment"><pre class="fragment">    format = <span class="stringliteral">&quot;GTiff&quot;</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">&#39;YES&#39;</span>:
        print <span class="stringliteral">&#39;Driver %s supports Create() method.&#39;</span> % format
    <span class="keywordflow">if</span> metadata.has_key(gdal.DCAP_CREATECOPY) \
       and metadata[gdal.DCAP_CREATECOPY] == <span class="stringliteral">&#39;YES&#39;</span>:
        print <span class="stringliteral">&#39;Driver %s supports CreateCopy() method.&#39;</span> % format
</pre></div><p>Note que um n&uacute;mero de drivers s&atilde;o de leitura apenas e n&atilde;o suportar&atilde;o Create() ou CreateCopy ().</p>
<h2><a class="anchor" id="gdal_tutorial_createcopy">
Usando CreateCopy()</a></h2>
<p>O GDALDriver:: O m&eacute;todo de CreateCopy() pode ser usado razoavelmente simples enquanto a maioria de informa&ccedil;&atilde;o &eacute; coletada do dataset de entrada. Entretanto, inclui op&ccedil;&otilde;es para passar a formato op&ccedil;&otilde;es espec&iacute;ficas da cria&ccedil;&atilde;o, e para relatar o progresso ao usu&aacute;rio enquanto uma c&oacute;pia longa da s&eacute;rie de dados ocorre. Uma c&oacute;pia simples de uma arquivo nomeou o pszSrcFilename, a uma arquivo nova nomeada pszDstFilename usando op&ccedil;&otilde;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-&gt;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&eacute;todo de CreateCopy() retorna um dataset writeable, e que deve ser fechado corretamente &agrave; escrita completa e a nivelar a s&eacute;rie de dados ao disco. No Python encaixotar isto ocorre automaticamente quando os "dst_ds" saem do espa&ccedil;o. O valor FALSO (ou 0) usado para a op&ccedil;&atilde;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&eacute;rie de dados do destino n&atilde;o puder ser criada para combinar exatamente a s&eacute;rie de dados da entrada. Isto p&ocirc;de ser porque o formato da sa&iacute;da n&atilde;o suporta o datatype do pixel do dataset de entrada, ou porque o destino n&atilde;o pode suportar a escrita que georeferencing por exemplo.</p>
<p>Casos mais complexo p&ocirc;dem envolver passar op&ccedil;&otilde;es da cria&ccedil;&atilde;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 &quot;cpl_string.h&quot;</span>
...
    <span class="keywordtype">char</span> **papszOptions = NULL;
    
    papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">&quot;TILED&quot;</span>, <span class="stringliteral">&quot;YES&quot;</span> );
    papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">&quot;COMPRESS&quot;</span>, <span class="stringliteral">&quot;PACKBITS&quot;</span> );
    poDstDS = poDriver-&gt;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 &quot;cpl_string.h&quot;</span>
...
    <span class="keywordtype">char</span> **papszOptions = NULL;
    
    papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">&quot;TILED&quot;</span>, <span class="stringliteral">&quot;YES&quot;</span> );
    papszOptions = CSLSetNameValue( papszOptions, <span class="stringliteral">&quot;COMPRESS&quot;</span>, <span class="stringliteral">&quot;PACKBITS&quot;</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">&#39;TILED=YES&#39;</span>, <span class="stringliteral">&#39;COMPRESS=PACKBITS&#39;</span> ] )
</pre></div><h2><a class="anchor" id="gdal_tutorial_create">
Usando Create()</a></h2>
<p>Em situa&ccedil;&otilde;es em que n&atilde;o se quer somente exportar um arquivo existente para uma arquivo novo, geralmente usa-se o m&eacute;todo GDALDriver::Criar() (embora algumas op&ccedil;&otilde;es interessantes s&atilde;o poss&iacute;veis com o uso de arquivos virtuais ou de arquivos da em-mem&oacute;ria). O m&eacute;todo Create() examina uma lista de op&ccedil;&otilde;es bem como o CreateCopy(), mas o tamanho da imagem, n&uacute;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-&gt;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 &eacute; criado com sucesso, todos os metadata apropriados devem ser gravados no arquivo. O que variar&aacute; de acordo com o uso, mas um caso simples com proje&ccedil;&atilde;o, do geotransform e da raster &eacute; 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-&gt;SetGeoTransform( adfGeoTransform );
    
    oSRS.SetUTM( 11, TRUE );
    oSRS.SetWellKnownGeogCS( <span class="stringliteral">&quot;NAD27&quot;</span> );
    oSRS.exportToWkt( &amp;pszSRS_WKT );
    poDstDS-&gt;SetProjection( pszSRS_WKT );
    CPLFree( pszSRS_WKT );

    poBand = poDstDS-&gt;GetRasterBand(1);
    poBand-&gt;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">&quot;NAD27&quot;</span> );                     
    OSRExportToWkt( hSRS, &amp;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">&#39;NAD27&#39;</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>