/// <summary> /// Begins image saving to database. /// Created by Brendan Brading, Fred Chappuis, and Phillip Kempton. /// </summary> /// <param name="sender">The event sender</param> /// <param name="e">The event arguments</param> private void OnClick_SaveImage(object sender, RoutedEventArgs e) { ApiHandler.ApiHandler handler = new ApiHandler.ApiHandler(); // Call DB to get the points. List <KeyValuePair <string, PostGisPoint> > points = handler.GetBounds(); PostGisPoint topLeft = new PostGisPoint(); PostGisPoint botRight = new PostGisPoint(); foreach ((string key, PostGisPoint value) in points) { switch (key) { case "top_left": topLeft = value; break; case "bottom_right": botRight = value; break; default: throw new Exception("Too Many Bounds"); } } // Get the width and height of the map in kilometers using the haversine conversion double widthInKm = HaversineConversion.HaversineDistance( topLeft, new PostGisPoint { X = botRight.Longitude, Y = topLeft.Latitude }, HaversineConversion.DistanceUnit.Kilometers); double heightInKm = HaversineConversion.HaversineDistance( topLeft, new PostGisPoint { X = topLeft.Longitude, Y = botRight.Latitude }, HaversineConversion.DistanceUnit.Kilometers); int width = (int)Math.Ceiling(5000 * widthInKm); int height = (int)Math.Ceiling(5000 * heightInKm); // Create a new bitmap with the required size Bitmap bitmap = new Bitmap( width, height, PixelFormat.Format32bppArgb); // Fill the bitmap background with the specified colour using (Graphics bitmapGraphics = Graphics.FromImage(bitmap)) { bitmapGraphics.FillRegion( Brushes.White, new Region(new Rectangle(0, 0, bitmap.Width, bitmap.Height))); } // Load the generated SVG SvgDocument svgDocument = SvgDocument.Open(FileIO.GetOutputDirectory() + @"\output.svg"); // Draw the contents of the SVG onto the bitmap svgDocument.Draw(bitmap); // Save the bitmap as a PNG bitmap.Save(FileIO.GetOutputDirectory() + @"\output.png", ImageFormat.Png); // Push image to API handler.InsertPng( 0.0f, @"\output.png", "osmMap.png", new PostGisPoint { X = (((botRight.Longitude - topLeft.Longitude) / 2) + topLeft.Longitude), Y = (((topLeft.Latitude - botRight.Latitude) / 2) + botRight.Latitude) }, widthInKm, heightInKm); }
/// <summary> /// Generates an SVG image file using the specified data-points, boundaries and options. /// Saves the file to the specified location. /// </summary> /// <param name="outputFile">The location to save the SVG file</param> /// <param name="dataPoints">The list of data-points to include</param> /// <param name="topLeftPoint">The top-left bound of the data</param> /// <param name="bottomRightPoint">The bottom-right bound of the data</param> /// <param name="listener">The callback for the UI</param> public static async void Generate( string outputFile, List <PostGisData> dataPoints, PostGisPoint topLeftPoint, PostGisPoint bottomRightPoint, ISvgGenerator listener) { // Run on background thread await Task.Run(() => { // Normalize bounds to start at (0,0) and move toward positive (bottom-right) values bottomRightPoint.X -= topLeftPoint.X; bottomRightPoint.Y -= topLeftPoint.Y; topLeftPoint.X -= topLeftPoint.X; topLeftPoint.Y -= topLeftPoint.Y; // Initialize stream writer using StreamWriter sw = new StreamWriter(outputFile); // Write the header of the SVG sw.Write("<svg viewBox=\""); sw.Write(topLeftPoint.X + " " + topLeftPoint.Y + " " + bottomRightPoint.X + " " + bottomRightPoint.Y); sw.WriteLine("\" xmlns=\"http://www.w3.org/2000/svg\">"); // Iterate through the polygons which fit the specified options foreach (PostGisData dataPoint in from optionsKey in SvgTabControl.Options.Keys let allowedValues = SvgTabControl.Options[optionsKey] from dataPoint in from dataPoint in dataPoints where dataPoint.Type == PostGisData.DataType.Polygon && dataPoint.Data.ContainsKey(optionsKey) && allowedValues.Contains(dataPoint.Data[optionsKey]) select dataPoint select dataPoint) { // Write the polygon path sw.Write("<path d=\""); sw.Write(dataPoint.Data["way"]); sw.Write("\" fill=\""); sw.Write(dataPoint.GetColour()); sw.WriteLine("\" stroke=\"none\"/>"); } // Iterate through the rest of the data-points which fit the specified options foreach (PostGisData dataPoint in from optionsKey in SvgTabControl.Options.Keys let allowedValues = SvgTabControl.Options[optionsKey] from dataPoint in from dataPoint in dataPoints where dataPoint.Type != PostGisData.DataType.Polygon && dataPoint.Data.ContainsKey(optionsKey) && allowedValues.Contains(dataPoint.Data[optionsKey]) select dataPoint select dataPoint) { // Write the road/line/point path sw.Write("<path d=\""); sw.Write(dataPoint.Data["way"]); sw.Write("\" stroke=\""); sw.Write(dataPoint.GetColour()); sw.WriteLine("\" stroke-width=\"3\" fill=\"none\"/>"); } // Close the SVG tag sw.WriteLine("</svg>"); }).ContinueWith(task => { // Launch the callback listener.OnGenerationFinished(outputFile); }); }