.gitattributes
@@ -1 +1,28 @@ * text=auto !eol ximple-dgnio/.project svneol=native#text/xml ximple-dgnio/pom.xml svneol=native#text/xml ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/io/dgn7/Utility.java svneol=native#text/plain ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java svneol=native#text/plain ximple-dgnio/.project
New file @@ -0,0 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>ximple-dgnio</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>org.maven.ide.eclipse.maven2Builder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>org.eclipse.jdt.core.javabuilder</name> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>org.eclipse.jdt.core.javanature</nature> <nature>org.maven.ide.eclipse.maven2Nature</nature> </natures> </projectDescription> ximple-dgnio/pom.xml
New file @@ -0,0 +1,443 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ximple</groupId> <artifactId>ximple-dgnio</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <name>ximple-dgnio-1.0.x</name> <scm> <connection> scm:svn:http://www.ximple.com.tw/svn/xeofms/xdgnio/truck/ </connection> <url>http://www.ximple.com.tw/svn/xeofms/xdgnio/truck/</url> </scm> <description>Ximple Dgn IO Library</description> <organization> <name>Ximple</name> <url>http://www.ximple.com.tw</url> </organization> <inceptionYear>2008</inceptionYear> <!-- =========================================================== --> <!-- Issue managements and mailing lists. --> <!-- =========================================================== --> <issueManagement> <system>JIRA</system> <url>http://www.ximple.com.tw/jira/browse/EOFMS</url> </issueManagement> <!-- =========================================================== --> <!-- Continuous Integration --> <!-- =========================================================== --> <ciManagement> <system>continuum</system> </ciManagement> <mailingLists> <mailingList> </mailingList> </mailingLists> <developers> <developer> </developer> </developers> <contributors> </contributors> <dependencies> <dependency> <groupId>org.vividsolutions</groupId> <artifactId>jts</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>com.testng</groupId> <artifactId>testng</artifactId> <classifier>jdk15</classifier> <version>5.7</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-contrib</artifactId> <version>3.0.1-FINAL</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <!-- Same as the dependency in commons-logging --> </dependency> </dependencies> <!-- =========================================================== --> <!-- Build Configuration --> <!-- =========================================================== --> <build> <!-- ========================================================= --> <!-- Maven plugins dependencies management. --> <!-- It should not be needed since Maven select by default --> <!-- the latest plugins. Unfortunatly, experience shows that --> <!-- new plugin releases sometime introduce new bugs that --> <!-- break our build. So it is saferto specify plugin --> <!-- versions that are known to work. This list is in --> <!-- alphabetical order for easier comparaison with latest --> <!-- plugins at --> <!-- http://www.ibiblio.org/maven2/org/apache/maven/plugins/ --> <!-- ========================================================= --> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.1</version> <configuration> <descriptors> <descriptor>build/maven/assembly/binaryDist.xml</descriptor> <descriptor>build/maven/assembly/sourceDist.xml</descriptor> </descriptors> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <version>2.1.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clover-plugin</artifactId> <version>2.3</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>2.3</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.0.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>2.0-beta-5</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.2</version> <!-- Current version is 2.3, but it cause the following exception: Running org.geotools.gce.imagepyramid.ImagePyramidReaderTest Error: Could not find mediaLib accelerator wrapper classes. Continuing in pure Java mode. Occurs in: com.sun.media.jai.mlib.MediaLibAccessor java.lang.NoClassDefFoundError: com/sun/medialib/mlib/Image at com.sun.media.jai.mlib.MediaLibAccessor.setUseMlib(MediaLibAccessor.java:245) at com.sun.media.jai.mlib.MlibAffineRIF.create(MlibAffineRIF.java:71) --> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> <version>2.3</version> </plugin> <!-- http://www.ibiblio.org/maven2/org/codehaus/mojo/ --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>changelog-maven-plugin</artifactId> <version>2.0-beta-1</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>changes-maven-plugin</artifactId> <version>2.0-beta-1</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jxr-maven-plugin</artifactId> <version>2.0-beta-1</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>taglist-maven-plugin</artifactId> <version>2.0</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jalopy-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> <outputDirectory>${src.output}</outputDirectory> <attach>false</attach> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.4</version> </plugin> </plugins> </pluginManagement> <!-- http://www.ibiblio.org/maven2/org/apache/maven/wagon/ --> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-webdav</artifactId> <version>1.0-beta-2</version> </extension> </extensions> <plugins> <!-- ======================================================= --> <!-- Source reformat --> <!-- (activated only on request, jalopy:format) --> <!-- See developer's guide for automated activation --> <!-- ======================================================= --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jalopy-maven-plugin</artifactId> <configuration> <convention>gt2/jalopygeotools.xml</convention> <failOnError>false</failOnError> </configuration> <dependencies> <dependency> <groupId>org.geotools.maven</groupId> <artifactId>gt2-build-configs</artifactId> <version>${project.version}</version> </dependency> </dependencies> </plugin> <!-- ======================================================= --> <!-- Compilation. --> <!-- ======================================================= --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <!-- The -source argument for the Java compiler. --> <target>1.5</target> <!-- The -target argument for the Java compiler. --> <debug>true</debug> <!-- Whether to include debugging information. --> <encoding>ISO-8859-1</encoding> <!-- The -encoding argument for the Java compiler. --> </configuration> </plugin> <!-- ======================================================= --> <!-- Tests. --> <!-- ======================================================= --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Test.java</include> </includes> <excludes> <exclude>${online.skip.pattern}</exclude> <exclude>${stress.skip.pattern}</exclude> </excludes> <argLine>-Xmx${test.maxHeapSize} -Dorg.geotools.test.extensive=${extensive.tests} -Dorg.geotools.test.interactive=${interactive.tests} -Djava.awt.headless=${java.awt.headless} </argLine> <!-- Ignores test failure only if we are generating a --> <!-- report for publication on the web site. See the --> <!-- profiles section at the begining of this pom.xml file. --> <testFailureIgnore> ${allow.test.failure.ignore} </testFailureIgnore> <!-- The two following options have the opposite value of what we would like. They are that way because they don't seem to work as expected with Surefire 2.3. TODO: Try again when Surefire 2.4 will be available. --> <!-- Option to print summary of test suites or just print the test cases that has errors. --> <printSummary>true</printSummary> <!-- Redirect the unit test standard output to a file. --> <redirectTestOutputToFile>false</redirectTestOutputToFile> </configuration> </plugin> <!-- ======================================================= --> <!-- Code coverage --> <!-- ======================================================= --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clover-plugin</artifactId> <configuration> <jdk>1.5</jdk> <licenseLocation> http://svn.geotools.org/geotools/branches/2.4.x/build/maven/build-configs/src/main/resources/gt2/clover.license </licenseLocation> <flushPolicy>directed</flushPolicy> </configuration> <executions> <execution> <phase>pre-site</phase> <goals> <goal>instrument</goal> <!-- aggregation is disabled due to the bug: --> <!-- http://jira.codehaus.org/browse/MCLOVER-34 --> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.geotools.maven</groupId> <artifactId>gt2-build-configs</artifactId> <version>${project.version}</version> </dependency> </dependencies> </plugin> <!-- ======================================================= --> <!-- JAR packaging. --> <!-- ======================================================= --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> <!-- ======================================================= --> <!-- Source packaging. --> <!-- ======================================================= --> <plugin> <inherited>true</inherited> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> <attach>true</attach> </configuration> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <!-- =========================================================== --> <!-- Repositories (ibiblio, refractions...). --> <!-- This is where Maven looks for dependencies. --> <!-- =========================================================== --> <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Ximple Artifactory Maven Repository Switchboard</name> <url>http://www.ximple.com.tw/artifactory/repo</url> </repository> <repository> <releases> <enabled>false</enabled> </releases> <id>snapshots</id> <name>Ximple Artifactory Maven Repository Switchboard</name> <url>http://www.ximple.com.tw/artifactory/repo</url> </repository> </repositories> <!-- =========================================================== --> <!-- Plugin repositories. --> <!-- This is where Maven looks for plugin dependencies. --> <!-- =========================================================== --> <pluginRepositories> <pluginRepository> <id>ximple-snapshots</id> <name>ximple-shapshots</name> <url>http://www.ximple.com.tw/artifactory/vplugins-snapshots</url> <snapshots> <enabled>true</enabled> </snapshots> <releases> <enabled>false</enabled> </releases> </pluginRepository> <pluginRepository> <id>ximple</id> <name>Ximple Maven 2 Repository</name> <url>http://www.ximple.com.tw/artifactory/vplugins-releases</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </pluginRepository> </pluginRepositories> </project> ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java
New file @@ -0,0 +1,166 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * ArcElement * * @author Ulysses * @version 0.1 * @since 2006/5/26 ¤U¤È 06:41:45 */ public class ArcElement extends Element implements GeometryConverter { public ArcElement(short[] raw) { super(raw); } public double getPrimary() { short[] primary = new short[4]; System.arraycopy(raw, 22, primary, 0, 4); return Utility.DGNToIEEEDouble(primary) / 1000.0; } public void setPrimary(double value) { double temp = value * 1000.0; short[] primary = Utility.IEEEDoubleToDGN(temp); System.arraycopy(primary, 0, raw, 22, 4); } public double getSecondary() { short[] secondary = new short[4]; System.arraycopy(raw, 26, secondary, 0, 4); return Utility.DGNToIEEEDouble(secondary) / 1000.0; } public void setSecondary(double value) { double temp = value * 1000.0; short[] secondary = Utility.IEEEDoubleToDGN(temp); System.arraycopy(secondary, 0, raw, 26, 4); } public Coordinate getOrigin() { short[] x = new short[4]; System.arraycopy(raw, 32, x, 0, 4); double dx = Utility.ConverUnitToCoord((int) Utility.DGNToIEEEDouble(x)); short[] y = new short[4]; System.arraycopy(raw, 36, y, 0, 4); double dy = Utility.ConverUnitToCoord((int) Utility.DGNToIEEEDouble(y)); return new Coordinate(dx, dy); } public void setOrigin(Coordinate value) { double temp = Utility.ConverCoordToUnit(value.x); short[] x = Utility.IEEEDoubleToDGN(temp); System.arraycopy(x, 0, raw, 32, 4); temp = Utility.ConverCoordToUnit(value.y); short[] y = Utility.IEEEDoubleToDGN(temp); System.arraycopy(y, 0, raw, 36, 4); } public double getStartAngle() { int angle = (int) (raw[18] << 16 & 0xffff0000); angle += raw[19] & 0x0000ffff; return Utility.ConverIntToRotation(angle); } public void setStartAngle(double value) { int angle = Utility.ConverRotatioToInt(value); raw[18] = (short) (angle >>> 16 & 0x0000ffff); raw[19] = (short) (angle & 0x0000ffff); } public double getSweepAngle() { int angle = (int) (raw[20] << 16 & 0xffff0000); angle += raw[21] & 0x0000ffff; return Utility.ConverIntToRotation(angle); } public void setSweepAngle(double value) { int angle = Utility.ConverRotatioToInt(value); raw[20] = (short) (angle >> 16 & 0x0000ffff); raw[21] = (short) (angle & 0x0000ffff); } public double getRotationAngle() { int rotation = (int) (raw[30] << 16 & 0xffff0000); rotation += raw[31] & 0x0000ffff; return Utility.ConverIntToRotation(rotation); } public void setRotationAngle(double value) { int angle = Utility.ConverRotatioToInt(value); raw[30] = (short) (angle >> 16 & 0x0000ffff); raw[31] = (short) (angle & 0x0000ffff); } public Geometry toGeometry(GeometryFactory factory) { return null; // To change body of implemented methods use File | Settings | File Templates. } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.ARC); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new ArcElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
New file @@ -0,0 +1,230 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; /** * ComplexChainElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 03:44:56 */ public class ComplexChainElement extends Element implements ComplexElement, GeometryConverter { ArrayList list = new ArrayList(); public ComplexChainElement(short[] raw) { super(raw); attrOffset = 4; } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator iterator() { return list.iterator(); } public Object[] toArray() { return list.toArray(); } public boolean add(Object o) { return list.add(o); } public boolean remove(Object o) { return list.remove(o); } public boolean addAll(Collection c) { return list.addAll(c); } public boolean addAll(int index, Collection c) { return list.addAll(index, c); } public void clear() { list.clear(); } public Object get(int index) { return list.get(index); } public Object set(int index, Object element) { return list.set(index, element); } public void add(int index, Object element) { list.add(index, element); } public Object remove(int index) { return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator listIterator() { return list.listIterator(); } public ListIterator listIterator(int index) { return list.listIterator(index); } public List subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } public boolean retainAll(Collection c) { return list.retainAll(c); } public boolean removeAll(Collection c) { return list.removeAll(c); } public boolean containsAll(Collection c) { return list.containsAll(c); } public Object[] toArray(Object[] a) { return list.toArray(a); } public Geometry toGeometry(GeometryFactory factory) { ArrayList list = new ArrayList(); if (size() == 1) { Element element = (Element) get(0); if (element instanceof LineStringElement) { return ((LineStringElement) element).toGeometry(factory); } else if (element instanceof LineElement) { return ((LineElement) element).toGeometry(factory); } else { if (element instanceof GeometryConverter) { return ((GeometryConverter) element).toGeometry(factory); } return null; } } for (ListIterator it = listIterator(); it.hasNext(); ) { Element element = (Element) it.next(); if (element instanceof LineStringElement) { list.add(((LineStringElement) element).toGeometry(factory)); } else if (element instanceof LineElement) { list.add(((LineElement) element).toGeometry(factory)); } } Geometry[] ga = (Geometry[]) list.toArray(new Geometry[list.size()]); GeometryCollection geos = new GeometryCollection(ga, factory); return geos; } public double getElementSize() { return raw[18]; } public boolean isClosed() { if (isEmpty()) { return false; } return false; } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.COMPLEXCHAIN); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new ComplexChainElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java
New file @@ -0,0 +1,16 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.util.List; /** * ComplexElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 04:17:37 */ public interface ComplexElement extends List { } ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java
New file @@ -0,0 +1,193 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; /** * ComplexShapeElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 03:45:15 */ public class ComplexShapeElement extends Element implements ComplexElement, GeometryConverter { ArrayList list = new ArrayList(); public ComplexShapeElement(short[] raw) { super(raw); } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator iterator() { return list.iterator(); } public Object[] toArray() { return list.toArray(); } public boolean add(Object o) { return list.add(o); } public boolean remove(Object o) { return list.remove(o); } public boolean addAll(Collection c) { return list.addAll(c); } public boolean addAll(int index, Collection c) { return list.addAll(index, c); } public void clear() { list.clear(); } public Object get(int index) { return list.get(index); } public Object set(int index, Object element) { return list.set(index, element); } public void add(int index, Object element) { list.add(index, element); } public Object remove(int index) { return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator listIterator() { return list.listIterator(); } public ListIterator listIterator(int index) { return list.listIterator(index); } public List subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } public boolean retainAll(Collection c) { return list.retainAll(c); } public boolean removeAll(Collection c) { return list.removeAll(c); } public boolean containsAll(Collection c) { return list.containsAll(c); } public Object[] toArray(Object[] a) { return list.toArray(a); } public Geometry toGeometry(GeometryFactory factory) { ArrayList list = new ArrayList(); for (ListIterator it = listIterator(); it.hasNext(); ) { Element element = (Element) it.next(); if (element instanceof LineStringElement) { list.add(((LineStringElement) element).toGeometry(factory)); } else if (element instanceof LineElement) { list.add(((LineElement) element).toGeometry(factory)); } } Geometry[] ga = (Geometry[]) list.toArray(new Geometry[list.size()]); GeometryCollection geos = new GeometryCollection(ga, factory); return geos; } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.COMPLEXSHAPE); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new ComplexShapeElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java
New file @@ -0,0 +1,246 @@ package com.ximple.io.dgn7; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Iterator; import org.apache.log4j.Logger; import oracle.jdbc.OracleConnection; import oracle.sql.BLOB; /** * Dgn7OracleReader * User: Ulysses * Date: 2007/10/24 * Time: ¤U¤È 01:01:08 */ public class Dgn7OracleReader implements Iterator<Element> { private final static Logger logger = Logger.getLogger(Dgn7OracleReader.class); private String _sql; private String _fieldName; private Connection _connection; private ResultSet _resultSet; private static final int FETCHSIZE = 20; private Element _element; public Dgn7OracleReader(String sql, String fieldName, OracleConnection connection) { this._sql = sql; this._fieldName = fieldName; this._connection = connection; } public String getSql() { return _sql; } public void setSql(String sql) { this._sql = sql; } public String getFieldName() { return _fieldName; } public void setFieldName(String fieldName) { this._fieldName = fieldName; } public boolean hasNext() { if (_resultSet == null) { try { initializeReader(); } catch (SQLException e) { throw new RuntimeException("initialize oralce error.", e); } catch (Dgn7fileException e) { throw new RuntimeException("initialize oralce error.", e); } } if (_element == null) { return false; } return true; } public Element next() { Element result = _element; try { fetchElement(); } catch (SQLException e) { throw new RuntimeException("Error:" + e.getMessage(), e); } catch (Dgn7fileException e) { throw new RuntimeException("Error:" + e.getMessage(), e); } return result; } public void remove() { throw new RuntimeException("Not Support this method."); } private boolean initializeReader() throws SQLException, Dgn7fileException { if (_resultSet != null) return true; Statement stmtSrc = _connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); stmtSrc.setFetchSize(FETCHSIZE); _resultSet = stmtSrc.executeQuery(_sql); fetchElement(); return true; } private boolean fetchElement() throws SQLException, Dgn7fileException { if (_resultSet.next()) { byte[] raw = null; Object value = _resultSet.getObject(this._fieldName); if (value instanceof BLOB) { BLOB blob = (BLOB) value; try { raw = getBytesFromBLOB(blob); } catch (IOException e) { throw new SQLException("IOError", e); } blob.close(); } else if (value instanceof byte[]) { raw = (byte[]) value; } if (raw == null) { _element = null; return false; } ByteBuffer buffer = ByteBuffer.wrap(raw); buffer.order(ByteOrder.LITTLE_ENDIAN); short signature = buffer.getShort(); // byte type = (byte) (buffer.get() & 0x7f); byte type = (byte) ((signature >>> 8) & 0x007f); // silly Bentley say contentLength is in 2-byte words // and ByteByffer uses bytes. // track the record location int elementLength = (buffer.getShort() * 2) + 4; ElementType recordType = ElementType.forID(type); IElementHandler handler = recordType.getElementHandler(); _element = (Element) handler.read(buffer, signature, elementLength); if (recordType.isComplexElement() && (elementLength < raw.length)) { int offset = elementLength; while (offset < (raw.length - 4)) { buffer.position(offset); signature = buffer.getShort(); type = (byte) ((signature >>> 8) & 0x007f); elementLength = (buffer.getShort() * 2) + 4; if (raw.length < (offset + elementLength)) { System.out.println("Length not match:" + offset +":"+ buffer.position() +":"+buffer.limit()); break; } recordType = ElementType.forID(type); handler = recordType.getElementHandler(); if (handler != null) { Element subElement = (Element) handler.read(buffer, signature, elementLength); ((ComplexElement) _element).add(subElement); offset += elementLength; } else { byte[] remain = new byte[buffer.remaining()]; System.arraycopy(raw, offset, remain, 0, buffer.remaining()); for (int i = 0; i < remain.length; i++) { if (remain[i] != 0) { logger.info("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]); System.out.println("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]); } } break; } } } } else { _element = null; return false; } return true; } protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException, IOException { byte[] raw = null; // BLOB blob = (BLOB) rs.getBlob(1); int optimalSize = blob.getChunkSize(); byte[] chunk = new byte[optimalSize]; InputStream is = blob.getBinaryStream(0); ByteBuffer buffer = null; // ByteBuffer.allocate(optimalSize); int len = 0; try { while ((len = (is.read(chunk))) != -1) { if (buffer != null) { buffer.limit(buffer.limit() + len); } else { buffer = ByteBuffer.allocate(len); } buffer.put(chunk); } is.close(); buffer.position(0); raw = buffer.array(); } catch (IOException e) { e.printStackTrace(); throw e; } return raw; } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java
New file @@ -0,0 +1,31 @@ package com.ximple.io.dgn7; /** * Created by IntelliJ IDEA. * User: Ulysses * Date: 2007/9/13 * Time: ¤W¤È 11:19:08 * To change this template use File | Settings | File Templates. */ public class Dgn7fileException extends Exception { public Dgn7fileException() { } public Dgn7fileException(String message) { super(message); } public Dgn7fileException(String message, Throwable cause) { super(message, cause); } public Dgn7fileException(Throwable cause) { super(cause); } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java
New file @@ -0,0 +1,58 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import com.vividsolutions.jts.util.Assert; /** * Dgn7fileHeader * * @author Ulysses * @version 0.1 * @since 2006/5/17 ¤U¤È 01:21:00 */ public class Dgn7fileHeader { private short elmtype; private byte[] raw; public Dgn7fileHeader() { } public void read(ByteBuffer file, boolean strict) throws IOException { file.order(ByteOrder.LITTLE_ENDIAN); elmtype = file.getShort(); short wtf = file.getShort(); int length = (wtf * 2); if (file.remaining() != (length)) { Assert.shouldNeverReachHere(); } raw = new byte[length]; file.get(raw, 0, file.remaining()); } public String toString() { return "Dgn7fileHeader{" + "raw=" + ((raw == null) ? "null" : raw.length) + '}'; } public int size() { if (raw == null) { return 0; } return raw.length + 4; } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java
New file @@ -0,0 +1,718 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import javax.swing.*; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import com.vividsolutions.jts.geom.GeometryFactory; /** * Dgn7fileReader * * @author Ulysses * @version 0.1 * @since 2006/5/17 ¤U¤È 01:24:10 */ public class Dgn7fileReader { private static final Logger logger = LogManager.getLogger("com.isimple.glyphjump.io.dgn7"); private Dgn7fileHeader header; private ReadableByteChannel channel; ByteBuffer buffer; private ElementType fileElementType = ElementType.UNDEFINED; private ByteBuffer headerTransfer; private final Record record = new Record(); private final boolean randomAccessEnabled; private Lock lock; private boolean useMemoryMappedBuffer; private long currentOffset = 0L; private StreamLogging streamLogger = new StreamLogging("Shapefile Reader"); private int maxElementId = 0; public Dgn7fileReader(ReadableByteChannel channel, boolean strict, boolean useMemoryMapped, Lock lock) throws IOException, Dgn7fileException { this.channel = channel; this.useMemoryMappedBuffer = useMemoryMapped; streamLogger.open(); randomAccessEnabled = channel instanceof FileChannel; this.lock = lock; lock.lockRead(); init(strict); } public Dgn7fileReader(ReadableByteChannel channel, Lock lock) throws IOException, Dgn7fileException { this(channel, true, true, lock); } // ensure the capacity of the buffer is of size by doubling the original // capacity until it is big enough // this may be naiive and result in out of MemoryError as implemented... public static ByteBuffer ensureCapacity(ByteBuffer buffer, int size, boolean useMemoryMappedBuffer) { // This sucks if you accidentally pass is a MemoryMappedBuffer of size // 80M // like I did while messing around, within moments I had 1 gig of // swap... if (buffer.isReadOnly() || useMemoryMappedBuffer) { return buffer; } int limit = buffer.limit(); while (limit < size) { limit *= 2; } if (limit != buffer.limit()) { // if (record.ready) { buffer = ByteBuffer.allocateDirect(limit); // } // else { // throw new IllegalArgumentException("next before hasNext"); // } } return buffer; } // for filling a ReadableByteChannel public static int fill(ByteBuffer buffer, ReadableByteChannel channel) throws IOException { int r = buffer.remaining(); // channel reads return -1 when EOF or other error // because they a non-blocking reads, 0 is a valid return value!! while ((buffer.remaining() > 0) && (r != -1)) { r = channel.read(buffer); } if (r == -1) { buffer.limit(buffer.position()); } return r; } public static Dgn7fileHeader readHeader(ReadableByteChannel channel, boolean strict) throws IOException { ByteBuffer buffer = ByteBuffer.allocateDirect(4); if (fill(buffer, channel) == -1) { throw new EOFException("Premature end of header"); } buffer.order(ByteOrder.LITTLE_ENDIAN); int length = buffer.getShort(2) * 2; ByteBuffer old = buffer; old.position(0); // ensure enough capacity for one more record header buffer = ByteBuffer.allocateDirect(length + 4); buffer.put(old); if (fill(buffer, channel) == -1) { throw new EOFException("Premature end of header"); } buffer.position(0); Dgn7fileHeader header = new Dgn7fileHeader(); header.read(buffer, strict); return header; } public Dgn7fileHeader getHeader() { return header; } public void close() throws IOException { lock.unlockRead(); if (channel.isOpen()) { channel.close(); streamLogger.close(); } if (buffer instanceof MappedByteBuffer) { NIOUtilities.clean(buffer); } channel = null; header = null; } public boolean supportsRandomAccess() { return randomAccessEnabled; } public Record nextElement() throws IOException, Dgn7fileException { // need to update position buffer.position(this.toBufferOffset(record.end)); // record header is big endian buffer.order(ByteOrder.LITTLE_ENDIAN); // read shape record header int recordNumber = ++maxElementId; short signature = buffer.getShort(); // byte type = (byte) (buffer.get() & 0x7f); byte type = (byte) ((signature >>> 8) & 0x007f); // silly Bentley say contentLength is in 2-byte words // and ByteByffer uses bytes. // track the record location int elementLength = (buffer.getShort() * 2) + 4; if (!buffer.isReadOnly() &&!useMemoryMappedBuffer) { // capacity is less than required for the record // copy the old into the newly allocated if (buffer.capacity() < elementLength) { this.currentOffset += buffer.position(); ByteBuffer old = buffer; // ensure enough capacity for one more record header buffer = ensureCapacity(buffer, elementLength, useMemoryMappedBuffer); buffer.put(old); fill(buffer, channel); buffer.position(0); } else // remaining is less than record length // compact the remaining data and read again, // allowing enough room for one more record header if (buffer.remaining() < elementLength) { this.currentOffset += buffer.position(); buffer.compact(); fill(buffer, channel); buffer.position(0); } } // shape record is all little endian // buffer.order(ByteOrder.LITTLE_ENDIAN); // read the type, handlers don't need it ElementType recordType = ElementType.forID(type); logger.debug("nextElement at " + this.toBufferOffset(record.end) + ":type=" + type); // this usually happens if the handler logic is bunk, // but bad files could exist as well... /* * if (recordType != ElementType.NULL && recordType != fileElementType) * { * throw new IllegalStateException("ShapeType changed illegally from " + fileElementType + " to " + recordType); * } */ // peek at bounds, then reset for handler // many handler's may ignore bounds reading, but we don't want to // second guess them... buffer.mark(); if (recordType.isMultiPoint()) { int lowCoorX = buffer.getInt(); lowCoorX = Utility.ConvertFromDGN(lowCoorX); record.minX = Utility.ConverUnitToCoord(lowCoorX); int lowCoorY = buffer.getInt(); lowCoorY = Utility.ConvertFromDGN(lowCoorY); record.minY = Utility.ConverUnitToCoord(lowCoorY); int lowCoorZ = buffer.getInt(); lowCoorZ = Utility.ConvertFromDGN(lowCoorZ); record.minZ = Utility.ConverUnitToCoord(lowCoorZ); int highCoorX = buffer.getInt(); highCoorX = Utility.ConvertFromDGN(highCoorX); record.maxX = Utility.ConverUnitToCoord(highCoorX); int highCoorY = buffer.getInt(); highCoorY = Utility.ConvertFromDGN(highCoorY); record.maxY = Utility.ConverUnitToCoord(highCoorY); int highCoorZ = buffer.getInt(); highCoorZ = Utility.ConvertFromDGN(highCoorZ); record.maxZ = Utility.ConverUnitToCoord(highCoorZ); } buffer.reset(); record.offset = record.end; // update all the record info. record.length = elementLength; record.signature = signature; record.number = recordNumber; // remember, we read one int already... record.end = this.toFileOffset(buffer.position()) + elementLength - 4; // record.end = this.toFileOffset(buffer.position()) + elementLength; // mark this position for the reader record.start = buffer.position(); // clear any cached record record.handler = recordType.getElementHandler(); record.element = null; return record; } public void goTo(int offset) throws IOException, UnsupportedOperationException { if (randomAccessEnabled) { if (this.useMemoryMappedBuffer) { buffer.position(offset); } else { /* * Check to see if requested offset is already loaded; ensure * that record header is in the buffer */ if ((this.currentOffset <= offset) && (this.currentOffset + buffer.limit() >= offset + 4)) { buffer.position(this.toBufferOffset(offset)); } else { FileChannel fc = (FileChannel) this.channel; fc.position(offset); this.currentOffset = offset; buffer.position(0); fill(buffer, fc); buffer.position(0); } } int oldRecordOffset = record.end; record.end = offset; try { hasNext(); } catch (IOException ioe) { record.end = oldRecordOffset; throw ioe; } } else { throw new UnsupportedOperationException("Random Access not enabled"); } } public Record elementAt(int offset) throws IOException, UnsupportedOperationException, Dgn7fileException { if (randomAccessEnabled) { this.goTo(offset); return nextElement(); } throw new UnsupportedOperationException("Random Access not enabled"); } public boolean hasNext() throws IOException { // mark current position int position = buffer.position(); // ensure the proper position, regardless of read or handler behavior try { buffer.position(this.toBufferOffset(record.end)); } catch (IllegalArgumentException e) { logger.warn("position=" + this.toBufferOffset(record.end), e); return false; } // no more data left if (buffer.remaining() < 4) { return false; } // looks good boolean hasNext = true; short type = buffer.getShort(); if (type == -1) { hasNext = false; } // reset things to as they were buffer.position(position); return hasNext; } private void init(boolean strict) throws IOException, Dgn7fileException { header = readHeader(channel, strict); // fileElementType = header.getElementType(); // handler = fileElementType.getElementHandler(); // recordHeader = ByteBuffer.allocateDirect(4); // recordHeader.order(ByteOrder.BIG_ENDIAN); // if (handler == null) // { // throw new IOException("Unsuported shape type:" + fileElementType); // } if ((channel instanceof FileChannel) && useMemoryMappedBuffer) { FileChannel fc = (FileChannel) channel; buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); // buffer.position(100); buffer.position(header.size()); this.currentOffset = 0; } else { // force useMemoryMappedBuffer to false this.useMemoryMappedBuffer = false; // start with 8K buffer buffer = ByteBuffer.allocateDirect(8 * 1024); fill(buffer, channel); buffer.flip(); this.currentOffset = header.size(); } headerTransfer = ByteBuffer.allocate(4); headerTransfer.order(ByteOrder.LITTLE_ENDIAN); // make sure the record end is set now... record.end = toFileOffset(buffer.position()); } private int toBufferOffset(int offset) { return (int) (offset - currentOffset); } private int toFileOffset(int offset) { return (int) (currentOffset + offset); } public int getCount(int count) throws Dgn7fileException { try { if (channel == null) { return -1; } count = 0; for (int tmp = readElement(); tmp != -1; tmp = readElement()) { count += tmp; } } catch (IOException ioe) { count = -1; // What now? This seems arbitrarily appropriate ! throw new Dgn7fileException("Problem reading dgnfile record", ioe); } return count; } public int getCount() throws Dgn7fileException { return getCount(0); } private int readElement() throws IOException { if (!fillBuffer()) { return -1; } // burn the record number buffer.getInt(); if (!fillBuffer()) { return -1; } int recordlength = buffer.getInt() * 2; // Going to read the first 4 bytes of the record so // subtract that from the record length recordlength -= 4; if (!fillBuffer()) { return -1; } // read record type (used to determine if record is a null record) int type = buffer.getInt(); // go to end of record while (buffer.limit() < buffer.position() + recordlength) { recordlength -= buffer.limit() - buffer.position(); buffer.clear(); if (channel.read(buffer) < 1) { return -1; } } buffer.position(buffer.position() + recordlength); // return 0 if record is null. Null records should be counted. if (type == 0) { // this is a null feature return 0; } return 1; } private boolean fillBuffer() throws IOException { int result = 1; if (buffer.limit() <= buffer.position() + 4) { result = fill(buffer, channel); } return result > 0; } public static void main(String[] args) { JFileChooser jfc = new JFileChooser("D:/TEMP"); File f = null; int r = jfc.showOpenDialog(new JFrame()); if (r == JFileChooser.APPROVE_OPTION) { try { f = jfc.getSelectedFile(); FileChannel channel = new FileInputStream(f).getChannel(); Dgn7fileReader reader = new Dgn7fileReader(channel, new Lock()); System.out.println(reader.getHeader().toString()); GeometryFactory factory = new GeometryFactory(); int count, size; count = 0; size = 0; try { Element lastComplex = null; while (reader.hasNext()) { size++; Dgn7fileReader.Record record = reader.nextElement(); if (record.element() != null) { Element element = (Element) record.element(); ElementType type = element.getElementType(); if ((!type.isComplexElement()) && (!element.isComponentElement())) { if (lastComplex != null) { // @todo add process in here count++; lastComplex = null; } // @todo add process in here count++; } else if (element.isComponentElement()) { if (lastComplex != null) { ((ComplexElement) lastComplex).add(element); } } else if (type.isComplexElement()) { if (lastComplex == null) { lastComplex = element; } else { // @todo add process in here count++; lastComplex = element; } } } } } catch (IOException e) { logger.warn("Stop read dgn file", e); } catch (Dgn7fileException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } finally { reader.close(); } System.out.println("count=" + count + " size=" + size); // reader.close(); } catch (IOException ioe) { System.out.println(ioe); ioe.printStackTrace(); } catch (Dgn7fileException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } System.exit(0); } public final class Record { int length; int number = 0; int offset; // Relative to the whole file int start = 0; // Relative to the current loaded buffer short signature = 0; /** * The minimum X value. */ public double minX; /** * The minimum Y value. */ public double minY; /** * The minimum Z value. */ public double minZ; /** * The maximum X value. */ public double maxX; /** * The maximum Y value. */ public double maxY; /** * The maximum Z value. */ public double maxZ; // ElementType type; int end = 0; // Relative to the whole file Object element = null; IElementHandler handler; public Object element() { if (element == null) { buffer.position(start); buffer.order(ByteOrder.LITTLE_ENDIAN); if (handler == null) { return null; } element = handler.read(buffer, signature, length); } return element; } public int offset() { return offset; } /** * A summary of the record. */ public String toString() { return "Record " + number + " length " + length + " bounds " + minX + "," + minY + " " + maxX + "," + maxY; } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
New file @@ -0,0 +1,271 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.List; import com.vividsolutions.jts.geom.Envelope; /** * Record * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 11:14:50 */ public class Element { public static final int CONSTRUCTION_CLASS = 0; public static final int CONSTRUCTION_RULE_CLASS = 0; public static final int DIMENSION_CLASS = 0; public static final int LINEAR_PATTERNED_CLASS = 0; public static final int MAX_ELEMENT_SIZE = 0; public static final int MAX_VERTICES = 100; public static final int PATTERN_AREA = 0; public static final int PATTERN_COMPONENT_CLASS = 0; public static final int PATTERN_CROSSHATCH = 0; public static final int PATTERN_HATCH = 0; public static final int PRIMARY_CLASS = 0; public static final int PRIMARY_RULE_CLASS = 0; short[] raw; byte attrOffset = 0; public Element(short[] raw) { this.raw = raw; } public int getLineStyle() { return 0; } public Envelope getRange() { int lowCoorX = (int) ((raw[3] << 16) & 0xffff0000) + (raw[2] & 0x0000ffff); lowCoorX = Utility.ConvertFromDGN(lowCoorX); int lowCoorY = (int) ((raw[5] << 16) & 0xffff0000) + (raw[4] & 0x0000ffff); lowCoorY = Utility.ConvertFromDGN(lowCoorY); int highCoorX = (int) ((raw[9] << 16) & 0xffff0000) + (raw[8] & 0x0000ffff); highCoorX = Utility.ConvertFromDGN(highCoorX); int highCoorY = (int) ((raw[11] << 16) & 0xffff0000) + (raw[10] & 0x0000ffff); highCoorY = Utility.ConvertFromDGN(highCoorY); return new Envelope(Utility.ConverUnitToCoord(lowCoorX), Utility.ConverUnitToCoord(highCoorX), Utility.ConverUnitToCoord(lowCoorY), Utility.ConverUnitToCoord(highCoorY)); } public boolean isComponentElement() { if ((short) ((raw[0] >>> 7) & 0x0001) == 1) { return true; } else { return false; } } public boolean removeUserAttributeData(int iLinkageId) { return true; } public boolean removeUserAttributeData(int iLinkageId, int iLinkageIndex) { return true; } public boolean isDeleted() { if ((short) ((raw[0] >>> 15) & 0x0001) == 1) { return true; } else { return false; } } public int getColorIndex() { return ((raw[17] >>> 8) & 0x00ff); } public int getType() { return ((raw[0] >>> 8) & 0x007f); } public ElementType getElementType() { return ElementType.forID(getType()); } public int getLevelIndex() { return (raw[0] & 0x003f); } public int getWeight() { return ((raw[17] >>> 3) & 0x001f); } public void addUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId) throws Element.Exception { } public void addUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef) throws Element.Exception { } public boolean hasUserAttributeData() { if (raw[15] <= 0) { return false; } short index = (short) (raw[15] + 16); if (index == -1) { return false; } return true; } public List<UserAttributeData> getUserAttributeData() { short[] data; short length, nextAttribute; if (raw[15] <= 0) { return new ArrayList<UserAttributeData>(); } short index = (short) (raw[15] + 16 + attrOffset); if (index == -1) { return null; } ArrayList<UserAttributeData> aLinkageSet = new ArrayList<UserAttributeData>(); while (index < raw.length) { length = (short) (raw[index] & (short) 0x00ff); if (length == 0) { break; } nextAttribute = (short) (index + length + 1); data = new short[length]; System.arraycopy(raw, index + 1, data, 0, length); if (data[0] == (short) 0x0020) { aLinkageSet.add(new FrammeAttributeData(data)); } else { aLinkageSet.add(new UserAttributeData(data)); } index = nextAttribute; } return aLinkageSet; } public void getUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId, int iLinkageIndex) { } public void getUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef) { } public static class Exception extends java.lang.Exception { public Exception() { } // Constructs an Record.Exception with no detail message. public Exception(String oStrMessage) { super(oStrMessage); } } public static class ElementHandler implements IElementHandler { ElementType elementType; public ElementHandler(ElementType elementType) { this.elementType = elementType; } public ElementType getElementType() { return elementType; } public Object read(ByteBuffer buffer, short signature, int length) { byte[] dst = new byte[length - 4]; try { buffer.get(dst, 0, dst.length); } catch (BufferUnderflowException exception) { throw exception; } ByteBuffer tmpBuffer = ByteBuffer.wrap(dst); tmpBuffer.order(ByteOrder.LITTLE_ENDIAN); ShortBuffer sbuffer = tmpBuffer.asShortBuffer(); short[] rawMem = new short[(length / 2)]; sbuffer.get(rawMem, 2, rawMem.length - 2); rawMem[0] = signature; rawMem[1] = (short) ((length / 2) - 2); Element elm = createElement(rawMem); return elm; } public void write(ByteBuffer buffer, Object element) { } public int getLength(Object element) { return ((Element) element).raw.length; } protected Element createElement(short[] raw) { return new Element(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
New file @@ -0,0 +1,534 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- /*----------------------------------------------------------------------+ | | | Type Description | | 1 Cell Library Header | | 2 Cell (complex) | | 3 Line | | 4 Line String | | 5 Group Data | | 6 Shape | | 7 Text Node (complex) | | 8 Digitizer Setup Data | | 9 Design File Header if level 8 | | 10 Level Symbology | | 11 Curve | | 12 Complex String (complex) | | 13 Conic | | 14 Complex Shape (complex) | | 15 Ellipse | | 16 Arc | | 17 Text | | 18 Surface (complex) | | 19 Solid (complex) | | 20 not used | | 21 B-Spline Pole | | 22 Point String | | 23 Circular Truncated Cone | | 24 B-Spline Surface (complex) | | 25 B-Spline Surface boundary | | 26 B-Spline Knot Record | | 27 B-Spline Curve (complex) | | 28 B-Spline Weight Factor | | 33 Dimension Record | | 34 Shared Cell Definition Record | | 35 Shared Cell Record | | 36 Multiline Record | | 37 Attribute Record | | 38 DgnStore Component | | 39 DgnStore Header | | 66 MicroStation Application | | 87 Raster Header | | 88 Raster Component | | 90 Raster Reference Attachment | | 91 Raster Reference Component | | 92 Raster Hierarchy Record | | 93 Raster Hierarchy Component | | 94 Raster Frame Record | | 95 Table Entry Record | | 96 Table Header Record | | 97 View Group Record | | 98 View Record | | 99 Level Mask Record | | 100 Reference Attach Record | | 101 Matrix Header | | 102 Matrix Int Data | | 103 Matrix Double Data | | 105 Mesh Header | | 106 Extended Record (graphic) (complex) | | 107 Extended Record (non-graphic) (complex) | | 108 Reference Override Record | | 110 Named Group Header | | 111 Named Group Component | | | +----------------------------------------------------------------------*/ /** * ElementType * * @author Ulysses * @version 0.1 * @since 2006/5/17 ¤U¤È 01:26:49 */ public final class ElementType { /** * Represents a Null shape (id = 0). */ public static final ElementType NULL = new ElementType(0, "Null"); /** * Represents a Line shape (id = 3). */ public static final ElementType LINE = new ElementType(3, "Line"); /** * Represents a LineString shape (id = 4). */ public static final ElementType LINESTRING = new ElementType(4, "LineString"); /** * Represents a Shape shape (id = 6). */ public static final ElementType SHAPE = new ElementType(6, "Shape"); /** * Represents an TextNode shape (id = 7). */ public static final ElementType TEXTNODE = new ElementType(7, "TextNode"); /** * Represents an IGDSDIGITIZER shape (id = 8). */ public static final ElementType IGDSDIGITIZER = new ElementType(8, "IGDSDigitizer"); /** * Represents an TCB shape (id = 9). */ public static final ElementType TCB = new ElementType(9, "Tcb"); /** * Represents a LevelSymbology shape (id = 5). */ public static final ElementType LEVELSYMBOLOGY = new ElementType(10, "LevelSymbology"); /** * Represents a ComplexChain shape (id = 15). */ public static final ElementType COMPLEXCHAIN = new ElementType(12, "ComplexChain"); /** * Represents a ComplexShape shape (id = 25). */ public static final ElementType COMPLEXSHAPE = new ElementType(14, "ComplexShape"); /** * Represents a Ellipse shape (id = 8). */ public static final ElementType ELLIPSE = new ElementType(15, "Ellipse"); /** * Represents a Arc shape (id = 28). */ public static final ElementType ARC = new ElementType(16, "Arc"); /** * Represents a Arc shape (id = 28). */ public static final ElementType TEXT = new ElementType(17, "Text"); /** * Represents a Arc shape (id = 28). */ public static final ElementType POINTSTRING = new ElementType(22, "PointString"); /** * Represents an Undefined shape (id = -1). */ public static final ElementType UNDEFINED = new ElementType(-1, "Undefined"); /** * The integer id of this ElementType. */ public final int id; /** * The human-readable name for this ElementType.<br> * Could easily use ResourceBundle for internationialization. */ public final String name; /** * Creates a new instance of ElementType. Hidden on purpose. * * @param id The id. * @param name The name. */ protected ElementType(int id, String name) { this.id = id; this.name = name; } /** * Get the name of this ElementType. * * @return The name. */ public String toString() { return name; } /** * Is this a multipoint shape? Hint- all shapes are multipoint except NULL, * UNDEFINED, and the POINTs. * * @return true if multipoint, false otherwise. */ public boolean isMultiPoint() { boolean mp = true; if (this == UNDEFINED) { mp = false; } else if (this == NULL) { mp = false; } else if (this == IGDSDIGITIZER) { mp = false; } else if (this == TCB) { mp = false; } else if (this == LEVELSYMBOLOGY) { mp = false; } return mp; } public boolean isComplexElement() { if (id == 2) { return true; } if (id == 7) { return true; } if (id == 12) { return true; } if (id == 14) { return true; } if (id == 18) { return true; } if (id == 19) { return true; } if (id == 106) { return true; } if (id == 107) { return true; } return false; } public boolean isPointType() { if (id == 7) { return true; } if (id == 17) { return true; } return false; } public boolean isLineType() { if (id == 3) { return true; } if (id == 4) { return true; } if (id == 11) { return true; } if (id == 12) { return true; } if (id == 16) { return true; } return false; } public boolean isPolygonType() { if (id == 6) { return true; } if (id == 14) { return true; } return false; } public boolean isMultiPointType() { if (id == 3) { return true; } if (id == 4) { return true; } if (id == 6) { return true; } if (id == 11) { return true; } if (id == 12) { return true; } if (id == 13) { return true; } if (id == 14) { return true; } if (id == 15) { return true; } if (id == 16) { return true; } if (id == 22) { return true; } return false; } /** * Determine the ElementType for the id. * * @param id The id to search for. * @return The ElementType for the id. */ public static ElementType forID(int id) { ElementType t; switch (id) { case 0 : t = NULL; break; case 3 : t = LINE; break; case 4 : t = LINESTRING; break; case 6 : t = SHAPE; break; case 7 : t = TEXTNODE; break; case 8 : t = IGDSDIGITIZER; break; case 9 : t = TCB; break; case 10 : t = LEVELSYMBOLOGY; break; case 12 : t = COMPLEXCHAIN; break; case 14 : t = COMPLEXSHAPE; break; case 15 : t = ELLIPSE; break; case 16 : t = ARC; break; case 17 : t = TEXT; break; default : t = UNDEFINED; break; } return t; } public IElementHandler getElementHandler() throws Dgn7fileException { IElementHandler handler; switch (id) { case 3 : handler = LineElement.ElementHandler.getInstance(); break; case 4 : handler = LineStringElement.ElementHandler.getInstance(); break; case 6 : handler = ShapeElement.ElementHandler.getInstance(); break; case 7 : handler = TextNodeElement.ElementHandler.getInstance(); break; case 8 : handler = new Element.ElementHandler(this); break; case 9 : handler = new Element.ElementHandler(this); break; case 10 : handler = new Element.ElementHandler(this); break; case 12 : handler = ComplexChainElement.ElementHandler.getInstance(); break; case 14 : handler = ComplexShapeElement.ElementHandler.getInstance(); break; case 15 : handler = new Element.ElementHandler(this); break; case 16 : handler = ArcElement.ElementHandler.getInstance(); break; case 17 : handler = TextElement.ElementHandler.getInstance(); break; default : handler = null; } return handler; } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java
New file @@ -0,0 +1,71 @@ package com.ximple.io.dgn7; /** * FrammeAttributeData * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 06:36:55 */ public class FrammeAttributeData extends UserAttributeData { public FrammeAttributeData(short id) { super(id, 7); } public FrammeAttributeData(short[] src) { super(src); } public short getFsc() { int fsc = _src[3] & 0x0000ffff; return (short) fsc; } public int getUfid() { int ufid = (int) (_src[2] << 16 & 0xffff0000); ufid += _src[1] & 0x0000ffff; return ufid; } public byte getComponentID() { int cmpid = (int) (_src[5] & 0x000000ff); return (byte) cmpid; } public byte getRuleNo() { int no = (int) ((_src[5] >> 8) & 0x000000ff); return (byte) no; } public short getStatus() { int status = (int) (_src[4] & 0x0000ffff); return (short) status; } public short getOccID() { int occid = (int) (_src[6] & 0x0000ffff); return (short) occid; } public String toString() { return "FrammeData{" + getFsc() + "," + getUfid() + "," + getComponentID() + "," + getRuleNo() + "," + getStatus() + "," + getOccID() + "}"; } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java
New file @@ -0,0 +1,18 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * GeometryConverter * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 11:38:57 */ public interface GeometryConverter { public Geometry toGeometry(GeometryFactory factory); } ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java
New file @@ -0,0 +1,23 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.nio.ByteBuffer; /** * IElementHandler * * @author Ulysses * @version 0.1 * @since 2006/5/17 ¤U¤È 01:50:26 */ public interface IElementHandler { public ElementType getElementType(); public Object read(ByteBuffer buffer, short signature, int length); public void write(ByteBuffer buffer, Object element); public int getLength(Object element); } ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java
New file @@ -0,0 +1,129 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * LineElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 11:34:59 */ public class LineElement extends Element implements GeometryConverter { public LineElement(short[] raw) { super(raw); } public Coordinate getCentroid(double dTolerance) { return null; } public Coordinate getEndPoint() { int endX = (int) ((raw[22] << 16) & 0xffff0000); endX = endX + (raw[23] & 0x0000ffff); double x = Utility.ConverUnitToCoord(endX); int endY = (int) ((raw[24] << 16) & 0xffff0000); endY = endY + (raw[25] & 0x0000ffff); double y = Utility.ConverUnitToCoord(endY); return new Coordinate(x, y); } public Coordinate getNormal() { return null; } public Coordinate getOrigin() { return null; } public Coordinate getStartPoint() { int startX = (int) ((raw[18] << 16) & 0xffff0000); startX = startX + (raw[19] & 0x0000ffff); double x = Utility.ConverUnitToCoord(startX); int startY = (int) ((raw[20] << 16) & 0xffff0000); startY = startY + (raw[21] & 0x0000ffff); double y = Utility.ConverUnitToCoord(startY); return new Coordinate(x, y); } public Coordinate getVertex(int index) { return (index == 0) ? getStartPoint() : getEndPoint(); } public double getLength() { Coordinate p1 = getStartPoint(); Coordinate p2 = getEndPoint(); return Utility.getLength(p1.x, p1.y, p2.x, p2.y); } public Coordinate pointAtDistance(double dDistance, double dTolerance) { return null; } public Coordinate[] getVertices() { Coordinate[] result = new Coordinate[2]; result[0] = getStartPoint(); result[1] = getEndPoint(); return result; } public Geometry toGeometry(GeometryFactory factory) { return factory.createLineString(getVertices()); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.LINE); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new LineElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java
New file @@ -0,0 +1,166 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * LineStringElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 02:48:58 */ public class LineStringElement extends Element implements GeometryConverter { public LineStringElement(short[] raw) { super(raw); } public Coordinate getCentroid(double dTolerance) { return null; } public Coordinate getEndPoint() { return new Coordinate(getX(getVerticeSize() - 1), getY(getVerticeSize() - 1)); } public Coordinate getNormal() { return null; } public Coordinate getOrigin() { return null; } public Coordinate getStartPoint() { return new Coordinate(getX(0), getY(0)); } public Coordinate getVertex(int index) { return (index == 0) ? getStartPoint() : getEndPoint(); } public int getVerticeSize() { return raw[18] & 0x0000ffff; } public double getLength() { double result = 0.0; Coordinate[] vset = getVertices(); for (int i = 1; i < getVerticeSize(); i++) { Coordinate p1 = vset[i - 1]; Coordinate p2 = vset[i]; result += Utility.getLength(p1.x, p1.y, p2.x, p2.y); } return result; } public Coordinate pointAtDistance(double dDistance, double dTolerance) { return null; } public Coordinate[] getVertices() { Coordinate[] result = new Coordinate[getVerticeSize()]; for (int i = 0; i < getVerticeSize(); i++) { result[i] = new Coordinate(getX(i), getY(i)); } return result; } public Geometry toGeometry(GeometryFactory factory) { return factory.createLineString(getVertices()); } protected double getX(int index) { if ((index < 0) || (index > getVerticeSize())) { return -1; } int x = (int) ((raw[19 + (4 * index)] << 16) & 0xffff0000); x += (int) (raw[20 + (4 * index)] & 0x0000ffff); return Utility.ConverUnitToCoord(x); } protected void setX(int index, double dx) { int newVal = Utility.ConverCoordToUnit(dx); raw[19 + (4 * index)] = (short) (newVal >> 16 & 0x0000ffff); raw[20 + (4 * index)] = (short) (newVal & 0x0000ffff); } protected double getY(int index) { if ((index < 0) || (index > getVerticeSize())) { return -1; } int y = (int) ((raw[21 + (4 * index)] << 16) & 0xffff0000); y = y + (int) (raw[22 + (4 * index)] & 0x0000ffff); return Utility.ConverUnitToCoord(y); } protected void setY(int index, double dy) { int newVal = Utility.ConverCoordToUnit(dy); raw[21 + (4 * index)] = (short) ((newVal >> 16) & 0x0000ffff); raw[22 + (4 * index)] = (short) (newVal & 0x0000ffff); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.LINESTRING); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new LineStringElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java
New file @@ -0,0 +1,263 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; /** * Lock * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 10:27:24 */ public class Lock { Logger logger = LogManager.getLogger("com.ximple.io.dgn7"); /** * indicates a write is occurring */ int writeLocks = 0; /** * if not null a writer is waiting for the lock or is writing. */ Thread writer; /** * Thread->Owner map. If empty no read locks exist. */ Map owners = new HashMap(); /** * If the lock can be read locked the lock will be read and default * visibility for tests * * @return * @throws java.io.IOException */ synchronized boolean canRead() throws IOException { if ((writer != null) && (writer != Thread.currentThread())) { return false; } if (writer == null) { return true; } if (owners.size() > 1) { return false; } return true; } /** * If the lock can be read locked the lock will be read and default * visibility for tests * * @return * @throws IOException */ synchronized boolean canWrite() throws IOException { if (owners.size() > 1) { return false; } if ((canRead()) && ((writer == Thread.currentThread()) || (writer == null))) { if (owners.isEmpty()) { return true; } if (owners.containsKey(Thread.currentThread())) { return true; } } return false; } /** * Called by shapefileReader before a read is started and before an IOStream * is openned. * * @throws IOException */ public synchronized void lockRead() throws IOException { if (!canRead()) { while ((writeLocks > 0) || (writer != null)) { try { wait(); } catch (InterruptedException e) { throw(IOException) new IOException().initCause(e); } } } assertTrue("A write lock exists that is owned by another thread", canRead()); Thread current = Thread.currentThread(); Owner owner = (Owner) owners.get(current); if (owner != null) { owner.timesLocked++; } else { owner = new Owner(current); owners.put(current, owner); } logger.debug("Start Read Lock:" + owner); } private void assertTrue(String message, boolean b) { if (!b) { throw new AssertionError(message); } } /** * Called by ShapefileReader after a read is complete and after the IOStream * is closed. */ public synchronized void unlockRead() { assertTrue("Current thread does not have a readLock", owners.containsKey(Thread.currentThread())); Owner owner = (Owner) owners.get(Thread.currentThread()); assertTrue("Current thread has " + owner.timesLocked + "negative number of locks", owner.timesLocked > 0); owner.timesLocked--; if (owner.timesLocked == 0) { owners.remove(Thread.currentThread()); } notifyAll(); logger.debug("unlock Read:" + owner); } /** * Called by ShapefileDataStore before a write is started and before an * IOStream is openned. * * @throws IOException */ public synchronized void lockWrite() throws IOException { Thread currentThread = Thread.currentThread(); if (writer == null) { writer = currentThread; } while (!canWrite()) { try { wait(); } catch (InterruptedException e) { throw(IOException) new IOException().initCause(e); } if (writer == null) { writer = currentThread; } } if (writer == null) { writer = currentThread; } assertTrue("The current thread is not the writer", writer == currentThread); assertTrue("There are read locks not belonging to the current thread.", canRead()); writeLocks++; logger.debug(currentThread.getName() + " is getting write lock:" + writeLocks); } /** * default visibility for tests */ synchronized int getReadLocks(Thread thread) { Owner owner = (Owner) owners.get(thread); if (owner == null) { return -1; } return owner.timesLocked; } public synchronized void unlockWrite() { if (writeLocks > 0) { assertTrue("current thread does not own the write lock", writer == Thread.currentThread()); assertTrue("writeLock has already been unlocked", writeLocks > 0); writeLocks--; if (writeLocks == 0) { writer = null; } } logger.debug("unlock write:" + Thread.currentThread().getName()); notifyAll(); } /** * default visibility for tests */ synchronized boolean ownWriteLock(Thread thread) { return (writer == thread) && (writeLocks > 0); } private class Owner { final Thread owner; int timesLocked; Owner(Thread owner) { this.owner = owner; timesLocked = 1; } public String toString() { return owner.getName() + " has " + timesLocked + " locks"; } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java
New file @@ -0,0 +1,114 @@ package com.ximple.io.dgn7; /* * GeoTools - OpenSource mapping toolkit * http://geotools.org * (C) 2003-2006, Geotools Project Managment Committee (PMC) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. */ // J2SE dependencies import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; /** * Utility class for managing memory mapped buffers. * * @since 2.0 * @source $URL$ * @version $Id$ * @author Andres Aimes */ public class NIOUtilities { /** * {@code true} if a warning has already been logged. */ private static boolean warned = false; /** * Do not allows instantiation of this class. * * @todo This constructor will become private when {@code NIOBufferUtils} * will have been removed. */ protected NIOUtilities() { } /** * Really closes a {@code MappedByteBuffer} without the need to wait for garbage * collection. Any problems with closing a buffer on Windows (the problem child in this * case) will be logged as {@code SEVERE} to the logger of the package name. To * force logging of errors, set the System property "org.geotools.io.debugBuffer" to "true". * * @param buffer The buffer to close. * @return true if the operation was successful, false otherwise. * * @see java.nio.MappedByteBuffer */ public static boolean clean(final ByteBuffer buffer) { if (buffer == null || ! buffer.isDirect() ) { return false; } Boolean b = (Boolean) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { Boolean success = Boolean.FALSE; try { Method getCleanerMethod = buffer.getClass().getMethod("cleaner", (Class[])null); getCleanerMethod.setAccessible(true); Object cleaner = getCleanerMethod.invoke(buffer, (Object[])null); Method clean = cleaner.getClass().getMethod("clean", (Class[])null); clean.invoke(cleaner, (Object[])null); success = Boolean.TRUE; } catch (Exception e) { // This really is a show stopper on windows if (isLoggable()) { log(e, buffer); } } return success; } }); return b.booleanValue(); } /** * Check if a warning message should be logged. */ private static synchronized boolean isLoggable() { try { return !warned && ( System.getProperty("org.geotools.io.debugBuffer", "false").equalsIgnoreCase("true") || System.getProperty("os.name").indexOf("Windows") >= 0 ); } catch (SecurityException exception) { // The utilities may be running in an Applet, in which case we // can't read properties. Assumes we are not in debugging mode. return false; } } /** * Log a warning message. */ private static synchronized void log(final Exception e, final ByteBuffer buffer) { warned = true; String message = "Error attempting to close a mapped byte buffer : " + buffer.getClass().getName() + "\n JVM : " + System.getProperty("java.version") + ' ' + System.getProperty("java.vendor"); Logger.getLogger("org.geotools.io").log(Level.SEVERE, message, e); } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java
New file @@ -0,0 +1,56 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LinearRing; /** * ShapeElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 03:08:43 */ public class ShapeElement extends LineStringElement implements GeometryConverter { public ShapeElement(short[] raw) { super(raw); } public Geometry toGeometry(GeometryFactory factory) { LinearRing ring = factory.createLinearRing(this.getVertices()); return ring; // return factory.createPolygon(ring, null); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.SHAPE); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new ShapeElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java
New file @@ -0,0 +1,45 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import org.apache.log4j.LogManager; import org.apache.log4j.Logger; /** * StreamLogging * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 10:31:08 */ public class StreamLogging { private static final Logger LOGGER = LogManager.getLogger("com.ximple.io.dgn7"); private String name; private int open = 0; /** * The name that will appear in the debug message * * @param name */ public StreamLogging(String name) { this.name = name; } /** * Call when reader or writer is opened */ public synchronized void open() { open++; LOGGER.debug(name + " has been opened. Number open: " + open); } public synchronized void close() { open--; LOGGER.debug(name + " has been closed. Number open: " + open); } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java
New file @@ -0,0 +1,90 @@ package com.ximple.io.dgn7; /** * TcbElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 05:03:46 */ public class TcbElement extends Element { public TcbElement(short[] raw) { super(raw); } public boolean is2D() { int dimension = (int) (raw[607] & 0x00000004); if (dimension == 0) { return true; } else { return false; } } public String getMasterUnitName() { byte[] master = new byte[1]; master[0] = (byte) (raw[560] & 0x00ff); java.nio.charset.Charset.forName("US-ASCII"); // ASCIIEncoding encode = new ASCIIEncoding(); StringBuffer sb = new StringBuffer(); sb.append((char) master[0]); // return encode.GetString(master); return sb.toString(); } public String getSubUnitName() { byte[] sub = new byte[2]; sub[0] = (byte) (raw[561] & 0x00ff); sub[1] = (byte) (raw[561] >> 8 & 0x00ff); StringBuffer sb = new StringBuffer(); sb.append((char) sub[0]); sb.append((char) sub[0]); return sb.toString(); } public int getGraphicGroup() { return (int) (raw[594] & 0x0000ffff); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.TCB); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new TcbElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java
New file @@ -0,0 +1,296 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * TextElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤W¤È 11:45:29 */ public class TextElement extends Element implements GeometryConverter { public static final int ED_CENTERJUSTIFICATION = 0; // Enter data field center justification public static final int ED_LEFTJUSTIFICATION = 0; // Enter data field left justification public static final int ED_RIGHTJUSTIFICATION = 0; // Enter data field right justification public static final int TXTJUST_CB = 0; // Center/bottom text justification. public static final int TXTJUST_CC = 0; // Center/center text justification. public static final int TXTJUST_CT = 0; // Center/top text justification. public static final int TXTJUST_LB = 0; // Left/bottom text justification. public static final int TXTJUST_LC = 0; // Left/center text justification. public static final int TXTJUST_LT = 0; // Left/top text justification. public static final int TXTJUST_RB = 0; // Right/bottom text justification. public static final int TXTJUST_RC = 0; // Right/center text justification. public static final int TXTJUST_RT = 0; public TextElement(short[] raw) { super(raw); } public Coordinate getOrigin() { int x = (int) (raw[25] << 16 & 0xffff0000); x += raw[26] & 0x0000ffff; double dx = Utility.ConverUnitToCoord(x); int y = (int) (raw[27] << 16 & 0xffff0000); y += raw[28] & 0x0000ffff; double dy = Utility.ConverUnitToCoord(y); return new Coordinate(dx, dy); } public Coordinate getUserOrigin() { Coordinate origin = getOrigin(); double x = origin.x; double weight = getUserSetWeight(); double height = getUserSetHeight(); double angle = Utility.ConverRotationToRadian(getRotationAngle()); x += weight * Math.cos(angle) - height * Math.sin(angle); double y = origin.y; y += weight * Math.cos(angle) - height * Math.sin(angle); return new Coordinate(x, y); } private double getUserSetWeight() { int just = getJustification(); Envelope range = getRange(); double weight = (range.getWidth()); switch (just) { case 0 : case 1 : case 2 : weight = 0; break; case 6 : case 7 : case 8 : weight = weight / 2; break; case 12 : case 13 : case 14 : break; } return weight; } private double getUserSetHeight() { int just = getJustification(); double height = getTextHeight(); switch (just) { case 2 : case 8 : case 14 : // bottom height = 0; break; case 1 : case 7 : case 13 : // center height = height / 2; break; case 0 : case 6 : case 12 : // height break; } return height; } public int getFontIndex() { return (int) raw[18] & 0x00000000ff; } public boolean hasSlant() { return true; } public boolean hasUnderline() { return true; } public boolean isFixedWidthSpacing() { return true; } public boolean isPlanar() { return true; } public boolean isVertical() { return true; } public double getTextHeight() { int height = (int) ((raw[21] << 16) & 0xffff0000); height += raw[22] & 0x0000ffff; return Utility.ConverIntToDouble(height); } public double getTextWidth() { int length = (int) (raw[19] << 16 & 0xffff0000); length += raw[20] & 0x0000ffff; return Utility.ConverIntToDouble(length); } public int getJustification() { return (int) ((raw[18] >>> 8) & 0x00000000ff); } public double getRotationAngle() { int totation = (int) ((raw[23] << 16) & 0xffff0000); totation += raw[24] & 0x0000ffff; return Utility.ConverIntToRotation(totation); } public boolean isChinese() { int isChinese = raw[30] & 0x0000ffff; if (isChinese == 0xfdff) { return true; } else { return false; } } public int getTextLength() { int num = raw[29]; if (isChinese()) { num = (num / 2) - 1; } return num; } public String getText() { StringBuffer val = new StringBuffer(); char[] temp; int num = getTextLength(); if (!isChinese()) { temp = new char[num]; for (int i = 0; i < temp.length; i++) { if ((i % 2) == 0) { temp[i] = (char) (raw[30 + (int) (i / 2)] & (short) 0x00ff); } else { temp[i] = (char) ((raw[30 + (int) (i / 2)] >> 8) & (short) 0x00ff); } val.append(temp[i]); } } return val.toString(); } public Geometry toGeometry(GeometryFactory factory) { return factory.createPoint(getUserOrigin()); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.TEXT); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new TextElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java
New file @@ -0,0 +1,291 @@ package com.ximple.io.dgn7; //~--- JDK imports ------------------------------------------------------------ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * TextNodeElement * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 04:02:58 */ public class TextNodeElement extends Element implements ComplexElement, GeometryConverter { ArrayList list = new ArrayList(); public TextNodeElement(short[] raw) { super(raw); } public int size() { return list.size(); } public boolean isEmpty() { return list.isEmpty(); } public boolean contains(Object o) { return list.contains(o); } public Iterator iterator() { return list.iterator(); } public Object[] toArray() { return list.toArray(); } public boolean add(Object o) { return list.add(o); } public boolean remove(Object o) { return list.remove(o); } public boolean addAll(Collection c) { return list.addAll(c); } public boolean addAll(int index, Collection c) { return list.addAll(index, c); } public void clear() { list.clear(); } public Object get(int index) { return list.get(index); } public Object set(int index, Object element) { return list.set(index, element); } public void add(int index, Object element) { list.add(index, element); } public Object remove(int index) { return list.remove(index); } public int indexOf(Object o) { return list.indexOf(o); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator listIterator() { return list.listIterator(); } public ListIterator listIterator(int index) { return list.listIterator(index); } public List subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } public boolean retainAll(Collection c) { return list.retainAll(c); } public boolean removeAll(Collection c) { return list.removeAll(c); } public boolean containsAll(Collection c) { return list.containsAll(c); } public Object[] toArray(Object[] a) { return list.toArray(a); } public String[] getTextArray() { ArrayList list = new ArrayList(); for (ListIterator it = listIterator(); it.hasNext(); ) { Element element = (Element) it.next(); if (element instanceof TextElement) { list.add(((TextElement) element).getText()); } } return (String[]) list.toArray(new String[list.size()]); } public Geometry toGeometry(GeometryFactory factory) { /* * CoordinateList coords = new CoordinateList(); * for (ListIterator it = listIterator(); it.hasNext(); ) * { * Element element = (Element) it.next(); * if (element instanceof TextElement) * { * coords.add(((TextElement) element).getUserOrigin()); * } * } */ return factory.createPoint(getOrigin()); // return factory.createMultiPoint(coords.toCoordinateArray()); } public int getNumString() { return (int) (raw[19] & 0x0000ffff); } public int getNodeNumber() { return (int) (raw[20] & 0x0000ffff); } public int getMaxLength() { return (int) (raw[21] & 0x00ff); } public int getMaxUsed() { return (int) ((raw[21] >> 8) & 0x00ff); } public int getJustification() { return (int) ((raw[22] >> 8) & 0x00ff); } public int getFontIndex() { return (int) (raw[22] & 0x00ff); } public double getLineSpacing() { int lineSpace; lineSpace = (int) ((raw[23] << 16) & 0xffff0000); lineSpace += (raw[24] & 0x0000ffff); return lineSpace; } public double getTextNodeLength() { int lengthMult = -1; lengthMult = (int) ((raw[25] << 16) & 0xffff0000); lengthMult += (raw[26] & 0x0000ffff); return Utility.ConverIntToDouble(lengthMult); } public double getTextNodeHeight() { int heightMult = -1; heightMult = (int) ((raw[27] << 16) & 0xffff0000); heightMult += (raw[28] & 0x0000ffff); return Utility.ConverIntToDouble(heightMult); } public double getRotationAngle() { int rotation = (int) (raw[29] << 16 & 0xffff0000); rotation += raw[30]; return Utility.ConverIntToRotation(rotation); } public Coordinate getOrigin() { int x = (int) ((raw[31] << 16) & 0xffff0000); x += raw[32] & 0x0000ffff; // return Utility.ConvertFromDGN(x); double dx = Utility.ConverUnitToCoord(x); int y = (int) ((raw[33] << 16) & 0xffff0000); y += (raw[34] & 0x0000ffff); double dy = Utility.ConverUnitToCoord(y); return new Coordinate(dx, dy); } public static class ElementHandler extends Element.ElementHandler { private static ElementHandler instance = null; public ElementHandler() { super(ElementType.TEXTNODE); } public static IElementHandler getInstance() { if (instance == null) { instance = new ElementHandler(); } return instance; } protected Element createElement(short[] raw) { return new TextNodeElement(raw); } } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java
New file @@ -0,0 +1,34 @@ package com.ximple.io.dgn7; /** * UserAttributeData * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 02:29:29 */ public class UserAttributeData { protected short[] _src; public UserAttributeData(short id, int attributeCount) { _src = new short[attributeCount]; _src[0] = id; } public UserAttributeData(short[] src) { _src = src; } public short getID() { return _src[0]; } public void setID(short value) { _src[0] = value; } } ximple-dgnio/src/main/java/com/ximple/io/dgn7/Utility.java
New file @@ -0,0 +1,238 @@ package com.ximple.io.dgn7; //~--- non-JDK imports -------------------------------------------------------- import com.vividsolutions.jts.geom.Envelope; /** * Utility * * @author Ulysses * @version 0.1 * @since 2006/5/18 ¤U¤È 01:33:00 */ public final class Utility { public static double ConverIntToDouble(int src) { double newVal = (double) ((long) ((src * 6) / 1000.0 + 0.5)) / 1000.0; // ?[0.5?O?¢X?F?|¡Ó????J return newVal; } public static int ConverDoubleToInt(double src) { int newVal = (int) (src / 6 * 1000000.0); return newVal; } public static int ConvertFromDGN(int aValue) { int newVal = 0; newVal = (((aValue ^ 0x00008000) << 16) & 0xffff0000); newVal += (aValue >>> 16) & 0x0000ffff; return newVal; } public static int ConverToDGN(int aValue) { int newVal = 0; newVal = (aValue << 16 & 0xffff0000); newVal += (((aValue ^ 0x80000000) >>> 16) & 0x0000ffff); return newVal; } public static double ConverIntToRotation(int aValue) { double newVal = aValue / 360000.0; if (newVal > 0) { newVal = (int) (newVal + 0.5); } else { newVal = (int) (newVal - 0.5); } return newVal; } public static int ConverRotatioToInt(double aValue) { int newVal = (int) (aValue * 360000.0); return newVal; } public static double ConverRotationToRadian(double aValue) { double newVal = aValue * Math.PI / 180; return newVal; } public static double ConverUnitToCoord(int aValue) { double newVal = 0; newVal = aValue / 1000.0; newVal += 2147483.648; // 2147483.648 = 2 ^ 31 return newVal; } public static int ConverCoordToUnit(double aValue) { double newVal = aValue; newVal -= 2147483.648; newVal = newVal * 1000.0; return (int) newVal; } public static Envelope ConverUnitToCoord(Envelope range) { if (range == null) { return null; } Envelope newRange = new Envelope(ConverUnitToCoord((int) range.getMinX()), ConverUnitToCoord((int) range.getMaxX()), ConverUnitToCoord((int) range.getMinY()), ConverUnitToCoord((int) range.getMaxY())); return newRange; } public static Envelope ConverCoordToUnit(Envelope range) { if (range == null) { return null; } Envelope newRange = new Envelope(ConverCoordToUnit(range.getMinX()), ConverCoordToUnit(range.getMaxX()), ConverCoordToUnit(range.getMinY()), ConverCoordToUnit(range.getMaxY())); return newRange; } public static double DGNToIEEEDouble(short[] src) { int[] tmp = new int[2]; long des = 0; int sign; int exponent; int rndbits; if (src == null) { throw new RuntimeException("Source short array is null"); } tmp[0] = (int) ((src[0] << 16) & 0xffff0000) | (src[1] & 0x0000ffff); // ¢X????? tmp[1] = (int) ((src[2] << 16) & 0xffff0000) | (src[3] & 0x0000ffff); // ¡±C???? sign = (int) (tmp[0] & 0x80000000); exponent = (tmp[0] >>> 23) & 0x000000ff; if (exponent != 0) { exponent = exponent - 129 + 1023; } rndbits = tmp[1] & 0x00000007; tmp[1] = tmp[1] >>> 3; tmp[1] = (tmp[1] & 0x1fffffff) | (tmp[0] << 29); if (rndbits != 0) { tmp[1] = tmp[1] | 0x00000001; } tmp[0] = (tmp[0] >>> 3) & 0x000fffff; tmp[0] = tmp[0] | (exponent << 20) | sign; des = (((long) tmp[0] << 32)); des = des | (long) tmp[1] & 0x00000000ffffffff; return Double.longBitsToDouble(des); } public static short[] IEEEDoubleToDGN(double src) { long newVal = Double.doubleToLongBits(src); // uint[] tmp = new int[ 2 ]; // ushort[] des = new short[ 4 ]; int[] tmp = new int[2]; short[] des = new short[4]; int sign; int exponent; tmp[0] = (int) ((newVal >>> 32) & 0x0ffffffff); tmp[1] = (int) (newVal & 0x0ffffffff); // sign = ( int ) ( ( uint ) tmp[ 0 ] & 0x80000000 ); sign = (int) tmp[0] & 0x80000000; exponent = (tmp[0] >>> 20) & 0x07ff; if (exponent != 0) { exponent = exponent - 1023 + 129; } if (exponent > 255) { if (sign != 0) { des[0] = -1; } else { des[0] = 0x7fff; } des[1] = -1; des[2] = -1; des[3] = -1; return des; } else if ((exponent < 0) || ((exponent == 0) && (sign == 0))) { des[0] = 0x0; des[1] = 0x0; des[2] = 0x0; des[3] = 0x0; return des; } else { tmp[0] = (tmp[0] << 3) | (tmp[1] >> 29); tmp[0] = tmp[0] & 0x007fffff; tmp[0] = tmp[0] | (exponent << 23) | sign; // changed by phil 07/05/2004 // tmp[ 1 ] = tmp[ 1 ] >> 3; tmp[1] = tmp[1] << 3; } des[0] = (short) ((tmp[0] >>> 16) & 0x0000ffff); des[1] = (short) (tmp[0] & 0x0000ffff); des[2] = (short) ((tmp[1] >>> 16) & 0x0000ffff); des[3] = (short) (tmp[1] & 0x0000ffff); return des; } public static double getLength(double x1, double y1, double x2, double y2) { double dx = x1 - x2; double dy = y1 - y2; double length = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); return length; } } ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java
New file Diff too large