Gis 点空间:将多边形要素转换为System.Drawing.Region

Gis 点空间:将多边形要素转换为System.Drawing.Region,gis,polygon,point-in-polygon,dotspatial,Gis,Polygon,Point In Polygon,Dotspatial,我想用颜色绘制多边形区域 我知道我可以使用symboler来实现这一点,但我希望该区域闪烁(在计时器中更改其颜色),而使用symboler似乎很慢 我已经在使用Map.OnPaint事件绘制点的彩色图像(在PointLayer中) 那么,如何将多边形特征(在PolygonLayer中)转换为System.Drawing.Region,以便使用Graphics类中的方法绘制该区域 提前感谢。这里是一个演示。这是特定于多边形的,但应该可以让您了解如何将多边形转换为GraphicsPath,然后可以使

我想用颜色绘制多边形区域

我知道我可以使用
symboler
来实现这一点,但我希望该区域闪烁(在计时器中更改其颜色),而使用
symboler
似乎很慢

我已经在使用
Map.OnPaint
事件绘制点的彩色图像(在
PointLayer
中)

那么,如何将多边形特征(在
PolygonLayer
中)转换为
System.Drawing.Region
,以便使用Graphics类中的方法绘制该区域


提前感谢。

这里是一个演示。这是特定于多边形的,但应该可以让您了解如何将多边形转换为GraphicsPath,然后可以使用图形对象上选择的笔刷/笔进行填充或绘制。这只在一个相对简单的形状上进行了测试,但它使用了与MapPolygonLayer基本相同的绘图代码,因此它应该非常准确。如果处于编辑模式,则可能希望直接从特征获取顶点,而不是按照我获取顶点的方式

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// Timer for controlling flashing
        /// </summary>
        Timer timer1;

        /// <summary>
        /// True if the timer is actively flashing
        /// </summary>
        private bool timerEnabled;

        /// <summary>
        /// True if the 0 index shape should be colored yellow
        /// </summary>
        private bool highlighted;

        /// <summary>
        /// The layer with the polygon you wish to show flashing
        /// </summary>
        IMapFeatureLayer layer;

        /// <summary>
        /// Form constructor, initialize timer and paint event handler
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            map1.Paint += map1_Paint;
            timer1 = new Timer();
            timer1.Interval = 1000;
            timer1.Tick += timer1_Tick;
        }

        /// <summary>
        /// Occurs when the timer ticks.  This changes the highlighting and forces the map to refresh itself.  This will not
        /// redraw all the other features, since those are cached.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void timer1_Tick(object sender, EventArgs e)
        {
            highlighted = !highlighted;
            map1.Invalidate();
        }

        /// <summary>
        /// Occurs when the map is painting.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void map1_Paint(object sender, PaintEventArgs e)
        {
            MapPolygonLayer pg = layer as MapPolygonLayer;

            // If the shape is highlighted, draw it here.
            if (pg != null && highlighted)
            {
                System.Drawing.Drawing2D.GraphicsPath borderPath = PolygonToGraphicsPath(e, pg, 0);
                e.Graphics.FillPath(Brushes.Yellow, borderPath);
                e.Graphics.DrawPath(Pens.Cyan, borderPath);
            }
        }

        /// <summary>
        /// Converts the polygon at index into a new shape.
        /// </summary>
        /// <param name="e">The paint event arguments from the paint event.</param>
        /// <param name="pg">The polygon layer</param>
        /// <param name="index">The integer zero based index of the shape to get</param>
        /// <returns></returns>
        private System.Drawing.Drawing2D.GraphicsPath PolygonToGraphicsPath(PaintEventArgs e, MapPolygonLayer pg, int index)
        {
            System.Drawing.Drawing2D.GraphicsPath borderPath = new System.Drawing.Drawing2D.GraphicsPath();

            // This controls the relationship between pixel and map coordinates
            MapArgs args = new MapArgs(map1.ClientRectangle, map1.PixelToProj(map1.ClientRectangle), e.Graphics);

            // These variables help define the offsets necessary for drawing from the args.
            double minX = args.MinX;
            double maxY = args.MaxY;
            double dx = args.Dx;
            double dy = args.Dy;

            // SoutherlandHodgman clipping is about preventing exceptions from points outside the bounds, while still keeping
            // the geometry the same inside the bounds.
            SoutherlandHodgman shClip = new SoutherlandHodgman(map1.ClientRectangle);
            ShapeRange shpx = pg.DataSet.ShapeIndices[index];

            // interleaved x/y values of all the shapes on the layer.
            double[] vertices = pg.DataSet.Vertex;
            for (int prt = 0; prt < shpx.Parts.Count; prt++)
            {
                PartRange prtx = shpx.Parts[prt];
                int start = prtx.StartIndex;
                int end = prtx.EndIndex;
                List<double[]> points = new List<double[]>();

                for (int i = start; i <= end; i++)
                {
                    double[] pt = new double[2];
                    pt[0] = (vertices[i * 2] - minX) * dx;
                    pt[1] = (maxY - vertices[i * 2 + 1]) * dy;
                    points.Add(pt);
                }
                // Actually do the SoutherlandHodgman clipping
                if (shClip != null)
                {
                    points = shClip.Clip(points);
                }
                // Prevent a lot of unnecessary drawing of duplicate pixels when zoomed out.
                List<Point> intPoints = DuplicationPreventer.Clean(points);
                if (intPoints.Count < 2)
                {
                    continue;
                }

                borderPath.StartFigure();
                Point[] pointArray = intPoints.ToArray();
                borderPath.AddLines(pointArray);
            }
            return borderPath;
        }

        /// <summary>
        /// When the first button is clicked, this will prompt the user to open a shapefile, and add it to the map.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            layer = map1.AddFeatureLayer();

        }

        /// <summary>
        /// when the second button is clicked the feature should start flashing.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (timerEnabled)
            {
                timer1.Stop();
                timerEnabled = false;
            }
            else
            {
                timer1.Start();
                timerEnabled = true;
            }

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用DotSpatial.Controls;
使用DotSpatial.Data;
使用DotSpatial.Symbology;
命名空间Windows窗体应用程序3
{
公共部分类Form1:Form
{
/// 
///控制闪光的定时器
/// 
定时器1;
/// 
///如果计时器正在积极闪烁,则为True
/// 
私家侦探小说;
/// 
///如果0索引形状应为黄色,则为True
/// 
强调私人布尔;
/// 
///要显示多边形的图层正在闪烁
/// 
IMapFeatureLayer层;
/// 
///窗体构造函数、初始化计时器和绘制事件处理程序
/// 
公共表格1()
{
初始化组件();
map1.Paint+=map1\U Paint;
timer1=新定时器();
计时器1。间隔=1000;
timer1.Tick+=timer1\u Tick;
}
/// 
///在计时器计时时发生。这会更改高亮显示并强制贴图刷新自身。这不会
///重新绘制所有其他功能,因为它们是缓存的。
/// 
/// 
/// 
无效计时器1_刻度(对象发送方,事件参数e)
{
突出显示=!突出显示;
map1.Invalidate();
}
/// 
///在绘制贴图时发生。
/// 
/// 
/// 
void map1_Paint(对象发送器,PaintEventArgs e)
{
MapPolygonLayer pg=作为MapPolygonLayer的图层;
//如果形状高亮显示,请在此处绘制。
if(pg!=null&突出显示)
{
System.Drawing.Drawing2D.GraphicsPath borderPath=多边形地形图(e,pg,0);
e、 图形。填充路径(画笔。黄色,边界路径);
e、 图形.绘图路径(Pens.Cyan,borderPath);
}
}
/// 
///将索引处的多边形转换为新形状。
/// 
///来自绘制事件的绘制事件参数。
///多边形层
///要获取的形状的从零开始的整数索引
/// 
private System.Drawing.Drawing2D.GraphicsPath PolygonToGraphicsPath(PaintEventArgs e、MapPolygonLayer pg、int index)
{
System.Drawing.Drawing2D.GraphicsPath borderPath=新的System.Drawing.Drawing2D.GraphicsPath();
//这将控制像素和贴图坐标之间的关系
MapArgs args=新的MapArgs(map1.ClientRectangle,map1.PixelToProj(map1.ClientRectangle),e.Graphics);
//这些变量有助于定义从参数绘图所需的偏移。
double minX=args.minX;
double maxY=args.maxY;
双dx=args.dx;
双dy=args.dy;
//SoutherlandHodgman裁剪是为了防止边界外的点出现异常,同时保持
//几何图形在边界内是相同的。
SoutherlandHodgman shClip=新的SoutherlandHodgman(map1.ClientRectangle);
ShapeRange shpx=pg.DataSet.ShapeIndices[index];
//层上所有形状的交错x/y值。
双[]顶点=pg.DataSet.Vertex;
对于(int-prt=0;prt对于(int i=start;i这里是一个演示。这是一个特定于多边形的演示,但应该可以让您了解如何将多边形转换为图形SPATH,然后您可以使用图形对象上选择的笔刷/笔进行填充或绘制。这只在相对简单的形状上进行了测试,但它使用的绘图代码与t基本相同他是MapPolygonLayer,所以应该非常准确。如果您处于编辑模式,您可能希望直接从功能中获取顶点,而不是按照我获取顶点的方式

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// Timer for controlling flashing
        /// </summary>
        Timer timer1;

        /// <summary>
        /// True if the timer is actively flashing
        /// </summary>
        private bool timerEnabled;

        /// <summary>
        /// True if the 0 index shape should be colored yellow
        /// </summary>
        private bool highlighted;

        /// <summary>
        /// The layer with the polygon you wish to show flashing
        /// </summary>
        IMapFeatureLayer layer;

        /// <summary>
        /// Form constructor, initialize timer and paint event handler
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            map1.Paint += map1_Paint;
            timer1 = new Timer();
            timer1.Interval = 1000;
            timer1.Tick += timer1_Tick;
        }

        /// <summary>
        /// Occurs when the timer ticks.  This changes the highlighting and forces the map to refresh itself.  This will not
        /// redraw all the other features, since those are cached.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void timer1_Tick(object sender, EventArgs e)
        {
            highlighted = !highlighted;
            map1.Invalidate();
        }

        /// <summary>
        /// Occurs when the map is painting.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void map1_Paint(object sender, PaintEventArgs e)
        {
            MapPolygonLayer pg = layer as MapPolygonLayer;

            // If the shape is highlighted, draw it here.
            if (pg != null && highlighted)
            {
                System.Drawing.Drawing2D.GraphicsPath borderPath = PolygonToGraphicsPath(e, pg, 0);
                e.Graphics.FillPath(Brushes.Yellow, borderPath);
                e.Graphics.DrawPath(Pens.Cyan, borderPath);
            }
        }

        /// <summary>
        /// Converts the polygon at index into a new shape.
        /// </summary>
        /// <param name="e">The paint event arguments from the paint event.</param>
        /// <param name="pg">The polygon layer</param>
        /// <param name="index">The integer zero based index of the shape to get</param>
        /// <returns></returns>
        private System.Drawing.Drawing2D.GraphicsPath PolygonToGraphicsPath(PaintEventArgs e, MapPolygonLayer pg, int index)
        {
            System.Drawing.Drawing2D.GraphicsPath borderPath = new System.Drawing.Drawing2D.GraphicsPath();

            // This controls the relationship between pixel and map coordinates
            MapArgs args = new MapArgs(map1.ClientRectangle, map1.PixelToProj(map1.ClientRectangle), e.Graphics);

            // These variables help define the offsets necessary for drawing from the args.
            double minX = args.MinX;
            double maxY = args.MaxY;
            double dx = args.Dx;
            double dy = args.Dy;

            // SoutherlandHodgman clipping is about preventing exceptions from points outside the bounds, while still keeping
            // the geometry the same inside the bounds.
            SoutherlandHodgman shClip = new SoutherlandHodgman(map1.ClientRectangle);
            ShapeRange shpx = pg.DataSet.ShapeIndices[index];

            // interleaved x/y values of all the shapes on the layer.
            double[] vertices = pg.DataSet.Vertex;
            for (int prt = 0; prt < shpx.Parts.Count; prt++)
            {
                PartRange prtx = shpx.Parts[prt];
                int start = prtx.StartIndex;
                int end = prtx.EndIndex;
                List<double[]> points = new List<double[]>();

                for (int i = start; i <= end; i++)
                {
                    double[] pt = new double[2];
                    pt[0] = (vertices[i * 2] - minX) * dx;
                    pt[1] = (maxY - vertices[i * 2 + 1]) * dy;
                    points.Add(pt);
                }
                // Actually do the SoutherlandHodgman clipping
                if (shClip != null)
                {
                    points = shClip.Clip(points);
                }
                // Prevent a lot of unnecessary drawing of duplicate pixels when zoomed out.
                List<Point> intPoints = DuplicationPreventer.Clean(points);
                if (intPoints.Count < 2)
                {
                    continue;
                }

                borderPath.StartFigure();
                Point[] pointArray = intPoints.ToArray();
                borderPath.AddLines(pointArray);
            }
            return borderPath;
        }

        /// <summary>
        /// When the first button is clicked, this will prompt the user to open a shapefile, and add it to the map.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            layer = map1.AddFeatureLayer();

        }

        /// <summary>
        /// when the second button is clicked the feature should start flashing.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (timerEnabled)
            {
                timer1.Stop();
                timerEnabled = false;
            }
            else
            {
                timer1.Start();
                timerEnabled = true;
            }

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用DotSpatial.Controls;
使用DotSpatial.Data;
使用DotSpatial.Symbology;
命名空间Windows窗体应用程序3
{
公共部分类Form1:Form
{
/// 
///控制闪光的定时器
/// 
定时器1;
/// 
///如果计时器正在积极闪烁,则为True
/// 
普里夫