/// <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 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); }
// Verifies that an arbitrary S2ShapeIndex is buffered correctly, by first // converting the covering to an S2Polygon and then checking that (a) the // S2Polygon contains the original geometry and (b) the distance between the // original geometry and the boundary of the S2Polygon is at least "radius". // // The "radius" parameter is an S1Angle for convenience. // TODO(ericv): Add Degrees, Radians, etc, methods to S1ChordAngle? private static void TestBufferIndex(string index_str, S1Angle radius_angle, S2RegionCoverer coverer) { var index = MakeIndexOrDie(index_str); S1ChordAngle radius = new(radius_angle); var region = new S2ShapeIndexBufferedRegion(index, radius); S2CellUnion covering = coverer.GetCovering(region); // Compute an S2Polygon representing the union of the cells in the covering. S2Polygon covering_polygon = new(); covering_polygon.InitToCellUnionBorder(covering); MutableS2ShapeIndex covering_index = new(); covering_index.Add(new S2Polygon.Shape(covering_polygon)); // (a) Check that the covering contains the original index. Assert.True(S2BooleanOperation.Contains(covering_index, index)); // (b) Check that the distance between the boundary of the covering and the // the original indexed geometry is at least "radius". S2ClosestEdgeQuery query = new(covering_index); query.Options_.IncludeInteriors = (false); var target = new S2ClosestEdgeQuery.ShapeIndexTarget(index); Assert.False(query.IsDistanceLess(target, radius)); }
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 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 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); }
public void testRandomCaps() { Console.WriteLine("TestRandomCaps"); var kMaxLevel = S2CellId.MaxLevel; var coverer = new S2RegionCoverer(); for (var i = 0; i < 1000; ++i) { do { coverer.MinLevel = random(kMaxLevel + 1); coverer.MaxLevel = random(kMaxLevel + 1); } while (coverer.MinLevel > coverer.MaxLevel); coverer.MaxCells = skewed(10); coverer.LevelMod = 1 + random(3); var maxArea = Math.Min( 4 * S2.Pi, (3 * coverer.MaxCells + 1) * S2Cell.AverageArea(coverer.MinLevel)); var cap = getRandomCap(0.1 * S2Cell.AverageArea(kMaxLevel), maxArea); var covering = new List <S2CellId>(); var interior = new List <S2CellId>(); coverer.GetCovering(cap, covering); checkCovering(coverer, cap, covering, false); coverer.GetInteriorCovering(cap, interior); checkCovering(coverer, cap, interior, true); // Check that GetCovering is deterministic. var covering2 = new List <S2CellId>(); coverer.GetCovering(cap, covering2); assertTrue(covering.SequenceEqual(covering2)); // Also check S2CellUnion.denormalize(). The denormalized covering // may still be different and smaller than "covering" because // S2RegionCoverer does not guarantee that it will not output all four // children of the same parent. var cells = new S2CellUnion(); cells.InitFromCellIds(covering); var denormalized = new List <S2CellId>(); cells.Denormalize(coverer.MinLevel, coverer.LevelMod, denormalized); checkCovering(coverer, cap, denormalized, false); } }
public void Test_S2ShapeIndexBufferedRegion_EmptyIndex() { // Test buffering an empty S2ShapeIndex. var index = new MutableS2ShapeIndex(); var radius = new S1ChordAngle(S1Angle.FromDegrees(2)); var region = new S2ShapeIndexBufferedRegion(index, radius); var coverer = new S2RegionCoverer(); S2CellUnion covering = coverer.GetCovering(region); Assert.True(covering.IsEmpty()); }
public void Test_S2CellUnion_Expand() { // This test generates coverings for caps of random sizes, expands // the coverings by a random radius, and then make sure that the new // covering covers the expanded cap. It also makes sure that the // new covering is not too much larger than expected. var coverer = new S2RegionCoverer(); for (var i = 0; i < 1000; ++i) { _logger.WriteLine($"Iteration {i}"); var cap = S2Testing.GetRandomCap( S2Cell.AverageArea(S2.kMaxCellLevel), S2.M_4_PI); // Expand the cap area by a random factor whose log is uniformly // distributed between 0 and log(1e2). var expanded_cap = S2Cap.FromCenterHeight( cap.Center, Math.Min(2.0, Math.Pow(1e2, rnd.RandDouble()) * cap.Height())); var radius = (expanded_cap.Radius - cap.Radius).Radians(); var max_level_diff = rnd.Uniform(8); // Generate a covering for the original cap, and measure the maximum // distance from the cap center to any point in the covering. coverer.Options_.MaxCells = 1 + rnd.Skewed(10); var covering = coverer.GetCovering(cap); S2Testing.CheckCovering(cap, covering, true); var covering_radius = GetRadius(covering, cap.Center); // This code duplicates the logic in Expand(min_radius, max_level_diff) // that figures out an appropriate cell level to use for the expansion. int min_level = S2.kMaxCellLevel; foreach (var id in covering) { min_level = Math.Min(min_level, id.Level()); } var expand_level = Math.Min(min_level + max_level_diff, S2.kMinWidth.GetLevelForMinValue(radius)); // Generate a covering for the expanded cap, and measure the new maximum // distance from the cap center to any point in the covering. covering.Expand(S1Angle.FromRadians(radius), max_level_diff); S2Testing.CheckCovering(expanded_cap, covering, false); double expanded_covering_radius = GetRadius(covering, cap.Center); // If the covering includes a tiny cell along the boundary, in theory the // maximum angle of the covering from the cap center can increase by up to // twice the maximum length of a cell diagonal. Assert.True(expanded_covering_radius - covering_radius <= 2 * S2.kMaxDiag.GetValue(expand_level)); } }
public void Test_S2RegionUnionTest_Basic() { S2RegionUnion ru_empty = new(new List <IS2Region>()); Assert.Equal(0, ru_empty.Count()); Assert.Equal(S2Cap.Empty, ru_empty.GetCapBound()); Assert.Equal(S2LatLngRect.Empty, ru_empty.GetRectBound()); var empty_clone = (S2RegionUnion)ru_empty.CustomClone(); var two_point_region = new List <IS2Region> { new S2PointRegion(S2LatLng.FromDegrees(35, 40).ToPoint()), new S2PointRegion(S2LatLng.FromDegrees(-35, -40).ToPoint()) }; var two_points_orig = new S2RegionUnion(two_point_region); // two_point_region is in a valid, but unspecified, state. // Check that Clone() returns a deep copy. var two_points = (S2RegionUnion)two_points_orig.CustomClone(); // The bounds below may not be exactly equal because the S2PointRegion // version converts each S2LatLng value to an S2Point and back. Assert.True(MakeLatLngRectOrDie("-35:-40,35:40") !.Value .ApproxEquals(two_points.GetRectBound())); S2Cell face0 = S2Cell.FromFace(0); Assert.True(two_points.MayIntersect(face0)); Assert.False(two_points.Contains(face0)); Assert.True(two_points.Contains(S2LatLng.FromDegrees(35, 40).ToPoint())); Assert.True(two_points.Contains(S2LatLng.FromDegrees(-35, -40).ToPoint())); Assert.False(two_points.Contains(S2LatLng.FromDegrees(0, 0).ToPoint())); // Check that we can Add() another region. var three_points = (S2RegionUnion)two_points.CustomClone(); Assert.False(three_points.Contains(S2LatLng.FromDegrees(10, 10).ToPoint())); three_points.Add(new S2RegionUnion(new List <IS2Region> { new S2PointRegion(S2LatLng.FromDegrees(10, 10).ToPoint()) })); Assert.True(three_points.Contains(S2LatLng.FromDegrees(10, 10).ToPoint())); var coverer = new S2RegionCoverer(); coverer.Options_.MaxCells = 1; coverer.GetCovering(two_points, out var covering); Assert.Single(covering); Assert.Equal(face0.Id, covering[0]); }
public void Test_S2ShapeIndexBufferedRegion_PointZeroRadius() { // Test that buffering a point using a zero radius produces a non-empty // covering. (This requires using "less than or equal to" distance tests.) var index = MakeIndexOrDie("34:25 # #"); var region = new S2ShapeIndexBufferedRegion(index, S1ChordAngle.Zero); var coverer = new S2RegionCoverer(); S2CellUnion covering = coverer.GetCovering(region); Assert.Equal(1, covering.Size()); foreach (S2CellId id in covering) { Assert.True(id.IsLeaf()); } }
public void Test_S2ShapeIndexBufferedRegion_FullPolygon() { // Test buffering an S2ShapeIndex that contains a full polygon. var index = MakeIndexOrDie("# # full"); var radius = new S1ChordAngle(S1Angle.FromDegrees(2)); var region = new S2ShapeIndexBufferedRegion(index, radius); var coverer = new S2RegionCoverer(); S2CellUnion covering = coverer.GetCovering(region); Assert.Equal(6, covering.Size()); foreach (S2CellId id in covering) { Assert.True(id.IsFace()); } }
public void Test_S2ShapeIndexBufferedRegion_FullAfterBuffering() { // Test a region that becomes the full polygon after buffering. var index = MakeIndexOrDie("0:0 | 0:90 | 0:180 | 0:-90 | 90:0 | -90:0 # #"); var radius = new S1ChordAngle(S1Angle.FromDegrees(60)); var region = new S2ShapeIndexBufferedRegion(index, radius); var coverer = new S2RegionCoverer(); coverer.Options_.MaxCells = 1000; S2CellUnion covering = coverer.GetCovering(region); Assert.Equal(6, covering.Size()); foreach (S2CellId id in covering) { Assert.True(id.IsFace()); } }
public void testRandomCells() { Console.WriteLine("TestRandomCells"); var coverer = new S2RegionCoverer(); coverer.MaxCells = 1; // Test random cell ids at all levels. for (var i = 0; i < 10000; ++i) { var id = getRandomCellId(); var covering = new S2CellUnion(); coverer.GetCovering(new S2Cell(id), covering.CellIds); assertEquals(covering.Count, 1); assertEquals(covering.CellId(0), id); } }
public void testRandomCaps() { Console.WriteLine("TestRandomCaps"); var kMaxLevel = S2CellId.MaxLevel; var coverer = new S2RegionCoverer(); for (var i = 0; i < 1000; ++i) { do { coverer.MinLevel = random(kMaxLevel + 1); coverer.MaxLevel = random(kMaxLevel + 1); } while (coverer.MinLevel > coverer.MaxLevel); coverer.MaxCells = skewed(10); coverer.LevelMod = 1 + random(3); var maxArea = Math.Min( 4*S2.Pi, (3*coverer.MaxCells + 1)*S2Cell.AverageArea(coverer.MinLevel)); var cap = getRandomCap(0.1*S2Cell.AverageArea(kMaxLevel), maxArea); var covering = new List<S2CellId>(); var interior = new List<S2CellId>(); coverer.GetCovering(cap, covering); checkCovering(coverer, cap, covering, false); coverer.GetInteriorCovering(cap, interior); checkCovering(coverer, cap, interior, true); // Check that GetCovering is deterministic. var covering2 = new List<S2CellId>(); coverer.GetCovering(cap, covering2); assertTrue(covering.SequenceEqual(covering2)); // Also check S2CellUnion.denormalize(). The denormalized covering // may still be different and smaller than "covering" because // S2RegionCoverer does not guarantee that it will not output all four // children of the same parent. var cells = new S2CellUnion(); cells.InitFromCellIds(covering); var denormalized = new List<S2CellId>(); cells.Denormalize(coverer.MinLevel, coverer.LevelMod, denormalized); checkCovering(coverer, cap, denormalized, false); } }
private IEnumerable <S2CellId> GetCurrentS2CellIds(GPSLatLong currentLatLong) { // Info on S2 Geometry - https://s2geometry.io/ // Code taken from this video - https://www.youtube.com/watch?v=UZsf3bqmmKs (6:26) // Min/Max Level and Max Cells taken from here - https://s2.sidewalklabs.com/regioncoverer/ // Using Nuget S2Geometry vs 1.0.3 (https://www.nuget.org/packages/S2Geometry/) S2RegionCoverer rc = new S2RegionCoverer(); rc.MaxCells = S2RegionCoverer.DefaultMaxCells; rc.MinLevel = rc.MaxLevel = 14; // var southwestLat = new GPSLatLong { Latitude = 47.013859, Longitude = -122.920682 }; // var northeast = new GPSLatLong { Latitude = 47.033532, Longitude = -122.894687 }; // // S2LatLng low = S2LatLng.FromDegrees(southwestLat.Latitude, southwestLat.Longitude); // S2LatLng high = S2LatLng.FromDegrees(northeast.Latitude, northeast.Longitude); // // S2LatLngRect latLngRect = new S2LatLngRect(low, high); // return rc.GetCovering(latLngRect); //// https://stackoverflow.com/questions/7477003/calculating-new-longitude-latitude-from-old-n-meters //// number of km per degree = ~111km (111.32 in google maps, but range varies //// between 110.567km at the equator and 111.699km at the poles) //// 1km in degree = 1 / 111.32km = 0.0089 //// 1m in degree = 0.0089 / 1000 = 0.0000089 double meters = this.loadRadiusInMeters; double coef = meters * 0.0000089; double new_lat = /*currentLatLong.Latitude +*/ coef; double new_long = /*currentLatLong.Longitude +*/ coef / Math.Cos(currentLatLong.Latitude * (Math.PI / 180.0)); S2LatLng center = S2LatLng.FromDegrees(currentLatLong.Latitude, currentLatLong.Longitude); S2LatLng size = S2LatLng.FromDegrees(new_lat, new_long); return(rc.GetCovering(S2LatLngRect.FromCenterSize(center, size))); }
public List <Guid> Search(double lon, double lat, int radius) { lock (locker) { 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); var qres = rtree.Search(new Interval <UserList>(new UserList() { s2CellId = begin }, new UserList() { s2CellId = end })); foreach (var item in qres) { res.AddRange(item.Start.list); } } else { var qres = rtree.Search(new UserList() { s2CellId = sell }); if (qres.Count > 0) { foreach (var r in qres) { res.AddRange(r.Start.list); } } } } return(res); } }
private void TestRandomCaps(S2RegionTermIndexer.Options options, QueryType query_type) { // This function creates an index consisting either of points (if // options.index_contains_points_only() is true) or S2Caps of random size. // It then executes queries consisting of points (if query_type == POINT) // or S2Caps of random size (if query_type == CAP). var indexer = new S2RegionTermIndexer(options); var coverer = new S2RegionCoverer(options); var caps = new List <S2Cap>(); var coverings = new List <S2CellUnion>(); var index = new Dictionary <string, List <int> >(); int index_terms = 0, query_terms = 0; for (int i = 0; i < iters; ++i) { // Choose the region to be indexed: either a single point or a cap // of random size (up to a full sphere). S2Cap cap; List <string> terms; if (options.IndexContainsPointsOnly) { cap = S2Cap.FromPoint(S2Testing.RandomPoint()); terms = indexer.GetIndexTerms(cap.Center, ""); } else { cap = S2Testing.GetRandomCap( 0.3 * S2Cell.AverageArea(options.MaxLevel), 4.0 * S2Cell.AverageArea(options.MinLevel)); terms = indexer.GetIndexTerms(cap, ""); } caps.Add(cap); coverings.Add(coverer.GetCovering(cap)); foreach (var term in terms) { if (!index.ContainsKey(term)) { index.Add(term, new List <int>()); } index[term].Add(i); } index_terms += terms.Count; } for (int i = 0; i < iters; ++i) { // Choose the region to be queried: either a random point or a cap of // random size. S2Cap cap; List <string> terms; if (query_type == QueryType.CAP) { cap = S2Cap.FromPoint(S2Testing.RandomPoint()); terms = indexer.GetQueryTerms(cap.Center, ""); } else { cap = S2Testing.GetRandomCap( 0.3 * S2Cell.AverageArea(options.MaxLevel), 4.0 * S2Cell.AverageArea(options.MinLevel)); terms = indexer.GetQueryTerms(cap, ""); } // Compute the expected results of the S2Cell query by brute force. S2CellUnion covering = coverer.GetCovering(cap); var expected = new List <int>(); var actual = new List <int>(); for (int j = 0; j < caps.Count; ++j) { if (covering.Intersects(coverings[j])) { expected.Add(j); } } foreach (var term in terms) { actual.AddRange(index[term]); } Assert.Equal(expected, actual); query_terms += terms.Count; } _logger.WriteLine($"Index terms/doc: {((double)index_terms) / iters:2f}, Query terms/doc: {((double)query_terms) / iters:2f}"); }
private async Task <BootstrapTask> GetBootstrapTask() { ulong target; lock (_bootstrapLock) { target = _bootstrapCellIds.FirstOrDefault(); if (target == default) { return(null); } _bootstrapCellIds.Remove(target); } var cell = new S2Cell(new S2CellId(target)); var latlng = new S2LatLng(cell.Center); double radius; if (latlng.LatDegrees <= 39) { radius = 715; } else if (latlng.LatDegrees >= 69) { radius = 330; } else { radius = (-13 * latlng.LatDegrees) + 1225; } var radians = radius / 6378137; var centerNormalizedPoint = latlng.Normalized.ToPoint(); var circle = S2Cap.FromAxisHeight(centerNormalizedPoint, (radians * radians) / 2); var coverer = new S2RegionCoverer { MinLevel = 15, MaxLevel = 15, MaxCells = 100 }; var nearbyCellIds = coverer.GetCovering(circle).Select(x => x.Id); lock (_bootstrapCellIds) { _bootstrapCellIds.RemoveAll(cell => nearbyCellIds.Contains(cell)); } if (_bootstrapCellIds.Count == 0) { await Bootstrap().ConfigureAwait(false); if (_bootstrapCellIds.Count == 0) { await Update().ConfigureAwait(false); } } return(new BootstrapTask { Action = ActionType.ScanRaid, Area = Name, Latitude = latlng.LatDegrees, Longitude = latlng.LngDegrees, MinimumLevel = MinimumLevel, MaximumLevel = MaximumLevel, }); }
async void Load_Click(object sender, RoutedEventArgs e) { var picker = new Windows.Storage.Pickers.FileOpenPicker(); picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail; picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; picker.FileTypeFilter.Add(".geojson"); picker.FileTypeFilter.Add(".geoJSON"); picker.FileTypeFilter.Add(".csv"); Windows.Storage.StorageFile file = await picker.PickSingleFileAsync(); if (file != null) { try { using (StreamReader sr = new StreamReader(file.Path)) { string content = sr.ReadToEnd(); if (file.FileType == ".csv") { string[] lines = content.Split('\n'); for (int i = 0; i < lines.Length; i++) { var item = lines[i]; if (String.IsNullOrWhiteSpace(item)) { continue; } string[] info = item.Split(','); double lat = 0; double lon = 0; if (!Double.TryParse(info[info.Length - 2], out lon) || !Double.TryParse(info[info.Length - 3], out lat)) { if (i == 0) { continue; } var messageDialog = new MessageDialog("Zeile " + i + " (" + item + ") hat nicht das richtige Format!"); messageDialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(this.CommandInvokedHandler))); messageDialog.DefaultCommandIndex = 0; messageDialog.Title = "Fehlerhafte Datei"; await messageDialog.ShowAsync(); return; } StringBuilder sb = new StringBuilder(""); for (int j = 0; j < info.Length - 3; j++) { sb.Append(info[j]); } PointOfInterest poi = new PointOfInterest() { Location = new Geopoint(new BasicGeoposition() { Latitude = lat, Longitude = lon }), DisplayName = sb.ToString(), NormalizedAnchorPoint = AnchorPoints[2], Flag = PointOfInterest.PORTAL, Leaf = FindExactCell(new BasicGeoposition() { Latitude = lat, Longitude = lon }, 30).Id.Id }; portals.Add(poi); //DataAccess.AddData(poi); } } else { var features = JsonConvert.DeserializeObject <FeatureCollection>(content).Features; foreach (var p in features) { double lon = ((Point)p.Geometry).Coordinates.Longitude; double lat = ((Point)p.Geometry).Coordinates.Latitude; int flag = PointOfInterest.PORTAL; if (p.Properties.ContainsKey("Flag")) { flag = (int)p.Properties["Flag"]; } PointOfInterest poi = new PointOfInterest() { Location = new Geopoint(new BasicGeoposition() { Latitude = lat, Longitude = lon }), DisplayName = (string)p.Properties["name"], NormalizedAnchorPoint = AnchorPoints[flag], Flag = flag, Leaf = FindExactCell(new BasicGeoposition() { Latitude = lat, Longitude = lon }, 30).Id.Id }; portals.Add(poi); //DataAccess.AddData(poi); } } AddLayers(); } } catch (UnauthorizedAccessException) { Windows.Storage.StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation; var messageDialog = new MessageDialog("Zugriff auf den Pfad " + file.Path + " wurde verweigert.\nBitte gewähren Sie Zugriff unter \n\nEinstellungen -> Privatsphäre -> Dateisystem\n\noder bewegen Sie die Datei an diesen Ort:\n" + installedLocation.Path); messageDialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(this.CommandInvokedHandler))); messageDialog.DefaultCommandIndex = 0; messageDialog.Title = "Keine Zugriffsrechte"; await messageDialog.ShowAsync(); return; } // outermost bounds double maxLat = -360; double maxLon = -360; double minLat = 360; double minLon = 360; // Find out all Lvl17 cells foreach (var p in portals) { double lat = p.Location.Position.Latitude; double lon = p.Location.Position.Longitude; if (lon < minLon) { minLon = lon; } if (lon > maxLon) { maxLon = lon; } if (lat < minLat) { minLat = lat; } if (lat > maxLat) { maxLat = lat; } var cell = FindExactCell(p.Location.Position, 17); MapPolygon polygon = new MapPolygon { Path = new Geopath(new List <BasicGeoposition>() { FromS2Point(cell.GetVertex(0)), FromS2Point(cell.GetVertex(1)), FromS2Point(cell.GetVertex(2)), FromS2Point(cell.GetVertex(3)) }), ZIndex = 1, FillColor = Color.FromArgb(50, 50, 50, 50), StrokeColor = Colors.Black, StrokeThickness = 2, StrokeDashed = false }; lvl17Cells.Add(polygon); AddCell(polygon); } // Find out Lvl14 cells var area = S2LatLngRect.FromPointPair( S2LatLng.FromDegrees(minLat, minLon), S2LatLng.FromDegrees(maxLat, maxLon) ); var cells14 = new List <S2CellId>(); lvl14Coverer.GetCovering(area, cells14); for (int i = 0; i < cells14.Count; i++) { S2Cell cell = new S2Cell(cells14[i]); MapPolygon polygon = new MapPolygon { Path = new Geopath(new List <BasicGeoposition>() { FromS2Point(cell.GetVertex(0)), FromS2Point(cell.GetVertex(1)), FromS2Point(cell.GetVertex(2)), FromS2Point(cell.GetVertex(3)) }), ZIndex = 1, FillColor = Color.FromArgb(50, 0, 0, 50), StrokeColor = Colors.Blue, StrokeThickness = 2, StrokeDashed = false }; lvl14Cells.Add(polygon); AddCell(polygon); } BasicGeoposition newCenter = new BasicGeoposition(); newCenter.Latitude = (minLat + maxLat) / 2; newCenter.Longitude = (minLon + maxLon) / 2; PokeMap.Center = new Geopoint(newCenter); } }