百度坐标 转 WGS84坐标 并保存到SHP图层中

步骤1、坐标转换代码

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;

namespace BDTOWGS84
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /*
         * BD-09:百度坐标系(百度地图)
         * GCJ-02:火星坐标系(谷歌中国地图、高德地图)
         * WGS84:地球坐标系(国际通用坐标系,谷歌地图)
         */

        public double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
        public double PI = 3.1415926535897932384626;
        public double a = 6378245.0;
        public double ee = 0.00669342162296594323;

        private void Form1_Load(object sender, EventArgs e)
        {
            //从shp中读取
            double bd_lon = 115.962804;//经度
            double bd_lat = 37.3786;//纬度

            //将wgs存入shp
            double[] wgs = bd09togcj02(bd_lon, bd_lat);
            MessageBox.Show(wgs[0].ToString()+"    "+wgs[1].ToString());
        }

        //百度坐标系转火星坐标系
        private double[] bd09togcj02(double bd_lon, double bd_lat)
        {
            double x = bd_lon - 0.0065;
            double y = bd_lat - 0.006;
            double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_PI);
            double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_PI);

            double gcj_lon = z * Math.Cos(theta);
            double gcj_lat = z * Math.Sin(theta);
            double[] gcj = { gcj_lon, gcj_lat };//火星坐标系值

            //火星坐标系转wgs84
            double[] wgs = gcj02towgs84(gcj[0], gcj[1]);
            return wgs;
        }

        //火星坐标系转wgs84
        private double[] gcj02towgs84(double gcj_lon, double gcj_lat)
        {
           if (out_of_china(gcj_lon, gcj_lat)) 
           {
               MessageBox.Show("不在国内范围!");
               double[] back={gcj_lon,gcj_lat};
               return back;
           } 
           else 
           {
                var dlon = transformlon(gcj_lon - 105.0, gcj_lat - 35.0);
                var dlat = transformlat(gcj_lon - 105.0, gcj_lat - 35.0);
                var radlat = gcj_lat / 180.0 * PI;
                var magic = Math.Sin(radlat);
                magic = 1 - ee * magic * magic;
                var sqrtmagic = Math.Sqrt(magic);
                dlon = (dlon * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * PI);
                dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
                double mglon = gcj_lon + dlon;
                double mglat = gcj_lat + dlat;
                double wgs_lon = gcj_lon * 2 - mglon;
                double wgs_lat = gcj_lat * 2 - mglat;
                double[] wgs = { wgs_lon,wgs_lat };//wgs84坐标系值
                return wgs;
            }
        }

        //火星坐标系转百度坐标系
        private double[] gcj02tobd09(double gcj_lon, double gcj_lat)
        {
            double z = Math.Sqrt(gcj_lon * gcj_lon + gcj_lat * gcj_lat) + 0.00002 * Math.Sin(gcj_lat * x_PI);
            double theta = Math.Atan2(gcj_lat, gcj_lon) + 0.000003 * Math.Cos(gcj_lon * x_PI);
            double bd_lon = z * Math.Cos(theta) + 0.0065;
            double bd_lat = z * Math.Sin(theta) + 0.006;
            double[] bd={bd_lon,bd_lat};
            return bd;
        }

        //wgs84转火星坐标系
        private double[] wgs84togcj02(double wgs_lon, double wgs_lat)
        {
            if (out_of_china(wgs_lon, wgs_lat)) 
            {
                MessageBox.Show("不在国内范围!");
                double[] back={wgs_lon,wgs_lat};
                return back;
            } 
            else 
            {
                double dwgs_lon = transformlon(wgs_lon - 105.0, wgs_lat - 35.0);
                double dwgs_lat = transformlat(wgs_lon - 105.0, wgs_lat - 35.0);
                double radwgs_lat = wgs_lat / 180.0 * PI;
                double magic = Math.Sin(radwgs_lat);
                magic = 1 - ee * magic * magic;
                double sqrtmagic = Math.Sqrt(magic);
                dwgs_lon = (dwgs_lon * 180.0) / (a / sqrtmagic * Math.Cos(radwgs_lat) * PI);
                dwgs_lat = (dwgs_lat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
                double gcj_lon = wgs_lon + dwgs_lon;
                double gcj_lat = wgs_lat + dwgs_lat;
                double[] gcj = {gcj_lon, gcj_lat};
                return gcj;
            }
        }

        private double transformlon(double lon, double lat)
        {
            var ret = 300.0 + lon + 2.0 * lat + 0.1 * lon * lon + 0.1 * lon * lat + 0.1 * Math.Sqrt(Math.Abs(lon));
            ret += (20.0 * Math.Sin(6.0 * lon * PI) + 20.0 * Math.Sin(2.0 * lon * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(lon * PI) + 40.0 * Math.Sin(lon / 3.0 * PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.Sin(lon / 12.0 * PI) + 300.0 * Math.Sin(lon / 30.0 * PI)) * 2.0 / 3.0;
            return ret;
        }

        private double transformlat(double lon, double lat)
        {
            var ret = -100.0 + 2.0 * lon + 3.0 * lat + 0.2 * lat * lat + 0.1 * lon * lat + 0.2 * Math.Sqrt(Math.Abs(lon));
            ret += (20.0 * Math.Sin(6.0 * lon * PI) + 20.0 * Math.Sin(2.0 * lon * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(lat * PI) + 40.0 * Math.Sin(lat / 3.0 * PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.Sin(lat / 12.0 * PI) + 320 * Math.Sin(lat * PI / 30.0)) * 2.0 / 3.0;
            return ret;
        }

        //判断是否在国内,不在国内则不做偏移
        private Boolean out_of_china(double lon, double lat)
        {
            return (lon < 72.004 || lon > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
        }

    }
}
步骤2、转换后的XY坐标生成新的shp图层(ArcToolbox下的创建XY事件图层)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using System.Windows.Forms;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataManagementTools;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.DataSourcesGDB;

namespace BDTOWGS84
{
    public class ThematicMap
    {
        Form1 f1 = new Form1();
        private IMapControl3 m_mapControl = null;//为axMapControl1
        ILayer pLayer = null;
        public double[] itemValue_X;//各X值,MainForm会调用,然后传到FormPie中去计算落在各个区间的个数
        public double[] itemValue_Y;

        public ThematicMap(IMapControl3 mapControl, AxTOCControl axTOCControl1, ILayer ppLayer, string strName_X, string strName_Y,int numall)
         {
             m_mapControl = mapControl;
             pLayer = ppLayer;//获取图层 ,并把它设置成IGeoFeatureLayer的实例 

             IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
             IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer;
             IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;获取图层上的feature

             // 通过查找features的所有字段的值
             ITable pTable;
             int fieldNumber_X=0;
             int fieldNumber_Y = 0;
             pTable = pGeoFeatureLayer as ITable;
             fieldNumber_X = pTable.FindField(strName_X);
             fieldNumber_Y = pTable.FindField(strName_Y);
             if (fieldNumber_X == -1)
             {
                 MessageBox.Show(ppLayer.Name + "图层中" + strName_X + "字段未被找到,请检查SHP文件!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                 return;
             }
             if (fieldNumber_Y == -1)
             {
                 MessageBox.Show(ppLayer.Name + "图层中" + strName_Y + "字段未被找到,请检查SHP文件!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                 return;
             }
             const int numFields = 1;// 设置bars的个数
             int[] fieldIndecies_X = new int[1];
             int[] fieldIndecies_Y = new int[1];
             double fieldValue_X=0;//X字段值
             double fieldValue_Y = 0;//Y字段值
             fieldIndecies_X[0] = pTable.FindField(strName_X);
             fieldIndecies_Y[0] = pTable.FindField(strName_Y);
             int n = pFeatureClass.FeatureCount(null);//列数,关键
             itemValue_X = new double[n];
             itemValue_Y = new double[n];
             for (int i = 0; i < numFields; i++)
             {
                 IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
                 for (int j = 0; j < n; j++)
                 {
                     IFeature pFeature = pFeatureCursor.NextFeature();
                     fieldValue_X = Convert.ToDouble(pFeature.get_Value(fieldIndecies_X[i]));
                     fieldValue_Y = Convert.ToDouble(pFeature.get_Value(fieldIndecies_Y[i]));
                     double[] wgs = f1.bd09togcj02(fieldValue_X, fieldValue_Y);//坐标转换
                     if (wgs[0] == 0)
                         continue;
                     itemValue_X[j] = wgs[0];
                     itemValue_Y[j] = wgs[1];
                     pFeature.set_Value(fieldIndecies_X[i],wgs[0]);//更改shp属性字段的值
                     pFeature.set_Value(fieldIndecies_Y[i], wgs[1]);
                     pFeature.Store();
                     if (j == n - 1)
                     {
                         //创建XY事件图层
                         MakeXYEventLayer MxyLayer = new MakeXYEventLayer();
                         MxyLayer.table = pLayer;
                         MxyLayer.in_x_field = "X";
                         MxyLayer.in_y_field = "Y";
                         MxyLayer.out_layer = pLayer.Name + "_AfterTransform";
                         MxyLayer.spatial_reference = "4326";//不能写GCS_WGS_1984,要写4326

                         Geoprocessor GP = new Geoprocessor();
                         GP.Execute(MxyLayer, null);//执行MxyLayer事件

                         //删除gdb下存在的shp文件,首先用Catalog在指定目录下新建gdb文件
                         IWorkspaceFactory worFact = new FileGDBWorkspaceFactory();
                         IWorkspace workspace = worFact.OpenFromFile(Application.StartupPath + "\\ BDTOWGS84 .gdb", 0);
                         IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace;
                         IFeatureWorkspaceManage featureWorkspaceMange = (IFeatureWorkspaceManage)featureWorkspace;
                         IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
                         IDatasetName datasetName = null;
                         while ((datasetName = enumDatasetName.Next()) != null)
                         {
                             if (datasetName.Name.Equals(MxyLayer.out_layer))
                             {
                                 featureWorkspaceMange.DeleteByName(datasetName);//删除指定要素类
                                 break;
                             }
                         }

                         //在gdb下新建shp文件,首先必须要删除原有重名文件,否则会报错
                         ESRI.ArcGIS.DataManagementTools.CopyFeatures cf = new ESRI.ArcGIS.DataManagementTools.CopyFeatures();
                         cf.in_features = MxyLayer.out_layer;
                         cf.out_feature_class = Application.StartupPath + "\\ BDTOWGS84 .gdb\\" + MxyLayer.out_layer;
                         //cf.out_feature_class = "D:\\test3.gdb\\" + MxyLayer.out_layer;
                         GP.Execute(cf, null);

                         MessageBox.Show("图层" + pLayer.Name + "转换完毕!");
                     }        
                 }
             }
             if (numall!=0)
                MessageBox.Show("全部图层转换完毕!!!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
         }

    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值