diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..9ed4869
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+ org.openjump
+ dxf-driver
+ 1.0.0
+ dxf-driver
+ Driver for dxf file format
+
+
+ 1.8
+ 1.8
+ UTF-8
+ 0.0.0
+ 1.18.1
+
+
+
+
+ org.locationtech.jts
+ jts-core
+ ${jts.version}
+
+
+ org.openjump
+ OpenJUMP
+ 2.0
+ system
+ ${project.basedir}/lib/OpenJUMP-0.0.0-r6c6037006e98f46a22f3d937b67694a133e6167f.jar
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DXFDriverConfiguration.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DXFDriverConfiguration.java
new file mode 100644
index 0000000..cceb39f
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DXFDriverConfiguration.java
@@ -0,0 +1,88 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import com.vividsolutions.jump.workbench.plugin.Extension;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+
+/**
+ * This is the entry class to declare the dxf driver to JUMP.
+ * You can put the <extension>drivers.dxf.DXFDriverConfiguration</extension>
+ * element in the workbench-properties.xml file or put the .jar file containing
+ * the driver in the ext directory of your installation.
+ * @author Michaël Michaud
+ * @version 1.0.0
+ */
+// History
+// 1.0.0 (2021-04-11) : * refactoring for OpenJUMP 2, JTS 1.18
+// 0.9.0 (2018-06-02) : * fix a regression preventing export of MultiPolygons
+// * use java 5 features (foreach, autoboxing, generics...)
+// 0.8.1 (2016-09-29) : * makes it compatible with 1.9.1 release
+// (remove multi-layer export capability - use java 1.7)
+// 0.8.0 (2013-10-09) : * make it compatible with next 1.7.0 OpenJUMP release
+// 0.7.8 (2012-09-22) : * Fix a bug preventing TEXT entities to be read
+// * Bug fixed x==Double.NaN --> Double.isNaN(x) in DXFPoint
+// 0.7.7 (2012-02-23) : * Fixed bug 3492384 preventing export of z in "lines"
+// 0.7.6 (2012-01-16) : * Compile again for java 1.5 compatibility
+// 0.7.5 (2011-12-02) : * Throws NumberFormatException
+// 0.7.4 (2011-11-20) : * fixed a compatibility problem between 0.7.3 and OJ1.4.3
+// 0.7.3 (2011-04-10) : * fixed a bug in DxfBLOCKS
+// * clean up the code
+// 0.7.2 (2011-04-07) : * add TEXT_ROTATION attribute from Giuseppe Aruta code
+// 0.7 (2010-11-01) : * read polygons with less than 3 points as lines
+// and lines with less than two different points as points
+// 0.6 () : * added DxfLWPOLYLINE
+// 0.5 (2006-11-12) : * remove the header writing option after L. Becker and
+// R. Littlefield have fix the bug in the header writing
+// * bug fixed x==Double.NaN --> Double.isNaN(x)
+// 0.4.x (2006-10-19) : * add optional '_' suffix
+// * add optional header writer
+// * DXF layer name is taken from layer attribute if it exists or
+// from layer name else if
+// * add multi-geometry export
+// * add attribute tests an ability to export ANY jump layer
+// * add ability to export holes in a separate layer or not
+// * replace standard SaveFileDataSourceQueryChooser by a
+// SaveDxfFileDataSourceQueryChooser with options for header
+// for entity handles and for layer name.
+// * add two options (one for header writing and the other
+// to suffix layers containing holes) and a function to
+// create valid DXF layer names from JUMP layer names
+// 0.4 (2006-10-15) : * makes it possible to export any JUMP layer (in 0.3,
+// layers which were not issued from a dxf file could not
+// be exported because it misses some attributes).
+// 0.3 (2003-12-10)
+// 0.2
+public class DXFDriverConfiguration extends Extension {
+
+ public void configure(PlugInContext context) {
+ new InstallDXFDataSourceQueryChooserPlugIn().initialize(context);
+ }
+
+ public String getName() {return "DXF driver";}
+
+ public String getVersion() {return "1.0.0 (2021-04-11)";}
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DXFFileReaderWriter.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DXFFileReaderWriter.java
new file mode 100644
index 0000000..cad2feb
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DXFFileReaderWriter.java
@@ -0,0 +1,40 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import com.vividsolutions.jump.io.datasource.StandardReaderWriterFileDataSource;
+
+
+/**
+ * DXF driver containg a DXFReader and a DXFWriter.
+ * @author Michaël Michaud
+ */
+public class DXFFileReaderWriter extends StandardReaderWriterFileDataSource {
+
+ public DXFFileReaderWriter() {
+ super(new DxfReader(), new DxfWriter(), new String[] { "dxf" });
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfBLOCKS.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfBLOCKS.java
new file mode 100644
index 0000000..edde43f
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfBLOCKS.java
@@ -0,0 +1,86 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import com.vividsolutions.jump.feature.FeatureDataset;
+
+
+/**
+ * A DXF block contains a block of geometries. The dxf driver can read entities
+ * inside a block, but it will not remember that the entities are in a same
+ * block.
+ * @author Michaël Michaud
+ */
+// History
+public class DxfBLOCKS {
+
+ FeatureCollection entities;
+
+ public DxfBLOCKS() {
+ entities = new FeatureDataset(DxfFile.DXF_SCHEMA);
+ }
+
+ public static DxfBLOCKS readBlocks(RandomAccessFile raf)
+ throws NumberFormatException, IOException {
+ return readEntities(raf);
+ }
+
+ public static DxfBLOCKS readEntities(RandomAccessFile raf)
+ throws NumberFormatException, IOException {
+ DxfBLOCKS dxfEntities = new DxfBLOCKS();
+ DxfGroup group = new DxfGroup(2, "BLOCKS");
+ while (group != null && !group.equals(DxfFile.ENDSEC)) {
+ if (group.getCode() == 0) {
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.getValue().equals("POINT")) {
+ group = DxfPOINT.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("TEXT")) {
+ group = DxfTEXT.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("LINE")) {
+ group = DxfLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("POLYLINE")) {
+ group = DxfPOLYLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("LWPOLYLINE")) {
+ group = DxfLWPOLYLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else {
+ group = DxfGroup.readGroup(raf);
+ }
+ }
+ else {
+ group = DxfGroup.readGroup(raf);
+ }
+ }
+ return dxfEntities;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfCLASSES.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfCLASSES.java
new file mode 100644
index 0000000..18eb867
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfCLASSES.java
@@ -0,0 +1,54 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+
+/**
+ * Dxf section between the HEADER and the TABLES sections.
+ * Not mandatory for DXF 12, don't use it.
+ * @author Michaël Michaud
+ */
+public class DxfCLASSES {
+
+ public DxfCLASSES() {}
+
+ public static DxfCLASSES readClasses(RandomAccessFile raf)
+ throws NumberFormatException, IOException {
+ DxfCLASSES classes = new DxfCLASSES();
+ DxfGroup group;
+ // readGroup returns a DxfGroup or throws an Exception. It does not return null.
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(DxfFile.ENDSEC)) {
+ // Read until end of CLASSES section without doing anything
+ }
+ return classes;
+ }
+
+ public String toString() {
+ return DxfFile.SECTION.toString() + DxfFile.CLASSES + DxfFile.ENDSEC;
+ }
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITIES.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITIES.java
new file mode 100644
index 0000000..f021c17
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITIES.java
@@ -0,0 +1,115 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.util.Iterator;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import com.vividsolutions.jump.feature.FeatureDataset;
+
+/**
+ * The ENTITIES section of a DXF file containing all the data.
+ * @author Michaël Michaud
+ */
+public class DxfENTITIES {
+
+ FeatureCollection entities;
+
+ public DxfENTITIES() {
+ entities = new FeatureDataset(DxfFile.DXF_SCHEMA);
+ }
+
+ public FeatureCollection getEntities() {
+ return entities;
+ }
+
+ public void setEntities(FeatureCollection featureCollection) {
+ this.entities = featureCollection;
+ }
+
+ public static DxfENTITIES readEntities(RandomAccessFile raf) throws IOException {
+ DxfENTITIES dxfEntities = new DxfENTITIES();
+ DxfGroup group = new DxfGroup(2, "ENTITIES");
+ while (group != null && !group.equals(DxfFile.ENDSEC)) {
+ if (group.getCode() == 0) {
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.getValue().equals("POINT")) {
+ group = DxfPOINT.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("TEXT")) {
+ group = DxfTEXT.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("LINE")) {
+ group = DxfLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("POLYLINE")) {
+ group = DxfPOLYLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else if (group.getValue().equals("LWPOLYLINE")) {
+ group = DxfLWPOLYLINE.readEntity(raf, dxfEntities.entities);
+ }
+ else {
+ group = DxfGroup.readGroup(raf);
+ }
+ }
+ else {
+ group = DxfGroup.readGroup(raf);
+ }
+ }
+ return dxfEntities;
+ }
+
+ public String toString() {
+ Iterator it = entities.iterator();
+ Feature feature;
+ StringBuilder sb = new StringBuilder(DxfFile.SECTION.toString());
+ sb.append(DxfFile.ENTITIES);
+ while (it.hasNext()) {
+ feature = it.next();
+ sb.append(DxfENTITY.feature2Dxf(feature, "LAYER0", true));
+ }
+ sb.append(DxfFile.ENDSEC);
+ return sb.toString();
+ }
+
+ public void write(BufferedWriter bw, String defaultLayer) throws IOException {
+ Iterator it = entities.iterator();
+ Feature feature;
+ bw.write(DxfFile.SECTION.toString());
+ bw.write(DxfFile.ENTITIES.toString());
+ while (it.hasNext()) {
+ feature = it.next();
+ String entity = DxfENTITY.feature2Dxf(feature, defaultLayer, true);
+ if (entity != null) {
+ bw.write(entity);
+ }
+ }
+ bw.write(DxfFile.ENDSEC.toString());
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITY.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITY.java
new file mode 100644
index 0000000..232dc7e
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfENTITY.java
@@ -0,0 +1,310 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+
+import com.vividsolutions.jump.feature.Feature;
+import org.locationtech.jts.geom.*;
+
+
+/**
+ * A DXF ENTITY is equivalent to a JUMP feature. This class is the parent class
+ * for POLYLINE, POINT, LINE and every kind of geometric entity present in a
+ * DXF file.
+ * @author Michaël Michaud
+ */
+// History
+// 2012-02-23 : fixed a bug in line export (it did always export z=0)
+// 2006-10-19 : add multi-geometry export
+// add attribute tests an ability to export ANY jump layer
+// add ability to export holes in a separate layer or not
+public class DxfENTITY {
+
+ public final static DxfGroup LINE = new DxfGroup(0, "LINE");
+ public final static DxfGroup POINT = new DxfGroup(0, "POINT");
+ public final static DxfGroup CIRCLE = new DxfGroup(0, "CIRCLE");
+ public final static DxfGroup ARC = new DxfGroup(0, "ARC");
+ public final static DxfGroup TRACE = new DxfGroup(0, "TRACE");
+ public final static DxfGroup SOLID = new DxfGroup(0, "SOLID");
+ public final static DxfGroup TEXT = new DxfGroup(0, "TEXT");
+ public final static DxfGroup SHAPE = new DxfGroup(0, "SHAPE");
+ public final static DxfGroup BLOCK = new DxfGroup(0, "BLOCK");
+ public final static DxfGroup ENDBLK = new DxfGroup(0, "ENDBLK");
+ public final static DxfGroup INSERT = new DxfGroup(0, "INSERT");
+ public final static DxfGroup ATTDEF = new DxfGroup(0, "ATTDEF");
+ public final static DxfGroup ATTRIB = new DxfGroup(0, "ATTRIB");
+ public final static DxfGroup POLYLINE = new DxfGroup(0, "POLYLINE");
+ public final static DxfGroup LWPOLYLINE = new DxfGroup(0, "LWPOLYLINE");
+ public final static DxfGroup VERTEX = new DxfGroup(0, "VERTEX");
+ public final static DxfGroup SEQEND = new DxfGroup(0, "SEQEND");
+ public final static DxfGroup _3DFACE = new DxfGroup(0, "3DFACE");
+ public final static DxfGroup VIEWPORT = new DxfGroup(0, "VIEWPORT");
+ public final static DxfGroup DIMENSION = new DxfGroup(0, "DIMENSION");
+ public final static PrecisionModel DPM = new PrecisionModel();
+ public static int precision = 4;
+
+ private String layerName = "DEFAULT";
+ //private String lineType = null;
+ //private float elevation = 0f;
+ //private float thickness = 0f;
+ //private int colorNumber = 256;
+ //private int space = 0;
+ //private double[] extrusionDirection = null;
+ //private int flags = 0;
+
+ public String getLayerName() {return layerName;}
+
+ public void setLayerName(String layerName) {
+ this.layerName = layerName;
+ }
+
+ public DxfENTITY(String layerName) {
+ this.layerName = layerName;
+ }
+
+ public static String feature2Dxf(Feature feature, String layerName, boolean suffix) {
+ Geometry g = feature.getGeometry();
+ if (g.getGeometryType().equals("Point")) {
+ return point2Dxf(feature, layerName);
+ }
+ else if (g.getGeometryType().equals("LineString")) {
+ return lineString2Dxf(feature, layerName);
+ }
+ else if (g.getGeometryType().equals("Polygon")) {
+ return polygon2Dxf(feature, layerName, suffix);
+ }
+ else if (g instanceof GeometryCollection) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0 ; i < g.getNumGeometries() ; i++) {
+ Feature ff = feature.clone(true);
+ ff.setGeometry(g.getGeometryN(i));
+ sb.append(feature2Dxf(ff, layerName, suffix));
+ }
+ return sb.toString();
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static String point2Dxf(Feature feature, String layerName) {
+ StringBuilder sb;
+ boolean hasText = (feature.getSchema().hasAttribute("TEXT") &&
+ feature.getAttribute("TEXT") != null);
+ if (hasText) {sb = new StringBuilder(DxfGroup.toString(0, "TEXT"));}
+ else {sb = new StringBuilder(DxfGroup.toString(0, "POINT"));}
+ if (feature.getSchema().hasAttribute("LAYER") &&
+ !feature.getString("LAYER").trim().equals("")) {
+ sb.append(DxfGroup.toString(8, feature.getAttribute("LAYER")));
+ }
+ else {sb.append(DxfGroup.toString(8, layerName));}
+ if (feature.getSchema().hasAttribute("LTYPE") &&
+ !feature.getAttribute("LTYPE").equals("BYLAYER")) {
+ sb.append(DxfGroup.toString(6, feature.getAttribute("LTYPE")));
+ }
+ //if (feature.getSchema().hasAttribute("ELEVATION") &&
+ // feature.getAttribute("ELEVATION") != null &&
+ // !feature.getAttribute("ELEVATION").equals(new Float(0f))) {
+ // sb.append(DxfGroup.toString(38, feature.getAttribute("ELEVATION")));
+ //}
+ if (feature.getSchema().hasAttribute("THICKNESS") &&
+ feature.getAttribute("THICKNESS") != null &&
+ !feature.getAttribute("THICKNESS").equals(0f)) {
+ sb.append(DxfGroup.toString(39, feature.getAttribute("THICKNESS")));
+ }
+ if (feature.getSchema().hasAttribute("COLOR") &&
+ feature.getAttribute("COLOR") != null &&
+ (Integer)feature.getAttribute("COLOR") != 256) {
+ sb.append(DxfGroup.toString(62, feature.getAttribute("COLOR").toString()));
+ }
+ Coordinate coord = feature.getGeometry().getCoordinate();
+ sb.append(DxfGroup.toString(10, coord.x, precision));
+ sb.append(DxfGroup.toString(20, coord.y, precision));
+ if (!Double.isNaN(coord.z)) sb.append(DxfGroup.toString(30, coord.z, precision));
+ if (hasText) {
+ sb.append(DxfGroup.toString(1, feature.getAttribute("TEXT")));
+ }
+ if (hasText && feature.getSchema().hasAttribute("TEXT_HEIGHT") &&
+ feature.getAttribute("TEXT_HEIGHT") != null) {
+ sb.append(DxfGroup.toString(40, feature.getAttribute("TEXT_HEIGHT")));
+ }
+ if (hasText && feature.getSchema().hasAttribute("TEXT_ROTATION") &&
+ feature.getAttribute("TEXT_ROTATION") != null) {
+ sb.append(DxfGroup.toString(50, feature.getAttribute("TEXT_ROTATION")));
+ }
+ if (hasText && feature.getSchema().hasAttribute("TEXT_STYLE") &&
+ feature.getAttribute("TEXT_STYLE") != null) {
+ sb.append(DxfGroup.toString(7, feature.getAttribute("TEXT_STYLE")));
+ }
+ return sb.toString();
+ }
+
+ public static String lineString2Dxf(Feature feature, String layerName) {
+ LineString geom = (LineString)feature.getGeometry();
+ Coordinate[] coords = geom.getCoordinates();
+ // Correction added by L. Becker and R Littlefield on 2006-11-08
+ // It writes 2 points-only polylines in a line instead of a polyline
+ // to make it possible to incorporate big dataset in View32
+ boolean isLine = (coords.length == 2);
+ StringBuilder sb;
+ if (!isLine) {
+ sb = new StringBuilder(DxfGroup.toString(0, "POLYLINE"));
+ }
+ else {
+ sb = new StringBuilder(DxfGroup.toString(0, "LINE"));
+ }
+ if (feature.getSchema().hasAttribute("LAYER") &&
+ !feature.getString("LAYER").trim().equals("")) {
+ sb.append(DxfGroup.toString(8, feature.getAttribute("LAYER")));
+ }
+ else {sb.append(DxfGroup.toString(8, layerName));}
+ if (feature.getSchema().hasAttribute("LTYPE") &&
+ !feature.getAttribute("LTYPE").equals("BYLAYER")) {
+ sb.append(DxfGroup.toString(6, feature.getAttribute("LTYPE")));
+ }
+ if (feature.getSchema().hasAttribute("ELEVATION") &&
+ feature.getAttribute("ELEVATION") != null) {
+ sb.append(DxfGroup.toString(38, feature.getAttribute("ELEVATION")));
+ }
+ if (feature.getSchema().hasAttribute("THICKNESS") &&
+ feature.getAttribute("THICKNESS") != null) {
+ sb.append(DxfGroup.toString(39, feature.getAttribute("THICKNESS")));
+ }
+ if (feature.getSchema().hasAttribute("COLOR") &&
+ feature.getAttribute("THICKNESS") != null) {
+ sb.append(DxfGroup.toString(62, feature.getAttribute("COLOR").toString()));
+ }
+ // modified by L. Becker and R. Littlefield (add the Line case)
+ if (isLine){
+ sb.append(DxfGroup.toString(10, coords[0].x, precision));
+ sb.append(DxfGroup.toString(20, coords[0].y, precision));
+ if (!Double.isNaN(coords[0].z)) {
+ sb.append(DxfGroup.toString(30, coords[0].z, precision));
+ }
+ sb.append(DxfGroup.toString(11, coords[1].x, precision));
+ sb.append(DxfGroup.toString(21, coords[1].y, precision));
+ if (!Double.isNaN(coords[1].z)) {
+ sb.append(DxfGroup.toString(31, coords[1].z, precision));
+ }
+ }
+ else {
+ sb.append(DxfGroup.toString(66, 1));
+ sb.append(DxfGroup.toString(10, "0.0"));
+ sb.append(DxfGroup.toString(20, "0.0"));
+ if (!Double.isNaN(coords[0].z)) sb.append(DxfGroup.toString(30, "0.0"));
+ sb.append(DxfGroup.toString(70, 8));
+
+ for (Coordinate coord : coords) {
+ sb.append(DxfGroup.toString(0, "VERTEX"));
+ if (feature.getSchema().hasAttribute("LAYER") &&
+ !feature.getString("LAYER").trim().equals("")) {
+ sb.append(DxfGroup.toString(8, feature.getAttribute("LAYER")));
+ }
+ else {sb.append(DxfGroup.toString(8, layerName));}
+ sb.append(DxfGroup.toString(10, coord.x, precision));
+ sb.append(DxfGroup.toString(20, coord.y, precision));
+ if (!Double.isNaN(coord.z)) sb.append(DxfGroup.toString(30, coord.z, precision));
+ sb.append(DxfGroup.toString(70, 32));
+ }
+ sb.append(DxfGroup.toString(0, "SEQEND"));
+ }
+ return sb.toString();
+ }
+
+ public static String polygon2Dxf(Feature feature, String layerName, boolean suffix) {
+ Polygon geom = (Polygon)feature.getGeometry();
+ Coordinate[] coords = geom.getExteriorRing().getCoordinates();
+ StringBuilder sb = new StringBuilder(DxfGroup.toString(0, "POLYLINE"));
+ sb.append(DxfGroup.toString(8, layerName));
+ if (feature.getSchema().hasAttribute("LTYPE") &&
+ feature.getAttribute("LTYPE") != null &&
+ !feature.getAttribute("LTYPE").equals("BYLAYER")) {
+ sb.append(DxfGroup.toString(6, feature.getAttribute("LTYPE")));
+ }
+ if (feature.getSchema().hasAttribute("ELEVATION") &&
+ feature.getAttribute("ELEVATION") != null) {
+ sb.append(DxfGroup.toString(38, feature.getAttribute("ELEVATION")));
+ }
+ if (feature.getSchema().hasAttribute("THICKNESS") &&
+ feature.getAttribute("THICKNESS") != null) {
+ sb.append(DxfGroup.toString(39, feature.getAttribute("THICKNESS")));
+ }
+ if (feature.getSchema().hasAttribute("COLOR") &&
+ feature.getAttribute("COLOR") != null) {
+ sb.append(DxfGroup.toString(62, feature.getAttribute("COLOR").toString()));
+ }
+ sb.append(DxfGroup.toString(66, 1));
+ sb.append(DxfGroup.toString(10, "0.0"));
+ sb.append(DxfGroup.toString(20, "0.0"));
+ if (!Double.isNaN(coords[0].z)) sb.append(DxfGroup.toString(30, "0.0"));
+ sb.append(DxfGroup.toString(70, 9));
+ for (Coordinate coord : coords) {
+ sb.append(DxfGroup.toString(0, "VERTEX"));
+ sb.append(DxfGroup.toString(8, layerName));
+ sb.append(DxfGroup.toString(10, coord.x, precision));
+ sb.append(DxfGroup.toString(20, coord.y, precision));
+ if (!Double.isNaN(coord.z)) sb.append(DxfGroup.toString(30, coord.z, precision));
+ sb.append(DxfGroup.toString(70, 32));
+ }
+ sb.append(DxfGroup.toString(0, "SEQEND"));
+ for (int h = 0 ; h < geom.getNumInteriorRing() ; h++) {
+ //System.out.println("polygon2Dxf (hole)" + suffix);
+ sb.append(DxfGroup.toString(0, "POLYLINE"));
+ if (suffix) sb.append(DxfGroup.toString(8, layerName+"_"));
+ else sb.append(DxfGroup.toString(8, layerName));
+ if (feature.getSchema().hasAttribute("LTYPE") &&
+ !feature.getAttribute("LTYPE").equals("BYLAYER")) {
+ sb.append(DxfGroup.toString(6, feature.getAttribute("LTYPE")));
+ }
+ if (feature.getSchema().hasAttribute("THICKNESS") &&
+ feature.getAttribute("THICKNESS") != null) {
+ sb.append(DxfGroup.toString(39, feature.getAttribute("THICKNESS")));
+ }
+ if (feature.getSchema().hasAttribute("COLOR") &&
+ feature.getAttribute("COLOR") != null) {
+ sb.append(DxfGroup.toString(62, feature.getAttribute("COLOR")));
+ }
+ sb.append(DxfGroup.toString(66, 1));
+ sb.append(DxfGroup.toString(10, "0.0"));
+ sb.append(DxfGroup.toString(20, "0.0"));
+ if (!Double.isNaN(coords[0].z)) sb.append(DxfGroup.toString(30, "0.0"));
+ sb.append(DxfGroup.toString(70, 9));
+ coords = geom.getInteriorRingN(h).getCoordinates();
+ for (Coordinate coord : coords) {
+ sb.append(DxfGroup.toString(0, "VERTEX"));
+ if (suffix) sb.append(DxfGroup.toString(8, layerName+"_"));
+ else sb.append(DxfGroup.toString(8, layerName));
+ sb.append(DxfGroup.toString(10, coord.x, precision));
+ sb.append(DxfGroup.toString(20, coord.y, precision));
+ if (!Double.isNaN(coord.z)) sb.append(DxfGroup.toString(30, coord.z, precision));
+ sb.append(DxfGroup.toString(70, 32));
+ }
+ sb.append(DxfGroup.toString(0, "SEQEND"));
+ }
+
+ return sb.toString();
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfFile.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfFile.java
new file mode 100644
index 0000000..e0c6e9c
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfFile.java
@@ -0,0 +1,330 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Date;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import com.vividsolutions.jump.feature.FeatureDataset;
+import com.vividsolutions.jump.feature.AttributeType;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.geom.GeometryFactory;
+
+/**
+ * A whole dataset contained in a DXF file, and main methods to read from and
+ * to write to the file.
+ *
+ * @author Michaël Michaud
+ */
+public class DxfFile {
+
+ public static boolean DEBUG = false;
+
+ public final static DxfGroup SECTION = new DxfGroup(0, "SECTION");
+ public final static DxfGroup ENDSEC = new DxfGroup(0, "ENDSEC");
+ public final static DxfGroup EOF = new DxfGroup(0, "EOF");
+ public final static DxfGroup HEADER = new DxfGroup(2, "HEADER");
+
+ // CLASSES section is used from version 13
+ public final static DxfGroup CLASSES = new DxfGroup(2, "CLASSES");
+ public final static DxfGroup TABLES = new DxfGroup(2, "TABLES");
+ public final static DxfGroup BLOCKS = new DxfGroup(2, "BLOCKS");
+ public final static DxfGroup ENTITIES = new DxfGroup(2, "ENTITIES");
+
+ // OBJECTS section is used from version 13
+ public final static DxfGroup OBJECTS = new DxfGroup(2, "OBJECTS");
+
+ // Common FeatureSchema for ENTITIES
+ public final static FeatureSchema DXF_SCHEMA = new FeatureSchema();
+ public static boolean DXF_SCHEMA_INITIALIZED = false;
+ //static int iterator = 0;
+ private DxfHEADER header = null;
+ private DxfCLASSES classes = null;
+ private DxfTABLES tables = null;
+ private DxfBLOCKS blocks = null;
+ private DxfENTITIES entities = null;
+ private int coordinatePrecision = 2;
+
+ FeatureCollection features;
+
+ public DxfFile() {
+ initializeDXF_SCHEMA();
+ }
+
+ /**
+ * Initialize a JUMP FeatureSchema to load dxf data keeping some graphic
+ * attributes.
+ */
+ public static void initializeDXF_SCHEMA() {
+ if (DXF_SCHEMA.getAttributeCount() != 0) return;
+ // codes 10,20,30... used by POINT, TEXT, LINE, POLYLINE, LWPOLYLINE
+ DXF_SCHEMA.addAttribute("GEOMETRY", AttributeType.GEOMETRY);
+ // code 8, common to all entities
+ DXF_SCHEMA.addAttribute("LAYER", AttributeType.STRING);
+ // code 6, common to all entities
+ DXF_SCHEMA.addAttribute("LTYPE", AttributeType.STRING);
+ // code 38 used by LWPOLYLINE
+ DXF_SCHEMA.addAttribute("ELEVATION", AttributeType.DOUBLE);
+ // code 39 used by POINT, TEXT, LINE, POLYLINE, LWPOLYLINE
+ DXF_SCHEMA.addAttribute("THICKNESS", AttributeType.DOUBLE);
+ // code 62, common to all entities
+ DXF_SCHEMA.addAttribute("COLOR", AttributeType.INTEGER);
+ // code 1 used by TEXT
+ DXF_SCHEMA.addAttribute("TEXT", AttributeType.STRING);
+ // code 40 used by TEXT
+ DXF_SCHEMA.addAttribute("TEXT_HEIGHT", AttributeType.DOUBLE);
+ // code 50 used by TEXT
+ DXF_SCHEMA.addAttribute("TEXT_ROTATION", AttributeType.DOUBLE);
+ // code 7 used by TEXT
+ DXF_SCHEMA.addAttribute("TEXT_STYLE", AttributeType.STRING);
+ }
+
+ public int getCoordinatePrecision(){
+ return coordinatePrecision;
+ }
+
+ public void setCoordinatePrecision(int coordinatePrecision) {
+ this.coordinatePrecision = coordinatePrecision;
+ }
+
+ public static DxfFile createFromFile(File file) throws IOException {
+ RandomAccessFile raf = new RandomAccessFile(file, "r");
+ return createFromFile(raf);
+ }
+
+ public static DxfFile createFromFile(RandomAccessFile raf)
+ throws NumberFormatException, IOException {
+ DxfFile dxfFile = new DxfFile();
+ initializeDXF_SCHEMA();
+ dxfFile.features = new FeatureDataset(DXF_SCHEMA);
+ DxfGroup group;
+ try {
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ if (group.equals(SECTION)) {
+ group = DxfGroup.readGroup(raf);
+ //if (group == null) break; // never happens, readGroup throws Exception
+ if (DxfFile.DEBUG) group.print(0);
+ if (group.equals(HEADER)) {
+ dxfFile.header = DxfHEADER.readHeader(raf);
+ }
+ else if (group.equals(CLASSES)) {
+ dxfFile.classes = DxfCLASSES.readClasses(raf);
+ }
+ else if (group.equals(TABLES)) {
+ dxfFile.tables = DxfTABLES.readTables(raf);
+ }
+ else if (group.equals(BLOCKS)) {
+ dxfFile.blocks = DxfBLOCKS.readEntities(raf);
+ dxfFile.features.addAll(dxfFile.blocks.entities.getFeatures());
+ }
+ else if (group.equals(ENTITIES)) {
+ dxfFile.entities = DxfENTITIES.readEntities(raf);
+ dxfFile.features.addAll(dxfFile.entities.entities.getFeatures());
+ }
+ else if (group.equals(OBJECTS)) {
+ //objects = DxfOBJECTS.readObjects(br);
+ }
+ else if (group.getCode() == 999) {
+ System.out.println("Comment : " + group.getValue());
+ }
+ else {
+ //System.out.println("Group " + group.getCode() + " " + group.getValue() + " UNKNOWN");
+ }
+ }
+ else if (group.getCode() == 999) {
+ //System.out.println("Comment : " + group.getValue());
+ }
+ else if (group.equals(EOF)) {
+ break;
+ }
+ else {
+ //System.out.println("Group " + group.getCode() + " " + group.getValue() + " UNKNOWN");
+ }
+ }
+ } finally {
+ raf.close();
+ }
+ return dxfFile;
+ }
+
+ public FeatureCollection read(GeometryFactory gf) {
+ return features;
+ }
+
+ public FeatureCollection getFeatureCollection() {
+ return null;
+ }
+
+ public static void write(FeatureCollection features, String[] layerNames,
+ FileWriter fw, int precision, boolean suffix) {
+
+ Envelope envelope = features.getEnvelope();
+
+ Date date = new Date(System.currentTimeMillis());
+ try {
+ // COMMENTAIRES DU TRADUCTEUR
+ fw.write(DxfGroup.toString(999, features.size() + " features"));
+ fw.write(DxfGroup.toString(999, "TRANSLATED BY DXF Driver 0.9.0"));
+ fw.write(DxfGroup.toString(999, "DATE : " + date));
+
+ // ECRITURE DU HEADER
+ fw.write(DxfGroup.toString(0, "SECTION"));
+ fw.write(DxfGroup.toString(2, "HEADER"));
+ fw.write(DxfGroup.toString(9, "$ACADVER"));
+ fw.write(DxfGroup.toString(1, "AC1009"));
+ fw.write(DxfGroup.toString(9, "$CECOLOR"));
+ fw.write(DxfGroup.toString(62, 256));
+ fw.write(DxfGroup.toString(9, "$CELTYPE"));
+ fw.write(DxfGroup.toString(6, "DUPLAN"));
+ fw.write(DxfGroup.toString(9, "$CLAYER"));
+ fw.write(DxfGroup.toString(8, "0")); // corrected by L. Becker on 2006-11-08
+ fw.write(DxfGroup.toString(9, "$ELEVATION"));
+ fw.write(DxfGroup.toString(40, 0.0, 3));
+ fw.write(DxfGroup.toString(9, "$EXTMAX"));
+ fw.write(DxfGroup.toString(10, envelope.getMaxX(), 6));
+ fw.write(DxfGroup.toString(20, envelope.getMaxY(), 6));
+ //fw.write(DxfGroup.toString(30, envelope.getMaxX(), 6));
+ fw.write(DxfGroup.toString(9, "$EXTMIN"));
+ fw.write(DxfGroup.toString(10, envelope.getMinX(), 6));
+ fw.write(DxfGroup.toString(20, envelope.getMinY(), 6));
+ //fw.write(DxfGroup.toString(30, envelope.getMaxX(), 6));
+ fw.write(DxfGroup.toString(9, "$INSBASE"));
+ fw.write(DxfGroup.toString(10, 0.0, 1));
+ fw.write(DxfGroup.toString(20, 0.0, 1));
+ fw.write(DxfGroup.toString(30, 0.0, 1));
+ fw.write(DxfGroup.toString(9, "$LIMCHECK"));
+ fw.write(DxfGroup.toString(70, 1));
+ fw.write(DxfGroup.toString(9, "$LIMMAX"));
+ fw.write(DxfGroup.toString(10, envelope.getMaxX(), 6));
+ fw.write(DxfGroup.toString(20, envelope.getMaxY(), 6));
+ fw.write(DxfGroup.toString(9, "$LIMMIN"));
+ fw.write(DxfGroup.toString(10, envelope.getMinX(), 6));
+ fw.write(DxfGroup.toString(20, envelope.getMinY(), 6));
+ fw.write(DxfGroup.toString(9, "$LUNITS"));
+ fw.write(DxfGroup.toString(70, 2));
+ fw.write(DxfGroup.toString(9, "$LUPREC"));
+ fw.write(DxfGroup.toString(70, 2));
+ fw.write(DxfGroup.toString(0, "ENDSEC"));
+
+ // ECRITURE DES TABLES
+ fw.write(DxfGroup.toString(0, "SECTION"));
+ fw.write(DxfGroup.toString(2, "TABLES"));
+ fw.write(DxfGroup.toString(0, "TABLE"));
+ fw.write(DxfGroup.toString(2, "STYLE"));
+ fw.write(DxfGroup.toString(70, 1));
+ fw.write(DxfGroup.toString(0, "STYLE")); // added by L. Becker on 2006-11-08
+ DxfTABLE_STYLE_ITEM style =
+ new DxfTABLE_STYLE_ITEM("STANDARD", 0, 0f, 1f, 0f, 0, 1.0f, "xxx.txt", "yyy.txt");
+ fw.write(style.toString());
+ fw.write(DxfGroup.toString(0, "ENDTAB"));
+ fw.write(DxfGroup.toString(0, "TABLE"));
+ fw.write(DxfGroup.toString(2, "LTYPE"));
+ fw.write(DxfGroup.toString(70, 1));
+ fw.write(DxfGroup.toString(0, "LTYPE")); // added by L. Becker on 2006-11-08
+ DxfTABLE_LTYPE_ITEM ltype =
+ new DxfTABLE_LTYPE_ITEM("CONTINUE", 0, "", 65, 0f, new float[0]);
+ fw.write(ltype.toString());
+ fw.write(DxfGroup.toString(0, "ENDTAB"));
+ fw.write(DxfGroup.toString(0, "TABLE"));
+ fw.write(DxfGroup.toString(2, "LAYER"));
+ fw.write(DxfGroup.toString(70, 2));
+ for (String layerName : layerNames) {
+ DxfTABLE_LAYER_ITEM dxfLayer =
+ new DxfTABLE_LAYER_ITEM(layerName, 0, 131, "CONTINUE");
+ fw.write(DxfGroup.toString(0, "LAYER")); // added by L. Becker on 2006-11-08
+ fw.write(dxfLayer.toString());
+ if (suffix) {
+ dxfLayer = new DxfTABLE_LAYER_ITEM(layerName + "_",
+ 0, 131, "CONTINUE");
+ fw.write(DxfGroup.toString(0, "LAYER")); // added by L. Becker on 2006-11-08
+ fw.write(dxfLayer.toString());
+ }
+ }
+ fw.write(DxfGroup.toString(0, "ENDTAB"));
+ fw.write(DxfGroup.toString(0, "ENDSEC"));
+
+ // ECRITURE DES FEATURES
+ fw.write(DxfGroup.toString(0, "SECTION"));
+ fw.write(DxfGroup.toString(2, "ENTITIES"));
+ for (Feature feature : features.getFeatures()) {
+ // use the layer attribute for layer name
+ String entity;
+ if (feature.getSchema().hasAttribute("LAYER")) {
+ entity = DxfENTITY.feature2Dxf(feature, feature.getString("LAYER"), suffix);
+ }
+ // use the JUMP layer name for DXF layer name
+ else if (layerNames.length > 0) {
+ entity = DxfENTITY.feature2Dxf(feature, layerNames[0], suffix);
+ }
+ else {
+ entity = DxfENTITY.feature2Dxf(feature, "0", suffix);
+ }
+ if (entity != null) {
+ fw.write(entity);
+ }
+ }
+ fw.write(DxfGroup.toString(0, "ENDSEC"));
+
+ // FIN DE FICHIER
+ fw.write(DxfGroup.toString(0, "EOF"));
+ fw.flush();
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ if (null != fw) {
+ try {
+ fw.close();
+ } catch(IOException ignored){}
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ JFileChooser jfc = new JFileChooser("C:/Michael/Test/dxf");
+ File f = null;
+ int r = jfc.showOpenDialog(new JFrame());
+ if(r == JFileChooser.APPROVE_OPTION) {
+ f = jfc.getSelectedFile();
+ }
+ try {
+ DxfFile dxfFile = DxfFile.createFromFile(f);
+ f = new File("C:/Michael/Test/dxf/essai.dxf");
+ java.io.BufferedWriter bw = new java.io.BufferedWriter(new java.io.FileWriter(f));
+ bw.write(dxfFile.header.toString());
+ bw.write(dxfFile.tables.toString());
+ bw.write(dxfFile.entities.toString());
+ bw.write(DxfGroup.toString(0, "EOF"));
+ bw.close();
+ } catch(IOException ignored) {}
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfGroup.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfGroup.java
new file mode 100644
index 0000000..3c42e8a
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfGroup.java
@@ -0,0 +1,161 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+/**
+ * DxfGroup is a group containing a dxf code and a dxf value.
+ * The class contains several utils to read and write groups an to format data.
+ * @author Michaël Michaud
+ */
+public class DxfGroup {
+
+ // Write international decimal symbol (.), not the french one (,)
+ private static final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
+
+ private static final DecimalFormat[] decimalFormats = new DecimalFormat[]{
+ new DecimalFormat("#0", dfs),
+ new DecimalFormat("#0.0", dfs),
+ new DecimalFormat("#0.00", dfs),
+ new DecimalFormat("#0.000", dfs),
+ new DecimalFormat("#0.0000", dfs),
+ new DecimalFormat("#0.00000", dfs),
+ new DecimalFormat("#0.000000", dfs),
+ new DecimalFormat("#0.0000000", dfs),
+ new DecimalFormat("#0.00000000", dfs),
+ new DecimalFormat("#0.000000000", dfs),
+ new DecimalFormat("#0.0000000000", dfs),
+ new DecimalFormat("#0.00000000000", dfs),
+ new DecimalFormat("#0.000000000000", dfs)};
+
+ private int code = -1;
+ private String value;
+ private long address;
+
+ public DxfGroup(int code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public DxfGroup(String code, String value) {
+ try {
+ this.value = value;
+ this.code = Integer.parseInt(code.trim());
+ }
+ catch(NumberFormatException nfe) {
+ System.out.println("Error reading group: \"" + code + "=" +
+ value + "\" is not a valid code/value pair");
+ }
+ }
+
+ public int getCode() {return code;}
+ public void setCode(int code) {this.code = code;}
+ public String getValue() {return value;}
+ public int getIntValue() {return Integer.parseInt(value.trim());}
+ public float getFloatValue() {return Float.parseFloat(value.trim());}
+ public double getDoubleValue() {return Double.parseDouble(value.trim());}
+ public void setValue(String value) {this.value = value;}
+ public long getAddress() {return address;}
+ private void setAddress(long address) {this.address = address;}
+
+ public boolean equals(Object other){
+ if (other instanceof DxfGroup &&
+ code==((DxfGroup)other).getCode() &&
+ value.equals(((DxfGroup)other).getValue())) {
+ return true;
+ }
+ else return false;
+ }
+
+ public String toString() {
+ String codeString = " " + code;
+ int stringLength = codeString.length();
+ codeString = codeString.substring(stringLength-(code<1000?3:4), stringLength);
+ return codeString + "\r\n" + value + "\r\n";
+ }
+
+ public void print(int indent) {
+ for (int i = 0 ; i < indent ; i++) System.out.print(" ");
+ System.out.println("" + code + " = " + value);
+ }
+
+ public boolean isValid() {
+ return code >= 0;
+ }
+
+ public static String int34car(int code) {
+ if (code<10) return " " + code;
+ else if (code<100) return " " + code;
+ else return Integer.toString(code);
+ }
+
+ public static String int6car(int value) {
+ String s = " " + value;
+ return s.substring(s.length()-6);
+ }
+
+ public static String toString(int code, String value) {
+ return int34car(code) + "\r\n" + value + "\r\n";
+ }
+
+ public static String toString(int code, int value) {
+ return int34car(code) + "\r\n" + int6car(value) + "\r\n";
+ }
+
+ public static String toString(int code, float value, int decimalPartLength) {
+ return int34car(code) + "\r\n" +
+ decimalFormats[decimalPartLength].format(value) + "\r\n";
+ }
+
+ public static String toString(int code, double value, int decimalPartLength) {
+ return int34car(code) + "\r\n" +
+ decimalFormats[decimalPartLength].format(value) + "\r\n";
+ }
+
+ public static String toString(int code, Object value) {
+ if (value instanceof String) {return toString(code, (String)value);}
+ else if (value instanceof Integer) {return toString(code, ((Integer)value).intValue());}
+ else if (value instanceof Float) {return toString(code, (Float)value, 3);}
+ else if (value instanceof Double) {return toString(code, (Double)value, 6);}
+ else return toString(code, value.toString());
+ }
+
+ /**
+ * Read a group from the current position in a RandomAccessFime.
+ * @return a DxfGroup
+ */
+ public static DxfGroup readGroup(RandomAccessFile raf) throws IOException {
+ long pos = raf.getFilePointer();
+ DxfGroup dxfGroup = new DxfGroup(raf.readLine(), raf.readLine());
+ dxfGroup.setAddress(pos);
+ return dxfGroup;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfHEADER.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfHEADER.java
new file mode 100644
index 0000000..2eb8892
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfHEADER.java
@@ -0,0 +1,243 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * A DXF HEADER section.
+ * This class has a static method to read the header section of a DXF file
+ * and a toString method to format the header section into DXF format
+ * @author Michaël Michaud
+ */
+public class DxfHEADER {
+ public static final String ACADVER = "ACADVER";
+ public static final String ANGBASE = "ANGBASE";
+ public static final String ANGDIR = "ANGDIR";
+ public static final String ATTDIA = "ATTDIA";
+ public static final String ATTMODE = "ATTMODE";
+ public static final String ATTREQ = "ATTREQ";
+ public static final String AUNITS = "AUNITS";
+ public static final String AUPREC = "AUPREC";
+ public static final String AXISMODE = "AXISMODE";
+ public static final String AXISUNIT = "AXISUNIT";
+ public static final String BLIPMODE = "BLIPMODE";
+ public static final String CECOLOR = "CECOLOR";
+ public static final String CELTYPE = "CELTYPE";
+ public static final String CHAMFERA = "CHAMFERA";
+ public static final String CHAMFERB = "CHAMFERB";
+ public static final String CLAYER = "CLAYER";
+ public static final String COORDS = "COORDS";
+ public static final String DIMALT = "DIMALT";
+ public static final String DIMALTD = "DIMALTD";
+ public static final String DIMALTF = "DIMALTF";
+ public static final String DIMAPOST = "DIMAPOST";
+ public static final String DIMASO = "DIMASO";
+ public static final String DIMASZ = "DIMASZ";
+ public static final String DIMBLK = "DIMBLK";
+ public static final String DIMBLK1 = "DIMBLK1";
+ public static final String DIMBLK2 = "DIMBLK2";
+ public static final String DIMCEN = "DIMCEN";
+ public static final String DIMCLRD = "DIMCLRD";
+ public static final String DIMCLRE = "DIMCLRE";
+ public static final String DIMCLRT = "DIMCLRT";
+ public static final String DIMDLE = "DIMDLE";
+ public static final String DIMDLI = "DIMDLI";
+ public static final String DIMEXE = "DIMEXE";
+ public static final String DIMEXO = "DIMEXO";
+ public static final String DIMGAP = "DIMGAP";
+ public static final String DIMLFAC = "DIMLFAC";
+ public static final String DIMLIM = "DIMLIM";
+ public static final String DIMPOST = "DIMPOST";
+ public static final String DIMRND = "DIMRND";
+ public static final String DIMSAH = "DIMSAH";
+ public static final String DIMSCALE = "DIMSCALE";
+ public static final String DIMSE1 = "DIMSE1";
+ public static final String DIMSE2 = "DIMSE2";
+ public static final String DIMSHO = "DIMSHO";
+ public static final String DIMSOXD = "DIMSOXD";
+ public static final String DIMSTYLE = "DIMSTYLE";
+ public static final String DIMTAD = "DIMTAD";
+ public static final String DIMTFAC = "DIMTFAC";
+ public static final String DIMTIH = "DIMTIH";
+ public static final String DIMTIX = "DIMTIX";
+ public static final String DIMTM = "DIMTM";
+ public static final String DIMTOFL = "DIMTOFL";
+ public static final String DIMTOH = "DIMTOH";
+ public static final String DIMTOL = "DIMTOL";
+ public static final String DIMTP = "DIMTP";
+ public static final String DIMTSZ = "DIMTSZ";
+ public static final String DIMTVP = "DIMTVP";
+ public static final String DIMTXT = "DIMTXT";
+ public static final String DIMZIN = "DIMZIN";
+ public static final String DRAGMODE = "DRAGMODE";
+ public static final String DWGCODEPAGE = "DWGCODEPAGE";
+ public static final String ELEVATION = "ELEVATION";
+ public static final String EXTMAX = "EXTMAX";
+ public static final String EXTMIN = "EXTMIN";
+ public static final String FASTZOOM = "FASTZOOM";
+ public static final String FILLETRAD = "FILLETRAD";
+ public static final String FILLMODE = "FILLMODE";
+ public static final String GRIDMODE = "GRIDMODE";
+ public static final String GRIDUNIT = "GRIDUNIT";
+ public static final String HANDLING = "HANDLING";
+ public static final String HANDSEED = "HANDSEED";
+ public static final String INSBASE = "INSBASE";
+ public static final String LIMCHECK = "LIMCHECK";
+ public static final String LIMMAX = "LIMMAX";
+ public static final String LIMMIN = "LIMMIN";
+ public static final String LTSCALE = "LTSCALE";
+ public static final String LUNITS = "LUNITS";
+ public static final String LUPREC = "LUPREC";
+ public static final String MAXACTVP = "MAXACTVP";
+ public static final String MENU = "MENU";
+ public static final String MIRRTEXT = "MIRRTEXT";
+ public static final String ORTHOMODE = "ORTHOMODE";
+ public static final String OSMODE = "OSMODE";
+ public static final String PDMODE = "PDMODE";
+ public static final String PDSIZE = "PDSIZE";
+ public static final String PELEVATION = "PELEVATION";
+ public static final String PEXTMAX = "PEXTMAX";
+ public static final String PEXTMIN = "PEXTMIN";
+ public static final String PLIMCHECK = "PLIMCHECK";
+ public static final String PLIMMAX = "PLIMMAX";
+ public static final String PLIMMIN = "PLIMMIN";
+ public static final String PLINEGEN = "PLINEGEN";
+ public static final String PLINEWID = "PLINEWID";
+ public static final String PSLTSCALE = "PSLTSCALE";
+ public static final String PUCSNAME = "PUCSNAME";
+ public static final String PUCSORG = "PUCSORG";
+ public static final String PUCSXDIR = "PUCSXDIR";
+ public static final String PUCSYDIR = "PUCSYDIR";
+ public static final String QTEXTMODE = "QTEXTMODE";
+ public static final String REGENMODE = "REGENMODE";
+ public static final String SHADEDGE = "SHADEDGE";
+ public static final String SHADEDIF = "SHADEDIF";
+ public static final String SKETCHINC = "SKETCHINC";
+ public static final String SKPOLY = "SKPOLY";
+ public static final String SNAPANG = "SNAPANG";
+ public static final String SNAPBASE = "SNAPBASE";
+ public static final String SNAPISOPAIR = "SNAPISOPAIR";
+ public static final String SNAPMODE = "SNAPMODE";
+ public static final String SNAPSTYLE = "SNAPSTYLE";
+ public static final String SNAPUNIT = "SNAPUNIT";
+ public static final String SPLFRAME = "SPLFRAME";
+ public static final String SPLINESEGS = "SPLINESEGS";
+ public static final String SPLINETYPE = "SPLINETYPE";
+ public static final String SURFTAB1 = "SURFTAB1";
+ public static final String SURFTAB2 = "SURFTAB2";
+ public static final String SURFTYPE = "SURFTYPE";
+ public static final String SURFU = "SURFU";
+ public static final String SURFV = "SURFV";
+ public static final String TDCREATE = "TDCREATE";
+ public static final String TDINDWG = "TDINDWG";
+ public static final String TDUPDATE = "TDUPDATE";
+ public static final String TDUSRTIMER = "TDUSRTIMER";
+ public static final String TEXTSIZE = "TEXTSIZE";
+ public static final String TEXTSTYLE = "TEXTSTYLE";
+ public static final String THICKNESS = "THICKNESS";
+ public static final String TILEMODE = "TILEMODE";
+ public static final String TRACEWID = "TRACEWID";
+ public static final String UCSNAME = "UCSNAME";
+ public static final String UCSORG = "UCSORG";
+ public static final String UCSXDIR = "UCSXDIR";
+ public static final String UCSYDIR = "UCSYDIR";
+ public static final String UNITMODE = "UNITMODE";
+ public static final String USERI1 = "USERI1";
+ public static final String USERI2 = "USERI2";
+ public static final String USERI3 = "USERI3";
+ public static final String USERI4 = "USERI4";
+ public static final String USERI5 = "USERI5";
+ public static final String USERR1 = "USERR1";
+ public static final String USERR2 = "USERR2";
+ public static final String USERR3 = "USERR3";
+ public static final String USERR4 = "USERR4";
+ public static final String USERR5 = "USERR5";
+ public static final String USRTIMER = "USRTIMER";
+ public static final String VIEWCTR = "VIEWCTR";
+ public static final String VIEWDIR = "VIEWDIR";
+ public static final String VIEWSIZE = "VIEWSIZE";
+ public static final String VISRETAIN = "VISRETAIN";
+ public static final String WORLDVIEW = "WORLDVIEW";
+
+ Map> headerTable;
+
+ public DxfHEADER() {
+ headerTable = new LinkedHashMap<>();
+ }
+
+ public List getVariable(String nomVariable) {
+ return headerTable.get(nomVariable);
+ }
+
+ public void setVariable(String nomVariable, List groups) {
+ headerTable.put(nomVariable, groups);
+ }
+
+ public static DxfHEADER readHeader(RandomAccessFile raf) throws NumberFormatException, IOException {
+ DxfHEADER header = new DxfHEADER();
+ DxfGroup group;
+ String nomVariable = null;
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ if (group.equals(DxfFile.ENDSEC)) break;
+ else if (group.getCode()==9) {
+ if (DxfFile.DEBUG) group.print(4);
+ nomVariable = group.getValue();
+ nomVariable = nomVariable.substring(1);
+ header.headerTable.put(nomVariable, new ArrayList<>(1));
+ }
+ //else if (group.getCode() == 999) {}
+ else if (nomVariable != null) {
+ if (DxfFile.DEBUG) group.print(8);
+ List groups = header.headerTable.get(nomVariable);
+ groups.add(group);
+ }
+ //else { }
+ }
+ return header;
+ }
+
+ public String toString() {
+ Iterator it = headerTable.keySet().iterator();
+ StringBuilder sb = new StringBuilder(DxfFile.SECTION.toString());
+ sb.append(DxfFile.HEADER);
+ while (it.hasNext()) {
+ String var = it.next();
+ sb.append(DxfGroup.toString(9, "$"+var));
+ List liste = headerTable.get(var);
+ for (DxfGroup dxfGroup : liste) {
+ sb.append(dxfGroup.toString());
+ }
+ }
+ sb.append(DxfFile.ENDSEC);
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLINE.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLINE.java
new file mode 100644
index 0000000..9ebf529
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLINE.java
@@ -0,0 +1,82 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+
+/**
+ * LINE DXF entity.
+ * This class has a static method reading a DXF LINE and adding the new
+ * feature to a FeatureCollection
+ * @author Michaël Michaud
+ */
+public class DxfLINE extends DxfENTITY {
+
+ public DxfLINE() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf, FeatureCollection entities)
+ throws IOException {
+ Feature feature = new BasicFeature(DxfFile.DXF_SCHEMA);
+ feature.setAttribute("LTYPE", "BYLAYER");
+ feature.setAttribute("THICKNESS", 0.0);
+ feature.setAttribute("COLOR", 256); // equivalent to BYLAYER
+ double x1=Double.NaN, y1=Double.NaN, z1=Double.NaN;
+ double x2=Double.NaN, y2=Double.NaN, z2=Double.NaN;
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ int code = group.getCode();
+ if (code==0) break;
+ if (DxfFile.DEBUG) group.print(12);
+ if (code==8) feature.setAttribute("LAYER", group.getValue());
+ else if (code==6) feature.setAttribute("LTYPE", group.getValue());
+ else if (code==39) feature.setAttribute("THICKNESS", group.getDoubleValue());
+ else if (code==62) feature.setAttribute("COLOR", group.getIntValue());
+ else if (code==10) x1 = group.getDoubleValue();
+ else if (code==20) y1 = group.getDoubleValue();
+ else if (code==30) z1 = group.getDoubleValue();
+ else if (code==11) x2 = group.getDoubleValue();
+ else if (code==21) y2 = group.getDoubleValue();
+ else if (code==31) z2 = group.getDoubleValue();
+ //else {}
+ }
+ if (!Double.isNaN(x1) && !Double.isNaN(y1) && !Double.isNaN(x2) && !Double.isNaN(y2)) {
+ GeometryFactory gf = new GeometryFactory(DPM,0);
+ feature.setGeometry(gf.createLineString(
+ new Coordinate[]{new Coordinate(x1,y1,z1),new Coordinate(x2,y2,z2)})
+ );
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLWPOLYLINE.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLWPOLYLINE.java
new file mode 100644
index 0000000..d965f90
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfLWPOLYLINE.java
@@ -0,0 +1,132 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.*;
+
+/**
+ * LWPOLYLINE DXF entity.
+ * This class has a static method reading a DXF LWPOLYLINE and adding the new
+ * feature to a FeatureCollection
+ * @author Michaël Michaud
+ */
+public class DxfLWPOLYLINE extends DxfENTITY {
+
+ public DxfLWPOLYLINE() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf, FeatureCollection entities)
+ throws IOException {
+ Feature feature = new BasicFeature(entities.getFeatureSchema());
+ GeometryFactory gf = new GeometryFactory(DPM,0);
+ String geomType = "LineString";
+ CoordinateList coordList = new CoordinateList();
+ feature.setAttribute("LTYPE", "BYLAYER");
+ feature.setAttribute("ELEVATION", 0.0);
+ feature.setAttribute("THICKNESS", 0.0);
+ feature.setAttribute("COLOR", 256); // equivalent to BYLAYER
+ double x=Double.NaN;
+ double y=Double.NaN;
+ double z=Double.NaN;
+ Coordinate coord = null;
+ DxfGroup group = DxfFile.ENTITIES;
+ int code;
+ while (0 != (code = group.getCode())) {
+ if (DxfFile.DEBUG) group.print(12);
+ if (code==8) {
+ feature.setAttribute("LAYER", group.getValue());
+ }
+ else if (code==6) {
+ feature.setAttribute("LTYPE", group.getValue());
+ }
+ else if (code==38) {
+ feature.setAttribute("ELEVATION", group.getDoubleValue());
+ z = group.getDoubleValue();
+ }
+ else if (code==39) {
+ feature.setAttribute("THICKNESS", group.getDoubleValue());
+ }
+ else if (code==62) {
+ feature.setAttribute("COLOR", group.getIntValue());
+ }
+ else if (code==70) {
+ if ((group.getIntValue()&1)==1) geomType = "Polygon";
+ }
+ else if (code==10) {
+ coord = new Coordinate();
+ coord.x = group.getDoubleValue();
+ }
+ else if (code==20) {
+ if (coord != null) {
+ coord.y = group.getDoubleValue();
+ coordList.add(new Coordinate(x, y, z));
+ }
+ }
+ //else {}
+ group = DxfGroup.readGroup(raf);
+ }
+ if (geomType.equals("LineString")) {
+ // Handle cases where coordList does not describe a valid Line
+ if (coordList.size() == 1) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 &&
+ coordList.getCoordinate(0).equals(coordList.getCoordinate(1))) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else {
+ feature.setGeometry(gf.createLineString(coordList.toCoordinateArray()));
+ }
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ else if (geomType.equals("Polygon")) {
+ coordList.closeRing();
+ // Handle cases where coordList does not describe a valid Polygon
+ if (coordList.size() == 1) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 &&
+ coordList.getCoordinate(0).equals(coordList.getCoordinate(1))) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 || coordList.size() == 3) {
+ feature.setGeometry(gf.createLineString(coordList.toCoordinateArray()));
+ }
+ else {
+ feature.setGeometry(gf.createPolygon(gf.createLinearRing(coordList.toCoordinateArray())));
+ }
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ //else {}
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOINT.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOINT.java
new file mode 100644
index 0000000..5aef597
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOINT.java
@@ -0,0 +1,79 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+
+
+/**
+ * POINT DXF entity.
+ * This class has a static method reading a DXF POINT and adding the new
+ * feature to a FeatureCollection
+ * @author Michaël Michaud
+ */
+public class DxfPOINT extends DxfENTITY {
+
+ public DxfPOINT() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf,
+ FeatureCollection entities)
+ throws IOException {
+ Feature feature = new BasicFeature(DxfFile.DXF_SCHEMA);
+ feature.setAttribute("LTYPE", "BYLAYER");
+ feature.setAttribute("THICKNESS", 0.0);
+ feature.setAttribute("COLOR", 256); // equivalent to BYLAYER
+ double x=Double.NaN, y=Double.NaN, z=Double.NaN;
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ int code = group.getCode();
+ if (code == 0) break;
+ if (DxfFile.DEBUG) group.print(12);
+ if (code==8) feature.setAttribute("LAYER", group.getValue());
+ else if (code==6) feature.setAttribute("LTYPE", group.getValue());
+ //else if (code==38) feature.setAttribute("ELEVATION", new Double(group.getDoubleValue()));
+ else if (code==39) feature.setAttribute("THICKNESS", group.getDoubleValue());
+ else if (code==62) feature.setAttribute("COLOR", group.getIntValue());
+ else if (code==10) x = group.getDoubleValue();
+ else if (code==20) y = group.getDoubleValue();
+ else if (code==30) z = group.getDoubleValue();
+ //else {}
+ }
+ if (!Double.isNaN(x) && !Double.isNaN(y)) {
+ GeometryFactory gf = new GeometryFactory(DPM,0);
+ feature.setGeometry(gf.createPoint(new Coordinate(x,y,z)));
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOLYLINE.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOLYLINE.java
new file mode 100644
index 0000000..12306e9
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfPOLYLINE.java
@@ -0,0 +1,126 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.CoordinateList;
+import org.locationtech.jts.geom.GeometryFactory;
+
+
+/**
+ * POLYLINE DXF entity.
+ * This class has a static method reading a DXF POLYLINE and adding the new
+ * feature to a FeatureCollection
+ * @author Michaël Michaud
+ */
+// History
+public class DxfPOLYLINE extends DxfENTITY {
+
+ public DxfPOLYLINE() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf,
+ FeatureCollection entities)
+ throws IOException {
+ Feature feature = new BasicFeature(entities.getFeatureSchema());
+ String geomType = "LineString";
+ CoordinateList coordList = new CoordinateList();
+ feature.setAttribute("LTYPE", "BYLAYER");
+ feature.setAttribute("THICKNESS", 0.0);
+ feature.setAttribute("COLOR", 256); // equivalent to BYLAYER
+ //double x=Double.NaN, y=Double.NaN, z=Double.NaN;
+ DxfGroup group = DxfFile.ENTITIES;
+ GeometryFactory gf = new GeometryFactory(DPM,0);
+ while (!group.equals(SEQEND)) {
+ if (DxfFile.DEBUG) group.print(12);
+ int code = group.getCode();
+ if (code==8) {
+ feature.setAttribute("LAYER", group.getValue());
+ }
+ else if (code==6) {
+ feature.setAttribute("LTYPE", group.getValue());
+ }
+ else if (code==39) {
+ feature.setAttribute("THICKNESS", group.getDoubleValue());
+ }
+ else if (code==62) {
+ feature.setAttribute("COLOR", group.getIntValue());
+ }
+ else if (code==70) {
+ if ((group.getIntValue()&1)==1) geomType = "Polygon";
+ }
+ else if (group.equals(VERTEX)) {
+ group = DxfVERTEX.readEntity(raf, coordList);
+ continue;
+ }
+ else if (group.equals(SEQEND)) {
+ continue;
+ }
+ //else {}
+ group = DxfGroup.readGroup(raf);
+ }
+ if (geomType.equals("LineString")) {
+ // Handle cases where coordList does not describe a valid Line
+ if (coordList.size() == 1) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 &&
+ coordList.getCoordinate(0).equals(coordList.getCoordinate(1))) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else {
+ feature.setGeometry(gf.createLineString(coordList.toCoordinateArray()));
+ }
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ else if (geomType.equals("Polygon")) {
+ coordList.closeRing();
+ // Handle cases where coordList does not describe a valid Polygon
+ if (coordList.size() == 1) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 &&
+ coordList.getCoordinate(0).equals(coordList.getCoordinate(1))) {
+ feature.setGeometry(gf.createPoint(coordList.getCoordinate(0)));
+ }
+ else if (coordList.size() == 2 || coordList.size() == 3) {
+ feature.setGeometry(gf.createLineString(coordList.toCoordinateArray()));
+ }
+ else {
+ feature.setGeometry(gf.createPolygon(gf.createLinearRing(coordList.toCoordinateArray())));
+ }
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ //else {}
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfReader.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfReader.java
new file mode 100644
index 0000000..2376501
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfReader.java
@@ -0,0 +1,95 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+
+import com.vividsolutions.jump.feature.*;
+import com.vividsolutions.jump.io.JUMPReader;
+import com.vividsolutions.jump.io.DriverProperties;
+import com.vividsolutions.jump.io.IllegalParametersException;
+import org.locationtech.jts.geom.GeometryFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+
+/**
+ * DXF reader.
+ * Use the file name to read in the DriverProperties parameter, read the file
+ * and return a FeatureCollection.
+ * @author Michaël Michaud
+ */
+public class DxfReader implements JUMPReader {
+
+ //private DxfFile dxfFile = null;
+
+ /** Creates new DxfReader */
+ public DxfReader() {
+ }
+
+ /**
+ * Main method to read a DXF file.
+ * @param dp 'InputFile' or 'DefaultValue' to specify input .dxf file.
+ *
+ */
+ public FeatureCollection read(DriverProperties dp) throws Exception {
+ FeatureCollection result;
+ String dxfFileName;
+ String fname;
+ int loc;
+ dxfFileName = dp.getProperty("File");
+
+ if (dxfFileName == null) {
+ dxfFileName = dp.getProperty("DefaultValue");
+ }
+
+ if (dxfFileName == null) {
+ throw new IllegalParametersException("no File property specified");
+ }
+
+ loc = dxfFileName.lastIndexOf(File.separatorChar);
+ fname = dxfFileName.substring(loc + 1);
+ loc = fname.lastIndexOf(".");
+ if (loc == -1) {
+ throw new IllegalParametersException("Filename must end in '.dxf'");
+ }
+
+ //dxfFile = getDXFFile(dxfFileName, dp.getProperty("CompressedFile"));
+ DxfFile dxfFile;
+ GeometryFactory factory = new GeometryFactory();
+ dxfFile = DxfFile.createFromFile(new File(dxfFileName));
+ result = dxfFile.read(factory);
+ System.gc();
+ return result;
+ }
+
+ private Collection exceptions;
+ public Collection getExceptions() {
+ if (exceptions == null) exceptions = new ArrayList<>();
+ return exceptions;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLES.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLES.java
new file mode 100644
index 0000000..819863c
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLES.java
@@ -0,0 +1,216 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+
+
+/**
+ * The TABLES section of a DXF file. It contains LAYERs, LTYPEs...
+ * There is a static reader to read the TABLES section in a DXF file
+ * and a toString method able to write the section in a DXF form
+ * @author Michaël Michaud
+ */
+// History
+// 2006-11-12 : Bug fixed x==Double.NaN --> Double.isNaN(x)
+public class DxfTABLES {
+
+ public final static DxfGroup TABLE = new DxfGroup(0, "TABLE");
+ public final static DxfGroup ENDTAB = new DxfGroup(0, "ENDTAB");
+ public final static DxfGroup NBMAX = new DxfGroup(70, "NBMAX");
+ public final static DxfGroup APPID = new DxfGroup(2, "APPID");
+ public final static DxfGroup DIMSTYLE = new DxfGroup(2, "DIMSTYLE");
+ public final static DxfGroup LTYPE = new DxfGroup(2, "LTYPE");
+ public final static DxfGroup LAYER = new DxfGroup(2, "LAYER");
+ public final static DxfGroup STYLE = new DxfGroup(2, "STYLE");
+ public final static DxfGroup UCS = new DxfGroup(2, "UCS");
+ public final static DxfGroup VIEW = new DxfGroup(2, "VIEW");
+ public final static DxfGroup VPORT = new DxfGroup(2, "VPORT");
+
+ private Map appId;
+ private Map dimStyle;
+ private Map lType;
+ private Map layer;
+ private Map style;
+ private Map ucs;
+ private Map view;
+ private Map vPort;
+
+ public DxfTABLES() {
+ appId = new HashMap<>();
+ dimStyle = new HashMap<>();
+ lType = new HashMap<>();
+ layer = new HashMap<>();
+ style = new HashMap<>();
+ ucs = new HashMap<>();
+ view = new HashMap<>();
+ vPort = new HashMap<>();
+ }
+
+ public static DxfTABLES readTables(RandomAccessFile raf) throws NumberFormatException, IOException {
+ DxfTABLES tables = new DxfTABLES();
+ DxfGroup group;
+ //String nomVariable = null;
+ // Iteration over each table
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ if (group.equals(DxfFile.ENDSEC)) break;
+ //Map map = null;
+ else if (group.equals(TABLE)) {
+ // Lecture du groupe portant le nom de la table
+ group = DxfGroup.readGroup(raf);
+ //if (group == null) break; // never happens
+ if (DxfFile.DEBUG) group.print(4);
+ if (group.equals(APPID)) {
+ tables.appId = DxfTABLE_APPID_ITEM.readTable(raf);
+ }
+ else if (group.equals(DIMSTYLE)) {
+ tables.dimStyle = DxfTABLE_DIMSTYLE_ITEM.readTable(raf);
+ }
+ else if (group.equals(LTYPE)) {
+ tables.lType = DxfTABLE_LTYPE_ITEM.readTable(raf);
+ }
+ else if (group.equals(LAYER)) {
+ tables.layer = DxfTABLE_LAYER_ITEM.readTable(raf);
+ }
+ else if (group.equals(STYLE)) {
+ tables.style = DxfTABLE_STYLE_ITEM.readTable(raf);
+ }
+ else if (group.equals(UCS)) {
+ tables.ucs = DxfTABLE_UCS_ITEM.readTable(raf);
+ }
+ else if (group.equals(VIEW)) {
+ tables.view = DxfTABLE_VIEW_ITEM.readTable(raf);
+ }
+ else if (group.equals(VPORT)) {
+ tables.vPort = DxfTABLE_VPORT_ITEM.readTable(raf);
+ }
+ //else if (group.getCode() == 999) {}
+ //else {}
+ }
+ //else if (group.getCode() == 999) {}
+ //else {}
+ }
+ return tables;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(DxfFile.SECTION.toString());
+ sb.append(DxfFile.TABLES);
+ if (vPort.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.VPORT.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(vPort.size())));
+ //Iterator it = vPort.keySet().iterator();
+ for (DxfTABLE_ITEM item : vPort.values()) {
+ sb.append(DxfGroup.toString(0, "VPORT"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (appId.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.APPID.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(appId.size())));
+ //Iterator it = appId.keySet().iterator();
+ for (DxfTABLE_ITEM item : appId.values()) {
+ sb.append(DxfGroup.toString(0, "APPID"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (dimStyle.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.DIMSTYLE.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(dimStyle.size())));
+ //Iterator it = dimStyle.keySet().iterator();
+ for (DxfTABLE_ITEM item : dimStyle.values()) {
+ sb.append(DxfGroup.toString(0, "DIMSTYLE"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (lType.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.LTYPE.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(lType.size())));
+ //Iterator it = lType.keySet().iterator();
+ for (DxfTABLE_ITEM item : lType.values()) {
+ sb.append(DxfGroup.toString(0, "LTYPE"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (layer.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.LAYER.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(layer.size())));
+ //Iterator it = layer.keySet().iterator();
+ for (DxfTABLE_ITEM item : layer.values()) {
+ sb.append(DxfGroup.toString(0, "LAYER"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (style.size() > 0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.STYLE.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(style.size())));
+ //Iterator it = style.keySet().iterator();
+ for (DxfTABLE_ITEM item : style.values()) {
+ sb.append(DxfGroup.toString(0, "STYLE"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (ucs.size() >0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.UCS.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(ucs.size())));
+ //Iterator it = ucs.keySet().iterator();
+ for (DxfTABLE_ITEM item : ucs.values()) {
+ sb.append(DxfGroup.toString(0, "UCS"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ if (view.size() >0) {
+ sb.append(DxfTABLES.TABLE.toString());
+ sb.append(DxfTABLES.VIEW.toString());
+ sb.append(DxfGroup.toString(70, Integer.toString(view.size())));
+ //Iterator it = view.keySet().iterator();
+ for (DxfTABLE_ITEM item : view.values()) {
+ sb.append(DxfGroup.toString(0, "VIEW"));
+ sb.append(item.toString());
+ }
+ sb.append(DxfTABLES.ENDTAB.toString());
+ }
+ sb.append(DxfFile.ENDSEC);
+ return sb.toString();
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_APPID_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_APPID_ITEM.java
new file mode 100644
index 0000000..d19600b
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_APPID_ITEM.java
@@ -0,0 +1,66 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The APPID item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_APPID_ITEM extends DxfTABLE_ITEM {
+
+ public DxfTABLE_APPID_ITEM(String name, int flags) {
+ super(name, flags);
+ }
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_APPID_ITEM item = new DxfTABLE_APPID_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(APPID)) {
+ item = new DxfTABLE_APPID_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {item.setFlags(group.getIntValue());}
+ //else {}
+ }
+ return table;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_DIMSTYLE_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_DIMSTYLE_ITEM.java
new file mode 100644
index 0000000..704d395
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_DIMSTYLE_ITEM.java
@@ -0,0 +1,68 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The DIMSTYLE item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_DIMSTYLE_ITEM extends DxfTABLE_ITEM {
+
+ public DxfTABLE_DIMSTYLE_ITEM(String name, int flags) {
+ super(name, flags);
+ }
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_DIMSTYLE_ITEM item = new DxfTABLE_DIMSTYLE_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(DIMSTYLE)) {
+ item = new DxfTABLE_DIMSTYLE_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {
+ item.setFlags(group.getIntValue());
+ }
+ //else {}
+ }
+ return table;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_ITEM.java
new file mode 100644
index 0000000..a8080e6
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_ITEM.java
@@ -0,0 +1,71 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+
+/**
+ * This class represent one of the TABLE of the TABLES section.
+ * It has as many subclasses as the number of table types
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_ITEM {
+
+ public final static DxfGroup ENDTAB = new DxfGroup(0, "ENDTAB");
+ public final static DxfGroup APPID = new DxfGroup(0, "APPID");
+ public final static DxfGroup DIMSTYLE = new DxfGroup(0, "DIMSTYLE");
+ public final static DxfGroup LAYER = new DxfGroup(0, "LAYER");
+ public final static DxfGroup LTYPE = new DxfGroup(0, "LTYPE");
+ public final static DxfGroup STYLE = new DxfGroup(0, "STYLE");
+ public final static DxfGroup UCS = new DxfGroup(0, "UCS");
+ public final static DxfGroup VIEW = new DxfGroup(0, "VIEW");
+ public final static DxfGroup VPORT = new DxfGroup(0, "VPORT");
+
+ private String name;
+ private int flags;
+
+ public DxfTABLE_ITEM(String name, int flags) {
+ this.name = name;
+ this.flags = flags;
+ }
+
+ public String getName(){return name;}
+ public void setName(String name) {this.name = name;}
+ public int getFlags(){return flags;}
+ public void setFlags(int flags) {this.flags = flags;}
+
+ public boolean getFlag1(){return ((flags&1)==1);}
+ public boolean getFlag2(){return ((flags&2)==2);}
+ public boolean getFlag4(){return ((flags&4)==4);}
+ public boolean getFlag8(){return ((flags&8)==8);}
+ public boolean getFlag16(){return ((flags&16)==16);}
+ public boolean getFlag32(){return ((flags&32)==32);}
+ public boolean getFlag64(){return ((flags&64)==64);}
+ public boolean getFlag128(){return ((flags&128)==128);}
+
+ public String toString() {
+ return DxfGroup.toString(2, name) + DxfGroup.toString(70, flags);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LAYER_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LAYER_ITEM.java
new file mode 100644
index 0000000..9ef9a6a
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LAYER_ITEM.java
@@ -0,0 +1,93 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The LAYER item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_LAYER_ITEM extends DxfTABLE_ITEM {
+
+ private int colorNumber;
+ private String lineType;
+
+ public DxfTABLE_LAYER_ITEM(String name, int flags) {
+ super(name, flags);
+ this.colorNumber = 0;
+ this.lineType = "DEFAULT";
+ }
+
+ public DxfTABLE_LAYER_ITEM(String name, int flags, int colorNumber, String lineType) {
+ super(name, flags);
+ this.colorNumber = colorNumber;
+ this.lineType = lineType;
+ }
+
+ public String getLineType() {return lineType;}
+
+ public void setLineType(String lineType) {this.lineType = lineType;}
+
+ public int getcolorNumber() {return colorNumber;}
+
+ public void setColorNumber(int colorNumber) {this.colorNumber = colorNumber;}
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_LAYER_ITEM item = new DxfTABLE_LAYER_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(LAYER)) {
+ item = new DxfTABLE_LAYER_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ //System.out.println("\t\t" + group.getValue());
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {item.setFlags(group.getIntValue());}
+ else if (group.getCode()==62) {item.setColorNumber(group.getIntValue());}
+ else if (group.getCode()==6) {item.setLineType(group.getValue());}
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ return super.toString() + DxfGroup.toString(62, colorNumber) +
+ DxfGroup.toString(6, lineType);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LTYPE_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LTYPE_ITEM.java
new file mode 100644
index 0000000..d066ab0
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_LTYPE_ITEM.java
@@ -0,0 +1,112 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The LTYPE item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_LTYPE_ITEM extends DxfTABLE_ITEM {
+ private String description;
+ private int alignment;
+ private float patternLength;
+ private float[] pattern;
+
+ public DxfTABLE_LTYPE_ITEM(String name, int flags) {
+ super(name, flags);
+ this.description = "";
+ this.alignment = 0;
+ this.patternLength = 1f;
+ this.pattern = new float[]{1f};
+ }
+
+ public DxfTABLE_LTYPE_ITEM(String name, int flags, String description,
+ int alignment, float patternLength, float[] pattern) {
+ super(name, flags);
+ this.description = description;
+ this.alignment = alignment;
+ this.patternLength = patternLength;
+ this.pattern = pattern;
+ }
+
+ public String getDescription() {return description;}
+ public void setDescription(String description) {this.description = description;}
+ public int getAlignment() {return alignment;}
+ public void setAlignment(int alignment) {this.alignment = alignment;}
+ public float getPatternLength() {return patternLength;}
+ public void setPatternLength(float patternLength) {this.patternLength = patternLength;}
+ public float[] getPattern() {return pattern;}
+ public void setPattern(float[] pattern) {this.pattern = pattern;}
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_LTYPE_ITEM item = new DxfTABLE_LTYPE_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ int patternDashCount = 0;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(LTYPE)) {
+ item = new DxfTABLE_LTYPE_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {item.setFlags(group.getIntValue());}
+ else if (group.getCode()==3) {item.setDescription(group.getValue());}
+ else if (group.getCode()==72) {item.setAlignment(group.getIntValue());}
+ else if (group.getCode()==73) {item.setPattern(new float[group.getIntValue()]);}
+ else if (group.getCode()==40) {item.setPatternLength(group.getFloatValue());}
+ else if (group.getCode()==49 && patternDashCount < item.getPattern().length) {
+ item.getPattern()[patternDashCount++] = group.getFloatValue();
+ }
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append(DxfGroup.toString(3, description));
+ sb.append(DxfGroup.toString(72, alignment));
+ sb.append(DxfGroup.toString(73, pattern.length));
+ sb.append(DxfGroup.toString(40, patternLength, 3));
+ for (float p : pattern) {
+ sb.append(DxfGroup.toString(49, p, 3));
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_STYLE_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_STYLE_ITEM.java
new file mode 100644
index 0000000..4d26a12
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_STYLE_ITEM.java
@@ -0,0 +1,147 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The STYLE item in the TABLES section
+ * There is a static reader to read the item from a DXF file
+ * and a toString method to write it in the DXF format
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_STYLE_ITEM extends DxfTABLE_ITEM {
+
+ private float textHeight;
+ private float widthFactor;
+ private float obliqueAngle;
+ private int textGenerationFlags;
+ private float lastHeightUsed;
+ private String primaryFontFileName;
+ private String bigFontFileName;
+
+ public DxfTABLE_STYLE_ITEM(String name, int flags) {
+ super(name, flags);
+ this.textHeight = 0f;
+ this.widthFactor = 0f;
+ this.obliqueAngle = 0f;
+ this.textGenerationFlags = 0;
+ this.lastHeightUsed = 0f;
+ this.primaryFontFileName = "";
+ this.bigFontFileName = "";
+ }
+
+ public DxfTABLE_STYLE_ITEM(String name, int flags,
+ float textHeight,
+ float widthFactor,
+ float obliqueAngle,
+ int textGenerationFlags,
+ float lastHeightUsed,
+ String primaryFontFileName,
+ String bigFontFileName) {
+ super(name, flags);
+ this.textHeight = textHeight;
+ this.widthFactor = widthFactor;
+ this.obliqueAngle = obliqueAngle;
+ this.textGenerationFlags = textGenerationFlags;
+ this.lastHeightUsed = lastHeightUsed;
+ this.primaryFontFileName = primaryFontFileName;
+ this.bigFontFileName = bigFontFileName;
+ }
+
+ public float getTextHeight() {return textHeight;}
+ public float getWidthFactor() {return widthFactor;}
+ public float getObliqueAngle() {return obliqueAngle;}
+ public int getTextGenerationFlags() {return textGenerationFlags;}
+ public float getLastHeightUsed() {return lastHeightUsed;}
+ public String getPrimaryFontFileName() {return primaryFontFileName;}
+ public String getBigFontFileName() {return bigFontFileName;}
+
+ public void setTextHeight(float textHeight) {
+ this.textHeight = textHeight;
+ }
+ public void setWidthFactor(float widthFactor) {
+ this.widthFactor = widthFactor;
+ }
+ public void setObliqueAngle(float obliqueAngle) {
+ this.obliqueAngle = obliqueAngle;
+ }
+ public void setTextGenerationFlags(int textGenerationFlags) {
+ this.textGenerationFlags = textGenerationFlags;
+ }
+ public void setLastHeightUsed(float lastHeightUsed) {
+ this.lastHeightUsed = lastHeightUsed;
+ }
+ public void setPrimaryFontFileName(String primaryFontFileName) {
+ this.primaryFontFileName = primaryFontFileName;
+ }
+ public void setBigFontFileName(String bigFontFileName) {
+ this.bigFontFileName = bigFontFileName;
+ }
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_STYLE_ITEM item = new DxfTABLE_STYLE_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(STYLE)) {
+ item = new DxfTABLE_STYLE_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {item.setFlags(group.getIntValue());}
+ else if (group.getCode()==40) {item.setTextHeight(group.getFloatValue());}
+ else if (group.getCode()==41) {item.setWidthFactor(group.getFloatValue());}
+ else if (group.getCode()==50) {item.setObliqueAngle(group.getFloatValue());}
+ else if (group.getCode()==71) {item.setTextGenerationFlags(group.getIntValue());}
+ else if (group.getCode()==42) {item.setLastHeightUsed(group.getFloatValue());}
+ else if (group.getCode()==3) {item.setPrimaryFontFileName(group.getValue());}
+ else if (group.getCode()==4) {item.setBigFontFileName(group.getValue());}
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ return super.toString() +
+ DxfGroup.toString(40, textHeight, 3) +
+ DxfGroup.toString(41, widthFactor, 3) +
+ DxfGroup.toString(50, obliqueAngle, 3) +
+ DxfGroup.toString(71, textGenerationFlags) +
+ DxfGroup.toString(42, lastHeightUsed, 3) +
+ DxfGroup.toString(3, primaryFontFileName) +
+ DxfGroup.toString(4, bigFontFileName);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_UCS_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_UCS_ITEM.java
new file mode 100644
index 0000000..83137ac
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_UCS_ITEM.java
@@ -0,0 +1,136 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The UCS item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_UCS_ITEM extends DxfTABLE_ITEM {
+
+ private double[] origin;
+ private double[] xAxisDirection;
+ private double[] yAxisDirection;
+
+ public DxfTABLE_UCS_ITEM(String name, int flags) {
+ super(name, flags);
+ this.origin = new double[3];
+ this.xAxisDirection = new double[3];
+ this.yAxisDirection = new double[3];
+ }
+
+ public DxfTABLE_UCS_ITEM(String name, int flags,
+ double[] origin,
+ double[] xAxisDirection,
+ double[] yAxisDirection ) {
+ super(name, flags);
+ this.origin = origin;
+ this.xAxisDirection = xAxisDirection;
+ this.yAxisDirection = yAxisDirection;
+ }
+
+ public double[] getOrigin() {return origin;}
+ public double getOriginX() {return origin[0];}
+ public double getOriginY() {return origin[1];}
+ public double getOriginZ() {return origin[2];}
+
+ public double[] getXAxisDirection() {return xAxisDirection;}
+ public double getXAxisDirectionX() {return xAxisDirection[0];}
+ public double getXAxisDirectionY() {return xAxisDirection[1];}
+ public double getXAxisDirectionZ() {return xAxisDirection[2];}
+
+ public double[] getYAxisDirection() {return yAxisDirection;}
+ public double getYAxisDirectionX() {return yAxisDirection[0];}
+ public double getYAxisDirectionY() {return yAxisDirection[1];}
+ public double getYAxisDirectionZ() {return yAxisDirection[2];}
+
+ public void setOrigin(double[] origin) {this.origin = origin;}
+ public void setOriginX(double originX) {this.origin[0] = originX;}
+ public void setOriginY(double originY) {this.origin[1] = originY;}
+ public void setOriginZ(double originZ) {this.origin[2] = originZ;}
+
+ public void setXAxisDirection(double[] xAxisDirection) {this.xAxisDirection = xAxisDirection;}
+ public void setXAxisDirectionX(double xAxisDirectionX) {this.xAxisDirection[0] = xAxisDirectionX;}
+ public void setXAxisDirectionY(double xAxisDirectionY) {this.xAxisDirection[1] = xAxisDirectionY;}
+ public void setXAxisDirectionZ(double xAxisDirectionZ) {this.xAxisDirection[2] = xAxisDirectionZ;}
+
+
+ public void setYAxisDirection(double[] yAxisDirection) {this.yAxisDirection = yAxisDirection;}
+ public void setYAxisDirectionX(double yAxisDirectionX) {this.yAxisDirection[0] = yAxisDirectionX;}
+ public void setYAxisDirectionY(double yAxisDirectionY) {this.yAxisDirection[1] = yAxisDirectionY;}
+ public void setYAxisDirectionZ(double yAxisDirectionZ) {this.yAxisDirection[2] = yAxisDirectionZ;}
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_UCS_ITEM item = new DxfTABLE_UCS_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(UCS)) {
+ item = new DxfTABLE_UCS_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {item.setFlags(group.getIntValue());}
+ else if (group.getCode()==10) {item.setOriginX(group.getDoubleValue());}
+ else if (group.getCode()==20) {item.setOriginY(group.getDoubleValue());}
+ else if (group.getCode()==30) {item.setOriginZ(group.getDoubleValue());}
+ else if (group.getCode()==11) {item.setXAxisDirectionX(group.getDoubleValue());}
+ else if (group.getCode()==21) {item.setXAxisDirectionY(group.getDoubleValue());}
+ else if (group.getCode()==31) {item.setXAxisDirectionZ(group.getDoubleValue());}
+ else if (group.getCode()==12) {item.setYAxisDirectionX(group.getDoubleValue());}
+ else if (group.getCode()==22) {item.setYAxisDirectionY(group.getDoubleValue());}
+ else if (group.getCode()==32) {item.setYAxisDirectionZ(group.getDoubleValue());}
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ return super.toString() +
+ DxfGroup.toString(10, origin[0], 6) +
+ DxfGroup.toString(20, origin[1], 6) +
+ DxfGroup.toString(30, origin[2], 6) +
+ DxfGroup.toString(11, xAxisDirection[0], 6) +
+ DxfGroup.toString(21, xAxisDirection[1], 6) +
+ DxfGroup.toString(31, xAxisDirection[2], 6) +
+ DxfGroup.toString(12, yAxisDirection[0], 6) +
+ DxfGroup.toString(22, yAxisDirection[1], 6) +
+ DxfGroup.toString(32, yAxisDirection[2], 6);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VIEW_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VIEW_ITEM.java
new file mode 100644
index 0000000..0dbf943
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VIEW_ITEM.java
@@ -0,0 +1,205 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The VIEW item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_VIEW_ITEM extends DxfTABLE_ITEM {
+ private float viewHeight;
+ private float viewWidth;
+ private double viewCenterPointX;
+ private double viewCenterPointY;
+ private double[] viewDirectionFromTarget;
+ private double[] targetPoint;
+ private float lensLength;
+ private double frontClippingPlaneOffset;
+ private double backClippingPlaneOffset;
+ private float twistAngle;
+ private int viewMode;
+
+ public DxfTABLE_VIEW_ITEM(String name, int flags) {
+ super(name, flags);
+ this.viewHeight = 0f;
+ this.viewWidth = 0f;
+ this.viewCenterPointX = 0.0;
+ this.viewCenterPointY = 0;
+ this.viewDirectionFromTarget = new double[3];
+ this.targetPoint = new double[3];
+ this.lensLength = 0f;
+ this.frontClippingPlaneOffset = 0.0;
+ this.backClippingPlaneOffset = 0.0;
+ this.twistAngle = 0f;
+ this.viewMode = 0;
+ }
+
+ public DxfTABLE_VIEW_ITEM(String name, int flags,
+ float viewHeight,
+ float viewWidth,
+ double viewCenterPointX,
+ double viewCenterPointY,
+ double[] viewDirectionFromTarget,
+ double[] targetPoint,
+ float lensLength,
+ double frontClippingPlaneOffset,
+ double backClippingPlaneOffset,
+ float twistAngle,
+ int viewMode) {
+ super(name, flags);
+ this.viewHeight = viewHeight;
+ this.viewWidth = viewWidth;
+ this.viewCenterPointX = viewCenterPointX;
+ this.viewCenterPointY = viewCenterPointY;
+ this.viewDirectionFromTarget = viewDirectionFromTarget;
+ this.targetPoint = targetPoint;
+ this.lensLength = lensLength;
+ this.frontClippingPlaneOffset = frontClippingPlaneOffset;
+ this.backClippingPlaneOffset = backClippingPlaneOffset;
+ this.twistAngle = twistAngle;
+ this.viewMode = viewMode;
+ }
+
+ public float getViewHeight() {return viewHeight;}
+ public float getViewWidth() {return viewWidth;}
+ public double getViewCenterPointX() {return viewCenterPointX;}
+ public double getViewCenterPointY() {return viewCenterPointY;}
+ public double[] getViewDirectionFromTarget() {return viewDirectionFromTarget;}
+ public double[] getTargetPoint() {return targetPoint;}
+ public float getLensLength() {return lensLength;}
+ public double getFrontClippingPlaneOffset() {return frontClippingPlaneOffset;}
+ public double getBackClippingPlaneOffset() {return backClippingPlaneOffset;}
+ public float getTwistAngle() {return twistAngle;}
+ public int getViewMode() {return viewMode;}
+
+ public void setViewHeight(float viewHeight) {this.viewHeight = viewHeight;}
+ public void setViewWidth(float viewWidth) {this.viewWidth = viewWidth;}
+ public void setViewCenterPointX(double viewCenterPointX) {this.viewCenterPointX = viewCenterPointX;}
+ public void setViewCenterPointY(double viewCenterPointY) {this.viewCenterPointY = viewCenterPointY;}
+ public void setViewDirectionFromTarget(double[] viewDirectionFromTarget) {this.viewDirectionFromTarget = viewDirectionFromTarget;}
+ public void setTargetPoint(double[] targetPoint) {this.targetPoint = targetPoint;}
+ public void setLensLength(float lensLength) {this.lensLength = lensLength;}
+ public void setFrontClippingPlaneOffset(double frontClippingPlaneOffset) {this.frontClippingPlaneOffset = frontClippingPlaneOffset;}
+ public void setBackClippingPlaneOffset(double backClippingPlaneOffset) {this.backClippingPlaneOffset = backClippingPlaneOffset;}
+ public void setTwistAngle(float twistAngle) {this.twistAngle = twistAngle;}
+ public void setViewMode(int viewMode) {this.viewMode = viewMode;}
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_VIEW_ITEM item = new DxfTABLE_VIEW_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ int code = group.getCode();
+ if (group.equals(VIEW)) {
+ item = new DxfTABLE_VIEW_ITEM("DEFAULT", 0);
+ }
+ else if (code==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (code==5) {} // tag appeared in version 13 of DXF
+ //else if (code==100) {} // tag appeared in version 13 of DXF
+ else if (code==70) {
+ item.setFlags(group.getIntValue());
+ }
+ else if (code==40) {
+ item.setViewHeight(group.getFloatValue());
+ }
+ else if (code==41) {
+ item.setViewWidth(group.getFloatValue());
+ }
+ else if (code==10) {
+ item.setViewCenterPointX(group.getDoubleValue());
+ }
+ else if (code==20) {
+ item.setViewCenterPointY(group.getDoubleValue());
+ }
+ else if (code==11) {
+ item.getViewDirectionFromTarget()[0] = group.getDoubleValue();
+ }
+ else if (code==21) {
+ item.getViewDirectionFromTarget()[1] = group.getDoubleValue();
+ }
+ else if (code==31) {
+ item.getViewDirectionFromTarget()[2] = group.getDoubleValue();
+ }
+ else if (code==12) {
+ item.getTargetPoint()[0] = group.getDoubleValue();
+ }
+ else if (code==22) {
+ item.getTargetPoint()[1] = group.getDoubleValue();
+ }
+ else if (code==32) {
+ item.getTargetPoint()[2] = group.getDoubleValue();
+ }
+ else if (code==42) {
+ item.setLensLength(group.getFloatValue());
+ }
+ else if (code==43) {
+ item.setFrontClippingPlaneOffset(group.getDoubleValue());
+ }
+ else if (code==44) {
+ item.setBackClippingPlaneOffset(group.getDoubleValue());
+ }
+ else if (code==50) {
+ item.setTwistAngle(group.getFloatValue());
+ }
+ else if (code==71) {
+ item.setViewMode(group.getIntValue());
+ }
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ return super.toString() +
+ DxfGroup.toString(40, viewHeight, 6) +
+ DxfGroup.toString(41, viewWidth, 6) +
+ DxfGroup.toString(10, viewCenterPointX, 6) +
+ DxfGroup.toString(20, viewCenterPointY, 6) +
+ DxfGroup.toString(11, viewDirectionFromTarget[0], 6) +
+ DxfGroup.toString(21, viewDirectionFromTarget[1], 6) +
+ DxfGroup.toString(31, viewDirectionFromTarget[2], 6) +
+ DxfGroup.toString(12, targetPoint[0], 6) +
+ DxfGroup.toString(22, targetPoint[1], 6) +
+ DxfGroup.toString(32, targetPoint[2], 6) +
+ DxfGroup.toString(42, lensLength, 6) +
+ DxfGroup.toString(43, frontClippingPlaneOffset, 6) +
+ DxfGroup.toString(44, backClippingPlaneOffset, 6) +
+ DxfGroup.toString(50, twistAngle, 6) +
+ DxfGroup.toString(71, viewMode);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VPORT_ITEM.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VPORT_ITEM.java
new file mode 100644
index 0000000..722805c
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTABLE_VPORT_ITEM.java
@@ -0,0 +1,395 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * The VPORT item in the TABLES section
+ * There is a static reader to read the item in a DXF file
+ * and a toString method able to write it in a DXF form
+ * @author Michaël Michaud
+ */
+public class DxfTABLE_VPORT_ITEM extends DxfTABLE_ITEM {
+ private double[] lowerLeftCorner; // XY 0.0 to 1.0
+ private double[] upperRightCorner; // XY 0.0 to 1.0
+ private double[] centerPoint; // XY
+ private double[] snapBasePoint; // XY
+ private double[] snapSpacing; // X and Y
+ private double[] gridSpacing; // X and Y
+ private double[] viewDirection; // XYZ
+ private double[] viewTargetPoint; // XYZ
+ private double viewHeight;
+ private float aspectRatio;
+ private float lensLength;
+ private double frontClippingPlaneOffset;
+ private double backClippingPlaneOffset;
+ private float snapRotationAngle;
+ private float twistAngle;
+ private int viewMode;
+ private int circleZoomPercent;
+ private int fastZoomSetting;
+ private int ucsIconSetting;
+ private int snapOnOff;
+ private int gridOnOff;
+ private int snapStyle;
+ private int snapIsoPair;
+
+
+ public DxfTABLE_VPORT_ITEM(String name, int flags) {
+ super(name, flags);
+ this.lowerLeftCorner = new double[2];
+ this.upperRightCorner = new double[2];
+ this.centerPoint = new double[2];
+ this.snapBasePoint = new double[2];
+ this.snapSpacing = new double[2];
+ this.gridSpacing = new double[2];
+ this.viewDirection = new double[3];
+ this.viewTargetPoint = new double[3];
+ this.viewHeight = 0;
+ this.aspectRatio = 0;
+ this.lensLength = 0;
+ this.frontClippingPlaneOffset = 0;
+ this.backClippingPlaneOffset = 0;
+ this.snapRotationAngle = 0;
+ this.twistAngle = 0;
+ this.viewMode = 0;
+ this.circleZoomPercent = 0;
+ this.fastZoomSetting = 0;
+ this.ucsIconSetting = 0;
+ this.snapOnOff = 0;
+ this.gridOnOff = 0;
+ this.snapStyle = 0;
+ this.snapIsoPair = 0;
+ }
+
+ public DxfTABLE_VPORT_ITEM(String name, int flags,
+ double[] lowerLeftCorner,
+ double[] upperRightCorner,
+ double[] centerPoint,
+ double[] snapBasePoint,
+ double[] snapSpacing,
+ double[] gridSpacing,
+ double[] viewDirection,
+ double[] viewTargetPoint,
+ double viewHeight,
+ float aspectRatio,
+ float lensLength,
+ double frontClippingPlaneOffset,
+ double backClippingPlaneOffset,
+ float snapRotationAngle,
+ float twistAngle,
+ int viewMode,
+ int circleZoomPercent,
+ int fastZoomSetting,
+ int ucsIconSetting,
+ int snapOnOff,
+ int gridOnOff,
+ int snapStyle,
+ int snapIsoPair ) {
+ super(name, flags);
+ this.lowerLeftCorner = lowerLeftCorner;
+ this.upperRightCorner = upperRightCorner;
+ this.centerPoint = centerPoint;
+ this.snapBasePoint = snapBasePoint;
+ this.snapSpacing = snapSpacing;
+ this.gridSpacing = gridSpacing;
+ this.viewDirection = viewDirection;
+ this.viewTargetPoint = viewTargetPoint;
+ this.viewHeight = viewHeight;
+ this.aspectRatio = aspectRatio;
+ this.lensLength = lensLength;
+ this.frontClippingPlaneOffset = frontClippingPlaneOffset;
+ this.backClippingPlaneOffset = backClippingPlaneOffset;
+ this.snapRotationAngle = snapRotationAngle;
+ this.twistAngle = twistAngle;
+ this.viewMode = viewMode;
+ this.circleZoomPercent = circleZoomPercent;
+ this.fastZoomSetting = fastZoomSetting;
+ this.ucsIconSetting = ucsIconSetting;
+ this.snapOnOff = snapOnOff;
+ this.gridOnOff = gridOnOff;
+ this.snapStyle = snapStyle;
+ this.snapIsoPair = snapIsoPair;
+ }
+
+ public double[] getLowerLeftCorner() {return lowerLeftCorner;}
+ public double[] getUpperRightCorner() {return upperRightCorner;}
+ public double[] getCenterPoint() {return centerPoint;}
+ public double[] getSnapBasePoint() {return snapBasePoint;}
+ public double[] getSnapSpacing() {return snapSpacing;}
+ public double[] getGridSpacing() {return gridSpacing;}
+ public double[] getViewDirection() {return viewDirection;}
+ public double[] getViewTargetPoint() {return viewTargetPoint;}
+ public double getViewHeight() {return viewHeight;}
+ public float getAspectRatio() {return aspectRatio;}
+ public float getLensLength() {return lensLength;}
+ public double getFrontClippingPlaneOffset() {return frontClippingPlaneOffset;}
+ public double getBackClippingPlaneOffset() {return backClippingPlaneOffset;}
+ public float getSnapRotationAngle() {return snapRotationAngle;}
+ public float getTwistAngle() {return twistAngle;}
+ public int getViewMode() {return viewMode;}
+ public int getCircleZoomPercent() {return circleZoomPercent;}
+ public int getFastZoomSetting() {return fastZoomSetting;}
+ public int getUcsIconSetting() {return ucsIconSetting;}
+ public int getSnapOnOff() {return snapOnOff;}
+ public int getGridOnOff() {return gridOnOff;}
+ public int getSnapStyle() {return snapStyle;}
+ public int getSnapIsoPair() {return snapIsoPair;}
+
+ public void setLowerLeftCorner(double[] lowerLeftCorner) {
+ this.lowerLeftCorner = lowerLeftCorner;
+ }
+ public void setUpperRightCorner(double[] upperRightCorner) {
+ this.upperRightCorner = upperRightCorner;
+ }
+ public void setCenterPoint(double[] centerPoint) {
+ this.centerPoint = centerPoint;
+ }
+ public void setSnapBasePoint(double[] snapBasePoint) {
+ this.snapBasePoint = snapBasePoint;
+ }
+ public void setSnapSpacing(double[] snapSpacing) {
+ this.snapSpacing = snapSpacing;
+ }
+ public void setGridSpacing(double[] gridSpacing) {
+ this.gridSpacing = gridSpacing;
+ }
+ public void setViewDirection(double[] viewDirection) {
+ this.viewDirection = viewDirection;
+ }
+ public void setViewTargetPoint(double[] viewTargetPoint) {
+ this.viewTargetPoint = viewTargetPoint;
+ }
+ public void setViewHeight(double viewHeight) {
+ this.viewHeight = viewHeight;
+ }
+ public void setAspectRatio(float aspectRatio) {
+ this.aspectRatio = aspectRatio;
+ }
+ public void setLensLength(float lensLength) {
+ this.lensLength = lensLength;
+ }
+ public void setFrontClippingPlaneOffset(double frontClippingPlaneOffset) {
+ this.frontClippingPlaneOffset = frontClippingPlaneOffset;
+ }
+ public void setBackClippingPlaneOffset(double backClippingPlaneOffset) {
+ this.backClippingPlaneOffset = backClippingPlaneOffset;
+ }
+ public void setSnapRotationAngle(float snapRotationAngle) {
+ this.snapRotationAngle = snapRotationAngle;
+ }
+ public void setTwistAngle(float twistAngle) {
+ this.twistAngle = twistAngle;
+ }
+ public void setViewMode(int viewMode) {
+ this.viewMode = viewMode;
+ }
+ public void setCircleZoomPercent(int circleZoomPercent) {
+ this.circleZoomPercent = circleZoomPercent;
+ }
+ public void setFastZoomSetting(int fastZoomSetting) {
+ this.fastZoomSetting = fastZoomSetting;
+ }
+ public void setUcsIconSetting(int ucsIconSetting) {
+ this.ucsIconSetting = ucsIconSetting;
+ }
+ public void setSnapOnOff(int snapOnOff) {
+ this.snapOnOff = snapOnOff;
+ }
+ public void setGridOnOff(int gridOnOff) {
+ this.gridOnOff = gridOnOff;
+ }
+ public void setSnapStyle(int snapStyle) {
+ this.snapStyle = snapStyle;
+ }
+ public void setSnapIsoPair(int snapIsoPair) {
+ this.snapIsoPair = snapIsoPair;
+ }
+
+ public static Map readTable(RandomAccessFile raf) throws IOException {
+ DxfTABLE_VPORT_ITEM item = new DxfTABLE_VPORT_ITEM("DEFAULT", 0);
+ Map table = new LinkedHashMap<>();
+ DxfGroup group;
+ while (null != (group = DxfGroup.readGroup(raf)) && !group.equals(ENDTAB)) {
+ //group = DxfGroup.readGroup(raf);
+ if (DxfFile.DEBUG) group.print(8);
+ if (group.equals(VPORT)) {
+ item = new DxfTABLE_VPORT_ITEM("DEFAULT", 0);
+ }
+ else if (group.getCode()==2) {
+ item.setName(group.getValue());
+ table.put(item.getName(), item);
+ }
+ //else if (group.getCode()==5) {} // tag appeared in version 13 of DXF
+ //else if (group.getCode()==100) {} // tag appeared in version 13 of DXF
+ else if (group.getCode()==70) {
+ item.setFlags(group.getIntValue());
+ }
+ else if (group.getCode()==10) {
+ item.getLowerLeftCorner()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==20) {
+ item.getLowerLeftCorner()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==11) {
+ item.getUpperRightCorner()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==21) {
+ item.getUpperRightCorner()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==12) {
+ item.getCenterPoint()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==22) {
+ item.getCenterPoint()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==13) {
+ item.getSnapBasePoint()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==23) {
+ item.getSnapBasePoint()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==14) {
+ item.getSnapSpacing()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==24) {
+ item.getSnapSpacing()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==15) {
+ item.getGridSpacing()[0] = group.getDoubleValue();
+ }
+ else if (group.getCode()==25) {
+ item.getGridSpacing()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==16) {
+ item.getViewDirection()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==26) {
+ item.getViewDirection()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==36) {
+ item.getViewDirection()[2] = group.getDoubleValue();
+ }
+ else if (group.getCode()==17) {
+ item.getViewTargetPoint()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==27) {
+ item.getViewTargetPoint()[1] = group.getDoubleValue();
+ }
+ else if (group.getCode()==37) {
+ item.getViewTargetPoint()[2] = group.getDoubleValue();
+ }
+ else if (group.getCode()==40) {
+ item.setViewHeight(group.getDoubleValue());
+ }
+ else if (group.getCode()==41) {
+ item.setAspectRatio(group.getFloatValue());
+ }
+ else if (group.getCode()==42) {
+ item.setLensLength(group.getFloatValue());
+ }
+ else if (group.getCode()==43) {
+ item.setFrontClippingPlaneOffset(group.getDoubleValue());
+ }
+ else if (group.getCode()==44) {
+ item.setBackClippingPlaneOffset(group.getDoubleValue());
+ }
+ else if (group.getCode()==50) {
+ item.setSnapRotationAngle(group.getFloatValue());
+ }
+ else if (group.getCode()==51) {
+ item.setTwistAngle(group.getFloatValue());
+ }
+ else if (group.getCode()==71) {
+ item.setViewMode(group.getIntValue());
+ }
+ else if (group.getCode()==72) {
+ item.setCircleZoomPercent(group.getIntValue());
+ }
+ else if (group.getCode()==73) {
+ item.setFastZoomSetting(group.getIntValue());
+ }
+ else if (group.getCode()==74) {
+ item.setUcsIconSetting(group.getIntValue());
+ }
+ else if (group.getCode()==75) {
+ item.setSnapOnOff(group.getIntValue());
+ }
+ else if (group.getCode()==76) {
+ item.setGridOnOff(group.getIntValue());
+ }
+ else if (group.getCode()==77) {
+ item.setSnapStyle(group.getIntValue());
+ }
+ else if (group.getCode()==78) {
+ item.setSnapIsoPair(group.getIntValue());
+ }
+ //else {}
+ }
+ return table;
+ }
+
+ public String toString() {
+ return super.toString() +
+ DxfGroup.toString(10, lowerLeftCorner[0], 6) +
+ DxfGroup.toString(20, lowerLeftCorner[1], 6) +
+ DxfGroup.toString(11, upperRightCorner[0], 6) +
+ DxfGroup.toString(21, upperRightCorner[1], 6) +
+ DxfGroup.toString(12, centerPoint[0], 6) +
+ DxfGroup.toString(22, centerPoint[1], 6) +
+ DxfGroup.toString(13, snapBasePoint[0], 6) +
+ DxfGroup.toString(23, snapBasePoint[1], 6) +
+ DxfGroup.toString(14, snapSpacing[0], 6) +
+ DxfGroup.toString(24, snapSpacing[1], 6) +
+ DxfGroup.toString(15, gridSpacing[0], 6) +
+ DxfGroup.toString(25, gridSpacing[1], 6) +
+ DxfGroup.toString(16, viewDirection[0], 6) +
+ DxfGroup.toString(26, viewDirection[1], 6) +
+ DxfGroup.toString(36, viewDirection[2], 6) +
+ DxfGroup.toString(17, viewTargetPoint[0], 6) +
+ DxfGroup.toString(27, viewTargetPoint[1], 6) +
+ DxfGroup.toString(37, viewTargetPoint[2], 6) +
+ DxfGroup.toString(40, viewHeight, 6) +
+ DxfGroup.toString(41, aspectRatio, 6) +
+ DxfGroup.toString(42, lensLength, 6) +
+ DxfGroup.toString(43, frontClippingPlaneOffset, 6) +
+ DxfGroup.toString(44, backClippingPlaneOffset, 6) +
+ DxfGroup.toString(50, snapRotationAngle, 6) +
+ DxfGroup.toString(51, twistAngle, 6) +
+ DxfGroup.toString(71, viewMode) +
+ DxfGroup.toString(72, circleZoomPercent) +
+ DxfGroup.toString(73, fastZoomSetting) +
+ DxfGroup.toString(74, ucsIconSetting) +
+ DxfGroup.toString(75, snapOnOff) +
+ DxfGroup.toString(76, gridOnOff) +
+ DxfGroup.toString(77, snapStyle) +
+ DxfGroup.toString(78, snapIsoPair);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTEXT.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTEXT.java
new file mode 100644
index 0000000..bac7921
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfTEXT.java
@@ -0,0 +1,88 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.BasicFeature;
+import com.vividsolutions.jump.feature.FeatureCollection;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.GeometryFactory;
+
+
+/**
+ * A TEXT and its static readEntity method to read a TEXT in a DXF file.
+ * @author Michaël Michaud
+ */
+// History
+// 2012-09-22 : Fix a bug preventing TEXT entities to be read
+// 2011-04-10 : Add TEXT_ROTATION
+// 2006-11-12 : Bug fixed x==Double.NaN --> Double.isNaN(x)
+public class DxfTEXT extends DxfENTITY {
+
+ public DxfTEXT() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf,
+ FeatureCollection entities)
+ throws IOException {
+ Feature feature = new BasicFeature(DxfFile.DXF_SCHEMA);
+ feature.setAttribute("LTYPE", "BYLAYER");
+ feature.setAttribute("THICKNESS", 0.0);
+ feature.setAttribute("COLOR", 256); // equivalent to BYLAYER
+ feature.setAttribute("TEXT", "");
+ feature.setAttribute("TEXT_HEIGHT", 0.0);
+ feature.setAttribute("TEXT_ROTATION", 0.0);
+ feature.setAttribute("TEXT_STYLE", "STANDARD");
+ double x=Double.NaN, y=Double.NaN, z=Double.NaN;
+ DxfGroup group;
+ GeometryFactory gf = new GeometryFactory(DPM,0);
+ while (null != (group = DxfGroup.readGroup(raf))) {
+ int code = group.getCode();
+ if (code == 0) break;
+ if (DxfFile.DEBUG) group.print(12);
+ if (code==8) feature.setAttribute("LAYER", group.getValue());
+ else if (code==6) feature.setAttribute("LTYPE", group.getValue());
+ else if (code==39) feature.setAttribute("THICKNESS", group.getDoubleValue());
+ else if (code==62) feature.setAttribute("COLOR", group.getIntValue());
+ else if (code==10) x = group.getDoubleValue();
+ else if (code==20) y = group.getDoubleValue();
+ else if (code==30) z = group.getDoubleValue();
+ else if (code==1) feature.setAttribute("TEXT", group.getValue());
+ else if (code==40) feature.setAttribute("TEXT_HEIGHT", group.getDoubleValue());
+ else if (code==50) feature.setAttribute("TEXT_ROTATION", group.getDoubleValue());
+ else if (code==7) feature.setAttribute("TEXT_STYLE", group.getValue());
+ //else {}
+ }
+ if (!Double.isNaN(x) && !Double.isNaN(y)) {
+ feature.setGeometry(gf.createPoint(new Coordinate(x,y,z)));
+ if (DxfFile.DEBUG) System.out.println(" " + feature.getString("LAYER") + " : " + feature.getGeometry());
+ entities.add(feature);
+ }
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfVERTEX.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfVERTEX.java
new file mode 100644
index 0000000..83b9208
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfVERTEX.java
@@ -0,0 +1,64 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.CoordinateList;
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+
+/**
+ * A VERTEX and a static readEntity method to read a VERTEX in a DXF file.
+ * @author Michaël Michaud
+ */
+// History
+// 2006-11-12 : Bug fixed x==Double.NaN --> Double.isNaN(x)
+public class DxfVERTEX extends DxfENTITY {
+
+ public DxfVERTEX() {super("DEFAULT");}
+
+ public static DxfGroup readEntity(RandomAccessFile raf,
+ CoordinateList coordList)
+ throws NumberFormatException, IOException {
+ //Coordinate coord;
+ double x=Double.NaN, y=Double.NaN, z=Double.NaN;
+ DxfGroup group;
+ int code;
+ while (null != (group = DxfGroup.readGroup(raf)) &&
+ 0 != (code = group.getCode())) {
+ if (code==10) x = group.getDoubleValue();
+ else if (code==20) y = group.getDoubleValue();
+ else if (code==30) z = group.getDoubleValue();
+ //else {}
+ }
+ if (!Double.isNaN(x) && !Double.isNaN(y)) {
+ if (DxfFile.DEBUG) System.out.println(" " + new Coordinate(x,y,z));
+ coordList.add(new Coordinate(x,y,z));
+ }
+ return group;
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/DxfWriter.java b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfWriter.java
new file mode 100644
index 0000000..329e3df
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/DxfWriter.java
@@ -0,0 +1,98 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import com.vividsolutions.jump.feature.*;
+import com.vividsolutions.jump.io.JUMPWriter;
+import com.vividsolutions.jump.io.DriverProperties;
+import com.vividsolutions.jump.io.IllegalParametersException;
+
+import java.io.*;
+
+
+/**
+ * DXF writer
+ * @author Michaël Michaud
+ */
+// History
+// 2006-11-12 : Much clean-up made on 2006-11-12 for version 0.5
+public class DxfWriter implements JUMPWriter {
+
+ //DxfFile dxfFile = null;
+
+ /** Creates new DxfWriter */
+ public DxfWriter() {}
+
+ /**
+ * Main method - write the featurecollection to a DXF file.
+ *
+ * @param featureCollection collection to write
+ * @param dp 'OutputFile' or 'DefaultValue' to specify where to write.
+ */
+ public void write(FeatureCollection featureCollection, DriverProperties dp)
+ throws Exception {
+ String dxfFileName;
+ String fname;
+ int loc;
+ dxfFileName = dp.getProperty("File");
+
+ if (dxfFileName == null) {
+ dxfFileName = dp.getProperty("DefaultValue");
+ }
+ if (dxfFileName == null) {
+ throw new IllegalParametersException("no File property specified");
+ }
+
+ // Fix on 2016-09-29 to make it compatible with OpenJUMP 1.9.1
+ //String[] layerNameProp = (String[])dp.get("LAYER_NAME");
+ //String[] layerNames = layerNameProp == null ? new String[]{}:layerNameProp;
+ String layerNameProperty = dp.getProperty("LAYER_NAME");
+ String[] layerNames;
+ if (layerNameProperty == null) layerNames = new String[]{""};
+ else layerNames = layerNameProperty.split("\n");
+
+ // Check if the writer has to create layers with "_" suffix for layers with holes
+ // Warning : using getProperty instead of get return null
+ // because SUFFIX is not a String
+ boolean suffix = true;
+ Object suffixObject = dp.get("SUFFIX");
+ if (suffixObject != null) {
+ if (suffixObject instanceof Boolean) suffix = (Boolean)suffixObject;
+ else if (suffixObject instanceof String) suffix = Boolean.parseBoolean(suffixObject.toString());
+ }
+
+ loc = dxfFileName.lastIndexOf(File.separatorChar);
+ fname = dxfFileName.substring(loc + 1); // ie. "/data1/hills.dxf" -> "hills.dxf"
+ loc = fname.lastIndexOf(".");
+ if (loc == -1) {
+ throw new IllegalParametersException("Filename must end in '.dxf'");
+ }
+
+ FileWriter fw = new FileWriter(dxfFileName);
+ DxfFile.write(featureCollection, layerNames, fw, 2, suffix);
+ fw.close();
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/InstallDXFDataSourceQueryChooserPlugIn.java b/src/main/java/fr/michaelm/jump/drivers/dxf/InstallDXFDataSourceQueryChooserPlugIn.java
new file mode 100644
index 0000000..50359ef
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/InstallDXFDataSourceQueryChooserPlugIn.java
@@ -0,0 +1,87 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import javax.swing.JFileChooser;
+
+import com.vividsolutions.jump.workbench.datasource.InstallStandardDataSourceQueryChoosersPlugIn;
+import com.vividsolutions.jump.workbench.plugin.PlugInContext;
+import com.vividsolutions.jump.io.JUMPWriter;
+import com.vividsolutions.jump.io.JUMPReader;
+import com.vividsolutions.jump.workbench.datasource.LoadFileDataSourceQueryChooser;
+import com.vividsolutions.jump.workbench.datasource.DataSourceQueryChooserManager;
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+
+
+/**
+ * Install the DXF driver.
+ * Extends the InstallStandardDataSourceQueryChoosersPlugIn class, overloading
+ * initialize() to initialize DxfReader, DxfWriter.
+ * @author Michaël Michaud
+ */
+// History
+// 2006-10-18 : replace standard SaveFileDataSourceQueryChooser by a
+// SaveDxfFileDataSourceQueryChooser with options for header for entity
+// handles and for layer name.
+public class InstallDXFDataSourceQueryChooserPlugIn extends InstallStandardDataSourceQueryChoosersPlugIn {
+
+ private void addFileDataSourceQueryChoosers(
+ JUMPReader reader,
+ JUMPWriter writer,
+ final String description,
+ WorkbenchContext workbenchContext,
+ Class> readerWriterDataSourceClass
+ ) {
+ DataSourceQueryChooserManager.get(
+ workbenchContext.getBlackboard())
+ .addLoadDataSourceQueryChooser(new LoadFileDataSourceQueryChooser(
+ readerWriterDataSourceClass,
+ description,
+ extensions(readerWriterDataSourceClass),
+ workbenchContext) {
+ protected void addFileFilters(JFileChooser chooser) {
+ super.addFileFilters(chooser);
+ InstallStandardDataSourceQueryChoosersPlugIn.addCompressedFileFilter(
+ description,
+ chooser);
+ }
+ }).addSaveDataSourceQueryChooser(
+ new SaveDxfFileDataSourceQueryChooser(
+ readerWriterDataSourceClass,
+ description,
+ extensions(readerWriterDataSourceClass),
+ workbenchContext));
+ }
+
+ public void initialize(final PlugInContext context) {
+ addFileDataSourceQueryChoosers(
+ new DxfReader(),
+ new DxfWriter(),
+ "dxf",
+ context.getWorkbenchContext(),
+ DXFFileReaderWriter.class);
+ }
+
+}
diff --git a/src/main/java/fr/michaelm/jump/drivers/dxf/SaveDxfFileDataSourceQueryChooser.java b/src/main/java/fr/michaelm/jump/drivers/dxf/SaveDxfFileDataSourceQueryChooser.java
new file mode 100644
index 0000000..2cf1a78
--- /dev/null
+++ b/src/main/java/fr/michaelm/jump/drivers/dxf/SaveDxfFileDataSourceQueryChooser.java
@@ -0,0 +1,154 @@
+/*
+ * Library name : dxf
+ * (C) 2021 Michaël Michaud
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * For more information, contact:
+ *
+ * m.michael.michaud@orange.fr
+ *
+ */
+
+package fr.michaelm.jump.drivers.dxf;
+
+import java.awt.Component;
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+
+import com.vividsolutions.jump.feature.Feature;
+import com.vividsolutions.jump.feature.FeatureSchema;
+import com.vividsolutions.jump.workbench.datasource.SaveFileDataSourceQueryChooser;
+import com.vividsolutions.jump.workbench.model.*;
+import com.vividsolutions.jump.workbench.WorkbenchContext;
+
+
+/**
+ * User interface to save a JUMP layer into a DXF file
+ * Add an option to the standard panel
+ * - option to create "_" suffixed layers for holes in polygon
+ * @author Michaël Michaud
+ */
+// History
+// 2006-11-12 : remove the header option after L. Becker and R. Littlefield
+// have fix the bug in the header writing
+// 2006-10-18 : add two options (one for header writing and the other to suffix
+// layers containing holes) and a function to create valid DXF
+// layer names from JUMP layer names
+public class SaveDxfFileDataSourceQueryChooser extends SaveFileDataSourceQueryChooser {
+
+ // Array making it possible to replace any of the 383 first unicode
+ // characters by a valid character for DXF layer name or file name
+ // (removes accents, escape characters and most of special symbols)
+ private static final String[] asciiChar = new String[] {
+ "","","","","","","","","","","","","","","","", //00-0F
+ "","","","","","","","","","","","","","","","", //10-1F
+ "_","_","_","_","_","_","_","_","_","_","_","_","_","-",".","_", //20-2F
+ "0","1","2","3","4","5","6","7","8","9","_","_","_","_","_","_", //30-3F
+ "_","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", //40-4F
+ "P","Q","R","S","T","U","V","W","X","Y","Z","_","_","_","_","_", //50-5F
+ "_","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o", //60-6F
+ "p","q","r","s","t","u","v","w","x","y","z","_","_","_","_","", //70-7F
+ "","","","","","","","","","","","","","","","", //80-8F
+ "","","","","","","","","","","","","","","","", //90-9F
+ "_","_","c","L","_","Y","_","_","","c","a","","_","-","r","", //A0-AF
+ "o","_","2","3","","u","_",".","","1","o","","_","_","_","_", //B0-BF
+ "A","A","A","A","A","A","AE","C","E","E","E","E","I","I","I","I",//C0-CF
+ "E","N","O","O","O","O","O","x","O","U","U","U","U","Y","T","SS",//D0-DF
+ "a","a","a","a","a","a","ae","c","e","e","e","e","i","i","i","i",//E0-EF
+ "e","n","o","o","o","o","o","_","0","u","u","u","u","y","t","y", //F0-FF
+ "A","a","A","a","A","a","C","c","C","c","C","c","C","c","D","d", //100-10F
+ "D","d","E","e","E","e","E","e","E","e","E","e","G","g","G","g", //110-11F
+ "G","g","G","g","H","h","H","h","I","i","I","i","I","i","I","i", //120-12F
+ "I","i","IJ","ij","J","j","K","k","k","L","l","L","l","L","l","L", //130-13F
+ "l","L","l","N","n","N","n","N","n","n","N","n","O","o","O","o", //140-14F
+ "O","o","OE","oe","R","r","R","r","R","r","S","s","S","s","S","s", //150-15F
+ "S","s","T","t","T","t","T","t","U","u","U","u","U","u","U","u", //160-16F
+ "U","u","U","u","W","w","Y","y","Y","Z","z","Z","z","Z","z","_" //170-17F
+ };
+
+ WorkbenchContext context;
+ JPanel optionPanel = new JPanel();
+ JCheckBox suffixCB = new JCheckBox("Put polygon holes in layers with a '_' suffix", true);
+
+ SaveDxfFileDataSourceQueryChooser(Class readerWriterDataSourceClass, String description,
+ String[] extensions, WorkbenchContext workbenchContext) {
+ super(readerWriterDataSourceClass, description, extensions, workbenchContext);
+ this.context = workbenchContext;
+ Box box = new Box(BoxLayout.Y_AXIS);
+ optionPanel.add(box);
+ //box.add(headerCB);
+ box.add(suffixCB);
+ }
+
+ protected Map toProperties(File file) {
+ Map properties = new HashMap<>(super.toProperties(file));
+ Layer selectedLayer = context.getLayerableNamePanel().getSelectedLayers()[0];
+ String layerName = toAscii(selectedLayer.getName()).substring(0, Math.min(selectedLayer.getName().length(), 31));
+ properties.put("LAYER_NAME", layerName);
+ // If the layer schema has an attribute "LAYER" the value of this
+ // attribute is used for the DXF layer name
+ if (selectedLayer instanceof Layer) {
+ FeatureSchema fs = selectedLayer.getFeatureCollectionWrapper().getFeatureSchema();
+ if (fs.hasAttribute("LAYER")) {
+ Set layerSet = new HashSet<>();
+ List features = selectedLayer.getFeatureCollectionWrapper().getFeatures();
+ for (Feature feature : features) {
+ if (feature.getString("LAYER") != null &&
+ feature.getString("LAYER").trim().length()>0 &&
+ !feature.getString("LAYER").endsWith("_")) {
+ layerSet.add(feature.getString("LAYER"));
+ }
+ }
+ String[] set = layerSet.toArray(new String[0]);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0 ; i < set.length ; i++) {
+ if (i > 0) sb.append("\n");
+ sb.append(set[i]);
+ }
+ properties.put("LAYER_NAME", sb.toString());
+ }
+ }
+ properties.put("SUFFIX", suffixCB.isSelected());
+ return properties;
+ }
+
+ protected Component getSouthComponent1() {
+ return optionPanel;
+ }
+
+ /**
+ * Remove accents using the asciiChar array.
+ */
+ public static String toAscii(String in) {
+ String input = in.trim();
+ StringBuilder output = new StringBuilder();
+ for(int i = 0 ; i < input.length() ; i++) {
+ int carVal = input.charAt(i);
+ if (carVal < 384) {output.append(asciiChar[carVal]);}
+ else {output.append("_");}
+ }
+ return output.toString();
+ }
+
+}