예제 #1
0
        // allows us to discard bad relations (bad so far as we can tell, still can't tell if it crosses multiple faces yet)
        private bool IsValidRelation(OSMMetaManager manager, long relation)
        {
            var relationInfo = manager.relationInfo[relation];

            foreach (var way in relationInfo.memids)
            {
                if (!manager.wayInfo.ContainsKey(way))
                {
                    return(true);                                   // benefit of the doubt, for now
                }
            }
            Dictionary <long, int> endCounts = new Dictionary <long, int>();

            foreach (var way in relationInfo.memids)
            {
                if (!endCounts.ContainsKey(manager.wayInfo[way].startNode))
                {
                    endCounts[manager.wayInfo[way].startNode] = 0;
                }
                endCounts[manager.wayInfo[way].startNode]++;
                if (!endCounts.ContainsKey(manager.wayInfo[way].endNode))
                {
                    endCounts[manager.wayInfo[way].endNode] = 0;
                }
                endCounts[manager.wayInfo[way].endNode]++;
            }
            foreach (var pair in endCounts)
            {
                if (pair.Value % 2 == 1)
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #2
0
 internal bool ContainsKeyValue(OSMMetaManager manager, string key, string val)
 {
     for (int i = 0; i < keys.Count; i++)
     {
         if (manager.stringTable[keys[i]].Equals(key) && manager.stringTable[values[i]].Equals(val))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #3
0
        private void SaveAsFile(OSMMetaManager manager, CubeSector root)
        {
            for (int i = 0; i < 257; i++)
            {
                for (int j = 0; j < 257; j++)
                {
                    for (int k = 1; k < naturalTypes.Count; k++)
                    {
                        bool containsThisType = false;
                        containsThisType |= gridPoints[root][i, j].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", naturalTypes[k]));
                        containsThisType |= gridPoints[root][i, j].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", naturalTypes[k]));
                        if (containsThisType)
                        {
                            gridPoints[root][i, j].naturalTypes.Add(k);
                        }
                    }
                }
            }
            string filePath = Path.Combine(OSMPaths.GetRenderRoot(), $"Coastline{root.sectorFace.GetFaceAcronym()}.txt");

            using (var writer = File.Open(filePath, FileMode.Create))
            {
                using (var bw = new BinaryWriter(writer))
                {
                    bw.Write(badRelations.Count);
                    foreach (var relation in badRelations)
                    {
                        bw.Write(relation);
                    }
                    for (int i = 0; i < 257; i++)
                    {
                        for (int j = 0; j < 257; j++)
                        {
                            GridPointInfo gridPoint = gridPoints[root][i, j];
                            bw.Write(gridPoint.naturalTypes.Count);
                            foreach (var naturalType in gridPoint.naturalTypes)
                            {
                                bw.Write(naturalType);
                            }
                            bw.Write(gridPoint.relations.Count);
                            foreach (var relation in gridPoint.relations)
                            {
                                bw.Write(relation);
                            }
                            bw.Write(gridPoint.ways.Count);
                            foreach (var way in gridPoint.ways)
                            {
                                bw.Write(way);
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
 private bool IsWater(OSMMetaManager manager, WayInfo wayInfo)
 {
     if (wayInfo.ContainsKeyValue(manager, "waterway", "river"))
     {
         return(false);                                                        // not area
     }
     if (wayInfo.ContainsKeyValue(manager, "type", "waterway"))
     {
         return(false);                                                       // not area
     }
     return(wayInfo.ContainsKeyValue(manager, "natural", "water"));
 }
예제 #5
0
        private void XORWithEdge(OSMMetaManager manager, GridPointInfo gridPointInfo, EdgeInfo edge)
        {
            var way = manager.wayInfo[edge.wayID];

            if (manager.wayInfo[edge.wayID].ContainsKeyValue(manager, "natural", "coastline"))
            {
                if (edge.node1 == way.endNode && edge.node2 == way.startNode)
                {
                    // for coast, let's reject all simple shape closures (OLD BUG: don't reject straight-line ways)
                }
                else
                {
                    if (gridPointInfo.naturalTypes.Contains(0))
                    {
                        gridPointInfo.naturalTypes.Remove(0);
                    }
                    else
                    {
                        gridPointInfo.naturalTypes.Add(0);
                    }
                }
            }
            bool relationHasWater   = false;
            bool relationHasGlacier = false;

            foreach (var relation in way.relations)
            {
                if (IsWater(manager, manager.relationInfo[relation]))
                {
                    relationHasWater = true;
                }
                if (manager.relationInfo[relation].ContainsKeyValue(manager, "natural", "glacier"))
                {
                    relationHasGlacier = true;
                }
                if (edge.node1 == way.endNode && edge.node2 == way.startNode)
                {
                    // for relations, let's reject all simple shape closures (OLD BUG: don't reject straight-line ways)
                }
                else if (IsWater(manager, manager.relationInfo[relation]) || manager.relationInfo[relation].ContainsKeyValue(manager, "natural", "glacier"))
                {
                    if (badRelations.Contains(relation))
                    {
                        continue;
                    }
                    if (gridPointInfo.relations.Contains(relation))
                    {
                        gridPointInfo.relations.Remove(relation);
                    }
                    else
                    {
                        gridPointInfo.relations.Add(relation);
                    }
                }
            }
            if (!relationHasWater && IsWater(manager, manager.wayInfo[edge.wayID]))
            {
                if (gridPointInfo.ways.Contains(edge.wayID))
                {
                    gridPointInfo.ways.Remove(edge.wayID);
                }
                else
                {
                    gridPointInfo.ways.Add(edge.wayID);
                }
            }
            if (!relationHasGlacier && manager.wayInfo[edge.wayID].ContainsKeyValue(manager, "natural", "glacier"))
            {
                if (gridPointInfo.ways.Contains(edge.wayID))
                {
                    gridPointInfo.ways.Remove(edge.wayID);
                }
                else
                {
                    gridPointInfo.ways.Add(edge.wayID);
                }
            }
        }
예제 #6
0
        internal void LoadAll(string fileName)
        {
            OSMMetaManager manager = new OSMMetaManager();

            if (fileName.Contains("*"))
            {
                for (int i = 0; i < 6; i++)
                {
                    manager.LoadAll(fileName.Replace("*", i + ""));
                }
            }
            else
            {
                manager.LoadAll(fileName);
            }
            // init
            gridPoints = new Dictionary <ISector, GridPointInfo[, ]>();
            gridTops   = new Dictionary <ISector, GridPointInfo[, ]>();
            gridLefts  = new Dictionary <ISector, GridPointInfo[, ]>();
            foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                GridPointInfo[,] gp = new GridPointInfo[257, 257];
                GridPointInfo[,] gt = new GridPointInfo[256, 257];
                GridPointInfo[,] gl = new GridPointInfo[257, 256];
                for (int x = 0; x < 257; x++)
                {
                    for (int y = 0; y < 257; y++)
                    {
                        gp[x, y] = new GridPointInfo();
                        if (x < 256)
                        {
                            gt[x, y] = new GridPointInfo();
                        }
                        if (y < 256)
                        {
                            gl[x, y] = new GridPointInfo();
                        }
                    }
                }
                gridPoints[root] = gp;
                gridTops[root]   = gt;
                gridLefts[root]  = gl;
            }
            // find bad relations
            foreach (var relation in manager.relationInfo)
            {
                if (!IsValidRelation(manager, relation.Key))
                {
                    badRelations.Add(relation.Key);
                }
            }
            // process all edge info
            foreach (var edge in manager.edgeInfo)
            {
                if (!manager.wayInfo.ContainsKey(edge.wayID))
                {
                    continue;                                           // probably doesn't exist because we've removed it to try and save some memory
                }
                foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
                {
                    var local1 = root.ProjectToLocalCoordinates(edge.longLat1.ToSphereVector());
                    var local2 = root.ProjectToLocalCoordinates(edge.longLat2.ToSphereVector());
                    if ((local1 - local2).Length() > 0.2)
                    {
                        continue;
                    }
                    // first, order by X
                    if (local1.X > local2.X)
                    {
                        var temp = local2;
                        local2 = local1;
                        local1 = temp;
                    }
                    for (int x = (int)Math.Ceiling(local1.X * 256); x <= local2.X * 256; x++)
                    {
                        if (x == local1.X * 256)
                        {
                            continue;
                        }
                        double t = (x / 256.0 - local1.X) / (local2.X - local1.X);
                        int    y = (int)Math.Floor((local1.Y + t * (local2.Y - local1.Y)) * 256);
                        if (x >= 0 && x < 257 && y >= 0 && y < 256)
                        {
                            XORWithEdge(manager, gridLefts[root][x, y], edge);
                        }
                    }
                    // now, order by Y
                    if (local1.Y > local2.Y)
                    {
                        var temp = local2;
                        local2 = local1;
                        local1 = temp;
                    }
                    for (int y = (int)Math.Ceiling(local1.Y * 256); y <= local2.Y * 256; y++) // BUG: can't believe this was required, but we do sometimes have nodes on exactly the edge, apparently
                    {
                        // ignore the edge that bruhes up exactly against the top (assuming it exists at all, since our original load logic can exclude such an edge)
                        // with a point exactly on an edge, the -other- edge that matches exactly on bottom should trigger the flag instead (double-flag would be bad)
                        if (y == local1.Y * 256)
                        {
                            continue;
                        }
                        double t = (y / 256.0 - local1.Y) / (local2.Y - local1.Y);
                        int    x = (int)Math.Floor((local1.X + t * (local2.X - local1.X)) * 256); // BUG: (int) is NOT THE SAME AS Math.Floor!
                        if (x >= 0 && x < 256 && y >= 0 && y < 257)
                        {
                            XORWithEdge(manager, gridTops[root][x, y], edge);
                        }
                    }
                }
            }
            // now actually figure out the points
            // TODO: we're just doing front for now
            var frRoot = new CubeSector((CubeSector.CubeSectorFace) int.Parse(Regex.Match(fileName, "[0-9]").Value), 0, 0, 0);

            if (frRoot.sectorFace == CubeSector.CubeSectorFace.RIGHT || frRoot.sectorFace == CubeSector.CubeSectorFace.BACK)
            {
                // invert these faces
                gridPoints[frRoot][0, 0].naturalTypes.Add(0);
            }
            for (int y = 0; y < 257; y++)
            {
                for (int x = 0; x < 257; x++)
                {
                    GridPointInfo prev;
                    GridPointInfo next;
                    GridPointInfo edge;
                    if (x == 0)
                    {
                        if (y == 0)
                        {
                            continue;
                        }
                        prev = gridPoints[frRoot][0, y - 1];
                        next = gridPoints[frRoot][0, y];
                        edge = gridLefts[frRoot][0, y - 1];
                    }
                    else
                    {
                        prev = gridPoints[frRoot][x - 1, y];
                        next = gridPoints[frRoot][x, y];
                        edge = gridTops[frRoot][x - 1, y];
                    }
                    foreach (var n in prev.naturalTypes)
                    {
                        next.naturalTypes.Add(n);
                    }
                    foreach (var n in prev.relations)
                    {
                        next.relations.Add(n);
                    }
                    foreach (var n in prev.ways)
                    {
                        next.ways.Add(n);
                    }
                    foreach (var n in edge.naturalTypes)
                    {
                        if (next.naturalTypes.Contains(n))
                        {
                            next.naturalTypes.Remove(n);
                        }
                        else
                        {
                            next.naturalTypes.Add(n);
                        }
                    }
                    foreach (var n in edge.relations)
                    {
                        if (next.relations.Contains(n))
                        {
                            next.relations.Remove(n);
                        }
                        else
                        {
                            next.relations.Add(n);
                        }
                    }
                    foreach (var n in edge.ways)
                    {
                        if (next.ways.Contains(n))
                        {
                            next.ways.Remove(n);
                        }
                        else
                        {
                            next.ways.Add(n);
                        }
                    }
                }
            }
            SaveAsImage(manager, frRoot);
            SaveAsFile(manager, frRoot);
        }
예제 #7
0
        private void SaveAsImage(OSMMetaManager manager, CubeSector frRoot)
        {
            // finally, render those coast images
            string mapFile = OSMPaths.GetCoastlineImagePath(frRoot);
            Bitmap map     = new Bitmap(256, 256);

            for (int i = 0; i < 256; i++)
            {
                for (int j = 0; j < 256; j++)
                {
                    int land1 = gridPoints[frRoot][i, j].naturalTypes.Contains(0) ? 0 : -1;
                    int land2 = gridPoints[frRoot][i + 1, j].naturalTypes.Contains(0) ? 0 : -1;
                    int land3 = gridPoints[frRoot][i, j + 1].naturalTypes.Contains(0) ? 0 : -1;
                    int land4 = gridPoints[frRoot][i + 1, j + 1].naturalTypes.Contains(0) ? 0 : -1;
                    if (gridPoints[frRoot][i, j].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land1 = 1;
                    }
                    if (gridPoints[frRoot][i, j].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land1 = 1;
                    }
                    if (gridPoints[frRoot][i + 1, j].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land2 = 1;
                    }
                    if (gridPoints[frRoot][i + 1, j].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land2 = 1;
                    }
                    if (gridPoints[frRoot][i, j + 1].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land3 = 1;
                    }
                    if (gridPoints[frRoot][i, j + 1].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land3 = 1;
                    }
                    if (gridPoints[frRoot][i + 1, j + 1].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land4 = 1;
                    }
                    if (gridPoints[frRoot][i + 1, j + 1].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "water")))
                    {
                        land4 = 1;
                    }
                    if (gridPoints[frRoot][i, j].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land1 = 2;
                    }
                    if (gridPoints[frRoot][i, j].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land1 = 2;
                    }
                    if (gridPoints[frRoot][i + 1, j].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land2 = 2;
                    }
                    if (gridPoints[frRoot][i + 1, j].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land2 = 2;
                    }
                    if (gridPoints[frRoot][i, j + 1].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land3 = 2;
                    }
                    if (gridPoints[frRoot][i, j + 1].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land3 = 2;
                    }
                    if (gridPoints[frRoot][i + 1, j + 1].relations.Any(x => manager.relationInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land4 = 2;
                    }
                    if (gridPoints[frRoot][i + 1, j + 1].ways.Any(x => manager.wayInfo[x].ContainsKeyValue(manager, "natural", "glacier")))
                    {
                        land4 = 2;
                    }
                    Color color = Color.FromArgb(128, 128, 128);

                    if (land1 == 2 && land2 == 2 && land3 == 2 && land4 == 2)
                    {
                        color = Color.FromArgb(255, 255, 255);
                    }
                    if (land1 == 1 && land2 == 1 && land3 == 1 && land4 == 1)
                    {
                        color = Color.FromArgb(0, 0, 255);
                    }
                    if (land1 == 0 && land2 == 0 && land3 == 0 && land4 == 0)
                    {
                        color = Color.FromArgb(0, 255, 0);
                    }
                    if (land1 == -1 && land2 == -1 && land3 == -1 && land4 == -1)
                    {
                        color = Color.FromArgb(0, 0, 255);
                    }

                    //color = Color.FromArgb(255, 255, 255);
                    //if (gridTops[frRoot][i, j].relations.Any(x => x == 1279614)) color = Color.FromArgb(0, 255, 0);
                    //if (gridLefts[frRoot][i, j].relations.Any(x => x == 1279614)) color = Color.FromArgb(255, 0, 0);
                    //if (gridLefts[frRoot][i, j].relations.Any(x => x == 1279614) && gridTops[frRoot][i, j].relations.Any(x => x == 1279614)) color = Color.FromArgb(0, 0, 0);

                    map.SetPixel(i, j, color);
                }
            }
            map.Save(mapFile, ImageFormat.Png);
        }