ThinkGeo.com    |     Blog    |     Wiki    |     Support

MapUnit Meter to Decimal Degrees

We have a Desktop Edition application that has always had the MapUnit set to DecimalDegrees.  We display many things on the map such as lines, circles, rectangles, polylines, and markers.  Up until now we have always rendered these graphics using map coordinates in Decimal Degrees.  Now, our user would like us to use aeronautical charts that are available on the FAA web site.  I have downloaded several of these FAA charts and they have a ".tfw" that has the map coordinates measured in meters.  I have modified our application to be able to load a GeoTiifRasterLayer and display the ".tif" image using MapUnit Meter.  However all of our graphics are still render as if the coordinates are still Decimal Degrees.  



Is there anyway to convert the ".tfw" file from meters to decimal degrees? If I do convert the ".tfw",  will the ".tif" image display correctly in decimal degrees or does the ".tif" image also need to be converted?  



I do not have a good understanding of the ManagedProj4Projection and UnmanagedProj4 classes.  Will I need to handle the projection for these images if they are converted to decimal degrees?



Any help you can give me would be greatly appreciated.



Richard



 

Hi Richard,



I think your issue is a projection issue and we don’t need to do anything to convert “.tfw” file but just apply a projection on the GeoTiffRasterLayer. Some codes like below:


GeoTiffRasterLayer tiffLayer = new GeoTiffRasterLayer(@"…\Data\World.tif");
            ManagedProj4Projection managedProj4 = new ManagedProj4Projection();
            managedProj4.InternalProjectionParametersString = ManagedProj4Projection.GetSphericalMercatorParametersString();
            managedProj4.ExternalProjectionParametersString = ManagedProj4Projection.GetDecimalDegreesParametersString();
 
            tiffLayer.ImageSource.Projection = managedProj4;

With the above codes, we have translate the Tiff layer from meter to decimal degree.



As for the differences between ManagedProj4Projection and UnmanagedProj4Projection. the ManagedProj4Projection is built with managed codes, however, the UnmanagedProj4Projection depends on a third-party dll in system 32. In general, the ManagedProj4Projection is suitable for  most of cases.



Hope it helps.

Troy

Troy, 
  
 Thanks for the guidance on this. 
  
 I have tried the ManagedProj4Projection as you suggested in the sample code above.  It works very well as far as displaying the GeoTiff image while keeping my winformsMap set to MapUnit Decimal degrees.  The only issue is that with the GetSpericalMercatorParametersString the GeoTiff image is always centered on a latitude of 0.0 and a longitude of 0.0.  So I have been digging into the Proj4 InternalProjectionParametersString format. I found that the Parameters do contain lat_0 and lon_0 which allow you to set the "center" latitude and longitude for the projection.  So after some googling, I found the FWTools 2.4.7 utility called listgeo.exe.  When I ran the listgeo on my GeoTiff file with the -proj4 command line option, it dumps out a lengthy metadata on the tif file which includes ProjFalseOriginLatGeoKey and ProjFalseOriginLongGeoKey with the latitude and longitude values that I need.  It also nicely dumped out "PROJ.4 Definition as follows: 
  
 +proj=lcc +lat_0=42.16667 +lon_0=-72.9667 +lat_1=46.6667 +lat_2=41.3333 +x_0=0.000 +y_0=0.000 +ellps=GRS80 +unit=m 
  
 I cut and pasted this string into the InternalProjectionParametersString of the ManagedProj4Projection and the GeoTiff loaded at the correct latitude/longitude and appears to zoom/pan etc correctly. 
  
 So, now I am in business if I can just figure out how to read the metadata from the GeoTiff file just like the listgeo.exe utility in the FWTools 2.4.7.  I have tracked it down that I probably need to call GTIFGetDefn or GTIFGetProj4Defn from the GeoTiff_FW.dll which is called in listgeo.exe.  I am trying to get these methods to work but before I waste a lot of time, I thought it would be worth asking if there is any access to the GeoTiff metadata through the MapSuite classes or libraries.  I noticed that GeoTiffRasterLayer does have a "Projection" object but it is null when I first open the GeoTiff.  Can you recommend an easier path to get the metadata than trying to use the GeoTiff_FW.dll out of FwTools? 
  
 Any help or guidance is greatly appreciated. 
  
 Thanks 
  
 Richard Styer

Hi Richard, 
  
 Okay, Richard, I got your issue, but sorry to say, currently, we didn’t support reading its projection info from GeoTiff metadata. 
 However, I have submitted this enhancement on our Issue system and we will work on it once we have enough resources. Before that, as for a temporary solution, I am afraid you still need the GeoTiff_FW.dll help to read the proj information out and then apply it in map suite. 
  
 Sorry for any inconvenience. 
 Thanks, 
 Troy 


Troy,



Thanks for the info and advice.



I was able to get this to work by adding a wrapper dll around the GTIFGetDefn and GTIFGetProj4Defn.  It is fairly simple as the GTIFGetProj4Defn returns the Proj4 Projection string for the GeoTiff file.  This string can be used directlry as the InternalProjectionParamaterString of the ManagedProj4Projection.  So the code to open the GeoTiff is 



                        var proj4String = new StringBuilder(2048);

                        GeoTiffHelper.GeoTiffWrapper.GetGeoTiffProj4String(sFilePath, proj4String, 2048);



                        ManagedProj4Projection proj4 = new ManagedProj4Projection();

                        if (!string.IsNullOrEmpty(proj4str) && proj4str.Contains("+proj"))

                        {

                            proj4.InternalProjectionParametersString = proj4str; //Proj4 parsed from metadata of the GeoTiff file.

                        }

                        else

                        {

                            proj4.InternalProjectionParametersString = ManagedProj4Projection.GetSphericalMercatorParametersString(); //SpericalMercator

                        }

                        proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetDecimalDegreesParametersString(); //Decimal Degrees

                        proj4.Open();


                        GeoTiffRasterLayer layer = new GeoTiffRasterLayer(sFilePath);

                        layer.Open();

                         layer.ImageSource.Projection = proj4;





                        Maybe this will help someone else if they need to handle GeoTiff with DecimalDegrees map layers.   I will try to attach the Wrapper DLL code to this message.



Richard







GeoTiffHelper.zip (50.3 KB)

Troy, 
  
 It would be great if Map Suite would expose the GTIFGetProj4Defn thru the GeoTiffRasterSource classes.  The coding was minimal and most of it is probably already in use to expose the GetImageWidth and GetImageHeight already in the implementation.  The RasterSource classes already has a HasProjectionText property and GetProjectionText method but they are always false and null respectively from what I can tell.  Maybe I haven’t figured out what causes these to be defined? 
  
 Thanks  
  
 Richard

Hi Richard,



I want to say you are a nice people to share those for us. That is very helpful for us to support reading project information. 

For the reason why the HasProjectionText adn GetProjectText always returns false and null. That is because the instance of the RasterSource is GeoTiffRasterSource and we don’t implements those methods without the world file. But there is a workaround by defining a custom TiffLayer and TiffRasterSource before we support to reading project string directly from its metadata.



Please try the attached files.

Hope it helps.

Troy

customTiffRasterLayer.txt (3.73 KB)

Troy, 
  
  
 Thanks for all your help and the sample code. 
  
 Richard

Hi Richard, 
  
 You are welcome and any other questions, feel free to let us know. 
 Thanks, 
 Troy

Troy and whoever reviews this list,

As discussed above the MapSuite code does not appear to support reading the projection string data from the GeoTiff file. I have been trying to convert our old MapSuite 9.0.0.x code to use the newer MapSuite 10.1.0 DLLs from nuget.org. Of course this has broken my customized build as described above where I download the LibGeoTiff and built custom wrapper DLL around it to read the projection string from the GeoTiff file. The MapSuite 10.1.0 uses some version of geotiff.dll and liftoff.dll to support the ThinkGeo.MapSuite.Layers.Geotiff classes in 10.1.0. I haven’t been able to identify which version of these files are part of the MapSuite dependency for LibGeoTiff from nuget…org but whatever versions they are, they are not compatible with the wrapper DLL I had to create. So I am back to the original issue, the GeoTiffRasterLayer and GeoTiffRasterSource both provide a GetProjectionText method but neither one seems to work. I also tried UnmanagedGeoTiffRasterLayer and UnmanagedGeoTiffRasterSource but they just produce exceptions about class initialization.

Will there ever be a solution to getting the Projection string from the raster files? Has anyone else solved the issue to read the latitude and longitude from the projection string so that the images can be located properly?

Richard

Hi Richard,

I think your custom wrapper don’t work should because we moved the folders under system folder to the bin folder, if you can modify the logic that should works also.

And we want to know does the wrapper built by yourself or it’s a professional service from us before? If your code don’t works maybe you can let us know your referenced detail 3rd part version, and we can compare with ours in V10.

Regards,

Don

Don

Thanks for answering so quickly.

I don’t think it has anything to do with the location of the dlls. I tried running with the ThinkGeo provided dlls in the bin folder and I also tried running with the older dlls in the bin folder that I had built and there are errors both ways. (I have not removed the MapSuite 9.0 folders from the Windows\System32 yet).

I built the wrapper myself because the answers above were indicating that the problem was low on ThinkGeo priorities (no professional services). I used the open source for libGeoTiff from the internet it contained the following version

proj-4.8.0.zip builds output proj.dll
tiff-4.0.3.zip
libgeotiff-1.4.0.zip builds output libtiff.dll and geotiff.dll

The wrapper I created was just to wrap the unmanaged C++ in these open source libraries in order to be able to reference and call the unmanaged classes in managed C# code. I needed to expose GTIFGetDefn and GTIFGetProj4Defn to be able to call it from C# managed code. I did not alter the open source libraries in any way except to build import libraries to use in the C++ wrapper project. I used libtiff_i.lib and geotiff_i.lib in the wrapper project.

Hi Richard,

Thanks for list the information, today I double check the API and found this had been supported by our V10.

Please try to use it by our managed and unmanaged mode and let us know whether it works for you.

If you still met problem with V10, please upload us a sample with data, we can help you look into it.

Regards,

Don

I am having a similar issue when going from v8 to v10. Was this ever resolved?

Hi Ernest,

I think your question should be the same in the ticket, we had replied you there.

If that’s another question, could you please provide us more detail information so we can help you solve it?

Regards,

Ethan