package com.ximple.eofms.filter; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateArrays; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import com.ximple.eofms.util.*; 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.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; import javax.swing.event.EventListenerList; import java.awt.geom.AffineTransform; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; import java.util.TreeMap; public class CreateSymbolStrategy implements CreateFeatureTypeStrategy { static final Log logger = LogFactory.getLog(CreateSymbolStrategy.class); GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); TreeMap typeBuilders = new TreeMap(); // Create the listener list protected EventListenerList listenerList = new EventListenerList(); public CreateSymbolStrategy() { } 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 SimpleFeatureType createFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createSymbolFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); typeBuilders.put(featureName, featureType); fireFeatureTypeEvent(new FeatureTypeEvent(this, featureType)); } return typeBuilders.get(featureName); } public SimpleFeature createFeature(SimpleFeatureType featureType, Element element, boolean useTransform) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); FrammeAttributeData fLinkage = getFeatureLinkage(element); SimpleFeature feature = null; if (fLinkage == null) return null; if (element instanceof TextElement) { TextElement txtElement = (TextElement) element; double angle = txtElement.getRotationAngle(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); if (txtElement.getText().length() == 0) { logger.info("CreateSymbolStrategy cannot conver " + element.toString() + "to Feature - getText() is empty."); return null; } StringBuilder sb = new StringBuilder(); sb.append("OCT"); char id = txtElement.getText().toCharArray()[0]; sb.append(Integer.toOctalString((int) id)); sb.append("-"); sb.append(txtElement.getFontIndex()); Geometry gobj; if (useTransform) { GeometryConverterDecorator convertDecorator = FeatureTypeBuilderUtil.lookupDefaultGeometryConverter(); convertDecorator.setConverter(txtElement); gobj = convertDecorator.toGeometry(geometryFactory); } else { gobj = txtElement.toGeometry(geometryFactory); } if (gobj instanceof Point) { Coordinate p = gobj.getCoordinate(); double width = txtElement.getTextWidth(); double height = txtElement.getTextHeight(); AffineTransform at = new AffineTransform(); at.translate(width, height); at.setToRotation(angle, p.x, p.y); at.scale(1, 1); Envelope envelope = new Envelope(p); envelope.expandBy(width / 2, height / 2); double[] srcPt = new double[8]; double[] dstPt = new double[8]; srcPt[0] = envelope.getMinX(); srcPt[1] = envelope.getMinY(); srcPt[2] = envelope.getMinX(); srcPt[3] = envelope.getMaxY(); srcPt[4] = envelope.getMaxX(); srcPt[5] = envelope.getMaxY(); srcPt[6] = envelope.getMaxX(); srcPt[7] = envelope.getMinY(); at.transform(srcPt, 0, dstPt, 0, 4); Coordinate[] coords = new Coordinate[5]; for (int i = 0; i < 4; i++) { coords[i] = new Coordinate(dstPt[i*2], dstPt[i*2+1]); } coords[4] = new Coordinate(dstPt[0], dstPt[1]); int srid = gobj.getSRID(); gobj = geometryFactory.createPolygon(geometryFactory.createLinearRing(coords), null); if (gobj.getSRID() != srid) { gobj.setSRID(srid); } } else { gobj = null; } if (gobj != null) feature = SimpleFeatureBuilder.build(featureType, new Object[]{ gobj, fLinkage.getFsc(), (long) fLinkage.getUfid(), (short) fLinkage.getComponentID(), fLinkage.getOccID(), (short) txtElement.getLevelIndex(), colorTable.getColorCode(txtElement.getColorIndex()), (short) txtElement.getWeight(), (short) txtElement.getLineStyle(), (short) txtElement.getJustification(), (float) txtElement.getTextHeight(), (float) txtElement.getTextWidth(), (float) angle, sb.toString() }, null); } else { logger.info("CreateSymbolStrategy cannot conver " + element.toString() + "to Feature"); } return feature; } public void addCreateFeatureTypeEventListener(CreateFeatureTypeEventListener listener) { listenerList.add(CreateFeatureTypeEventListener.class, listener); } public void removeCreateFeatureTypeEventListener(CreateFeatureTypeEventListener listener) { listenerList.remove(CreateFeatureTypeEventListener.class, listener); } protected void fireFeatureTypeEvent(FeatureTypeEvent evt) { Object[] listeners = listenerList.getListenerList(); for (int i = 0; i < listeners.length; i += 2) { if (listeners[i] == CreateFeatureTypeEventListener.class) { ((CreateFeatureTypeEventListener) listeners[i + 1]).createFeatureTypeOccurred(evt); } } } }