前言:我们项目上最近有个需求,要把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# 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坐标系转换相关推荐

  1. CGCS2000坐标系和WGS84坐标系的区别与联系

    01 概述 由于历史原因,业内普遍对WGS84坐标系存在一定程度的误解,诸多文献对WGS84坐标系的解释也比较含糊,给测绘.导航.遥感.地信等工作带来一定困扰.本文重点对CGCS2000坐标系与WGS ...

  2. 基于Postgresql和PostGIS实现火星坐标系、百度坐标系、WGS84坐标系、CGCS2000坐标系互转

    背景 最近有一个需求,需要将WGS84转成火星坐标系.个人觉得在代码中逐个点坐标进行转换,太麻烦,而且效率低.PostGIS的st_transform虽然可以进行坐标转换,但是不支持国内这些坐标系.最 ...

  3. Python打开shp文件报错:Set SHAPE_RESTORE_SHX config option to YES to restore or create it.

    ERROR 4: Unable to open point.shx or point.SHX. Set SHAPE_RESTORE_SHX config option to YES to restor ...

  4. java调用python的函数_java如何调用python的.py文件,以及如何执行里面的函数,和创建...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package com.hmammon.service; import java.io.FileInputStream; import java.io.F ...

  5. python读取图片文件显示_Python—图像基本操作以及图像格式转换

    关于图像处理的模块常用的有 PIL,openCV等,不过应为要处理 tif 格式的图片,故特来写下这篇博客. 关于安装模块 libtiff 直接pip install libtiff 安装模块,发现无 ...

  6. QT调用python文件

    QT调用python文件 基本步骤 1.将python文件要是使用的环境添加到环境变量中 2.新建一个QT项目 3.在.pro文件中加入需要的python库文件目录 右击项目名,然后单击"添 ...

  7. c++调用python原理_C++调用Python浅析

    环境 VS2005Python2.5.4 Windows XP SP3 简述 一般开发过游戏的都知道Lua和C++可以很好的结合在一起,取长补短,把Lua脚本当成类似动态链接库来使用,很好的利用了脚本 ...

  8. 解决C++调用Python中文乱码

    C++调用Python,包括参数传递及返回值的处理的教程都很多.但是对于中文字符作为参数传递时,会遇到编码问题而乱码甚至崩溃.经过搜集资料,终于解决乱码问题,特记录在此: 1.参数传递一般采用PyOb ...

  9. xml转化为kml_借助ogr2ogr工具实现shp文件转换kml格式

    kml格式是一种在GOOGLE地图浏览器中用于交换地理数据的文件.它基于XML,并定义了一些TAG用于规定地理数据的显示方式.KML可用于定义的地理特征包括地点.描述.叠层.路径和多边形等. 实际工作 ...

最新文章

  1. mysql没有frm文件_【1.1】mysql frm文件丢失(ibd文件丢失)
  2. 【Android】java.lang.AssertionError use looper thread, must call Looper.prepare() first!异常分析
  3. Spring 通过Java Config方式连接数据库
  4. Angular 依赖注入的一个常见错误 NullInjectorError, No provider for XXX
  5. vue的this.$set的作用
  6. 本地信息搜索php程序,PHP搜索引擎
  7. 多线程3,线程池封装库
  8. js刷新当前页面的几种方式
  9. linux冒险岛服务端,冒险岛V118单机版一键端,开放全职业 带GM工具和命令
  10. 清华计算机专业培养,清华大学计算机本科生培养方案..pdf
  11. 简单的围棋棋盘打谱设计C#实现
  12. 五一博客连载——毕业游记录
  13. 复盘:企业微信中国发展简史
  14. python uiautomator2控制手机点击_uiautomator2 python远程操作Android
  15. webview显示flv远程文件
  16. 蚂蚁金服暂缓上市,程序IT圈炸了
  17. python替换图片背景色,适用于制作证件照
  18. java web3j示例教程
  19. Arduino mega 2560 上传项目总是出错最全解决方案以及串口测试教程
  20. 解构微信(二):团队是研究院、艺术中心甚至学校

热门文章

  1. python批量重命名工具
  2. java 工具类怎么命名_java 批量重命名工具类
  3. 非常漂亮的Web前端波形点击效果
  4. uniapp 底部菜单_利用uni-app怎么对底部导航栏进行自定义
  5. Python高级特性与网络爬虫(二):使用Selenium自动化测试工具爬取一号店商品信息
  6. Da Vinci: 一种微创手术机器人
  7. xp系统访问共享服务器提示无网络路径,WinXP提示无任何网络提供程序接受指定的网络路径怎么办?...
  8. 什么是shell?linux常用的shell有哪些
  9. 掀起WPS 2009的盖头来
  10. 测试手机视频录屏并转GIF功能