238 lines
9.6 KiB
C#
238 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Diagnostics;
|
|
using ExifLib;
|
|
using System.Xml;
|
|
using Microsoft.WindowsAPICodePack.Dialogs;
|
|
using System.IO;
|
|
namespace ImgGPS2KML
|
|
{
|
|
public partial class MainWin : Form
|
|
{
|
|
public MainWin()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void putPlacemark(XmlTextWriter writer,string name, double longitude, double latitude)
|
|
{
|
|
writer.WriteStartElement("Placemark");
|
|
writer.WriteStartElement("name");
|
|
writer.WriteString(name);
|
|
writer.WriteEndElement();//end of name
|
|
writer.WriteStartElement("Style");
|
|
writer.WriteStartElement("IconStyle");
|
|
writer.WriteStartElement("Icon");
|
|
writer.WriteStartElement("href");
|
|
writer.WriteString("http://maps.google.com/mapfiles/kml/paddle/blu-blank.png");
|
|
writer.WriteEndElement();//end of href
|
|
writer.WriteEndElement();//end of Icon
|
|
writer.WriteStartElement("color");
|
|
writer.WriteString("ffffffff");
|
|
writer.WriteEndElement();//end of color
|
|
writer.WriteStartElement("scale");
|
|
writer.WriteString("1.0");
|
|
writer.WriteEndElement();//end of scale
|
|
writer.WriteEndElement();//end of IconStyle
|
|
writer.WriteEndElement();//end of Style
|
|
writer.WriteStartElement("Point");
|
|
writer.WriteStartElement("coordinates");
|
|
writer.WriteString(String.Format("{0},{1},0", longitude, latitude));
|
|
writer.WriteEndElement();//end of coordinates
|
|
writer.WriteEndElement();//end of Point
|
|
writer.WriteEndElement();//end of Placemark
|
|
}
|
|
|
|
private double toDecimalUnit(double degree, double minute, double second)//把2度2分3秒这样的数据转换成2.3212这样的数据。
|
|
{
|
|
return degree + minute / 60 + second / 3600;
|
|
}
|
|
|
|
//private double distanceByLongNLat(double long1, double lat1, double long2, double lat2)//计算经纬度两点间距离
|
|
//{
|
|
// double a, b, R;
|
|
// R = 6378137;//地球半径
|
|
// lat1 = lat1 * Math.PI / 180.0;
|
|
// lat2 = lat2 * Math.PI / 180.0;
|
|
// a = lat1 - lat2;
|
|
// b = (long1 - long2) * Math.PI / 180.0;
|
|
// double d;
|
|
// double sa2, sb2;
|
|
// sa2 = Math.sin(a / 2.0);
|
|
// sb2 = Math.sin(b / 2.0);
|
|
// d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
|
|
// return d;
|
|
//}
|
|
|
|
private List<double[]> extractCordinattionFromImg(List<string> imgPaths)//获得所有图片的坐标
|
|
{
|
|
List<double[]> longitudNLatitude = new List<double[]>();//第一个是经度,第二个是纬度
|
|
foreach (string path in imgPaths)
|
|
{
|
|
try
|
|
{
|
|
using (ExifReader reader = new ExifReader(path))
|
|
{
|
|
double[] longitude;//经度
|
|
double[] latitude;//纬度
|
|
reader.GetTagValue<double[]>(ExifTags.GPSLongitude, out longitude);
|
|
reader.GetTagValue<double[]>(ExifTags.GPSLatitude, out latitude);
|
|
if (longitude == null || latitude == null)
|
|
{
|
|
continue;
|
|
}
|
|
double decimalLongtitude;
|
|
decimalLongtitude = toDecimalUnit(longitude[0], longitude[1], longitude[2]);
|
|
double decimalLatitude;
|
|
decimalLatitude = toDecimalUnit(latitude[0], latitude[1], latitude[2]);
|
|
longitudNLatitude.Add(new double[] { decimalLongtitude, decimalLatitude });
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
|
|
}
|
|
}
|
|
return longitudNLatitude;
|
|
|
|
}
|
|
|
|
double[] get_centroid(List<double[]> cluster)
|
|
{
|
|
double x;
|
|
double y;
|
|
double z;
|
|
x = 0;
|
|
y = 0;
|
|
z = 0;
|
|
int coord_num = cluster.Count;
|
|
foreach (double[] coord in cluster)
|
|
{
|
|
double lon = coord[0] / 180 * Math.PI;
|
|
double lat = coord[1] / 180 * Math.PI;
|
|
x += Math.Cos(lat) * Math.Cos(lon);
|
|
y += Math.Cos(lat) * Math.Sin(lon);
|
|
z += Math.Sin(lat);
|
|
}
|
|
x /= coord_num;
|
|
y /= coord_num;
|
|
z /= coord_num;
|
|
return new double[] { Math.Atan2(y, x) * 180 / Math.PI, Math.Atan2(z, Math.Sqrt(x * x + y * y)) * 180 / Math.PI };
|
|
}
|
|
|
|
private List<string> searchJPG(string sourceDir)
|
|
{
|
|
string[] allFiles = Directory.GetFiles(sourceDir);
|
|
List<string> jpgFiles = new List<string>();
|
|
foreach (string file in allFiles)
|
|
{
|
|
if (Path.GetExtension(file).ToLower() == ".jpg")
|
|
{
|
|
jpgFiles.Add(file);
|
|
}
|
|
}
|
|
return jpgFiles;
|
|
|
|
}
|
|
|
|
private void bt_add_directory(object sender, EventArgs e)
|
|
{
|
|
this.dvDirectory.Rows.Clear();
|
|
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
|
|
dialog.Multiselect = true;
|
|
dialog.IsFolderPicker = true;
|
|
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
|
|
{
|
|
foreach (String selectDir in dialog.FileNames)
|
|
{
|
|
string coordination_col_text;
|
|
bool canExport;
|
|
canExport = true;
|
|
List<string> imgPaths = searchJPG(selectDir);
|
|
if (imgPaths.Count > 0)
|
|
{
|
|
List<double[]> coordinationOfImg;
|
|
coordinationOfImg = extractCordinattionFromImg(imgPaths);
|
|
if (coordinationOfImg.Count > 0)
|
|
{
|
|
double[] centroid;
|
|
centroid = get_centroid(coordinationOfImg);//计算所有图片坐标的中心
|
|
coordination_col_text = string.Format("{0},{1}", centroid[0], centroid[1]);
|
|
}
|
|
else
|
|
{
|
|
coordination_col_text = "图片中未找到坐标。";
|
|
canExport = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
coordination_col_text="未找到图片。";
|
|
canExport = false;
|
|
}
|
|
this.dvDirectory.Rows.Add(new object[]{selectDir,coordination_col_text,canExport});
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
private void btExportKML_Click(object sender, EventArgs e)
|
|
{
|
|
SaveFileDialog dialog = new SaveFileDialog();
|
|
dialog.Filter = "kml file (*.kml)|*.kml";
|
|
if (dialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
using (XmlTextWriter writer = new XmlTextWriter(dialog.FileName, Encoding.UTF8))
|
|
{
|
|
writer.Formatting = Formatting.Indented;
|
|
writer.WriteStartDocument();
|
|
writer.WriteStartElement("kml");
|
|
writer.WriteStartAttribute("xmlns");
|
|
writer.WriteString("http://www.opengis.net/kml/2.2");
|
|
writer.WriteEndAttribute();
|
|
writer.WriteStartAttribute("xmlns:gx");
|
|
writer.WriteString("http://www.google.com/kml/ext/2.2");
|
|
writer.WriteEndAttribute();
|
|
writer.WriteStartAttribute("xmlns:atom");
|
|
writer.WriteString("http://www.w3.org/2005/Atom");
|
|
writer.WriteEndAttribute();
|
|
writer.WriteStartElement("Document");
|
|
writer.WriteStartElement("name");
|
|
writer.WriteString("照片导出坐标");
|
|
writer.WriteEndElement();//end of name
|
|
foreach (DataGridViewRow row in this.dvDirectory.Rows)
|
|
{
|
|
Int32 canExport;
|
|
DataGridViewCheckBoxCell checkBoxColum=row.Cells[2] as DataGridViewCheckBoxCell;
|
|
canExport =Convert.ToInt32(checkBoxColum.Value);
|
|
if (canExport !=1)
|
|
{
|
|
continue;
|
|
}
|
|
double longitude;
|
|
double latitude;
|
|
string name;
|
|
name = Path.GetFileName(Convert.ToString(row.Cells[0].Value));
|
|
longitude = Convert.ToDouble(Convert.ToString(row.Cells[1].Value).Split(',')[0]);
|
|
latitude = Convert.ToDouble(Convert.ToString(row.Cells[1].Value).Split(',')[1]);
|
|
putPlacemark(writer, name, longitude, latitude);
|
|
}
|
|
writer.WriteEndElement();//end of Document
|
|
writer.WriteEndElement();//end of xml
|
|
writer.WriteEndDocument();
|
|
|
|
}
|
|
MessageBox.Show("已导出");
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|