感謝: 小慧only http://www.cnblogs.com/zhaohuionly/p/3142623.html GPS轉化坐標方法
大胡子青松 http://www.cnblogs.com/xianyin05/archive/2013/05/10/3071224.html 獲取照片中Exif信息里GPS經緯度數
需求:上傳個圖片 解釋出拍攝地的 GPS 信息,以地圖的形式展現出來。GPS 信息的驗證,可下載 MagicEXIF 元數據編輯器 查看
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="Code.Test.WebForm2" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <div> <input type="file" id="file_img" runat="server"/> <asp:Button runat="server" Text="提取" ID="btn_zh" OnClick="btn_zh_Click"/> <asp:Image runat="server" ID="Map" /> </div> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; using System.Data; using System.IO; using System.Drawing.Imaging; using System.Net; using Newtonsoft.Json; namespace Code.Test { public partial class WebForm2 : System.Web.UI.Page { Code.SysManage.Commen.CommonTool commonTool = new SysManage.Commen.CommonTool(); public class MapConvert { public string error { get; set; } public string x { get; set; } public string y { get; set; } } protected void Page_Load(object sender, EventArgs e) { } #region 讀取圖片中GPS點 /// <summary> /// 獲取圖片中的GPS坐標點 /// </summary> /// <param name="p_圖片路徑">圖片路徑</param> /// <returns>返回坐標【緯度+經度】用"+"分割 取數組中第0和1個位置的值</returns> public String fnGPS坐標(String p_圖片路徑) { String s_GPS坐標 = ""; //載入圖片 System.Drawing.Image objImage = System.Drawing.Image.FromFile(p_圖片路徑); //取得所有的屬性(以PropertyId做排序) var propertyItems = objImage.PropertyItems.OrderBy(x => x.Id); //暫定緯度N(北緯) char chrGPSLatitudeRef = 'N'; //暫定經度為E(東經) char chrGPSLongitudeRef = 'E'; foreach (PropertyItem objItem in propertyItems) { //只取Id范圍為0x0000到0x001e if (objItem.Id >= 0x0000 && objItem.Id <= 0x001e) { switch (objItem.Id) { case 0x0000: var query = from tmpb in objItem.Value select tmpb.ToString(); string sreVersion = string.Join(".", query.ToArray()); break; case 0x0001://北緯 N chrGPSLatitudeRef chrGPSLatitudeRef = BitConverter.ToChar(objItem.Value, 0); break; case 0x0002://維度 strLatitude if (objItem.Value.Length == 24) { //degrees(將byte[0]~byte[3]轉成uint, 除以byte[4]~byte[7]轉成的uint) double d = BitConverter.ToUInt32(objItem.Value, 0) * 1.0d / BitConverter.ToUInt32(objItem.Value, 4); //minutes(將byte[8]~byte[11]轉成uint, 除以byte[12]~byte[15]轉成的uint) double m = BitConverter.ToUInt32(objItem.Value, 8) * 1.0d / BitConverter.ToUInt32(objItem.Value, 12); //seconds(將byte[16]~byte[19]轉成uint, 除以byte[20]~byte[23]轉成的uint) double s = BitConverter.ToUInt32(objItem.Value, 16) * 1.0d / BitConverter.ToUInt32(objItem.Value, 20); //計算經緯度數值, 如果是南緯, 要乘上(-1) double dblGPSLatitude = (((s / 60 + m) / 60) + d) * (chrGPSLatitudeRef.Equals('N') ? 1 : -1); string strLatitude = string.Format("{0:#}°{1:#}'{2:#.00}\"{3}", d , m, s, chrGPSLatitudeRef); //緯度 //s_GPS坐標 += "維度:" + dblGPSLatitude + "," + strLatitude + "|"; s_GPS坐標 += (dblGPSLatitude + "|"); } break; case 0x0003: //東經 chrGPSLongitudeRef //透過BitConverter, 將Value轉成Char('E' / 'W') //此值在后續的Longitude計算上會用到 chrGPSLongitudeRef = BitConverter.ToChar(objItem.Value, 0); break; case 0x0004: //經度 if (objItem.Value.Length == 24) { //degrees(將byte[0]~byte[3]轉成uint, 除以byte[4]~byte[7]轉成的uint) double d = BitConverter.ToUInt32(objItem.Value, 0) * 1.0d / BitConverter.ToUInt32(objItem.Value, 4); //minutes(將byte[8]~byte[11]轉成uint, 除以byte[12]~byte[15]轉成的uint) double m = BitConverter.ToUInt32(objItem.Value, 8) * 1.0d / BitConverter.ToUInt32(objItem.Value, 12); //seconds(將byte[16]~byte[19]轉成uint, 除以byte[20]~byte[23]轉成的uint) double s = BitConverter.ToUInt32(objItem.Value, 16) * 1.0d / BitConverter.ToUInt32(objItem.Value, 20); //計算精度的數值, 如果是西經, 要乘上(-1) double dblGPSLongitude = (((s / 60 + m) / 60) + d) * (chrGPSLongitudeRef.Equals('E') ? 1 : -1); string strLongitude = string.Format("{0:#}°{1:#}'{2:#.00}\"{3}", d , m, s, chrGPSLongitudeRef); //s_GPS坐標 += "經度:" + dblGPSLongitude + "," + strLongitude + "|"; s_GPS坐標 += (dblGPSLongitude + "|"); } break; case 0x0005://海平面 string strAltitude = BitConverter.ToBoolean(objItem.Value, 0) ? "0" : "1"; s_GPS坐標 += "海平面:" + strAltitude + "|"; break; case 0x0006://高度 if (objItem.Value.Length == 8) { //將byte[0]~byte[3]轉成uint, 除以byte[4]~byte[7]轉成的uint double dblAltitude = BitConverter.ToUInt32(objItem.Value, 0) * 1.0d / BitConverter.ToUInt32(objItem.Value, 4); s_GPS坐標 += "水平高度:" + dblAltitude + "|"; } break; } } } return s_GPS坐標; } #endregion protected void btn_zh_Click(object sender, EventArgs e) { string picpath = commonTool.SaveImg(file_img, "News"); /*上傳圖片的方法,可自己重寫*/ picpath = HttpContext.Current.Request.MapPath(picpath); string Gpslocation = fnGPS坐標(picpath);/*獲得GPS 信心,詳細信息參考方法*/ Response.Write(Gpslocation); //獲取當前緯度 string Latitude = Gpslocation.Split('|')[0];/*上傳圖片的方法,可自己重寫*/ //獲取當前經度 string Longitude = Gpslocation.Split('|')[1]; //百度坐標轉換API string path = "http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" + Longitude + "&y=" + Latitude + "";/*坐標糾正,生成百度地圖的坐標*/ //WebClient請求 WebClient wc = new WebClient(); Stream stream = wc.OpenRead(path); StreamReader sr = new StreamReader(stream); MapConvert mapConvert = new MapConvert(); string strResult = sr.ReadToEnd(); Response.Write(strResult); mapConvert = JsonConvert.DeserializeObject<MapConvert>(strResult); string lon = mapConvert.x; string lat = mapConvert.y; //進行Base64解碼 byte[] xBuffer = Convert.FromBase64String(lon); string strX = Encoding.UTF8.GetString(xBuffer, 0, xBuffer.Length); byte[] yBuffer = Convert.FromBase64String(lat); string strY = Encoding.UTF8.GetString(yBuffer, 0, yBuffer.Length); Response.Write(strX + ","); Response.Write(strY); //生成靜態圖片 string imgSrc = string.Format("http://api.map.baidu.com/staticimage?center={0},{1}&width=600&height=600&zoom=19&markers={2},{3}&markerStyles=l,A", strX, strY, strX, strY);/*此處生成靜態地圖,以顯示是否正確,可自行修改*/ //顯示圖片 Map.ImageUrl = imgSrc; } } }