热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

shp文件奥秘及c语言编程对策,VS2017编译GDAL(64bit)+解决C#读取Shp数据中文路径的问题...

编译GDAL过程比较繁琐,查阅了网上相关资料,同时通过实践,完成GDAL的编译,同时解决了SHP数据中文路径及中文字段乱码的

编译GDAL过程比较繁琐,查阅了网上相关资料,同时通过实践,完成GDAL的编译,同时解决了SHP数据中文路径及中文字段乱码的问题,本文以“gdal-2.3.2”版本为例阐述整个编译过程。

一、编译准备

1、编译工具是VS2017,编译前需要下载“gdal-2.3.2”和“swigwin-3.0.12”,下载链接如下:

GDAL:http://trac.osgeo.org/gdal/wiki/DownloadSource

swigwin:https://sourceforge.net/projects/swig/files/swigwin/

2、在“D盘”新建目录“GDAL”,将两个压缩包解压到该目录中,同时新建一个文件夹用于存放编译结果(如“D:\GDAL\GDAL\GDAL232“”),如图所示:

5e86010c3182e11270d82d954c316822.png

3、修改“D:\GDAL\gdal-2.3.2\nmake.opt”文件,如下图:

a4c72605a8cc77241ae276c1249859de.png

文件“nmake.opt”修改如下:

修改57行,GDAL_HOME = "D:\GDAL\GDAL\GDAL232"(编译后文件的生成目录)

修改86行,SWIG = D:\GDAL\swigwin-3.0.12\swig.exe(这个必须是完全路径)

修改184行,去掉“#”,效果为WIN64=YES

修改960行,去掉后边的下划线,效果为SYM_PREFIX=

二、编译C++

以管理员运行【开始】-【所有程序】-【Visual Studio 2017】-【Visual Studio Tools】-【VC】-【适用于 VS 2017 的 x64 本机工具命令提示】菜单,弹出命令框如图所示:

2cd65eb278870248d163ec3affd172cf.png

输入cd D:\GDAL\gdal-2.3.2 切换至gdal-2.3.2目录,如图所示:

6afe5fca13bfbb8ab6584c5df226267e.png

然后依次输入:

nmake /f makefile.vc

nmake /f makefile.vc install

nmake /f makefile.vc devinstall

C++编译时间较长,需要耐心等待……

三、编译C#

1、修改C#源码文件

打开“D:\GDAL\gdal-2.3.2\swig\csharp\AssemblyInfo.cs”,注释掉【[assembly: AllowPartiallyTrustedCallers]】,如下图所示:

c30d88edfb5bd73909224b095d8edc82.png

打开如下三个文件:

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\GdalPINVOKE.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\ogr\OgrPINVOKE.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\osr\OsrPINVOKE.cs”

分别注释掉重复的构造函数,如图所示:

43a47697196211cc7436de9e6746150e.png

打开如下三个文件:

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\Band.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\Dataset.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\Driver.cs”

文件,修改接口成员(大概17行),如下:

public Band(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);}public Dataset(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);}public Driver(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);}

接下来解决读取中文路径及属性乱码 :

打开如下四个文件:

“D:\GDAL\gdal-2.3.2\swig\csharp\const\GdalConstPINVOKE.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\GdalPINVOKE.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\ogr\OgrPINVOKE.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\osr\OsrPINVOKE.cs”

分别修改类“SWIGStringHelper”(大概168行),具体代码(红色为修改过得代码)如下:

protected classSWIGStringHelper {public delegate stringSWIGStringDelegate(IntPtr message);static SWIGStringDelegate stringDelegate = newSWIGStringDelegate(CreateString);

[global::System.Runtime.InteropServices.DllImport("ogr_wrap", EntryPoint="SWIGRegisterStringCallback_Ogr")]public static extern voidSWIGRegisterStringCallback_Ogr(SWIGStringDelegate stringDelegate);static stringCreateString(IntPtr pNativeData)

{if (pNativeData ==IntPtr.Zero)return "";int i = 0;byte[] strbuf1 = new byte[1];

Marshal.Copy(pNativeData+ i, strbuf1, 0, 1);while (strbuf1[0] != 0)

{

i++;

strbuf1= new byte[1];

Marshal.Copy(pNativeData+ i, strbuf1, 0, 1);

}int length = i;//循环查找字符串的长度

byte[] strbuf = new byte[length];

Marshal.Copy(pNativeData, strbuf,0, length);returnSystem.Text.Encoding.UTF8.GetString(strbuf);

}staticSWIGStringHelper() {

SWIGRegisterStringCallback_Ogr(stringDelegate);

}

}

打开如下三个文件:

“D:\GDAL\gdal-2.3.2\swig\csharp\gdal\Gdal.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\ogr\Ogr.cs”

“D:\GDAL\gdal-2.3.2\swig\csharp\osr\Osr.cs”

分别修改函数“Utf8BytesToString”,代码如下:

internal static stringUtf8BytesToString(IntPtr pNativeData)

{if (pNativeData ==IntPtr.Zero)return null;int i = 0;byte[] strbuf1 = new byte[1];

Marshal.Copy(pNativeData+ i, strbuf1, 0, 1);while (strbuf1[0] != 0)

{

i++;

strbuf1= new byte[1];

Marshal.Copy(pNativeData+ i, strbuf1, 0, 1);

}int length = i;//循环查找字符串的长度

byte[] strbuf = new byte[length];

Marshal.Copy(pNativeData, strbuf,0, length);//int length = Marshal.PtrToStringAnsi(pNativeData).Length;//byte[] strbuf = new byte[length];//Marshal.Copy(pNativeData, strbuf, 0, length);

returnSystem.Text.Encoding.UTF8.GetString(strbuf);

}

2、编译

输入cd swig\csharp ,切换到csharp目录,

输入nmake /f makefile.vc(运行这一步有问题的话,加以下两句:namke /f makefile.vc clear 、nmake /f makefile.vc interface)

输入nmake /f makefile.vc install

编译完成后,在目录“D:\GDAL\GDAL\GDAL232\csharp”会生成8个文件,如图所示:

1077602678f6eb0e9f76c5e78106389f.png

注:C#编译过程中,如果出现HandleRef和IntPtr没有引用的错误,只需要在相应文件中添加命名空间

using System;

using System.Runtime.InteropServices;即可解决该问题

四、测试DLL

新建一个Winform应用程序,修改运行配置为x64,如图所示:

9f677d4cc669b347da0e8d6b27a2f8be.png

把“D:\GDAL\GDAL\GDAL232\csharp”中的8个dll和“D:\GDAL\GDAL\GDAL232\bin”中的一个dll复制到“x64/Release”目录下,添加引用

读取Shp数据的代码如下:

OSGeo.GDAL.Gdal.AllRegister();

OSGeo.OGR.Ogr.RegisterAll();

OSGeo.OGR.Driver dr= OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile");

OSGeo.OGR.DataSource ds= dr.Open(path, 0);if (ds == null)

{

MessageBox.Show("文件不能打开,请检查!");return;

}

效果如图所示:

669cab2ee8e4776a1cfcd8e773d07a6d.png



推荐阅读
  • ipsec 加密流程(二):ipsec初始化操作
    《openswan》专栏系列文章主要是记录openswan源码学习过程中的笔记。Author:叨陪鲤Email:vip_13031075266163.comDate:2020.1 ... [详细]
  • 最近遇到了一道关于哈夫曼树的编程题目,需要在下午之前完成。题目要求设计一个哈夫曼编码和解码系统,能够反复显示和处理多个项目,直到用户选择退出。希望各位大神能够提供帮助。 ... [详细]
  • hdu4539郑厂长系列故事——排兵布阵http:acm.hdu.edu.cnshowproblem.php?pid4539问题描述:给你一个n行m列的0-1矩阵,0表示不 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • C语言编写线程池的简单实现方法
    2019独角兽企业重金招聘Python工程师标准好文章,一起分享——有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带 ... [详细]
  • 本文介绍了Spring 2.0引入的TaskExecutor接口及其多种实现,包括同步和异步执行任务的方式。文章详细解释了如何在Spring应用中配置和使用这些线程池实现,以提高应用的性能和可管理性。 ... [详细]
  • 机器学习算法:SVM(支持向量机)
    SVM算法(SupportVectorMachine,支持向量机)的核心思想有2点:1、如果数据线性可分,那么基于最大间隔的方式来确定超平面,以确保全局最优, ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 本文介绍了并查集(Union-Find算法)的基本概念及其应用。通过一个具体的例子,解释了如何使用该算法来处理涉及多个集合的问题。题目要求输入两个整数 n 和 m,分别表示总人数和操作次数。算法通过高效的合并与查找操作,能够快速确定各个元素所属的集合,适用于大规模数据的动态管理。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在HTML布局中,即使将 `top: 0%` 和 `left: 0%` 设置为元素的定位属性,浏览器中仍然会出现空白填充。这个问题通常与默认的浏览器样式、盒模型或父元素的定位方式有关。为了消除这些空白,可以考虑重置浏览器的默认样式,确保父元素的定位方式正确,并检查是否有其他CSS规则影响了元素的位置。 ... [详细]
  • 在分析和解决 Keepalived VIP 漂移故障的过程中,我们发现主备节点配置如下:主节点 IP 为 172.16.30.31,备份节点 IP 为 172.16.30.32,虚拟 IP 为 172.16.30.10。故障表现为监控系统显示 Keepalived 主节点状态异常,导致 VIP 漂移到备份节点。通过详细检查配置文件和日志,我们发现主节点上的 Keepalived 进程未能正常运行,最终通过优化配置和重启服务解决了该问题。此外,我们还增加了健康检查机制,以提高系统的稳定性和可靠性。 ... [详细]
  • 本文通过基准测试(Benchmark)对.NET Core环境下Thrift和HTTP客户端的微服务通信性能进行对比分析。基准测试是一种评估系统或组件性能的方法,通过运行一系列标准化的测试来衡量其表现。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
author-avatar
殇子休
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有