예제 #1
0
        public override double Distance(PointF2D point)
        {
            VectorF2D vectorF2D = point - this._a;
            double    num1      = VectorF2D.Cross(this.Direction, vectorF2D);
            double    length    = this.Length;
            double    num2      = point.Distance(this._a);
            double    num3      = point.Distance(this._b);
            double    num4      = System.Math.Abs(num1 / length);

            if (this.IsSegment)
            {
                if (VectorF2D.Dot(vectorF2D, this.Direction) < 0.0 && num1 != 0.0)
                {
                    num4 = this._a.Distance(point);
                }
                else if (num1 == 0.0 && (num2 >= length || num3 >= length))
                {
                    num4 = num2 <= num3?this._a.Distance(point) : this._b.Distance(point);
                }
                if (VectorF2D.Dot(point - this._b, this.Direction.Inverse) < 0.0 && num1 != 0.0)
                {
                    num4 = this._b.Distance(point);
                }
            }
            return(num4);
        }
예제 #2
0
        /// <summary>
        /// Returns the distance from the point to this line.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public override double Distance(PointF2D point)
        {
            double distance = 0.0f;

            // get the second vector for the cross product.
            VectorF2D a_point = point - _a;

            // get the cross product.
            double cross = VectorF2D.Cross(this.Direction, a_point);

            // distances between a, b and point.
            double distance_a_b = this.Length;
            double distance_a   = point.Distance(_a);
            double distance_b   = point.Distance(_b);

            // calculate distance to line as if it were no segment.
            distance = System.Math.Abs(cross / distance_a_b);

            // if this line is a segment.
            if (this.IsSegment)
            {
                double dot1 = VectorF2D.Dot(a_point, this.Direction);
                if (dot1 < 0 && cross != 0)
                {
                    distance = _a.Distance(point);
                }
                else if (cross == 0 &&
                         (distance_a >= distance_a_b ||
                          distance_b >= distance_a_b))
                {     // check if the point is between the points.
                    if (distance_a > distance_b)
                    { // if the distance to a is greater then the point is at the b-side.
                        distance = _b.Distance(point);
                    }
                    else
                    {// if the distance to b is greater then the point is at the a-side.
                        distance = _a.Distance(point);
                    }
                }
                VectorF2D b_point = point - _b;
                double    dot2    = VectorF2D.Dot(b_point, this.Direction.Inverse);
                if (dot2 < 0 && cross != 0)
                {
                    distance = _b.Distance(point);
                }
            }
            return(distance);
        }
예제 #3
0
        /// <summary>
        /// Adds a line.
        /// </summary>
        /// <param name="maxZoom"></param>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        /// <param name="color">Color.</param>
        /// <param name="width">Width.</param>
        /// <param name="minZoom"></param>
        /// <returns>The line.</returns>
        public override uint AddLine(int layer, float minZoom, float maxZoom, double[] x, double[] y,
                                     int color, double width, LineJoin lineJoin, int[] dashes)
        {         // add the line but simplify it for higher zoom levels.
            float currentMaxZoom = float.MaxValue;

            for (int idx = 0; idx < _zoomLevelCutoffs.Count; idx++)
            {
                float currentMinZoom = _zoomLevelCutoffs[idx];
                if (!(currentMinZoom >= maxZoom) && !(currentMaxZoom < minZoom))
                {
                    float thisMinZoom = System.Math.Max(currentMinZoom, minZoom);
                    float thisMaxZoom = System.Math.Min(currentMaxZoom, maxZoom);

                    // simplify the algorithm.
                    double     epsilon    = this.CalculateSimplificationEpsilon(thisMaxZoom);
                    double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y },
                                                                                            epsilon);
                    double distance = epsilon;
                    if (simplified[0].Length == 2)
                    { // check if the simplified version is smaller than epsilon.
                        OsmSharp.Math.Primitives.PointF2D point1 = new OsmSharp.Math.Primitives.PointF2D(
                            simplified[0][0], simplified[0][1]);
                        OsmSharp.Math.Primitives.PointF2D point2 = new OsmSharp.Math.Primitives.PointF2D(
                            simplified[1][0], simplified[0][1]);
                        distance = point1.Distance(point2);
                    }
                    if (distance >= epsilon &&
                        this.CalculateSimplificationSurfaceCondition(currentMaxZoom, x, y))
                    {
                        // add to the scene.
                        if (_scenes[idx] == null)
                        {
                            _scenes[idx] = new Scene2DSimple();
                        }
                        _scenes[idx].AddLine(layer, thisMinZoom, thisMaxZoom, simplified[0], simplified[1],
                                             color, width, lineJoin, dashes);
                    }
                }
                currentMaxZoom = currentMinZoom; // move to the next cutoff.
            }
            return(0);
        }
예제 #4
0
        public void Point2DTest()
        {
            // create the test cases.
            PointF2D a = new PointF2D(0, 0);
            PointF2D b = new PointF2D(1, 1);

            // calculate the results
            double sqrt_2 = (double)System.Math.Sqrt(2);
            //double sqrt_2_div_2 = (double)System.Math.Sqrt(2) / 2.0f;

            // test distance.
            Assert.AreEqual(a.Distance(b), sqrt_2, string.Format("Distance should be {0}!", sqrt_2));

            // test substraction into vector.
            VectorF2D ab = b - a;
            Assert.AreEqual(ab[0], 1, "Vector should be 1 at index 0!");
            Assert.AreEqual(ab[1], 1, "Vector should be 1 at index 1!");
            VectorF2D ba = a - b;
            Assert.AreEqual(ba[0], -1, "Vector should be -1 at index 0!");
            Assert.AreEqual(ba[1], -1, "Vector should be -1 at index 1!");
        }
예제 #5
0
        /// <summary>
        /// Adds a line.
        /// </summary>
        /// <param name="maxZoom"></param>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        /// <param name="color">Color.</param>
        /// <param name="width">Width.</param>
        /// <param name="minZoom"></param>
        /// <returns>The line.</returns>
        public override uint AddLine(int layer, float minZoom, float maxZoom, double[] x, double[] y,
            int color, double width, LineJoin lineJoin, int[] dashes)
        {
            // add the line but simplify it for higher zoom levels.
            float currentMaxZoom = float.MaxValue;
            for (int idx = 0; idx < _zoomLevelCutoffs.Count; idx++)
            {
                float currentMinZoom = _zoomLevelCutoffs[idx];
                if (!(currentMinZoom >= maxZoom) && !(currentMaxZoom < minZoom))
                {
                    float thisMinZoom = System.Math.Max(currentMinZoom, minZoom);
                    float thisMaxZoom = System.Math.Min(currentMaxZoom, maxZoom);

                    // simplify the algorithm.
                    double epsilon = this.CalculateSimplificationEpsilon(thisMaxZoom);
                    double[][] simplified = OsmSharp.Math.Algorithms.SimplifyCurve.Simplify(new double[][] { x, y },
                                                                    epsilon);
                    double distance = epsilon * 2;
                    if (simplified[0].Length == 2)
                    { // check if the simplified version is smaller than epsilon.
                        OsmSharp.Math.Primitives.PointF2D point1 = new OsmSharp.Math.Primitives.PointF2D(
                            simplified[0][0], simplified[0][1]);
                        OsmSharp.Math.Primitives.PointF2D point2 = new OsmSharp.Math.Primitives.PointF2D(
                            simplified[1][0], simplified[0][1]);
                        distance = point1.Distance(point2);
                    }
                    if (distance >= epsilon)
                    {
                        // add to the scene.
                        if (_scenes[idx] == null)
                        {
                            _scenes[idx] = new Scene2DSimple();
                        }
                        _scenes[idx].AddLine(layer, thisMinZoom, thisMaxZoom, simplified[0], simplified[1],
                            color, width, lineJoin, dashes);
                    }
                }
                currentMaxZoom = currentMinZoom; // move to the next cutoff.
            }
            return 0;
        }
예제 #6
0
 /// <summary>
 /// Calculates the distance between this point and the given point.
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public override double Distance(PointF2D p)
 {
     return(PointF2D.Distance(this, p));
 }
예제 #7
0
        /// <summary>
        /// Try and find matching lines.
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="points"></param>
        /// <returns></returns>
        private MatchPosition FindMatch(Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, out Scene2D.ScenePoints found)
        {
            PointF2D first = new PointF2D(x[0], y[0]);
            PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]);

            MatchPosition position = MatchPosition.None;
            found = null;
            foreach (var line in lines)
            {
                if (line.Value.Equals(style))
                {
                    // check first.
                    PointF2D potentialFirst = new PointF2D(line.Key.X[0], line.Key.Y[0]);
                    if (first.Distance(potentialFirst) < _epsilon)
                    {
                        found = line.Key;
                        position = MatchPosition.FirstFirst;
                        break;
                    }
                    if (last.Distance(potentialFirst) < _epsilon)
                    {
                        found = line.Key;
                        position = MatchPosition.LastFirst;
                        break;
                    }

                    PointF2D potentialLast = new PointF2D(line.Key.X[line.Key.X.Length - 1], line.Key.Y[line.Key.Y.Length - 1]);
                    if (first.Distance(potentialLast) < _epsilon)
                    {
                        found = line.Key;
                        position = MatchPosition.FirstLast;
                        break;
                    }
                    if (last.Distance(potentialLast) < _epsilon)
                    {
                        found = line.Key;
                        position = MatchPosition.LastLast;
                        break;
                    }
                }
            }
            return position;
        }
예제 #8
0
        /// <summary>
        /// Returns the distance from the point to this line.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public override double Distance(PointF2D point)
        {
            double distance = 0.0f;

            // get the second vector for the cross product.
            VectorF2D a_point = point - _a;

            // get the cross product.
            double cross = VectorF2D.Cross(this.Direction, a_point);

            // distances between a, b and point.
            double distance_a_b = this.Length;
            double distance_a = point.Distance(_a);
            double distance_b = point.Distance(_b);

            // calculate distance to line as if it were no segment.
            distance = System.Math.Abs(cross / distance_a_b);

            // if this line is a segment.
            if(this.IsSegment)
            {
                double dot1 = VectorF2D.Dot(a_point, this.Direction);
                if (dot1 < 0 && cross != 0)
                {
                    distance = _a.Distance(point);
                }
                else if (cross == 0 &&
                    (distance_a >= distance_a_b
                    || distance_b >= distance_a_b))
                { // check if the point is between the points.
                    if (distance_a > distance_b)
                    { // if the distance to a is greater then the point is at the b-side.
                        distance = _b.Distance(point);
                    }
                    else
                    {// if the distance to b is greater then the point is at the a-side.
                        distance = _a.Distance(point);
                    }
                }
                VectorF2D b_point = point - _b;
                double dot2 = VectorF2D.Dot(b_point, this.Direction.Inverse);
                if (dot2 < 0 && cross != 0)
                {
                    distance = _b.Distance(point);
                }
            }
            return distance;
        }
예제 #9
0
        /// <summary>
        /// Try and find matching lines.
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="points"></param>
        /// <returns></returns>
        private MatchPosition FindMatch(ILocatedObjectIndex<PointF2D, Scene2D.ScenePoints> linesIndex, Dictionary<Scene2D.ScenePoints, Scene2DStylesSet> lines, 
            double[] x, double[] y, Scene2DStylesSet style, float epsilon, out Scene2D.ScenePoints found)
        {
            // build box.
            var box = new BoxF2D(x, y);
            box = box.ResizeWith(epsilon * 1.1);

            // get all geometries in this box.
            var potentialMatches = linesIndex.GetInside(box);

            // find a match in the potential matches list.
            PointF2D first = new PointF2D(x[0], y[0]);
            PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]);

            MatchPosition position = MatchPosition.None;
            found = null;
            foreach (var line in potentialMatches)
            {
                // check first.
                PointF2D potentialFirst = new PointF2D(line.X[0], line.Y[0]);
                PointF2D potentialLast = new PointF2D(line.X[line.X.Length - 1], line.Y[line.Y.Length - 1]);
                if (first.Distance(potentialFirst) < epsilon)
                {
                    found = line;
                    position = MatchPosition.FirstFirst;
                }
                else if (last.Distance(potentialFirst) < epsilon)
                {
                    found = line;
                    position = MatchPosition.LastFirst;
                }
                else if (first.Distance(potentialLast) < epsilon)
                {
                    found = line;
                    position = MatchPosition.FirstLast;
                }
                else if (last.Distance(potentialLast) < epsilon)
                {
                    found = line;
                    position = MatchPosition.LastLast;
                }

                Scene2DStylesSet styleValue;
                if (position != MatchPosition.None && lines.TryGetValue(line, out styleValue) && styleValue.Equals(style))
                {
                    break;
                }
                else
                {
                    position = MatchPosition.None;
                    found = null;
                }
            }
            return position;
        }