ToB企服应用市场:ToB评测及商务社交产业平台

标题: 搭建GDAL JAVA环境;DXF转KML;坐标转换;PROJ: proj_create_from_database [打印本页]

作者: 天津储鑫盛钢材现货供应商    时间: 2024-1-8 17:57
标题: 搭建GDAL JAVA环境;DXF转KML;坐标转换;PROJ: proj_create_from_database
搭建JAVA  GDAL环境

GDAL是一个栅格和矢量地理空间数据格式的转换库,由开源地理空间基金会按照MIT开源协议发布。作为一个库,它向应用程序为所有支持的数据格式提供统一的栅格抽象数据模型和矢量抽象数据模型。它还提供了用于数据转换和处理的各种有用的命令行实用工具。
GDAL官网: GDAL — GDAL documentation
中文官网:GDAL — GDAL 文档 (osgeo.cn)
下载安装

GISInternals 下载GDAL生产环境包
GISInternals is an online system for creating daily built binary packages for the GDAL and MapServer projects.
GISIinternals是一个在线系统,用于为GDAL和MapServer项目创建每日构建的二进制包。
打开上述地址后,根据自己系统选择对应的版本

本地部署

使用GDAL命令行

这个库分为两大部分是GDAL和OGR,分别管理着栅格和矢量数据。底层是c语言,上层可以是多种语言(包括python,java等)调用,下方是(栅格和矢量)数据处理的中文索引,以及中文帮助;
附官网数据来源:栅格:栅格raster— GDAL 文档矢量Programs — GDAL documentation
栅格

矢量

使用JAVA读取DXF文件并转为KML



  1. import org.gdal.gdal.gdal;
  2. import org.gdal.ogr.ogr;
  3. //测试案例
  4. class GdalDemo {
  5.         //获取所有驱动的名称并打印
  6.         public void printDriver() {
  7.                 gdal.AllRegister();
  8.                 int count = ogr.GetDriverCount();
  9.                 for (int i = 0; i < count; i++) {
  10.                         String driverName = ogr.GetDriver(i).getName();
  11.                         System.out.print(driverName + "\t");
  12.                 }
  13.                 gdal.GDALDestroyDriverManager();
  14.         }
  15.         public static void main(String[] args) {
  16.                 GdalDemo demo = new GdalDemo();
  17.                 demo.printDriver();
  18.         }
  19. }
复制代码

  1. /**
  2. * 使用gdal 解析dxf,并将数据读取转为KML 或 GEOJSON
  3. * 包含坐标转换
  4. */
  5. public class DXFToGeoJSONConverter {
  6.     public static void main(String[] args) {
  7.         Boolean converter = converter("E://test//1.kml", "E://test//白马2000-3-108.dxf");
  8.         if (converter) {
  9.             System.out.println("成功");
  10.         } else {
  11.             System.out.println("失败");
  12.         }
  13.     }
  14.     /**
  15.      *
  16.      * @param outPath 输出文件全路径
  17.      * @param inPath  读取文件全路径
  18.      * @return
  19.      */
  20.     public static Boolean converter(String outPath, String inPath) {
  21.         // 注册所有的驱动
  22.         //gdal.AllRegister();
  23.         ogr.RegisterAll();
  24.         gdal.SetConfigOption("DWG_ENCODING", "UTF-8");//DWG文件编码
  25.         gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");//支持中文路径
  26.         gdal.SetConfigOption("SHAPE_ENCODING", "CP936");//属性表字段支持中文
  27.         DataSource dataSource = ogr.Open(inPath, 0);
  28.         if (dataSource == null) {
  29.             System.out.println("打开文件失败!" + gdal.GetLastErrorMsg());
  30.             return false;
  31.         }
  32.         System.out.println("打开文件成功!");
  33.         //构造坐标系转换对象
  34.         SpatialReference src = new SpatialReference();
  35. //        src.ImportFromProj4("+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
  36.         src.ImportFromEPSG(4545); // CGCS2000 中央经线 108 3分带  36带
  37.         System.out.println("原坐标系:" + src.ExportToProj4());
  38.         SpatialReference dest = new SpatialReference();
  39.         dest.ImportFromEPSG(4326); // WGS84
  40.         System.out.println("目标坐标系:" + dest.ExportToProj4());
  41. //        SpatialReference dest = dest1.CloneGeogCS();
  42.         CoordinateTransformation transformation = new CoordinateTransformation(src, dest);//源,目标
  43.         //1.创建驱动程序
  44.         Driver dv = ogr.GetDriverByName("KML"); //直接转KML
  45. //        Driver dv = ogr.GetDriverByName("GeoJSON"); //直接转GEOJSON
  46.         int layerCount = dataSource.GetLayerCount();
  47.         System.out.println("总图层数:" + layerCount);
  48.         DataSource ds = dv.CreateDataSource(outPath);
  49.         for (int i = 0; i < layerCount; i++) {
  50.             // 2.循环读取每个图层
  51.             Layer inLayer = dataSource.GetLayerByIndex(i);
  52.             if (inLayer == null) {
  53.                 continue;
  54.             }
  55.             String layerName = inLayer.GetName();
  56.             //3.每个DataSource创建一个输出的layer
  57.             Layer outLayer = ds.CreateLayer(layerName, dest, ogrConstants.wkbUnknown, null);
  58.             long featureCount = inLayer.GetFeatureCount();
  59.             System.out.println("总图形数:" + featureCount);
  60.             for (long j = 0; j < featureCount; j++) {
  61.                 Feature feature = inLayer.GetFeature(j);
  62.                 feature.GetStyleString();
  63.                 //4.获取输入的几何对象,调用其转换方法,转换后存入新的layer中
  64.                 Geometry geometry = feature.GetGeometryRef();
  65.                 geometry.Transform(transformation);
  66.                 //注意,转换为后时 经度 纬度 的顺序,如果需要纬度在前,需要交换xy
  67.                 //  geometry.SwapXY();
  68.                 geometry.CloseRings();
  69.                 outLayer.CreateFeature(feature);
  70.             }
  71.         }
  72.         System.out.println("转换成功!!!");
  73.         return true;
  74.     }
  75. }
复制代码
GDAL坐标转换
  1. /**
  2. * 用gdal进行坐标转换
  3. */
  4. public class CoordinateTransformationExample {
  5.     public static void main(String[] args) {
  6.         // 注册GDAL驱动
  7.         gdal.AllRegister();
  8.         // 输入的坐标
  9.         double inputX = 36587998.113885;
  10.         double inputY = 3796047.384520;
  11.         // 创建源坐标系统 (CGCS2000 3度带,中央经线108)
  12.         SpatialReference srcSRS = new SpatialReference();
  13.         srcSRS.ImportFromProj4("+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
  14.         // 创建目标坐标系统 (WGS84)
  15.         SpatialReference tgtSRS = new SpatialReference();
  16.         tgtSRS.ImportFromEPSG(4326);
  17.         // 创建坐标转换对象
  18.         CoordinateTransformation transformation = new CoordinateTransformation(srcSRS, tgtSRS);
  19.         // 执行坐标转换
  20.         double[] transformedCoords = transformation.TransformPoint(inputX, inputY);
  21.         // 输出转换后的经纬度 (转换后经纬度位置交换了,注意不要取错参数)
  22.         System.out.println("Transformed Coordinates (WGS84):");
  23.         System.out.println("Longitude: " + transformedCoords[1]);
  24.         System.out.println("Latitude: " + transformedCoords[0]);
  25.     }
  26. }
复制代码
可能遇到的错误
  1. ERROR 1: PROJ: proj_create_from_database: D:\ideawork\pkgs\proj-6.2.1-h9f7ef89_0\Library\share\proj\proj.db lacks DATABASE.LAYOUT.VERSION.MAJOR / DATABASE.LAYOUT.VERSION.MINOR metadata. It comes from another PROJ installation.
复制代码
原因分析:
使用osgeo.osr能够直接从安装的GDAL包读取指定投影类型的信息,在proj.db中存储了常用的投影系统的参数,因此指定EPSG号就能从proj.db中取到投影信息。
经过排查,我的情况是在开发环境中同时安装了GDAL和其他地理空间库(如PostGresql),此时同一环境路径下可能会产生多个proj.db文件,访问它的时候程序会无法判断访问哪个。因此只需要去查找gdal安装的那个proj.db在哪里,在程序中指定环境变量即可解决
解决方法:



其他参考文章:
Gdal 之 dxf转geojson (附加坐标转换)
gdal for java 从安装到各种案例demo实现
GDAL JAVA 开发文档

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4