public void DoFilter(string key, IEnumerable <OsmGeo> elements) { var values = elements.Where(e => e.Tags.ContainsKey(key)).Select(e => e.Tags[key]).Distinct().OrderBy(v => v).ToArray(); foreach (var value in values) { Console.WriteLine("?\t" + value); var choice = char.ToUpper(Console.ReadKey().KeyChar); if (choice == 'N') { Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}"); } else if (choice == 'U') { Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~addr:unit"); } else if (choice == 'D') { Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~description"); } else if (choice == 'O') { Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~operator"); } else if (choice == 'B') { var newValue = value.ToLower().Replace("building", "").Trim(); Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~building={newValue}"); } else if (choice == 'M') { Console.WriteLine($"Move '{value}' to what key?"); var newKey = Console.ReadLine(); Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~{newKey}"); } else if (choice == 'A') { Static.Municipalities[Municipality].BlackTags.Add($"*.{key}={value}~alt_name"); } else if (choice == 'Y') { } else { Console.WriteLine("Canceling"); return; } } FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); }
// nohousenumber=yes // consider just leaving out all addr:unit=* // option to moveNode or not. (Do you trust E911 locations more than OSM?) // MatchWidth list to handle multi-match // Maybe fix addr:street punctuation on elements that I didn't add or update // Maybe fix addr:street should be addr:place on elements that I didn't add or update // Maybe fix nodes merging into buildings on elements that I didn't add or update public void Main() { Static.Municipalities = FileSerializer.ReadJsonCacheOrSource("MaineMunicipalities.json", GetMunicipalities).Result; ShowProgress(); Municipality = Static.Municipalities.Values.First(m => !m.ChangeSetIds.Any()).Name; Console.WriteLine("Starting in " + Municipality); while (true) { Console.Write("> "); var userInput = Console.ReadLine(); if (Is(userInput, "reference")) { //Func<Feature, bool> filter = f => (f.Geometry as Point).Coordinates.Longitude >= -70.505; var reference = References.Fetch(Municipality).Result; FileSerializer.WriteXml(Municipality + "/Reference.osm", reference); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "review ref")) { var reference = GetReference(); References.Report(reference.GetElements().ToArray()); } else if (Is(userInput, "subject")) { var reference = GetReference(); var subject = Subjects.GetElementsInBoundingBox(reference.Bounds.ExpandBy(15)); FileSerializer.WriteXml(Municipality + "/Subject.osm", subject); File.Delete(Municipality + "/Conflated.osc"); Console.WriteLine("ChangeId high watermark: " + subject.GetHighestChangeSetId()); } else if (Is(userInput, "conflate")) { DoConflate(); } else if (Is(userInput, "review con")) { Conflate.Review(Municipality); } else if (Is(userInput, "review")) { OpenJosm(); } else if (Is(userInput, "list")) { var key = userInput.Split(" ")[1]; var reference = GetReference(); var values = reference.GetElements().Where(e => e.Tags.ContainsKey(key)).Select(e => "\n\t" + e.Tags[key]).GroupBy(n => n).ToArray(); Console.WriteLine(string.Concat(values.Select(v => v.Key + "\tx" + v.Count()))); } else if (Is(userInput, "filter")) { var key = userInput.Split(" ")[1]; var reference = GetReference(); DoFilter(key, reference.GetElements()); File.Delete(Municipality + "/Reference.osm"); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "note")) { Static.Municipalities[Municipality].Notes += "/n" + userInput.Split(' ', 2)[1]; FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); } else if (Is(userInput, "WhiteAll")) { var review = FileSerializer.ReadXml <Osm>(Municipality + "/Conflated.Review.osm"); var selection = review.GetElements() .Where(e => e.Tags != null && e.Tags.ContainsKey(Static.maineE911id)) .Select(e => e.Tags[Static.maineE911id]) .SelectMany(id => id.Split(new char[] { ' ', ',', ';', '-' }, StringSplitOptions.RemoveEmptyEntries)) .Select(long.Parse) .Except(Static.Municipalities[Municipality].WhiteList) .ToArray(); Static.Municipalities[Municipality].WhiteList.AddRange(selection); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "white")) { var selection = userInput.Split(' ', 2)[1] .Split(new char[] { ' ', ',', ';', '-', '=' }, StringSplitOptions.RemoveEmptyEntries) .Where(c => long.TryParse(c, out _)) .Select(long.Parse) .Except(Static.Municipalities[Municipality].WhiteList) .ToArray(); Static.Municipalities[Municipality].WhiteList.AddRange(selection); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "blacktag")) { var tag = userInput.Split(' ', 2)[1].Replace("maineE911id=", ""); Static.Municipalities[Municipality].BlackTags.Add(tag); Static.Municipalities[Municipality].BlackTags = Static.Municipalities[Municipality].BlackTags.Distinct().ToList(); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); File.Delete(Municipality + "/Reference.osm"); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "black")) { AddToList(userInput.Split(' ', 2)[1], Static.Municipalities[Municipality].BlackList); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); File.Delete(Municipality + "/Reference.osm"); File.Delete(Municipality + "/Conflated.osc"); } else if (Is(userInput, "ignore")) { AddToList(userInput.Split(' ', 2)[1], Static.Municipalities[Municipality].IgnoreList); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); } else if (Is(userInput, "commit")) { var change = FileSerializer.ReadXml <OsmChange>(Municipality + "/Conflated.osc"); var results = Subjects.UploadChange(change, Municipality).Result; Static.Municipalities[Municipality].ChangeSetIds.AddRange(results); Static.Municipalities[Municipality].ImportDate = DateTime.UtcNow; FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); Console.WriteLine("Finished!"); Next(); } else if (Is(userInput, "skip")) { Static.Municipalities[Municipality].Notes += " SKIPPED"; Static.Municipalities[Municipality].ChangeSetIds.Add(-1); FileSerializer.WriteJson("MaineMunicipalities.json", Static.Municipalities); } else if (Is(userInput, "next")) { Next(); } else if (Is(userInput, "switch")) { Municipality = ChooseMunicipality(); ShowProgress(); } else if (Is(userInput, "folder")) { OpenExplorer(); } else if (Is(userInput, "remind")) { var parts = userInput.Split(' ', 3); var id = long.Parse(parts[1].Replace("maineE911id=", "")); var reference = GetReference(); var element = reference.Nodes.First(e => Math.Abs(e.Id.Value) == Math.Abs(id)); var message = parts.Length > 2 ? parts[2] : "The addresses imported on this neighborhood need to be aligned with the correct buildings"; Subjects.CreateNote(element.Latitude.Value, element.Longitude.Value, message).Wait(); } else if (Is(userInput, "help")) { Console.WriteLine("Options:"); Console.WriteLine("\tSwitch"); Console.WriteLine("\tNext"); Console.WriteLine("\tReference"); Console.WriteLine("\tReview Reference"); Console.WriteLine("\tSubject"); Console.WriteLine("\tConflate"); Console.WriteLine("\tReview Conflate"); Console.WriteLine("\tReview"); Console.WriteLine("\tList [key]"); Console.WriteLine("\tFilter [key]"); Console.WriteLine("\t\t[Y/N/AUnit/Descr/Build/Move]"); Console.WriteLine("\tNote [message]"); Console.WriteLine("\tWhitelist [###]<,[###]...>"); Console.WriteLine("\tWhiteAll"); Console.WriteLine("\tBlacklist [###]<,[###]...>"); Console.WriteLine("\tBlackTag [###].[key] || *.[key]=[value]"); Console.WriteLine("\tIgnore [###]<,[###]...>"); Console.WriteLine("\tRemind [ref###] <message>"); Console.WriteLine("\tCommit"); } else { Console.WriteLine("What?"); } Console.WriteLine("Done"); } }