From 6523c1f6534042d89ff8a07d4e7c06050276521e Mon Sep 17 00:00:00 2001
From: ?? ? <ulysseskao@ximple.com.tw>
Date: Thu, 22 Apr 2010 16:31:12 +0800
Subject: [PATCH] dgn7 write function for complex chain

---
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java |    1 
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileWriter.java            |   15 ++
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java      |    1 
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java        |   47 ++-----
 .gitattributes                                                                        |    1 
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java       |   25 ++++
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java                   |   23 +++
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/ElementFactoryTest.java        |  177 +++++++++++++++++++++++++++++
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementFactory.java            |   23 +++
 9 files changed, 272 insertions(+), 41 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index 975754f..ad1b2e2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -39,6 +39,7 @@
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileReaderTest.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java -text svneol=unset#text/plain
+xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/ElementFactoryTest.java -text svneol=unset#text/plain
 xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/OracleTarget.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/Demo.dgn -text
 xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491-1.dgn -text
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
index a5d7980..ef07d30 100644
--- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
@@ -1,6 +1,7 @@
 package com.ximple.io.dgn7;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -155,10 +156,32 @@
         return factory.createMultiLineString(lines);
     }
 
-    public double getElementSize() {
+    public short getTotalLength() {
         return raw[18];
     }
 
+    protected void setTotalLength(short value) {
+        raw[18] = value;
+    }
+
+    public short getNumOfElement() {
+        return raw[19];
+    }
+
+    protected void setNumOfElement(short value) {
+        raw[19] = value;
+    }
+
+
+    public short[] getAttributes() {
+        return Arrays.copyOfRange(raw, 20, 23);
+    }
+
+    protected void setAttributes(short[] values) {
+        if (values.length < 4) return;
+        System.arraycopy(values, 0, raw, 20, 24 - 20);
+    }
+
     public boolean isClosed() {
         if (isEmpty()) {
             return false;
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileWriter.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileWriter.java
index fded903..6e475cd 100644
--- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileWriter.java
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileWriter.java
@@ -304,8 +304,19 @@
     }
 
     public void writeElement(Element element) throws IOException {
-        // element.raw
         if (element == null) return;
+        if (element.getElementType().isComplexElement()) {
+            writeTo(element);
+            ComplexElement complexElement = (ComplexElement) element;
+            for (Element component : complexElement) {
+                writeTo(component);
+            }
+        } else {
+            writeTo(element);
+        }
+    }
+
+    private void writeTo(Element element) throws IOException {
         ByteBuffer writeBuffer = ByteBuffer.allocateDirect(element.raw.length * 2);
         writeBuffer.order(ByteOrder.LITTLE_ENDIAN);
         for (short word : element.raw) {
@@ -316,6 +327,8 @@
         channel.write(writeBuffer);
     }
 
+
+
     public void toEnd() throws IOException, Dgn7fileException {
         while (hasNext()) {
             nextElement();
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
index 91f0198..5c44664 100644
--- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
@@ -17,7 +17,6 @@
  *
  * @author Ulysses
  * @version 0.1
- * @since 2006/5/18 �W�� 11:14:50
  */
 public class Element {
     public static final int CONSTRUCTION_CLASS = 0;
@@ -85,6 +84,10 @@
         raw[5] = (short) (temp >> 16 & 0x0000ffff);
         raw[4] = (short) (temp & 0x0000ffff);
 
+        // lowZ
+        raw[7] = 0;
+        raw[8] = 0;
+
         int highCoorX = DgnUtility.converCoordToUnit(bbox.getMaxX());
         temp = DgnUtility.converToDGN(highCoorX);
         raw[9] = (short) (temp >> 16 & 0x0000ffff);
@@ -94,6 +97,11 @@
         temp = DgnUtility.converToDGN(highCoorY);
         raw[11] = (short) (temp >> 16 & 0x0000ffff);
         raw[10] = (short) (temp & 0x0000ffff);
+
+        // highZ
+        raw[13] = (short) 0xffff;
+        raw[12] = (short) 0xffff;
+
     }
 
     public boolean isComponentElement() {
@@ -163,6 +171,15 @@
         }
     }
 
+    public short getFollowLength() {
+        return raw[1];
+    }
+
+    protected void setFollowLength(short value) {
+        assert (raw.length >= value + 2);
+        raw[1] = value;
+    }
+
     public void addUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId) throws Element.Exception {
     }
 
@@ -183,6 +200,10 @@
         return true;
     }
 
+    public int getUserAttributeDataOffset() {
+        return (raw[15] + 16);
+    }
+
     public List<UserAttributeData> getUserAttributeData() {
         short[] data;
         short length, nextAttribute;
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementFactory.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementFactory.java
index dc52e46..34dda57 100644
--- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementFactory.java
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementFactory.java
@@ -9,11 +9,11 @@
 import java.util.LinkedList;
 
 public class ElementFactory {
-    private static final int DEFAULT_ELMHEAD_LENGTH = 28;
-    private static final int DEFAULT_DISPHEAD_LENGTH = 8;
-    private static final int MINIMAL_ELEMLENGTH = 18 * 2;
+    static final int DEFAULT_ELMHEAD_LENGTH = 28;
+    static final int DEFAULT_DISPHEAD_LENGTH = 8;
+    static final int MINIMAL_ELEMLENGTH = 18 * 2;
 
-    private static final int MAXINUM_LINESTRING_PTLEN = 100;
+    static final int MAXINUM_LINESTRING_PTLEN = 100;
 
     private static ElementFactory elementFactory = new ElementFactory();
     private static GeometryFactory factory = new GeometryFactory();
@@ -35,6 +35,7 @@
         }
         element.setVerticeSize(pts.length);
         element.setType(ElementType.SHAPE.id);
+        element.setFollowLength((short) ((elmsize / 2) - 2));
         element.setRange(ring.getEnvelopeInternal());
         element.setLevelIndex(0);
         element.setColorIndex(0);
@@ -52,6 +53,7 @@
         }
         element.setVerticeSize(pts.length);
         element.setType(ElementType.LINESTRING.id);
+        element.setFollowLength((short) ((elmsize / 2) - 2));
         element.setLevelIndex(0);
         element.setColorIndex(0);
         element.setWeight(0);
@@ -68,6 +70,7 @@
         }
         element.setVerticeSize(pts.length);
         element.setType(ElementType.SHAPE.id);
+        element.setFollowLength((short) ((elmsize / 2) - 2));
         element.setLevelIndex(0);
         element.setColorIndex(0);
         element.setWeight(0);
@@ -80,13 +83,16 @@
         Coordinate[] allpts = linestring.getCoordinates();
         int segsize = allpts.length / MAXINUM_LINESTRING_PTLEN;
         int currentpos = 0;
+        int totalLength = 0;
         for (int seg = 0; seg < segsize; seg++) {
             Coordinate[] pts = Arrays.copyOfRange(allpts,
-                    currentpos, currentpos + MAXINUM_LINESTRING_PTLEN, Coordinate[].class);
+                    currentpos, currentpos + MAXINUM_LINESTRING_PTLEN + 1, Coordinate[].class);
             LineStringElement element = elementFactory.createLineStringElement(pts);
             currentpos += MAXINUM_LINESTRING_PTLEN;
             element.setRange(element.toGeometry(factory).getEnvelopeInternal());
             element.setComponentElement(true);
+            element.setLevelIndex(0);
+            totalLength += element.raw.length;
             elms.add(element);
         }
         int remain = allpts.length % MAXINUM_LINESTRING_PTLEN;
@@ -95,12 +101,19 @@
         LineStringElement element = elementFactory.createLineStringElement(pts);
         element.setRange(element.toGeometry(factory).getEnvelopeInternal());
         element.setComponentElement(true);
+        element.setLevelIndex(0);
         elms.add(element);
+        totalLength += element.raw.length;
 
         ComplexChainElement result = new ComplexChainElement(new byte[MINIMAL_ELEMLENGTH + 12]);
         result.addAll(elms);
         result.setRange(linestring.getEnvelopeInternal());
         result.setType(ElementType.COMPLEXCHAIN.id);
+        result.setFollowLength((short) (((MINIMAL_ELEMLENGTH + 12) / 2) - 2));
+        result.setNumOfElement((short) elms.size());
+        totalLength += result.raw.length;
+        totalLength -= 19;
+        result.setTotalLength((short) totalLength);
         result.setLevelIndex(0);
         result.setColorIndex(0);
         result.setWeight(0);
diff --git a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java
index 18992ac..0996150 100644
--- a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java
+++ b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java
@@ -17,7 +17,6 @@
  * Dgn7OracleReaderTest
  * User: Ulysses
  * Date: 2007/10/24
- * Time: �W�� 10:49:54
  */
 public class Dgn7OracleReaderTest {
     @BeforeTest
diff --git a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java
index 92a3c0b..54d8808 100644
--- a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java
+++ b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java
@@ -17,7 +17,6 @@
  * Dgn7TextElementReaderTest
  * User: Ulysses
  * Date: 2008/1/10
- * Time: �W�� 12:19:14
  */
 public class Dgn7TextElementReaderTest {
     private final static Logger logger = Logger.getLogger(Dgn7fileReaderTest.class);
diff --git a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java
index 0e8c65d..2d87990 100644
--- a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java
+++ b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileWriterTest.java
@@ -3,6 +3,7 @@
 import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 import org.geotools.TestData;
+import org.testng.Assert;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
@@ -58,52 +59,31 @@
             if (record.element() != null) {
                 Element element = (Element) record.element();
                 ElementType type = element.getElementType();
-
+                boolean completed = false;
                 if ((!type.isComplexElement()) && (!element.isComponentElement())) {
                     if (lastComplex != null) {
                         // @todo add process in here
+                        processCompleteElement(lastComplex, writer);
                         lastComplex = null;
                     }
 
                     // @todo add process in here
+                    processCompleteElement(element, writer);
                 } else if (element.isComponentElement()) {
                     if (lastComplex != null) {
                         ((ComplexElement) lastComplex).add(element);
+                    } else {
+                        logger.warn("wong." + element.toString());
+                        Assert.fail("Component Element cannot found parent.");
                     }
                 } else if (type.isComplexElement()) {
-                    if (lastComplex == null) {
-                        lastComplex = element;
-                    } else {
+                    if (lastComplex != null) {
                         // @todo add process in here
-                        lastComplex = element;
+                        processCompleteElement(lastComplex, writer);
                     }
+                    lastComplex = element;
                 }
-
-                if (element.getElementType().isComplexElement()) {
-                    if (element instanceof ComplexChainElement) {
-                        ComplexChainElement complexChain = (ComplexChainElement) element;
-                        int size = complexChain.size();
-                        for (Object aComplexChain : complexChain) {
-                            Element subElement = (Element) aComplexChain;
-                            subElement.getType();
-                        }
-                    }
-
-                    if (element instanceof ComplexShapeElement) {
-                        ComplexShapeElement complexShape = (ComplexShapeElement) element;
-                    }
-
-                    if (element instanceof TextNodeElement) {
-                        TextNodeElement textNode = (TextNodeElement) element;
-                        int size = textNode.size();
-                        for (int i = 0; i < size; i++) {
-                            Element subElement = textNode.get(i);
-                            subElement.getElementType();
-                        }
-                    }
-                }
-
-                writer.writeElement(element);
+                // writer.writeElement(element);
             }
             count++;
         }
@@ -112,4 +92,9 @@
 
         // FileUtils.copyFile(target, new File("G://target.dgn"));
     }
+
+    private boolean processCompleteElement(Element element, Dgn7fileWriter writer) throws IOException {
+        writer.writeElement(element);
+        return true;
+    }
 }
diff --git a/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/ElementFactoryTest.java b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/ElementFactoryTest.java
new file mode 100644
index 0000000..eaa5d73
--- /dev/null
+++ b/xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/ElementFactoryTest.java
@@ -0,0 +1,177 @@
+package com.ximple.io.dgn7;
+
+import com.vividsolutions.jts.geom.CoordinateList;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+import org.geotools.TestData;
+import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Ulysses
+ * Date: 2010/4/21
+ */
+public class ElementFactoryTest {
+    private final static Logger logger = Logger.getLogger(Dgn7fileReaderTest.class);
+
+    // private final static String testFilePath = "test-data\\testHV.dgn";
+    private final static String testFilePath = "testHV.dgn";
+
+    private static GeometryFactory factory = new GeometryFactory();
+
+    private FileInputStream _fs;
+    private LineStringElement _testLineString = null;
+    private ComplexChainElement _testComplexChain = null;
+
+    @BeforeTest
+    public void setUp() throws IOException, Dgn7fileException {
+        File dataFile = TestData.file(this, testFilePath);
+        if (!dataFile.exists()) {
+            return;
+        }
+
+        _fs = new FileInputStream(dataFile);
+
+        fetchTestElement(_fs);
+        _fs.close();
+    }
+
+    private void fetchTestElement(FileInputStream fs) throws Dgn7fileException, IOException {
+        FileChannel fc = _fs.getChannel();
+        Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
+        int count = 0;
+        Element lastComplex = null;
+        while (reader.hasNext()) {
+            Element.FileRecord record = reader.nextElement();
+            if (record.element() != null) {
+                Element element = (Element) record.element();
+                ElementType type = element.getElementType();
+                boolean completed = false;
+                if ((!type.isComplexElement()) && (!element.isComponentElement())) {
+                    if (lastComplex != null) {
+                        // @todo add process in here
+                        if (!processCompleteElement(lastComplex)) break;
+                        lastComplex = null;
+                    }
+
+                    // @todo add process in here
+                    if (!processCompleteElement(element)) break;
+                } else if (element.isComponentElement()) {
+                    if (lastComplex != null) {
+                        ((ComplexElement) lastComplex).add(element);
+                    } else {
+                        logger.warn("wong." + element.toString());
+                        Assert.fail("Component Element cannot found parent.");
+                    }
+                } else if (type.isComplexElement()) {
+                    if (lastComplex != null) {
+                        // @todo add process in here
+                        if (!processCompleteElement(lastComplex)) break;
+                    }
+                    lastComplex = element;
+                }
+            }
+            count++;
+        }
+    }
+
+    private boolean processCompleteElement(Element element) throws IOException {
+        if (element instanceof LineStringElement) {
+            _testLineString = (LineStringElement) element;
+        }
+
+        if (element instanceof ComplexChainElement) {
+            _testComplexChain = (ComplexChainElement) element;
+        }
+
+        if ((_testLineString != null) && (_testComplexChain != null)) return false;
+        return true;
+    }
+
+    @Test
+    public void testCreateLineString() throws IOException, Dgn7fileException {
+        Assert.assertNotNull(_testLineString);
+        LineStringElement originElement = _testLineString;
+
+        LineString geometry = (LineString) originElement.toGeometry(factory);
+        Element cloneElement = ElementFactory.createLineString(geometry);
+        Assert.assertTrue(cloneElement instanceof LineStringElement);
+        cloneElement.setLevelIndex(originElement.getLevelIndex());
+        cloneElement.setColorIndex(originElement.getColorIndex());
+        cloneElement.setWeight(originElement.getWeight());
+        cloneElement.setLineStyle(originElement.getLineStyle());
+        cloneElement.setRange(geometry.getEnvelopeInternal());
+
+        int len = originElement.raw.length;
+        int lenClone = cloneElement.raw.length;
+        // Assert.assertEquals(lenClone, len - originElement.getUserAttributeDataOffset() + 1);
+        if (originElement.hasUserAttributeData()) {
+            Assert.assertEquals(lenClone, originElement.getUserAttributeDataOffset());
+        }
+        System.out.println("origin size=(" + len + ")-:- Clone size=(" + lenClone + ")");
+        int headerSize = ElementFactory.MINIMAL_ELEMLENGTH / 2;
+        for (int i = 0; i <= headerSize; i++) {
+            if (originElement.raw[i] != cloneElement.raw[i]) {
+                System.out.print("different index=" + i + ":");
+                System.out.println("origin[" + Integer.toHexString(originElement.raw[i])
+                        + "]-clone:[" + Integer.toHexString(cloneElement.raw[i]) + "]");
+            }
+        }
+    }
+
+    @Test
+    public void testCreateComplexChain() throws IOException, Dgn7fileException {
+        Assert.assertNotNull(_testComplexChain);
+        ComplexChainElement originElement = _testComplexChain;
+
+        System.out.print("len=" + originElement.raw.length);
+        for (Element elm : originElement) {
+            System.out.print(":" + elm.raw.length);
+        }
+        System.out.println();
+
+        MultiLineString geometries = (MultiLineString) originElement.toGeometry(factory);
+        LineString geometry = factory.createLineString(geometries.getCoordinates());
+
+        ComplexChainElement cloneElement = (ComplexChainElement) ElementFactory.createComplexChain(geometry);
+        Assert.assertTrue(cloneElement instanceof ComplexChainElement);
+        cloneElement.setLevelIndex(originElement.getLevelIndex());
+        cloneElement.setColorIndex(originElement.getColorIndex());
+        cloneElement.setWeight(originElement.getWeight());
+        cloneElement.setLineStyle(originElement.getLineStyle());
+        cloneElement.setRange(geometry.getEnvelopeInternal());
+
+        int len = originElement.raw.length;
+        int lenClone = cloneElement.raw.length;
+        // Assert.assertEquals(lenClone, len - originElement.getUserAttributeDataOffset() + 1);
+        System.out.print("clonelen=" + cloneElement.raw.length);
+        for (Element elm : cloneElement) {
+            System.out.print(":" + elm.raw.length);
+        }
+        System.out.println();
+
+        if (originElement.hasUserAttributeData()) {
+            Assert.assertEquals(lenClone, originElement.getUserAttributeDataOffset() + 4);
+        }
+        System.out.println("origin size=(" + len + ")-:- Clone size=(" + lenClone + ")");
+        int headerSize = ElementFactory.MINIMAL_ELEMLENGTH / 2 + 6;
+        for (int i = 0; i < headerSize; i++) {
+            if (originElement.raw[i] != cloneElement.raw[i]) {
+                System.out.print("different index=" + i + ":");
+                System.out.println("origin[" + Integer.toHexString(originElement.raw[i])
+                        + "]-clone:[" + Integer.toHexString(cloneElement.raw[i]) + "]");
+            }
+        }
+    }
+}

--
Gitblit v0.0.0-SNAPSHOT