private static NetTopologySuite.Geometries.Geometry LoadBounds(string scopeName, long relationId) { var scopeFile = $"{scopeName}\\Scope.osm"; var osm = FileSerializer.ReadXml <Osm>(scopeFile); CompleteRelation relation; if (osm != null) { relation = osm.GetElements().ToComplete().OfType <CompleteRelation>().First(); } else { NonAuthClient client = new NonAuthClient("https://www.osm.org/api/", new HttpClient()); relation = client.GetCompleteRelation(relationId).Result; FileSerializer.WriteXml(scopeFile, relation.ToSimpleWithChildren().AsOsm()); } var geometry = FeatureInterpreter.DefaultInterpreter.Interpret(relation).First().Geometry; if (geometry is LinearRing linRing) { var polygon = Polygon.DefaultFactory.CreatePolygon(linRing); // Or multipolygon? return(polygon); } else if (geometry is MultiPolygon multi) { return(multi); //Polygon.DefaultFactory.CreateMultiPolygon(); } throw new Exception("unexpected geometry type: " + geometry.GetType().Name); }
public static Osm GetElementsInBoundingBox(params Bounds[] bounds) { Log.LogInformation("Fetching Subject material from OSM"); var osmApiClient = new NonAuthClient(Static.Config["OsmApiUrl"], Static.HttpClient, Static.LogFactory.CreateLogger <NonAuthClient>()); var answers = new List <Osm>(); foreach (var bound in bounds) { answers.Add(GetElementsInBoundingBox(bound, osmApiClient).Result); } return(answers.Merge()); //var tasks = bounds.Select(async bound => await GetElementsInBoundingBox(bound, osmApiClient)).ToArray(); //Task.WaitAll(tasks); //return tasks.Select(t => t.Result).Merge(); }
private static async Task <Osm> GetElementsInBoundingBox(Bounds bounds, NonAuthClient client, int depth = 0, int maxDepth = 3) { try { return(await client.GetMap(bounds)); } catch (OsmApiException e) { if (!e.Message.Contains("limit is 50000") || depth > maxDepth) { throw; } Log.LogInformation("Fetch area was too big. Splitting it into smaller pieces and re-trying."); var tasks = bounds.Quarter().Select(async quarter => await GetElementsInBoundingBox(quarter, client, depth + 1)).ToArray(); Task.WaitAll(tasks); return(tasks.Select(t => t.Result).Merge()); } }
public static void RecreateMissingDiffResultFiles() { Static.Municipalities = FileSerializer.ReadJson <Dictionary <string, GeoJsonAPISource.Municipality> >("MaineMunicipalities.json"); var osmApiClient = new NonAuthClient(Static.Config["OsmApiUrl"], Static.HttpClient, Static.LogFactory.CreateLogger <NonAuthClient>()); foreach (var municipality in Static.Municipalities.Values.Where(m => m.ChangeSetIds.Any(id => id != -1))) { foreach (var changeId in municipality.ChangeSetIds) { var diffPath = $"{municipality.Name}/Uploaded/{changeId}-DiffResult.diff"; if (!File.Exists(diffPath)) { Console.WriteLine(diffPath); var changePath = $"{municipality.Name}/Uploaded/{changeId}-Conflated.osc"; var change = FileSerializer.ReadXml <OsmChange>(changePath); var mine = change.Create.OfType <Node>().ToArray(); var theirs = osmApiClient.GetChangesetDownload(changeId).Result; List <OsmGeoResult> results = theirs.Modify.Select(e => e.AsDiffResult()).ToList(); var map = Geometry.NodesInOrNearCompleteElements(theirs.Create.OfType <Node>().ToArray(), mine, 0, 0, new HashSet <long>()); if (map.Count != theirs.Create.Length || map.Any(pair => pair.Value.Count(v => Tags.AreEqual(v.Tags, pair.Key.Tags)) != 1)) { throw new Exception("bad map"); } results.AddRange(map.Select(pair => pair.Value.Single(v => Tags.AreEqual(v.Tags, pair.Key.Tags)).AsDiffResult(pair.Key.Id, 1))); var diffResult = new DiffResult() { Version = 0.6, Generator = "OsmPipeline", Results = results.ToArray() }; FileSerializer.WriteXml(diffPath, diffResult); } } } }