.gitattributes
@@ -63,6 +63,7 @@ xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateFeatureTypeStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateShapeStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateSymbolStrategy.java svneol=native#text/plain xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateTextStrategy.java svneol=native#text/plain xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java
@@ -12,6 +12,7 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.CoordinateList; import com.ximple.util.DgnUtility; @@ -230,6 +231,47 @@ return factory.createPoint(getUserOrigin()); } public Geometry toAnchorGeometry(GeometryFactory factory) { if (getText() == null) { return factory.createMultiPoint(new Coordinate[] {}); } return factory.createMultiPoint(toAnchorCoordinates()); } public Coordinate[] toAnchorCoordinates() { CoordinateList result = new CoordinateList(); int len = getText().trim().length(); if (len == 0) return result.toCoordinateArray(); double width = getUserWidth(); double height = getUserHeight(); double angle = Math.toRadians(getRotationAngle()); AffineTransform at = new AffineTransform(); at.translate(width, height); Coordinate p = getOrigin(); at.setToRotation(angle, p.x, p.y); at.scale(1, 1); for (int i = 0; i < len; i++) { double[] srcPt = new double[2]; double[] dstPt = new double[2]; srcPt[0] = p.x + width * i; srcPt[1] = p.y; at.transform(srcPt, 0, dstPt, 0, 1); result.add(new Coordinate(dstPt[0], dstPt[1]), true); } return result.toCoordinateArray(); } private double getUserWidth() { int just = getJustification(); xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java
@@ -13,6 +13,7 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.CoordinateList; import com.ximple.util.DgnUtility; @@ -184,6 +185,17 @@ // return factory.createMultiPoint(coords.toCoordinateArray()); } public Geometry toAnchorGeometry(GeometryFactory factory) { CoordinateList coords = new CoordinateList(); for (int i = 0; i < size(); i++) { TextElement txtElm = (TextElement) get(i); coords.add(txtElm.toAnchorCoordinates()); } return factory.createMultiPoint(coords.toCoordinateArray()); } public int getTotalWords() { return (raw[18] & 0x0000ffff); xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java
New file @@ -0,0 +1,208 @@ package com.ximple.eofms.filter; import java.util.TreeMap; import java.util.List; import java.math.BigDecimal; import java.math.RoundingMode; import javax.swing.event.EventListenerList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.geotools.feature.FeatureTypeBuilder; import org.geotools.feature.FeatureType; import org.geotools.feature.SchemaException; import org.geotools.feature.Feature; import org.geotools.feature.IllegalAttributeException; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.util.Assert; import com.ximple.eofms.util.TWD97GeometryConverterDecorator; import com.ximple.eofms.util.FeatureTypeBuilderUtil; import com.ximple.eofms.util.DefaultColorTable; import com.ximple.io.dgn7.FrammeAttributeData; import com.ximple.io.dgn7.Element; import com.ximple.io.dgn7.UserAttributeData; import com.ximple.io.dgn7.TextElement; import com.ximple.io.dgn7.TextNodeElement; import com.ximple.io.dgn7.GeometryConverter; public class CreateMultiSymbolStrategy implements CreateFeatureTypeStrategy { static final Log logger = LogFactory.getLog(CreateMultiSymbolStrategy.class); GeometryFactory geometryFactory = new GeometryFactory(); TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>(); TWD97AnchorGeometryConverterDecorator convertDecorator = new TWD97AnchorGeometryConverterDecorator(); // Create the listener list protected EventListenerList listenerList = new EventListenerList(); public CreateMultiSymbolStrategy() { } protected FrammeAttributeData getFeatureLinkage(Element element) { if (!element.hasUserAttributeData()) return null; List<UserAttributeData> 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) 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(); if (txtElement.getText().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 = txtElement.getText().toCharArray()[0]; sb.append(Integer.toOctalString((int) id)); sb.append("-"); sb.append(txtElement.getFontIndex()); convertDecorator.setConverter(txtElement); Geometry gobj = convertDecorator.toGeometry(geometryFactory); if (gobj != null) feature = featureType.create(new Object[]{ gobj, fLinkage.getFsc(), (long) fLinkage.getUfid(), (short) fLinkage.getComponentID(), (short) 0, (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; } String[] tmpstrs = nodeElement.getTextArray(); StringBuilder sb = new StringBuilder(); sb.append("OCT"); char id = tmpstrs[0].toCharArray()[0]; sb.append(Integer.toOctalString((int) id)); sb.append("-"); sb.append(nodeElement.getFontIndex()); convertDecorator.setConverter(nodeElement); Geometry gobj = convertDecorator.toGeometry(geometryFactory); if (gobj != null) feature = featureType.create(new Object[]{ gobj, fLinkage.getFsc(), (long) fLinkage.getUfid(), (short) fLinkage.getComponentID(), (short) 0, (short) nodeElement.getLevelIndex(), colorTable.getColorCode(nodeElement.getColorIndex()), (short) nodeElement.getWeight(), (short) nodeElement.getLineStyle(), (short) nodeElement.getJustification(), (float) nodeElement.getTextNodeHeight(), (float) nodeElement.getTextNodeLength(), (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 TWD97AnchorGeometryConverterDecorator extends TWD97GeometryConverterDecorator { public Geometry toGeometry(GeometryFactory factory) { if (getConverter() == null) Assert.shouldNeverReachHere(); getCoordinatesFilter().reset(); GeometryConverter converter = getConverter(); Geometry geom = null; if (converter instanceof TextElement) { geom = ((TextElement) converter).toAnchorGeometry(factory); } else if (converter instanceof TextNodeElement) { geom = ((TextNodeElement) converter).toAnchorGeometry(factory); } if (geom == null) return null; geom.apply(getCoordinatesFilter()); return geom; } } } xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java
@@ -8,6 +8,7 @@ import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; public final class FeatureTypeBuilderUtil { @@ -234,4 +235,24 @@ return typeBuilder; */ } public static FeatureTypeBuilder createMultiSymbolFeatureTypeBuilder(String featureName) { FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName); typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", MultiPoint.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("lid", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("level", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("just", Short.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("height", Float.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("width", Float.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("angle", Float.class, false)); typeBuilder.addType(AttributeTypeFactory.newAttributeType("symbol", String.class, false, 20)); return typeBuilder; } } xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java
@@ -28,6 +28,16 @@ this.converter = converter; } protected TWD97ConvertFilter getCoordinatesFilter() { return coordinatesFilter; } protected void setCoordinatesFilter(TWD97ConvertFilter coordinatesFilter) { this.coordinatesFilter = coordinatesFilter; } public Geometry toGeometry(GeometryFactory factory) { if (converter == null) Assert.shouldNeverReachHere(); @@ -40,7 +50,7 @@ return geom; } class TWD97ConvertFilter implements CoordinateSequenceFilter protected class TWD97ConvertFilter implements CoordinateSequenceFilter { public void filter(CoordinateSequence coordinateSequence, int i) { xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml
@@ -27,6 +27,11 @@ <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="LineTextCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> @@ -80,6 +85,11 @@ </pattern> <pattern value="SymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> @@ -146,6 +156,11 @@ <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="LineTextCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml
@@ -27,6 +27,11 @@ <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="LineTextCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> @@ -75,6 +80,11 @@ </pattern> <pattern value="SymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> @@ -136,6 +146,11 @@ <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="MultiSymbolCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateMultiSymbolStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/> <set-properties-rule/> </pattern> <pattern value="LineTextCreateStrategy"> <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/> <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>