代码拉取完成,页面将自动刷新
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsForms;
using GMap.NET.WindowsForms.Markers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WherePoint
{
public partial class MainForm : Form
{
public readonly GMapOverlay _objects = new GMapOverlay("objects"); // 照片组
public readonly GMapOverlay _markers = new GMapOverlay("markers"); // 单张照片
public MainForm()
{
InitializeComponent();
InitGrid(); // 初始化表格
if (!GMapControl.IsDesignerHosted) {
// add your custom map db provider
//GMap.NET.CacheProviders.MySQLPureImageCache ch = new GMap.NET.CacheProviders.MySQLPureImageCache();
//ch.ConnectionString = @"server=sql2008;User Id=trolis;Persist Security Info=True;database=gmapnetcache;password=trolis;";
//MainMap.Manager.SecondaryCache = ch;
MainMap.ShowTileGridLines = false;
GMapProviders.GoogleSatelliteMap.TryCorrectVersion = false;
MainMap.MapProvider = GMapProviders.GoogleSatelliteMap; // 默认地图
MainMap.Position = new PointLatLng(24.355, 109.404); // 地图中心点(北京)GPS坐标
MainMap.MinZoom = GMapProviders.GoogleSatelliteMap.MinZoom; // 地图最小比例
MainMap.MaxZoom = GMapProviders.GoogleSatelliteMap.MaxZoom ?? 24; // 地图最大比例
MainMap.Zoom = 13; // 当前缩放等级
MainMap.DragButton = MouseButtons.Left; // 鼠标平移键
MainMap.MouseMove += MainMap_MouseMove;
MainMap.Overlays.Add(_objects);
MainMap.Overlays.Add(_markers);
}
}
/// <summary>
/// 初始化表格
/// </summary>
private void InitGrid()
{
outlookGridPoints.Columns.Add(new DataGridViewTextBoxColumn { Name = "TYPE", HeaderText = "类别", Visible = false });
outlookGridPoints.Columns.Add(new DataGridViewTextBoxColumn() { Name = "NAME", HeaderText = "名称" });
outlookGridPoints.Columns.Add(new DataGridViewTextBoxColumn() { Name = "FILE", HeaderText = "文件", Visible = false });
outlookGridPoints.Columns.Add(new DataGridViewTextBoxColumn() { Name = "COORDINATE", HeaderText = "坐标", Visible = false, ValueType = typeof(double[]) });
}
/// <summary>
/// 显示坐标
/// </summary>
private void MainMap_MouseMove(object sender, MouseEventArgs e)
{
PointLatLng pnew = MainMap.FromLocalToLatLng(e.X, e.Y);
toolStripStatusLabelInfo.Text = string.Format("经度:{0:0.000000} 纬度:{1:0.000000}", pnew.Lng, pnew.Lat);
}
/// <summary>
///
/// </summary>
/// <param name="path"></param>
private void OpenPath(string path)
{
DataTable table = MakeTable(path);
if (table.Rows.Count == 0) return;
DataSet dataset = new DataSet();
dataset.Tables.Add(table);
outlookGridPoints.BindData(dataset, table.TableName);
outlookGridPoints.GroupTemplate.Column = outlookGridPoints.Columns["TYPE"];
outlookGridPoints.Sort(new DataRowComparerEx(0, ListSortDirection.Ascending));
foreach (DataColumn col in table.Columns) {
outlookGridPoints.Columns[col.ColumnName].ValueType = col.DataType;
}
outlookGridPoints.Columns["TYPE"].Visible = false;
outlookGridPoints.Columns["NAME"].Visible = true;
outlookGridPoints.Columns["FILE"].Visible = false;
outlookGridPoints.Columns["COORDINATE"].Visible = false;
outlookGridPoints.Columns["TYPE"].HeaderText = "分类";
outlookGridPoints.Columns["NAME"].HeaderText = "名称";
}
/// <summary>
/// 解析目录数据
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private DataTable MakeTable(string path)
{
// 解析深度2级
DataTable result = new DataTable("照片");
result.Columns.Add("TYPE", typeof(string)); // 分类
result.Columns.Add("NAME", typeof(string)); // 文件名
result.Columns.Add("FILE", typeof(string)); // 文件
result.Columns.Add("COORDINATE", typeof(double[])); // 坐标
StreamWriter writer = new StreamWriter("POINTS.TXT", false);
int num = 0;
// 解析第一级
string[] rootfiles = System.IO.Directory.GetFiles(path, "*.jpg");
foreach (string file in rootfiles) {
double lat, lng;
bool success = GetData(file, out lat, out lng);
if (success == false) continue;
DataRow row = result.NewRow();
row["TYPE"] = "无分类";
row["NAME"] = System.IO.Path.GetFileNameWithoutExtension(file);
row["FILE"] = file;
row["COORDINATE"] = new double[] { lat, lng };
result.Rows.Add(row);
// 标记中心点
GMapMarker marker = new GMarkerGoogle(new PointLatLng(lat, lng), GMarkerGoogleType.lightblue);
marker.ToolTipMode = MarkerTooltipMode.Always;
marker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
marker.ToolTipText = System.IO.Path.GetFileNameWithoutExtension(file);
_objects.Markers.Add(marker);
writer.WriteLine("{0},{1:0.000000000000},{2:0.000000000000}", num++, lat, lng);
}
writer.Flush();
writer.Close();
// 解析第二级
string[] rootdirs = System.IO.Directory.GetDirectories(path);
//_objects.Markers.Clear();
foreach (string rootdir in rootdirs) {
string name = new System.IO.DirectoryInfo(rootdir).Name.ToUpper();
string[] files = System.IO.Directory.GetFiles(rootdir, "*.jpg");
List<double[]> points = new List<double[]>();
foreach (string file in files) {
double lat, lng;
bool success = GetData(file, out lat, out lng);
if (success == false) continue;
DataRow row = result.NewRow();
row["TYPE"] = name;
row["NAME"] = System.IO.Path.GetFileNameWithoutExtension(file);
row["FILE"] = file;
row["COORDINATE"] = new double[] { lat, lng };
result.Rows.Add(row);
points.Add(new double[] { lat, lng });
}
if (points.Count > 0) {
double[] centerpoint = GetCenterPoint(points); // 计算中心点
Console.Write("{0}\t{1:0.000000}\t{2:0.000000}\r\n", name, centerpoint[0], centerpoint[1]);
// 标记中心点
GMapMarker marker = new GMarkerGoogle(new PointLatLng(centerpoint[0], centerpoint[1]), GMarkerGoogleType.lightblue);
marker.ToolTipMode = MarkerTooltipMode.Always;
marker.ToolTipText = name;
_objects.Markers.Add(marker);
}
}
return result;
}
/// <summary>
/// 解析图片信息
/// </summary>
/// <param name="file"></param>
/// <param name="lat"></param>
/// <param name="lng"></param>
/// <returns></returns>
private bool GetData(string file, out double lat, out double lng)
{
try {
double[] lats, lngs;
using (ExifReader reader = new ExifReader(file)) {
bool success1 = reader.GetTagValue(ExifTags.GPSLatitude, out lats);
bool success2 = reader.GetTagValue(ExifTags.GPSLongitude, out lngs);
}
lat = lats[0] + lats[1] / 60.0 + lats[2] / 3600.0;
lng = lngs[0] + lngs[1] / 60.0 + lngs[2] / 3600.0;
//Bitmap img = (Bitmap)Bitmap.FromFile(file);
//using (ExifManager exifMan = new ExifManager(img)) {
// lat = exifMan.Latitude;
// lng = exifMan.Longitude;
//}
return true;
}
catch (Exception ex) { lat = lng = 0; return false; }
}
/// <summary>
/// 显示照片位置
/// </summary>
private void outlookGridPoints_SelectionChanged(object sender, EventArgs e)
{
//
_markers.Markers.Clear();
if (outlookGridPoints.SelectedRows.Count != 1) return;
string name = outlookGridPoints.SelectedRows[0].Cells["NAME"].Value as string;
if (name == null) return;
string type = outlookGridPoints.SelectedRows[0].Cells["TYPE"].Value as string;
string file = outlookGridPoints.SelectedRows[0].Cells["FILE"].Value as string;
double[] coordinate = (double[])outlookGridPoints.SelectedRows[0].Cells["COORDINATE"].Value;
if (coordinate == null || coordinate.Length != 2) return;
double lat = coordinate[0];
double lng = coordinate[1];
GMapMarker marker = new GMarkerGoogle(new PointLatLng(lat, lng), GMarkerGoogleType.pink);
marker.ToolTipMode = MarkerTooltipMode.Always;
marker.ToolTipText = string.IsNullOrEmpty(type) ? name : string.Format("({0}) {1}", type, name);
_markers.Markers.Add(marker);
pictureBoxPhoto.Image = null;
pictureBoxPhoto.ImageLocation = null;
if (System.IO.File.Exists(file)) pictureBoxPhoto.ImageLocation = file;
}
/// <summary>
/// 获取中心点
/// </summary>
/// <param name="points"></param>
/// <returns></returns>
private double[] GetCenterPoint(List<double[]> points)
{
// 判断有效点 距离在50M以内的都为有效点
bool[] flags = new bool[points.Count];
for (int m = 0; m < points.Count - 1; m++) {
for (int n = m + 1; n < points.Count; n++) {
double distance = GetDistance(points[m][1], points[m][0], points[n][1], points[n][0]);
if (distance <= 50) {
flags[m] = flags[n] = true;
break;
}
}
}
//
double lat = 0;
double lng = 0;
int count = 0;
for (int i = 0; i < points.Count; i++) {
if (flags[i] == false) continue;
lat += points[i][0];
lng += points[i][1];
count++;
}
if (count == 0) {
lat = points[0][0];
lng = points[0][1];
}
else {
lat = lat / (double)count;
lng = lng / (double)count;
}
return new double[] { lat, lng };
}
private const double EARTH_RADIUS = 6378137; // 赤道半径(单位m)
/// <summary>
/// 转化为弧度(rad)
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
private double rad(double d)
{
return d * Math.PI / 180.0;
}
#region 算法1
/// <summary>
/// 基于余弦定理求两经纬度距离
/// </summary>
/// <param name="lon1">第一点的经度</param>
/// <param name="lat1">第一点的纬度</param>
/// <param name="lon2">第二点的经度</param>
/// <param name="lat2">第二点的纬度</param>
/// <returns>返回的距离,单位km</returns>
private double LantitudeLongitudeDist(double lon1, double lat1, double lon2, double lat2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double radLon1 = rad(lon1);
double radLon2 = rad(lon2);
if (radLat1 < 0) radLat1 = Math.PI / 2 + Math.Abs(radLat1); // south
if (radLat1 > 0) radLat1 = Math.PI / 2 - Math.Abs(radLat1); // north
if (radLon1 < 0) radLon1 = Math.PI * 2 - Math.Abs(radLon1); // west
if (radLat2 < 0) radLat2 = Math.PI / 2 + Math.Abs(radLat2); // south
if (radLat2 > 0) radLat2 = Math.PI / 2 - Math.Abs(radLat2); // north
if (radLon2 < 0) radLon2 = Math.PI * 2 - Math.Abs(radLon2); // west
double x1 = EARTH_RADIUS * Math.Cos(radLon1) * Math.Sin(radLat1);
double y1 = EARTH_RADIUS * Math.Sin(radLon1) * Math.Sin(radLat1);
double z1 = EARTH_RADIUS * Math.Cos(radLat1);
double x2 = EARTH_RADIUS * Math.Cos(radLon2) * Math.Sin(radLat2);
double y2 = EARTH_RADIUS * Math.Sin(radLon2) * Math.Sin(radLat2);
double z2 = EARTH_RADIUS * Math.Cos(radLat2);
double d = Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
// 余弦定理求夹角
double theta = Math.Acos((EARTH_RADIUS * EARTH_RADIUS + EARTH_RADIUS * EARTH_RADIUS - d * d) / (2 * EARTH_RADIUS * EARTH_RADIUS));
double dist = theta * EARTH_RADIUS;
return dist;
}
#endregion
#region 算法2
/// <summary>
/// 基于googleMap中的算法得到两经纬度之间的距离,计算经度与谷歌地图的距离精度差不多,相差范围在0.2米以下
/// </summary>
/// <param name="lon1">第一点的经度</param>
/// <param name="lat1">第一点的纬度</param>
/// <param name="lon2">第二点的经度</param>
/// <param name="lat2">第二点的纬度</param>
/// <returns>返回的距离,单位km</returns>
private double GetDistance(double lon1, double lat1, double lon2, double lat2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * EARTH_RADIUS;
return s;
}
#endregion
/// <summary>
/// 双击打开
/// </summary>
private void pictureBoxPhoto_DoubleClick(object sender, EventArgs e)
{
string file = pictureBoxPhoto.ImageLocation;
if (System.IO.File.Exists(file)) {
System.Diagnostics.Process.Start(file);
}
}
/// <summary>
///
/// </summary>
private void toolStripButtonOpen_Click(object sender, EventArgs e)
{
FolderBrowserDialogEx dialog = new FolderBrowserDialogEx();
if (dialog.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) return;
OpenPath(dialog.SelectedPath);
}
/// <summary>
/// 导出坐标
/// </summary>
private void toolStripButtonExport_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "坐标信息(*.TXT)|*.TXT";
if (dialog.ShowDialog(this) != DialogResult.OK) return;
int num = 0;
StreamWriter writer = new StreamWriter(dialog.FileName, false);
writer.WriteLine("ID\tLAT\tLNG\tNAME");
// 对名称进行排序
foreach (GMapMarker marker in _objects.Markers.OrderBy(m => m.ToolTip)) {
double lat = marker.Position.Lat;
double lng = marker.Position.Lng;
string name = marker.ToolTipText;
writer.WriteLine("{0}\t{1:0.00000000}\t{2:0.00000000}\t{3}", num++, lat, lng, name);
}
writer.Flush();
writer.Close();
MessageBox.Show("完成");
}
private void toolStripButtonCollect_Click(object sender, EventArgs e)
{
FolderBrowserDialogEx dialog = new FolderBrowserDialogEx();
if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
string[] files = System.IO.Directory.GetFiles(dialog.SelectedPath, "*.jpg", SearchOption.AllDirectories);
List<string> list = new List<string>(files);
list.Sort();
for (int i = 0; i < list.Count; i++) {
System.IO.File.Copy(files[i], i.ToString("00000") + ".JPG");
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。