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());
}
}
}
注意:如果业务中的数据较多的话,建议分页处理。
所呈现的结果:
插入的文本注释:
项目更完善的源码在评论区留言我即可获取。