예제 #1
0
 // "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));
        }
예제 #3
0
        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;
                }
            }
        }
예제 #4
0
 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);
 }