package com.ximple.eofms.jobs.context.shapefile; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.MalformedURLException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.TimeZone; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; 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.GeometryConverterDecorator; import com.ximple.eofms.util.TPCLIDConverter; import com.ximple.eofms.util.TWDDatumConverter; import com.ximple.io.dgn7.Element; import com.ximple.io.dgn7.FrammeAttributeData; import com.ximple.io.dgn7.TextElement; import com.ximple.io.dgn7.UserAttributeData; 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.FeatureWriter; import org.geotools.data.Transaction; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.feature.SchemaException; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geometry.jts.JTSFactoryFinder; import org.opengis.feature.IllegalAttributeException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; public class IndexDgnConvertShpJobContext extends AbstractDgnToShapefileJobContext { static final Log logger = LogFactory.getLog(IndexDgnConvertShpJobContext.class); static final LoggerFacade sLogger = new CommonsLoggingLogger(logger); static final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); public static final String SHPOUTPATH = "shpout"; private String dataOut = null; private HashMap> featuresContext = new HashMap>(); private HashMap featuresWriterContext = new HashMap(); private PessimisticMapWrapper txFeaturesContext; private SimpleFeatureTypeBuilder typeBuilderPnt = null; private SimpleFeatureTypeBuilder typeBuilderRect = null; private SimpleFeatureType featureType = null; private SimpleFeatureType featureType2 = null; private SimpleFeatureType featureType3 = null; private int accumulate = 0; public IndexDgnConvertShpJobContext(String dataPath, boolean profileMode, boolean useTransform) { super(dataPath, profileMode, useTransform); txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger); } public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException { if (!(element instanceof TextElement)) { return; } SimpleFeature feature = createFeature((TextElement) element); if (feature == null) { logger.info("cannot craete feature." + element.toString() + "'" + ((TextElement) element).getText() + "'"); return; } if (!txFeaturesContext.containsKey(feature.getFeatureType())) { txFeaturesContext.put(feature.getFeatureType(), new ArrayList()); } ArrayList arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType()); arrayList.add(feature); feature = createFeature2((TextElement) element); if (feature == null) { logger.info("cannot craete feature2." + element.toString() + "'" + ((TextElement) element).getText() + "'"); return; } if (!txFeaturesContext.containsKey(feature.getFeatureType())) { txFeaturesContext.put(feature.getFeatureType(), new ArrayList()); } arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType()); arrayList.add(feature); SimpleFeature[] features = createFeature3((TextElement) element); if (features == null) { logger.info("cannot craete feature3." + element.toString() + "'" + ((TextElement) element).getText() + "'"); return; } if (!txFeaturesContext.containsKey(features[0].getFeatureType())) { txFeaturesContext.put(features[0].getFeatureType(), new ArrayList()); } arrayList = (ArrayList) txFeaturesContext.get(features[0].getFeatureType()); arrayList.addAll(Arrays.asList(features)); accumulate++; } public void startTransaction() { } public void commitTransaction() { if (!txFeaturesContext.isEmpty()) { logger.debug("Transaction size = " + txFeaturesContext.size()); //txFeaturesContext.commitTransaction(); } else { logger.debug("Transaction is empty."); } if (!featuresContext.isEmpty()) { updateDataStore(); } } public void rollbackTransaction() { //txFeaturesContext.rollbackTransaction(); if (!featuresContext.isEmpty()) { updateDataStore(); } } private void updateDataStore() { if (isProfileMode()) markUpdateTime(); Iterator it = featuresContext.keySet().iterator(); try { while (it.hasNext()) { SimpleFeatureType featureType = (SimpleFeatureType) it.next(); File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName()); logger.debug("Begin Save shapefile:" + sfile.toURI()); FeatureWriter writer; if (featuresWriterContext.containsKey(featureType.getTypeName())) { writer = featuresWriterContext.get(featureType.getTypeName()); } else { /* ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(), true, Charset.forName("UTF-8")); */ ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL()); /* if(namespace != null) { shapefileDataStore.setNamespaceURI(namespace.toString()); } */ shapefileDataStore.setMemoryMapped(true); // shapefileDataStore.setBufferCachingEnabled(cacheMemoryMaps); shapefileDataStore.setCharset(Charset.forName("UTF-8")); shapefileDataStore.setTimeZone(TimeZone.getDefault()); shapefileDataStore.setIndexed(true); shapefileDataStore.setIndexCreationEnabled(true); shapefileDataStore.createSchema(featureType); writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(), Transaction.AUTO_COMMIT); featuresWriterContext.put(featureType.getTypeName(), writer); } ArrayList features = featuresContext.get(featureType); for (SimpleFeature feature1 : features) { ((SimpleFeature) writer.next()).setAttributes(feature1.getAttributes()); } //writer.close(); logger.debug("End Save shapefile:" + sfile.toURI()); } featuresContext.clear(); } catch (MalformedURLException e) { logger.error(e.getMessage(), e); } catch (IllegalAttributeException e) { logger.error(e.getMessage(), e); } catch (IOException e) { logger.error(e.getMessage(), e); } finally { if (isProfileMode()) accumulateUpdateTime(); } } public String getDataOutPath() { if (dataOut == null) { File outPath = new File(getDataPath(), SHPOUTPATH); if (!outPath.exists()) { outPath.mkdir(); } else if (!outPath.isDirectory()) { outPath.mkdir(); } dataOut = outPath.toString(); } return dataOut; } public void closeFeatureWriter() throws IOException { for (FeatureWriter featureWriter : this.featuresWriterContext.values()) { featureWriter.close(); } this.featuresWriterContext.clear(); } public SimpleFeatureType createFeatureElement(String featureName) throws SchemaException { if (typeBuilderRect == null) { typeBuilderRect = FeatureTypeBuilderUtil.createNormalIndexFeatureTypeBuilder(featureName); } return typeBuilderRect.buildFeatureType(); } public SimpleFeatureType createFeatureElement2(String featureName) throws SchemaException { if (typeBuilderPnt == null) { typeBuilderPnt = FeatureTypeBuilderUtil.createNormalIndexTextFeatureTypeBuilder(featureName); } return typeBuilderPnt.buildFeatureType(); } public SimpleFeature createFeature(SimpleFeatureType featureType, Element element) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); if (element instanceof TextElement) { TextElement textElement = (TextElement) element; String tpclid = textElement.getText(); Envelope extent = TPCLIDConverter.convertTpclIdToEnvelope(tpclid); Geometry geom; if (FeatureTypeBuilderUtil.getDefaultFeatureSRID() == 3826) { geom = geometryFactory.createLinearRing(new Coordinate[] { TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate(extent.getMinX(), extent.getMinY())), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate(extent.getMaxX(), extent.getMinY())), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate(extent.getMaxX(), extent.getMaxY())), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate(extent.getMinX(), extent.getMaxY())), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate(extent.getMinX(), extent.getMinY())), }); } else { geom = geometryFactory.createLinearRing(new Coordinate[] { TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate(extent.getMinX(), extent.getMinY())), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate(extent.getMaxX(), extent.getMinY())), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate(extent.getMaxX(), extent.getMaxY())), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate(extent.getMinX(), extent.getMaxY())), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate(extent.getMinX(), extent.getMinY())), }); } return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY(), tpclid, colorTable.getColorCode(textElement.getColorIndex()), textElement.getWeight(), textElement.getLineStyle() }, null); } return null; } public SimpleFeature createFeature2(SimpleFeatureType featureType, Element element) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); if (element instanceof TextElement) { TextElement txtElement = (TextElement) element; double angle = txtElement.getRotationAngle(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); GeometryConverterDecorator convertDecorator = FeatureTypeBuilderUtil.lookupDefaultGeometryConverter(); convertDecorator.setConverter(txtElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); SimpleFeature feature = SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(txtElement.getColorIndex()), txtElement.getWeight(), txtElement.getLineStyle(), txtElement.getJustification(), txtElement.getTextHeight(), txtElement.getTextWidth(), angle, txtElement.getText() }, null); return feature; } return null; } public SimpleFeature[] createFeature3(SimpleFeatureType featureType, Element element) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); if (element instanceof TextElement) { TextElement textElement = (TextElement) element; String tpclid = textElement.getText(); SimpleFeature[] result = new SimpleFeature[4]; Envelope extent = TPCLIDConverter.convertTpclIdToEnvelope(tpclid); 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; if (FeatureTypeBuilderUtil.getDefaultFeatureSRID() == 3826) { geom = geometryFactory.createPolygon(geometryFactory.createLinearRing(new Coordinate[] { TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate( extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate( extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - dy)), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - dy)), TWDDatumConverter.fromTM2ToEPSG3826(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), }), null); } else { geom = geometryFactory.createPolygon(geometryFactory.createLinearRing(new Coordinate[] { TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate( extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate( extent.getMinX() + TPCLIDConverter.SX600 + dx, extent.getMaxY() - dy)), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - dy)), TWDDatumConverter.fromTM2ToEPSG3825(new Coordinate( extent.getMinX() + dx, extent.getMaxY() - TPCLIDConverter.SY600 - dy)), }), null); } result[i] = SimpleFeatureBuilder.build(featureType, new Object[]{ geom, extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY(), tpclid + mapSubId, colorTable.getColorCode(textElement.getColorIndex()), textElement.getWeight(), textElement.getLineStyle() }, null); } return result; } return null; } private SimpleFeature createFeature(TextElement element) throws SchemaException, IllegalAttributeException { if (featureType == null) { String dgnname = getFilename().toLowerCase(); int i = dgnname.lastIndexOf("."); if (i != -1) { dgnname = dgnname.substring(0, i); } featureType = createFeatureElement(dgnname); } return createFeature(featureType, element); } private SimpleFeature createFeature2(TextElement element) throws SchemaException, IllegalAttributeException { if (featureType2 == null) { String dgnname = getFilename().toLowerCase(); int i = dgnname.lastIndexOf("."); if (i != -1) { dgnname = dgnname.substring(0, i); } dgnname = dgnname + "P"; featureType2 = createFeatureElement2(dgnname); } return createFeature2(featureType2, element); } private SimpleFeature[] createFeature3(TextElement element) throws SchemaException, IllegalAttributeException { if (featureType3 == null) { String dgnname = getFilename().toLowerCase(); int i = dgnname.lastIndexOf("."); if (i != -1) { dgnname = dgnname.substring(0, i); } dgnname = dgnname + "_s"; featureType3 = createFeatureElement(dgnname.toLowerCase()); } return createFeature3(featureType3, element); } 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; } }