前言

基于前一篇文章GeoServer系列-通过mongodb发布geojson数据,业务上可将常见的地理文件统一为geojson保存到mongodb,方便统一维护和发布geoserver,这一篇将举例cad格式转geojson。

1,必要的依赖

  • 文件转换和解析用到了gdal,需要先下载并配置环境变量(我用的3.3),安装后可使用以下命令查看版本

    C:\Users\CDLX>gdalinfo.exe --version
    GDAL 3.3.0, released 2021/04/26

  • pom引入

    <dependencies><dependency><groupId>org.gdal</groupId><artifactId>gdal</artifactId><version>3.2.0</version></dependency>
    </dependencies>
    <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.7</version>
    </dependency>
    

2,转换入口

    /*** dwg转geojson** @param fileName gdb文件名  xxx.dwg* @param fileMd5  文件md5值   1232131* @return*/@Overridepublic String dwgToJson(String fileName,String userId, String fileMd5) {String wsDirPath = fileDirectory + "/" + fileMd5 + userId;//文件名String dwgname = fileName.substring(0, fileName.lastIndexOf("."));String dwgpath = wsDirPath + "/" + fileName;//1,dwg转dxf D:\TS\temp\cadtest\cadtest.dxfString outFile = dwgpath.replace(".dwg", ".dxf");String res = dwg2dxf(dwgpath, outFile);if (res != null) {return res;}//2,dxf转换成json  D:\TS\temp\cadtest\cadtest.geojsonString jsonPath = outFile.replace(".dxf", "转换前.geojson");res = dxfToJson(outFile, jsonPath);if (res != null) {return res;}//3,坐标转换  D:\TS\temp\cadtest\cadtest转换.geojsonlong begin = System.currentTimeMillis();String newJsonPath = jsonPath.replace("转换前.geojson", "") + ".geojson";res = geoJsonCov(jsonPath, newJsonPath, dwgname);if (res != null) {return res;}long end = System.currentTimeMillis();log.info("dwg坐标转换耗时:{}", (end - begin));return null;}

3,dwg转dxf

    public String dwg2dxf(String dwgPath, String outFile) {File dwgFile = new File(dwgPath);if (dwgFile.exists()) {if (!dwgFile.getName().endsWith(".dwg")) {return "文件格式错误";}LoadOptions loadOptions = new LoadOptions();loadOptions.setSpecifiedEncoding(CodePages.SimpChinese);CadImage cadImage = (CadImage) Image.load(dwgFile.getAbsolutePath(), loadOptions);cadImage.save(outFile);cadImage.close();return null;} else {return "dwg文件不存在," + dwgPath;}}

4,dxf转geojson

    /*** dxf转json** @param dxfPath     D:\TS\sharding\filemd5\cadtest.dxf* @param geoJsonPath D:\TS\sharding\filemd5\cadtest.geojson*/public String dxfToJson(String dxfPath, String geoJsonPath) {ogr.RegisterAll();//支持中文路径gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");gdal.SetConfigOption("DXF_ENCODING", "UTF-8");//读取文件转化为DataSourceDataSource ds = ogr.Open(dxfPath, 0);if (ds == null) {return "打开文件失败," + dxfPath;}//获取geojsoDriver geojsonDriver = ogr.GetDriverByName("GeoJSON");DataSource geojsonDataSource = geojsonDriver.CopyDataSource(ds, geoJsonPath);geojsonDataSource.delete();ds.delete();return null;}

5,坐标转换(重点来了)

因为cad文件没有坐标系,需要预设一个坐标系,将上一步中geojson中的坐标进行转换

    /*** 坐标转换** @param geoJsonPath D:\\ITS\\Sharding\filemd5\xx.geojson* @param outputJson  D:\\ITS\\Sharding\filemd5\xx转换.geojson* @param dwgName     图层名称*/public String geoJsonCov(String geoJsonPath, String outputJson, String dwgName) {ogr.RegisterAll();gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");//支持中文路径gdal.SetConfigOption("DXF_ENCODING", "UTF-8");DataSource ds2 = ogr.Open(geoJsonPath, 0);System.out.println("----------坐标转换开始-----------");//读取第一个图层,这个图层不是cad中的layerLayer oLayer = ds2.GetLayerByIndex(0);if (oLayer == null) {log.error("从dwg的geojson中获取layer 获取失败:{}", geoJsonPath);ds2.delete();return "从dwg的geojson中获取layer 获取失败";}//新创建一个图层geojsonDriver geojsonDriver = ogr.GetDriverByName("GeoJSON");SpatialReference epsg2000 = new SpatialReference("");epsg2000.ImportFromEPSG(4490);DataSource dataSource = geojsonDriver.CreateDataSource(outputJson, null);Layer geojsonLayer = dataSource.CreateLayer(dwgName, epsg2000, ogrConstants.wkbUnknown, null);Feature feature;String geometryStr;String newGeometryStr;while ((feature = oLayer.GetNextFeature()) != null) {//获取空间属性Geometry geometry = feature.GetGeometryRef();// 解决自相交问题//geometry = geometry.Buffer(0.0);//System.out.println(geometry.ExportToJson());geometryStr = geometry.GetCurveGeometry().ExportToJson();if (geometryStr == null) {continue;}newGeometryStr = String.valueOf(paseCoordinates(geometryStr));Geometry newGeometry = Geometry.CreateFromJson(newGeometryStr);//传给新建的矢量图层Feature dstFeature = feature.Clone();dstFeature.SetGeometry(newGeometry);geojsonLayer.CreateFeature(dstFeature);}geojsonDriver.delete();ds2.delete();dataSource.delete();return null;}

6,一个朴实无华的逐行坐标转换

逐行读取geojson的Feature,遍历每个坐标

    /*** 转换每个Feature的坐标* @param coordinatesStr Feature原始json字符串* @return*/public StringBuffer paseCoordinates(String coordinatesStr) {//String a = "{ \"type\": \"Feature\", \"id\": 0, \"properties\": { \"Layer\": \"SXSS\", \"SubClasses\": \"AcDbEntity:AcDbBlockReference\", \"Linetype\": \"Continuous\", \"EntityHandle\": \"4F2\" }, \"geometry\": { \"type\": \"MultiLineString\", \"coordinates\": [ [ [ 406567.373450083076023, 3058272.568403942044824 ], [ 406565.039480640378315, 3058269.633257158566266 ] ], [ [ 406565.039480640378315, 3058269.633257158566266 ], [ 406565.597624949878082, 3058269.85315527068451 ] ], [ [ 406565.039480640378315, 3058269.633257158566266 ], [ 406565.128001464472618, 3058270.226590381469578 ] ] ] } }";int offset = coordinatesStr.indexOf("coordinates\":") + 13;String b = coordinatesStr.substring(offset);//System.out.println(b);String[] c = b.split("\\],");StringBuffer stringBuffer = new StringBuffer();int n = c.length;for (String d : c) {//System.out.println(d);int begin = d.lastIndexOf("[");int end = d.indexOf("]");String oldZb = d.substring(begin < 0 ? 0 : begin + 1, end < 0 ? d.length() - 1 : end - 1);//System.out.println(oldZb);String newZb = CadUtil.covStr(oldZb);//System.out.println(newZb);if (begin > 0) {stringBuffer.append(d, 0, begin + 1).append(newZb);}if (n != 1) {stringBuffer.append("]");}if (end > 0) {stringBuffer.append(d.substring(end - 1));}if (n > 1) {stringBuffer.append(",");}n--;}stringBuffer.insert(0, coordinatesStr.substring(0, offset));return stringBuffer;}

纠正经纬度颠倒问题

    public static String covStr(String zb) {String[] poi = zb.trim().split(",");double x = Double.parseDouble(poi[0]);double y = Double.parseDouble(poi[1]);//坐标经纬度交换if (x > y) {return dxfToSwapxy(x, y);} else {return dxfToSwapxy(y, x);}}

硬菜(x_x)

    /*** 坐标转换** @param X* @param Y* @return*/public static String dxfToSwapxy(double X, double Y) {double lat, lon;//中央子午线,结合这个网址进行查找,目前用的EPSG:4532中的123D。https://wenku.baidu.com/view/e219e246e3bd960590c69ec3d5bbfd0a7856d530.htmldouble L0 = 105;Y -= 500000;double[] result = new double[2];double iPI = 0.0174532925199433;//pi/180double a = 6378137.0; //长半轴 mdouble b = 6356752.31414; //短半轴 m//扁率 a-b/adouble e = 0.0818191910428; //第一偏心率 Math.sqrt(5)double ee = Math.sqrt(a * a - b * b) / b; //第二偏心率double bf = 0; //底点纬度double a0 = 1 + (3 * e * e / 4) + (45 * e * e * e * e / 64) + (175 * e * e * e * e * e * e / 256) + (11025 * e * e * e * e * e * e * e * e / 16384) + (43659 * e * e * e * e * e * e * e * e * e * e / 65536);double b0 = X / (a * (1 - e * e) * a0);double c1 = 3 * e * e / 8 + 3 * e * e * e * e / 16 + 213 * e * e * e * e * e * e / 2048 + 255 * e * e * e * e * e * e * e * e / 4096;double c2 = 21 * e * e * e * e / 256 + 21 * e * e * e * e * e * e / 256 + 533 * e * e * e * e * e * e * e * e / 8192;double c3 = 151 * e * e * e * e * e * e * e * e / 6144 + 151 * e * e * e * e * e * e * e * e / 4096;double c4 = 1097 * e * e * e * e * e * e * e * e / 131072;bf = b0 + c1 * Math.sin(2 * b0) + c2 * Math.sin(4 * b0) + c3 * Math.sin(6 * b0) + c4 * Math.sin(8 * b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...double tf = Math.tan(bf);double n2 = ee * ee * Math.cos(bf) * Math.cos(bf); //第二偏心率平方成bf余弦平方double c = a * a / b;double v = Math.sqrt(1 + ee * ee * Math.cos(bf) * Math.cos(bf));double mf = c / (v * v * v); //子午圈半径double nf = c / v;//卯酉圈半径//纬度计算lat = bf - (tf / (2 * mf) * Y) * (Y / nf) * (1 - 1 / 12 * (5 + 3 * tf * tf + n2 - 9 * n2 * tf * tf) * (Y * Y / (nf * nf)) + 1 / 360 * (61 + 90 * tf * tf + 45 * tf * tf * tf * tf) * (Y * Y * Y * Y / (nf * nf * nf * nf)));//经度偏差lon = 1 / (nf * Math.cos(bf)) * Y - (1 / (6 * nf * nf * nf * Math.cos(bf))) * (1 + 2 * tf * tf + n2) * Y * Y * Y + (1 / (120 * nf * nf * nf * nf * nf * Math.cos(bf))) * (5 + 28 * tf * tf + 24 * tf * tf * tf * tf) * Y * Y * Y * Y * Y;result[0] = retain6(lat / iPI);result[1] = retain6(L0 + lon / iPI);return result[1] + "," + result[0];}public static double retain6(double num) {String result = String.format("%.10f", num);//小数点后面保留10位小数return Double.valueOf(result);}

文件转换-cad转geojson相关推荐

  1. 如何将PDF文件转换CAD格式?

    设计师设计完图之后,为了方便接收者查看都会将CAD图纸的格式进行转换,一般将它转换成PDF格式,那么如何将CAD图纸转换为PDF格式呢?下面教你具体操作步骤. 1.先在电脑桌面上找到CAD转换器软件, ...

  2. java 毫秒转分钟和秒_PDF如何转换CAD文件?教你一分钟批量转上百文件方法,看完秒懂!...

    如今科技这么发达,很多人在工作中都会遇到形形色色的各类文件.而同时也因为工作需求碰到文件格式转换难题,如:PDF如何快速转换成CAD文件?今天小编就教大家一个方法,让你轻松一秒完成百个PDF文件转CA ...

  3. cad导出pdf_如何使用CAD手机看图软件将DWG格式图纸文件转换成PDF格式?

    在使用CAD手机看图软件修改好CAD图纸后想要发送给其他人,怎么将手机中DWG格式图纸文件转换成PDF格式呢?接下来就给大家介绍一下CAD手机看图软件浩辰CAD看图王手机版中将DWG格式图纸文件转换成 ...

  4. rpgmvp文件转换图片_干货|如何快速将图片转换成CAD文件格式

    文|阿锶 图|阿锶 hello,小伙伴们大家好!我是阿锶. 之前在第一篇文章中有跟大家提到过,阿锶是一名在校的建筑学高年级学生,所以必不可免要掌握CAD绘图. 最近,在做山地旅馆建筑设计,拿到的地形图 ...

  5. java使用aspose-cad将CAD的dwg文件转换png等格式

    第一步 引入jar包 需要引入官方库,放置于<dependencies>上即可 <repositories><repository><id>aspose ...

  6. CAD转换技巧:高版本CAD文件转换成低版本在线版最简单

    CAD版本转换,在接触CAD的工作中是常见的问题了,因为CAD系统兼容的问题,有的图纸在另一个软件中根本打不开,到现在一直没有一个系统的快速解决方法,重要的是现在很多的转换软件都是要收费的好吗?不过不 ...

  7. 怎么转换CAD文件的版本?分享两种转换版本的方法

    CAD文件的版本怎么转换呢?大家如果有使用CAD编辑软件的小伙伴肯定遇到过CAD文件打不开的现象,出现这种情况如果排除了文件自身收到损坏之外,那么大概率就是CAD文件的版本问题了,遇到低版本或高版本的 ...

  8. cad转dxf格式文件太大,怎样操作将多张CAD图纸文件转换成高版本的DXF格式?

    怎样操作将多张CAD图纸文件转换成高版本的DXF格式?CAD图纸文件版本过低会导致其无法进行打开查看,那么这个时候就需要将其进行版本间的转换了,具体应该怎么进行操作,接下来小编就要来教大家的就是怎样操 ...

  9. PDF转CAD怎么弄?PDF文件转换快速入门

    PDF转CAD怎么弄?相信大家在做设计的时候肯定遇到过这种情况,就接到一个室内设计的项目,由于面积较大,或者形状不规则,现场量尺比较麻烦,善解人意的甲方提供了原建筑图纸,当你满心欢喜的收到图纸后,却发 ...

最新文章

  1. 与或非逻辑符号_理解FPGA的基础知识——逻辑电路
  2. shell字体颜色应用
  3. SQLAlchemy Tutorial
  4. leetcode 7. 反转整数(python3)
  5. corosync +drbd实现HA MariaDB
  6. Atitit.js的键盘按键事件捆绑and事件调度
  7. [基础控件]---状态切换控件CompoundButton及其子类CheckBox、RadioButton、ToggleButton、switch事件监听与场景使用...
  8. Javascript中的运算符及其优先级顺序
  9. 西安省某小学能耗监测及电力监控系统的研究与应用
  10. 是时候放弃循环神经网络了
  11. 未完成的IT路停在回车键---2014年末总结篇
  12. android 设备注册,Android平台上PMEM的使用及Platform设备注册(二)
  13. 电子合同是什么意思,电子合同怎么签才有效?
  14. 穆穆推荐-软件销售行业软件公司销售参考操作手册-之2-软件公司销售团队的组建及岗位分类
  15. linux vim粘贴和复制文件,【linux】vim怎么粘贴其他地方复制的代码?
  16. 写点东西祭奠老师这个职业
  17. 云浮农村生活污水处理设备——水生态环境保护“十四五”规划
  18. taro标签_Taro自定义标签栏TabBar
  19. 夏天一直流汗,做近视矫正手术会有影响吗?
  20. Go解密之路——GPM

热门文章

  1. oracle solaris cluster 4,在sun solaris suncluster and volume manger环境下的ORACLE数据库表空间的扩容...
  2. 如何将文字转化为语音?三种方法超级简单,立刻就能学会!
  3. HTML5+app开发学习之快速入门篇
  4. PX4开发指南中文版维护说明
  5. 如何选择靠谱的游戏联运系统?
  6. LeetCode17:电话号码的字母组合(Javascript 解答)
  7. Unity3D关于如何使用iTween制作各种简易动画 (官方例子的解释)
  8. 蓝牙ble学习开发资料
  9. Edius7下载,安装,破解完整
  10. 计算机现代教育三大特征,现代教育技术试题和答案