C#调用python实现shp文件的CGCS2000坐标系向WGS84坐标系转换

       前言:我们项目上最近有个需求,要把shp文件导入到我们的webgis系统中来,展示在前端的网页上。如果是任意的shp想展示在webgis中,我们就使用postgresql提供的ogr2ogr工具,直接将shp转为geojson,数据传给前端就行了。但是现在我们的shp是有固定格式的,我们的数据库中也有对应格式的表,因此问题就转变为了,将shp导入我们的表中。
       shp文件导入postgresql使用的是shp2pgsql工具,这个工具的使用方法网上的文章非常多,我们在这里就不过多介绍。我们在这里主要讨论的是,我们的shp文件是国家2000坐标系,采用的是高斯投影,即投影坐标系。而我们要在web页面上使用展示地图的话,必须将其转为 WGS84 Web Mercator投影(3857)或者WGS84(4326),我们系统使用的是后者,因此我们需要将投影坐标系转为地理坐标系。这就复杂了,涉及到七参数的转换。
      最初我们是想用proj.4进行转换,然而查看了相关的接口后,觉得太复杂,要传的参数太多,很乱,舍弃了。于是我们转向了用python来实现这一功能。arcgis的toolbox工具中的投影工具不就可以完成这个功能吗?并且工具运行完成了以后,还可以拿到工具对应的python代码。这就方便了,我们直接让C#来调用一下这个python代码不就行了吗?于是,本着talk is cheap,show me the code的原则,我们开始撸起袖子码代码。
     思路:首先我们要拿到arcgis中的python代码,然后改造,生成我们的python文件,用C#代码调用python.exe去执行这个文件,拿到结果。我们的目标shp的名字就在源文件的名字的后面加个4326,和源文件存储在同一个地方。
C#调用python实现shp文件的CGCS2000坐标系向WGS84坐标系转换

C#调用python实现shp文件的CGCS2000坐标系向WGS84坐标系转换
 
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/// 
/// 将shp从CGCS2000高斯投影坐标为WGS84地理坐标
/// 
/// 
/// 

[HttpPost]
public  IActionResult ConvertCoor2WGS84( string  sourceShpPath)
{
    
//1.shp转featureClass
    sourceShpPath = @ "D:\test\test.shp" ;
    sourceShpPath = sourceShpPath.Replace(
"\" "/" );
    

     string  goalShpPath = (Path.GetDirectoryName(sourceShpPath) +  "\"  + Path.GetFileNameWithoutExtension(sourceShpPath) +  "4326.shp" ).Replace( "\" "/" );
    
    
string  pyCommand =  "# encoding=utf8\r\n"  +
        
"import sys\r\n" +
        
"import arcpy\r\n"  +
        
"reload(sys)\r\n"  +
        
"sys.setdefaultencoding('utf8')\r\n"  +
        $
"arcpy.Project_management('{sourceShpPath}', '{goalShpPath}', " GEOGCS[ 'GCS_WGS_1984' ,DATUM[ 'D_WGS_1984' ,SPHEROID[ 'WGS_1984' , 6378137 . 0 , 298 . 257223563 ]],PRIMEM[ 'Greenwich' , 0 . 0 ],UNIT[ 'Degree' , 0 . 0174532925199433 ],METADATA[ 'World' ,- 180 . 0 ,- 90 . 0 , 180 . 0 , 90 . 0 , 0 . 0 , 0 . 0174532925199433 , 0 . 0 , 1262 ]]\ ", 'CGCS2000_WGS84', " PROJCS[ 'CGCS2000_GK_CM_117E' ,GEOGCS[ 'GCS_China_Geodetic_Coordinate_System_2000' ,DATUM[ 'D_China_2000' ,SPHEROID[ 'CGCS2000' , 6378137 . 0 , 298 . 257222101 ]],PRIMEM[ 'Greenwich' , 0 . 0 ],UNIT[ 'Degree' , 0 . 0174532925199433 ]],PROJECTION[ 'Gauss_Kruger' ],PARAMETER[ 'False_Easting' , 500000 . 0 ],PARAMETER[ 'False_Northing' , 0 . 0 ],PARAMETER[ 'Central_Meridian' , 117 . 0 ],PARAMETER[ 'Scale_Factor' , 1 . 0 ],PARAMETER[ 'Latitude_Of_Origin' , 0 . 0 ],UNIT[ 'Meter' , 1 . 0 ]]\ ")" ;

    
string  res2000_84res=GeoConvertMethods.RunPy(pyCommand);
    
return  Ok();
}

/// 
/// 执行python
/// 
/// 
/// 

public   static   string  RunPy( string  pyCommand)
{
    
string  res =  "" ;
    
using  (Process p =  new  Process())
    {
        
//.NET Core不支持gbk和gb2312,这里需要处理一下
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        Console.InputEncoding = Encoding.UTF8;
        
//创建py文件
         string  pyPath =  "Upload\\PyFiles\"  + Guid.NewGuid() +  ".py" ;
        flag = Save(pyPath, pyCommand);
        
if (!flag)  throw   new  Exception( "创建python文件失败!" );
        p.StartInfo.Arguments = pyPath;
        p.StartInfo.FileName = GetPythonPath();
        
if (p.StartInfo.FileName== "" ) throw   new  Exception( "未找到python.exe!" );
        p.StartInfo.UseShellExecute = 
false ;         //是否使用操作系统shell启动
        p.StartInfo.RedirectStandardInput =  true ;    //接受来自调用程序的输入信息
        p.StartInfo.RedirectStandardOutput =  true ;   //由调用程序获取输出信息
        p.StartInfo.RedirectStandardError =  true ;    //重定向标准错误输出
        p.StartInfo.CreateNoWindow =  true ;           //不显示程序窗口
        p.Start(); //启动程序

        p.WaitForExit(); //等待程序执行完退出进程

         //获取cmd窗口的输出信息
         string  s = p.StandardOutput.ReadToEnd();
        
//获取错误信息
         string  error = p.StandardError.ReadToEnd();
        
byte [] bytes = Encoding.GetEncoding( "GB2312" ).GetBytes(s);
        res = Encoding.UTF8.GetString(bytes);

        p.Close();
    }
    
return  res;

}

/// 
/// 获取python所在路径
/// 
/// 

public   static   string  GetPythonPath()
{
    
string  path =  "" ;
    
string [] directories = Directory.GetDirectories( "C:" );
    
foreach  (var item  in  directories)
    {
        
if  (item.Contains( "Python" ))
        {
            
string [] files=Directory.GetFiles(item, "*.exe" , SearchOption.AllDirectories);
            
foreach  (var file  in  files)
            {
                
if  (file.EndsWith( "python.exe" ))
                {
                    
return  file;
                }
            }
        }
    }
    
return  path;
}


/// 
/// 创建文件
/// 
/// 文件路径
/// 文件内容

public   static   bool  Save( string  path,  string  str)
{
    
string  s = path.Substring( 0 , path.LastIndexOf( '\\' ));
    Directory.CreateDirectory(s);
//如果文件夹不存在就创建它
    FileStream fs =  new  FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
    
byte [] data = System.Text.Encoding.Default.GetBytes(str);
    
//开始写入
    fs.Write(data,  0 , data.Length);
    
//清空缓冲区、关闭流
    fs.Flush();
    fs.Close();
    
return   true ;
}
结果1:我们生成的python代码
 Python Code 
1
2
3
4
5
6
7
# encoding=utf8
import  sys
import  arcpy
reload (sys)
sys.setdefaultencoding(
'utf8' )
arcpy.Project_management(
'D:/test/test.shp' 'D:/test/test4326.shp' "GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433],METADATA['World',-180.0,-90.0,180.0,90.0,0.0,0.0174532925199433,0.0,1262]]" 'CGCS2000_WGS84' "PROJCS['CGCS2000_GK_CM_117E',GEOGCS['GCS_China_Geodetic_Coordinate_System_2000',DATUM['D_China_2000',SPHEROID['CGCS2000',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Gauss_Kruger'],PARAMETER['False_Easting',500000.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',117.0],PARAMETER['Scale_Factor',1.0],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]]" )
结果2:我们转换好的python文件
C#调用python实现shp文件的CGCS2000坐标系向WGS84坐标系转换

C#调用python实现shp文件的CGCS2000坐标系向WGS84坐标系转换



 
结语:最近落下了好几篇博文没发,今天刚好记录下吧。本次的教程就分享到这里,下次再会。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGIS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值