/// <summary> /// Convert bounding box from one coordinate system to /// another coordinate system. /// Converted bounding box is returned as a polygon /// since it probably is not a rectangle any more. /// </summary> /// <param name="clientInformation">Information about the client that makes this web service call.</param> /// <param name="boundingBox">Bounding boxe that should be converted.</param> /// <param name="fromCoordinateSystem">From coordinate system.</param> /// <param name="toCoordinateSystem">To coordinate system.</param> /// <returns>Converted bounding box.</returns> public WebPolygon GetConvertedBoundingBox( WebClientInformation clientInformation, WebBoundingBox boundingBox, WebCoordinateSystem fromCoordinateSystem, WebCoordinateSystem toCoordinateSystem) { using (WebServiceContext context = GetWebServiceContext(clientInformation)) { try { return(WebServiceData.CoordinateConversionManager.GetConvertedBoundingBox( boundingBox, fromCoordinateSystem, toCoordinateSystem)); } catch (Exception exception) { LogException(clientInformation, context, exception); LogParameter(context, "BoundingBox", boundingBox.WebToString()); LogParameter(context, "FromCoordinateSystem", fromCoordinateSystem.WebToString()); LogParameter(context, "ToCoordinateSystem", toCoordinateSystem.WebToString()); throw; } } }
/// <summary> /// Load data into the WebBoundingBox instance. /// </summary> /// <param name="boundingBox">This boundingbox.</param> /// <param name='dataReader'>An open data reader.</param> /// <param name='columnName'>Name of the column in result set to read data from.</param> public static void LoadData(this WebBoundingBox boundingBox, DataReader dataReader, String columnName) { char[] delimiter; String boundingBoxString; String[] coordinates; // Get coordinates. boundingBoxString = dataReader.GetString(columnName); delimiter = new[] { Settings.Default.CoordinateDelimiter }; coordinates = boundingBoxString.Split(delimiter); if (coordinates.Length != 4) { throw new ApplicationException("Wrong format in bounding box: " + boundingBox); } // Create points. boundingBox.Min = new WebPoint(); boundingBox.Max = new WebPoint(); boundingBox.Min.X = Double.Parse(coordinates[0], NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-GB")); boundingBox.Min.Y = Double.Parse(coordinates[1], NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-GB")); boundingBox.Max.X = Double.Parse(coordinates[2], NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-GB")); boundingBox.Max.Y = Double.Parse(coordinates[3], NumberStyles.AllowDecimalPoint, CultureInfo.CreateSpecificCulture("en-GB")); }
/// <summary> /// Creates the centre coordinate from bounding box. /// </summary> /// <param name="boundingBox">The bounding box.</param> private static WebPoint CreateCentreCoordinateFromBoundingBox(WebBoundingBox boundingBox) { WebPoint point = new WebPoint( boundingBox.Min.X + ((boundingBox.Max.X - boundingBox.Min.X) / 2.0), boundingBox.Min.Y + ((boundingBox.Max.Y - boundingBox.Min.Y) / 2.0)); return(point); }
/// <summary> /// Test if point is located inside bounding box. /// Currently only two dimensions are handled. /// </summary> /// <param name="boundingBox">Bounding box.</param> /// <param name='point'>Point.</param> /// <returns>True if point is located inside bounding box.</returns> public static Boolean IsPointInside(this WebBoundingBox boundingBox, WebPoint point) { return(boundingBox.IsNotNull() && point.IsNotNull() && (boundingBox.Max.X >= point.X) && (boundingBox.Min.X <= point.X) && (boundingBox.Max.Y >= point.Y) && (boundingBox.Min.Y <= point.Y)); }
/// <summary> /// Cast web linearring to linearring /// </summary> /// <param name="webBoundingBox"></param> /// <returns></returns> public static IPolygon ToPolygon(this WebBoundingBox webBoundingBox) { return(new Polygon(new LinearRing(new[] { new Coordinate(webBoundingBox.Min.X, webBoundingBox.Min.Y), new Coordinate(webBoundingBox.Min.X, webBoundingBox.Max.Y), new Coordinate(webBoundingBox.Max.X, webBoundingBox.Max.Y), new Coordinate(webBoundingBox.Max.X, webBoundingBox.Min.Y), new Coordinate(webBoundingBox.Min.X, webBoundingBox.Min.Y) }))); }
/// <summary> /// Gets the sweden extent bounding box in SWEREF99_TM coordinates. /// </summary> /// <returns> /// The sweden extent bounding box in SWEREF99_TM coordinates. /// </returns> public static WebBoundingBox GetSwedenExtentWebBoundingBoxSweref99() { WebBoundingBox boundingBox; boundingBox = new WebBoundingBox(); boundingBox.Max = new WebPoint(); boundingBox.Min = new WebPoint(); boundingBox.Max.X = 969927.0414948005; boundingBox.Max.Y = 7737973.607602615; boundingBox.Min.X = 195816.17626999575; boundingBox.Min.Y = 6029444.002008331; return(boundingBox); }
/// <summary> /// Creates the grid cell bounding polygon from an SQL geometry. /// </summary> /// <param name="gridCell">The grid cell.</param> private static WebBoundingBox CreateGridCellBoundingBoxFromSqlGeometry(SqlGeometry gridCell) { WebBoundingBox gridCellBoundingBox; //Map the gridCell coordinates to the BoundingBox polygon property in the returning object gridCellBoundingBox = new WebBoundingBox(); gridCellBoundingBox.Min = new WebPoint(); gridCellBoundingBox.Max = new WebPoint(); gridCellBoundingBox.Min.X = Convert.ToDouble(gridCell.STStartPoint().STX.Value); gridCellBoundingBox.Min.Y = Convert.ToDouble(gridCell.STStartPoint().STY.Value); gridCellBoundingBox.Max.X = Convert.ToDouble(gridCell.STPointN(3).STX.Value); gridCellBoundingBox.Max.Y = Convert.ToDouble(gridCell.STPointN(3).STY.Value); return(gridCellBoundingBox); }
/// <summary> /// Convert a WebBoundingBox instance into a WebPolygon /// instance with same geographic area. /// </summary> /// <param name="boundingBox">Bounding box.</param> /// <returns>A WebPolygon instance.</returns> public static WebPolygon GetPolygon(this WebBoundingBox boundingBox) { WebLinearRing linearRing; WebPolygon polygon; linearRing = new WebLinearRing(); linearRing.Points = new List <WebPoint>(); linearRing.Points.Add(new WebPoint(boundingBox.Min.X, boundingBox.Min.Y)); linearRing.Points.Add(new WebPoint(boundingBox.Max.X, boundingBox.Min.Y)); linearRing.Points.Add(new WebPoint(boundingBox.Max.X, boundingBox.Max.Y)); linearRing.Points.Add(new WebPoint(boundingBox.Min.X, boundingBox.Max.Y)); linearRing.Points.Add(new WebPoint(boundingBox.Min.X, boundingBox.Min.Y)); polygon = new WebPolygon(); polygon.LinearRings = new List <WebLinearRing>(); polygon.LinearRings.Add(linearRing); return(polygon); }
/// <summary> /// Check that data is valid. /// </summary> /// <param name="boundingBox">Bounding box.</param> public static void CheckData(this WebBoundingBox boundingBox) { if (boundingBox.IsNotNull()) { // Check points. boundingBox.Max.CheckNotNull("Max"); boundingBox.Max.CheckData(); boundingBox.Min.CheckNotNull("Min"); boundingBox.Min.CheckData(); // Check that points are of the same dimension. if (boundingBox.Max.IsMSpecified != boundingBox.Min.IsMSpecified) { throw new ArgumentException("WebBoundingBox: Min and max has different M dimensions"); } if (boundingBox.Max.IsZSpecified != boundingBox.Min.IsZSpecified) { throw new ArgumentException("WebBoundingBox: Min and max has different Z dimensions"); } // Check that all min values are lower than all max values. if (boundingBox.Max.X < boundingBox.Min.X) { throw new ArgumentException("WebBoundingBox: Max.X is smaller than Min.X"); } if (boundingBox.Max.Y < boundingBox.Min.Y) { throw new ArgumentException("WebBoundingBox: Max.Y is smaller than Min.Y"); } if (boundingBox.Max.IsZSpecified && (boundingBox.Max.Z < boundingBox.Min.Z)) { throw new ArgumentException("WebBoundingBox: Max.Z is smaller than Min.Z"); } if (boundingBox.Max.IsMSpecified && (boundingBox.Max.M < boundingBox.Min.M)) { throw new ArgumentException("WebBoundingBox: Max.M is smaller than Min.M"); } } }
/// <summary> /// Add bounding box 2 to bounding box 1. /// The union of bounding box 1 and bounding box 2 /// are stored in bounding box 1. /// </summary> /// <param name="boundingBox1">Bounding box 1.</param> /// <param name="boundingBox2">Bounding box 2.</param> public static void Add(this WebBoundingBox boundingBox1, WebBoundingBox boundingBox2) { if (boundingBox1.Max.IsNull()) { boundingBox1.Max = boundingBox2.Max.Clone(); } else { boundingBox1.Max.X = Math.Max(boundingBox1.Max.X, boundingBox2.Max.X); boundingBox1.Max.Y = Math.Max(boundingBox1.Max.Y, boundingBox2.Max.Y); if (boundingBox1.Max.IsZSpecified != boundingBox2.Max.IsZSpecified) { throw new ArgumentException("Different dimensions in points!"); } boundingBox1.Max.Z = Math.Max(boundingBox1.Max.Z, boundingBox2.Max.Z); if (boundingBox1.Max.IsMSpecified != boundingBox2.Max.IsMSpecified) { throw new ArgumentException("Different dimensions in points!"); } boundingBox1.Max.M = Math.Max(boundingBox1.Max.M, boundingBox2.Max.M); } if (boundingBox1.Min.IsNull()) { boundingBox1.Min = boundingBox2.Min.Clone(); } else { boundingBox1.Min.X = Math.Min(boundingBox1.Min.X, boundingBox2.Min.X); boundingBox1.Min.Y = Math.Min(boundingBox1.Min.Y, boundingBox2.Min.Y); if (boundingBox1.Min.IsZSpecified != boundingBox2.Min.IsZSpecified) { throw new ArgumentException("Different dimensions in points!"); } boundingBox1.Min.Z = Math.Min(boundingBox1.Min.Z, boundingBox2.Min.Z); if (boundingBox1.Min.IsMSpecified != boundingBox2.Min.IsMSpecified) { throw new ArgumentException("Different dimensions in points!"); } boundingBox1.Min.M = Math.Min(boundingBox1.Min.M, boundingBox2.Min.M); } }
/// <summary> /// Gets the bounding box of all geometries in a list of SqlGeometry objects. /// </summary> /// <param name="featureList">The feature list.</param> private static WebBoundingBox GetBoundingBoxFromSqlGeometryList(List <SqlGeometry> featureList) { SqlGeometry feature; if (featureList.IsEmpty()) { return(null); } feature = featureList[0]; feature = feature.STEnvelope(); WebBoundingBox boundingBox = new WebBoundingBox(); boundingBox.Min = new WebPoint(feature.STStartPoint().STX.Value, feature.STStartPoint().STY.Value); boundingBox.Max = new WebPoint(feature.STPointN(3).STX.Value, feature.STPointN(3).STY.Value); for (int i = 1; i < featureList.Count; i++) { feature = featureList[i]; feature = feature.STEnvelope(); if (feature.STStartPoint().STX.Value < boundingBox.Min.X) { boundingBox.Min.X = feature.STStartPoint().STX.Value; } if (feature.STStartPoint().STY.Value < boundingBox.Min.Y) { boundingBox.Min.Y = feature.STStartPoint().STY.Value; } if (feature.STPointN(3).STX.Value > boundingBox.Max.X) { boundingBox.Max.X = feature.STPointN(3).STX.Value; } if (feature.STPointN(3).STY.Value > boundingBox.Max.Y) { boundingBox.Max.Y = feature.STPointN(3).STY.Value; } } return(boundingBox); }
/// <summary> /// Gets the sweden extent bounding box polygon. /// </summary> /// <param name="coordinateSystem">The coordinate system.</param> public static WebPolygon GetSwedenExtentBoundingBoxPolygon(WebCoordinateSystem coordinateSystem) { WebPolygon boundingBox = new WebPolygon(); // Sweden extent in SWEREF99_TM WebBoundingBox swedenBoundingBox = SwedenExtentCoordinates.GetSwedenExtentWebBoundingBoxSweref99(); if (coordinateSystem.IsNotNull() && coordinateSystem.Id.IsNotNull() && (coordinateSystem.Id != CoordinateSystemId.SWEREF99_TM)) { WebCoordinateSystem sweref99CoordinateSystem = new WebCoordinateSystem(); sweref99CoordinateSystem.Id = CoordinateSystemId.SWEREF99_TM; boundingBox = WebServiceData.CoordinateConversionManager.GetConvertedBoundingBox( swedenBoundingBox, sweref99CoordinateSystem, coordinateSystem); } else { boundingBox = swedenBoundingBox.GetPolygon(); } return(boundingBox); }
/// <summary> /// Get bounding box for provided polygon. /// Currently only 2 dimensions are handled. /// </summary> /// <param name="polygon">This polygon.</param> /// <returns>Bounding box for provided polygon.</returns> public static WebBoundingBox GetBoundingBox(this WebPolygon polygon) { WebBoundingBox boundingBox; boundingBox = null; if (polygon.LinearRings.IsNotEmpty() && polygon.LinearRings[0].Points.IsNotEmpty()) { foreach (WebPoint point in polygon.LinearRings[0].Points) { if (boundingBox.IsNull()) { boundingBox = new WebBoundingBox(); boundingBox.Max = point.Clone(); boundingBox.Min = point.Clone(); } else { if (boundingBox.Max.X < point.X) { boundingBox.Max.X = point.X; } if (boundingBox.Max.Y < point.Y) { boundingBox.Max.Y = point.Y; } if (boundingBox.Min.X > point.X) { boundingBox.Min.X = point.X; } if (boundingBox.Min.Y > point.Y) { boundingBox.Min.Y = point.Y; } } } } return(boundingBox); }
/// <summary> /// Check if grid specifications is correct. /// </summary> /// <param name="gridSpecification"> Information on grid specifications.</param> /// <param name="speciesObservationBoundingBox">Bounding box for species observation.</param> public static void CheckGridSpecifications(this WebGridSpecification gridSpecification, WebBoundingBox speciesObservationBoundingBox) { if (gridSpecification.IsNotNull() && gridSpecification.BoundingBox.IsNotNull()) { if (speciesObservationBoundingBox.IsNotNull()) { throw new ArgumentException("WebGridSpecifications: Properties WebGridSpecifications.BoundingBox and WebSpeciesObservatioSearchCriteria.BoundingBox have value set, only one BoundigBox can be set."); } } }
public static List <WebGridCellFeatureStatistics> GetFeaturesBasedOnGridCells(List <SqlGeometry> featureList, WebGridSpecification gridSpecification, int srid) { List <WebGridCellFeatureStatistics> webGridCellFeatureStatisticsList; List <SqlGeometry> gridCellList; List <WebPoint> centrePointList; SqlGeometry newFeature; if (featureList.IsNotNull() && featureList.Count.Equals(0)) { throw new Exception("There are no features in the featureList."); } webGridCellFeatureStatisticsList = new List <WebGridCellFeatureStatistics>(); if (gridSpecification.IsNull()) { return(webGridCellFeatureStatisticsList); } WebBoundingBox gridBoundingBox = gridSpecification.BoundingBox; WebBoundingBox featuresBoundingBox = GetBoundingBoxFromSqlGeometryList(featureList); var mergedBoundingBox = GetFeatureStatisticsMergedBoundingBox(featuresBoundingBox, gridBoundingBox); if (mergedBoundingBox != null) { gridSpecification.BoundingBox = mergedBoundingBox; // change bounding box } gridCellList = CreateSqlGeometryGrid(gridSpecification, srid, out centrePointList); gridSpecification.BoundingBox = gridBoundingBox; // reset bounding box WebCoordinateSystem gridCoordinateSystem = gridSpecification.GridCoordinateSystem.ToWebCoordinateSystem(); int maxGridCellArea = gridSpecification.GridCellSize * gridSpecification.GridCellSize; // Pick one grid cell at a time and step through all the features. // If they overlap, add the grid cell and the data to the resulting list. for (int i = 0; i < gridCellList.Count; i++) { SqlGeometry gridCell = gridCellList[i]; WebGridCellFeatureStatistics webGridCellFeatureStatistics = null; foreach (SqlGeometry feature in featureList) { if (feature == null) { continue; } // * ____ -------- ____ // ____/ | | | __/ | // < ___ | | | =>(intersect) |_ | // |_ _| feature |_______| gridcell |____| // |_| newFeature = feature.STIntersection(gridCell).MakeValid(); //Create a new feature from overlay with the geometry feature and the gridcell if (!(newFeature.STNumGeometries() == 0)) //If there is intersection { if (webGridCellFeatureStatistics == null) { webGridCellFeatureStatistics = new WebGridCellFeatureStatistics(); webGridCellFeatureStatistics.CoordinateSystem = gridCoordinateSystem; webGridCellFeatureStatistics.BoundingBox = CreateGridCellBoundingPolygonFromSqlGeometry(gridCell); webGridCellFeatureStatistics.CentreCoordinate = centrePointList[i]; webGridCellFeatureStatistics.Size = gridSpecification.GridCellSize; webGridCellFeatureStatistics.GridCoordinateSystem = gridSpecification.GridCoordinateSystem; webGridCellFeatureStatistics.OrginalBoundingBox = CreateGridCellBoundingBoxFromSqlGeometry(gridCell); webGridCellFeatureStatistics.OrginalCentreCoordinate = CreateCentreCoordinateFromBoundingBox(webGridCellFeatureStatistics.OrginalBoundingBox); if (feature.GetGeometryType().ToString().Equals("MultiPolygon")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Multipolygon; } if (feature.GetGeometryType().ToString().Equals("Polygon")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Polygon; } if (feature.GetGeometryType().ToString().Equals("MultiLineString")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Multiline; } if (feature.GetGeometryType().ToString().Equals("LineString")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Line; } if (feature.GetGeometryType().ToString().Equals("MultiPoint")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Point; } if (feature.GetGeometryType().ToString().Equals("Point")) { webGridCellFeatureStatistics.FeatureType = FeatureType.Point; } webGridCellFeatureStatisticsList.Add(webGridCellFeatureStatistics); // Create line for lines and Polygones if (feature.GetGeometryType().ToString().Equals("MultiPolygon") || feature.GetGeometryType().ToString().Equals("Polygon") || feature.GetGeometryType().ToString().Equals("MultiLineString") || feature.GetGeometryType().ToString().Equals("LineString")) { // Old incorrect value // webGridCellFeatureStatistics.FeatureLength += newFeature.STLength().Value; // For debug only // double test = newFeature.STLength().Value; // Here we get the length of the newFeaure without intersection length. // First we get boundaries for feature, newFeature and gridcell SqlGeometry featureBoundary = feature.STBoundary(); SqlGeometry newfeatureBoundary = newFeature.STBoundary(); // SqlGeometry gridBoundary = gridCell.STBoundary(); // * ____ ____ // __/ | ___/ | // |_ | <___ | => (difference) | // |____| newfeature |_ _| feature __ // |_| // Get the difference between newfeature and feature ie intersection with the gridcell SqlGeometry intersectionObjectsWithGridCell = newfeatureBoundary.STDifference(featureBoundary); // * ____ ____ // __/ | __/ | // |_ | | => (difference) _ | // |____| newfeature __ |_ _| // // Then we remove intersectionObjects from newFeature and we get the resulting objects. SqlGeometry newFeatueWithoutIntersection = newfeatureBoundary.STDifference(intersectionObjectsWithGridCell); // And now we have the correct lenght of newFeature. double newFeatueWithoutIntersectionLine = newFeatueWithoutIntersection.STLength().Value; webGridCellFeatureStatistics.FeatureLength += newFeatueWithoutIntersectionLine; } } else { // Create add line length to existing line used for lines and polygones if (feature.GetGeometryType().ToString().Equals("MultiPolygon") || feature.GetGeometryType().ToString().Equals("Polygon") || feature.GetGeometryType().ToString().Equals("MultiLineString") || feature.GetGeometryType().ToString().Equals("LineString")) { webGridCellFeatureStatistics.FeatureLength += newFeature.STLength().Value; } } // Calculate area only for polygons if (feature.GetGeometryType().ToString().Equals("MultiPolygon") || feature.GetGeometryType().ToString().Equals("Polygon")) { webGridCellFeatureStatistics.FeatureArea += newFeature.STArea().Value; if (webGridCellFeatureStatistics.FeatureArea > maxGridCellArea) { webGridCellFeatureStatistics.FeatureArea = maxGridCellArea; } } if (feature.GetGeometryType().ToString().Equals("MultiPoint") || feature.GetGeometryType().ToString().Equals("Point")) { webGridCellFeatureStatistics.FeatureCount += (int)newFeature.STNumGeometries(); } else { webGridCellFeatureStatistics.FeatureCount += 1; } // webGridCellFeatureStatistics.FeatureCount += newFeature.STNumGeometries().Value; } } } return(webGridCellFeatureStatisticsList); }
/// <summary> /// Merges the features bounding box with the grid bounding box. /// </summary> /// <param name="featuresBoundingBox">The features bounding box.</param> /// <param name="gridBoundingBox">The grid bounding box.</param> /// <returns>A minimum bounding box.</returns> public static WebBoundingBox GetFeatureStatisticsMergedBoundingBox(WebBoundingBox featuresBoundingBox, WebBoundingBox gridBoundingBox) { WebBoundingBox boundingBox = null; if (featuresBoundingBox == null & gridBoundingBox == null) { return(null); } if (featuresBoundingBox == null) { boundingBox = new WebBoundingBox(); boundingBox.Min = new WebPoint(gridBoundingBox.Min.X, gridBoundingBox.Min.Y); boundingBox.Max = new WebPoint(gridBoundingBox.Max.X, gridBoundingBox.Max.Y); return(boundingBox); } if (gridBoundingBox == null) { boundingBox = new WebBoundingBox(); boundingBox.Min = new WebPoint(featuresBoundingBox.Min.X, featuresBoundingBox.Min.Y); boundingBox.Max = new WebPoint(featuresBoundingBox.Max.X, featuresBoundingBox.Max.Y); return(boundingBox); } boundingBox = new WebBoundingBox(); boundingBox.Min = new WebPoint(); boundingBox.Max = new WebPoint(); if (featuresBoundingBox.Min.X < gridBoundingBox.Min.X) { boundingBox.Min.X = gridBoundingBox.Min.X; } else { boundingBox.Min.X = featuresBoundingBox.Min.X; } if (featuresBoundingBox.Min.Y < gridBoundingBox.Min.Y) { boundingBox.Min.Y = gridBoundingBox.Min.Y; } else { boundingBox.Min.Y = featuresBoundingBox.Min.Y; } if (gridBoundingBox.Max.X < featuresBoundingBox.Max.X) { boundingBox.Max.X = gridBoundingBox.Max.X; } else { boundingBox.Max.X = featuresBoundingBox.Max.X; } if (gridBoundingBox.Max.Y < featuresBoundingBox.Max.Y) { boundingBox.Max.Y = gridBoundingBox.Max.Y; } else { boundingBox.Max.Y = featuresBoundingBox.Max.Y; } return(boundingBox); }