internal static Mapper RenderMap(BoundingBox boundingBox, int widthPx, int heightPx) { var zoomLevel = LocationUtils.GetZoomLevel(boundingBox, widthPx, heightPx); Console.WriteLine("Desired zoomlevel: {0}", zoomLevel); var midX = LocationUtils.GetX(zoomLevel, boundingBox.MiddleLongitude); var midY = LocationUtils.GetY(zoomLevel, boundingBox.MiddleLatitude); var unitsPerPixel = LocationUtils.GetUnitsPerPixel(zoomLevel); var noOfTilesPerWidth = (widthPx - 1) / TileWidthHeight + 2; // + 1 for rounding error, +2 because the tile may lie outside of the screen, we need at least 1 full tile on each side. var noOfTilesPerHeight = (heightPx - 1) / TileWidthHeight + 2; var mapper = new Mapper(widthPx, heightPx, new BoundingBox( boundingBox.MiddleLatitude - unitsPerPixel * heightPx / 2, boundingBox.MiddleLongitude - unitsPerPixel * widthPx / 2, boundingBox.MiddleLatitude + unitsPerPixel * heightPx / 2, boundingBox.MiddleLongitude + unitsPerPixel * widthPx / 2 ), new TilerConfig()); for (int y = midY - noOfTilesPerHeight / 2; y <= midY + noOfTilesPerHeight / 2; y++) { for (int x = midX - noOfTilesPerWidth / 2; x <= midX + noOfTilesPerWidth / 2; x++) { // or too far right. TODO if (y < 0 || x < 0 || x >= Math.Pow(2, zoomLevel) || y >= Math.Pow(2, zoomLevel)) { Console.WriteLine(Fetcher.BlackTile); } else { Console.WriteLine(GoogleMapsUrl, x, y, zoomLevel); using (Bitmap b = fetcher.Fetch(string.Format(CultureInfo.InvariantCulture, GoogleMapsUrl, x, y, zoomLevel))) { mapper.DrawTile(LocationUtils.GetBoundingBox(x, y, zoomLevel), b); } } } } return(mapper); }
private static void CreateMapFromPoints(List <Position> points, Settings settings) { points = points.Select(LocationUtils.ToMercator).ToList(); var boundingBox = LocationUtils.GetBoundingBox(points); var mapper = Tiler.RenderMap(boundingBox, settings.VideoConfig.Width, settings.VideoConfig.Height); points = mapper.GetPixels(points).ToList(); points = points.SkipTooClose(8).ToList(); points = points.SmoothLineChaikin(settings.SofteningSettings); mapper.Save(Path.Combine(settings.OutputDirectory, "empty-map.png")); var writer = new AviWriter(Path.Combine(settings.OutputDirectory, "map.avi")) { FramesPerSecond = settings.VideoConfig.Framerate, EmitIndex1 = true }; IAviVideoStream stream = new NullVideoStream(settings.VideoConfig.Width, settings.VideoConfig.Height); if (settings.VideoConfig.ProduceVideo) { var encoder = new MotionJpegVideoEncoderWpf(settings.VideoConfig.Width, settings.VideoConfig.Height, 70); stream = writer.AddEncodingVideoStream(encoder, true, settings.VideoConfig.Width, settings.VideoConfig.Height); stream.Width = settings.VideoConfig.Width; stream.Height = settings.VideoConfig.Height; } double lengthSeconds = settings.VideoConfig.VideoDuration.TotalSeconds; double totalDistanceMeters = 0; double yieldFrame = Math.Max(1, (points.Count / (lengthSeconds * settings.VideoConfig.Framerate))); double nextFrame = 1; int wroteFrames = 0; for (int i = 1; i < points.Count; i++) { var previousPoint = mapper.FromPixelsToMercator(points[i - 1]); var currentPoint = mapper.FromPixelsToMercator(points[i]); totalDistanceMeters += previousPoint.DistanceMeters(currentPoint); if (mapper.IsStashed) { mapper.StashPop(); } mapper.DrawLine(points[i - 1], points[i]); if (settings.DisplayDistance || settings.DisplayDateTime) { mapper.Stash(); } if (settings.DisplayDistance) { mapper.WriteText(string.Format("{0:0}km", totalDistanceMeters / 1000)); } if (settings.DisplayDateTime) { // mapper.WriteText(points[i].Time.ToString(), settings.VideoConfig.Height - 200); Position positionWgs84 = currentPoint.GetWgs84(); var ianaTz = TimeZoneLookup.GetTimeZone(positionWgs84.Latitude, positionWgs84.Longitude).Result; TimeSpan offset = TimeZoneConverter.TZConvert.GetTimeZoneInfo(ianaTz).GetUtcOffset(points[i].Time); mapper.WriteText(points[i].Time.ToUniversalTime().Add(offset).ToString("MM/dd hh tt"), settings.VideoConfig.Height - 100); } if (i >= nextFrame) { byte[] frameData = mapper.GetBitmap(); stream.WriteFrame(true, frameData, 0, frameData.Length); wroteFrames++; nextFrame += yieldFrame; } } if (mapper.IsStashed) { mapper.StashPop(); } byte[] lastFrameData = mapper.GetBitmap(); stream.WriteFrame(true, lastFrameData, 0, lastFrameData.Length); writer.Close(); // DrawBoundingBox(boundingBox, mapper); string path = Path.Combine(settings.OutputDirectory, "complete-map.png"); mapper.Save(path); Console.WriteLine("Wrote frames: {0}, points.Count={1}, yieldFrame={2}, path={3}", wroteFrames, points.Count, yieldFrame, path); }