/// <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);
        }
Exemplo n.º 2
0
        /// <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);
            });
        }