使用Java生成DXF格式文件

JAVA DXF 库

  Java JDXF 库支持使用标准 Java AWT 图形“绘制”和“填充”命令生成用于 CAD 程序的 DXF 文件。该库提供了一个特殊的 Graphics2D 子类 DXFGraphics,它与 DXF 文档相关联,并将绘制命令呈现为 DXF 语法。因此,对 DXFGraphics 实例的一系列标准 Java 图形绘图方法调用将创建一个结构化的 DXF 文档,当使用标准 CAD 程序打开该文档时,该文档会将 Java 图像显示为可在 CAD 程序中修改的 CAD 设计。

地址:jdxf库

将jdxf的最新分支拉过来之后,可以使用maven命令,将其放入我们本地的仓库方便后面自己的使用

放入本地:mvn install:install-file -Dfile=path\jdxf\jdxf.jar -DgroupId=com.example.jdxf -DartifactId=jdxf -Dversion=1.0.0 -Dpackaging=jar

在项目的pom文件中使用:

<dependency>
     <groupId>com.example.jdxf</groupId>
      <artifactId>jdxf</artifactId>
      <version>1.0.0</version>
</dependency>

项目代码如下:

1.编写entity用于接受所转换CAD图像的实体线,点对象。

@Data
@AllArgsConstructor
public class PipeVo {

    private String subType;

    private String material;

    private String addr;

    private String geom;
}

2.编写工具类,用于坐标转换类型转换等。

public class WktUtils {


    public static Geometry wktToGeom(String wkt) throws ParseException {
        WKTReader reader = new WKTReader();
        if (wkt.contains("SRID"))
            wkt = wkt.substring(wkt.indexOf(";")+1);
        return reader.read(wkt);
    }
    /**
     * @param wkt 
     * 将数据库中取得的ewkt字符转为RealPoint对象
     * */
    public static List<List<RealPoint>> lineToRealPoint(String wkt) throws ParseException {
        List<List<RealPoint>> list = new ArrayList<>();
        WKTReader reader = new WKTReader();
        if (wkt.contains("SRID"))
            wkt = wkt.substring(wkt.indexOf(";")+1);
        Geometry geom = reader.read(wkt);
        String d = geom.getGeometryType();
        if ("MultiLineString".equals(geom.getGeometryType())) {
            MultiLineString lines = (MultiLineString)geom;
            int num = lines.getNumGeometries();
            for(int i = 0;i<num;i++){
                List<RealPoint> temp = new ArrayList<>();
                Arrays.stream(lines.getGeometryN(i).getCoordinates()).forEach(e->temp.add(new RealPoint(e.x,e.y,0)));
                list.add(temp);
            }
        }else{
            LineString lines = (LineString) geom;
            List<RealPoint> temp = new ArrayList<>();
            Arrays.stream(lines.getCoordinates()).forEach(e->temp.add(new RealPoint(e.x,e.y,0)));
            list.add(temp);
        }
        return list;
    }

    /**
     * @param start 线起点坐标
     * @param end 线终点坐标
     * 用于计算注释的基点坐标
     * */
    public static RealPoint getBasePoint(RealPoint start,RealPoint end){
        return new RealPoint((start.x+end.x)/2,(start.y+end.y)/2,0);
    }

    public static double getAngle(RealPoint start,RealPoint end){
        return Math.atan((end.y- start.y)/(end.x-start.x));
    }

    public static double getLength(RealPoint start,RealPoint end){
        double var1 = (end.y- start.y)*(end.y- start.y)+(end.x-start.x)*(end.x-start.x);
        return Math.atan(var1);
    }
}

3.编写业务层,将数据库中的对象转为CAD的对象并写入DXF文件。

public interface CADService{
    void transformCad(String filePath);
}

4.具体实现的代码

@Service
@RequiredArgsConstructor
public class CADServiceImpl extends DXFDocument implements CADService {
    private final JdbcTemplate jdbcTemplate;
    @Override
    public void transformCad(String filePath) {
        DXFGraphics graphics = this.getGraphics();
        graphics.setColor(Color.BLUE);
        Font font = new Font(Font.DIALOG,Font.BOLD,2);
        DXFStyle style = new DXFStyle(font);
        this.addStyle(style);

        String sql = "select st_asewkt(geom) as geom,subtype,material,addr from gd";
        RowMapper<PipeVo> rowMapper = (rs, i) ->
                new PipeVo(rs.getString("subtype"),rs.getString("material"),
                        rs.getString("addr"),rs.getString("geom"));
        List<PipeVo> list = jdbcTemplate.query(sql,rowMapper);
        File file = new File(filePath);
        try{
            if (!file.exists()) {
                file.createNewFile();
            }
            //遍历数据写入dxf
            list.stream().forEach(item -> {
                try {
                    String wkt = item.getGeom();
                    List<List<RealPoint>> lines = WktUtils.lineToRealPoint(wkt);
                    lines.stream().forEach(line->{
                        this.setLayer("pipe");
                        RealPoint[] points = line.toArray(new RealPoint[0]);
                        for(int i = 0; i<points.length-1;i++){
                            //写入管段线信息
                            RealPoint start = points[i];
                            RealPoint end = points[i+1];
                            DXFLine dxfLine = new DXFLine(start,end,graphics);
                            this.addEntity(dxfLine);
                            //写入属性信息
                            String str = "";
                            str += StringUtils.isNoneBlank(item.getSubType())?item.getSubType():"";
                            str += StringUtils.isNoneBlank(item.getAddr())?item.getAddr():"";
                            str += StringUtils.isNoneBlank(item.getMaterial())?item.getMaterial():"";

                            RealPoint basePoint = WktUtils.getBasePoint(start,end);
                            double height = WktUtils.getLength(start,end)/4;
                            DXFText text = new DXFText(str,basePoint,height,WktUtils.getAngle(start,end),style,graphics);
                            this.addEntity(text);
                        }
                    });
                } catch (ParseException e) {
                    System.out.println(e.getMessage());
                }
            });
            //写入文件
            byte[] data = this.toDXFString().getBytes("UTF-8");
            FileOutputStream out = new FileOutputStream(file);
            out.write(data);
            out.flush();
            out.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

注意:如果业务中的数据较多的话,建议分页处理。

所呈现的结果:

af7a077f4b2342949e43a4e193f683f9.png

插入的文本注释:

40be64ad9f3442058c389a53290e95ba.png

项目更完善的源码在评论区留言我即可获取。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值