Calculate a new Map Point

2644
2
01-29-2013 04:57 AM
GaryWhitcher
New Contributor
Hi all:

I am a bit of a neebie so here it goes:

I will try to explain what I am trying to do clearly in the Silverlight Viewer.

I have a polyline. I select the polyline. When I move the mouse I capture the mousepoint(p3). With Trig, I can calculate the triangle using the beginning of the polyline(p1), the angle of the inner angle(angle of p1 to the p2 - angle p1 to p3), and distance from p1 to p3. By calculating the triangle out, I can determine a distance from the start of the polyline a perpendicular point to p3 along the path of the polyline.

[ATTACH=CONFIG]21172[/ATTACH]

I hope that wasnt too confusing.

Once I try to Map that point using the bearing of the polyline and the calculated distance, the Mappoint is not accurate. It is at the right bearing, but the measurement seems to be much greater than it should be.

I calculate the triangle using the lat,lon coordinates of each point. I am thoughly confused. I have tried factoring the distance by Miles to Kilometers, meters to kilometers, feet to kilometers...etc. I can not seem to get this figured out. Any help on this would be fantatastic and very much apprciated.
0 Kudos
2 Replies
ChrisBradberry
Occasional Contributor
Gary,

It seems to me that your distances are incorrect because you are working with lat lon coordinates.  Lat lon is an angular measurement.  You would be better off using a projected coordinate system, or at least project your lat lon points then do the trig.

Chris
0 Kudos
GaryWhitcher
New Contributor
Thanks Chris:

I actually resolved this this morning. I tried a new approach. Instead of trying to calculate a point with trig, I found some formulas to find an intersecting point of two lines. I adapted it to the silverlight viewer.

For future reference of anyone trying to do this here is how I accompished this:

        public  void ShowPerpFromPipe(MapPoint p1, MapPoint p2, MapPoint p3)
        {

            try
            {
                ESRI.ArcGIS.Client.Projection.WebMercator merc = new ESRI.ArcGIS.Client.Projection.WebMercator();
                Point p1x = MyMap.MapToScreen(p1);
                Point p2x = MyMap.MapToScreen(p2);
                Point p3x = MyMap.MapToScreen(p3);

                p1.SpatialReference = p3.SpatialReference;
                p2.SpatialReference = p3.SpatialReference;

                p1 = merc.ToGeographic(p1) as MapPoint;
                p2 = merc.ToGeographic(p2) as MapPoint;
                p3 = merc.ToGeographic(p3) as MapPoint;

                double pipeAngle = GetAngle(p1, p2);

                p1 = merc.FromGeographic(p1) as MapPoint;
                p2 = merc.FromGeographic(p2) as MapPoint;

                MapPoint mp;
                mp = Support.GetPointFromHeading(p3, 1, pipeAngle - 90);
                p3 = merc.FromGeographic(p3) as MapPoint;
                mp = merc.FromGeographic(mp) as MapPoint;
                MapPoint p4 = new MapPoint();

                p4 = findIntersection(p1, p2, p3, mp);
                MyGraphicsLayer.Graphics.Clear();
                ESRI.ArcGIS.Client.Geometry.Polyline ply = Support.GraphicLineBetweenPoint(p4, p3, Colors.Red);
            }
            catch (Exception ex)
            {

            }
        }

Supporting Functions:
public static MapPoint GetPointFromHeading(MapPoint start, double distanceKM, double heading)
        {

            double brng = heading / 180 * Math.PI;
            double lon1 = start.X / 180 * Math.PI;
            double lat1 = start.Y / 180 * Math.PI;
           
            double dR = distanceKM / 6378.137; //Angular distance in radians
            double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(dR) + Math.Cos(lat1) * Math.Sin(dR) * Math.Cos(brng));
            double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(dR) * Math.Cos(lat1), Math.Cos(dR) - Math.Sin(lat1) * Math.Sin(lat2));
            double lon = lon2 / Math.PI * 180;
            double lat = lat2 / Math.PI * 180;
           
            while (lon < -180) lon += 360;
            while (lat < -90) lat += 180;
            while (lon > 180) lon -= 360;
            while (lat > 90) lat -= 180;
            return new MapPoint(lon, lat);
        }

public MapPoint findIntersection(MapPoint p1, MapPoint p2, MapPoint p3, MapPoint p4)
        {
            double x1 = p1.X;
            double y1 = p1.Y;
            double x2 = p2.X;
            double y2 = p2.Y;
            double x3 = p3.X;
            double y3 = p3.Y;
            double x4 = p4.X;
            double y4 = p4.Y;
            double x;
            double y;

            double A1 = y2 - y1;
            double B1 = x1 - x2;
            double C1 = A1 * x1 + B1 * y1;

            double A2 = y4 - y3;
            double B2 = x3 - x4;
            double C2 = A2 * x3 + B2 * y3;

            double det = A1 * B2 - A2 * B1;

            if (det == 0)
            {
                throw new NotImplementedException("Lines are Parallel");
            }
            else
            {
                x = (B2 * C1 - B1 * C2) / det;
                y = (A1 * C2 - A2 * C1) / det;
            }
            MapPoint mp = new MapPoint();
            mp.X = x;
            mp.Y = y;
            return mp;
        }


  public static ESRI.ArcGIS.Client.Geometry.Polyline GraphicLineBetweenPoint(MapPoint p1, MapPoint p2, Color clr)
        {
            Graphic clickGraphic = new Graphic();
            SolidColorBrush sl = new SolidColorBrush();
            sl.Color = clr;
            SimpleLineSymbol simpleline = new SimpleLineSymbol();
            simpleline.Width = 4;
            simpleline.Color = sl;
            ESRI.ArcGIS.Client.Geometry.PointCollection pc = new ESRI.ArcGIS.Client.Geometry.PointCollection();
            pc.Add(p1);
            pc.Add(p2);

            ESRI.ArcGIS.Client.Geometry.Polyline pl = new ESRI.ArcGIS.Client.Geometry.Polyline();
            pl.Paths.Add(pc);


            clickGraphic.Symbol = simpleline;
            clickGraphic.Geometry = pl;
            clickGraphic.Geometry.SpatialReference = MyMap.SpatialReference;
            MyGraphicsLayer.Graphics.Add(clickGraphic);
            return pl;
        }

private double GetAngle(MapPoint p1, MapPoint p2)
        {
            MapPoint p1x = p1;
            MapPoint p2x = p2;
            double angle = Math.Atan2((p2x.X - p1x.X), (p2x.Y - p1x.Y)) / Math.PI * 180 - 90;

            if (angle < 0)
                angle = (angle * -1);

            angle = 90 - angle;

           return angle;
          
        }
0 Kudos