VS2017编译GDAL(64bit)+解决C#读取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“”),如图所示:
3、修改“D:\GDAL\gdal-2.3.2\nmake.opt”文件,如下图:
文件“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 本机工具命令提示】菜单,弹出命令框如图所示:
输入cd D:\GDAL\gdal-2.3.2 切换至gdal-2.3.2目录,如图所示:
然后输入: 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]】,如下图所示:
打开“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”
三个文件,分别注释掉重复的构造函数,如图所示:
打开“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”
4个文件,分别修改类“SWIGStringHelper”(大概168行),具体代码(红色为修改过得代码)如下:
protected class SWIGStringHelper {
public delegate string SWIGStringDelegate(IntPtr message);
static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString);
[global::System.Runtime.InteropServices.DllImport("ogr_wrap", EntryPoint="SWIGRegisterStringCallback_Ogr")]
public static extern void SWIGRegisterStringCallback_Ogr(SWIGStringDelegate stringDelegate);
static string CreateString(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);
return System.Text.Encoding.UTF8.GetString(strbuf);
}
static SWIGStringHelper() {
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 string Utf8BytesToString(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);
return System.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个文件,如图所示:
注:C#编译过程中,如果出现HandleRef和IntPtr没有引用的错误,只需要在相应文件中添加命名空间
using System;
using System.Runtime.InteropServices;即可解决该问题
四、测试DLL
新建一个Winform应用程序,修改运行配置为x64,如图所示:
把“D:\GDAL\GDAL\GDAL232\csharp”中的8gedll和“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;
}
效果如图所示:
VS2017编译GDAL(64bit)+解决C#读取Shp数据中文路径的问题的更多相关文章
- GDAL打开HDF格式时遇到的中文路径问题(未解决)
众所周知,中文环境下(VS2010 C++工程编码为多字节编码),在使用1.8.0版本以后的GDAL打开中文路径下的影像文件(如GeoTiff文件)时, 需对中文文件路径做特殊处理,有2种方法:(我使 ...
- Java读取文件时中文路径处理
读取文件路径时可能存在以下情况: 1.空格,如果出现空格会转变成“%20” 2.中文路径,如果出现中文路径会变成URI编码“%e5%bc%80%e5%8f%91%e5%b7%a5%e7%a8%8b” ...
- arcgis for android 读取shp文件中文乱码解决方法
设置注册表默认字符,即可解决中文乱码问题. 'dbfDefault' 设置方法1.开始--运行,输入”Regedit“,打开注册表.2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ...
- 解决pl/sql 查询数据中文显示成?
解决方法: 1.打开 PLSQL Developer 安装目录下,看到有PLSQLDev.exe的目录, 在PLSQL Developer文件夹内新建“PLSql_run.bat”文件,在该文件中输入 ...
- Atitit.404错误解决标准流程and url汉字中文路径404错误resin4 resin chinese char path 404 err解决
Atitit.404错误解决标准流程and 错误resin4 resin chinese char path 404 err解决 1. #原因解析 1 2. #解决方式 2 3. 输出图片流... 2 ...
- GDAL C#读取shp中文属性值乱码问题
GDAL的C#版本读取shp中,如果属性值中含有中文,读出来有可能是乱码的问题,根据SWIG生成的C#代码调试发现问题所在,在Ogr.cs文件中有这么一个函数,代码如下: internal stati ...
- GDAL读取Shp问题解决:Unable to open EPSG support file gcs.csv
在GIS软件的开发中,经常用到开源库GDAL读取Shp数据,当shp数据中包含投影信息时,可能会遇到“Unable to open EPSG support file gcs.csv”错误提示,该错误 ...
- VS2015编译GDAL库出现宏重复定义 snprintf: 宏重定义
E:\OpenSourceGraph\gdal-1.10.0\gdal\port cpl_config.h 20行 #define HAVE_VPRINTF 1#define HAVE_ ...
- .NET读取Excel数据,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
解决.NET读取Excel数据时,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序的操作: 1. 检查本机是否安装Office Access,如果未安装去去h ...
随机推荐
- python实际练习1——简单购物车
要求实现 启动程序后,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 可随时退出,退出时,打印已购买商品和余额 自己写的代码是 ...
- java对excel操作
package test; import jxl.*; import jxl.Cell; import java.io.*; /** * 读取excel */ public class TestExc ...
- Python 内编写类的各种技巧和方法
Python 内编写类的各种技巧和方法 简介 有关 Python 内编写类的各种技巧和方法(构建和初始化.重载操作符.类描述.属性访问控制.自定义序列.反射机制.可调用对象.上下文管理.构建描述符对象 ...
- MySQL在高内存、IO利用率上的几个优化点
以下优化都是基于CentOS系统下的一些MySQL优化整理,有不全或有争议的地方望继续补充完善. 一.mysql层面优化 1. innodb_flush_log_at_trx_commit 设置为2设 ...
- ln 软链
ln -s a b 中的 a 就是源文件,b是链接文件名,其作用是当进入b目录,实际上是链接进入了a目录 如上面的示例,当我们执行命令 cd /gamestat/的时候 实际上是进入了 /hom ...
- python笔记-数学、元组、日期、文件
python在很多地方和C++相似,比如都会有关系.逻辑等运算符,但也有不同的地方,比如:#Python Number 类型转换int(x [,base ]) 将x转换为一个整数 long(x [,b ...
- HDU - 5755:Gambler Bo (开关问题,%3意义下的高斯消元)
pro:给定N*M的矩阵,每次操作一个位置,它会增加2,周围4个位置会增加1.给定初始状态,求一种方案,使得最后的数都为0:(%3意义下. sol:(N*M)^3的复杂度的居然过了. ...
- Python全栈之路----常用模块----hashlib加密模块
加密算法介绍 HASH Python全栈之路----hash函数 Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列 ...
- CrawlSpider模板
crawlSpider 创建CrawlSpider模板 scrapy genspider -t crawl <爬虫名字> <域名> 模板代码示例: # -*- coding: ...
- Java第五周总结
Java抽象类与接口的区别 很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题.本文我们将仔细讨论这些话题. 在讨论它们之间的不同点之前,我们先看 ...