package com.ximple.eofms.jobs.context.postgis; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.TreeMap; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.transaction.memory.PessimisticMapWrapper; import org.apache.commons.transaction.util.CommonsLoggingLogger; import org.apache.commons.transaction.util.LoggerFacade; import org.geotools.data.DataStore; import org.geotools.data.FeatureWriter; import org.geotools.data.Transaction; import org.geotools.data.DefaultTransaction; import org.geotools.data.DataSourceException; import org.geotools.data.FeatureStore; import org.geotools.feature.Feature; import org.geotools.feature.FeatureType; import org.geotools.feature.FeatureTypeBuilder; import org.geotools.feature.IllegalAttributeException; import org.geotools.feature.SchemaException; import org.geotools.feature.SimpleFeature; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollections; import org.postgresql.util.PSQLException; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.ximple.eofms.util.DefaultColorTable; import com.ximple.eofms.util.FeatureTypeBuilderUtil; import com.ximple.eofms.util.TWD97GeometryConverterDecorator; import com.ximple.io.dgn7.ArcElement; import com.ximple.io.dgn7.ComplexChainElement; import com.ximple.io.dgn7.Element; import com.ximple.io.dgn7.EllipseElement; import com.ximple.io.dgn7.FrammeAttributeData; import com.ximple.io.dgn7.LineElement; import com.ximple.io.dgn7.LineStringElement; import com.ximple.io.dgn7.ShapeElement; import com.ximple.io.dgn7.TextElement; import com.ximple.io.dgn7.TextNodeElement; import com.ximple.io.dgn7.UserAttributeData; public class GeneralDgnConvertPostGISJobContext extends AbstractDgnToPostGISJobContext { static final Log logger = LogFactory.getLog(GeneralDgnConvertPostGISJobContext.class); static final LoggerFacade sLogger = new CommonsLoggingLogger(logger); static final GeometryFactory geometryFactory = new GeometryFactory(); private HashMap> txFeaturesContext = new HashMap>(); private TreeMap typeBuilders = new TreeMap(); private TreeMap featureTypes = new TreeMap(); private TWD97GeometryConverterDecorator convertDecorator = null; private String featureBaseName = null; private boolean dropTableMode = true; public GeneralDgnConvertPostGISJobContext(String dataPath, DataStore targetDataStore) { super(dataPath, targetDataStore); convertDecorator = new TWD97GeometryConverterDecorator(); } public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException { FeatureType ft = lookupFeatureType(element); if (ft != null) { Feature feature = createFeature(ft, element); if (feature == null) { if (element instanceof TextElement) logger.info("cannot craete feature." + element.toString() + "'" + ((TextElement) element).getText() + "'"); else if (element instanceof ShapeElement) logger.info("cannot craete feature." + element.toString() + "'" + ((ShapeElement) element).getVerticeSize() + "'" + ((ShapeElement) element).getStartPoint()); else if (element instanceof LineStringElement) logger.info("cannot craete feature." + element.toString() + "'" + ((LineStringElement) element).getVerticeSize() + "'" + ((LineStringElement) element).getStartPoint()); else if (element instanceof ArcElement) logger.info("cannot craete feature." + element.toString() + "'" + ((ArcElement) element).getOrigin().toString() + "'" + ((ArcElement) element).getRotationAngle()); return; } if (!txFeaturesContext.containsKey(feature.getFeatureType())) { txFeaturesContext.put(feature.getFeatureType(), new ArrayList()); } ArrayList arrayList = txFeaturesContext.get(feature.getFeatureType()); if (feature.getDefaultGeometry() != null && !feature.getDefaultGeometry().isEmpty()) arrayList.add(makeInsertSql(feature, -1)); } else { logger.info("Unknown Element :" + element.getType() + ", lv=" + element.getLevelIndex()); } } private Transaction transaction; public void startTransaction() { } public void commitTransaction() { if (!txFeaturesContext.isEmpty()) { logger.debug("Transaction size = " + txFeaturesContext.size()); //txFeaturesContext.commitTransaction(); } else { logger.debug("Transaction is empty."); } if (!txFeaturesContext.isEmpty()) { updateDataStore(); } txFeaturesContext.clear(); } public void rollbackTransaction() { txFeaturesContext.clear(); } private void updateDataStore() { Iterator it = txFeaturesContext.keySet().iterator(); String currentStmt = null; try { while (it.hasNext()) { FeatureType featureType = it.next(); logger.debug("Begin Save into PostGIS:" + featureType.getTypeName()); ArrayList stmtTexts = txFeaturesContext.get(featureType); Connection conn = getConnection(); boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(true); for (String stmtText : stmtTexts) { currentStmt = stmtText; Statement stmt = conn.createStatement(); try { stmt.execute(stmtText); } catch (PSQLException e) { if (currentStmt != null) { logger.error("Execute:" + currentStmt); } logger.error(e.getServerErrorMessage()); logger.error(e.getMessage(), e); } finally { stmt.close(); } /* if ((i % BATCHSIZE) != 0) { stmt.addBatch(stmtText); } else { stmt.addBatch(stmtText); stmt.executeBatch(); } i++; */ } stmtTexts.clear(); conn.setAutoCommit(autoCommit); logger.debug("End Save into PostGIS:" + featureType.getTypeName()); } } catch (SQLException e) { logger.error(e.getMessage(), e); } } public void closeFeatureWriter() throws IOException { /* for (FeatureWriter featureWriter : this.featuresWriterContext.values()) { featureWriter.close(); } this.featuresWriterContext.clear(); */ } public FeatureType createPointFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalPointFeatureTypeBuilder(featureName); typeBuilders.put(featureName, typeBuilder); clearFeatureData(typeBuilder); } return typeBuilders.get(featureName).getFeatureType(); } public FeatureType createLineFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalLineFeatureTypeBuilder(featureName); typeBuilders.put(featureName, typeBuilder); clearFeatureData(typeBuilder); } return typeBuilders.get(featureName).getFeatureType(); } public FeatureType createArcFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalArcFeatureTypeBuilder(featureName); typeBuilders.put(featureName, typeBuilder); clearFeatureData(typeBuilder); } return typeBuilders.get(featureName).getFeatureType(); } public FeatureType createEllipseFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalEllipseFeatureTypeBuilder(featureName); typeBuilders.put(featureName, typeBuilder); clearFeatureData(typeBuilder); } return typeBuilders.get(featureName).getFeatureType(); } public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); if (element instanceof TextElement) { TextElement textElement = (TextElement) element; convertDecorator.setConverter(textElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); double angle = textElement.getRotationAngle(); String content = textElement.getText(); content = content.replace('\u0000', ' '); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); if (geom != null) { return featureType.create(new Object[]{ geom, colorTable.getColorCode(textElement.getColorIndex()), textElement.getFontIndex(), textElement.getJustification(), textElement.getTextHeight(), textElement.getTextWidth(), angle, content }); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof TextNodeElement) { TextNodeElement textNodeElement = (TextNodeElement) element; convertDecorator.setConverter(textNodeElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); double angle = textNodeElement.getRotationAngle(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); String[] texts = textNodeElement.getTextArray(); StringBuffer sb = new StringBuffer(); for (String text : texts) { if (sb.length() != 0) sb.append("\n"); String content = text.replace('\u0000', ' '); sb.append(content); } if (geom != null) { return featureType.create(new Object[]{ geom, colorTable.getColorCode(textNodeElement.getColorIndex()), textNodeElement.getFontIndex(), textNodeElement.getJustification(), textNodeElement.getTextNodeHeight(), textNodeElement.getTextNodeLength(), angle, sb.toString() }); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof ShapeElement) { ShapeElement shapeElement = (ShapeElement) element; convertDecorator.setConverter(shapeElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return featureType.create(new Object[]{ geom, colorTable.getColorCode(shapeElement.getColorIndex()), shapeElement.getWeight(), shapeElement.getLineStyle() }); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof LineStringElement) { LineStringElement linestring = (LineStringElement) element; convertDecorator.setConverter(linestring); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) return featureType.create(new Object[]{ geom, colorTable.getColorCode(linestring.getColorIndex()), linestring.getWeight(), linestring.getLineStyle() }); return null; } else if (element instanceof LineElement) { LineElement line = (LineElement) element; convertDecorator.setConverter(line); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) return featureType.create(new Object[]{ geom, colorTable.getColorCode(line.getColorIndex()), line.getWeight(), line.getLineStyle() }); return null; } else if (element instanceof ArcElement) { ArcElement arcElement = (ArcElement) element; /* logger.fatal("" + arcElement.getPrimary() + ":" + arcElement.getSecondary() + "-" + arcElement.getStartAngle() + ":" + arcElement.getSweepAngle() + ":" + arcElement.getRotationAngle() + ":" + arcElement.getOrigin()); */ convertDecorator.setConverter(arcElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) return featureType.create(new Object[]{ geom, colorTable.getColorCode(arcElement.getColorIndex()), arcElement.getWeight(), arcElement.getLineStyle() }); return null; } else if (element instanceof EllipseElement) { EllipseElement arcElement = (EllipseElement) element; convertDecorator.setConverter(arcElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) return featureType.create(new Object[]{ geom, colorTable.getColorCode(arcElement.getColorIndex()), arcElement.getWeight(), arcElement.getLineStyle() }); return null; } else if (element instanceof ComplexChainElement) { ComplexChainElement complexChainElement = (ComplexChainElement) element; convertDecorator.setConverter(complexChainElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) return featureType.create(new Object[]{ geom, colorTable.getColorCode(complexChainElement.getColorIndex()), complexChainElement.getWeight(), complexChainElement.getLineStyle() }); return null; } return null; } private String getFeatureBaseName() { if (featureBaseName == null) { String dgnname = getFilename().toLowerCase(); int i = dgnname.lastIndexOf("."); if (i != -1) { dgnname = dgnname.substring(0, i); } featureBaseName = dgnname; } return featureBaseName; } private FeatureType lookupFeatureType(Element element) throws SchemaException, IllegalAttributeException { String typeName; if (element instanceof TextElement) { typeName = getFeatureBaseName() + "P"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createPointFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof TextNodeElement) { typeName = getFeatureBaseName() + "P"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createPointFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof LineStringElement) { if (element instanceof ShapeElement) { typeName = getFeatureBaseName() + "R"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } else { typeName = getFeatureBaseName() + "L"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } } else if (element instanceof LineElement) { typeName = getFeatureBaseName() + "L"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof ComplexChainElement) { typeName = getFeatureBaseName() + "L"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof ArcElement) { typeName = getFeatureBaseName() + "A"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createArcFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof EllipseElement) { typeName = getFeatureBaseName() + "R"; if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createEllipseFeatureElement(typeName)); } return featureTypes.get(typeName); } return null; } protected FrammeAttributeData getFeatureLinkage(Element element) { if (!element.hasUserAttributeData()) return null; List usrDatas = element.getUserAttributeData(); for (UserAttributeData anUsrData : usrDatas) { if (anUsrData instanceof FrammeAttributeData) { return (FrammeAttributeData) anUsrData; } } return null; } public Log getLogger() { return logger; } public boolean isDropTableMode() { return dropTableMode; } public void setDropTableMode(boolean dropTableMode) { this.dropTableMode = dropTableMode; } protected void clearFeatureData(FeatureTypeBuilder typeBuilder) throws SchemaException { String featureName = typeBuilder.getName(); if (isExistFeature(typeBuilder.getFeatureType())) { try { Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT); if (dropTableMode) { dropGeometryColumn(conn, featureName, typeBuilder.getFeatureType().getDefaultGeometry().getLocalName()); dropTable(conn, featureName); ArrayList schemaTexts = createSchemaTexts(typeBuilder.getFeatureType()); for (String stmtText : schemaTexts) { Statement stmt = conn.createStatement(); stmt.execute(stmtText); stmt.close(); } } else { deleteTable(conn, featureName); } conn.close(); } catch (IOException e) { logger.warn(e.getMessage(), e); } catch (SQLException e) { logger.warn(e.getMessage(), e); } } else { try { Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT); ArrayList schemaTexts = createSchemaTexts(typeBuilder.getFeatureType()); for (String stmtText : schemaTexts) { Statement stmt = conn.createStatement(); stmt.execute(stmtText); stmt.close(); } conn.close(); } catch (IOException e) { logger.warn(e.getMessage(), e); } catch (SQLException e) { logger.warn(e.getMessage(), e); } } } }