public void AddUser(Guid uid, double lon, double lat) { var lonLat = S2LatLng.FromDegrees(lat, lon); var cellId = S2CellId.FromLatLng(lonLat); var cellIdStorageLevel = cellId.ParentForLevel(_level); var userList = new UserList { s2CellId = cellIdStorageLevel, list = new List <Guid>() }; var item = tree.Search(userList.s2CellId); if (item != null) { userList = new UserList { s2CellId = item.Key, list = item.Pointer }; tree.Delete(userList.s2CellId); } if (userList.list == null) { userList.list = new List <Guid>(); } userList.list.Add(uid); tree.Insert(userList.s2CellId, userList.list); }
public static ulong[] GetCellIdsForLatLong(double latitude, double longitude) { var latLong = S2LatLng.FromDegrees(latitude, longitude); var cell = S2CellId.FromLatLng(latLong); var cellId = cell.ParentForLevel(15); var cells = cellId.GetEdgeNeighbors(); var cellIds = new List <ulong> { cellId.Id }; foreach (var cellEdge1 in cells) { if (!cellIds.Contains(cellEdge1.Id)) { cellIds.Add(cellEdge1.Id); } foreach (var cellEdge2 in cellEdge1.GetEdgeNeighbors()) { if (!cellIds.Contains(cellEdge2.Id)) { cellIds.Add(cellEdge2.Id); } } } return(cellIds.ToArray()); }
public List <S2CellId> GetS2CellIds(ushort level, int maxCells) { //var geofence = Geofence.FromMultiPolygon(this); var bbox = GetBoundingBox(); var regionCoverer = new S2RegionCoverer { MinLevel = level, MaxLevel = level, MaxCells = maxCells, }; var region = new S2LatLngRect( S2LatLng.FromDegrees(bbox.MinimumLatitude, bbox.MinimumLongitude), S2LatLng.FromDegrees(bbox.MaximumLatitude, bbox.MaximumLongitude) ); var coverage = new List <S2CellId>(); regionCoverer.GetCovering(region, coverage); var result = new List <S2CellId>(); foreach (var cellId in coverage) { var cell = new S2Cell(cellId); for (var i = 0; i <= 3; i++) { var vertex = cell.GetVertex(i); var coord = new S2LatLng(new S2Point(vertex.X, vertex.Y, vertex.Z)); //if (geofence.Intersects(coord.LatDegrees, coord.LngDegrees)) if (GeofenceService.InPolygon(this, coord.LatDegrees, coord.LngDegrees)) { result.Add(cellId); } } } return(result); }
public void testConversion() { // Test special cases: poles, "date line" assertDoubleNear( new S2LatLng(S2LatLng.FromDegrees(90.0, 65.0).ToPoint()).Lat.Degrees, 90.0); assertEquals( new S2LatLng(S2LatLng.FromRadians(-S2.PiOver2, 1).ToPoint()).Lat.Radians, -S2.PiOver2); assertDoubleNear( Math.Abs(new S2LatLng(S2LatLng.FromDegrees(12.2, 180.0).ToPoint()).Lng.Degrees), 180.0); assertEquals( Math.Abs(new S2LatLng(S2LatLng.FromRadians(0.1, -S2.Pi).ToPoint()).Lng.Radians), S2.Pi); // Test a bunch of random points. for (var i = 0; i < 100000; ++i) { var p = randomPoint(); assertTrue(S2.ApproxEquals(p, new S2LatLng(p).ToPoint())); } // Test generation from E5 var test = S2LatLng.FromE5(123456, 98765); assertDoubleNear(test.Lat.Degrees, 1.23456); assertDoubleNear(test.Lng.Degrees, 0.98765); }
public void testGetClosestPoint() { var kMargin = 1e-6; var a = S2LatLng.FromDegrees(-0.5, 0).ToPoint(); var b = S2LatLng.FromDegrees(+0.5, 0).ToPoint(); // On edge at end points. assertEquals(a, S2EdgeUtil.GetClosestPoint(a, a, b)); assertEquals(b, S2EdgeUtil.GetClosestPoint(b, a, b)); // On edge in between. var mid = S2LatLng.FromDegrees(0, 0).ToPoint(); assertEquals(mid, S2EdgeUtil.GetClosestPoint(mid, a, b)); // End points are closest assertEquals(a, S2EdgeUtil.GetClosestPoint(S2LatLng.FromDegrees(-1, 0).ToPoint(), a, b)); assertEquals(b, S2EdgeUtil.GetClosestPoint(S2LatLng.FromDegrees(+1, 0).ToPoint(), a, b)); // Intermediate point is closest. var x = S2LatLng.FromDegrees(+0.1, 1).ToPoint(); var expectedClosestPoint = S2LatLng.FromDegrees(+0.1, 0).ToPoint(); assertTrue(expectedClosestPoint.ApproxEquals(S2EdgeUtil.GetClosestPoint(x, a, b), kMargin)); }
public void Test_S2LatLng_TestDistance() { Assert.Equal(0.0, S2LatLng.FromDegrees(90, 0).GetDistance(S2LatLng.FromDegrees(90, 0)).Radians); Assert2.Near(77.0, S2LatLng.FromDegrees(-37, 25).GetDistance(S2LatLng.FromDegrees(-66, -155)).GetDegrees(), 1e-13); Assert2.Near(115.0, S2LatLng.FromDegrees(0, 165).GetDistance(S2LatLng.FromDegrees(0, -80)).GetDegrees(), 1e-13); Assert2.Near(180.0, S2LatLng.FromDegrees(47, -127).GetDistance(S2LatLng.FromDegrees(-47, 53)).GetDegrees(), 2e-6); }
/// <summary> /// Find the cell of the given level that covers the given Geoposition. /// This method uses the library given S2RegionCoverer to find the leaf cell containing the given Geoposition /// and uses binary operation on the leaf cell's Id to find the higher level cell containing the leaf. /// This is somehow more accurate than using the S2RegionCoverer for the higher level cell, where some errors occured. /// </summary> /// <param name="pos">Position in the cell</param> /// <param name="level">Level of the cell</param> /// <returns>The cell covering the given position that matches the specifications</returns> private S2Cell FindExactCell(BasicGeoposition pos, int level) { var point = S2LatLngRect.FromPoint(S2LatLng.FromDegrees(pos.Latitude, pos.Longitude)); var cells = new List <S2CellId>(); // find leaf cell var coverer = new S2RegionCoverer() { MinLevel = 30, MaxLevel = 30, MaxCells = 1 }; coverer.GetCovering(point, cells); var leaf = new S2Cell(cells[0]); int shift = 64 - (3 + level * 2 + 1); ulong id = leaf.Id.Id & ulong.MaxValue << shift; id |= 0 | ((ulong)1 << shift); return(new S2Cell(new S2CellId(id))); }
private S2CellId getCellId(double latDegrees, double lngDegrees) { var id = S2CellId.FromLatLng(S2LatLng.FromDegrees(latDegrees, lngDegrees)); Trace.WriteLine(Convert.ToString(unchecked ((long)id.Id), 16)); return(id); }
private static List <Coordinate> GetS2Cells(BoundingBox bbox) { var regionCoverer = new S2RegionCoverer { MinLevel = 15, MaxLevel = 15, //MaxCells = 100, }; var region = new S2LatLngRect( S2LatLng.FromDegrees(bbox.MinimumLatitude, bbox.MinimumLongitude), S2LatLng.FromDegrees(bbox.MaximumLatitude, bbox.MaximumLongitude) ); var cellIds = regionCoverer.GetCovering(region); var list = new List <Coordinate>(); foreach (var cellId in cellIds) { var center = cellId.ToLatLng(); list.Add(new Coordinate(center.LatDegrees, center.LngDegrees)); } // TODO: Check if point is within geofence //var filtered = FilterCoordinates(coordinates); //return filtered; return(list); }
public static ulong GetPokeCell(ICoordinate poke) { var latLng = S2LatLng.FromDegrees((double)poke.Latitude, (double)poke.Longitude); var hash = S2CellId.FromLatLng(latLng).ParentForLevel(20).Id; return(hash); }
public void Test_MakeLatLngRect_ValidInput() { Assert.True(MakeLatLngRect("-10:-10, 10:10", out var rect)); Assert.Equal(rect, new S2LatLngRect( S2LatLng.FromDegrees(-10, -10), S2LatLng.FromDegrees(10, 10))); }
/// <summary> /// Filter out any points outside of the queried area from the input list. /// </summary> /// <param name="list">List of items return by Amazon DynamoDB. It may contains points outside of the actual area queried.</param> /// <param name="geoQueryRequest">List of items within the queried area.</param> /// <returns></returns> private IEnumerable <IDictionary <string, AttributeValue> > Filter(IEnumerable <IDictionary <string, AttributeValue> > list, GeoQueryRequest geoQueryRequest) { var result = new List <IDictionary <String, AttributeValue> >(); S2LatLngRect?latLngRect = null; S2LatLng? centerLatLng = null; double radiusInMeter = 0; if (geoQueryRequest is QueryRectangleRequest) { latLngRect = S2Util.GetBoundingLatLngRect(geoQueryRequest); } foreach (var item in list) { var geoJson = item[_config.GeoJsonAttributeName].S; var geoPoint = GeoJsonMapper.GeoPointFromString(geoJson); var latLng = S2LatLng.FromDegrees(geoPoint.lat, geoPoint.lng); if (latLngRect != null && latLngRect.Value.Contains(latLng)) { result.Add(item); } else if (centerLatLng != null && radiusInMeter > 0 && centerLatLng.Value.GetEarthDistance(latLng) <= radiusInMeter) { result.Add(item); } } return(result); }
public void Test_S2LatLngRect_FromPoint() { S2LatLng p = S2LatLng.FromDegrees(23, 47); Assert.Equal(S2LatLngRect.FromPoint(p), new S2LatLngRect(p, p)); Assert.True(S2LatLngRect.FromPoint(p).IsPoint()); }
public List <Guid> Search(double lon, double lat, int radius) { var latlng = S2LatLng.FromDegrees(lat, lon); var centerPoint = pointFromLatLng(lat, lon); var centerAngle = ((double)radius) / EarthRadiusM; var cap = S2Cap.FromAxisAngle(centerPoint, S1Angle.FromRadians(centerAngle)); var regionCoverer = new S2RegionCoverer(); regionCoverer.MaxLevel = 13; // regionCoverer.MinLevel = 13; //regionCoverer.MaxCells = 1000; // regionCoverer.LevelMod = 0; var covering = regionCoverer.GetCovering(cap); var res = new List <Guid>(); foreach (var u in covering) { var sell = new S2CellId(u.Id); if (sell.Level < _level) { var begin = sell.ChildBeginForLevel(_level); var end = sell.ChildEndForLevel(_level); do { var cur = tree.Search(new S2CellId(begin.Id)); if (cur != null) { res.AddRange(cur.Pointer); } begin = begin.Next; } while (begin.Id != end.Id); } else { var item = tree.Search(sell); if (item != null) { res.AddRange(item.Pointer); } } } return(res); }
public static ulong GenerateGeohash(double latitude, double longitude) { var latLng = S2LatLng.FromDegrees(latitude, longitude); var cell = new S2Cell(latLng); var cellId = cell.Id; return(cellId.Id); }
public static ulong GenerateGeohash(GeoPoint geoPoint) { var latLng = S2LatLng.FromDegrees(geoPoint.lat, geoPoint.lng); var cell = new S2Cell(latLng); var cellId = cell.Id; return(cellId.Id); }
public List <Guid> Search(double lon, double lat, int radius) { var latlng = S2LatLng.FromDegrees(lat, lon); var centerPoint = Index.pointFromLatLng(lat, lon); var centerAngle = ((double)radius) / Index.EarthRadiusM; var cap = S2Cap.FromAxisAngle(centerPoint, S1Angle.FromRadians(centerAngle)); var regionCoverer = new S2RegionCoverer(); regionCoverer.MaxLevel = 13; // regionCoverer.MinLevel = 13; //regionCoverer.MaxCells = 1000; // regionCoverer.LevelMod = 0; var covering = regionCoverer.GetCovering(cap); var res = new List <Guid>(); foreach (var u in covering) { var sell = new S2CellId(u.Id); if (sell.Level < _level) { var begin = sell.ChildBeginForLevel(_level); var end = sell.ChildEndForLevel(_level); var qres = rtree.Query(new Range <S2CellId>(begin, end)); foreach (var r in qres) { res.AddRange(r.Content); } } else { var qres = rtree.Query(new Range <S2CellId>(sell)); if (qres.Count > 0) { foreach (var r in qres) { res.AddRange(r.Content); } } } } return(res); }
private static S2LatLngRect RectFromDegrees(double lat_lo, double lng_lo, double lat_hi, double lng_hi) { // Convenience method to construct a rectangle. This method is // intentionally *not* in the S2LatLngRect interface because the // argument order is ambiguous, but hopefully it's not too confusing // within the context of this unit test. return(new S2LatLngRect(S2LatLng.FromDegrees(lat_lo, lng_lo).Normalized(), S2LatLng.FromDegrees(lat_hi, lng_hi).Normalized())); }
public void Test_E7() { ExpectMaxDigits(S2LatLng.FromDegrees(0, 0), 7); for (var i = 0; i < kIters; i++) { var ll = S2LatLng.FromPoint(S2Testing.RandomPoint()); var ll_e7 = S2LatLng.FromE7(ll.Lat().E7(), ll.Lng().E7()); ExpectMaxDigits(ll_e7, 7); } }
public void Test_MakeLaxPolyline_ValidInput() { Assert.True(MakeLaxPolyline("-20:150, -20:151, -19:150", out var laxPolyline)); // No easy equality check for LaxPolylines; check vertices instead. Assert.Equal(3, laxPolyline.NumVertices()); Assert.True(new S2LatLng(laxPolyline.Vertex(0)).ApproxEquals(S2LatLng.FromDegrees(-20, 150))); Assert.True(new S2LatLng(laxPolyline.Vertex(1)).ApproxEquals(S2LatLng.FromDegrees(-20, 151))); Assert.True(new S2LatLng(laxPolyline.Vertex(2)).ApproxEquals(S2LatLng.FromDegrees(-19, 150))); }
public void Test_ParsePoints_ValidInput() { var vertices = new List <S2Point>(); Assert.True(ParsePoints("-20:150, -20:151, -19:150", vertices)); Assert.Equal(3, vertices.Count); Assert.Equal(vertices[0], S2LatLng.FromDegrees(-20, 150).ToPoint()); Assert.Equal(vertices[1], S2LatLng.FromDegrees(-20, 151).ToPoint()); Assert.Equal(vertices[2], S2LatLng.FromDegrees(-19, 150).ToPoint()); }
public void Test_ParseLatLngs_ValidInput() { var latlngs = new List <S2LatLng>(); Assert.True(ParseLatLngs("-20:150, -20:151, -19:150", latlngs)); Assert.Equal(3, latlngs.Count); Assert.Equal(latlngs[0], S2LatLng.FromDegrees(-20, 150)); Assert.Equal(latlngs[1], S2LatLng.FromDegrees(-20, 151)); Assert.Equal(latlngs[2], S2LatLng.FromDegrees(-19, 150)); }
public void Test_S2LatLngRect_Expanded() { Assert.True(RectFromDegrees(70, 150, 80, 170). Expanded(S2LatLng.FromDegrees(20, 30)). ApproxEquals(RectFromDegrees(50, 120, 90, -160))); Assert.True(S2LatLngRect.Empty.Expanded(S2LatLng.FromDegrees(20, 30)). IsEmpty()); Assert.True(S2LatLngRect.Full.Expanded(S2LatLng.FromDegrees(500, 500)). IsFull()); Assert.True(RectFromDegrees(-90, 170, 10, 20). Expanded(S2LatLng.FromDegrees(30, 80)). ApproxEquals(RectFromDegrees(-90, -180, 40, 180))); // Negative margins. Assert.True(RectFromDegrees(10, -50, 60, 70). Expanded(S2LatLng.FromDegrees(-10, -10)). ApproxEquals(RectFromDegrees(20, -40, 50, 60))); Assert.True(RectFromDegrees(-20, -180, 20, 180). Expanded(S2LatLng.FromDegrees(-10, -10)). ApproxEquals(RectFromDegrees(-10, -180, 10, 180))); Assert.True(RectFromDegrees(-20, -180, 20, 180). Expanded(S2LatLng.FromDegrees(-30, -30)).IsEmpty()); Assert.True(RectFromDegrees(-90, 10, 90, 11). Expanded(S2LatLng.FromDegrees(-10, -10)).IsEmpty()); Assert.True(RectFromDegrees(-90, 10, 90, 100). Expanded(S2LatLng.FromDegrees(-10, -10)). ApproxEquals(RectFromDegrees(-80, 20, 80, 90))); Assert.True(S2LatLngRect.Empty.Expanded(S2LatLng.FromDegrees(-50, -500)). IsEmpty()); Assert.True(S2LatLngRect.Full.Expanded(S2LatLng.FromDegrees(-50, -50)). ApproxEquals(RectFromDegrees(-40, -180, 40, 180))); // Mixed margins. Assert.True(RectFromDegrees(10, -50, 60, 70). Expanded(S2LatLng.FromDegrees(-10, 30)). ApproxEquals(RectFromDegrees(20, -80, 50, 100))); Assert.True(RectFromDegrees(-20, -180, 20, 180). Expanded(S2LatLng.FromDegrees(10, -500)). ApproxEquals(RectFromDegrees(-30, -180, 30, 180))); Assert.True(RectFromDegrees(-90, -180, 80, 180). Expanded(S2LatLng.FromDegrees(-30, 500)). ApproxEquals(RectFromDegrees(-60, -180, 50, 180))); Assert.True(RectFromDegrees(-80, -100, 80, 150). Expanded(S2LatLng.FromDegrees(30, -50)). ApproxEquals(RectFromDegrees(-90, -50, 90, 100))); Assert.True(RectFromDegrees(0, -180, 50, 180). Expanded(S2LatLng.FromDegrees(-30, 500)).IsEmpty()); Assert.True(RectFromDegrees(-80, 10, 70, 20). Expanded(S2LatLng.FromDegrees(30, -200)).IsEmpty()); Assert.True(S2LatLngRect.Empty.Expanded(S2LatLng.FromDegrees(100, -100)). IsEmpty()); Assert.True(S2LatLngRect.Full.Expanded(S2LatLng.FromDegrees(100, -100)). IsFull()); }
public void Test_MakePolyline_ValidInput() { Assert.True(MakePolyline("-20:150, -20:151, -19:150", out var polyline)); var expected = new S2Polyline(new[] { S2LatLng.FromDegrees(-20, 150).ToPoint(), S2LatLng.FromDegrees(-20, 151).ToPoint(), S2LatLng.FromDegrees(-19, 150).ToPoint(), }); Assert.True(polyline == expected); }
public void Test_MakeLoop_ValidInput() { Assert.True(MakeLoop("-20:150, -20:151, -19:150", out var loop)); var expected = new S2Loop(new[] { S2LatLng.FromDegrees(-20, 150).ToPoint(), S2LatLng.FromDegrees(-20, 151).ToPoint(), S2LatLng.FromDegrees(-19, 150).ToPoint(), }); Assert.True(loop.BoundaryApproxEquals(expected)); }
public void Test_S2_GetPointToRightS1ChordAngle() { S2Point a = S2LatLng.FromDegrees(0, 0).ToPoint(); S2Point b = S2LatLng.FromDegrees(0, 5).ToPoint(); // east S1Angle kDistance = S2Testing.MetersToAngle(10); S2Point c = S2.GetPointToRight(a, b, new S1ChordAngle(kDistance)); Assert2.Near(new S1Angle(a, c).Radians, kDistance.Radians, 1e-15); // CAB must be a right angle with C to the right of AB. Assert2.Near(S2.TurnAngle(c, a, b), -S2.M_PI_2 /*radians*/, 1e-15); }
public void Test_S2LatLngRect_AddPoint() { S2LatLngRect p = S2LatLngRect.Empty; p = p.AddPoint(S2LatLng.FromDegrees(0, 0)); Assert.True(p.IsPoint()); p = p.AddPoint(S2LatLng.FromRadians(0, -S2.M_PI_2)); Assert.False(p.IsPoint()); p = p.AddPoint(S2LatLng.FromRadians(S2.M_PI_4, -Math.PI)); p = p.AddPoint(new S2Point(0, 0, 1)); Assert.Equal(p, RectFromDegrees(0, -180, 90, 0)); }
public void testContains() { assertTrue(candyCane.Contains(S2LatLng.FromDegrees(5, 71).ToPoint())); for (var i = 0; i < 4; ++i) { assertTrue(northHemi.Contains(new S2Point(0, 0, 1))); assertTrue(!northHemi.Contains(new S2Point(0, 0, -1))); assertTrue(!southHemi.Contains(new S2Point(0, 0, 1))); assertTrue(southHemi.Contains(new S2Point(0, 0, -1))); assertTrue(!westHemi.Contains(new S2Point(0, 1, 0))); assertTrue(westHemi.Contains(new S2Point(0, -1, 0))); assertTrue(eastHemi.Contains(new S2Point(0, 1, 0))); assertTrue(!eastHemi.Contains(new S2Point(0, -1, 0))); northHemi = rotate(northHemi); southHemi = rotate(southHemi); eastHemi = rotate(eastHemi); westHemi = rotate(westHemi); } // This code checks each cell vertex is contained by exactly one of // the adjacent cells. for (var level = 0; level < 3; ++level) { var loops = new List <S2Loop>(); var loopVertices = new List <S2Point>(); ISet <S2Point> points = new HashSet <S2Point>(); for (var id = S2CellId.Begin(level); !id.Equals(S2CellId.End(level)); id = id.Next) { var cell = new S2Cell(id); points.Add(cell.Center); for (var k = 0; k < 4; ++k) { loopVertices.Add(cell.GetVertex(k)); points.Add(cell.GetVertex(k)); } loops.Add(new S2Loop(loopVertices)); loopVertices.Clear(); } foreach (var point in points) { var count = 0; for (var j = 0; j < loops.Count; ++j) { if (loops[j].Contains(point)) { ++count; } } assertEquals(count, 1); } } }
public void Test_MakeVerbatimPolygon_ValidInput() { Assert.True(MakeVerbatimPolygon("-20:150, -20:151, -19:150", out var polygon)); var vertices = new[] { new [] { -20, 150 }, new [] { -20, 151 }, new [] { -19, 150 }, }.Select(t => S2LatLng.FromDegrees(t[0], t[1]).ToPoint()); var expected = new S2Polygon(new S2Loop(vertices)); Assert.Equal(polygon, expected); }
public void Test_MakePolygon_ValidInput() { Assert.True(MakePolygon("-20:150, -20:151, -19:150", out var polygon)); var vertices = new[] { S2LatLng.FromDegrees(-20, 150).ToPoint(), S2LatLng.FromDegrees(-20, 151).ToPoint(), S2LatLng.FromDegrees(-19, 150).ToPoint(), }; var expected = new S2Polygon(new S2Loop(vertices)); Assert.True(polygon == expected); }