コード例 #1
0
ファイル: Polygon.cs プロジェクト: pskrip/elmanager
        internal List <Polygon> PolygonOperationWith(Polygon p, PolygonOperationType type)
        {
            if (!IsSimple || !p.IsSimple)
            {
                throw new PolygonException("Both polygons must be non-self-intersecting.");
            }

            Geometry resultPolys;

            switch (type)
            {
            case PolygonOperationType.Intersection:
                resultPolys = p.ToIPolygon().Intersection(ToIPolygon());
                break;

            case PolygonOperationType.Union:
                resultPolys = p.ToIPolygon().Union(ToIPolygon());
                break;

            case PolygonOperationType.Difference:
                resultPolys = p.ToIPolygon().Difference(ToIPolygon());
                break;

            case PolygonOperationType.SymmetricDifference:
                resultPolys = p.ToIPolygon().SymmetricDifference(ToIPolygon()).Buffer(BufferDistance);
                break;

            default:
                throw new PolygonException("Unsupported operation type.");
            }

            var multiPolygon = resultPolys as MultiPolygon;
            var results      = new List <Polygon>();

            if (multiPolygon != null)
            {
                results.AddRange(multiPolygon.Geometries.Cast <NetTopologySuite.Geometries.Polygon>().SelectMany(poly => poly.ToElmaPolygons()));
            }

            if (resultPolys is NetTopologySuite.Geometries.Polygon polygon)
            {
                results.AddRange(polygon.ToElmaPolygons());
            }

            foreach (var x in results)
            {
                x.UpdateDecomposition();
            }
            return(results);
        }
コード例 #2
0
ファイル: PolyOpTool.cs プロジェクト: j-masci/elmanager
        public void KeyDown(KeyEventArgs key)
        {
            if (key.KeyCode != Keys.Space || FirstSelected)
            {
                return;
            }
            switch (_currentOpType)
            {
            case PolygonOperationType.Union:
                _currentOpType = PolygonOperationType.Difference;
                break;

            case PolygonOperationType.Intersection:
                break;

            case PolygonOperationType.Difference:
                _currentOpType = PolygonOperationType.Union;
                break;
            }

            UpdateHelp();
        }
コード例 #3
0
ファイル: PolyOpTool.cs プロジェクト: j-masci/elmanager
        public static bool PolyOpSelected(PolygonOperationType opType, List <Polygon> polygons)
        {
            var polys = polygons.GetSelectedPolygons().ToList();

            Geometry SymDiff(Geometry g, Geometry p) => p.SymmetricDifference(g);

            var selection = polygons.GetSelectedPolygonsAsMultiPolygon();
            var touching  = polygons.Where(p =>
            {
                if (p.IsGrass)
                {
                    return(false);
                }
                var ip = p.ToIPolygon();
                return(!polys.Contains(p) && ip.Intersects(selection) && !ip.Contains(selection));
            }).ToList();

            if (!touching.Any())
            {
                return(false);
            }

            var others    = touching.ToIPolygons().Aggregate((Func <Geometry, Geometry, Geometry>)SymDiff);
            var remaining = polygons.Where(p =>
            {
                if (p.IsGrass)
                {
                    return(false);
                }
                var ipoly = p.ToIPolygon();
                return(!touching.Contains(p) && !polys.Contains(p) && ipoly.Within(others));
            }).ToList();

            others = remaining.ToIPolygons().Aggregate(others, (Func <Geometry, Geometry, Geometry>)SymDiff);

            Geometry result;

            try
            {
                switch (opType)
                {
                case PolygonOperationType.Union:
                    result = others.Union(selection);
                    break;

                case PolygonOperationType.Difference:
                    result = others.Difference(selection);
                    break;

                case PolygonOperationType.Intersection:
                    result = others.Intersection(selection);
                    break;

                case PolygonOperationType.SymmetricDifference:
                    result = others.SymmetricDifference(selection)
                             .Buffer(Polygon.BufferDistance, new BufferParameters(0, EndCapStyle.Flat, JoinStyle.Bevel, 1));
                    break;

                default:
                    throw new Exception("Unknown operation type.");
                }
            }
            catch (TopologyException)
            {
                Utils.ShowError(
                    "Could not perform this operation. Make sure the polygons don't have self-intersections.");
                return(false);
            }

            touching.ForEach(p => polygons.Remove(p));
            polys.ForEach(p => polygons.Remove(p));
            remaining.ForEach(p => polygons.Remove(p));
            switch (result)
            {
            case MultiPolygon polygon:
            {
                foreach (var geometry in polygon.Geometries.Cast <NetTopologySuite.Geometries.Polygon>().Where(p => !p.IsEmpty))
                {
                    var newPolys = geometry.ToElmaPolygons().ToList();
                    newPolys.ForEach(p => p.RemoveDuplicateVertices());
                    polygons.AddRange(newPolys);
                }

                break;
            }

            case NetTopologySuite.Geometries.Polygon polygon1 when !polygon1.IsEmpty:
            {
                var newPolys = polygon1.ToElmaPolygons().ToList();
                newPolys.ForEach(p => p.RemoveDuplicateVertices());
                polygons.AddRange(newPolys);
                break;
            }
            }

            if (!polygons.Any())
            {
                Utils.ShowError("The level would become empty after this operation.");
                polygons.AddRange(polys);
                polygons.AddRange(touching);
            }

            return(true);
        }