ThinkGeo.com    |     Documentation    |     Premium Support

How to draw MultiLineShape with MapUnit in Meter

Hello,


I want to show route and a moving car in the defined route. I am using Google Map and  MapUnit in meter. I have seen the sample in HowDoISamples ->  EfficientlyMoveAPlane. It is properly working with MapUnit in DecimalDegree but not in Meter.How can I do in Meter. 


 Thanks,


Akku


 


 


 


 



Akku, 
  
 Thanks for your post and questions. 
  
 Yes, as you already seen, this HowDoI samples only shows the GreatCirle used in DecimalDegrees, I am not sure we can achieve the same effects in other projections, I will ask for help from one of our GIS specialist. It seems we can achieve this, take a look the final result of the snapping shot: 
 code.thinkgeo.com/projects/show/greatcirclepacific 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Yale, 
   
 I am not getting any help from the snapshot link you have provided. So please provide anyother option to solve my problem. 
  
 Thanks, Akku 


Yale, 
   
 I am not getting any help from the snapshot link you have provided. So please provide anyother option to solve my problem. 
  
 Thanks,  
 Akku 


Yale, 
   
 I am not getting any help from the snapshot link you have provided. So please provide anyother option to solve my problem. 
  
 Thanks,  
 Akku 



 Akku, 
  
 Thanks for your input.  
  
 In fact, it is not only a snapshot; it is a sample in our code gallery which contains all the sample codes. 
  
 The reason I provide you the snapshot is to make sure this is the final effects we want to achieve, right? 
  
 Thanks. 
  
 Yale 


Yale, 
  
 Please help to solve this problem. Waiting  for your reply. 
  
 Thanks, 
 Akku

Akku, 
  
 I am sorry for the delay. I will do more research to see if we can achieve this. Hope we can get it soon. 
  
 Thanks. 
  
 Yale 


Yale, 
  
 I want to ask that whether it can be possible or not if you have searched about it. 
  
 Waiting for your reply. 
  
 Thanks, 
 Akku

Akku, 
  
 See following code community showing you the way to achieve this: 
 code.thinkgeo.com/projects/show/greatcirclegooglemap 
  
 Thanks. 
  
 Yale 


Akku, 
  
 I forgot to say that the sample is developed in Web Edition, the code should be very similar if a desktop edition version is wanted. 
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Akku,


I made a Desktop Edition version with the following code. Try to click on the map to see the effects.



private void DisplayMap_Load(object sender, EventArgs e)
        {
            winformsMap1.MapUnit = GeographyUnit.Meter;
            winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

            GoogleMapsLayer googlemapLayer = new GoogleMapsLayer();
            LayerOverlay staticOverlay = new LayerOverlay();
            staticOverlay.Layers.Add("googlemapLayer", googlemapLayer);

            InMemoryFeatureLayer GreatCircle = new InMemoryFeatureLayer();
            GreatCircle.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.SimpleColors.Red, 3, true);
            GreatCircle.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            staticOverlay.Layers.Add("GreatCircleLayer", GreatCircle);
            winformsMap1.Overlays.Add("WorldOverlay", staticOverlay);

            winformsMap1.CurrentExtent = new RectangleShape(-2000000, 2000000, 2000000, -2000000);
            winformsMap1.Refresh();

            winformsMap1.MapClick += new EventHandler<MapClickWinformsMapEventArgs>(winformsMap1_MapClick);
        }

        void winformsMap1_MapClick(object sender, MapClickWinformsMapEventArgs e)
        {

            InMemoryFeatureLayer greatCircleLayer = (InMemoryFeatureLayer)winformsMap1.FindFeatureLayer("GreatCircleLayer");

            greatCircleLayer.InternalFeatures.Clear();

            //double Longitude1 = -118.55;
            //double Latitude1 = 34.08;
            double Longitude1 = 0;
            double Latitude1 = 0;

            double Longitude2 = e.WorldX;
            double Latitude2 =e.WorldY;

            Proj4Projection proj4 = new Proj4Projection();
            proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
            proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
            proj4.Open();
            Vertex vertex = proj4.ConvertToInternalProjection(Longitude2, Latitude2);
            proj4.Close();

            MultilineShape greatCircleMultiLineShape = GetGreatCircle(new PointShape(Longitude1, Latitude1), new PointShape(vertex.X, vertex.Y));
            greatCircleLayer.InternalFeatures.Add(new Feature(greatCircleMultiLineShape));

            winformsMap1.Refresh();
        }

        private MultilineShape GetGreatCircle(PointShape pointShape1, PointShape pointShape2)
        {
            //Projection from Geodetic to Google Map.
            Proj4Projection proj4 = new Proj4Projection();
            proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
            proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();

            proj4.Open();
            Vertex offsetVertexReference = proj4.ConvertToExternalProjection(180, 0);

            //Gets the Great Circle in decimal degrees.
            MultilineShape greatCircleMultiLineShape = pointShape1.GetShortestLineTo(pointShape2, GeographyUnit.DecimalDegree);

            //Builds the MultilineShape in the Google Map projection.
            MultilineShape resultGreatMultiLineShape = new MultilineShape();
            foreach (LineShape lineShape in greatCircleMultiLineShape.Lines)
            {
                //For the western hemisphere, simply converts to Google Map projection
                if (lineShape.Vertices[0].X < 0)
                {
                    LineShape resultLineShape = new LineShape();
                    foreach (Vertex vertex in lineShape.Vertices)
                    {
                        Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                        resultLineShape.Vertices.Add(projVertex);
                    }
                    resultGreatMultiLineShape.Lines.Add(resultLineShape);
                }
                //For the eastern hemisphere, converts to Google Map projection and offsets.
                else
                {
                    LineShape resultLineShape = new LineShape();
                    foreach (Vertex vertex in lineShape.Vertices)
                    {
                        Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                        resultLineShape.Vertices.Add(projVertex);
                    }
                    resultGreatMultiLineShape.Lines.Add(resultLineShape);
                }
            }

            proj4.Close();
            return resultGreatMultiLineShape;
        }

Any more questions just feel free to let me know.


Thanks.


Yale

 



Yale, 
  
 In the code given by you, if the start position of multishape line is origin (0,0) then only it works properly. If start point is not origin then the line ploted do not passes through the given points. 
  
 Waiting for your reply. 
 Thanks, 
 Akku

Can you give us some concrete examples of start and end points you would like to have the Great Circle? Thank you.



Hiii, 



I am exactly using the same code given by Yale above. And it works properly only if one of the location is set to (0,0) and if I donot set any of the location to 0 then the multiline ploted donot passes through the set end points.


For example: Coordinates as


Longitude1 = -93.697919536597226

Latitude1=  47.9236905227374

Longitude2  = 37.549353522156949

Latitude2 = 37.660395791749444

So please help me to solve this problem. 



Waiting for the reply. 



Thanks, 

Akku



Akku, 
  
 Can you let me know if you do not set the lat/long to 0, then what values are you trying to use? And it would be great if you could get a screenshot out to show us the problem, that would be much more clear. 
  
 Thanks. 
  
 Yale 


Hii, 
  
 For example: Coordinates as 
  
 Longitude1 = -93.697919536597226 
 Latitude1=  47.9236905227374 
 Longitude2  = 37.549353522156949 
 Latitude2 = 37.660395791749444 
  
 The ploted line donot passes through it. 
 Thanks, 
 Akku 
  


You have to understand that the function GetGreatCircle in the Code Community project is for placing the great circle over the Pacific Rim when the Great Circle actually crosses the 180 degree meridian. In the example, you are giving the Great Circle does not crosses the 180 degree meridian. I modified the GetGreatCircle function so that it takes into account all the scenarios and you have the choice to offset the Great Circle either to the West or to the East. I think that with the attached screen shots you will better understand what is going on. Keep in mind that with that new GetGreatCircle if the Great Circle does not cross the 180 degree meridian no offset is applied.





 



 enum OffsetType { OffsetWest, OffsetEast }
        private MultilineShape GetGreatCircle(PointShape pointShape1, PointShape pointShape2, OffsetType offsetType)
        {
            //Projection from Geodetic to Google Map.
            Proj4Projection proj4 = new Proj4Projection();
            proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
            proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();

            //Offset projection for Google map.
            OffsetProjection offsetGoogleProj = new OffsetProjection();
            proj4.Open();
            Vertex offsetVertexReference = proj4.ConvertToExternalProjection(180, 0);

            if (offsetType == OffsetType.OffsetWest)
            {
                offsetGoogleProj.offset = offsetVertexReference.X * 2;
            }
            else
            {
                offsetGoogleProj.offset = -offsetVertexReference.X * 2;
            }

            offsetGoogleProj.Open();

            //Gets the Great Circle in decimal degrees.
            MultilineShape greatCircleMultiLineShape = pointShape1.GetShortestLineTo(pointShape2, GeographyUnit.DecimalDegree);

            //Builds the MultilineShape in the Google Map projection.
            MultilineShape resultGreatMultiLineShape = new MultilineShape();

            if (greatCircleMultiLineShape.Lines.Count > 1)
            {
                foreach (LineShape lineShape in greatCircleMultiLineShape.Lines)
                {
                    if (lineShape.Vertices[0].X < 0)
                    {
                        LineShape resultLineShape = new LineShape();
                        if (offsetType == OffsetType.OffsetWest)
                        {
                            foreach (Vertex vertex in lineShape.Vertices)
                            {
                                Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                                resultLineShape.Vertices.Add(projVertex);
                            }
                        }
                        else
                        {
                            foreach (Vertex vertex in lineShape.Vertices)
                            {
                                Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                                Vertex offsetVertex = offsetGoogleProj.ConvertToExternalProjection(projVertex.X, projVertex.Y);
                                resultLineShape.Vertices.Add(offsetVertex);
                            }
                        }
                        resultGreatMultiLineShape.Lines.Add(resultLineShape);
                    }
                    else
                    {
                        LineShape resultLineShape = new LineShape();
                        if (offsetType == OffsetType.OffsetWest)
                        {
                            foreach (Vertex vertex in lineShape.Vertices)
                            {
                                Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                                Vertex offsetVertex = offsetGoogleProj.ConvertToExternalProjection(projVertex.X, projVertex.Y);
                                resultLineShape.Vertices.Add(offsetVertex);
                            }
                        }
                        else
                        {
                            foreach (Vertex vertex in lineShape.Vertices)
                            {
                                Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                                resultLineShape.Vertices.Add(projVertex);
                            }
                        }
                        resultGreatMultiLineShape.Lines.Add(resultLineShape);
                    }
                }
            }
            else
            {
                LineShape resultLineShape = new LineShape();
                foreach (Vertex vertex in greatCircleMultiLineShape.Lines[0].Vertices)
                {
                    Vertex projVertex = proj4.ConvertToExternalProjection(vertex.X, vertex.Y);
                    resultLineShape.Vertices.Add(projVertex);
                }
                resultGreatMultiLineShape.Lines.Add(resultLineShape);
            }

            proj4.Close();
            offsetGoogleProj.Close();

            return resultGreatMultiLineShape;
        }



I also let you know that we made the modification in the Code Community project.


code.thinkgeo.com/projects/s...egooglemap



Hii, 



I am able to plot a ShortestLine between two defined vertex instead of GreatCircle. By using the line given below


greatCircleMultiLineShape As MultilineShape = pointShape1.GetShortestLineTo(pointShape2, GeographyUnit.Meter)


Dim


Now I want to show an object moving on the line drawn according to Timer. But I am getting only two vertex of the line i.e Start and End Point of the line. So I am not able to move a Point on the line drawn. As which was working with GreatCircle with GeographicUnit as DecimalDegree. So please help me to do it in Meter as Geographic Unit.


Waiting for the help.


 




Thanks, 

Akku