ThinkGeo.com    |     Documentation    |     Premium Support

Calculate distance between more than two point

 hi,


 


i want to calculate distance between two and more point where the user clicks.


the code i have written is as follow...


 


 



using System.Linq;


using System.Text;


using System.Collections.ObjectModel;


using ThinkGeo.MapSuite.Core;


using ThinkGeo.MapSuite.DesktopEdition;


 


namespace CustomTrackLine


{


    class CustomTrackInteractiveOverlay : TrackInteractiveOverlay


    {


        private const string currentFeatureKey = "CurrentFeature";


        private LineShape rulerLineShape;


        private int mouseDown;


 


        public CustomTrackInteractiveOverlay()


            : base()


        {


            this.TrackMode = TrackMode.Line;


        }


 


        protected override InteractiveResult MouseDownCore(InteractionArguments interactionArguments)


        {


            


            if (interactionArguments.MouseButton != MapMouseButton.Right)


                return base.MouseDownCore(interactionArguments);


            else


                RemoveLastVertexAdded();


                return new InteractiveResult();


        }


 


        private void RemoveLastVertexAdded()


        {


            int minVertex = 2;


            if (this.Vertices.Count > minVertex)


            {


                this.Lock.EnterWriteLock();


                try


                {


                    Vertex lastVertex = this.Vertices[this.Vertices.Count - 2];


                    this.Vertices.Remove(lastVertex);


                }


                finally


                {


                    this.Lock.ExitWriteLock();


                }


            }


       }


        protected override void DrawCore(GeoCanvas canvas)


        {


            //Draws the line and update the distance text of the ruler.


            Collection<SimpleCandidate> labelingInAllLayers = new Collection<SimpleCandidate>();


 


            try


            {


                if (rulerLineShape != null)


                {


                    Feature feature = new Feature(rulerLineShape);


                    double length = rulerLineShape.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Feet);


                    feature.ColumnValues.Add("length", ((int)length).ToString() + " feet");


                    


                    Lock.EnterWriteLock();


                    {


                        if (TrackShapeLayer.InternalFeatures.Contains(currentFeatureKey))


                        {


                            TrackShapeLayer.InternalFeatures[currentFeatureKey] = feature;


                        }


                        else


                        {


                            TrackShapeLayer.InternalFeatures.Add(currentFeatureKey, feature);


                        }


                    }


                    Lock.ExitWriteLock();


                }


 


                TrackShapeLayer.Open();


                TrackShapeLayer.Draw(canvas, labelingInAllLayers);


                canvas.Flush();


            }


            finally


            {


                


                TrackShapeLayer.Close();


            }


        }


    }


    }


 



 
 
but it is not calculating distance...

 



Sneha,


 If your goal is to calculate the distance between points where the user clicks on the map, I can present you with an approach that you might be interested in. I create a custom distance LineStyle that displays the distance between two vertices of a LineShape. Then I apply this custom distance LineStyle to the default LineStyle of TrackOverlay. See the screen shot below and the code. If this is not exactely what you are looking for, I think it will get you inspired. Here it shows the distance in meters on Google but the custom Distance LineStyle is flexible enough to have it working with any background map and with any distance unit.




winformsMap1.MapUnit = GeographyUnit.Meter;
winformsMap1.CurrentExtent = new RectangleShape(-10781742,3910056,-10777517,3907571);
winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));

GoogleMapsOverlay googleOverlay = new GoogleMapsOverlay(); 
winformsMap1.Overlays.Add(googleOverlay);


winformsMap1.TrackOverlay.TrackMode = TrackMode.Line;
winformsMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new CustomDistanceLineStyle
    (DistanceUnit.Meter, new GeoFont("Arial", 12,DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.StandardColors.Navy), new GeoPen(GeoColor.StandardColors.Red,3));
winformsMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

winformsMap1.Refresh();

public class CustomDistanceLineStyle : LineStyle
{
    private GeoFont geoFont;
    private GeoSolidBrush geoSolidBrush;
    private GeoPen geoPen;
    private DistanceUnit distanceUnit;

    public CustomDistanceLineStyle()
        : this(DistanceUnit.Meter,new GeoFont(), new GeoSolidBrush(), new GeoPen())
    {}

    public CustomDistanceLineStyle( DistanceUnit distanceUnit, GeoFont geoFont, GeoSolidBrush geoSolidBrush, GeoPen geoPen)
    {
        this.distanceUnit = distanceUnit;
        this.geoFont = geoFont;
        this.geoSolidBrush = geoSolidBrush;
        this.geoPen = geoPen;
    }

    //For the font of the distance
    public GeoFont GeoFont
    {
        get { return geoFont; }
        set { geoFont = value; }
    }

    //For the color of the font
    public GeoSolidBrush GeoSolidBrush
    {
        get { return geoSolidBrush; }
        set { geoSolidBrush = value; }
    }

    //For the color of the line
    public GeoPen GeoPen
    {
        get { return geoPen; }
        set { geoPen = value; }
    }

    //For the distance unit used.
    public DistanceUnit DistanceUnit
    {
        get { return distanceUnit; }
        set { distanceUnit = value; }
    }

    protected override void DrawCore(System.Collections.Generic.IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
    {
        //Loops thru the features to to label the distance of each line segment at mid point.
        
        foreach (Feature feature in features)
        {
                LineShape lineShape = (LineShape)feature.GetShape();
                for (int i = 0; i < lineShape.Vertices.Count - 1; i++)
                {
                    PointShape pointShape1 = new PointShape(lineShape.Vertices[i]);
                    PointShape pointShape2 = new PointShape(lineShape.Vertices[i + 1]);
                    double currentDist = Math.Round(pointShape1.GetDistanceTo(pointShape2, canvas.MapUnit,distanceUnit),2);

                    LineShape tempLineShape = new LineShape();
                    tempLineShape.Vertices.Add(new Vertex(pointShape1));
                    tempLineShape.Vertices.Add(new Vertex(pointShape2));

                    PointShape midPointShape = tempLineShape.GetPointOnALine(StartingPoint.FirstPoint, 50);
                    Collection<ScreenPointF> screenPointFs = new Collection<ScreenPointF>();

                    screenPointFs.Add(ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, midPointShape, canvas.Width, canvas.Height));

                    double angle = GetAngleFromTwoVertices(tempLineShape.Vertices[0], tempLineShape.Vertices[1]);

                    canvas.DrawLine(tempLineShape, geoPen, DrawingLevel.LevelOne);
                    canvas.DrawText(currentDist.ToString(),geoFont,geoSolidBrush,null, screenPointFs,DrawingLevel.LabelLevel,0,0,(float)angle);
               }
            }
       }

    private double GetAngleFromTwoVertices(Vertex b, Vertex c)
    {
        double result;
        double alpha = 0;
        double tangentAlpha = (c.Y - b.Y) / (c.X - b.X);
        double Peta = Math.Atan(tangentAlpha);

        if (c.X > b.X)
        {
            alpha = 90 + (Peta * (180 / Math.PI));
        }
        else if (c.X < b.X)
        {
            alpha = 270 + (Peta * (180 / Math.PI));
        }
        else
        {
            if (c.Y > b.Y) alpha = 0;
            if (c.Y < b.Y) alpha = 180;
        }

        double offset;
        if (b.X > c.X)
        { offset = 90; }
        else { offset = - 90; }

        result = alpha + offset;
        return result;   
    }
}