From b6a392076f6cae23014baebd1945f9496cd48e1a Mon Sep 17 00:00:00 2001
From: ?? ? <ulysseskao@ximple.com.tw>
Date: Wed, 03 Sep 2008 10:11:17 +0800
Subject: [PATCH] update for EOFM-161

---
 xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java                                         |    1 
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java                                              |   26 +
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TagElement.java                                               |   46 ++
 xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementFetcher.java                                        |  507 +++++++++++++++++++++++++++++++
 xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java                              |   41 ++
 .gitattributes                                                                                                       |    2 
 xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2PostGISJob.java                      |   17 
 xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java |  284 ++++++++++++++++-
 8 files changed, 883 insertions(+), 41 deletions(-)

diff --git a/.gitattributes b/.gitattributes
index 926347c..0ad992e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -26,6 +26,7 @@
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java svneol=native#text/plain
+xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TagElement.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java svneol=native#text/plain
 xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java svneol=native#text/plain
@@ -42,6 +43,7 @@
 xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88494_0.dgn -text
 xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/testHV.dgn -text
 xdgnjobs/ximple-elmparser/pom.xml svneol=native#text/xml
+xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementFetcher.java svneol=native#text/plain
 xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java svneol=native#text/plain
 xdgnjobs/ximple-elmparser/src/main/resources/com/ximple/eofms/XElementParser.properties svneol=native#text/plain
 xdgnjobs/ximple-elmparser/src/main/resources/com/ximple/eofms/XElementParser_zh_TW.properties svneol=native#text/plain
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
index 5612e7a..8541156 100644
--- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
@@ -111,39 +111,44 @@
     public static final ElementType TCB = new ElementType(9, "Tcb");
 
     /**
-     * Represents a LevelSymbology shape (id = 5).
+     * Represents a LevelSymbology shape (id = 10).
      */
     public static final ElementType LEVELSYMBOLOGY = new ElementType(10, "LevelSymbology");
 
     /**
-     * Represents a ComplexChain shape (id = 15).
+     * Represents a ComplexChain shape (id = 12).
      */
     public static final ElementType COMPLEXCHAIN = new ElementType(12, "ComplexChain");
 
     /**
-     * Represents a ComplexShape shape (id = 25).
+     * Represents a ComplexShape shape (id = 12).
      */
     public static final ElementType COMPLEXSHAPE = new ElementType(14, "ComplexShape");
 
     /**
-     * Represents a Ellipse shape (id = 8).
+     * Represents a Ellipse shape (id = 15).
      */
     public static final ElementType ELLIPSE = new ElementType(15, "Ellipse");
 
     /**
-     * Represents a Arc shape (id = 28).
+     * Represents a Arc shape (id = 16).
      */
     public static final ElementType ARC = new ElementType(16, "Arc");
 
     /**
-     * Represents a Arc shape (id = 28).
+     * Represents a Text shape (id = 17).
      */
     public static final ElementType TEXT = new ElementType(17, "Text");
 
     /**
-     * Represents a Arc shape (id = 28).
+     * Represents a PointString shape (id = 22).
      */
     public static final ElementType POINTSTRING = new ElementType(22, "PointString");
+
+    /**
+     * Represents a Tag shape (id = 28).
+     */
+    public static final ElementType TAG = new ElementType(37, "Tag");
 
     /**
      * Represents an Undefined shape (id = -1).
@@ -314,6 +319,9 @@
             t = TEXT;
             break;
 
+        case 37:
+            t = TAG;
+
         default:
             t = UNDEFINED;
             break;
@@ -376,6 +384,10 @@
             handler = TextElement.ElementHandler.getInstance();
             break;
 
+        case 37:
+            handler = TagElement.ElementHandler.getInstance();
+            break;
+
         default:
             handler = null;
         }
diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TagElement.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TagElement.java
new file mode 100644
index 0000000..13a3f3a
--- /dev/null
+++ b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TagElement.java
@@ -0,0 +1,46 @@
+package com.ximple.io.dgn7;
+
+import org.apache.log4j.Logger;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+public class TagElement extends Element implements GeometryConverter
+{
+    private static final Logger logger = Logger.getLogger(TagElement.class);
+
+    public TagElement(byte[] raw)
+    {
+        super(raw);
+    }
+
+    public Geometry toGeometry(GeometryFactory factory)
+    {
+        return null;
+    }
+
+    public static class ElementHandler extends Element.ElementHandler
+    {
+        private static ElementHandler instance = null;
+
+        public ElementHandler()
+        {
+            super(ElementType.TAG);
+        }
+
+        public static IElementHandler getInstance()
+        {
+            if (instance == null)
+            {
+                instance = new ElementHandler();
+            }
+
+            return instance;
+        }
+
+        protected Element createElement(byte[] raw)
+        {
+            return new TagElement(raw);
+        }
+    }
+}
diff --git a/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementFetcher.java b/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementFetcher.java
new file mode 100644
index 0000000..5e6ec32
--- /dev/null
+++ b/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementFetcher.java
@@ -0,0 +1,507 @@
+package com.ximple.eofms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.MalformedURLException;
+import java.net.URL;
+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.sql.Types;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import org.apache.commons.collections.OrderedMap;
+import org.apache.commons.collections.OrderedMapIterator;
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.commons.collections.map.MultiValueMap;
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.xmlrules.DigesterLoader;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.geotools.data.Transaction;
+import org.geotools.data.oracle.OracleDataStore;
+import org.geotools.data.oracle.OracleDataStoreFactory;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.util.Assert;
+
+import oracle.sql.BLOB;
+
+import com.ximple.eofms.filter.ElementDispatcher;
+import com.ximple.eofms.jobs.context.postgis.FeatureDgnConvertPostGISJobContext;
+import com.ximple.eofms.jobs.OracleElementLogger;
+import com.ximple.io.dgn7.ComplexElement;
+import com.ximple.io.dgn7.Dgn7fileException;
+import com.ximple.io.dgn7.Element;
+import com.ximple.io.dgn7.ElementType;
+import com.ximple.io.dgn7.IElementHandler;
+import com.ximple.io.dgn7.ArcElement;
+import com.ximple.io.dgn7.ComplexChainElement;
+import com.ximple.util.PrintfFormat;
+
+public class XElementFetcher implements Runnable
+{
+    /**
+     * The Oracle driver class name
+     */
+    private static final String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver";
+    private static final String ORAHOST = "ORAHOST";
+    private static final String ORAINST = "ORAINST";
+    private static final String ORAPORT = "ORAPORT";
+    private static final String ORAUSER = "ORAUSER";
+    private static final String ORAPASS = "ORAPASS";
+    private static final String ORGSCHEMA = "ORGSCHEMA";
+    private static final String DATAPATH = "DATAPATH";
+
+    private static final int FETCHSIZE = 30;
+    private static final int COMMITSIZE = 100;
+    private static final int MAXELM_LOGCOUNT = 6000;
+
+    private static final String FETCHLOGGER_PREFIX = "XFE_";
+
+    static Log logger = LogFactory.getLog(XElementFetcher.class);
+    static final GeometryFactory geometryFactory = new GeometryFactory();
+
+    static final boolean isCompactMode = true;
+    static OracleDataStoreFactory dataStoreFactory = new OracleDataStoreFactory();
+
+    protected static class Pair
+    {
+        Object first;
+        Object second;
+
+        public Pair(Object first, Object second)
+        {
+            this.first = first;
+            this.second = second;
+        }
+    }
+
+    private HashMap<String, String> dataConfig;
+    private ElementDispatcher elementDispatcher;
+    private MultiValueMap featuresContext = new MultiValueMap();
+    private boolean driverFound = true;
+
+    public static void main(String[] args)
+    {
+        XElementFetcher fetcher = new XElementFetcher();
+        fetcher.run();
+    }
+
+    public XElementFetcher()
+    {
+        initializeDataConfig();
+        try
+        {
+            Class.forName(JDBC_DRIVER);
+        } catch (Throwable t)
+        {
+            // must be running off dummy jar!
+            driverFound = false;
+        }
+    }
+
+    private void initializeDataConfig()
+    {
+        dataConfig = new HashMap<String, String>();
+        dataConfig.put(DATAPATH, "G:\\Temp\\JobData\\tctpc\\elmout");
+        dataConfig.put(ORAHOST, "192.168.11.200");
+        dataConfig.put(ORAINST, "tctpc");
+        dataConfig.put(ORAPORT, "1521");
+        dataConfig.put(ORAUSER, "spatialdb");
+        dataConfig.put(ORAPASS, "spatialdb000");
+        // dataConfig.put(ORGSCHEMA, "SPATIALDB, CMMS_SPATIALDB");
+        dataConfig.put(ORGSCHEMA, "CMMS_SPATIALDB");
+
+        elementDispatcher = createElementDispatcher();
+    }
+
+    private ElementDispatcher createElementDispatcher()
+    {
+        try
+        {
+            URL rulesURL = ElementDispatcher.class.getResource("ElementDispatcherRules.xml");
+            assert rulesURL != null;
+            Digester digester = DigesterLoader.createDigester(rulesURL);
+            URL filterURL;
+
+            filterURL = FeatureDgnConvertPostGISJobContext.class.getResource("/conf/DefaultConvertShpFilter.xml");
+
+            assert filterURL != null;
+            return (ElementDispatcher) digester.parse(filterURL);
+        } catch (UnsupportedEncodingException e)
+        {
+            logger.info(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        } catch (MalformedURLException e)
+        {
+            logger.info(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        } catch (IOException e)
+        {
+            logger.info(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        } catch (SAXException e)
+        {
+            logger.info(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    public void run()
+    {
+        try
+        {
+            OracleDataStore dataStore = createSourceDataStore();
+            ArrayList<String> schemas = getSchemaNames();
+            for (String schema : schemas)
+            {
+                executeFetchElement(dataStore, schema, dataConfig.get(DATAPATH));
+            }
+        } catch (SQLException e)
+        {
+            logger.error(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    protected OracleDataStore createSourceDataStore()
+    {
+        if (!driverFound)
+        {
+            throw new RuntimeException("Oracle JDBC Driver not found.-" + JDBC_DRIVER);
+        }
+        Map<String, String> map = new TreeMap<String, String>();
+        map.put("host", dataConfig.get(ORAHOST));
+        map.put("port", dataConfig.get(ORAPORT));
+        map.put("instance", dataConfig.get(ORAINST));
+        map.put("user", dataConfig.get(ORAUSER));
+        map.put("passwd", dataConfig.get(ORAPASS));
+        map.put("dbtype", "oracle");
+        map.put("alias", dataConfig.get(ORAINST));
+        map.put("namespace", null);
+        if (!map.containsKey(OracleDataStoreFactory.MAXCONN.key))
+        {
+            map.put(OracleDataStoreFactory.MAXCONN.key, "10");
+        }
+        if (!map.containsKey(OracleDataStoreFactory.MINCONN.key))
+        {
+            map.put(OracleDataStoreFactory.MINCONN.key, "1");
+        }
+
+        if (!dataStoreFactory.canProcess(map))
+        {
+            logger.warn("cannot process properties-");
+            throw new RuntimeException("cannot process properties-");
+        }
+        try
+        {
+            return (OracleDataStore) dataStoreFactory.createDataStore(map);
+        } catch (IOException e)
+        {
+            logger.warn(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    private ArrayList<String> getSchemaNames()
+    {
+        ArrayList<String> result = new ArrayList<String>();
+        String strSchema = dataConfig.get(ORGSCHEMA);
+        StringTokenizer st = new StringTokenizer(strSchema, ",");
+        while (st.hasMoreTokens())
+        {
+            String aSchema = st.nextToken().trim();
+            result.add(aSchema);
+        }
+        return result;
+    }
+
+    protected OrderedMap getBlobStorageList(Connection connection, String schemaSrc, String tableSrc,
+                                            OrderedMap orderedMap) throws SQLException
+    {
+        if (orderedMap == null)
+            orderedMap = new LinkedMap(99);
+        String fetchStmtFmt = "SELECT SNID, SPACETABLE FROM \"%s\".\"%s\"";
+        PrintfFormat spf = new PrintfFormat(fetchStmtFmt);
+        String fetchStmt = spf.sprintf(new Object[]{schemaSrc, tableSrc});
+        Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+        ResultSet rs = null;
+
+        stmt.setFetchSize(FETCHSIZE);
+        try
+        {
+            rs = stmt.executeQuery(fetchStmt);
+            int size = rs.getMetaData().getColumnCount();
+
+            while (rs.next())
+            {
+                Object[] values = new Object[size];
+
+                for (int i = 0; i < size; i++)
+                {
+                    values[i] = rs.getObject(i + 1);
+                }
+
+                Integer key = ((BigDecimal) values[0]).intValue();
+                String name = (String) values[1];
+
+                Pair pair = (Pair) orderedMap.get(key);
+                if (pair == null)
+                    orderedMap.put(key, new Pair(name, null));
+                else
+                    pair.first = name;
+            }
+        } catch (SQLException e)
+        {
+            logger.error(e.toString(), e);
+            logger.error("stmt=" + fetchStmt);
+            throw e;
+        } finally
+        {
+            if (rs != null) rs.close();
+            if (stmt != null) stmt.close();
+        }
+
+        return orderedMap;
+    }
+
+    public Connection getOracleConnection(OracleDataStore dataStore)
+    {
+        try
+        {
+            return dataStore.getConnection(Transaction.AUTO_COMMIT);
+        } catch (IOException e)
+        {
+            logger.warn(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    private void executeFetchElement(OracleDataStore dataStore, String schema, String dataPath) throws SQLException
+    {
+        Connection connection = getOracleConnection(dataStore);
+
+        int order = 0;
+        OrderedMap map = getBlobStorageList(connection, schema, "SD$SPACENODES", null);
+        logger.info("begin fecther job:[" + map.size() + "]");
+
+        int total = map.size(); //spacenodes count
+        int step = total / 100;
+        int current = 0;
+
+        OracleElementLogger elmLogger = createElementLogger(connection, dataPath);
+        elmLogger.setLogPrefix(FETCHLOGGER_PREFIX);
+
+        for (OrderedMapIterator it = map.orderedMapIterator(); it.hasNext();)
+        {
+            it.next();
+
+            Pair pair = (Pair) it.getValue();
+            String tableSrc = (String) pair.first;
+
+            logger.info("begin convert:[" + order + "]-" + tableSrc);
+            queryNFetchIgsetElement(connection, schema, tableSrc, elmLogger);
+
+            order++;
+
+            if ((order % COMMITSIZE) == 0)
+            {
+                elmLogger.flashLogging();
+                System.gc();
+                System.runFinalization();
+            }
+
+            int now = order % step;
+            if (now != current)
+            {
+                current = now;
+            }
+        }
+
+        elmLogger.flashLogging();
+    }
+
+    protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException
+    {
+        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;
+
+        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();
+
+            assert buffer != null;
+            buffer.position(0);
+            raw = buffer.array();
+        } catch (IOException e)
+        {
+            e.printStackTrace();    // To change body of catch statement use File | Settings | File Templates.
+            Assert.shouldNeverReachHere();
+        }
+
+        return raw;
+    }
+
+    private Element fetchBinaryElement(byte[] raws) throws Dgn7fileException
+    {
+        ByteBuffer buffer = ByteBuffer.wrap(raws);
+        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 raws.
+        // track the record location
+        int elementLength = (buffer.getShort() * 2) + 4;
+        ElementType recordType = ElementType.forID(type);
+        IElementHandler handler;
+
+        handler = recordType.getElementHandler();
+
+        Element dgnElement = (Element) handler.read(buffer, signature, elementLength);
+        if (recordType.isComplexElement() && (elementLength < raws.length))
+        {
+            int offset = elementLength;
+            while (offset < (raws.length - 4))
+            {
+                buffer.position(offset);
+                signature = buffer.getShort();
+                type = (byte) ((signature >>> 8) & 0x007f);
+                elementLength = (buffer.getShort() * 2) + 4;
+                if (raws.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) dgnElement).add(subElement);
+                    offset += elementLength;
+                } else
+                {
+                    byte[] remain = new byte[buffer.remaining()];
+                    System.arraycopy(raws, 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;
+                }
+            }
+        }
+
+        return dgnElement;
+    }
+
+    private void queryNFetchIgsetElement(Connection connection, String srcschema, String srctable, OracleElementLogger elmLogger) throws SQLException
+    {
+        String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" ORDER BY ROWID";
+        PrintfFormat spf = new PrintfFormat(fetchSrcStmtFmt);
+        String fetchSrcStmt = spf.sprintf(new Object[]{srcschema, srctable});
+        Statement stmtSrc = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+
+        stmtSrc.setFetchSize(FETCHSIZE);
+        ResultSet rsSrc = stmtSrc.executeQuery(fetchSrcStmt);
+        try
+        {
+            int igdsMetaType = rsSrc.getMetaData().getColumnType(1);
+            while (rsSrc.next())
+            {
+                byte[] raw;
+                if (igdsMetaType == Types.BLOB)
+                {
+                    BLOB blob = (BLOB) rsSrc.getBlob(1);
+
+                    raw = getBytesFromBLOB(blob);
+                    blob.close();
+                } else
+                {
+                    raw = rsSrc.getBytes(1);
+                }
+
+                try
+                {
+                    Element element = fetchBinaryElement(raw);
+
+                    processFeatureElement(elmLogger, element, srcschema);
+                } catch (Dgn7fileException e)
+                {
+                    logger.warn("Dgn7Exception", e);
+                }
+            }
+        } finally
+        {
+            rsSrc.close();
+            stmtSrc.close();
+        }
+    }
+
+    protected OracleElementLogger createElementLogger(Connection connection, String dataPath)
+    {
+
+        return new OracleElementLogger(connection, dataPath, MAXELM_LOGCOUNT);
+    }
+
+    private void processFeatureElement(OracleElementLogger elmLogger, Element element, String currentSchema)
+    {
+        boolean match = false;
+        if (element instanceof ArcElement)
+        {
+            match = true;
+        } else if (element instanceof ComplexChainElement)
+        {
+            ComplexChainElement complex = (ComplexChainElement) element;
+            for (Element subElm : complex)
+            {
+                if (subElm instanceof ArcElement)
+                {
+                    match = true;
+                    break;
+                }
+            }
+        }
+
+        if (match)
+            elmLogger.logElement(element, currentSchema);
+    }
+
+}
diff --git a/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java b/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java
index d616bd8..a26d5ee 100644
--- a/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java
+++ b/xdgnjobs/ximple-elmparser/src/main/java/com/ximple/eofms/XElementParser.java
@@ -25,7 +25,6 @@
 import com.ximple.eofms.filter.AbstractFLinkageDispatchableFilter;
 import com.ximple.eofms.filter.ElementDispatcher;
 import com.ximple.eofms.jobs.context.postgis.FeatureDgnConvertPostGISJobContext;
-import com.ximple.io.dgn7.ComplexChainElement;
 import com.ximple.io.dgn7.ComplexElement;
 import com.ximple.io.dgn7.Dgn7fileException;
 import com.ximple.io.dgn7.Dgn7fileReader;
diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2PostGISJob.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2PostGISJob.java
index 0f48fcd..961379e 100644
--- a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2PostGISJob.java
+++ b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2PostGISJob.java
@@ -58,6 +58,7 @@
 import com.ximple.io.dgn7.IElementHandler;
 import com.ximple.io.dgn7.Lock;
 import com.ximple.io.dgn7.TextElement;
+import com.ximple.io.dgn7.ShapeElement;
 import com.ximple.util.PrintfFormat;
 
 public class OracleConvertDgn2PostGISJob extends AbstractOracleDatabaseJob
@@ -72,10 +73,12 @@
     private static final String PGPASS = "PGPASS";
     private static final String USEWKB = "USEWKB";
 
+    private static final boolean useTpclidText = true;
+
     private static final int FETCHSIZE = 30;
     private static final int COMMITSIZE = 100;
 
-    class Pair
+    protected static class Pair
     {
         Object first;
         Object second;
@@ -764,9 +767,17 @@
     private void processIndexElement(Element element, IndexDgnConvertPostGISJobContext convertContext)
             throws IllegalAttributeException, SchemaException
     {
-        if (element instanceof TextElement)
+        if (useTpclidText)
         {
-            convertContext.putFeatureCollection(element);
+            if (element instanceof TextElement)
+            {
+                convertContext.putFeatureCollection(element);
+            }
+        } else {
+            if (element instanceof ShapeElement)
+            {
+                convertContext.putFeatureCollection(element);
+            }
         }
     }
 
diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java
index 49e2b19..8615537 100644
--- a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java
+++ b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java
@@ -54,6 +54,7 @@
     private boolean useElementCount = true;
     private ArrayList<byte[]> dgnFileHeader = null;
     private String elmOutPath;
+    private String prefix = null;
 
     public OracleElementLogger(Connection connection)
     {
@@ -67,6 +68,20 @@
         this.elmOutPath = elmOutPath;
     }
 
+    public OracleElementLogger(Connection connection, int maxCount)
+    {
+        this.connection = connection;
+        elmOutPath = DEFAULT_ELMOUTPATH;
+        this.maxElmCount = maxCount;
+    }
+
+    public OracleElementLogger(Connection connection, String elmOutPath, int maxCount)
+    {
+        this.connection = connection;
+        this.elmOutPath = elmOutPath;
+        this.maxElmCount = maxCount;
+    }
+    
     public String getDataOutPath()
     {
         if (dataOut == null)
@@ -284,11 +299,21 @@
             fch = null;
         }
 
-        File logFile = new File(getDataOutPath(), this.currentSchema + ".dgn");
+        String outLogName = currentSchema + ".dgn";
+        if (prefix != null)
+        {
+            outLogName = prefix + outLogName;
+        }
+        File logFile = new File(getDataOutPath(), outLogName);
         while (logFile.exists())
         {
-            logFile = new File(getDataOutPath(), this.currentSchema + "-"
-                    + (++logCount) + ".dgn");
+            outLogName = this.currentSchema + "-" + (++logCount) + ".dgn";
+            if (prefix != null)
+            {
+                outLogName = prefix + outLogName;
+            }
+
+            logFile = new File(getDataOutPath(), outLogName);
         }
 
         logger.warn("Create Dgn Logging File:" + logFile.toString());
@@ -453,4 +478,14 @@
     {
         this.maxElmCount = maxElmCount;
     }
+
+    public String getLogPrefix()
+    {
+        return prefix;
+    }
+
+    public void setLogPrefix(String prefix)
+    {
+        this.prefix = prefix;
+    }
 }
diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java
index 56e75a7..f7d33f1 100644
--- a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java
+++ b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java
@@ -4,14 +4,14 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.sql.PreparedStatement;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Arrays;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -30,6 +30,7 @@
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
 
 import com.ximple.eofms.util.DefaultColorTable;
 import com.ximple.eofms.util.FeatureTypeBuilderUtil;
@@ -38,6 +39,7 @@
 import com.ximple.eofms.util.TWDDatumConverter;
 import com.ximple.io.dgn7.Element;
 import com.ximple.io.dgn7.FrammeAttributeData;
+import com.ximple.io.dgn7.ShapeElement;
 import com.ximple.io.dgn7.TextElement;
 import com.ximple.io.dgn7.UserAttributeData;
 
@@ -68,16 +70,29 @@
 
     public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException
     {
-        if (!(element instanceof TextElement))
+        if ((!(element instanceof TextElement)) && (!(element instanceof ShapeElement)))
         {
             return;
         }
 
-        Feature feature = createFeature((TextElement) element);
+        if ((element instanceof TextElement))
+        {
+            putTextFeatureCollection((TextElement) element);
+        }
+
+        if ((element instanceof ShapeElement))
+        {
+            putShapeFeatureCollection((ShapeElement) element);
+        }
+    }
+
+    protected void putTextFeatureCollection(TextElement element) throws SchemaException, IllegalAttributeException
+    {
+        Feature feature = createFeature(element);
         if (feature == null)
         {
             logger.info("cannot craete feature." + element.toString() + "'" +
-                    ((TextElement) element).getText() + "'");
+                    element.getText() + "'");
             return;
         }
 
@@ -88,11 +103,11 @@
         ArrayList<Feature> arrayList = txFeaturesContext.get(feature.getFeatureType());
         arrayList.add(feature);
 
-        feature = createFeature2((TextElement) element);
+        feature = createFeature2(element);
         if (feature == null)
         {
             logger.info("cannot craete feature2." + element.toString() + "'" +
-                    ((TextElement) element).getText() + "'");
+                    element.getText() + "'");
             return;
         }
 
@@ -103,11 +118,95 @@
         arrayList = txFeaturesContext.get(feature.getFeatureType());
         arrayList.add(feature);
 
-        Feature[] features = createFeature3((TextElement) element);
+        Feature[] features = createFeature3(element);
         if (features == null)
         {
             logger.info("cannot craete feature3." + element.toString() + "'" +
-                    ((TextElement) element).getText() + "'");
+                    element.getText() + "'");
+            return;
+        }
+        if (!txFeaturesContext.containsKey(features[0].getFeatureType()))
+        {
+            txFeaturesContext.put(features[0].getFeatureType(), new ArrayList<Feature>());
+        }
+        arrayList = txFeaturesContext.get(features[0].getFeatureType());
+        arrayList.addAll(Arrays.asList(features));
+
+        accumulate++;
+
+        if (accumulate > BATCHSIZE)
+        {
+            commitTransaction();
+        }
+    }
+
+    protected void putShapeFeatureCollection(ShapeElement element) throws SchemaException, IllegalAttributeException
+    {
+        Feature feature = createFeature(element);
+        if (feature == null)
+        {
+            LinearRing ring = (LinearRing) element.toGeometry(geometryFactory);
+            if (ring == null)
+            {
+                logger.info("cannot craete feature." + element.toString() + "'" +
+                        "linear is null" + "'");
+            } else
+            {
+                Coordinate pt = ring.getEnvelopeInternal().centre();
+                String id = TPCLIDConverter.CoordinateToTpclId(pt);
+                logger.info("cannot craete feature." + element.toString() + "'" +
+                        id + "'- from pt=" + pt);
+            }
+            return;
+        }
+
+        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
+        {
+            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<Feature>());
+        }
+        ArrayList<Feature> arrayList = txFeaturesContext.get(feature.getFeatureType());
+        arrayList.add(feature);
+
+        feature = createFeature2(element);
+        if (feature == null)
+        {
+            LinearRing ring = (LinearRing) element.toGeometry(geometryFactory);
+            if (ring == null)
+            {
+                logger.info("cannot craete feature2." + element.toString() + "'" +
+                        "linear is null" + "'");
+            } else
+            {
+                Coordinate pt = ring.getEnvelopeInternal().centre();
+                String id = TPCLIDConverter.CoordinateToTpclId(pt);
+                logger.info("cannot craete feature2." + element.toString() + "'" +
+                        id + "'- from pt=" + pt);
+            }
+            return;
+        }
+
+        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
+        {
+            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<Feature>());
+        }
+        arrayList = txFeaturesContext.get(feature.getFeatureType());
+        arrayList.add(feature);
+
+        Feature[] features = createFeature3(element);
+        if (features == null)
+        {
+            LinearRing ring = (LinearRing) element.toGeometry(geometryFactory);
+            if (ring == null)
+            {
+                logger.info("cannot craete feature3." + element.toString() + "'" +
+                        "linear is null" + "'");
+            } else
+            {
+                Coordinate pt = ring.getEnvelopeInternal().centre();
+                String id = TPCLIDConverter.CoordinateToTpclId(pt);
+                logger.info("cannot craete feature3." + element.toString() + "'" +
+                        id + "'- from pt=" + pt);
+            }
             return;
         }
         if (!txFeaturesContext.containsKey(features[0].getFeatureType()))
@@ -458,6 +557,45 @@
                     textElement.getWeight(),
                     textElement.getLineStyle()
             });
+        } else if (element instanceof ShapeElement)
+        {
+            ShapeElement shapeElement = (ShapeElement) element;
+            Geometry geomShape = shapeElement.toGeometry(geometryFactory);
+            LinearRing linearRing = (LinearRing) geomShape;
+            if (linearRing.isRectangle())
+            {
+                Envelope bounds = linearRing.getEnvelopeInternal();
+                if (bounds.getWidth() == TPCLIDConverter.SX1200)
+                {
+                    Coordinate center = bounds.centre();
+                    String tpclid = TPCLIDConverter.CoordinateToTpclId(center);
+                    if (tpclid.length() > 5)
+                    {
+                        tpclid = tpclid.substring(0, 4);
+                    }
+                    Envelope extent = TPCLIDConverter.convertTpclIdToEnvelope(tpclid);
+                    Geometry geom = geometryFactory.createPolygon(geometryFactory.createLinearRing(new Coordinate[]
+                            {
+                                    TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
+                                    TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMinY())),
+                                    TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMaxY())),
+                                    TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMaxY())),
+                                    TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
+                            }), null);
+
+                    return featureType.create(new Object[]{
+                            geom,
+                            extent.getMinX(),
+                            extent.getMinY(),
+                            extent.getMaxX(),
+                            extent.getMaxY(),
+                            tpclid,
+                            colorTable.getColorCode(shapeElement.getColorIndex()),
+                            shapeElement.getWeight(),
+                            shapeElement.getLineStyle()
+                    });
+                }
+            }
         }
         return null;
     }
@@ -474,18 +612,56 @@
             convertDecorator.setConverter(txtElement);
             Geometry gobj = convertDecorator.toGeometry(geometryFactory);
             if (gobj != null)
-            feature = featureType.create(new Object[]{
-                    gobj,
-                    colorTable.getColorCode(txtElement.getColorIndex()),
-                    txtElement.getWeight(),
-                    txtElement.getLineStyle(),
-                    txtElement.getJustification(),
-                    txtElement.getTextHeight(),
-                    txtElement.getTextWidth(),
-                    angle,
-                    txtElement.getText()
-            });
+                feature = featureType.create(new Object[]{
+                        gobj,
+                        colorTable.getColorCode(txtElement.getColorIndex()),
+                        txtElement.getWeight(),
+                        txtElement.getLineStyle(),
+                        txtElement.getJustification(),
+                        txtElement.getTextHeight(),
+                        txtElement.getTextWidth(),
+                        angle,
+                        txtElement.getText()
+                });
             return feature;
+        } else if (element instanceof ShapeElement)
+        {
+            Feature feature = null;
+            ShapeElement shapeElement = (ShapeElement) element;
+            double angle = 0.0;
+            Geometry geomShape = shapeElement.toGeometry(geometryFactory);
+            LinearRing linearRing = (LinearRing) geomShape;
+
+            if (linearRing.isRectangle())
+            {
+                Envelope bounds = linearRing.getEnvelopeInternal();
+                if (bounds.getWidth() == TPCLIDConverter.SX1200)
+                {
+                    Coordinate center = bounds.centre();
+                    String tpclid = TPCLIDConverter.CoordinateToTpclId(center);
+                    if (tpclid.length() > 5)
+                    {
+                        tpclid = tpclid.substring(0, 4);
+                        Coordinate pos = TWDDatumConverter.fromTM2ToTWD97(new Coordinate(center.x, center.y));
+                        Geometry gobj = geometryFactory.createPoint(pos);
+
+                        if (gobj != null)
+                            feature = featureType.create(new Object[]{
+                                    gobj,
+                                    colorTable.getColorCode(shapeElement.getColorIndex()),
+                                    shapeElement.getWeight(),
+                                    shapeElement.getLineStyle(),
+                                    0,
+                                    15.0,
+                                    15 * 5,
+                                    angle,
+                                    tpclid
+                            });
+                        return feature;
+                    }
+
+                }
+            }
         }
         return null;
     }
@@ -521,12 +697,14 @@
                                         extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)),
                         }), null);
 
+                Envelope innerExtent = geom.getEnvelopeInternal();
+
                 result[i] = featureType.create(new Object[]{
                         geom,
-                        extent.getMinX(),
-                        extent.getMinY(),
-                        extent.getMaxX(),
-                        extent.getMaxY(),
+                        innerExtent.getMinX(),
+                        innerExtent.getMinY(),
+                        innerExtent.getMaxX(),
+                        innerExtent.getMaxY(),
                         tpclid + mapSubId,
                         colorTable.getColorCode(textElement.getColorIndex()),
                         textElement.getWeight(),
@@ -535,11 +713,63 @@
 
             }
             return result;
+        } else if (element instanceof ShapeElement)
+        {
+            ShapeElement shapeElement = (ShapeElement) element;
+            Geometry geomShape = shapeElement.toGeometry(geometryFactory);
+            LinearRing linearRing = (LinearRing) geomShape;
+            if (linearRing.isRectangle())
+            {
+                Envelope extent = linearRing.getEnvelopeInternal();
+                if (extent.getWidth() == TPCLIDConverter.SX1200)
+                {
+                    Feature[] result = new Feature[4];
+                    Coordinate center = extent.centre();
+                    String tpclid = TPCLIDConverter.CoordinateToTpclId(center);
+                    for (int i = 0; i < 4; i++)
+                    {
+                        char mapSubId = TPCLIDConverter.intToAscii(65 + i);
+                        int dx = (i % 2) * TPCLIDConverter.SX600;
+                        int dy = (i / 2) * TPCLIDConverter.SY600;
+
+                        Geometry geom = geometryFactory.createPolygon(geometryFactory.createLinearRing(new Coordinate[]
+                                {
+                                        TWDDatumConverter.fromTM2ToTWD97(new Coordinate(
+                                                extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)),
+                                        TWDDatumConverter.fromTM2ToTWD97(new Coordinate(
+                                                extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)),
+                                        TWDDatumConverter.fromTM2ToTWD97(new Coordinate(
+                                                extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - dy)),
+                                        TWDDatumConverter.fromTM2ToTWD97(new Coordinate(
+                                                extent.getMinX() + dx, extent.getMaxY() - dy)),
+                                        TWDDatumConverter.fromTM2ToTWD97(new Coordinate(
+                                                extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)),
+                                }), null);
+
+                        Envelope innerExtent = geom.getEnvelopeInternal();
+
+                        result[i] = featureType.create(new Object[]{
+                                geom,
+                                innerExtent.getMinX(),
+                                innerExtent.getMinY(),
+                                innerExtent.getMaxX(),
+                                innerExtent.getMaxY(),
+                                tpclid + mapSubId,
+                                colorTable.getColorCode(shapeElement.getColorIndex()),
+                                shapeElement.getWeight(),
+                                shapeElement.getLineStyle()
+                        });
+                    }
+
+                    return result;
+                }
+            }
         }
+
         return null;
     }
 
-    private Feature createFeature(TextElement element) throws SchemaException, IllegalAttributeException
+    private Feature createFeature(Element element) throws SchemaException, IllegalAttributeException
     {
         if (featureType == null)
         {
@@ -554,7 +784,7 @@
         return createFeature(featureType, element);
     }
 
-    private Feature createFeature2(TextElement element) throws SchemaException, IllegalAttributeException
+    private Feature createFeature2(Element element) throws SchemaException, IllegalAttributeException
     {
         if (featureType2 == null)
         {
@@ -570,7 +800,7 @@
         return createFeature2(featureType2, element);
     }
 
-    private Feature[] createFeature3(TextElement element) throws SchemaException, IllegalAttributeException
+    private Feature[] createFeature3(Element element) throws SchemaException, IllegalAttributeException
     {
         if (featureType3 == null)
         {

--
Gitblit v0.0.0-SNAPSHOT