ThinkGeo.com    |     Documentation    |     Premium Support

Save Map as GeoTIFF with TFW

Hi,

I’m trying to save the Map as GeoTIFF. The Function will store a TIF and TFW file.
But the result is stretched and rotated.
The data is projected (EPSG 25832)
This is the Function to store GeoTIFF with TFW:

Public Sub ExportBitmap(filename As String, format As Imaging.ImageFormat, Optional pictureWidth As Integer = 1000, Optional ExportExtent As RectangleShape = Nothing, Optional BackColor As Boolean = False)
Dim bitmap As Bitmap = Nothing
    
If ExportExtent Is Nothing Then
    ExportExtent = theMap.CurrentExtent
End If
Dim MapRect As RectangleShape = GetProjectedShape(ExportExtent.GetBoundingBox).GetBoundingBox

Dim MapWidth As Integer = CInt(MapRect.Width) 
Dim MapHeight As Integer = CInt(MapRect.Height)
If pictureWidth > 0 Then
    Dim f As Double = pictureWidth / MapRect.Width
    MapHeight = f * MapRect.Height
    MapWidth = pictureWidth
End If

bitmap = New Bitmap(MapWidth, MapHeight)

Dim g As Graphics = Graphics.FromImage(bitmap)
If BackColor Then
    g.FillRectangle(Brushes.White, 0, 0, MapWidth, MapHeight)
End If

Dim gdiPlusPlatformGeoCanvas As New PlatformGeoCanvas

gdiPlusPlatformGeoCanvas.BeginDrawing(bitmap, ExportExtent.GetBoundingBox(), theMap.MapUnit)
gdiPlusPlatformGeoCanvas.DrawingQuality = DrawingQuality.HighQuality

Dim labelsInAllLayers As New Collection(Of SimpleCandidate)()
For Each exportOverlay As LayerOverlay In theMap.Overlays
    If IsMapOverlayVisible(exportOverlay.Name) Then
        For Each exportLayer As ThinkGeo.MapSuite.Layers.Layer In exportOverlay.Layers
            If exportLayer.IsVisible Then 
                exportLayer.Draw(gdiPlusPlatformGeoCanvas, labelsInAllLayers)
            End If
        Next
    End If
Next

gdiPlusPlatformGeoCanvas.EndDrawing()

Dim MyFile As FileInfo = My.Computer.FileSystem.GetFileInfo(filename)

bitmap.Save(filename, format)

Dim worldFile As String
Dim PixelSizeX As Double = MapRect.Width / MapWidth
Dim PixelSizeY As Double = MapRect.Height / MapHeight
Dim XCoord As Double = MapRect.UpperLeftPoint.X
Dim YCoord As Double = MapRect.UpperLeftPoint.Y 

worldFile = PixelSizeX.ToString() & vbNewLine
worldFile &= "0" & vbNewLine
worldFile &= "0" & vbNewLine

worldFile &= "-" & PixelSizeY.ToString() & vbNewLine
worldFile &= XCoord.ToString("0.000") & vbNewLine
worldFile &= YCoord.ToString("0.000")

My.Computer.FileSystem.WriteAllText(MyFile.FullName.Replace(MyFile.Extension, ".tfw"), worldFile.Replace(",", "."), False, Encoding.ASCII)

End Sub

The result looks like:

Blue: Shape-File as reference

What to do to get a correct GeoTIFF?

Regards
Hardy

Here are the Shape file and the resulting GeoTIFF.
thinkgeo.zip (198.8 KB)

Hi Hardy,

Thanks for your code and file, I have built a sample based on them, it looks GetProjectedShape function is not included here, does it convert the feature from 25832 to 3857 here?

Regards,

Ethan

Hi Ethan,

yes, the GetProjectedShape looks like:

....

BaseProjection.ExternalProjectionParametersString = GetEpsgParametersString(3857)
BaseProjection.InternalProjectionParametersString = GetEpsgParametersString(25832)
BaseProjection.Open()
Return BaseProjection.ConvertToInternalProjection(TheShape)

Regards
Hardy

Hi Hardy,

Thanks for your update, I will try to reproduce it.

Regards,

Ethan

Hi Hardy,

I build a simple sample based on your code, but the logic looks is a little confused.

Your shape file is under 25832, then when you draw it in the image, it also should be 25832, but you get the MapRect for 3857, which means you draw the 25832 image but calculate related parameters with 3857.

I think maybe I still missed something, so the exported tiff image totally not at the same position with the shape file.

Here is the simple sample, I hadn’t complete it so it still be C#, if I missed anything for the sample please let me know.

9432.zip (265.7 KB)

Regards,

Ethan

Hi Ethan,
what we do is:

  1. Load a Feature Layer with EPSG:25832,
  2. Export to GeoTiff,
  3. ReLoad this GeoTiff using EPSG:25832

The Shape file is an example. When exporting and reloading the Tif is not in the expected area…

Regards
Hardy

Hi Hardy,

Thanks for your description.

The 25832 is using the meter as its map unit, the same as 3857, so it looks you don’t need to convert it to 3857 here.

So I modify the test sample follow your information, it looks the exported tiff just cover the shape file, could you please view it?

9432.zip (265.1 KB)

You can build the tiff file by click the first button, then load the tiff in the second button, and then click third button to show or hide the tiff layer to see wether they can be covered.

Regards,

Ethan

Hi Ethan,

thanks for the sample.

You are loading the Shape-File without setting the projection to EPSG:25832.
Why?

And when you are loading the Tiff you also do not set the Projection to EPSG:25832.

So the geometries will behandled in EPSG:3857, correct?

Regards
Hardy

Hi Hardy,

Thanks for your question.

In fact our map don’t have default projection, the projection only useful when you use different projection data.

So if we don’t set projection, the default projection is the data projection.

I think I understand your scenario, your data is under 25832, but when you render it and save it into tiff you have another layer with projection 3857, so you need to convert them to 3857.

Please wait I will modify the sample and see whether it can reproduce this problem.

Regards,

Ethan

Hi Hardy,

I still save the tiff file without projection(that’s in fact 25832, because your shape file is 25832).

And then load the shape file and tiff file after convert them from 25832 to 3857, then in certain scenario, the result cannot totally match. That’s in fact the same as the problem of your other topic “Geotiff jump”.(We still hadn’t solve that, it’s more complex than we thought) So if you want to save the tiff file but don’t need to save it as 3857, please don’t choose save image after reproject.

Here is the certain scenario I found when pan the test result.

But in most of other time it match well:

And I thought you maybe have another scenario:
Render 25832 shape file under projection 3857, then save the shape file into 3857 tiff data.
And load it back, the result look well also.

Here is the test sample code:
9432.zip (259.9 KB)

So here are two scenarios:

  1. Shape file(25832) export to tiff file(25832), just don’t need to set projection to it, and the result will be well.
  2. Shape file(25832) export to tiff file(3857), set projection to shape file, and then don’t need to set projection to the exported tiff file, the result will be looks well.

If I missed anything please let me know.

Regards,

Ethan

Hi Ethan,

I like to explain our common project scenario:

We have several different datasets from different projection (EPSG: 25832, 31466, 4326 etc.).
All these datasets we have to handle in one map.
So we setup a map loading the layers with it’s projection. For example parcels from PostGIS with 25832, aerial images with 31467, OpenStreetMap and some pipes with projection under 25832.

In this scenario we are getting all coordinates (when moving the mouse, digitizing etc.) in EPSG 3857 because map suite will handle this projection by default? Am I wrong?

How to setup up a map with different coordinate systems?

Regards
Hardy

Hi Hardy,

Thanks for your describe, I understand you need to use different projection in the same map, and I think your solution is right.

But I means if you want to save shape file to tiff, the best way is save it before reproject unless the saved tiff require 3857.

So please let me know if the two scenarios I listed don’t cover your requirement.

And I think maybe I missed some points in your sample code, because in my test for the two scenarios the saved tiff can cover the shape file when set them into the same projection. If you found that please let me know and I will test it again.

Regards,

Ethan

Hi Ethan,

I have made some tests and the trick will be to export with EPSG 3587.
If needed we can warp the tiff using gdal.
This will produce the best results.

Thank you for your support.

Hardy

Hi Hardy,

Thanks for your update.

Any question please let us know.

Regards,

Ethan