ThinkGeo.com    |     Documentation    |     Premium Support

Proj4Projection Not Projecting On The Fly

Hi:


With the WPF Desktop edition, I am experiencing the following problem:


 


- Map display is in metres


- I've created a Proj4Projection with 4326 Internal and google External.


- I've created an InMemoryFeatureLayer and applied the Proj4Projection to the Feature Source


- The Layer has been added to an overlay, which is added to the map.


- Adding a WGS84 point to the layer in question does not project it on the fly.  The only way I can get it to display in the right location is to project it first, which defeats the purpose.


Can anyone please explain how the projection / internal / external part works?  The API isn't very descriptive.


Regards,



Hi Jonathan, 
  
 You are right. Apply the Proj4Projection to the Feature Source of InMemoryFeatureLayer won’t reproject your point on the fly, it only works well if you are using ShapeFileFeatureLayer. 
  
 If you are using InMemoryFeatureLayer you can only reprojection your point before add it to the layer: 
  
 Proj4Projection proj = new Proj4Projection(); 
             proj.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326); 
             proj.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString(); 
  
             proj.Open(); 
             layer.InternalFeatures.Add(new Feature(proj.ConvertToExternalProjection§)); 
  
 Regards, 
  
 Don

 Don, 


So what is the use of setting the Projection property on the FeatureSource if you do not re-projection points that are added to it?  This seems like something easy you guys can fix.  If I set the Projection property on a FeatureSource, I would expect all points added to it to be added to it to be reprojected automatically.


 



Klaus, 
  
 We have the Projection property there because it inherited from base class. I think maybe we will redesign that property in future. 
  
 For why we cannot re-projection the point added to InMemoryFeatureLayer on the fly, I just can talk my understanding, because I am not the designer. 
  
 I think when we use ShapeFileFeatureLayer, all shapes saved in the shape file, at most time data is read only for map, and map "knows" all the features under the same projection. But when we use InMemoryFeatureLayer, map cannot make sure the added feature under same projection, if customer add one 4326 data and then he want to add one 900913 data directly, he still need to reprojection the 2nd data back to 4326, the process also confused. Beside, the InMemoryFeatureLayer mainly for improve render performance, add projection logic will reduce that. 
  
 Regards, 
  
 Don

 Thanks, I didn't see that anywhere in the documentation.


Regards,



Jonathan,  
  
 That’s our lack for documentation. We will try to make all of our APIs more descriptive and the documentation more detail.  
  
 Thanks for your posts, that’s very helpful for us to be better.  
  
 Regards,  
  
 Don

Hi, 
 Is it possible to reproject data in Cape Datum coordinate system to WGS 84 or UTM on the fly using Proj4Projection?  
 Regards, 
 Jacob

Hi Jacob,



Yes, we can reproject most of the coordinate system each other. In your case, we need to know which EPSG code of the Cape Datum and then we can use the below codes to finish the reprojection:


Proj4Projection proj4 = new Proj4Projection();
proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(Cape EPSG); 
proj4.ExternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326); // WGS 84
proj4.Open();
RectangleShape sourceShape = new RectangleShape(extent on Cape Datum);
RectangleShape targetShape = proj4.ConvertToExternalProjection(sourceShape);

So, let’s find the EPSG code of the Cape is and here are some links where we can find the most of the EPSG in the world.

spatialreference.org/

epsg.io/



If you have any questions on the projection conversion, please feel free to let us know and we will explain it more clearer if you need.

Thanks,

Troy


Hi, 
  
 I have to insert a point on the map (which has bing maps as a layer) based on the following values entered by the user. 
 Easting  (eg. 382949.15)  
 Northing (eg. 6494729.89) 
 Zone (eg. 56) 
 Grid System (eg. UTM) 
  
  
 With the half cooked code below, I am able to display a point on the map, but the result is no where near to where it should be. How do I incorporate the missing projection and input values of zone and grid system. 
  
 

double dblEasting = 0;
double dblNorthing = 0;

dblEasting = Convert.ToDouble(txtEasting.Text);
dblNorthing = Convert.ToDouble(txtNorthing.Text);

ManagedProj4Projection proj4 = new ManagedProj4Projection();
                    
proj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326);
                    
proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString(); 
                    
proj4.Open();
Vertex vertexPoint1 = proj4.ConvertToExternalProjection(dblEasting, dblNorthing);
proj4.Close();

PointShape pointShape1 = new PointShape(vertexPoint1);

LayerOverlay dynamicOverlay = new LayerOverlay();

wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(new Feature(pointShape1));

wpfMap1.CurrentExtent = new RectangleShape((vertexPoint1.X - 100), (vertexPoint1.Y + 100), (vertexPoint1.X + 100), (vertexPoint1.Y - 100));
    
wpfMap1.Refresh();


 
 
  
 Thanks in advance, 
 Jacob

Hi Jacob, 
  
 Please let me know whether this is your projection: 
 spatialreference.org/ref/epsg/wgs-84-utm-zone-56s/ 
  
 Your code can render point on my end. But it still have some problem: 
  
 1. You haven’t set correct MapUnit 
 2. Your point is not under 4326, so the InternalProjectionParametersString shouldn’t be 4326. In my modified code as below, I just thought your point is under EPSG:32756 and you want to show it under 4326 
  
 
        private void WpfMap_Loaded(object sender, RoutedEventArgs e)
        {
            Map1.MapUnit = GeographyUnit.DecimalDegree;

            double dblEasting = 382949.15;
            double dblNorthing = 6494729.89;

            //dblEasting = Convert.ToDouble(txtEasting.Text);
            //dblNorthing = Convert.ToDouble(txtNorthing.Text);

            ManagedProj4Projection proj4 = new ManagedProj4Projection();

            proj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(32756);

            proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetDecimalDegreesParametersString();

            proj4.Open();
            Vertex vertexPoint1 = proj4.ConvertToExternalProjection(dblEasting, dblNorthing);
            proj4.Close();

            PointShape pointShape1 = new PointShape(vertexPoint1);

            LayerOverlay dynamicOverlay = new LayerOverlay();

            Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(new Feature(pointShape1));

            Map1.CurrentExtent = new RectangleShape((vertexPoint1.X - 100), (vertexPoint1.Y + 100), (vertexPoint1.X + 100), (vertexPoint1.Y - 100));

            Map1.Refresh();
        }
 
 
  
 Any question please let me know. 
  
 Regards, 
  
 Don

Hi Don, 
 Yes, the projection is what you mentioned. 
  
 I was using Meter as geography unit, I still need to use the same. Anyway I tried different  externalprojection parameter strings and finally got the desired results. 
  
 Below is the code that I used 
  

 MapWindow.wpfMap1.MapUnit = GeographyUnit.Meter;

                MapWindow.wpfMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));

               
                    double dblEasting = 0;
                    double dblNorthing = 0;

                    dblEasting = Convert.ToDouble(txtEasting.Text);
                    dblNorthing = Convert.ToDouble(txtNorthing.Text);

                    ManagedProj4Projection proj4 = new ManagedProj4Projection();

                    int intZone = 32700 + Convert.ToInt16(txtZone.Text);

                    if (cmbGridSys.SelectedIndex == 0)
                    {
                        //proj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(32756);
                        proj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(intZone);
                    }

                    proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString();

                    proj4.Open();
                    Vertex vertexPoint1 = proj4.ConvertToExternalProjection(dblEasting, dblNorthing);
                    proj4.Close();

                    PointShape pointShape1 = new PointShape(vertexPoint1);
                    LayerOverlay dynamicOverlay = new LayerOverlay();

                    MapWindow.wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Add(new Feature(pointShape1));

                    MapWindow.wpfMap1.CurrentExtent = new RectangleShape((vertexPoint1.X - 100), (vertexPoint1.Y + 100), (vertexPoint1.X + 100), (vertexPoint1.Y - 100));

 MapWindow.wpfMap1.Refresh();
 
  
 Thank you for the support. 
  
 Regards, 
 Jacob

Hi Jacob, 
  
 I am glad to hear that works for you. 
  
 Any question please let us know. 
  
 Regards, 
  
 Don