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); }