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
///
普里夫