Exemplo n.º 1
0
        public bool ReadRelationDirect(long relationID, out OsmRelation osmRelation, out OsmWay[] osmWays, out OsmNode[] osmNodes)
        {
            var rels = pbfReader.ReadRelations(relationID);

            if (rels.Length == 0)
            {
                osmRelation = default(OsmRelation);
                osmWays     = new OsmWay[0];
                osmNodes    = new OsmNode[0];
                return(false);
            }

            osmRelation = rels.First();

            osmWays = pbfReader.ReadWays(osmRelation.members.Where(x => x.type == MemberType.Way).Select(x => x.id).ToArray());
            Array.Sort(osmWays, (x, y) => x.id.CompareTo(y.id));
            int wayCount = 1;

            for (int i = 1; i < osmWays.Length; i++)
            {
                if (osmWays[i - 1].id == osmWays[i].id)
                {
                    continue;
                }
                osmWays[wayCount++] = osmWays[i];
            }
            Array.Resize(ref osmWays, wayCount);

            osmNodes = pbfReader.ReadNodes(osmWays.SelectMany(x => x.nodeIds).Concat(osmRelation.members.Where(x => x.type == MemberType.Node).Select(x => x.id)).ToArray());
            Array.Sort(osmNodes, (x, y) => x.id.CompareTo(y.id));
            int nodeCount = 1;

            for (int i = 1; i < osmNodes.Length; i++)
            {
                if (osmNodes[i - 1].id == osmNodes[i].id)
                {
                    continue;
                }
                osmNodes[nodeCount++] = osmNodes[i];
            }
            Array.Resize(ref osmNodes, nodeCount);

            return(true);
        }
Exemplo n.º 2
0
        static void ParseTest()
        {
            using (var pbf = new OsmPbfReader(PbfPath))
            {
                //long testRelationID = 418713; // Herrnhut (Germany)
                //long testRelationID = 62422; // Berlin
                //long testRelationID = 62504; // Brandenburg (Germany) - https://www.openstreetmap.org/relation/62504
                //long testRelationID = 1434381; // Insel Rügen (Germany)
                long testRelationID = 51477; // Germany
                //long testRelationID = 2214684; // La Gomera (Canarias)
                //long testRelationID = 2182003; // Menorca (Balearic Islands)
                //long testRelationID = 11775386; // La Palma (Canarias)

                var relations = pbf.ReadRelations(testRelationID);
                //var relations = pbf.ReadRelations(418713, 62422, 62504, 1434381, 51477, 2214684, 2182003, 11775386);
                for (; ;) // untergeordnete Relationen einlesen
                {
                    var needRelations = new List <long>();
                    foreach (var r in relations)
                    {
                        foreach (var sub in r.members.Where(x => x.type == MemberType.Relation))
                        {
                            if (relations.Any(x => x.id == sub.id))
                            {
                                continue;
                            }
                            needRelations.Add(sub.id);
                        }
                    }
                    if (needRelations.Count == 0)
                    {
                        break;
                    }
                    relations = relations.Concat(pbf.ReadRelations(needRelations.ToArray())).ToArray(relations.Length + needRelations.Count);
                    break;
                }

                var ways = pbf.ReadWays(relations.SelectMany(r => r.members.Where(x => x.type == MemberType.Way).Select(x => x.id)).ToArray());
                Array.Sort(ways, (x, y) => x.id.CompareTo(y.id));

                var nodes = pbf.ReadNodes(relations.SelectMany(r => r.members.Where(x => x.type == MemberType.Node).Select(x => x.id)).Concat(ways.SelectMany(w => w.nodeIds)).ToArray());
                Array.Sort(nodes, (x, y) => x.id.CompareTo(y.id));

                Console.WriteLine("nodes: {0:N0}", nodes.Length);

                var knownNodes = new HashSet <long>();
                Func <StreamWriter, long, string, int> writePath = null;
                writePath = (wdat, relationId, type) =>
                {
                    int count = 0;
                    var rel   = relations.FirstOrDefault(x => x.id == relationId);
                    if (rel.id == 0)
                    {
                        return(0);
                    }
                    foreach (var member in rel.members)
                    {
                        switch (member.type)
                        {
                        case MemberType.Node: break; // skip

                        case MemberType.Way:
                        {
                            if (member.role == type)
                            {
                                var way = ways.BinarySearchSingle(w => w.id - member.id);
                                foreach (var nodeId in way.nodeIds)
                                {
                                    if (knownNodes.Contains(nodeId))
                                    {
                                        continue;
                                    }
                                    knownNodes.Add(nodeId);
                                    var node = nodes.BinarySearchSingle(n => n.id - nodeId);
                                    wdat.WriteLine(node.latCode + "," + node.lonCode);
                                    count++;
                                }
                            }
                        } break;

                        case MemberType.Relation: count += writePath(wdat, member.id, type); break;
                        }
                    }
                    return(count);
                };

                using (var wdat = new StreamWriter(testRelationID + "_outer.txt"))
                {
                    writePath(wdat, testRelationID, "outer");
                }
                using (var wdat = new StreamWriter(testRelationID + "_inner.txt"))
                {
                    writePath(wdat, testRelationID, "inner");
                }
            }
        }
Exemplo n.º 3
0
        static void MappingTest()
        {
            //long[] relIds = { 3920249L };
            //long[] relIds = { 3459013L };
            long[] relIds = { 62504L }; // Brandenburg
            //long[] relIds = { 51477L }; // Deutschland

            using (var pbf = new OsmPbfReader(PbfPath))
            {
                foreach (long relId in relIds)
                {
                    OsmNode[] nodesPath;

                    if (File.Exists("path_cache_" + relId + ".dat"))
                    {
                        byte[] buf = File.ReadAllBytes("path_cache_" + relId + ".dat");
                        int    len = ReadNodesPath(buf, 0, out nodesPath);
                        if (len != buf.Length)
                        {
                            throw new IOException();
                        }
                    }
                    else
                    {
                        var rels  = pbf.ReadRelations(relIds);
                        var ways  = pbf.ReadWays(rels.First().members.Where(x => x.type == MemberType.Way).Select(x => x.id).ToArray());
                        var nodes = pbf.ReadNodes(ways.SelectMany(x => x.nodeIds).ToArray());
                        nodesPath = GetPath(ways, nodes).ToArray();

                        byte[] buf = new byte[1048576 * 256];
                        int    len = WriteNodesPath(buf, 0, nodesPath);
                        Array.Resize(ref buf, len);

                        File.WriteAllBytes("path_cache_" + relId + ".dat", buf);
                    }

                    var polyLines = new List <GpsLine>();
                    for (int i = 1; i < nodesPath.Length; i++)
                    {
                        if (nodesPath[i - 1].latCode >= nodesPath[i].latCode)
                        {
                            polyLines.Add(new GpsLine(new GpsPos(nodesPath[i - 1]), new GpsPos(nodesPath[i])));
                        }
                        else
                        {
                            polyLines.Add(new GpsLine(new GpsPos(nodesPath[i]), new GpsPos(nodesPath[i - 1])));
                        }
                    }
                    polyLines.Sort((x, y) => x.pos1.posY.CompareTo(y.pos1.posY));

                    // --- init ---
                    int maxLinesPerStripe = (int)(Math.Sqrt(nodesPath.Length) * 0.3) + 1;
                    maxLinesPerStripe = 0;

                    int limitStripes = polyLines.GroupBy(line => line.pos1.posY).Max(g => g.Count());

                    if (maxLinesPerStripe < limitStripes)
                    {
                        maxLinesPerStripe = limitStripes;
                    }

                    var firstLines = new List <GpsLine>();
                    foreach (var line in polyLines)
                    {
                        if (firstLines.Count >= maxLinesPerStripe && firstLines.Last().pos1.posY < line.pos1.posY)
                        {
                            break;
                        }
                        firstLines.Add(line);
                    }

                    var stripes = new List <Tuple <uint, uint, List <GpsLine> > >
                    {
                        new Tuple <uint, uint, List <GpsLine> >(firstLines.First().pos1.posY, firstLines.Last().pos1.posY, firstLines)
                    };

                    for (; ;)
                    {
                        uint startY    = stripes.Last().Item2;
                        var  nextLines = polyLines.Where(line => line.pos1.posY < startY && line.pos2.posY >= startY).ToList();
                        int  maxCount  = nextLines.Count + maxLinesPerStripe;

                        foreach (var line in polyLines)
                        {
                            if (line.pos1.posY >= startY)
                            {
                                if (nextLines.Count > maxCount && nextLines.Last().pos1.posY < line.pos1.posY)
                                {
                                    break;
                                }
                                nextLines.Add(line);
                            }
                        }

                        stripes.Add(new Tuple <uint, uint, List <GpsLine> >(nextLines.First().pos1.posY, nextLines.Last().pos1.posY, nextLines));
                        if (Equals(nextLines.Last(), polyLines.Last()))
                        {
                            break;
                        }
                    }

                    int sumStripes1 = stripes.Sum(s => s.Item3.Count);

                    stripes.Add(new Tuple <uint, uint, List <GpsLine> >(stripes.Last().Item2 + 1, stripes.Last().Item2, new List <GpsLine>()));
                    var fastStripes = stripes.Select((x, i) => new GpsStripe(i == 0 ? x.Item1 : stripes[i - 1].Item2, x.Item2, x.Item3.ToArray())).ToArray();

                    DrawTest(nodesPath, polyLines, fastStripes);
                }
            }
        }