GPS轨迹压缩之Douglas-Peucker算法之C# winform实现,代码包括导入.txt经度纬度数据,输出压缩后的文本
时间: 2024-02-19 21:03:40 浏览: 220
好的,这里为您提供一份C# Winform实现的GPS轨迹压缩代码,包括导入.txt经度纬度数据和输出压缩后的文本。代码如下:
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace DouglasPeuckerAlgorithm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnImport_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text Files (*.txt)|*.txt";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
List<Point> points = ReadPointsFromFile(filePath);
if (points != null && points.Count > 0)
{
double epsilon = 0.001; // 压缩精度
List<int> results = DouglasPeucker(points, 0, points.Count - 1, epsilon);
string outputText = string.Join("\r\n", results.Select(i => $"{points[i].X},{points[i].Y}"));
txtOutput.Text = outputText;
}
else
{
MessageBox.Show("无法读取数据", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private List<Point> ReadPointsFromFile(string filePath)
{
try
{
List<Point> points = new List<Point>();
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] values = line.Split(',');
if (values.Length == 2 && double.TryParse(values[0], out double x) && double.TryParse(values[1], out double y))
{
points.Add(new Point(x, y));
}
}
}
return points;
}
catch (Exception)
{
return null;
}
}
private List<int> DouglasPeucker(List<Point> points, int start, int end, double epsilon)
{
double dmax = 0;
int index = 0;
for (int i = start + 1; i < end; i++)
{
double d = PointToLineDistance(points[i], points[start], points[end]);
if (d > dmax)
{
dmax = d;
index = i;
}
}
List<int> results = new List<int>();
if (dmax > epsilon)
{
List<int> leftResults = DouglasPeucker(points, start, index, epsilon);
List<int> rightResults = DouglasPeucker(points, index, end, epsilon);
results = leftResults.Concat(rightResults.Skip(1)).ToList();
}
else
{
results.Add(start);
}
return results;
}
private double PointToLineDistance(Point p, Point p1, Point p2)
{
double dx = p2.X - p1.X;
double dy = p2.Y - p1.Y;
double d = dx * dx + dy * dy;
double u = ((p.X - p1.X) * dx + (p.Y - p1.Y) * dy) / d;
Point pt;
if (u < 0)
{
pt = p1;
}
else if (u > 1)
{
pt = p2;
}
else
{
pt = new Point(p1.X + u * dx, p1.Y + u * dy);
}
return Math.Sqrt((p.X - pt.X) * (p.X - pt.X) + (p.Y - pt.Y) * (p.Y - pt.Y));
}
private class Point
{
public double X { get; set; }
public double Y { get; set; }
public Point(double x, double y)
{
X = x;
Y = y;
}
}
}
}
```
需要注意的是,这份代码是基于C#的Winform框架实现的,需要在Visual Studio等开发环境中使用。在界面中,有一个导入按钮(btnImport)和一个输出文本框(txtOutput),通过点击导入按钮可以从.txt文件中读取经度纬度数据,然后进行轨迹压缩并输出到文本框中。在DouglasPeucker函数中,压缩精度epsilon可以根据实际需求进行调整。
阅读全文