// make a lo-rez map showing where there's coast so we can flood-fill it later with land/water public static void SaveCoastLineMap(GraphicsDevice graphicsDevice) { var manager = ZCoords.GetSectorManager(); int imageSize = 1 << manager.GetHighestOSMZoom(); foreach (var sector in manager.GetTopmostOSMSectors()) { RenderTarget2D newTarget = new RenderTarget2D(graphicsDevice, imageSize, imageSize, false, graphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24); graphicsDevice.SetRenderTarget(newTarget); List <ISector> sectorsToCheck = new List <ISector>(); sectorsToCheck.AddRange(sector.GetChildrenAtLevel(ZCoords.GetSectorManager().GetHighestOSMZoom())); foreach (var s in sectorsToCheck) { if (File.Exists(OSMPaths.GetSectorPath(s))) { GraphicsBasic.DrawScreenRect(graphicsDevice, s.X, s.Y, 1, 1, ContainsCoast(s) ? Microsoft.Xna.Framework.Color.Gray : Microsoft.Xna.Framework.Color.White); } else { GraphicsBasic.DrawScreenRect(graphicsDevice, s.X, s.Y, 1, 1, Microsoft.Xna.Framework.Color.Red); } } string mapFile = OSMPaths.GetCoastlineImagePath(sector); using (var writer = File.OpenWrite(mapFile)) { newTarget.SaveAsPng(writer, imageSize, imageSize); } } }
private static void BreakupStepDone() { CURRENT_BREAKUP_STEP++; if (READ_BREAKUP_STEP <= CURRENT_BREAKUP_STEP) { File.WriteAllText(OSMPaths.GetPlanetStepPath(), CURRENT_BREAKUP_STEP + ", " + (CURRENT_BREAKUP_STEP / 131071.0 * 100) + "%"); } }
private static void MoveSectorImage(ISector sector) { string from = OSMPaths.GetSectorImagePath(sector); string to = OSMPaths.GetSectorImagePath(sector, Path.Combine(GetAndroidAssetsRoot(), @"OpenStreetMaps\Renders")); Directory.CreateDirectory(to.Substring(0, to.LastIndexOf('\\'))); if (!File.Exists(to)) { File.Copy(from, to); } }
private void RebuildImage(GraphicsDevice graphicsDevice, ISector sector) { // combination images using (Texture2D rendered = new RenderTarget2D(graphicsDevice, 512, 512, false, graphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24)) { int highestZoom = ZCoords.GetSectorManager().GetHighestCacheZoom(); foreach (var parent in sector.GetAllParents().OrderBy(x => - x.Zoom).Where(x => x.Zoom <= highestZoom)) { List <ISector> roadSectors = parent.GetChildrenAtLevel(parent.Zoom == highestZoom - 1 ? ZCoords.GetSectorManager().GetHighestOSMZoom() : parent.Zoom + 1); Texture2D[] textures = new Texture2D[roadSectors.Count]; for (int i = 0; i < roadSectors.Count; i++) { IGraphicsBuffer buffer = null; if (File.Exists(OSMPaths.GetSectorImagePath(roadSectors[i]))) { using (var reader = File.OpenRead(OSMPaths.GetSectorImagePath(roadSectors[i]))) { buffer = new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), roadSectors[i]); } } else { throw new NotImplementedException(); } textures[i] = buffer.GetImage(graphicsDevice); } if (textures.Any(x => x != null)) { graphicsDevice.SetRenderTarget((RenderTarget2D)rendered); for (int i = 0; i < roadSectors.Count; i++) { int size, x, y; size = 512 >> (roadSectors[i].Zoom - parent.Zoom); x = parent.GetRelativeXOf(roadSectors[i]) * size; y = parent.GetRelativeYOf(roadSectors[i]) * size; if (textures[i] != null) { GraphicsBasic.DrawSpriteRect(graphicsDevice, x, y, size, size, textures[i], BlendState.AlphaBlend, Microsoft.Xna.Framework.Color.White); } } } for (int i = 0; i < textures.Length; i++) { if (textures[i] != null && textures[i] != GlobalContent.Error) { textures[i].Dispose(); } } SuperSave(rendered, OSMPaths.GetSectorImagePath(parent)); } } }
private static bool ContainsCoast(ISector s) { var source = new PBFOsmStreamSource(new FileInfo(OSMPaths.GetSectorPath(s)).OpenRead()); foreach (var element in source) { if (element.Tags.Contains("natural", "coastline")) { return(true); } } return(false); }
// est: since going from 6 to 10 took 1 minute, we might expect doing all 256 would take 256 minutes // if we break it up into quadrants using the same library, maybe it'll only take (4+1+1/16...) roughly 5.33 minutes? // actually took 8.673 mins (went from 450MB to 455MB) // estimated time to segment the whole 43.1 GB planet? 12/28/2018 = 8.673 * 43.1 / 8.05 * 47.7833 = 36.98 hours public static void BreakupFile(string filePath, ISector sector, int targetZoom) { if (sector.Zoom == targetZoom) { return; } List <ISector> quadrants = sector.GetChildrenAtLevel(sector.Zoom + 1); if (READ_BREAKUP_STEP <= CURRENT_BREAKUP_STEP) { foreach (var quadrant in quadrants) { String quadrantPath = OSMPaths.GetSectorPath(quadrant); if (File.Exists(quadrantPath)) { File.Delete(quadrantPath); // we're assuming it's corrupted } if (!Directory.Exists(Path.GetDirectoryName(quadrantPath))) { Directory.CreateDirectory(Path.GetDirectoryName(quadrantPath)); } var fInfo = new FileInfo(filePath); using (var fileInfoStream = fInfo.OpenRead()) { using (var source = new PBFOsmStreamSource(fileInfoStream)) { var filtered = source.FilterNodes(x => x.Longitude.HasValue && x.Latitude.HasValue && quadrant.ContainsLongLat(new LongLat(x.Longitude.Value * Math.PI / 180, x.Latitude.Value * Math.PI / 180)), true); using (var stream = new FileInfo(quadrantPath).Open(FileMode.Create, FileAccess.ReadWrite)) { var target = new PBFOsmStreamTarget(stream, true); target.RegisterSource(filtered); target.Pull(); target.Close(); } } } } if (Path.GetFileName(filePath).ToLower() != Path.GetFileName(OSMPaths.GetPlanetPath()).ToLower()) { File.Delete(filePath); } } BreakupStepDone(); foreach (var quadrant in quadrants) { String quadrantPath = OSMPaths.GetSectorPath(quadrant); BreakupFile(quadrantPath, quadrant, targetZoom); } }
static int READ_BREAKUP_STEP = 0; // easy way to allow continuation, should usually equal (#filesThatArenttoplevel)/3 public static void SegmentOSMPlanet() { READ_BREAKUP_STEP = int.Parse(File.ReadAllText(OSMPaths.GetPlanetStepPath()).Split(',')[0]); // file should contain the number of physical breakups that were finished List <ISector> quadrants = ZCoords.GetSectorManager().GetTopmostOSMSectors(); if (READ_BREAKUP_STEP <= CURRENT_BREAKUP_STEP) { foreach (var quadrant in quadrants) { String quadrantPath = OSMPaths.GetSectorPath(quadrant); if (File.Exists(quadrantPath)) { File.Delete(quadrantPath); // we're assuming it's corrupted } if (!Directory.Exists(Path.GetDirectoryName(quadrantPath))) { Directory.CreateDirectory(Path.GetDirectoryName(quadrantPath)); } var fInfo = new FileInfo(OSMPaths.GetPlanetPath()); using (var fileInfoStream = fInfo.OpenRead()) { using (var source = new PBFOsmStreamSource(fileInfoStream)) { var filtered = source.FilterNodes(x => x.Longitude.HasValue && x.Latitude.HasValue && quadrant.ContainsLongLat(new LongLat(x.Longitude.Value * Math.PI / 180, x.Latitude.Value * Math.PI / 180)), true); using (var stream = new FileInfo(quadrantPath).Open(FileMode.Create, FileAccess.ReadWrite)) { var target = new PBFOsmStreamTarget(stream, true); target.RegisterSource(filtered); target.Pull(); target.Close(); } } } } } BreakupStepDone(); foreach (var quadrant in quadrants) { String quadrantPath = OSMPaths.GetSectorPath(quadrant); BreakupFile(quadrantPath, quadrant, ZCoords.GetSectorManager().GetHighestOSMZoom()); } }
private IGraphicsBuffer GetBuffer(GraphicsDevice graphicsDevice, ISector sector, bool cached) { if (sector.Zoom > ZCoords.GetSectorManager().GetHighestOSMZoom()) { throw new NotImplementedException(); } if (ZCoords.GetSectorManager().GetHighestCacheZoom() > ZCoords.GetSectorManager().GetHighestOSMZoom()) { throw new NotImplementedException(); } try { if ((cached || sector.Zoom != ZCoords.GetSectorManager().GetHighestOSMZoom())) { string path = OSMPaths.GetSectorImagePath(sector); #if WINDOWS || LINUX if (File.Exists(path)) { using (var reader = File.OpenRead(path)) { return(new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), sector)); } } #else using (var reader = Activity1.ASSETS.Open(path)) { return(new ImageTileBuffer(graphicsDevice, Texture2D.FromStream(graphicsDevice, reader), sector)); } #endif } } catch (Exception ex) { // sometimes the image is corrupt (or zero bytes) } // otherwise, build it if (sector.Zoom == ZCoords.GetSectorManager().GetHighestOSMZoom()) { if (cached) { // TODO: somehow all of this still breaks often and is pretty slow, but at least we only have to run it once if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom()) { SuperSave(GlobalContent.Error, OSMPaths.GetSectorImagePath(sector)); //RebuildImage(graphicsDevice, sector); } return(new ImageTileBuffer(graphicsDevice, GlobalContent.Error, sector)); } else { try { ProceduralTileBuffer buffer = new ProceduralTileBuffer(sector); Stopwatch sw = new Stopwatch(); sw.Start(); buffer.LoadLinesFromFile(); buffer.GenerateVertices(); buffer.GenerateBuffers(graphicsDevice); Console.WriteLine($"Total load time for {sector} is {sw.Elapsed.TotalSeconds} s"); if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom()) { #if WINDOWS || LINUX using (var image = buffer.GetImage(graphicsDevice)) { SuperSave(image, OSMPaths.GetSectorImagePath(sector)); } RebuildImage(graphicsDevice, sector); #endif } return(buffer); } catch (Exception ex) { if (sector.Zoom <= ZCoords.GetSectorManager().GetHighestCacheZoom()) { SuperSave(GlobalContent.Error, OSMPaths.GetSectorImagePath(sector)); RebuildImage(graphicsDevice, sector); } return(new ImageTileBuffer(graphicsDevice, GlobalContent.Error, sector)); } } } else { throw new NotImplementedException(); } }