/// <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.");
            }
        }
Пример #2
0
        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;
            }
        }