/// <summary> /// Zooms map to current selection. /// </summary> private void ZoomToSelection() { // Get dictionary of bounds from API IDictionary <string, PostGisPoint> bounds = new ApiHandler.ApiHandler().GetBounds().ToDictionary(pair => pair.Key, pair => pair.Value); // Ensure that bounds exist if (!bounds.TryGetValue("top_left", out PostGisPoint topLeft) || !bounds.TryGetValue("bottom_right", out PostGisPoint botRight)) { // TODO : Add some sort of error return; } BoundTopLeft = topLeft; BoundBottomRight = botRight; // Calculate the center point Geopoint centerGeopoint = new Geopoint(new BasicGeoposition { Latitude = ((BoundTopLeft.Latitude - BoundBottomRight.Latitude) / 2) + BoundBottomRight.Latitude, Longitude = ((BoundBottomRight.Longitude - BoundTopLeft.Longitude) / 2) + BoundTopLeft.Longitude }); // Set viewport to bounds MyMapControl.TrySetViewAsync(centerGeopoint, 16); }
/// <summary> /// Saves the point. /// </summary> /// <param name="sender">Event sender</param> /// <param name="e">Event arguments</param> private void OnClick_SavePoint(object sender, RoutedEventArgs e) { // Validate information if (string.IsNullOrEmpty(TextBoxName.Text) || string.IsNullOrEmpty(TextBoxDescription.Text) || TourPointLocation == null) { MessageBox.Show(Application.Current.FindResource("PromptTourPointMustInclude")?.ToString()); return; } // Create point string for PostGIS string point = "POINT(" + TourPointLocation.Position.Longitude + " " + TourPointLocation.Position.Latitude + ")"; // Use API to save the point ApiHandler.ApiHandler handler = new ApiHandler.ApiHandler(); if (!handler.AddPoint(point, TextBoxName.Text, TextBoxDescription.Text, ImagePath)) { // Something went wrong, so go back return; } // Clear the current information UpdateSelectionVisual(); }
/// <summary> /// Adds the user-selected bounds to the database for reference in the future /// Due to requiring custom Select ST_AsText with a transform of 3857 for the /// SVG, we are also going to perform an API call as well to insert the /// bounds in to be used on unity /// </summary> /// <param name="minLon">The minimum longitudinal value</param> /// <param name="maxLon">The maximum longitudinal value</param> /// <param name="minLat">The minimum latitudinal value</param> /// <param name="maxLat">The maximum latitudinal value</param> public void AddBounds(string minLon, string maxLon, string minLat, string maxLat) { // Ensure that the database connection is open if (mConnection.FullState != ConnectionState.Open) { return; } // This SQL does the following: // Deletes the 'bounds' table if it exists in the database. // This is to make sure that the table is completely clear and will follow our specified rules. // Creates the 'bounds' table if it does not exist in the database (which it shouldn't). // This is to make sure that the table is what we need it to be in the database. // Inserts the boundaries as selected by the user. // This is in a specific format. StringBuilder builder = new StringBuilder() .Append("DROP TABLE IF EXISTS bounds;") .Append(Environment.NewLine) .Append("CREATE TABLE IF NOT EXISTS bounds") .Append("(id serial, name varchar UNIQUE, geom geometry(Point, 4326));") .Append("INSERT INTO bounds (name, geom) VALUES") .Append(Environment.NewLine) .Append("('top_left', ST_GeomFromText('POINT(") .Append(minLon) .Append(" ") .Append(maxLat) .Append(")', 4326)),") .Append(Environment.NewLine) .Append("('bottom_right', ST_GeomFromText('POINT(") .Append(maxLon) .Append(" ") .Append(minLat) .Append(")', 4326));"); // Execute the command in the database. new NpgsqlCommand(builder.ToString(), mConnection).ExecuteNonQuery(); // Now we build up our requirements to add the bounds to the API database, the table map_bounds // Contains a map_name, a top left corner point, and a bot right corner point. Due to limitations // on the API, the two points will be strings and not actually GIS points. This is due to the fact // that we could not get geoalchemy2 to work with sqlalchemy on the API, and thus are keeping it as // a string. const string map_name = "osmMap"; string top_left = "POINT(" + minLon + " " + maxLat + ")"; string bottom_right = "POINT(" + maxLon + " " + minLat + ")"; ApiHandler.ApiHandler api = new ApiHandler.ApiHandler(); api.AddBounds(map_name, top_left, bottom_right); }
/// <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); }