/// <summary> /// Cuts the given linestring in one of more segments. /// </summary> /// <param name="tilePolygon">The tile polygon.</param> /// <param name="lineString">The linestring.</param> /// <returns>One or more segments.</returns> public static IEnumerable <LineString> Cut(this Polygon tilePolygon, LineString lineString) { var op = new OverlayOp(lineString, tilePolygon); var intersection = op.GetResultGeometry(SpatialFunction.Intersection); if (intersection.IsEmpty) { yield break; } switch (intersection) { case LineString ls: // intersection is a linestring. yield return(ls); yield break; case GeometryCollection gc: { foreach (var geometry in gc.Geometries) { switch (geometry) { case LineString ls0: yield return(ls0); break; case Point _: // The linestring only has a single point in this tile // We skip it // TODO check if this is correct continue; default: throw new Exception( $"{nameof(LineStringTiler)}.{nameof(Cut)} failed: A geometry was found in the intersection that wasn't a {nameof(LineString)}."); } } yield break; } default: throw new Exception($"{nameof(LineStringTiler)}.{nameof(Cut)} failed: Unknown result."); } }
public static FeatureClassSDO Intersect(this FeatureClassSDO featureClassSelf, FeatureClassSDO featureClassOther) { FeatureClassSDO newFeatureClass = null; try { if (featureClassSelf == null || featureClassOther == null) { throw new ArgumentException("对象未实例化"); } if (featureClassSelf.GeometryTypeNet != featureClassOther.GeometryTypeNet) { throw new ArgumentException("空间对象类型错误"); } if (CompareProperties(featureClassSelf.spatialReference, featureClassOther.spatialReference, typeof(object))) { throw new ArgumentException("空间坐标系不一致"); } newFeatureClass = new FeatureClassSDO() { Name = $"{featureClassSelf.Name}_{featureClassOther.Name}", DisplayFieldName = $"{featureClassSelf.DisplayFieldName}_{featureClassOther.DisplayFieldName}", Fields = featureClassSelf.Fields, GeometryType = featureClassSelf.GeometryType, GeometryTypeNet = featureClassSelf.GeometryTypeNet, spatialReference = featureClassSelf.spatialReference }; foreach (var item in featureClassOther.Fields) { if (item.Type == enumFieldType.esriFieldTypeGeometry || item.Name.ToLower() == "shape_area") { continue; } newFeatureClass.Fields.Add(new Field() { Alias = $"{featureClassOther.Name}_{item.Alias}", Type = item.Type, Name = $"{featureClassOther.Name}_{item.Name}" }); } int groupCount = featureClassOther.Features.Count / SpatialDataObtain.MinWorkThreadCount; Parallel.ForEach(featureClassOther.Features, (otherItem) => { foreach (var selfItem in featureClassSelf.Features) { if (otherItem.Geometry.Intersects(selfItem.Geometry)) { OverlayOp overlayOp = new OverlayOp(otherItem.Geometry, selfItem.Geometry); Geometry newGeometry = overlayOp.GetResultGeometry(SpatialFunction.Intersection); Feature newFeature = new Feature(); newFeature.Attributes = new Dictionary <string, object>(selfItem.Attributes); foreach (var oterAttribute in otherItem.Attributes) { Field field = featureClassOther.Fields.Single(item => item.Name == oterAttribute.Key); if (field.Type == enumFieldType.esriFieldTypeGeometry || field.Name.ToLower() == "shape_area") { continue; } string newKey = $"{featureClassOther.Name}_{field.Name}"; newFeature.Attributes.Add(newKey, oterAttribute.Value); } newFeature.Geometry = newGeometry; newFeatureClass.AddFeature(newFeature); } } }); return(newFeatureClass); } catch (Exception e) { LogUtil.Error(e.ToString()); throw; } }