如何使用WinMapGIS或DotSpace库在地图窗口中过滤出一些形状
本文关键字:过滤 窗口 地图 WinMapGIS 何使用 DotSpace | 更新日期: 2023-09-27 18:24:50
我有加州所有道路的大街道形状文件。每当我制作地图窗口来重新绘制地图(放大、缩小、移动地图…)时,都需要很长时间。我想知道是否有任何方法可以告诉地图窗口根据特定的范围只渲染特定数量的街道。这样我就可以提高应用程序的整体性能。如有任何帮助,我们将不胜感激。
Vu-Tran,
像DotSpace这样的地图应用程序将尝试在屏幕上为加载的形状文件渲染所有向量。他们不会试图画出任何不在当前范围内的线。但当你缩小时,他们会试图准确地画出所有的线,这很慢。一种可能有帮助的策略是设置可见性比例,使您只在放大时绘制图层。DotSpace中的layer类允许您设置图层的动态可见性,使您仅在放大超过某个点时绘制完整的shapefile。
myLayer.UseDynamicVisiblity = true;
myLayer.DynamicVisibilityMode = DynamicVisibilityMode.ZoomedIn;
myLayer.DynamicVisibiltyWidth = .2; // eg. .2 degrees of longitude in WGS84
这种策略唯一不利的一面是,在放大到指定范围之前,你根本看不到任何道路。因此,一种选择是创建一个低分辨率版本的道路形状,当你缩小时看起来不错,但对于更大的网格大小,它不包含任何"重复"点。您可以通过使用另一个线形文件或创建图像或创建图像平铺来完成此操作。下面的第一个示例使用1000 x 1000的网格大小,以便将冗余点减少到最小表示。使用不同网格大小和动态可见性的组合,您应该能够更有效地渲染大型线形文件。光栅通常有概览,但矢量通常没有,因此这是为矢量创建人工概览的一种方法。第二个示例将使用DP线简化,它保留了所有形状,但使用较少的点来表示每个形状。
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.Data;
using DotSpatial.Projections;
using DotSpatial.Topology;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Shapefile source = new Shapefile();
source = Shapefile.OpenFile(@"C:'Data'Rivers'River.shp");
bool[,] pointRepresented = new bool[1000, 1000];
double width = source.Extent.Width;
double height = source.Extent.Height;
double dx = width / 1000;
double dy = height / 1000;
FeatureSet result = new FeatureSet(FeatureType.Line);
result.Projection = KnownCoordinateSystems.Geographic.World.WGS1984; // lat lon in WGS84
result.DataTable.Columns.Add("Index", typeof(int));
int index = 0;
foreach (ShapeRange shape in source.ShapeIndices) {
bool started = false;
List<LineString> linestrings = new List<LineString>();
foreach (PartRange part in shape.Parts) {
List<Coordinate> coords = new List<Coordinate>();
foreach (Vertex vert in part) {
int i = (int)((vert.X - source.Extent.MinX) / dx);
int j = (int)((vert.Y - source.Extent.MinY) / dy);
if (i > 999) {
i = 999;
}
if (j > 999) {
j = 999;
}
if (pointRepresented[i, j] == true) continue;
coords.Add(new Coordinate(vert.X, vert.Y));
pointRepresented[i, j] = true;
}
if (coords.Count > 0) {
if (coords.Count == 1) {
coords.Add(coords[0]); // add a duplicate "endpoint" to the line if we only have one point.
}
linestrings.Add(new LineString(coords));
}
}
if (linestrings.Count > 0) {
IFeature feature;
if (linestrings.Count > 1)
{
feature = result.AddFeature(new MultiLineString(linestrings));
}
else {
feature = result.AddFeature(linestrings[0]);
}
feature.DataRow["Index"] = index;
index++;
}
result.SaveAs(@"C:'Data'Rivers'RiverPreview.shp", true);
}
MessageBox.Show(@"Finished creating file: C:'Data'Rivers'RiverPreview.shp");
}
}
}
第二种方法使用DP线简化,不会删除形状,只是简单地减少了用于表示每个形状的点的数量。必须调整公差以匹配您的数据集和坐标。
/// <summary>
/// This alternative uses DP line simplification, which keeps every shape, but "simplifies" the shape, simply reducing
/// the number of points. This will not accomplish the goal of reducing the number of shapes, but will
/// give you a reduced representation that matches the original features in cases where slowness is caused
/// by too much detail, which can be useful if you still want to keep all your features.
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
Shapefile source = new Shapefile();
source = Shapefile.OpenFile(@"C:'Data'Rivers'River.shp");
FeatureSet result = new FeatureSet(FeatureType.Line);
result.Projection = source.Projection;
result.CopyTableSchema(source);
foreach (IFeature feature in source.Features) {
LineString linestring = feature.BasicGeometry as LineString;
if (linestring != null)
{
IList<Coordinate> points = linestring.Coordinates;
IList<Coordinate> simplified = DouglasPeuckerLineSimplifier.Simplify(points, .00002);
IFeature resultFeature = result.AddFeature(new LineString(simplified));
resultFeature.CopyAttributes(feature);
}
else {
MultiLineString multipleLines = feature.BasicGeometry as MultiLineString;
if (multipleLines != null)
{
List<LineString> resultLines = new List<LineString>();
foreach (IGeometry line in multipleLines.Geometries)
{
IList<Coordinate> points = line.Coordinates;
IList<Coordinate> simplified = DouglasPeuckerLineSimplifier.Simplify(points, .00002);
resultLines.Add(new LineString(simplified));
}
IFeature resultFeature = result.AddFeature(new MultiLineString(resultLines));
resultFeature.CopyAttributes(feature);
}
}
}
result.SaveAs(@"C:'Data'Rivers'RiverSimplified.shp", true);
MessageBox.Show(@"Finished creating file: C:'Data'Rivers'RiverSimplified.shp");
}