// "temporarily" copy the logic to get all of our ways private static List<Way> TempGetWays(BlobCollection blobs) { Dictionary<long, Way> wayLookup = new Dictionary<long, Way>(); foreach (var way in blobs.EnumerateWays(false)) wayLookup[way.id] = way; HashSet<long> ways = new HashSet<long>(); HashSet<long> innersOuters = new HashSet<long>(); HashSet<long> otherInnerOuters = new HashSet<long>(); foreach (var way in TempGetRelationWays("natural", "water", blobs)) { ways.Add(way); innersOuters.Add(way); } foreach (var way in TempGetRelationWays("building", "yes", blobs)) { ways.Add(way); innersOuters.Add(way); } foreach (var way in TempGetRelationWays(blobs)) { if (!innersOuters.Contains(way)) otherInnerOuters.Add(way); } foreach (var way in TempGetWays("natural", "coastline", blobs)) ways.Add(way); foreach (var way in TempGetWays("natural", "water", blobs)) { if (!innersOuters.Contains(way) && wayLookup[way].refs.Count > 2) { // some folks forget to close a simple way, or perhaps the mistake is tagging subcomponents of a relation // then there's just straight up errors like way 43291726 if (wayLookup[way].refs.Last() != wayLookup[way].refs.First()) { if (otherInnerOuters.Contains(way)) continue; // unsure of how else to ignore bad ways like 43815149 wayLookup[way].refs.Add(wayLookup[way].refs.First()); } } ways.Add(way); } foreach (var way in TempGetWays("building", "yes", blobs)) { if (!innersOuters.Contains(way) && wayLookup[way].refs.Count > 2) { // some folks forget to close a simple way, or perhaps the mistake is tagging subcomponents of a relation // then there's just straight up errors like way 43291726 if (wayLookup[way].refs.Last() != wayLookup[way].refs.First()) { if (otherInnerOuters.Contains(way)) continue; // unsure of how else to ignore bad ways like 43815149 wayLookup[way].refs.Add(wayLookup[way].refs.First()); } } ways.Add(way); } return ways.Where(x => wayLookup.ContainsKey(x)).Select(x => wayLookup[x]).ToList(); }
// generates a zero-width quad for each line in the blob collection, with texture and color // arrow texture will point in the direction the nodes are given in internal static BasicVertexBuffer GenerateDebugLines(GraphicsDevice graphicsDevice, BlobCollection blobs) { List <int> indices = new List <int>(); List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); foreach (Way way in blobs.EnumerateWays()) { long?prev = null; foreach (var nodeRef in way.refs) { long?v = blobs.nodes.ContainsKey(nodeRef) ? nodeRef : (long?)null; if (prev != null && v != null) { Vector2d pos1 = blobs.nodes[prev.Value]; Vector2d pos2 = blobs.nodes[v.Value]; float length = (float)(pos2 - pos1).Length(); // unfortunately calculating the normal from the next/prev vertex in the vertexshader has issues, due to WVP inaccuracies of offscreen vertices Vector2d normalRight = (pos2 - pos1).RotateCW90().Normalized(); Vector2d normalLeft = (pos2 - pos1).RotateCCW90().Normalized(); // the top of the image will be at the end of the path var topLeft = new VertexPositionNormalTexture(new Vector3(pos2, 0), new Vector3(normalLeft, 0), new Vector2(0, 0)); var topRight = new VertexPositionNormalTexture(new Vector3(pos2, 0), new Vector3(normalRight, 0), new Vector2(1, 0)); var bottomLeft = new VertexPositionNormalTexture(new Vector3(pos1, 0), new Vector3(normalLeft, 0), new Vector2(0, length)); var bottomRight = new VertexPositionNormalTexture(new Vector3(pos1, 0), new Vector3(normalRight, 0), new Vector2(1, length)); vertices.Add(topLeft); vertices.Add(topRight); vertices.Add(bottomLeft); vertices.Add(bottomRight); // TODO: undo the bad flipping when we're ready int i = vertices.Count - 4; indices.Add(i); indices.Add(i + 3); indices.Add(i + 1); indices.Add(i); indices.Add(i + 2); indices.Add(i + 3); } prev = v; } } return(new BasicVertexBuffer(graphicsDevice, indices, vertices, GlobalContent.CCWArrows, true, PrimitiveType.TriangleList)); }
private void LoadDetailsFromSource(ISector sector) { BlobCollection blobs = OSMReader.GetAllBlobs(sector); foreach (var way in blobs.EnumerateWays(false)) { for (int i = 0; i < way.refs.Count; i++) { long ref1 = way.refs[i]; long ref2 = way.refs[(i + 1) % way.refs.Count]; if (ref1 == ref2) { continue; } Vector2d v1 = blobs.nodes[ref1]; Vector2d v2 = blobs.nodes[ref2]; LongLat longLat1 = new SphereVector(sector.ProjectToSphereCoordinates(v1)).ToLongLat(); LongLat longLat2 = new SphereVector(sector.ProjectToSphereCoordinates(v2)).ToLongLat(); // hmm, this logic will ignore edges that brush up exactly against the top or left of their sector (ex: nodes 6151473219, 6151473220 in way 146849673) // I have to compensate for this elswhere ISector sector1 = GetContainingSector(longLat1, 8); ISector sector2 = GetContainingSector(longLat2, 8); if (!sector1.Equals(sector2)) { var e = new EdgeInfo() { wayID = way.id, node1 = ref1, node2 = ref2, longLat1 = longLat1, longLat2 = longLat2 }; if (!edgeInfo.Contains(e)) { edgeInfo.Add(e); } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last(), relations = new List <long>() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } } } HashSet <long> extraWays = new HashSet <long>(); foreach (var relation in blobs.EnumerateRelations()) { foreach (var way in relation.memids) { extraWays.Add(way); if (wayInfo.ContainsKey(way) && !relationInfo.ContainsKey(relation.id)) { List <int> rKeys = new List <int>(); List <int> rVals = new List <int>(); List <int> rRoles = new List <int>(); foreach (var pair in relation.keyValues) { rKeys.Add(LoadIntoStringTable(pair.Key)); rVals.Add(LoadIntoStringTable(pair.Value)); } foreach (var role in relation.roleValues) { rRoles.Add(LoadIntoStringTable(role)); } var r = new RelationInfo() { id = relation.id, keys = rKeys, values = rVals, roleValues = rRoles, memids = relation.memids, types = relation.types }; relationInfo[r.id] = r; } } } foreach (var way in blobs.EnumerateWays(false)) { if (!extraWays.Contains(way.id)) { continue; } List <int> wKeys = new List <int>(); List <int> wVals = new List <int>(); foreach (var pair in way.keyValues) { wKeys.Add(LoadIntoStringTable(pair.Key)); wVals.Add(LoadIntoStringTable(pair.Value)); } var w = new WayInfo() { id = way.id, keys = wKeys, values = wVals, startNode = way.refs.First(), endNode = way.refs.Last() }; if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } }
private static IEnumerable<long> TempGetWays(string key, string value, BlobCollection blobs) { return blobs.EnumerateWays(false).Where(x => x.keyValues.ContainsKey(key) && x.keyValues[key] == value).Select(x => x.id); }