文件转换-cad转geojson
Posted 占星安啦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件转换-cad转geojson相关的知识,希望对你有一定的参考价值。
前言
基于前一篇文章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
*/
@Override
public 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.dxf
String outFile = dwgpath.replace(".dwg", ".dxf");
String res = dwg2dxf(dwgpath, outFile);
if (res != null)
return res;
//2,dxf转换成json D:\\TS\\temp\\cadtest\\cadtest.geojson
String jsonPath = outFile.replace(".dxf", "转换前.geojson");
res = dxfToJson(outFile, jsonPath);
if (res != null)
return res;
//3,坐标转换 D:\\TS\\temp\\cadtest\\cadtest转换.geojson
long 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");
//读取文件转化为DataSource
DataSource ds = ogr.Open(dxfPath, 0);
if (ds == null)
return "打开文件失败," + dxfPath;
//获取geojso
Driver 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中的layer
Layer oLayer = ds2.GetLayerByIndex(0);
if (oLayer == null)
log.error("从dwg的geojson中获取layer 获取失败:", geoJsonPath);
ds2.delete();
return "从dwg的geojson中获取layer 获取失败";
//新创建一个图层geojson
Driver 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.html
double L0 = 105;
Y -= 500000;
double[] result = new double[2];
double iPI = 0.0174532925199433;//pi/180
double a = 6378137.0; //长半轴 m
double b = 6356752.31414; //短半轴 m
//扁率 a-b/a
double 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转图片怎么转?教你快速转换方法
工作中会遇到很多的问题,就比如说在CAD中就需要将CAD文件的格式进行来回的转换,常见的就是CAD转换为图片格式的。下面来教大家快速转换的方法。具体操作如下:
转换方法:
1.打开需要使用的CAD工具来转换图纸文件的格式,之后就会进入到CAD的首页界面中,选择左侧文件转换功能区的“CAD转图片”选项。
.
2.添加需要转换的文件,想要方便的小伙伴们可以直接将转换的文件拖拽到CAD界面中进行转换。或者也可以选择界面中的“添加文件”选项进行点击,在跳转出的界面中添加好要转换的文件。
3.将其文件添加完成后,在输入目录中选择“浏览”按钮,设置好图片转换后需要保存的位置。这样方便实用的时候进行查找。
4.在CAD软件右下角中的输出格式中,有七种转换图片的格式。根据工作需要来设置图片转换的格式,这里就以JPG格式为例。为了不让转换文件中的字体模糊,在转换前将“页面大小”调整到最大值进行转换。
5.然后就可以选择“批量转换”按钮进行点击,稍微等待几分钟后,在状态栏中就会显示文件转换完成。
转换后预览文件方法:
1.点击文件后的“预览”选项,在界面弹出的页面中就可以查看到转换后的JPG图片的效果展示。
2.点击“图层”选项,查看文件的的图层,之后在退出预览界面就可以了。
好了,以上就是给大家整理的CAD转图片的的转换方法,希望在大家繁忙的工作中对大家有所帮助,感兴趣的伙伴们可以去试一试哈。
以上是关于文件转换-cad转geojson的主要内容,如果未能解决你的问题,请参考以下文章