ThinkGeo.com    |     Documentation    |     Premium Support

WGS84 to NAD27 Conversion

Hi,

I’m doing some transforms from WGS84 to NAD27 and I’m getting some incorrect values.

Below are the strings I am using for the projection. I’ve added the translation towgs84 field for the conversion I want to use (EPSG: 15856)

Internal string = “+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”
External string = “+proj=utm +zone=15 +ellps=clrk66 +datum=NAD27 +units=m +no_defs +towgs84=-7,158,172”

Here is my test point in WGS84 UTM Zone15N
944910.0, 3178338.3

When I convert my test point using ConvertToExternalProjection, I get the following:
944918.7, 3178163.9

I am expecting the following (from QGis):
944942.4, 3178137.2

The difference is more than 20 meters.

Oddly enough, it doesn’t seem to matter what values I put into the towgs84 field, I end up with the same answer every time which can’t be right. Seems like it is ignoring the towgs84 field for NAD27.

I have done the same test with WGS84 to ED50 and I get correct answers.

Thanks,
Damian

Thanks Damian,
I use QGIS to do the conversion. I got a different result. The result is
944920.50732006679754704 3178137.49636736558750272

Here is the script

crsSrc = QgsCoordinateReferenceSystem()
crsSrc.createFromProj("+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")

crsDest = QgsCoordinateReferenceSystem()
crsDest.createFromProj("+proj=utm +zone=15 +ellps=clrk66 +datum=NAD27 +units=m +no_defs +towgs84=-7,158,172")

transformContext = QgsProject.instance().transformContext()
xform = QgsCoordinateTransform(crsSrc, crsDest, transformContext)

pt1 = xform.transform(QgsPointXY(944910.0, 3178338.3))
print(“Transformed point:”, pt1)

I also use the online service. https://mygeodata.cloud/cs2cs/ it get the same result as the python script

Both above ways. The towgs84 seem won’t effect the result.

And I got the same result as yours when use mapsuite do the conversion which is 944918.7, 3178163.9. I think this result is wrong. I am still looking into the detail. Just need figure out the correct result. Do you have the steps using QGIS do the conversion. I was using python script.

Thanks

Frank

Hi Frank,

I just read the following in a QGis blog post.

" Alternatively, +datum=nad27 will look up all north American datum shift values from conus and other grid shift files. This overrides any +towgs84 parameter set, as long as you are inside the area of grid file definition."

And, if I drop the +datum=NAD27 and leave the ellipse, the +towgs84 values start making an impact using the mygeodata website you provided.

So, that explains why the results are always the same, but not why the answers are different. I am curious about the grid shift files. As far as I know, the proj4 distribution in Mapsuite doesn’t have any conus shift files packaged… Maybe that’s the issue is it reverts to some other method when it can’t find what it wants.

As far as my test point, that’s another mystery. I loaded a shape in WGS84 and then changed the project projection to NAD27 15N at which point it asked me for the transform (as above). The value I sent you was the value of the point of interest from the shape on the screen after the conversion completed. I get the same result as you using the python editor, so let’s assume that is correct and just focus on why Mapsuite gives different result.

One other observation - If I drop the +datum=NAD27 in the python editor and run it again, I get the same result as Mapsuite along with an error as follows. I have no idea why QGis is asking for grid files when we say we want to use a 3 parameter shift.

The preferred transform between EPSG:32615 - WGS 84 / UTM zone 15N and EPSG:2027 - NAD27(76) / UTM zone 15N is not available for use on the system.

  • This transformation requires the grid file “May76v20.gsb”, which is not available for use on the system.

Current transform “Inverse of UTM zone 15N + Ballpark geographic offset from WGS 84 to NAD27(76) + UTM zone 15N” has an unknown accuracy, while the preferred transformation “Inverse of UTM zone 15N + Inverse of NAD27(76) to WGS 84 (1) + UTM zone 15N” has accuracy 1 meters.

Thanks,
Damian

Thanks Damian,
I found the solution for this one. We will apply the changes to the next release. If you want a quick fix on your side here are the steps.

  1. Copy the files in share.zip https://drive.google.com/file/d/1s104bx1OlOBdJgGPH5vhRnutm0aenGG5/view?usp=sharing to overwrite all files upder your \bin\Debug\gdaldata\share

  2. Set the environment variable PROJ_LIB to point to your \bin\Debug\gdaldata\share folder
    image

  3. Restart the visual studio. And use the UnmanagedProjectionConverter.

PointShape pointShape = new PointShape(944910.0, 3178338.3);
UnmanagedProjectionConverter unmanagedProjectionConverter = new UnmanagedProjectionConverter("+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs", “+proj=utm +zone=15 +ellps=clrk66 +datum=NAD27 +units=m +no_defs +towgs84=1”);
unmanagedProjectionConverter.Open();
var x2 = unmanagedProjectionConverter.ConvertToExternalProjection(pointShape);

You should get the same result as the QGIS.
We will apply the #1 and #2 changes to the next release. So later you don’t need copy the files or set the variables. We will let you know once the new release avaiable.

Thanks

Frank

Hi Frank,

This sounds great, but I’m having some issue to replicate the results.

I do not have any directory in my bin called gdaldata from which to delete the files. Your note seems to indicate that it should exist.

I went ahead and added the directory and set the system variable, computer reboot and tried. It didn’t change the results. Question: Why does it have to go into bin? What if user already has a proj_lib var defined from some other app?

Also, I don’t have any object called UnmanagedProjectionConverter. Missing library?

I’m using version 10.

Thanks,
Damian

Thanks Damian,
It is my fault. I don’t know you are on the version 10. Here is the work-around for the version 10.

  1. Copy the files in share.zip https://drive.google.com/file/d/1s104bx1OlOBdJgGPH5vhRnutm0aenGG5/view?usp=sharing to your \bin\Debug\share. It doesn’t have to be there. It could be anywhere you want.

  2. Set the environment variables base on the #1’s path.
    image

  3. You probably already done the above steps. For mapsuite 10 you need use this libary.
    https://www.nuget.org/packages/ThinkGeo.MapSuite.Shapes.UnmanagedProj4Projection/10.6.3?_src=template

  1. Now use the unmanaged proj4 to replace your manage proj4. Here is an example

PointShape pointShape = new PointShape(944910.0, 3178338.3);
UnmanagedProj4Projection unmanagedProj4Projection = new UnmanagedProj4Projection("+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs", “+proj=utm +zone=15 +ellps=clrk66 +datum=NAD27 +units=m +no_defs +towgs84=1”);
unmanagedProj4Projection.Open();
var x2 = unmanagedProj4Projection.ConvertToExternalProjection(pointShape);
System.Diagnostics.Trace.WriteLine(x2.ToString());


Here is the full project
WpfApp25.zip (10.0 KB)

Note: after you set the environment variable. It won’t effective immediately. You have to restart the visual studio.

Thanks

Frank

Hi Frank,

Thanks for this.

I do have one kind of sticky point though. I have over 70 references to Proj4Projection in my project. What are the guidelines for replacing Proj4Projection with UnmanagedProj4Projection? Why would you ever use one over the other if one gives you incorrect results? I really don’t want to introduce projection errors into my project by globally replacing them all.

Regards,
Damian

Thanks Damian,
We built the Proj4Projection(Managed) by C# few years ago(around 10 years). So it kind of old. But you know the projection algorithm has not change for many years. So Proj4Projection(Managed) still work for most cases. And the .Net managed code could also work on the iOS and Android platform. We found Gdal also has very good support for a lot of projections. So we add a wrapper for the Gdal which is UnmanagedProj4Projection. The most of QGIS features are based on the Gdal.

So if your application is windows application. We recommend use UnmanagedProj4Projection. If we want to reduce the rick. We may need just replace the Proj4Projection which related with NAD27.

Thanks

Frank

Thanks for the details Frank. Makes sense.

My application doesn’t have a specific part that would only relate to the NAD27 datum, but since I am using windows seems safe to convert all to the unmanaged code.

Regards,
Damian

Thanks Damian,
I am going to close this one. Go ahead let us know if you have any more question.

Thanks

Frank

Hi Frank,

I’m coming back to this issue with a slightly different question.

I’m looking to deploy the gdaldata\share libraries referenced above with my application; however, even though I have them in my bin directory, the application doesn’t seem to pick them up unless I set PROJ_LIB for the process like in the following.

Environment.SetEnvironmentVariable(“PROJ_LIB”, Application.StartupPath + @"\ThinkGeo\gdaldata\share", EnvironmentVariableTarget.Process);

Is there a recommended approach to get my application to find gdaldata\share?

Thanks,
Damian

hi Damian,

Did you run into any issues with the “Environment.SetEnvironmentVariable” code? The code is needed. If you just don’t want to write code to set environment variable, could you try to find which path this variable points to and try to gdaldata\share folder to that path.

Thanks,
Leo

Hi Leo,

No, I haven’t seen any issues. I just wondered if I could confirm this method had been tested by ThinkGeo and was an approved way to do it.

Thanks,
Damian

Hi Damian,

Yes, it’s an approved way. Because MapSuite doesn’t use gdal data, so you have to setup the relevant environment variable.

Thanks,
Leo