利用java调用python相关库读取dwg文件坐标

507 阅读3分钟

需求:在项目中甲方的测绘图纸很多是用cad进行存储,希望能有一个功能对cad文件坐标信息进行提取并绘制在前端与相关图层叠加等

难点:先前找了一些java的开源cad读取库但都对cad的版本支持不全,且有些已经很久无维护,后面采用了arcgis的arcpy进行dwg文件处理解析成geojson,虽然依赖于arcgis但对dwg版本支持全面。

代码: python:主要思路是读取cad文件,并传入对应的dwg文件路径和dwg坐标系以及你想输出的坐标系.其中涉及坐标定义,坐标转换,cad色号转换,dwg属性过滤,最终geojson生成的路径可以固定也可以用输入参数控制。

# coding=utf-8
import arcpy
import sys
import json

reload(sys)
sys.setdefaultencoding('utf-8')
# 默认覆盖
arcpy.env.overwriteOutput = True

dwg_spatial = None
out_spatial = None
filterArr = ["村界线","涵管","沟","渠","道","路","桥","水","地块","槽"]
def contains_item_fuzzy(char_to_find):
    return any(item in char_to_find  for item in filterArr)

def tranformPolygon(arr):
    array = arcpy.Array([arcpy.Point(*coords) for coords in arr])
    fs = arcpy.Polygon(array, dwg_spatial)
    js = fs.projectAs(out_spatial)
    return js.JSON
def tranformPolyLine(arr):
    array = arcpy.Array([arcpy.Point(*coords) for coords in arr])
    fs = arcpy.Polyline(array, dwg_spatial)
    js = fs.projectAs(out_spatial)
    return js.JSON

def getColorFromCad(type):
    if type == 1:
        return "rgb(255 0 0)"
    if type == 2:
        return "rgb(255 255 0)"
    if type == 3:
        return "rgb(0 255 255)"
    if type == 4 or type == 151: #范围线 沟渠
        return "rgb(0 255 255)"
    if type == 5:
        return "rgb(0 0 255)"
    if type == 6:
        return "rgb(255 0 255)"
    if type == 7 or type == -2: #村界线
        return "rgb(0 0 0)" #黑色
    if type == 8:
        return "rgb(128 128 128)"
    if type == 9:
        return "rgb(192 192 192)"
    if type == 10:
        return "rgb(255 0 0)"
    if type == 11:
        return "rgb(255 127 127)"
    if type == 15:
        return "rgb(153 76 76)"
    if type == 131:
        return "rgb(153 76 76)"
    if type == 154:
        return "rgb(0 76 153)"
    return None


def cadToJson(filePath):
    try:
        # 加载dwg数据
        arcpy.env.workspace = filePath
        layers = arcpy.ListFeatureClasses()
        datas = {
            "type": "FeatureCollection",
            "features": []
        }
        for fc in layers:
            if fc == "Polyline" or fc == "Polygon":
                with arcpy.da.SearchCursor(fc, ["SHAPE@JSON", "Layer", "Color"], "", dwg_spatial) as cursor:
                    for row in cursor:
                        bool = fc == "Polygon"
                        isColor = getColorFromCad(row[2])
                        if row[0] is not None and isColor is not None and contains_item_fuzzy(row[1]) :
                            geom = {
                                "type":"Feature",
                                "properties":{
                                    "name": row[1],
                                    "color": getColorFromCad(row[2])
                                },
                                "geometry":{
                                    "type":"",
                                    "coordinates":""
                                },
                            }
                            if bool:
                                geom["geometry"]['type'] = "Polygon"
                                geom["geometry"]['coordinates'] = [eval(tranformPolygon(eval(row[0])["rings"][0]))["rings"][0]]
                                datas.get('features').append(geom)
                            else:
                                geom["geometry"]['type'] = "LineString"
                                geom["geometry"]['coordinates'] = eval(tranformPolyLine(eval(row[0])["paths"][0]))["paths"][0]
                                datas.get('features').append(geom)
        # 将数据保存到json文件
        with open('E:\work\git\cadServices/cads/data.json', 'w') as json_file:
            json.dump(datas, json_file)
        print ("success")
    except Exception as err:
        print("error")


if __name__ == '__main__':
    try:
        arg1 = sys.argv[1]  # dwg文件路径
        arg2 = sys.argv[2]  # dwg文件坐标系
        arg3 = sys.argv[3]  # 输出坐标系
        if arg2 :
            arg2 = int(arg2)
        if arg3 :
            arg3 = int(arg3)
        dwg_spatial = arcpy.SpatialReference(arg2 or 4526)
        out_spatial = arcpy.SpatialReference(arg3 or 4490)
        if arg1:
            cadToJson(arg1)
    except Exception as err:
        print ("请传必须参数", err)

java代码片段: 采用springboot框架,获取dwg文件,并调用写的python进行处理获取返回geojson。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.cadservices.untils.ResponseModel;
import java.io.*;
@Service
public class CadServices {

    @Value("${python.env_path}")
    private String pythonEnvPath;
    @Value("${python.code_path}")
    private String pythonCodePath;
    @Value("${dwg_spatial}")
    private String dwgSpatial;
    @Value("${out_spatial}")
    private String outSpatial;

    //默认保存在当前项目下
    private String workPath = System.getProperty("user.dir")+"/cads/";
    //cad解析成json
    public ResponseModel getCadToJson(MultipartFile multipartFile) throws Exception{
        ResponseModel responseModel;
        File file = new File(workPath+"cad.dwg");
        try{
            //ae许可初
            multipartFile.transferTo(file);
            String cmds = String.format("%s %s  %s %s %s",pythonEnvPath,pythonCodePath,workPath+"cad.dwg",dwgSpatial,outSpatial);
            Process pcs = Runtime.getRuntime().exec(cmds);
            pcs.waitFor();
            StringBuilder res = new StringBuilder();
            BufferedInputStream bis = new BufferedInputStream(pcs.getInputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(bis));
            String lineStr = "";
            while ((lineStr = br.readLine()) != null) {
                res.append(lineStr);
            }
            br.close();
            bis.close();
            StringBuilder jsonStr= new StringBuilder();
            if(res.toString().equals("success")){
                FileReader fileReader = new FileReader(workPath+"data.json");
                BufferedReader jsonBr = new BufferedReader(fileReader);
                String str="";
                while ((str = jsonBr.readLine()) != null){
                    jsonStr.append(str);
                }
                responseModel = new ResponseModel(200,jsonStr.toString(),"success");
                jsonBr.close();
                fileReader.close();
            }else{
                responseModel = new ResponseModel(500,null, res.toString());
            }
            return responseModel;
        } catch (IOException e) {
            responseModel = new ResponseModel(500,null,e.getMessage());
            return responseModel;
        }finally{
            file.delete();
        }
    }
}