06-集合操作符

第六章:集合操作符

6.1 概述

集合操作符用于计算两个几何对象之间的布尔运算,生成新的几何对象。这些操作符在空间分析中非常重要,常用于区域叠加分析、空间查询等场景。

6.1.1 集合操作类型

操作 操作符 数学表示 说明
并集 UnionOperator A ∪ B 两个几何对象的所有点
交集 IntersectionOperator A ∩ B 两个几何对象的共同点
差集 DifferenceOperator A - B A 中不属于 B 的点
对称差 SymmetricDifferenceOperator A △ B 属于 A 或 B 但不同时属于两者的点

6.1.2 维恩图表示

     并集 (Union)              交集 (Intersection)
    ┌─────────────┐            ┌─────────────┐
    │  ░░░░░░░░░  │            │     ░░░     │
    │ ░░░░░░░░░░░ │            │    ░░░░░    │
    │░░░░░░░░░░░░░│            │   ░░░░░░░   │
    │░░░░░░░░░░░░░│            │    ░░░░░    │
    │ ░░░░░░░░░░░ │            │     ░░░     │
    │  ░░░░░░░░░  │            │             │
    └─────────────┘            └─────────────┘
    
    差集 (Difference A-B)      对称差 (SymmetricDifference)
    ┌─────────────┐            ┌─────────────┐
    │ ░░░         │            │ ░░░     ░░░ │
    │░░░░░        │            │░░░░░   ░░░░░│
    │░░░░░        │            │░░░░░   ░░░░░│
    │░░░░░        │            │░░░░░   ░░░░░│
    │ ░░░         │            │ ░░░     ░░░ │
    │             │            │             │
    └─────────────┘            └─────────────┘

6.2 Union(并集)

6.2.1 定义

并集操作返回两个几何对象中所有点的集合。结果几何对象包含 A 或 B 中的任何点。

数学表达:A ∪ B = { x | x ∈ A 或 x ∈ B }

6.2.2 API

public sealed class UnionOperator : IBinaryGeometryOperator<Geometry>
{
    public static UnionOperator Instance { get; }
    
    public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                           SpatialReference? spatialReference = null);
}

6.2.3 使用示例

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;

// 两个点的并集 → MultiPoint
var point1 = new Point(0, 0);
var point2 = new Point(10, 10);

var union1 = GeometryEngine.Union(point1, point2);
Console.WriteLine($"并集类型:{union1.Type}");  // MultiPoint

if (union1 is MultiPoint mp)
{
    Console.WriteLine($"点数:{mp.Count}");  // 2
}

// 相同的点合并为一个
var point3 = new Point(0, 0);
var union2 = GeometryEngine.Union(point1, point3);
Console.WriteLine($"相同点并集类型:{union2.Type}");  // Point

// 点与 MultiPoint 的并集
var multiPoint = new MultiPoint();
multiPoint.Add(new Point(5, 5));
multiPoint.Add(new Point(15, 15));

var union3 = GeometryEngine.Union(point1, multiPoint);
if (union3 is MultiPoint result)
{
    Console.WriteLine($"并集点数:{result.Count}");  // 3
}

// 两个包络矩形的并集
var env1 = new Envelope(0, 0, 50, 50);
var env2 = new Envelope(25, 25, 75, 75);

var union4 = GeometryEngine.Union(env1, env2);
if (union4 is Envelope envResult)
{
    Console.WriteLine($"并集范围:({envResult.XMin}, {envResult.YMin}) - ({envResult.XMax}, {envResult.YMax})");
    // 输出:(0, 0) - (75, 75)
}

6.2.4 实现原理

public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                       SpatialReference? spatialReference = null)
{
    // 处理空几何
    if (geometry1.IsEmpty && geometry2.IsEmpty)
        return new Point(double.NaN, double.NaN);
    if (geometry1.IsEmpty) return geometry2;
    if (geometry2.IsEmpty) return geometry1;

    // Point + Point
    if (geometry1 is Point p1 && geometry2 is Point p2)
    {
        if (EqualsOperator.Instance.Execute(p1, p2))
            return p1;  // 相同点返回一个
        
        var mp = new MultiPoint();
        mp.Add(p1);
        mp.Add(p2);
        return mp;
    }

    // Point + MultiPoint
    if (geometry1 is Point point && geometry2 is MultiPoint mp2)
    {
        var result = new MultiPoint();
        result.Add(point);
        foreach (var p in mp2.GetPoints())
            result.Add(p);
        return result;
    }

    // MultiPoint + MultiPoint
    if (geometry1 is MultiPoint multiPoint1 && geometry2 is MultiPoint multiPoint2)
    {
        var result = new MultiPoint();
        foreach (var p in multiPoint1.GetPoints())
            result.Add(p);
        foreach (var p in multiPoint2.GetPoints())
            result.Add(p);
        return result;
    }

    // Envelope + Envelope
    if (geometry1 is Envelope env1 && geometry2 is Envelope env2)
    {
        var xMin = Math.Min(env1.XMin, env2.XMin);
        var yMin = Math.Min(env1.YMin, env2.YMin);
        var xMax = Math.Max(env1.XMax, env2.XMax);
        var yMax = Math.Max(env1.YMax, env2.YMax);
        return new Envelope(xMin, yMin, xMax, yMax);
    }

    // 对于其他复杂情况,返回包络的并集
    var envelope1 = geometry1.GetEnvelope();
    var envelope2 = geometry2.GetEnvelope();
    return Execute(envelope1, envelope2);
}

6.2.5 应用场景

// 场景:合并多个服务区域
var zone1 = new Envelope(0, 0, 100, 100);
var zone2 = new Envelope(80, 80, 180, 180);
var zone3 = new Envelope(50, 50, 150, 150);

// 逐步合并
var combined = GeometryEngine.Union(zone1, zone2);
combined = GeometryEngine.Union(combined, zone3);

Console.WriteLine($"合并后的服务区域:{combined.GetEnvelope()}");

6.3 Intersection(交集)

6.3.1 定义

交集操作返回两个几何对象共同拥有的点的集合。

数学表达:A ∩ B = { x | x ∈ A 且 x ∈ B }

6.3.2 API

public sealed class IntersectionOperator : IBinaryGeometryOperator<Geometry>
{
    public static IntersectionOperator Instance { get; }
    
    public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                           SpatialReference? spatialReference = null);
}

6.3.3 使用示例

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;

// 相同的点的交集
var point1 = new Point(10, 10);
var point2 = new Point(10, 10);
var intersection1 = GeometryEngine.Intersection(point1, point2);
Console.WriteLine($"相同点交集:{intersection1.IsEmpty}");  // false

// 不同的点的交集(空)
var point3 = new Point(20, 20);
var intersection2 = GeometryEngine.Intersection(point1, point3);
Console.WriteLine($"不同点交集为空:{intersection2.IsEmpty}");  // true

// 点与包络矩形的交集
var envelope = new Envelope(0, 0, 50, 50);
var pointInside = new Point(25, 25);
var pointOutside = new Point(100, 100);

var int3 = GeometryEngine.Intersection(pointInside, envelope);
Console.WriteLine($"内部点与包络交集:{int3.Type}");  // Point

var int4 = GeometryEngine.Intersection(pointOutside, envelope);
Console.WriteLine($"外部点与包络交集为空:{int4.IsEmpty}");  // true

// 两个包络矩形的交集
var env1 = new Envelope(0, 0, 50, 50);
var env2 = new Envelope(25, 25, 75, 75);

var intersection3 = GeometryEngine.Intersection(env1, env2);
if (intersection3 is Envelope envResult)
{
    Console.WriteLine($"交集范围:({envResult.XMin}, {envResult.YMin}) - ({envResult.XMax}, {envResult.YMax})");
    // 输出:(25, 25) - (50, 50)
}

// 不相交的包络矩形
var env3 = new Envelope(100, 100, 150, 150);
var intersection4 = GeometryEngine.Intersection(env1, env3);
Console.WriteLine($"不相交包络的交集为空:{intersection4.IsEmpty}");  // true

6.3.4 实现原理

public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                       SpatialReference? spatialReference = null)
{
    // 空几何的交集为空
    if (geometry1.IsEmpty || geometry2.IsEmpty)
        return new Point(double.NaN, double.NaN);

    // Point + Point
    if (geometry1 is Point p1 && geometry2 is Point p2)
    {
        if (EqualsOperator.Instance.Execute(p1, p2))
            return p1;
        return new Point(double.NaN, double.NaN);
    }

    // Point + Envelope
    if (geometry1 is Point point && geometry2 is Envelope envelope)
    {
        if (ContainsOperator.Instance.Execute(envelope, point))
            return point;
        return new Point(double.NaN, double.NaN);
    }

    // Envelope + Envelope
    if (geometry1 is Envelope env1 && geometry2 is Envelope env2)
    {
        var xMin = Math.Max(env1.XMin, env2.XMin);
        var yMin = Math.Max(env1.YMin, env2.YMin);
        var xMax = Math.Min(env1.XMax, env2.XMax);
        var yMax = Math.Min(env1.YMax, env2.YMax);

        if (xMin <= xMax && yMin <= yMax)
            return new Envelope(xMin, yMin, xMax, yMax);
        
        return new Point(double.NaN, double.NaN);
    }

    // MultiPoint + Envelope
    if (geometry1 is MultiPoint multiPoint && geometry2 is Envelope env)
    {
        var result = new MultiPoint();
        foreach (var p in multiPoint.GetPoints())
        {
            if (ContainsOperator.Instance.Execute(env, p))
                result.Add(p);
        }
        
        if (result.Count > 0)
            return result;
        return new Point(double.NaN, double.NaN);
    }

    // 复杂几何的交集:使用包络近似
    if (IntersectsOperator.Instance.Execute(geometry1, geometry2))
    {
        var env1_temp = geometry1.GetEnvelope();
        var env2_temp = geometry2.GetEnvelope();
        return Execute(env1_temp, env2_temp);
    }

    return new Point(double.NaN, double.NaN);
}

6.3.5 应用场景

// 场景1:查找两个区域的重叠部分
var region1 = new Envelope(0, 0, 100, 100);
var region2 = new Envelope(50, 50, 150, 150);

var overlap = GeometryEngine.Intersection(region1, region2);
if (!overlap.IsEmpty && overlap is Envelope overlapEnv)
{
    double overlapArea = overlapEnv.Area;
    Console.WriteLine($"重叠面积:{overlapArea}");  // 2500
}

// 场景2:过滤在特定区域内的点
var searchArea = new Envelope(10, 10, 90, 90);
var allPoints = new MultiPoint();
allPoints.Add(new Point(50, 50));   // 在区域内
allPoints.Add(new Point(5, 5));     // 在区域外
allPoints.Add(new Point(80, 80));   // 在区域内

var pointsInArea = GeometryEngine.Intersection(allPoints, searchArea);
if (pointsInArea is MultiPoint filteredPoints)
{
    Console.WriteLine($"区域内的点数:{filteredPoints.Count}");  // 2
}

6.4 Difference(差集)

6.4.1 定义

差集操作返回属于第一个几何对象但不属于第二个几何对象的点的集合。

数学表达:A - B = { x | x ∈ A 且 x ∉ B }

注意:差集是非对称的,A - B ≠ B - A

6.4.2 API

public sealed class DifferenceOperator : IBinaryGeometryOperator<Geometry>
{
    public static DifferenceOperator Instance { get; }
    
    public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                           SpatialReference? spatialReference = null);
}

6.4.3 使用示例

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;

// MultiPoint 与 Envelope 的差集
var multiPoint = new MultiPoint();
multiPoint.Add(new Point(5, 5));    // 在包络内
multiPoint.Add(new Point(25, 25));  // 在包络内
multiPoint.Add(new Point(75, 75));  // 在包络外

var envelope = new Envelope(0, 0, 50, 50);

// MultiPoint - Envelope = 包络外的点
var difference = GeometryEngine.Difference(multiPoint, envelope);

if (difference is Point p)
{
    Console.WriteLine($"差集结果:单个点 ({p.X}, {p.Y})");  // (75, 75)
}
else if (difference is MultiPoint mp)
{
    Console.WriteLine($"差集结果:{mp.Count} 个点");
}

// 不同点的差集
var point1 = new Point(10, 10);
var point2 = new Point(20, 20);
var diff = GeometryEngine.Difference(point1, point2);
Console.WriteLine($"不同点差集:{diff.Type}");  // Point (point1)

// 相同点的差集
var diff2 = GeometryEngine.Difference(point1, point1);
Console.WriteLine($"相同点差集为空:{diff2.IsEmpty}");  // true

6.4.4 实现原理

public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                       SpatialReference? spatialReference = null)
{
    // 空几何处理
    if (geometry1.IsEmpty)
        return new Point(double.NaN, double.NaN);
    if (geometry2.IsEmpty)
        return geometry1;  // A - ∅ = A

    // Point - Point
    if (geometry1 is Point p1 && geometry2 is Point p2)
    {
        if (EqualsOperator.Instance.Execute(p1, p2))
            return new Point(double.NaN, double.NaN);  // 相同点,差集为空
        return p1;  // 不同点,返回 p1
    }

    // Point - Envelope
    if (geometry1 is Point point && geometry2 is Envelope envelope)
    {
        if (ContainsOperator.Instance.Execute(envelope, point))
            return new Point(double.NaN, double.NaN);  // 点在包络内,差集为空
        return point;  // 点在包络外,返回点
    }

    // MultiPoint - Envelope
    if (geometry1 is MultiPoint multiPoint && geometry2 is Envelope env)
    {
        var result = new MultiPoint();
        foreach (var p in multiPoint.GetPoints())
        {
            // 只保留不在包络内的点
            if (!ContainsOperator.Instance.Execute(env, p))
                result.Add(p);
        }
        
        if (result.Count == 0)
            return new Point(double.NaN, double.NaN);
        if (result.Count == 1)
            return result.GetPoint(0);
        return result;
    }

    // MultiPoint - Point
    if (geometry1 is MultiPoint mp && geometry2 is Point pt)
    {
        var result = new MultiPoint();
        foreach (var p in mp.GetPoints())
        {
            if (!EqualsOperator.Instance.Execute(p, pt))
                result.Add(p);
        }
        
        if (result.Count == 0)
            return new Point(double.NaN, double.NaN);
        if (result.Count == 1)
            return result.GetPoint(0);
        return result;
    }

    // 复杂情况:如果不相交,返回 geometry1
    if (!IntersectsOperator.Instance.Execute(geometry1, geometry2))
        return geometry1;

    // 如果完全包含,返回空
    if (ContainsOperator.Instance.Execute(geometry2, geometry1))
        return new Point(double.NaN, double.NaN);

    // 其他情况返回 geometry1(简化处理)
    return geometry1;
}

6.4.5 应用场景

// 场景:从全国范围中排除某个省份
var china = new Envelope(73, 18, 135, 54);  // 中国大致范围
var beijing = new Envelope(115.4, 39.4, 117.5, 41.1);  // 北京大致范围

// 注意:对于复杂多边形的差集需要更高级的算法
// 当前实现返回简化结果

// 场景:过滤已处理的点
var allPoints = new MultiPoint();
allPoints.Add(new Point(1, 1));
allPoints.Add(new Point(2, 2));
allPoints.Add(new Point(3, 3));

var processedPoints = new MultiPoint();
processedPoints.Add(new Point(2, 2));

// 获取未处理的点
// 注意:当前实现需要逐点处理
var unprocessed = new MultiPoint();
foreach (var p in allPoints.GetPoints())
{
    bool processed = false;
    foreach (var pp in processedPoints.GetPoints())
    {
        if (GeometryEngine.Equals(p, pp))
        {
            processed = true;
            break;
        }
    }
    if (!processed)
        unprocessed.Add(p);
}
Console.WriteLine($"未处理的点数:{unprocessed.Count}");  // 2

6.5 SymmetricDifference(对称差)

6.5.1 定义

对称差操作返回属于任一几何对象但不同时属于两者的点的集合。可以理解为并集减去交集。

数学表达:A △ B = (A ∪ B) - (A ∩ B) = (A - B) ∪ (B - A)

6.5.2 API

public sealed class SymmetricDifferenceOperator : IBinaryGeometryOperator<Geometry>
{
    public static SymmetricDifferenceOperator Instance { get; }
    
    public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                           SpatialReference? spatialReference = null);
}

6.5.3 使用示例

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;

// 两个不同点的对称差
var point1 = new Point(0, 0);
var point2 = new Point(10, 10);

var symDiff1 = GeometryEngine.SymmetricDifference(point1, point2);
if (symDiff1 is MultiPoint mp1)
{
    Console.WriteLine($"对称差点数:{mp1.Count}");  // 2
}

// 两个相同点的对称差(空)
var point3 = new Point(0, 0);
var symDiff2 = GeometryEngine.SymmetricDifference(point1, point3);
Console.WriteLine($"相同点对称差为空:{symDiff2.IsEmpty}");  // true

// 两个 MultiPoint 的对称差
var multiPoint1 = new MultiPoint();
multiPoint1.Add(new Point(0, 0));
multiPoint1.Add(new Point(10, 10));

var multiPoint2 = new MultiPoint();
multiPoint2.Add(new Point(10, 10));  // 共同点
multiPoint2.Add(new Point(20, 20));

var symDiff3 = GeometryEngine.SymmetricDifference(multiPoint1, multiPoint2);
// 结果:(0, 0) 和 (20, 20),排除了共同点 (10, 10)

if (symDiff3 is MultiPoint result)
{
    Console.WriteLine($"对称差点数:{result.Count}");  // 2
    foreach (var p in result.GetPoints())
    {
        Console.WriteLine($"  点:({p.X}, {p.Y})");
    }
}

6.5.4 实现原理

public Geometry Execute(Geometry geometry1, Geometry geometry2, 
                       SpatialReference? spatialReference = null)
{
    // 空几何处理
    if (geometry1.IsEmpty && geometry2.IsEmpty)
        return new Point(double.NaN, double.NaN);
    if (geometry1.IsEmpty)
        return geometry2;
    if (geometry2.IsEmpty)
        return geometry1;

    // Point △ Point
    if (geometry1 is Point p1 && geometry2 is Point p2)
    {
        if (EqualsOperator.Instance.Execute(p1, p2))
            return new Point(double.NaN, double.NaN);  // 相同点,对称差为空
        
        var mp = new MultiPoint();
        mp.Add(p1);
        mp.Add(p2);
        return mp;
    }

    // MultiPoint △ MultiPoint
    if (geometry1 is MultiPoint mp1 && geometry2 is MultiPoint mp2)
    {
        var result = new MultiPoint();
        
        // 添加 mp1 中不在 mp2 中的点
        foreach (var p in mp1.GetPoints())
        {
            bool found = false;
            foreach (var p2Point in mp2.GetPoints())
            {
                if (EqualsOperator.Instance.Execute(p, p2Point))
                {
                    found = true;
                    break;
                }
            }
            if (!found)
                result.Add(p);
        }
        
        // 添加 mp2 中不在 mp1 中的点
        foreach (var p in mp2.GetPoints())
        {
            bool found = false;
            foreach (var p1Point in mp1.GetPoints())
            {
                if (EqualsOperator.Instance.Execute(p, p1Point))
                {
                    found = true;
                    break;
                }
            }
            if (!found)
                result.Add(p);
        }
        
        if (result.Count == 0)
            return new Point(double.NaN, double.NaN);
        if (result.Count == 1)
            return result.GetPoint(0);
        return result;
    }

    // 对于其他复杂情况:使用 (A - B) ∪ (B - A)
    var diffAB = DifferenceOperator.Instance.Execute(geometry1, geometry2);
    var diffBA = DifferenceOperator.Instance.Execute(geometry2, geometry1);
    return UnionOperator.Instance.Execute(diffAB, diffBA);
}

6.5.5 应用场景

// 场景:找出两个数据集之间的差异
var dataset1 = new MultiPoint();
dataset1.Add(new Point(1, 1));
dataset1.Add(new Point(2, 2));
dataset1.Add(new Point(3, 3));

var dataset2 = new MultiPoint();
dataset2.Add(new Point(2, 2));
dataset2.Add(new Point(3, 3));
dataset2.Add(new Point(4, 4));

var differences = GeometryEngine.SymmetricDifference(dataset1, dataset2);
// 结果包含 (1, 1) 和 (4, 4) - 只在一个数据集中存在的点

Console.WriteLine("两个数据集的差异:");
if (differences is MultiPoint diffPoints)
{
    foreach (var p in diffPoints.GetPoints())
    {
        Console.WriteLine($"  ({p.X}, {p.Y})");
    }
}

6.6 集合操作的关系

6.6.1 数学恒等式

// 并集的交换律
Union(A, B) = Union(B, A)

// 交集的交换律
Intersection(A, B) = Intersection(B, A)

// 对称差的交换律
SymmetricDifference(A, B) = SymmetricDifference(B, A)

// 差集的非交换性
Difference(A, B) ≠ Difference(B, A)  // 通常情况

// 对称差与差集的关系
SymmetricDifference(A, B) = Union(Difference(A, B), Difference(B, A))

// 德摩根律
Difference(A, Union(B, C)) = Intersection(Difference(A, B), Difference(A, C))
Difference(A, Intersection(B, C)) = Union(Difference(A, B), Difference(A, C))

6.6.2 代码验证

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;

var env1 = new Envelope(0, 0, 50, 50);
var env2 = new Envelope(25, 25, 75, 75);

// 验证交换律
var union1 = GeometryEngine.Union(env1, env2);
var union2 = GeometryEngine.Union(env2, env1);
bool unionCommutative = GeometryEngine.Equals(union1, union2);
Console.WriteLine($"并集满足交换律:{unionCommutative}");  // true

var inter1 = GeometryEngine.Intersection(env1, env2);
var inter2 = GeometryEngine.Intersection(env2, env1);
bool interCommutative = GeometryEngine.Equals(inter1, inter2);
Console.WriteLine($"交集满足交换律:{interCommutative}");  // true

// 验证对称差公式
var symDiff = GeometryEngine.SymmetricDifference(env1, env2);
var diffAB = GeometryEngine.Difference(env1, env2);
var diffBA = GeometryEngine.Difference(env2, env1);
var symDiffAlt = GeometryEngine.Union(diffAB, diffBA);
// 注意:对于复杂几何,需要更高级的比较

6.7 性能考虑

6.7.1 复杂度分析

操作 简单情况复杂度 复杂情况复杂度
Union O(1) 包络 O(n + m) 多边形
Intersection O(1) 包络 O(n × m) 多边形
Difference O(n) 点集 O(n × m) 多边形
SymmetricDifference O(n × m) 点集 O(n × m) 多边形

其中 n 和 m 是两个几何对象的顶点数。

6.7.2 优化建议

// 1. 先用包络矩形快速过滤
if (!env1.Intersects(env2))
{
    // 不相交,Union = 两者都保留
    // Intersection = 空
    // Difference(A, B) = A
}

// 2. 对于大量几何对象的并集,使用迭代
var allEnvelopes = new List<Envelope> { /* 大量包络 */ };
Geometry combined = allEnvelopes[0];
for (int i = 1; i < allEnvelopes.Count; i++)
{
    combined = GeometryEngine.Union(combined, allEnvelopes[i]);
}

// 3. 批量操作时缓存中间结果
var cache = new Dictionary<(int, int), Geometry>();

6.8 实际应用案例

6.8.1 案例:区域合并

// 场景:将相邻的配送区域合并
var zone1 = new Polygon();
zone1.AddRing(new List<Point>
{
    new Point(0, 0),
    new Point(50, 0),
    new Point(50, 50),
    new Point(0, 50),
    new Point(0, 0)
});

var zone2 = new Polygon();
zone2.AddRing(new List<Point>
{
    new Point(50, 0),
    new Point(100, 0),
    new Point(100, 50),
    new Point(50, 50),
    new Point(50, 0)
});

var mergedZone = GeometryEngine.Union(zone1, zone2);
Console.WriteLine($"合并后区域类型:{mergedZone.Type}");

// 计算合并后的总面积
var mergedEnvelope = mergedZone.GetEnvelope();
Console.WriteLine($"合并后范围:{mergedEnvelope.Width} x {mergedEnvelope.Height}");

6.8.2 案例:区域重叠分析

// 场景:计算两个服务区域的重叠部分
var provider1 = new Envelope(0, 0, 100, 100);
var provider2 = new Envelope(50, 50, 150, 150);

var overlap = GeometryEngine.Intersection(provider1, provider2);

if (!overlap.IsEmpty && overlap is Envelope overlapEnv)
{
    double overlapArea = overlapEnv.Area;
    double totalArea = provider1.Area + provider2.Area - overlapArea;
    double overlapRatio = overlapArea / totalArea;
    
    Console.WriteLine($"重叠区域面积:{overlapArea}");
    Console.WriteLine($"总覆盖面积:{totalArea}");
    Console.WriteLine($"重叠比例:{overlapRatio:P2}");
}

6.8.3 案例:排除区域

// 场景:从服务区域中排除禁止区域
var serviceArea = new Envelope(0, 0, 100, 100);
var noServiceZone = new Envelope(40, 40, 60, 60);

// 计算可服务区域(需要高级多边形处理)
var exclusiveArea = GeometryEngine.Difference(serviceArea, noServiceZone);

// 对于当前简化实现,可以使用多个子区域
Console.WriteLine("注意:复杂的差集操作需要更高级的多边形裁剪算法");

6.9 小结

本章详细介绍了 geometry-api-net 的四种集合操作符:

  1. Union(并集):合并两个几何对象的所有点
  2. Intersection(交集):获取两个几何对象的共同点
  3. Difference(差集):获取第一个几何对象中不属于第二个的点
  4. SymmetricDifference(对称差):获取只属于一个几何对象的点

这些操作符在空间分析中非常重要,常用于:

  • 区域合并和分割
  • 重叠分析
  • 数据差异比较
  • 空间数据过滤

当前实现针对简单几何类型(Point、MultiPoint、Envelope)提供了完整支持,对于复杂多边形操作使用包络近似。

在下一章中,我们将学习数据格式的导入导出,了解如何在不同格式之间转换几何数据。

posted @ 2025-12-03 16:29  我才是银古  阅读(5)  评论(0)    收藏  举报