public List <VertexPositionColor> GetTesselationVertices(Color color)
        {
            var fakeSector = new CubeSector(CubeSector.CubeSectorFace.FRONT, 0, 0, 8);
            List <List <ContourVertex> > contours = new List <List <ContourVertex> >();

            foreach (var inner in inners)
            {
                var innerContour = inner.Skip(1).Select(x => Vector2DToContourVertex(x, true)).ToList(); // skip 1 since our loops end in a duplicate
                if (innerContour.Count == 3)
                {
                    // TODO: the tesselator just doesn't like triangles!? seriously??
                    var avg01 = new ContourVertex()
                    {
                        Position = new Vec3()
                        {
                            X = innerContour[0].Position.X / 2 + innerContour[1].Position.X / 2, Y = innerContour[0].Position.Y / 2 + innerContour[1].Position.Y / 2, Z = 0
                        }, Data = innerContour[0].Data
                    };
                    innerContour.Insert(1, avg01);
                }
                contours.Add(innerContour);
            }
            foreach (var outer in outers)
            {
                var outerContours = new List <List <ContourVertex> >()
                {
                    outer.Skip(1).Select(y => Vector2DToContourVertex(y)).ToList()
                };                                                                                                                      // skip 1 since our loops end in a duplicate
                contours.AddRange(outerContours);
            }
            var vertices = OSMPolygonBufferGenerator.Tesselate(contours, color);

            return(vertices);
        }
Example #2
0
        // move some of our files to the Android assets folder
        private static void HelpZenithAndroid()
        {
            LongLat           longLat       = new LongLat(-87.3294527 * Math.PI / 180, 30.4668536 * Math.PI / 180); // Pensacola
            CubeSector        ourRoot       = new CubeSector(CubeSector.CubeSectorFace.LEFT, 0, 0, 0);
            Vector2d          relativeCoord = ourRoot.ProjectToLocalCoordinates(longLat.ToSphereVector());
            HashSet <ISector> sectorsToLoad = new HashSet <ISector>();

            foreach (var r in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                sectorsToLoad.Add(r);
                for (int z = 1; z <= 3; z++)
                {
                    foreach (var child in r.GetChildrenAtLevel(z))
                    {
                        sectorsToLoad.Add(child);
                    }
                }
            }
            for (int z = 4; z <= 8; z++)
            {
                ISector sector = ourRoot.GetSectorAt(relativeCoord.X, relativeCoord.Y, z);
                for (int i = 0; i < 25; i++)
                {
                    sectorsToLoad.Add(new CubeSector(((CubeSector)sector).sectorFace, sector.X + i / 5 - 2, sector.Y + i % 5 - 2, sector.Zoom));
                }
            }
            foreach (var sector in sectorsToLoad)
            {
                MoveSectorImage(sector);
                MoveSectorOSM(sector);
            }
        }
Example #3
0
        public void TestParallelPerformance()
        {
            LongLat        longLat       = new LongLat(-87.3294527 * Math.PI / 180, 30.4668536 * Math.PI / 180);
            CubeSector     root          = new CubeSector(CubeSector.CubeSectorFace.LEFT, 0, 0, 0);
            Vector2d       relativeCoord = root.ProjectToLocalCoordinates(longLat.ToSphereVector());
            List <ISector> sectors       = root.GetSectorAt(relativeCoord.X, relativeCoord.Y, 6).GetChildrenAtLevel(8);
            Stopwatch      sw            = new Stopwatch();

            sw.Start();
            foreach (var sector in sectors)
            {
                ProceduralTileBuffer buffer = new ProceduralTileBuffer(sector);
                buffer.LoadLinesFromFile();
                buffer.GenerateVertices();
                buffer.Dispose();
            }
            double sequentialSecs = sw.Elapsed.TotalSeconds; // 5.585 secs

            sw.Restart();
            Parallel.ForEach(sectors, sector =>
            {
                ProceduralTileBuffer buffer = new ProceduralTileBuffer(sector);
                buffer.LoadLinesFromFile();
                buffer.GenerateVertices();
                buffer.Dispose();
            });
            double parallelSecs    = sw.Elapsed.TotalSeconds;       // 5.056 secs
            double speedMultiplier = sequentialSecs / parallelSecs; // 1.105 (seems to vary between 1.7 at highest and 1.1 at lowest, not the best multiplier but could still be worthwhile)
        }
Example #4
0
 private static void LoadAll()
 {
     GLOBAL_FINAL = new OSMMetaFinal();
     // init
     GLOBAL_FINAL.gridPoints = new Dictionary <ISector, GridPointInfo[, ]>();
     foreach (var root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
     {
         GridPointInfo[,] gp = new GridPointInfo[257, 257];
         for (int x = 0; x < 257; x++)
         {
             for (int y = 0; y < 257; y++)
             {
                 gp[x, y] = new GridPointInfo();
             }
         }
         GLOBAL_FINAL.gridPoints[root] = gp;
     }
     for (int r = 0; r < 6; r++)
     {
         var    frRoot   = new CubeSector((CubeSector.CubeSectorFace)r, 0, 0, 0);
         string filePath = Path.Combine(OSMPaths.GetRenderRoot(), $"Coastline{frRoot.sectorFace.GetFaceAcronym()}.txt");
         using (var writer = File.Open(filePath, FileMode.Open))
         {
             using (var br = new BinaryReader(writer))
             {
                 int badRelationsCount = br.ReadInt32();
                 for (int i = 0; i < badRelationsCount; i++)
                 {
                     GLOBAL_FINAL.badRelations.Add(br.ReadInt64());
                 }
                 for (int i = 0; i < 257; i++)
                 {
                     for (int j = 0; j < 257; j++)
                     {
                         GridPointInfo gridPoint         = GLOBAL_FINAL.gridPoints[frRoot][i, j];
                         int           naturalTypesCount = br.ReadInt32();
                         for (int k = 0; k < naturalTypesCount; k++)
                         {
                             gridPoint.naturalTypes.Add(br.ReadInt32());
                         }
                         int relationsCount = br.ReadInt32();
                         for (int k = 0; k < relationsCount; k++)
                         {
                             gridPoint.relations.Add(br.ReadInt64());
                         }
                         int waysCount = br.ReadInt32();
                         for (int k = 0; k < waysCount; k++)
                         {
                             gridPoint.ways.Add(br.ReadInt64());
                         }
                     }
                 }
             }
         }
     }
 }
Example #5
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);
                            }
                        }
                    }
                }
            }
        }
Example #6
0
        private void DoCubeFaceTest(CubeSectorFace face, LongLat longLat, bool doXNotY, double expectedAnswer)
        {
            var      front  = new CubeSector(face, 0, 0, 0);
            Vector3d normal = front.sectorFace.GetFaceNormal();
            Vector3d down   = front.sectorFace.GetFaceDownDirection();
            Vector3d right  = front.sectorFace.GetFaceRightDirection();

            if (doXNotY)
            {
                ZAssert.AssertIsClose(front.GetRel(normal, right, longLat.ToSphereVector()), expectedAnswer);
            }
            else
            {
                ZAssert.AssertIsClose(front.GetRel(normal, down, longLat.ToSphereVector()), expectedAnswer);
            }
        }
Example #7
0
        public void TestSectorLoadPerformance()
        {
            LongLat    longLat       = new LongLat(-87.3294527 * Math.PI / 180, 30.4668536 * Math.PI / 180);
            CubeSector root          = new CubeSector(CubeSector.CubeSectorFace.LEFT, 0, 0, 0);
            Vector2d   relativeCoord = root.ProjectToLocalCoordinates(longLat.ToSphereVector());
            ISector    sector        = root.GetSectorAt(relativeCoord.X, relativeCoord.Y, 8);
            Stopwatch  sw            = new Stopwatch();

            sw.Start();
            ProceduralTileBuffer buffer = new ProceduralTileBuffer(sector);

            buffer.LoadLinesFromFile();
            double loadTimeSecs = sw.Elapsed.TotalSeconds; // 0.842 secs (1.781 tablet)

            sw.Restart();
            buffer.GenerateVertices();
            double vertSecs = sw.Elapsed.TotalSeconds; // 0.404 secs (0.773 tablet)
        }
Example #8
0
        // took 21.117584 hours to save 4.19 GB
        // saved to 6 different files in case it crashes
        public void LoadAllDetailsFromSource()
        {
            int i = 0;

            foreach (CubeSector root in ZCoords.GetSectorManager().GetTopmostOSMSectors())
            {
                for (int x = 0; x < 256; x++)
                {
                    for (int y = 0; y < 256; y++)
                    {
                        var sector = new CubeSector(root.sectorFace, x, y, 8);
                        LoadDetailsFromSource(sector);
                    }
                }
                SaveAll("planet-meta" + i + ".data");
                Clear();
                i++;
            }
        }
Example #9
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);
        }
Example #10
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);
        }