📄 vb6_tutorial.html
字号:
Print Drv.GetShortName() & <span class="stringliteral">": "</span> & Drv.GetMetadataItem(GDAL.DMD_LONGNAME, <span class="stringliteral">""</span>) & xMsg Next drvIndex</pre></div><p>Once we have the driver object, the simplest way of creating a new file is to use CreateCopy(). This tries to create a copy of the input file in the new format. A complete segment (without any error checking) would look like the following. The CreateCopy() method corresponds to the C++ method <a class="el" href="classGDALDriver.html#d0f7a33b0bd7f9d685bbd90d04fde629">GDALDriver::CreateCopy()</a>. The VB6 implementation does not support the use of progress callbacks.<p><div class="fragment"><pre class="fragment"> Dim Drv As <a class="code" href="classGDALDriver.html">GDALDriver</a> Dim SrcDS As <a class="code" href="classGDALDataset.html">GDALDataset</a>, DstDS As GDALDataset Call GDAL.AllRegister Set Drv = GDALCore.GetDriverByName( <span class="stringliteral">"GTiff"</span> ) Set SrcDS = GDAL.Open( <span class="stringliteral">"in.tif"</span>, GDAL.GA_ReadOnly ) Set DstDS = Drv.CreateCopy( <span class="stringliteral">"out.tif"</span>, SrcDS, True, Nothing )</pre></div><p>This is nice and simple, but sometimes we need to create a file with more detailed control. So, next we show how to create a file and then copy pieces of data to it "manually". The <a class="el" href="classGDALDriver.html#191dc4a5c8f48c1dea4083c711b8f7c4">GDALDriver::Create()</a> analog is Create().<p><div class="fragment"><pre class="fragment"> Set DstDS = Drv.Create(<span class="stringliteral">"out.tif"</span>, SrcDS.XSize, SrcDS.YSize, _ SrcDS.BandCount, GDAL.GDT_Byte, Nothing)</pre></div><p>In some cases we may want to provide some creation options, which is demonstrated here. Creation options (like metadata set through the SetMetadata() method) are arrays of Strings.<p><div class="fragment"><pre class="fragment"> Dim CreateOptions(1) As String CreateOptions(1) = "PHOTOMETRIC=MINISWHITE" Set DstDS = Drv.Create("out.tif", SrcDS.XSize, SrcDS.YSize, _ SrcDS.BandCount, GDAL.<a class="code" href="gdal_8h.html#22e22ce0a55036a96f652765793fb7a438a66c26861d368e95ba42106ee3ab92">GDT_Byte</a>, CreateOptions)</pre></div><p>When copying the GeoTransform, we take care to check that reading the geotransform actually worked. Most methods which return CPLErr in C++ also return it in VB6. A return value of 0 will indicate success, and non-zero is failure.<p><div class="fragment"><pre class="fragment"> Dim err As Long Dim gt(6) As Double err = SrcDS.GetGeoTransform(gt) If err = 0 Then Call DstDS.SetGeoTransform(gt) End If</pre></div><p>Copy the projection. Even if GetProjection() fails we get an empty string which is safe enough to set on the target. Similarly for metadata.<p><div class="fragment"><pre class="fragment"> Call DstDS.SetProjection(SrcDS.GetProjection()) Call DstDS.SetMetadata(SrcDS.GetMetadata(<span class="stringliteral">""</span>), <span class="stringliteral">""</span>)</pre></div><p>Next we loop, processing bands, and copy some common data items.<p><div class="fragment"><pre class="fragment"> For iBand = 1 To SrcDS.BandCount Dim SrcBand As <a class="code" href="classGDALRasterBand.html">GDALRasterBand</a>, DstBand As GDALRasterBand Set SrcBand = SrcDS.GetRasterBand(iBand) Set DstBand = DstDS.GetRasterBand(iBand) Call DstBand.SetMetadata(SrcBand.GetMetadata(<span class="stringliteral">""</span>), <span class="stringliteral">""</span>) Call DstBand.SetOffset(SrcBand.GetOffset()) Call DstBand.SetScale(SrcBand.GetScale()) Dim NoDataValue As Double, Success As Long NoDataValue = SrcBand.GetNoDataValue(Success) If Success <> 0 Then Call DstBand.SetNoDataValue(NoDataValue) End If</pre></div><p>Then, if one is available, we copy the palette.<p><div class="fragment"><pre class="fragment"> Dim ct As GDALColorTable Set ct = SrcBand.GetColorTable() If ct.IsValid() Then err = DstBand.SetColorTable(ct) End If</pre></div><p>Finally, the meat and potatoes. We copy the image data. We do this one scanline at a time so that we can support very large images without require large amounts of RAM. Here we use a Double buffer for the scanline, but if we knew in advance the type of the image, we could dimension a buffer of the appropriate type. The RasterIO() method internally knows how to convert pixel data types, so using Double ensures all data types (except for complex) are properly preserved, though at the cost of some extra data conversion internally.<p><div class="fragment"><pre class="fragment"> Dim Scanline() As Double, iLine As Long ReDim Scanline(SrcDS.XSize) As Double ' Copy band raster data. For iLine = 0 To SrcDS.YSize - 1 Call SrcBand.RasterIO(GDAL.GF_Read, 0, iLine, SrcDS.XSize, 1, _ Scanline) Call DstBand.RasterIO(GDAL.<a class="code" href="gdal_8h.html#e602fdf251b6b0210a5af5a7cf7623b37f8fbb849495a05f2281b9a6fac0e7e2">GF_Write</a>, 0, iLine, SrcDS.XSize, 1, _ Scanline) Next iLine</pre></div><h2><a class="anchor" name="OSRTut">Tutorial - Coordinate Systems and Reprojection</a></h2>The GDAL VB6 bindings also include limited support for use of the OGRSpatialReference and OGRCoordinateTransformation classes. The OGRSpatialReference represents a coordinate system and can be used to parse, manipulate and form WKT strings, such as those returned by the GDALDataset.GetProjection() method. The OGRCoordinateTransformation class provides a way of reprojecting between two coordinate systems.<p>The following example shows how to report the corners of an image in georeferenced and geographic (lat/long) coordinates. First, we open the file, and read the geotransform.<p><div class="fragment"><pre class="fragment"> Dim ds As GDALDataset Call GDALCore.GDALAllRegister Set ds = GDAL.OpenDS(FileDlg.Filename, GDAL.GA_ReadOnly) If ds.IsValid() Then Dim Geotransform(6) As Double Call ds.GetGeoTransform(Geotransform)</pre></div><p>Next, we fetch the coordinate system, and if it is non-empty we try to instantiate an OGRSpatialReference from it.<p><div class="fragment"><pre class="fragment"> ' report projection in pretty format. Dim WKT As String Dim srs As New OGRSpatialReference Dim latlong_srs As OGRSpatialReference Dim ct As New OGRCoordinateTransformation WKT = ds.GetProjection() If Len(WKT) > 0 Then Print <span class="stringliteral">"Projection: "</span> Call srs.SetFromUserInput(WKT)</pre></div><p>If the coordinate system is projected it will have a PROJECTION node. In that case we build a new coordinate system which is the corresponding geographic coordinate system. So for instance if the "srs" was UTM 11 WGS84 then it's corresponding geographic coordinate system would just be WGS84. Once we have these two coordinate systems, we build a transformer to convert between them.<p><div class="fragment"><pre class="fragment"> If srs.GetAttrValue(<span class="stringliteral">"PROJECTION"</span>, 0) <> <span class="stringliteral">""</span> Then Set latlong_srs = srs.CloneGeogCS() Set ct = GDAL.CreateCoordinateTransformation(srs, latlong_srs) End If End If</pre></div><p>Next we call a helper function to report each corner, and the center. We pass in the name of the corner, the pixel/line location at the corner, and the geotransform and transformer object.<p><div class="fragment"><pre class="fragment"> Call ReportCorner(<span class="stringliteral">"Top Left "</span>, 0, 0, _ Geotransform, ct) Call ReportCorner("Top Right ", ds.XSize, 0, _ Geotransform, ct) Call ReportCorner("Bottom Left ", 0, ds.YSize, _ Geotransform, ct) Call ReportCorner("Bottom Right ", ds.XSize, ds.YSize, _ Geotransform, ct) Call ReportCorner("Center ", ds.XSize / 2<span class="preprocessor">#, ds.YSize / 2#, _</span><span class="preprocessor"> Geotransform, ct)</span></pre></div><p>The ReportCorner subroutine starts by computing the corresponding georeferenced x and y location using the pixel/line coordinates and the geotransform.<p><div class="fragment"><pre class="fragment">Private Sub ReportCorner(CornerName As String, pixel As Double, line As Double, _ gt() As Double, ct As OGRCoordinateTransformation) Dim geox As Double, geoy As Double geox = gt(0) + pixel * gt(1) + line * gt(2) geoy = gt(3) + pixel * gt(4) + line * gt(5)</pre></div><p>Next, if we have a transformer, we use it to compute a corresponding latitude and longitude.<p><div class="fragment"><pre class="fragment"> Dim longitude As Double, latitude As Double, Z As Double Dim latlong_valid As Boolean latlong_valid = False If ct.IsValid() Then Z = 0 longitude = geox latitude = geoy latlong_valid = ct.TransformOne(longitude, latitude, Z) End If</pre></div><p>Then we report the corner location in georeferenced, and if we have it geographic coordinates.<p><div class="fragment"><pre class="fragment"> If latlong_valid Then Print CornerName & geox & <span class="stringliteral">","</span> & geoy & <span class="stringliteral">" "</span> & longitude & <span class="stringliteral">","</span> & latitude Else Print CornerName & geox & <span class="stringliteral">","</span> & geoy End IfEnd Sub</pre></div><p> <p>$Id: vb6_tutorial.dox 10108 2006-10-17 22:30:22Z mloskot $</p> <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.5.1.</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -