public void TestML() { { const double scale = 2.0E10; var precisionModel = new PrecisionModel(scale); var gs = new NtsGeometryServices(precisionModel, 0); //var geometryFactory = gs.CreateGeometryFactory(); var reader = new WKTReader(gs); var lineStringA = (LineString) reader.Read("LINESTRING (-93.40178610435 -235.5437531975, -401.24229900825 403.69365857925)"); var lineStringB = (LineString) reader.Read("LINESTRING (-50.0134121926 -145.44686640725, -357.8539250965 493.7905453695)"); var lineStringC = (LineString) reader.Read("LINESTRING (-193.8964147753 -30.64653554935, -186.68866383205 -34.1176054623)"); var middlePoint = (Point)reader.Read("POINT (-203.93366864454998 174.171839481125)"); var lineStrings = new List <LineString>(); lineStrings.Add(lineStringA); lineStrings.Add(lineStringB); lineStrings.Add(lineStringC); var noder = new GeometryNoder(precisionModel); var nodedLineStrings = noder.Node(lineStrings.ToArray()); double shortestDistanceToPointBeforeNoding = double.MaxValue; foreach (var lineString in lineStrings) { shortestDistanceToPointBeforeNoding = Math.Min(lineString.Distance(middlePoint), shortestDistanceToPointBeforeNoding); } double shortestDistanceToPointAfterNoding = double.MaxValue; foreach (var lineString in nodedLineStrings) { shortestDistanceToPointAfterNoding = Math.Min(lineString.Distance(middlePoint), shortestDistanceToPointAfterNoding); } double difference = Math.Abs(shortestDistanceToPointAfterNoding - shortestDistanceToPointBeforeNoding); TestContext.WriteLine("Scale: {0}", scale); TestContext.WriteLine("Distance to point before noding: {0}", shortestDistanceToPointBeforeNoding); TestContext.WriteLine("Distance to point after noding: {0}", shortestDistanceToPointAfterNoding); TestContext.WriteLine("Difference is {0} and should be lesser than {1}", difference, 1.0 / scale); const double roughTolerance = 10.0; Assert.IsTrue(difference < roughTolerance, "this difference should should be lesser than " + 1.0 / scale); } }
public static Geometry NodeWithPointwisePrecision(Geometry geom, double scaleFactor) { var pm = new PrecisionModel(scaleFactor); var roundedGeom = GeometryPrecisionReducer.Reduce(geom, pm); var geomList = new List <Geometry>(); geomList.Add(roundedGeom); var noder = new GeometryNoder(pm); var lines = noder.Node(geomList); return(Utility.FunctionsUtil.getFactoryOrDefault(geom).BuildGeometry(lines.Cast <Geometry>().ToList())); }
public static IGeometry NodeWithPointwisePrecision(IGeometry geom, double scaleFactor) { var pm = new PrecisionModel(scaleFactor); var roundedGeom = GeometryPrecisionReducer.Reduce(geom, pm); var geomList = new List <IGeometry>(); geomList.Add(roundedGeom); var noder = new GeometryNoder(pm); var lines = noder.Node(geomList); return(FunctionsUtil.getFactoryOrDefault(geom).BuildGeometry(CollectionUtil.Cast <IGeometry>((ICollection)lines))); }
/// <summary> /// Reduces precision pointwise, then snap-rounds. /// Note that output set may not contain non-unique linework /// (and thus cannot be used as input to Polygonizer directly). /// UnaryUnion is one way to make the linework unique. /// </summary> /// <param name="geom">A geometry containing linework to node</param> /// <param name="scaleFactor">the precision model scale factor to use</param> /// <returns>The noded, snap-rounded linework</returns> public static IGeometry SnapRoundWithPointwisePrecisionReduction(IGeometry geom, double scaleFactor) { var pm = new PrecisionModel(scaleFactor); var roundedGeom = GeometryPrecisionReducer.ReducePointwise(geom, pm); var geomList = new List <IGeometry>(); geomList.Add(roundedGeom); var noder = new GeometryNoder(pm); var lines = noder.Node(geomList); return(FunctionsUtil.GetFactoryOrDefault(geom).BuildGeometry(lines.Cast <IGeometry>().ToArray())); }
private void CheckRounding(string[] wkt) { var geoms = FromWKT(wkt); var pm = new PrecisionModel(SnapTolerance); var noder = new GeometryNoder(pm); noder.IsValidityChecked = true; var nodedLines = noder.Node(geoms); foreach (var ls in nodedLines) { TestContext.WriteLine(ls); } Assert.IsTrue(IsSnapped(nodedLines, SnapTolerance)); }
/// <summary> /// Creates a featureset from the given raster. /// </summary> /// <param name="rst">Raster used for creation.</param> /// <param name="contourType">The contour type used for creation.</param> /// <param name="fieldName">Name of the field that gets added to the featureset to put the level values into.</param> /// <param name="levels">The levels to sort the features into.</param> /// <returns>The featureset that was created from the raster.</returns> public static FeatureSet Execute(Raster rst, ContourType contourType, string fieldName = "Value", double[] levels = null) { double[] lev = levels; noData = rst.NoDataValue; type = contourType; Raster iRst = RasterCheck(rst, lev); string field = fieldName ?? "Value"; double[] x = new double[rst.NumColumns]; double[] y = new double[rst.NumRows]; for (int i = 0; i < rst.NumColumns; i++) { x[i] = rst.Extent.MinX + (rst.CellWidth * i) + (rst.CellWidth / 2); } for (int i = 0; i < rst.NumRows; i++) { y[i] = rst.Extent.MaxY - (rst.CellHeight * i) - (rst.CellHeight / 2); } FeatureSet fs = null; switch (type) { case ContourType.Line: fs = new FeatureSet(FeatureType.Line); fs.DataTable.Columns.Add(field, typeof(double)); if (levels != null) { for (int z = 0; z < levels.Length; z++) { IList <IGeometry> cont = GetContours(ref iRst, x, y, lev[z]); foreach (var g in cont) { var f = (Feature)fs.AddFeature((ILineString)g); f.DataRow[field] = lev[z]; } } } break; case ContourType.Polygon: fs = new FeatureSet(FeatureType.Polygon); fs.DataTable.Columns.Add("Lev", typeof(int)); fs.DataTable.Columns.Add("Label", typeof(string)); Collection <IGeometry> contours = new Collection <IGeometry>(); if (levels != null) { for (int z = 0; z < levels.Length; z++) { IList <IGeometry> cont = GetContours(ref iRst, x, y, lev[z]); foreach (var g in cont) { contours.Add(new LineString(g.Coordinates)); } } Coordinate[] boundary = new Coordinate[5]; boundary[0] = new Coordinate(x[0], y[0]); boundary[1] = new Coordinate(x[0], y[rst.NumRows - 1]); boundary[2] = new Coordinate(x[rst.NumColumns - 1], y[rst.NumRows - 1]); boundary[3] = new Coordinate(x[rst.NumColumns - 1], y[0]); boundary[4] = new Coordinate(x[0], y[0]); contours.Add(new LineString(boundary)); Collection <IGeometry> nodedContours = new Collection <IGeometry>(); IPrecisionModel pm = new PrecisionModel(1000d); GeometryNoder geomNoder = new GeometryNoder(pm); foreach (var c in geomNoder.Node(contours)) { nodedContours.Add(c); } Polygonizer polygonizer = new Polygonizer(); polygonizer.Add(nodedContours); foreach (IPolygon p in polygonizer.GetPolygons().OfType <IPolygon>()) { IPoint pnt = p.InteriorPoint; int c = (int)((pnt.X - iRst.Extent.MinX) / iRst.CellWidth); int r = (int)((iRst.Extent.MaxY - pnt.Y) / iRst.CellHeight); double z = iRst.Value[r, c]; int cls = GetLevel(z, lev); string label = "Undefined"; if (cls == -1) { label = "< " + lev[0]; } else if (cls == lev.Length) { label = "> " + lev[lev.Length - 1]; } else if (cls >= 0 & cls < lev.Length) { label = lev[cls] + " - " + lev[cls + 1]; } IFeature f = fs.AddFeature(p); f.DataRow["Lev"] = cls; f.DataRow["Label"] = label; } } break; } return(fs); }
public static DotSpatial.Data.FeatureSet Execute(DotSpatial.Data.Raster rst, ContourType contourType, string FieldName = "Value", double[] levels = null) { double[] lev = levels; noData = rst.NoDataValue; type = contourType; DotSpatial.Data.Raster iRst = RasterCheck(rst, lev);; string field; if (FieldName == null) { field = "Value"; } else { field = FieldName; } double[] x = new double[rst.NumColumns]; double[] y = new double[rst.NumRows]; for (int i = 0; i < rst.NumColumns; i++) { x[i] = rst.Extent.MinX + rst.CellWidth * i + rst.CellWidth / 2; } for (int i = 0; i < rst.NumRows; i++) { y[i] = rst.Extent.MaxY - rst.CellHeight * i - rst.CellHeight / 2; } DotSpatial.Data.FeatureSet fs = null; switch (type) { case ContourType.Line: { fs = new DotSpatial.Data.FeatureSet(DotSpatial.Topology.FeatureType.Line); fs.DataTable.Columns.Add(field, typeof(double)); for (int z = 0; z < levels.Length; z++) { IList <IGeometry> cont = GetContours(ref iRst, x, y, lev[z]); foreach (var g in cont) { var f = (DotSpatial.Data.Feature)fs.AddFeature(ToDotSpatialLineString((ILineString)g)); f.DataRow[field] = lev[z]; } } } break; case ContourType.Polygon: { fs = new DotSpatial.Data.FeatureSet(DotSpatial.Topology.FeatureType.Polygon); fs.DataTable.Columns.Add("Lev", typeof(int)); fs.DataTable.Columns.Add("Label", typeof(string)); Collection <IGeometry> Contours = new Collection <IGeometry>(); for (int z = 0; z < levels.Count(); z++) { IList <IGeometry> cont = GetContours(ref iRst, x, y, lev[z]); foreach (var g in cont) { Contours.Add(new LineString(g.Coordinates)); } } Coordinate[] Boundary = new Coordinate[5]; Boundary[0] = new Coordinate(x[0], y[0]); Boundary[1] = new Coordinate(x[0], y[rst.NumRows - 1]); Boundary[2] = new Coordinate(x[rst.NumColumns - 1], y[rst.NumRows - 1]); Boundary[3] = new Coordinate(x[rst.NumColumns - 1], y[0]); Boundary[4] = new Coordinate(x[0], y[0]); Contours.Add(new LineString(Boundary)); Collection <IGeometry> NodedContours = new Collection <IGeometry>(); GeometryNoder geomNoder = new GeometryNoder(new PrecisionModel(1000d)); foreach (var c in geomNoder.Node(Contours)) { NodedContours.Add(c); } Polygonizer polygonizer = new Polygonizer(); polygonizer.Add(NodedContours); foreach (IPolygon p in polygonizer.GetPolygons()) { Point pnt = (Point)p.InteriorPoint; int c = (int)((pnt.X - iRst.Extent.MinX) / iRst.CellWidth); int r = (int)((iRst.Extent.MaxY - pnt.Y) / iRst.CellHeight); double z = ((DotSpatial.Data.Raster)iRst).Value[r, c]; int Cls = GetLevel(z, lev); string label = "Undefined"; if (Cls == -1) { label = "< " + lev[0].ToString(); } if (Cls == lev.Count()) { label = "> " + lev[lev.Count() - 1].ToString(); } if (Cls >= 0 & Cls < lev.Count()) { label = lev[Cls].ToString() + " - " + lev[Cls + 1].ToString(); } DotSpatial.Topology.Polygon dsp = ToDotSpatialPolygon(p); DotSpatial.Data.Feature f = (DotSpatial.Data.Feature)fs.AddFeature(dsp); f.DataRow["Lev"] = Cls; f.DataRow["Label"] = label; } } break; } return(fs); }