ThinkGeo.com    |     Documentation    |     Premium Support

Proj4Extension and pj_transform readiness in MapSuite Desktop WPF 4.5

Hi Yale,


    I need to make use of  pj_transform(Void* , Void* , Int32 , Int32 , Double* , Double* , Double* )

            and Proj4Extension.Proj4ExtensionX64.Transform(IntPtr srcCs, IntPtr destCs, Int32 pointCount, Double[] x, Double[] y, Double[] z)

Could ThinkGeo confirm that MapSuite Desktop WPF 4.5 Edition has capability of supporting such operations at code level?  If not, can ThinkGeo implement  in the wpf edition  pj_transform(Void* , Void* , Int32 , Int32 , Double* , Double* , Double* ) and Proj4Extension.Proj4ExtensionX64.Transform(IntPtr srcCs, IntPtr destCs, Int32 pointCount, Double[] x, Double[] y, Double[] z) to do coordinates transformation with datum shifts? I believe that there is a great majority of wpf map application developers who want this kind of significant support from ThinkGeo.




Thanks very much.


Franklin


 


 


 


 



Franklin,


Thanks for your post and questions.
 
The Transform is the core API provided by the Proj4 library, we did use it in our UnmanagedProj4Projection class, while we does not public this wrapper API out. I think the two APIs ConvertToExternalProjection and ConvertToInternaProjection are very helpful and useful, why do not use them?
 
Any more questions please feel free to let me know.
 
Thanks.
 
Yale

Yale, 
  
   When you say the two APIs are very useful, do you mean that they can be instrumental to carrying out the Coordinates Transformations with Datum Shifts? 
 Can you give me an example to illustrate how to use the two APIs in this regard? Thanks very much. 
  
 Franklin

Franklin,


 I don't know what the case of your datum transformation exactely is but I can point you out to some samples. We have a Code Community sample that shows how to transform a point in Geodetic Datum E50 (That's a european datum) to Geodetic in WGS84 datum to match our World Map Kit. I suggest you check it out, Datum Transformation  wiki.thinkgeo.com/wiki/Map_Suite_Wp...sformation


Thank you.



Val, 
  
  Thanks for the pointer. I will study the example and give the feedback to you  in the ticket.  
  
 Franklin

Hi Val, 
  
   I have studied the example and made some comments in the Ticket (3358). If you say the purpose of the example is to convert the coordinates in ED50 geodetic system to its equivalents in WGS84 geodetic system based on the two datums and shifts, it is less than half-way through. 
 Please refer to my reply in the ticket. 
  
 Franklin

Hi Val, 
  
   The example project cannot be run due to "Remote Server Access problem" at run time. In order to clarify the effectiveness of the example method, 
 I will upload a test data file which contains 2 datums in Ticket 3358, for you to test out the method. Please take a look at the ticket. Franklly speaking, 
 I cannnot find from the websites (given above Proj4.InternalProjectionParameters  in TestForm.cs) the datum shift parameters which tally with the example statement: proj4.InternalProjectionParameters="+proj=longlat +ellps=intl +towgs84=-157.89,-17.16,-78.41,2.118,2.697,-1.434,-1.1097046576093785 +no_defs"; 
 Why this proj4.InternalProjectionParameters cannot be accepted in wpf desktop 4.5, although I have created reference to MapSuiteCore in WPF 4.5? 
 Thanks. 
  
 Franklin

Franklin,


 I am sorry if we did not give you the complete answer first. We did not know with what datum exactely you were dealing with. Now that we have that information, we can give the full answer.


 So, for P2 Exc T9 datum Samboja (Indonesia), you need the EPSG 4125 spatial-reference.org/ref/epsg/4125/. Please see the code below to see how I went I did the datum shift from P2 Exc T9 to Wgs84. Also, you can see in the screenshot the result and how the same point in p2 Exc T9 is shifted about 100 meters to the south west compared to WGS84.



 


 



           // Set the extent and the background color
            wpfMap1.CurrentExtent = new RectangleShape(117.146, -0.960, 117.150, -0.963);
            wpfMap1.Background = new SolidColorBrush(Color.FromRgb(148, 196, 243));


            //Displays the World Map Kit as a background.
            WorldMapKitWmsWpfOverlay worldMapKitWmsWpfOverlay = new WorldMapKitWmsWpfOverlay();
            wpfMap1.Overlays.Add(worldMapKitWmsWpfOverlay);


            //InMemoryFeatureLayer for displaying the points.
            InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
            inMemoryFeatureLayer.Open();
            inMemoryFeatureLayer.Columns.Add(new FeatureSourceColumn("Datum", "string", 20));
            inMemoryFeatureLayer.Close();

            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.DarkGreen,
                                                                              10, GeoColor.StandardColors.Black, 2);
            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Datum", "Arial", 10, DrawingFontStyles.Bold,
                                                                              GeoColor.StandardColors.Black, 10, 0);


            inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            double longitudeP2_Exc_T9 = DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(117, 8, 50.972);
            double latitudeP2_Exc_T9 = -DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(0, 57, 45.589);

            //We are adding the points for P2 Exc T9 and WGS84. You have to understand that they are actually the same points except that two different
            //datums are used.

            //The point is originatly in degrees with P2 Exc T9 datum. We display it to show how offset it is compared to the same point in degrees with WGS84 datum
            PointShape P2_Exc_T9pointShape = new PointShape(longitudeP2_Exc_T9, latitudeP2_Exc_T9);
            Feature P2_Exc_T9feature = new Feature(P2_Exc_T9pointShape);
            P2_Exc_T9feature.ColumnValues.Add("Datum", "P2 Exc T9");

            inMemoryFeatureLayer.InternalFeatures.Add(P2_Exc_T9feature);

            //We take the same point in P2 Exc T9 datum and apply Datum trasformation to it so that it is using WGS84 as for the World Map Kit.
            //So, the point in WGS84 is the corrected point from P2 Exc T9 so that it matched World Map Kit.
            //Notice that for datum transformation, the same API is used where you set the parameters for InternalProjectionParameters and externalProjectionParameters.

            //To go from P2 Exc T9 datum to WGS84 datum so that the point matches the projection of the map.
            ManagedProj4Projection proj4 = new ManagedProj4Projection();

            //Degrees P2 Exc T9 for internal projection
            //spatial-reference.org/ref/epsg/4125/  (for reference)
            //Datum shift using +towgs84 parameters with Delta X -404.78, Delta Y 685.68 and Delta Y 45.47.
            //See trac.osgeo.org/proj/wiki/GenParms#towgs84-DatumtransformationtoWGS84 for futher info on parameters.
            proj4.InternalProjectionParameters = "+proj=longlat +ellps=bessel +towgs84=-404.78,685.68,45.47,0,0,0,0 +no_defs";

            //WGS84 projection (datum) for external projection
            //spatialreference.org/ref/epsg/4326/  (for reference)
            //en.wikipedia.org/wiki/WGS84 (for further information)
            proj4.ExternalProjectionParameters = ManagedProj4Projection.GetWgs84ParametersString();

            proj4.Open();
            Vertex WGS84vertex = proj4.ConvertToExternalProjection(longitudeP2_Exc_T9, latitudeP2_Exc_T9);
            proj4.Close();

            Feature WGS84feature = new Feature(new PointShape(WGS84vertex.X, WGS84vertex.Y));
            WGS84feature.ColumnValues.Add("Datum", "WSG84");

            inMemoryFeatureLayer.InternalFeatures.Add(WGS84feature);

            LayerOverlay dynamicOverlay = new LayerOverlay();
            dynamicOverlay.Layers.Add("WGS84Feature", inMemoryFeatureLayer);
            wpfMap1.Overlays.Add(dynamicOverlay);

            //Displays Scale Bar to how offset the same point is based on the datum.
            //You can notice that the P2 Exc T9 point is offset about 100 meters to the south west compared to WGS84.
            //When doing a datum transformation, the difference is slight, usually a few meters. It can be thought as merely a correction.
            //When changing projection to the data, though, the difference is huge. We change completely of coordinate system and the same
            //point cannot be displayed on the same map.
            ScaleBarAdornmentLayer scaleBarAdornmentLayer = new ScaleBarAdornmentLayer();
            scaleBarAdornmentLayer.UnitFamily = UnitSystem.Metric;
            scaleBarAdornmentLayer.Location = AdornmentLocation.LowerLeft;

            AdornmentOverlay adornmentOverlay = new AdornmentOverlay();
            adornmentOverlay.Layers.Add(scaleBarAdornmentLayer);
            wpfMap1.Overlays.Add(adornmentOverlay);

            wpfMap1.Refresh();


Franklin, 
  
  I also want to inform you that you will find the entire Wpf sample app attached in your support ticket.

Hi Val, 
  
  Beautiful CustomScaleBar, is it’s code available in any CodeComunity project? 


Hi Carlos, 
  
 I guess that is the ThinkGeo.MapSuite.Core.ScaleBarAdornmentLayer. 
 And Val, please point it out if my guess is wrong. 
  
 We’d suggest you to use it after you get the next build of WpfDesktopEdition, because we just fixed a bug in AdornmentOverlay. 
  
 Regards, 
 Tsui

Yes, the scale bar that you can see in the picture is ScaleBarAdormentLayer. If you want to customize your scale bars, we have a Code Community sample Custom ScaleBar  wiki.thinkgeo.com/wiki/Map_Suite_Wp..._Scale_Bar 



Hi Val, 
  
  I know about the Code Community Custom ScaleBar, it’s what I’m using now, but I liked this, and did not remember the AdornmetLayer one that way. 
  
  Carlos.

Carlos, 
  
   Yes, ScaleBarAdornmentLayer is available ThinkGeo.MapSuite.Core and it is a very convenient and eye pleasing adorment for the map. Do you need soem guidance on how to accomplish a specific task with ScaleBar? Thank you.

It’s ok, and also I don’t want to hijack this thread more than I’ve already done. 
  
 Thanks 
 Carlos.

Carlos, 
  
  That’s alright. This is what discussion forums are for :-). 
  
 Franklin, 
  
  To go back to the original theme in this thread, I hope that we have your datum transformation issue resolved now. In your support ticket are the full details of the solution. Thank you.

Hi Val, 
  
   Could you give me the coordinates of the two points which you showed on 21 Feb 11 (3:19pm) map above? I woujld like to have them in both (Easting,Northing) and (Latitude, Longitude). It is difficult to check on the accuracy of your transformation by looking at the map. Thanks very much. 
  
 Franklin

The screenshot showed on 21 Feb 3:19pm was taking from the sample app I attached for you in your Support Ticket 3358. The two points are in decimal degrees (Longitude, Latitude), one in P2 Exc-T9 datum, the other in WGS84. Please, read the comments in the sample app for the explanation and for further readings on that subject.


 "Easting, Northing"  are for how x and y values apply for projection in meter or feet (as opposed to geodetic (Longitude, Latitude). You are not giving us any projection information in this post but based on the projection information in image001.png that you attached in your support ticket (I include it with the relevent parts  in this post for everybody to understand what we are talking about), I assume that you want to see your point in UTM zone 50 south. Next I will show you the code to go from P2 Exc-T9 (Longitude/Latitude) to UTM zone 50 south and from WGS84 (Longitude/Latitude) to UTM zone 50 south using th example in the image.


 


 



 As promised, I wrote the code to go from P2 Exc-T9 to UTM 50 S and from WGS84 to UTM 50 S using the example in your image. You can see the results are the same within a milimeter or two. So I think I proved to you that the methods presented to you are accurate.



See the code. Note that in the first case the external projection is UTM 50 S using datum P2 Exc-T9 and in the second case the external projection is also UTM 50 S  but using datum WGS84.


 



//Longitude and Latitude for Datum P2 Exc-T9
double longitudeP2_Exc_T9 = DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(117, 8, 50.972);
double latitudeP2_Exc_T9 = -DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(0, 57, 45.589);

//Longitude and Latitude for Datum WGS84
double longitudeWGS84 = DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(117, 8, 52.503);
double latitudeWGS84 = -DecimalDegreesHelper.GetDecimalDegreeFromDegreesMinutesSeconds(0, 57, 43.746);


//To go from P2 Exc T9 datum to UTM 50 S
ManagedProj4Projection proj4_P2_Exc_T9_To_UTM = new ManagedProj4Projection();

//Degrees P2 Exc T9 for internal projection
//spatial-reference.org/ref/epsg/4125/  (for reference)
//Datum shift using +towgs84 parameters with Delta X -404.78, Delta Y 685.68 and Delta Y 45.47.
//See trac.osgeo.org/proj/wiki/GenParms#towgs84-DatumtransformationtoWGS84 for futher info on parameters.
proj4_P2_Exc_T9_To_UTM.InternalProjectionParameters = "+proj=longlat +ellps=bessel +towgs84=-404.78,685.68,45.47,0,0,0,0 +no_defs";

//UTM zone 50 South (datum P2 Exc-P9 ) for external projection
//spatial-reference.org/ref/epsg/2550/  (for reference)
proj4_P2_Exc_T9_To_UTM.ExternalProjectionParameters = ManagedProj4Projection.GetEpsgParametersString(2550); // UTM 50 S datum P2 Exc-P9

proj4_P2_Exc_T9_To_UTM.Open();
Vertex UTM_From_P2_Exc_T9_vertex = proj4_P2_Exc_T9_To_UTM.ConvertToExternalProjection(longitudeP2_Exc_T9, latitudeP2_Exc_T9);
proj4_P2_Exc_T9_To_UTM.Close();

//? UTM_From_P2_Exc_T9_vertex.X
//516 408.01
//? UTM_From_P2_Exc_T9_vertex.Y
//9 893 606.49

//------------------------------------------------------------------------------------------------------------------------------

//To go from WGS84 datum to UTM 50 S
ManagedProj4Projection proj4_WGS84_To_UTM = new ManagedProj4Projection();

//Degrees WGS84 for internal projection
//spatial-reference.org/ref/epsg/4326/  (for reference)
proj4_WGS84_To_UTM.InternalProjectionParameters = ManagedProj4Projection.GetEpsgParametersString(4326); // GetWgs84ParametersString();

//UTM zone 50 South (datum WGS84) for external projection
//spatial-reference.org/ref/epsg/32750/  (for reference)
proj4_WGS84_To_UTM.ExternalProjectionParameters = ManagedProj4Projection.GetEpsgParametersString(32750); // UTM 50 S WGS84

proj4_WGS84_To_UTM.Open();
Vertex UTM_From_WGS84_vertex = proj4_WGS84_To_UTM.ConvertToExternalProjection(longitudeWGS84, latitudeWGS84);
proj4_WGS84_To_UTM.Close();

//? UTM_From_WGS84_vertex.X
//516 457.23
//? UTM_From_WGS84_vertex.Y
//9 893 652.87