照片地理定位-坐标解析

时间:2024-03-05 14:06:50

现在的很多照片都可以带坐标,出去旅游的时候,如果将这些照片跟拍摄位置结合就可以使用照片定位,并且查看当地的风景。

这些照片存储着坐标信息,其实不仅仅是坐标信息,还有很多其他的,这类照被称为Extif格式。

Exif是英文Exchangeable Image File(可交换图像文件)的缩写,最初由日本电子工业发展协会(JEIDA --Japan Electronic Industry Development Association) 制订,目前的最新版本是发表于2002年04月的2.21 版。国际标准化组织(ISO)正在制订的相机文件设计标准(DCF -- Design role for Camera File system)可能以Exif2.1为基础。

  Exif 文件实际是JPEG文件的一种,遵从JPEG标准,只是在文件头信息中增加了有关拍摄信息的内容和索引图。所以你可以使用任何支持JPEG格式的图像工具软件观看或修改Exif文件,但,打开时可能看不到Exif信息,一旦修改,Exif信息可能丢失。

  简单来说,EXIF 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 EXIF 信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,主要包括摄影时的光圈、快门、ISO、时间等各种与当时摄影条件相关的讯息,相机品牌型号,色彩编码,拍摄时录制的声音以及全球定位系统(GPS)等信息。简单的说,它就好像是傻瓜相机的日期打印功能一样,只不过 EXIF 信息所记录的资讯更为详尽和完备。

下面是解析这里照片的核心代码,我是在WPF中将照片拖放的,然后里面调用坐标解析函数,如下:

private void _mapControl_Drop(object sender, DragEventArgs e)
        {
          

            //拖放的数据都存在e.Data中
            if (e.Data == null)
            {
                return;
            }
            IDataObject data = e.Data;
            //IDataObject.GetData(DataFormats.FileDrop) - 返回被拖放的外部文件的 FileInfo 数组
            string[] files = (string[])data.GetData(DataFormats.FileDrop);
            foreach (string fileInfo in files)
            {
                if (Path.GetExtension(fileInfo).Equals(".jpg", StringComparison.OrdinalIgnoreCase))
                {
                  //  FileInfo fi = new FileInfo(fileInfo);

                    System.Drawing.Image theImage = System.Drawing.Image.FromFile(fileInfo);

                    //  http://www.exiv2.org/tags.html

                    PropertyItem[] pt = theImage.PropertyItems;
                    double x = 0;
                    double y = 0;

                    double z;

                    PictureMarkerSymbol pPicTure = new PictureMarkerSymbol();

             


                    for (int i = 0; i < pt.Length; i++)
                    {

                        PropertyItem p = pt[i];
                       
                        switch (pt[i].Id)
                        {  // 纬度

                            case 2:

                               x = GPSLatitude(p);

                                break;

                            case 4: // 

                                y = GPSLongitude(p);

                                break;

                            case 6: // 

                                 z = GPSAltitude(p);

                                break;

                          
                            default:

                                break;

                        }

                  
                    }


                    Graphic pGraphic = new Graphic();

                    pPicTure.Source = new BitmapImage(new Uri(fileInfo, UriKind.Absolute));
                    //偏移距离
                    pPicTure.OffsetX = 0.1;

                    pPicTure.OffsetY = 0.1;

                   pGraphic.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(pGraphic_MouseLeftButtonDown);

                    // pGraphic.MouseEnter += new System.Windows.Input.MouseEventHandler(pGraphic_MouseEnter);
                    pGraphic.Geometry = new MapPoint(y, x);

                    pGraphic.Symbol = pPicTure;
                   
                    
                    pGraphicsLayer.Graphics.Add(pGraphic);

                    pPicTure.Width = pPicTure.Source.Width/5;

                    pPicTure.Height= pPicTure.Source.Height/5;



                }
                else
                {
                    MessageBox.Show(fileInfo  + " is not supported image file!");
                }
            }

           // _mapControl.Extent = pGraphicsLayer.FullExtent;
               
        }

╰醉意人间╮  8:42:18

        private double GPSLatitude(PropertyItem pi)     
         {
             double latitude = 0; 

             
             double deg = BitConverter.ToUInt32(pi.Value, 0);
             uint deg_div = BitConverter.ToUInt32(pi.Value, 4);
             double min = BitConverter.ToUInt32(pi.Value, 8);
             uint min_div = BitConverter.ToUInt32(pi.Value, 12);
             double mmm = BitConverter.ToUInt32(pi.Value, 16);
             uint mmm_div = BitConverter.ToUInt32(pi.Value, 20);
             double m = 0;
             if (deg_div != 0 || deg != 0)   
             { m = (deg / deg_div); }
             if (min_div != 0 || min != 0)
             {
                 m = m + (min / min_div) / 60;
             } 
             if (mmm_div != 0 || mmm != 0)
             {
                 m = m + (mmm / mmm_div / 3600);
             }
             latitude = m;                   
             return latitude;
         }

         private double GPSLongitude(PropertyItem pi)
         {
             double Longitude;
             double deg = BitConverter.ToUInt32(pi.Value, 0);
             uint deg_div = BitConverter.ToUInt32(pi.Value, 4);
             double min = BitConverter.ToUInt32(pi.Value, 8);
             uint min_div = BitConverter.ToUInt32(pi.Value, 12);
             double mmm = BitConverter.ToUInt32(pi.Value, 16);
             uint mmm_div = BitConverter.ToUInt32(pi.Value, 20);
             double m = 0;
             if (deg_div != 0 || deg != 0)    //36.26.0140          
             {
                 m = (deg / deg_div);
             }
             if (min_div != 0 || min != 0)
             {
                 m = m + (min / min_div) / 60;
             }
             if (mmm_div != 0 || mmm != 0)    //36.26.0140       
             {
                 m = m + (mmm / mmm_div / 3600);
             }
             Longitude = m;
             return Longitude;
         }
         private double GPSAltitude(PropertyItem pi)
            {             

                double deg = BitConverter.ToUInt32(pi.Value, 0);
                uint deg_div = BitConverter.ToUInt32(pi.Value, 4);
                double m = 0;
                if (deg_div != 0 || deg != 0)
                {
                    m = (deg / deg_div);
                }
                return m;
            }