ThinkGeo.com    |     Documentation    |     Premium Support

Point lies on line, but line.getDistance() > 0




Hi,



I need your help again. I am actually doing some routing tests with MapSuite, but there is some strange thing that is not really routing related and therefore belongs in here (at least I think so). Like in this Routing Topic, I have to trim the resulting route. I do this with my circuitous code as follows:




01.private LineShape trimRoute(LineShape origRoute, PointShape start, PointShape end)
02.        {
03.             
04.                LineShape result = (LineShape)origRoute.CloneDeep();
05.                //trim from front
06.                bool bStartFound = false;
07.                bool bEndFound = false;
08.                int vertCount = 0;
09.               
10.                while (vertCount < origRoute.Vertices.Count && !(new LineShape(new Collection<vertex> { result.Vertices[0], result.Vertices[1] }).GetDistanceTo(start, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0) && !(new LineShape(new Collection<Vertex> { result.Vertices[0], result.Vertices[1] }).GetDistanceTo(end, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0))
11.                {
12.                    result.Vertices.Remove(result.Vertices[0]);
13.                    vertCount++;
14.                }
15.               
16.                bStartFound = (new LineShape(new Collection<Vertex> { result.Vertices[0], result.Vertices[1] }).GetDistanceTo(start, GeographyUnit.Meter, DistanceUnit.Meter) == 0);
17.                bEndFound = (new LineShape(new Collection<Vertex> { result.Vertices[0], result.Vertices[1] }).GetDistanceTo(end, GeographyUnit.Meter, DistanceUnit.Meter) == 0);
18.                if (bStartFound && !bEndFound)
19.                {
20.                    // add start point
21.                    result.Vertices[0] = new Vertex(start.X, start.Y);
22.                }
23.                else if (!bStartFound && bEndFound)
24.                {
25.                    //add end point
26.                    result.Vertices[0] = new Vertex(end.X, end.Y);
27.                }
28.                else if (bStartFound && bEndFound)
29.                {
30.                    //add both points
31.                    result.Vertices[0] = new Vertex(start.X, start.Y);
32.                    result.Vertices[1] = new Vertex(end.X, end.Y);
33.                }
34. 
35.                //trim from back
36.                vertCount = result.Vertices.Count - 1;
37.                bool bContainsEnd = false;
38.                bool bContainsStart = false;
39.                 
40.                while (vertCount > 1 && ((bStartFound && !(new LineShape(new Collection<Vertex> { result.Vertices[vertCount], result.Vertices[vertCount - 1] }).GetDistanceTo(end, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0)) || (bEndFound && !(new LineShape(new Collection<Vertex> { result.Vertices[vertCount], result.Vertices[vertCount - 1] }).GetDistanceTo(start, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0))))
41.                {
42.                    result.Vertices.Remove(result.Vertices[vertCount]);
43.                    vertCount--;
44.                }
45.             
46.                bContainsEnd = (new LineShape(new Collection<Vertex> { result.Vertices[vertCount], result.Vertices[vertCount - 1] }).GetDistanceTo(end, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0);
47.                bContainsStart = (new LineShape(new Collection<Vertex> { result.Vertices[vertCount], result.Vertices[vertCount - 1] }).GetDistanceTo(start, GeographyUnit.Meter, DistanceUnit.Meter) == 0.0);
48. 
49.                if (bContainsEnd && !bEndFound)
50.                {
51.                    result.Vertices[vertCount] = new Vertex(end.X, end.Y);
52.                }
53.                if (bContainsStart && !bStartFound)
54.                {
55.                    result.Vertices[vertCount] = new Vertex(start.X, start.Y);
56.                }
57.                bStartFound |= bContainsStart;
58.                bEndFound |= bContainsEnd;
59. 
60.                if (!(bStartFound && bEndFound))
61.                {
62.                    Console.WriteLine("Start and/or End not found, route cannot be trimmed");
63.                    return origRoute;
64.                }
65.                else
66.                    return result;
67.            }
68.        }

The problem now is that sometimes (don't yet know under which circumstances), although both start and end point lie on the route line shape, the distance() function does not return 0. I have a sample data set as WKT which I attach.

I decided to give the distance() function a try after realizing that lineshape.contains(point) also did not work. When I use lineshape.GetBoundingBox().Contains() instead, it works well. Seems as if the point does NOT lie on the line - but I wonder why this is, because I define my start and end point based as follows:


string
startId =
routableStreetsLayer.FeatureSource.GetFeaturesNearestTo(routeStart,
GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns)[0].Id;

routingLayer.StartPoint
= routableStreetsLayer.FeatureSource.GetFeatureById(startId,
ReturningColumnsType.AllColumns).GetShape().GetClosestPointTo(routeStart,
GeographyUnit.Meter);


, where routeStart is the place on the map where the user clicked. Using Feature.GetShape().GetClosestPointTo(pointWhereUserClicked), I think I am right to assume that the resulting point lies directly on the line.



Thanks in advance,



Hanna

001_wellKnownText.txt (250 Bytes)

Hi Hanna, 
  
 This is a known phenonemon, this is caused by Calculation error for now it is unavoidable, would you please use round() to avoid it? 
  
 Thanks, 
  
 Summer