package com.ximple.eofms.filter; import javax.swing.event.EventListenerList; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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 com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateList; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.util.Assert; import com.ximple.eofms.util.DefaultColorTable; import com.ximple.eofms.util.EPSG3825GeometryConverterDecorator; import com.ximple.eofms.util.EPSG3826GeometryConverterDecorator; import com.ximple.eofms.util.FeatureTypeBuilderUtil; import com.ximple.eofms.util.GeometryConverterDecorator; import com.ximple.io.dgn7.Element; import com.ximple.io.dgn7.FrammeAttributeData; import com.ximple.io.dgn7.GeometryConverter; import com.ximple.io.dgn7.TextElement; import com.ximple.io.dgn7.TextNodeElement; import com.ximple.io.dgn7.UserAttributeData; public class CreateMultiSymbolStrategy implements CreateFeatureTypeStrategy { static final Log logger = LogFactory.getLog(CreateMultiSymbolStrategy.class); GeometryFactory geometryFactory = new GeometryFactory(); TreeMap typeBuilders = new TreeMap(); static final GeometryConverterDecorator convertDecorator[] = new GeometryConverterDecorator[]{ new EPSG3826AnchorGeometryConverterDecorator(), new EPSG3825AnchorGeometryConverterDecorator() }; // Create the listener list protected EventListenerList listenerList = new EventListenerList(); public CreateMultiSymbolStrategy() { } 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 FeatureType createFeatureElement(String featureName) throws SchemaException { if (!typeBuilders.containsKey(featureName)) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createMultiSymbolFeatureTypeBuilder(featureName); typeBuilders.put(featureName, typeBuilder); fireFeatureTypeEvent(new FeatureTypeEvent(this, typeBuilder.getFeatureType())); } return typeBuilders.get(featureName).getFeatureType(); } public Feature createFeature(FeatureType featureType, Element element, boolean useTransform, boolean useEPSG3826) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); FrammeAttributeData fLinkage = getFeatureLinkage(element); Feature 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(); String content = txtElement.getText().trim(); if (content.length() == 0) { logger.info("CreateMultiSymbolStrategy cannot conver " + element.toString() + "to Feature - getText() is empty."); return null; } StringBuilder sb = new StringBuilder(); sb.append("OCT"); char id = content.toCharArray()[0]; sb.append(Integer.toOctalString((int) id)); sb.append("-"); sb.append(txtElement.getFontIndex()); Geometry gobj; if (useTransform) { if (useEPSG3826) { convertDecorator[0].setConverter(txtElement); gobj = convertDecorator[0].toGeometry(geometryFactory); } else { convertDecorator[1].setConverter(txtElement); gobj = convertDecorator[1].toGeometry(geometryFactory); } } else { gobj = txtElement.toGeometry(geometryFactory); } if (gobj != null) feature = featureType.create(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() }); } else if (element instanceof TextNodeElement) { TextNodeElement nodeElement = (TextNodeElement) element; double angle = nodeElement.getRotationAngle(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); if (nodeElement.size() == 0) { logger.info("CreateMultiSymbolStrategy cannot conver " + element.toString() + "to Feature - getText() is empty."); return null; } Iterator txtElement = nodeElement.iterator(); while(txtElement.hasNext()) { TextElement txtChildElement = (TextElement) element; char[] charArray = txtChildElement.getText().toCharArray(); if (charArray.length == 0) { logger.info("CreateMultiSymbolStrategy cannot conver " + element.toString() + "to Feature - getText() is empty."); return null; } for(int i = 0 ; i < charArray.length ; i++) { StringBuilder sb = new StringBuilder(); sb.append("OCT"); char id = charArray[i]; sb.append(Integer.toOctalString((int) id)); sb.append("-"); sb.append(txtChildElement.getFontIndex()); Geometry gobj; if (useTransform) { if (useEPSG3826) { convertDecorator[0].setConverter(txtChildElement); gobj = convertDecorator[0].toGeometry(geometryFactory); } else { convertDecorator[1].setConverter(txtChildElement); gobj = convertDecorator[1].toGeometry(geometryFactory); } } else { gobj = txtChildElement.toGeometry(geometryFactory); } if (gobj != null) feature = featureType.create(new Object[]{ gobj, fLinkage.getFsc(), (long) fLinkage.getUfid(), (short) fLinkage.getComponentID(), fLinkage.getOccID(), (short) txtChildElement.getLevelIndex(), colorTable.getColorCode(nodeElement.getColorIndex()), (short) txtChildElement.getWeight(), (short) txtChildElement.getLineStyle(), (short) txtChildElement.getJustification(), (float) txtChildElement.getTextHeight(), (float) txtChildElement.getTextWidth(), (float) angle, sb.toString() }); } } } else { logger.info("CreateMultiSymbolStrategy 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); } } } private static class EPSG3826AnchorGeometryConverterDecorator extends EPSG3826GeometryConverterDecorator { public Geometry toGeometry(GeometryFactory factory) { if (getConverter() == null) Assert.shouldNeverReachHere(); getCoordinatesFilter().reset(); GeometryConverter converter = getConverter(); Geometry geom = null; try { if (converter instanceof TextElement) { geom = ((TextElement) converter).toAnchorGeometry(factory); } else if (converter instanceof TextNodeElement) { geom = ((TextNodeElement) converter).toAnchorGeometry(factory); } } catch (ArrayStoreException e) { logger.warn(e.getMessage(), e); if (converter instanceof TextNodeElement) { TextNodeElement node = (TextNodeElement) converter; CoordinateList pts = new CoordinateList(); for (int i = 0; i < node.size(); i++) { TextElement txtElm = (TextElement) node.get(i); Coordinate[] coords = txtElm.toAnchorCoordinates(); logger.warn("-coords=[" + coords.length + "]"); for (int j = 0; j < coords.length; j++) { logger.warn("[" + j + "]-" + coords.toString()); } } } } if (geom == null) return null; geom.apply(getCoordinatesFilter()); return geom; } } private static class EPSG3825AnchorGeometryConverterDecorator extends EPSG3825GeometryConverterDecorator { public Geometry toGeometry(GeometryFactory factory) { if (getConverter() == null) Assert.shouldNeverReachHere(); getCoordinatesFilter().reset(); GeometryConverter converter = getConverter(); Geometry geom = null; try { if (converter instanceof TextElement) { geom = ((TextElement) converter).toAnchorGeometry(factory); } else if (converter instanceof TextNodeElement) { geom = ((TextNodeElement) converter).toAnchorGeometry(factory); } } catch (ArrayStoreException e) { logger.warn(e.getMessage(), e); if (converter instanceof TextNodeElement) { TextNodeElement node = (TextNodeElement) converter; CoordinateList pts = new CoordinateList(); for (int i = 0; i < node.size(); i++) { TextElement txtElm = (TextElement) node.get(i); Coordinate[] coords = txtElm.toAnchorCoordinates(); logger.warn("-coords=[" + coords.length + "]"); for (int j = 0; j < coords.length; j++) { logger.warn("[" + j + "]-" + coords.toString()); } } } } if (geom == null) return null; geom.apply(getCoordinatesFilter()); return geom; } } }