// Convert an input geometry instance to a valid geography instance. // This function requires that the WKT coordinate values are longitude/latitude values, // in that order and that a valid geography SRID value is supplied. // public static SqlGeography MakeValidGeographyFromGeometry(SqlGeometry geometry) { if (geometry.IsNull) { return(SqlGeography.Null); } if (geometry.STIsEmpty().Value) { return(CreateEmptyGeography(geometry.STSrid.Value)); } // Extract vertices from our input to be able to compute geography EnvelopeCenter SqlGeographyBuilder pointSetBuilder = new SqlGeographyBuilder(); geometry.Populate(new GeometryToPointGeographySink(pointSetBuilder)); SqlGeography center; try { center = pointSetBuilder.ConstructedGeography.EnvelopeCenter(); } catch (ArgumentException) { // Input is larger than a hemisphere. return(SqlGeography.Null); } // Construct Gnomonic projection centered on input geography SqlProjection gnomonicProjection = SqlProjection.Gnomonic(center.Long.Value, center.Lat.Value); // Project, run geometry MakeValid and unproject SqlGeometryBuilder geometryBuilder = new SqlGeometryBuilder(); geometry.Populate(new VacuousGeometryToGeographySink(geometry.STSrid.Value, new Projector(gnomonicProjection, geometryBuilder))); SqlGeometry outGeometry = MakeValidForGeography(geometryBuilder.ConstructedGeometry); try { return(gnomonicProjection.Unproject(outGeometry)); } catch (ArgumentException) { // Try iteratively to reduce the object to remove very close vertices. for (double tollerance = 1e-4; tollerance <= 1e6; tollerance *= 2) { try { return(gnomonicProjection.Unproject(outGeometry.Reduce(tollerance))); } catch (ArgumentException) { // keep trying } } return(SqlGeography.Null); } }
// Computes ConvexHull of input geography and returns a polygon (unless all input points are colinear). // public static SqlGeography ConvexHullGeography(SqlGeography geography) { if (geography.IsNull || geography.STIsEmpty().Value) { return(geography); } SqlGeography center = geography.EnvelopeCenter(); SqlProjection gnomonicProjection = SqlProjection.Gnomonic(center.Long.Value, center.Lat.Value); SqlGeometry geometry = gnomonicProjection.Project(geography); return(gnomonicProjection.Unproject(geometry.MakeValid().STConvexHull())); }
public Projector(SqlProjection projection, IGeometrySink sink) { _projection = projection; _sink = sink; }
public Unprojector(SqlProjection projection, IGeographySink sink, int newSrid) { _projection = projection; _sink = sink; _sink.SetSrid(newSrid); }