|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
|
using System.Data;
|
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Numerics;
|
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
using NaturalNeighbor;
|
|
|
|
|
|
|
|
|
|
|
|
namespace TestNeighborInterpolator
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class Form1 : Form
|
|
|
|
|
|
{
|
|
|
|
|
|
public Form1()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行计算.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">The source of the event.</param>
|
|
|
|
|
|
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
|
|
|
|
|
private void btnOK_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
string strFile = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300).csv";
|
|
|
|
|
|
string strResult = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300)-Result.csv";
|
|
|
|
|
|
IEnumerable<Vector3> points = this.ReadData(strFile);
|
|
|
|
|
|
Interpolator2d interpolator = Interpolator2d.Create(points.ToArray(), 0.5);
|
|
|
|
|
|
Vector2 minLoc = interpolator.MinValue.Value;
|
|
|
|
|
|
Vector2 maxLoc = interpolator.MaxValue.Value;
|
|
|
|
|
|
|
|
|
|
|
|
double dWidth = maxLoc.X - minLoc.X;
|
|
|
|
|
|
double dHeight = maxLoc.Y - minLoc.Y;
|
|
|
|
|
|
int nCols = 200;
|
|
|
|
|
|
int nRows = 200;
|
|
|
|
|
|
double scaleX = dWidth / (nCols - 1);
|
|
|
|
|
|
double scaleY = dHeight / (nRows - 1);
|
|
|
|
|
|
float dScale = (float)Math.Min(scaleX, scaleY);
|
|
|
|
|
|
|
|
|
|
|
|
int nCalCols = (int)Math.Floor(dWidth / dScale);
|
|
|
|
|
|
int nCalRows = (int)Math.Floor(dHeight / dScale);
|
|
|
|
|
|
Vector2[] result = new Vector2[nCalRows * nCalCols];
|
|
|
|
|
|
for (int i = 0; i < nCalRows; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
var x = minLoc.X + i * dScale;
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < nCalCols; ++j)
|
|
|
|
|
|
{
|
|
|
|
|
|
var y = minLoc.Y + j * dScale;
|
|
|
|
|
|
result[i * nCalCols + j] = new Vector2(x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
double[] resultZ = new double[nCalRows * nCalCols];
|
|
|
|
|
|
interpolator.LookupRange(result, resultZ);
|
|
|
|
|
|
using (StreamWriter sw = new StreamWriter(strResult, false, Encoding.Default))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < nCalRows; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int j = 0; j < nCalCols; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
sw.WriteLine($"{result[i * nCalCols + j].X},{result[i * nCalCols + j].Y},{resultZ[i * nCalCols + j]}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
MessageBox.Show("OK");
|
|
|
|
|
|
//string strFile = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300).csv";
|
|
|
|
|
|
//string strResult = "C:\\GeoIntelligent\\Test\\厚度图数据\\39SO(300)-Result.csv";
|
|
|
|
|
|
//IEnumerable<Vector3> points = this.ReadData(strFile);
|
|
|
|
|
|
|
|
|
|
|
|
//Vector3 rangeMin = new Vector3();
|
|
|
|
|
|
//Vector3 rangeMax = new Vector3();
|
|
|
|
|
|
////this.CalculateRange(points.ToArray(), ref rangeMin, ref rangeMax);
|
|
|
|
|
|
|
|
|
|
|
|
//Interpolator2d interpolator = Interpolator2d.Create(points.ToArray(), 0.5);
|
|
|
|
|
|
//Vector2 minLoc = interpolator.MinValue.Value;
|
|
|
|
|
|
//Vector2 maxLoc = interpolator.MaxValue.Value;
|
|
|
|
|
|
|
|
|
|
|
|
//double dWidth = maxLoc.X - minLoc.X;
|
|
|
|
|
|
//double dHeight = maxLoc.Y - minLoc.Y;
|
|
|
|
|
|
//int nCols = 200;
|
|
|
|
|
|
//int nRows = 200;
|
|
|
|
|
|
//double scaleX = dWidth / (nCols - 1);
|
|
|
|
|
|
//double scaleY = dHeight / (nRows - 1);
|
|
|
|
|
|
//float dScale = (float)Math.Min(scaleX, scaleY);
|
|
|
|
|
|
|
|
|
|
|
|
//int nCalCols = (int)Math.Floor(dWidth / dScale);
|
|
|
|
|
|
//int nCalRows = (int)Math.Floor(dHeight / dScale);
|
|
|
|
|
|
//// 生成网格文件
|
|
|
|
|
|
//Vector2[] result = new Vector2[nCalRows * nCalCols];
|
|
|
|
|
|
//for (int i = 0; i < nCalCols; ++i)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// var x = minLoc.X + i * dScale;
|
|
|
|
|
|
// for (int j = 0; j < nCalRows; ++j)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// var y = minLoc.Y + j * dScale;
|
|
|
|
|
|
// result[i * nCalRows + j] = new Vector2(x, y);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
//double[] resultZ = new double[nCalRows * nCalCols];
|
|
|
|
|
|
//interpolator.LookupRange(result, resultZ);
|
|
|
|
|
|
|
|
|
|
|
|
//SetGridData(rangeMin.X, rangeMin.Y, resultZ, nCalCols, nCalRows, (double)dScale, (double)dScale
|
|
|
|
|
|
// , rangeMin.Z, rangeMax.Z, null, 0);
|
|
|
|
|
|
//DestoryXy();
|
|
|
|
|
|
///*
|
|
|
|
|
|
////using (StreamWriter sw = new StreamWriter(strResult, false, Encoding.Default))
|
|
|
|
|
|
////{
|
|
|
|
|
|
//// for (int i = 0; i < nCalRows; i++)
|
|
|
|
|
|
//// {
|
|
|
|
|
|
//// for (int j = 0; j < nCalCols; j++)
|
|
|
|
|
|
//// {
|
|
|
|
|
|
//// sw.WriteLine($"{result[i * nCalCols + j].X},{result[i * nCalCols + j].Y},{resultZ[i * nCalCols + j]}");
|
|
|
|
|
|
//// }
|
|
|
|
|
|
//// }
|
|
|
|
|
|
////}*/
|
|
|
|
|
|
//MessageBox.Show("OK");
|
|
|
|
|
|
}
|
|
|
|
|
|
private IEnumerable<Vector3> ReadData(string filename)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (StreamReader txt = new StreamReader(File.Open(filename, FileMode.Open)
|
|
|
|
|
|
, Encoding.Default))
|
|
|
|
|
|
{
|
|
|
|
|
|
txt.ReadLine(); // Skip columns
|
|
|
|
|
|
|
|
|
|
|
|
var s = txt.ReadLine();
|
|
|
|
|
|
while (s != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var parts = s.Split(',');
|
|
|
|
|
|
if (parts.Length == 3 &&
|
|
|
|
|
|
double.TryParse(parts[0], out var x) &&
|
|
|
|
|
|
double.TryParse(parts[1], out var y) &&
|
|
|
|
|
|
double.TryParse(parts[2], out var z))
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return new Vector3((float)x, (float)y, (float)z);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s = txt.ReadLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 窗口退出.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">The source of the event.</param>
|
|
|
|
|
|
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
|
|
|
|
|
private void btnQuit_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.DialogResult = DialogResult.Cancel;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 选择输入文件.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">The source of the event.</param>
|
|
|
|
|
|
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
|
|
|
|
|
private void btnFileInput_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
OpenFileDialog ofd = new OpenFileDialog();
|
|
|
|
|
|
ofd.Filter = "*.csv|*.csv|*.xyz|*.xyz|*.*|*.*||";
|
|
|
|
|
|
ofd.RestoreDirectory = true;
|
|
|
|
|
|
if(ofd.ShowDialog() == DialogResult.OK)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.txtInput.Text = ofd.FileName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 选择输出文件.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sender">The source of the event.</param>
|
|
|
|
|
|
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
|
|
|
|
|
private void btnFileOutput_Click(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveFileDialog sfd = new SaveFileDialog();
|
|
|
|
|
|
sfd.Filter = "*.dfd|*.dfd|*.pcg|*.pcg|*.*|*.*||";
|
|
|
|
|
|
sfd.RestoreDirectory = true;
|
|
|
|
|
|
sfd.OverwritePrompt = true;
|
|
|
|
|
|
if(sfd.ShowDialog() == DialogResult.OK)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.txtOutput.Text = sfd.FileName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void CalculateRange(IReadOnlyList<Vector3> points, ref Vector3 pointMin, ref Vector3 pointMax)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (points.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
pointMin = pointMax = Vector3.Zero;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float minX = float.MaxValue;
|
|
|
|
|
|
float minY = float.MaxValue;
|
|
|
|
|
|
float minZ = float.MaxValue;
|
|
|
|
|
|
|
|
|
|
|
|
float maxX = float.MinValue;
|
|
|
|
|
|
float maxY = float.MinValue;
|
|
|
|
|
|
float maxZ = float.MinValue;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < points.Count; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pt = points[i];
|
|
|
|
|
|
|
|
|
|
|
|
minX = Math.Min(minX, pt.X);
|
|
|
|
|
|
maxX = Math.Max(maxX, pt.X);
|
|
|
|
|
|
|
|
|
|
|
|
minY = Math.Min(minY, pt.Y);
|
|
|
|
|
|
maxY = Math.Max(maxY, pt.Y);
|
|
|
|
|
|
|
|
|
|
|
|
minZ = Math.Min(minZ, pt.Z);
|
|
|
|
|
|
maxZ = Math.Max(maxZ, pt.Z);
|
|
|
|
|
|
}
|
|
|
|
|
|
pointMin.X = minX;
|
|
|
|
|
|
pointMin.Y = minY;
|
|
|
|
|
|
pointMin.Z = minZ;
|
|
|
|
|
|
|
|
|
|
|
|
pointMax.X = maxX;
|
|
|
|
|
|
pointMax.Y = maxY;
|
|
|
|
|
|
pointMax.Z = maxZ;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
const string DLL_FILE = "GridUtility.dll";
|
|
|
|
|
|
#else
|
|
|
|
|
|
const string DLL_FILE = "GridUtility.dll";
|
|
|
|
|
|
#endif
|
|
|
|
|
|
[DllImport(DLL_FILE, EntryPoint = "SetGridData", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
|
|
public static extern void SetGridData(double xMin, double yMin, double[] pDataZ
|
|
|
|
|
|
, double nCols, int nRows, double dx, double dy
|
|
|
|
|
|
, double zMin, double zMax
|
|
|
|
|
|
, double[] borderData, int borderDataSize);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(DLL_FILE, EntryPoint = "Destroy", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
|
|
public static extern void DestoryXy();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|