1、下载gdal
https://www.gisinternals.com/archive.php 打开官方下载地址。
我下载的是3.8.5版本,MSVC2022,x64,release-1930-x64-gdal-3-8-5-mapserver-8-0-1,区别不大,自身系统比较低的下载低版本。
进入3.8.5的下载列表,我选择的第一个,编译后的二进制压缩包
解压压缩包,cmd进入命令行C:\Users\HIGHGO\Desktop\GIS\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin\gdal\apps
查看支持格式.
ogr2ogr --formats
1.2、配置环境变量
添加PATH,3个
G:\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin
G:\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin\gdal\apps
G:\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin\gdal-data
添加GDAL_DATA
G:\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin\gdal-data
添加PROJ_LIB
G:\release-1930-x64-gdal-3-8-5-mapserver-8-0-1\bin\proj9\share
2、导入shp
#导入shp-linux
ogr2ogr -f "PostgreSQL" PG:"host='127.0.0.1' dbname='xxxxxx' user='xxxxx' password='xxxxx@123' port=5432" /opt/110m_physical/ne_110m_ocean.shp
#导入shp-win
ogr2ogr -f "PostgreSQL" PG:"host='xxxxxx' dbname='postgres' user='postgres' password='postgres' port=5432" C:\Users\HIGHGO\Desktop\GIS\data\NewYork\110m_physical\ne_110m_ocean.shp
3、导入xlsx
#导入xls-linux
ogr2ogr -f "PostgreSQL" PG:"host='127.0.0.1' dbname='highgo' user='sysdba' password='Test@123' port=5866" /opt/dltbxz_tqmj.xlsx
#导入xls-win
ogr2ogr -f "PostgreSQL" PG:"host='192.168.110.217' dbname='postgres' user='postgres' password='postgres' port=5432" C:\Users\HIGHGO\Desktop\GIS\data\dltbxz_tqmj.xlsx
4、导入gdb
#导入gdb-win
ogr2ogr -f "PostgreSQL" PG:"host='192.168.110.217' dbname='postgres' user='postgres' password='postgres' port=5432" C:\Users\HIGHGO\Desktop\GIS\data\test_highgo.gdb -nln chinasheng -overwrite chinasheng -progress -lco GEOMETRY_NAME=geom --config PG_USE_COPY YES
5、java调用(非最优方法)
注明:本方法只是快速使用,尽量不改变jdk目录结构,如果使用框架或更深入,请采用其他方法。
把gdal.jar和gdalalljni.dll拷贝到项目的lib下,然后配置maven
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>3.8.5</version>
<scope>system</scope>
<systemPath>E:\space\workspace4.30\test/lib/gdal.jar</systemPath>
</dependency>
添加运行参数
gdal把shp导入pg数据库
package test;
import org.gdal.gdal.gdal;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.Layer;
import org.gdal.ogr.ogr;
public class ShapefileToPostgres {
public static void main(String[] args) {
// 初始化 GDAL 和 OGR
gdal.AllRegister();
ogr.RegisterAll();
// Shapefile 的路径
String shpFilePath = "C:/Users/HIGHGO/Desktop/GIS/data/NewYork/110m_physical/ne_110m_coastline.shp";
// PostgreSQL 的连接字符串
String pgConnectionString = "PG:host=192.168.110.217 user=postgres dbname=postgres password=postgres";
// 打开 Shapefile 数据源
DataSource shpDataSource = ogr.Open(shpFilePath, 0); // 0 表示只读
if (shpDataSource == null) {
System.err.println("无法打开 Shapefile 文件: " + shpFilePath);
return;
}
// 打开 PostgreSQL 数据源
DataSource pgDataSource = ogr.Open(pgConnectionString, 1); // 1 表示读写
if (pgDataSource == null) {
System.err.println("无法连接 PostgreSQL 数据库: " + pgConnectionString);
return;
}
// 获取 Shapefile 中的第一个图层
Layer shpLayer = shpDataSource.GetLayer(0);
// 创建 PostgreSQL 图层,名称为 Shapefile 图层的名称
String layerName = shpLayer.GetName();
Layer pgLayer = pgDataSource.CreateLayer(layerName, shpLayer.GetSpatialRef(), shpLayer.GetGeomType());
if (pgLayer == null) {
System.err.println("无法在 PostgreSQL 中创建图层: " + layerName);
return;
}
// 将 Shapefile 中的每个字段添加到 PostgreSQL 图层中
for (int i = 0; i < shpLayer.GetLayerDefn().GetFieldCount(); i++) {
pgLayer.CreateField(shpLayer.GetLayerDefn().GetFieldDefn(i));
}
// 开始复制 Shapefile 中的每个要素到 PostgreSQL 图层
shpLayer.ResetReading();
org.gdal.ogr.Feature feature;
while ((feature = shpLayer.GetNextFeature()) != null) {
// 克隆要素以插入到 PostgreSQL 图层
org.gdal.ogr.Feature pgFeature = feature.Clone();
pgLayer.CreateFeature(pgFeature);
// 清理资源
pgFeature.delete();
feature.delete();
}
// 关闭数据源
shpDataSource.delete();
pgDataSource.delete();
System.out.println("Shapefile 成功导入 PostgreSQL 数据库!");
}
}
不添加运行参数的方法
1、把gdal.jar和gdalalljni.dll文件拷贝到项目的resources目录下,然后再java代码中调用。
2、java从资源文件加载
package gdal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* 动态库加载类:从资源加载动态库
**/
public class LibraryUtil {
private static final Logger log = LoggerFactory.getLogger(LibraryUtil.class);
/**
* 从资源文件加载类
* * @param clazz jar中类
* @param file resources目录下文件全路径:/gdal/win32/gdalalljni.dll
*/
public static void loadFromResource(String file) throws IOException{
try {
//获取系统路径
String[] libraryPaths=initializePath("java.library.path");
// log.info("---LibraryUtil-----java.library.path={}",StringUtil.join(";", libraryPaths));
if(libraryPaths==null||libraryPaths.length==0) {
log.info("---LibraryUtil--请设置环境变量java.library.path");
return;
}
String nativeTempDir=libraryPaths[0];
int sepIndex=file.lastIndexOf(File.separator);
if(sepIndex==-1) {
sepIndex=file.lastIndexOf("/");
}
String fileName=file.substring(sepIndex+1);
log.info("---LibraryUtil--从环境变量{}加载{}",nativeTempDir,fileName);
//系统库不存在,就从资源文件复制
File extractedLibFile = new File(nativeTempDir+File.separator +fileName);
if(!extractedLibFile.exists()){
//file resources目录下文件全路径:/gdal/windows/gdalalljni.dll
InputStream in = LibraryUtil.class.getResourceAsStream(file);
if(in==null) {
log.info("---LibraryUtil--资源文件不存在{}",file);
throw new FileNotFoundException(file);
}
saveFile(in,extractedLibFile);
//保存文件到java.library.path
log.info("---LibraryUtil--成功保存文件{}到{}",fileName,extractedLibFile.getPath());
}
//注意采用loadLibrary加载时mapLibraryName方法会根据系统补全名称
int startIndex=fileName.startsWith("lib")?3:0;
String libName=fileName.substring(startIndex,fileName.indexOf("."));
String mapLibraryName=System.mapLibraryName(libName);
log.info("---LibraryUtil--mapLibraryName={}",mapLibraryName);
//输出调试信息
log.info("---LibraryUtil--系统加载动态库{}开始",libName);
System.loadLibrary(libName);
log.info("---LibraryUtil--系统加载动态库{}完成",libName);
}
catch(Exception ex) {
log.error(ex.getMessage());
}
}
private static String[] initializePath(String propname) {
String ldpath = System.getProperty(propname, "");
String ps = File.pathSeparator;
int ldlen = ldpath.length();
int i, j, n;
// Count the separators in the path
i = ldpath.indexOf(ps);
n = 0;
while (i >= 0) {
n++;
i = ldpath.indexOf(ps, i + 1);
}
// allocate the array of paths - n :'s = n + 1 path elements
String[] paths = new String[n + 1];
// Fill the array with paths from the ldpath
n = i = 0;
j = ldpath.indexOf(ps);
while (j >= 0) {
if (j - i > 0) {
paths[n++] = ldpath.substring(i, j);
} else if (j - i == 0) {
paths[n++] = ".";
}
i = j + 1;
j = ldpath.indexOf(ps, i);
}
paths[n] = ldpath.substring(i, ldlen);
return paths;
}
public static void saveFile(InputStream in, File extractedLibFile) throws IOException{
BufferedInputStream reader = null;
FileOutputStream writer = null;
try {
//文件不存在创建文件,否则获取流报异常
createFile(extractedLibFile);
reader = new BufferedInputStream(in);
writer = new FileOutputStream(extractedLibFile);
byte[] buffer = new byte[1024];
while (reader.read(buffer) > 0){
writer.write(buffer);
buffer = new byte[1024];
}
} catch (IOException e){
throw e;
} finally {
if(in!=null)
in.close();
if(writer!=null)
writer.close();
}
}
/**
* 文件不存在创建文件,包括上级目录
*/
public static void createFile(File destFile) throws IOException{
File pfile = destFile.getParentFile();
if (!pfile.exists()) {
pfile.mkdirs();
}
if(!destFile.exists()){
destFile.createNewFile();
}
}
}
主程序启动
package test;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.Driver;
import org.gdal.ogr.Layer;
import org.gdal.ogr.ogr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import gdal.LibraryUtil;
import org.gdal.gdal.gdal;
public class GdalShapeImport {
private static final Logger log = LoggerFactory.getLogger(GdalShapeImport.class);
static {
log.info("---LibraryUtil--gdal载入动态库");
try {
//根据系统环境加载资源
String systemType = System.getProperty("os.name");
String file="";
boolean isWin=systemType.toLowerCase().indexOf("win")!=-1;
if(isWin) {
file="/gdal/gdalalljni.dll";
}
else {
file="/gdal/libgdalalljni.so";
}
//从资源文件加载动态库
LibraryUtil.loadFromResource(file);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String shpFileName="C:\\Users\\HIGHGO\\Desktop\\GIS\\data\\NewYork\\10m_cultural\\ne_10m_roads_north_america.shp";
String geojsonFileName="C:\\Users\\HIGHGO\\Desktop\\GIS\\data\\NewYork\\zzt_headCells.geojson";
shpToGeojson(shpFileName,geojsonFileName);
}
/**
* shp转换geojson
* @param shpFileName
* @param geojsonFileName
*/
public static void shpToGeojson(String shpFileName,String geojsonFileName) {
// 注册所有的驱动
ogr.RegisterAll();
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING","");
//打开数据
DataSource ds = ogr.Open(shpFileName,0);
if (ds == null){
System.out.println("打开文件"+shpFileName+"失败!" );
return;
}
System.out.println("打开文件成功!" );
org.gdal.ogr.Driver dv = ogr.GetDriverByName("GeoJSON");
if (dv == null){
System.out.println("打开驱动失败!" );
return;
}
System.out.println("打开驱动成功!" );
//输出geojson的位置及文件名
dv.CopyDataSource(ds, geojsonFileName);
System.out.println("转换成功!");
}
}