Winform/Csharp中筛选/过滤/判断点是否在面(区域)内-通过Where和Region

发布时间 2023-03-25 11:11:46作者: 霸道流氓

场景

在Redis中存储一些坐标数据,需要遍历这些坐标数据筛选出在某个区域范围内的坐标数据。

System.Drawing.Region类

https://learn.microsoft.com/zh-cn/dotnet/api/system.drawing.region?view=dotnet-plat-ext-7.0

官方示例代码:

private void DemonstrateRegionData2(PaintEventArgs e)
{

    //Create a simple region.
    Region region1 = new Region(new Rectangle(10, 10, 100, 100));

    // Extract the region data.
    System.Drawing.Drawing2D.RegionData region1Data = region1.GetRegionData();
    byte[] data1;
    data1 = region1Data.Data;

    // Create a second region.
    Region region2 = new Region();

    // Get the region data for the second region.
    System.Drawing.Drawing2D.RegionData region2Data = region2.GetRegionData();

    // Set the Data property for the second region to the Data from the first region.
    region2Data.Data = data1;

    // Construct a third region using the modified RegionData of the second region.
    Region region3 = new Region(region2Data);

    // Dispose of the first and second regions.
    region1.Dispose();
    region2.Dispose();

    // Call ExcludeClip passing in the third region.
    e.Graphics.ExcludeClip(region3);

    // Fill in the client rectangle.
    e.Graphics.FillRectangle(Brushes.Red, this.ClientRectangle);

    region3.Dispose();
}

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

1、查看官方文档,有个属性

IsVisible(PointF) 
测试指定 PointF 结构是否包含在此 Region 中。

 

 

可以利用该属性实现

2、新建一个工具类方法

    public class GisHelper
    {
        public static bool isPointInPolygon(PointF point ,PointF[] points) {
            GraphicsPath myGraphicsPath = new GraphicsPath();
            Region myRegion = new Region();
            myGraphicsPath.Reset();
            myGraphicsPath.AddPolygon(points);
            myRegion.MakeEmpty();
            myRegion.Union(myGraphicsPath);
            //返回判断点是否在多边形里
            bool result = myRegion.IsVisible(point);
            return result;
        }
    }

3、筛选方法实现以及判断方法调用

                List<RedisKey> keyList  = keys.Where(key =>
                    {
                        CarVo car = redis.StringGet<CarVo>(key);
                        PointF point = new PointF(Convert.ToSingle(car.x), Convert.ToSingle(car.y));
                        bool result = GisHelper.isPointInPolygon(point, waitingRoomPoints);
                        return result;
                    }
                ).ToList();

其中waitingRoomPoints是固定的区域数据的Point的数组

        private PointF[] waitingRoomPoints = new PointF[5] {
                new PointF((float)36582813.46296957, (float)4259626.142283574),
                new PointF((float)36582853.489937834, (float)4259649.775375716),
                new PointF((float)36582858.70959735, (float)4259640.848999171),
                new PointF((float)36582818.38044125, (float)4259617.616121467),
                new PointF((float)36582813.46296957, (float)4259626.142283574),
            };