public static HashSet <uint> Search(this GeometricGraph graph, int n, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude) { List <long> longList = HilbertCurve.HilbertDistances(System.Math.Max(minLatitude, -90f), System.Math.Max(minLongitude, -180f), System.Math.Min(maxLatitude, 90f), System.Math.Min(maxLongitude, 180f), (long)n); longList.Sort(); HashSet <uint> uintSet = new HashSet <uint>(); int index = 0; uint vertex1 = 0; uint vertex2 = graph.VertexCount - 1U; for (; index < longList.Count && vertex1 < graph.VertexCount; ++index) { long num1 = longList[index]; long maxHilbert; for (maxHilbert = num1; index < longList.Count - 1 && longList[index + 1] <= maxHilbert + 1L; ++index) { maxHilbert = longList[index + 1]; } uint vertex; int count; float latitude; float longitude; if (num1 == maxHilbert) { if (graph.Search(num1, n, vertex1, vertex2, out vertex, out count)) { int num2 = count; for (; count > 0; --count) { if (graph.GetVertex(vertex + (uint)(count - 1), out latitude, out longitude) && (double)minLatitude < (double)latitude && ((double)minLongitude < (double)longitude && (double)maxLatitude > (double)latitude) && (double)maxLongitude > (double)longitude) { uintSet.Add(vertex + (uint)(count - 1)); } } vertex1 = vertex + (uint)num2; } } else if (graph.SearchRange(num1, maxHilbert, n, vertex1, vertex2, out vertex, out count)) { int num2 = count; for (; count > 0; --count) { if (graph.GetVertex(vertex + (uint)(count - 1), out latitude, out longitude) && (double)minLatitude < (double)latitude && ((double)minLongitude < (double)longitude && (double)maxLatitude > (double)latitude) && (double)maxLongitude > (double)longitude) { uintSet.Add(vertex + (uint)(count - 1)); } } vertex1 = vertex + (uint)num2; } } return(uintSet); }
public void SearchCloseVerticesTest() { var DefaultHilbertSteps = (int)System.Math.Pow(2, 15); // build locations. var locations = new List <Coordinate>(); locations.Add(new Coordinate(53.06905f, 29.40519f)); locations.Add(new Coordinate(53.1183f, 29.31932f)); locations.Add(new Coordinate(53.08611f, 29.37143f)); locations.Add(new Coordinate(53.05757f, 29.44653f)); // build graph. var graph = new GeometricGraph(1); int vertex = 0; for (vertex = 0; vertex < locations.Count; vertex++) { graph.AddVertex((uint)vertex, locations[vertex].Latitude, locations[vertex].Longitude); } // build a sorted version in-place. graph.Sort(DefaultHilbertSteps); var closelist1 = graph.Search(53.0695f, 29.40594f, 0.1f); Assert.AreEqual(4, closelist1.Count); // add another vertex. graph.AddVertex((uint)vertex, 52.7362f, 29.4935f); graph.Sort(DefaultHilbertSteps); // build a sorted version in-place. var closelist2 = graph.Search(53.0695f, 29.40594f, 0.1f); Assert.IsTrue(closelist2.Count >= 3, "some close vertex missed"); }
public static uint SearchClosest(this GeometricGraph graph, float latitude, float longitude, float latitudeOffset, float longitudeOffset) { HashSet <uint> uintSet = graph.Search(latitude - latitudeOffset, longitude - longitudeOffset, latitude + latitudeOffset, longitude + longitudeOffset); double num1 = double.MaxValue; uint num2 = 4294967294; foreach (uint vertex in uintSet) { float latitude1; float longitude1; if (graph.GetVertex(vertex, out latitude1, out longitude1)) { double num3 = GeoCoordinate.DistanceEstimateInMeter((double)latitude, (double)longitude, (double)latitude1, (double)longitude1); if (num3 < num1) { num1 = num3; num2 = vertex; } } } return(num2); }
public void SearchVerticesTest() { var graph = new GeometricGraph(1); graph.AddVertex(0, .00f, .00f); graph.AddVertex(1, .02f, .00f); graph.AddVertex(2, .04f, .00f); graph.AddVertex(3, .06f, .00f); graph.AddVertex(4, .08f, .00f); graph.AddVertex(5, .00f, .02f); graph.AddVertex(6, .02f, .02f); graph.AddVertex(7, .04f, .02f); graph.AddVertex(8, .06f, .02f); graph.AddVertex(9, .08f, .02f); graph.AddVertex(10, .00f, .04f); graph.AddVertex(11, .02f, .04f); graph.AddVertex(12, .04f, .04f); graph.AddVertex(13, .06f, .04f); graph.AddVertex(14, .08f, .04f); graph.AddVertex(15, .00f, .06f); graph.AddVertex(16, .02f, .06f); graph.AddVertex(17, .04f, .06f); graph.AddVertex(18, .06f, .06f); graph.AddVertex(19, .08f, .06f); graph.AddVertex(20, .00f, .08f); graph.AddVertex(21, .02f, .08f); graph.AddVertex(22, .04f, .08f); graph.AddVertex(23, .06f, .08f); graph.AddVertex(24, .08f, .08f); graph.Sort(); // test 0.009, 0.009, 0.019, 0.019 var vertices = graph.Search(0.009f, 0.009f, 0.029f, 0.029f); Assert.AreEqual(1, vertices.Count); Assert.IsTrue(vertices.Contains(3)); var location = graph.GetVertex(3); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); // test 0.009, 0.009, 0.099, 0.019 vertices = graph.Search(0.009f, 0.009f, 0.099f, 0.029f); Assert.AreEqual(4, vertices.Count); Assert.IsTrue(vertices.Contains(3)); location = graph.GetVertex(3); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(13)); location = graph.GetVertex(13); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(16)); location = graph.GetVertex(16); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(19)); location = graph.GetVertex(19); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); // test -0.001, -0.001, 0.09, 0.09 vertices = graph.Search(-0.001f, -0.001f, 0.09f, 0.09f); Assert.AreEqual(25, vertices.Count); Assert.IsTrue(vertices.Contains(0)); location = graph.GetVertex(0); Assert.AreEqual(.0f, location.Latitude); Assert.AreEqual(.0f, location.Longitude); Assert.IsTrue(vertices.Contains(1)); location = graph.GetVertex(1); Assert.AreEqual(.0f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(2)); location = graph.GetVertex(2); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.0f, location.Longitude); Assert.IsTrue(vertices.Contains(3)); location = graph.GetVertex(3); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(4)); location = graph.GetVertex(4); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.04f, location.Longitude); Assert.IsTrue(vertices.Contains(5)); location = graph.GetVertex(5); Assert.AreEqual(.00f, location.Latitude); Assert.AreEqual(.04f, location.Longitude); Assert.IsTrue(vertices.Contains(6)); location = graph.GetVertex(6); Assert.AreEqual(.00f, location.Latitude); Assert.AreEqual(.06f, location.Longitude); Assert.IsTrue(vertices.Contains(7)); location = graph.GetVertex(7); Assert.AreEqual(.00f, location.Latitude); Assert.AreEqual(.08f, location.Longitude); Assert.IsTrue(vertices.Contains(8)); location = graph.GetVertex(8); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.08f, location.Longitude); Assert.IsTrue(vertices.Contains(9)); location = graph.GetVertex(9); Assert.AreEqual(.02f, location.Latitude); Assert.AreEqual(.06f, location.Longitude); Assert.IsTrue(vertices.Contains(10)); location = graph.GetVertex(10); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.08f, location.Longitude); Assert.IsTrue(vertices.Contains(11)); location = graph.GetVertex(11); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.06f, location.Longitude); Assert.IsTrue(vertices.Contains(12)); location = graph.GetVertex(12); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.04f, location.Longitude); Assert.IsTrue(vertices.Contains(13)); location = graph.GetVertex(13); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(14)); location = graph.GetVertex(14); Assert.AreEqual(.04f, location.Latitude); Assert.AreEqual(.00f, location.Longitude); Assert.IsTrue(vertices.Contains(15)); location = graph.GetVertex(15); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.04f, location.Longitude); Assert.IsTrue(vertices.Contains(16)); location = graph.GetVertex(16); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(17)); location = graph.GetVertex(17); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.00f, location.Longitude); Assert.IsTrue(vertices.Contains(18)); location = graph.GetVertex(18); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.00f, location.Longitude); Assert.IsTrue(vertices.Contains(19)); location = graph.GetVertex(19); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.02f, location.Longitude); Assert.IsTrue(vertices.Contains(20)); location = graph.GetVertex(20); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.04f, location.Longitude); Assert.IsTrue(vertices.Contains(21)); location = graph.GetVertex(21); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.06f, location.Longitude); Assert.IsTrue(vertices.Contains(22)); location = graph.GetVertex(22); Assert.AreEqual(.08f, location.Latitude); Assert.AreEqual(.08f, location.Longitude); Assert.IsTrue(vertices.Contains(23)); location = graph.GetVertex(23); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.08f, location.Longitude); Assert.IsTrue(vertices.Contains(24)); location = graph.GetVertex(24); Assert.AreEqual(.06f, location.Latitude); Assert.AreEqual(.06f, location.Longitude); }
public static HashSet <uint> Search(this GeometricGraph graph, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude) { return(graph.Search(Hilbert.DefaultHilbertSteps, minLatitude, minLongitude, maxLatitude, maxLongitude)); }
public static HashSet <uint> Search(this GeometricGraph graph, float latitude, float longitude, float offset) { return(graph.Search(Hilbert.DefaultHilbertSteps, latitude - offset, longitude - offset, latitude + offset, longitude + offset)); }
public static List <uint> SearchCloserThan(this GeometricGraph graph, float latitude, float longitude, float offset, float maxDistanceMeter, Func <GeometricEdge, bool> isOk) { HashSet <uint> uintSet1 = new HashSet <uint>(); GeoCoordinate geoCoordinate = new GeoCoordinate((double)latitude, (double)longitude); HashSet <uint> uintSet2 = graph.Search(latitude, longitude, offset); GeometricGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(); foreach (uint vertex1 in uintSet2) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (GeoCoordinate.DistanceEstimateInMeter((double)latitude, (double)longitude, (double)vertex2.Latitude, (double)vertex2.Longitude) < (double)maxDistanceMeter) { edgeEnumerator.MoveTo(vertex1); while (edgeEnumerator.MoveNext()) { if (isOk(edgeEnumerator.Current)) { uintSet1.Add(edgeEnumerator.Id); break; } } } } GeoCoordinateBox geoCoordinateBox = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.SouthEast)); HashSet <uint> uintSet3 = new HashSet <uint>(); foreach (uint vertex1 in uintSet2) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (edgeEnumerator.MoveTo(vertex1) && edgeEnumerator.HasData) { while (edgeEnumerator.MoveNext()) { if (!uintSet3.Contains(edgeEnumerator.Id)) { uintSet3.Add(edgeEnumerator.Id); bool flag = isOk == null; ICoordinate coordinate = (ICoordinate)vertex2; ShapeBase shapeBase = edgeEnumerator.Shape; if (shapeBase != null) { if (edgeEnumerator.DataInverted) { shapeBase = shapeBase.Reverse(); } IEnumerator <ICoordinate> enumerator = shapeBase.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext()) { ICoordinate current = enumerator.Current; if (GeoCoordinate.DistanceEstimateInMeter((double)current.Latitude, (double)current.Longitude, (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } if (geoCoordinateBox.IntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)current.Longitude, (double)current.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)current.Latitude, (double)current.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null && GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } } coordinate = current; } } ICoordinate vertex3 = (ICoordinate)graph.GetVertex(edgeEnumerator.To); if (geoCoordinateBox.IntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)vertex3.Longitude, (double)vertex3.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)vertex3.Latitude, (double)vertex3.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null && GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude) < (double)maxDistanceMeter) { if (!flag && isOk(edgeEnumerator.Current)) { flag = true; } if (flag) { uintSet1.Add(edgeEnumerator.Id); } } } } } } } return(new List <uint>((IEnumerable <uint>)uintSet1)); }
public static uint[] SearchClosestEdges(this GeometricGraph graph, float latitude, float longitude, float latitudeOffset, float longitudeOffset, float maxDistanceMeter, Func <GeometricEdge, bool>[] isOks) { GeoCoordinate geoCoordinate = new GeoCoordinate((double)latitude, (double)longitude); HashSet <uint> uintSet1 = graph.Search(latitude - latitudeOffset, longitude - longitudeOffset, latitude + latitudeOffset, longitude + longitudeOffset); uint[] numArray1 = new uint[isOks.Length]; double[] numArray2 = new double[isOks.Length]; for (int index = 0; index < numArray1.Length; ++index) { numArray1[index] = uint.MaxValue; numArray2[index] = (double)maxDistanceMeter; } GeometricGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(); foreach (uint vertex1 in uintSet1) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); double num = GeoCoordinate.DistanceEstimateInMeter((double)latitude, (double)longitude, (double)vertex2.Latitude, (double)vertex2.Longitude); for (int index = 0; index < isOks.Length; ++index) { if (num < numArray2[index]) { edgeEnumerator.MoveTo(vertex1); while (edgeEnumerator.MoveNext()) { if (isOks[index](edgeEnumerator.Current)) { numArray2[index] = num; numArray1[index] = edgeEnumerator.Id; break; } } } } } GeoCoordinateBox[] boxes = new GeoCoordinateBox[isOks.Length]; for (int index = 0; index < boxes.Length; ++index) { boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)((double)maxDistanceMeter), DirectionEnum.SouthEast)); } HashSet <uint> uintSet2 = new HashSet <uint>(); foreach (uint vertex1 in uintSet1) { GeoCoordinateSimple vertex2 = graph.GetVertex(vertex1); if (edgeEnumerator.MoveTo(vertex1) && edgeEnumerator.HasData) { while (edgeEnumerator.MoveNext()) { if (!uintSet2.Contains(edgeEnumerator.Id)) { uintSet2.Add(edgeEnumerator.Id); bool[] flagArray = new bool[isOks.Length]; for (int index = 0; index < isOks.Length; ++index) { flagArray[index] = isOks[index] == null; } ICoordinate coordinate = (ICoordinate)vertex2; ShapeBase shapeBase = edgeEnumerator.Shape; if (shapeBase != null) { if (edgeEnumerator.DataInverted) { shapeBase = shapeBase.Reverse(); } IEnumerator <ICoordinate> enumerator = shapeBase.GetEnumerator(); enumerator.Reset(); while (enumerator.MoveNext()) { ICoordinate current = enumerator.Current; double num1 = GeoCoordinate.DistanceEstimateInMeter((double)current.Latitude, (double)current.Longitude, (double)latitude, (double)longitude); for (int index = 0; index < numArray1.Length; ++index) { if (num1 < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num1; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } if (boxes.AnyIntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)current.Longitude, (double)current.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)current.Latitude, (double)current.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null) { double num2 = GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude); for (int index = 0; index < numArray1.Length; ++index) { if (num2 < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num2; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } } } coordinate = current; } } ICoordinate vertex3 = (ICoordinate)graph.GetVertex(edgeEnumerator.To); if (boxes.AnyIntersectsPotentially((double)coordinate.Longitude, (double)coordinate.Latitude, (double)vertex3.Longitude, (double)vertex3.Latitude)) { PointF2D pointF2D = new GeoCoordinateLine(new GeoCoordinate((double)coordinate.Latitude, (double)coordinate.Longitude), new GeoCoordinate((double)vertex3.Latitude, (double)vertex3.Longitude), true, true).ProjectOn((PointF2D)geoCoordinate); if (pointF2D != (PointF2D)null) { double num = GeoCoordinate.DistanceEstimateInMeter(pointF2D[1], pointF2D[0], (double)latitude, (double)longitude); for (int index = 0; index < isOks.Length; ++index) { if (num < numArray2[index]) { if (!flagArray[index] && isOks[index](edgeEnumerator.Current)) { flagArray[index] = true; } if (flagArray[index]) { numArray2[index] = num; numArray1[index] = edgeEnumerator.Id; boxes[index] = new GeoCoordinateBox(new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.NorthWest), new GeoCoordinate((double)latitude, (double)longitude).OffsetWithDirection((Meter)numArray2[index], DirectionEnum.SouthEast)); } } } } } } } } } return(numArray1); }