From e08301c599a383107211d6aa051f4c42b0c9b250 Mon Sep 17 00:00:00 2001 From: ?? ? <ulysseskao@ximple.com.tw> Date: Tue, 12 Aug 2008 15:49:30 +0800 Subject: [PATCH] update for EOFM-144 --- xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java | 208 ++++++++++++++++++++++++++++++++++ xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java | 12 ++ .gitattributes | 1 xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java | 21 +++ xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java | 42 +++++++ xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml | 15 ++ xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java | 12 + xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml | 15 ++ 8 files changed, 325 insertions(+), 1 deletions(-) diff --git a/.gitattributes b/.gitattributes index 30444fa..acb8a46 100644 --- a/.gitattributes +++ b/.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 diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java index 79ca5eb..28aa8e5 100644 --- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java +++ b/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(); diff --git a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java b/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java index fbab7cd..f4e5c76 100644 --- a/xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java +++ b/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); diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java new file mode 100644 index 0000000..542ba6b --- /dev/null +++ b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateMultiSymbolStrategy.java @@ -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; + } + } +} + diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java index 4fb6712..b2a9fa1 100644 --- a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java +++ b/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; + } } diff --git a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java b/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java index 0cb12d5..95ca1d8 100644 --- a/xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java +++ b/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) { diff --git a/xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml b/xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml index 9686501..6719421 100644 --- a/xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml +++ b/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"/> diff --git a/xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml b/xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml index 0272b88..2032c3c 100644 --- a/xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml +++ b/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"/> -- Gitblit v0.0.0-SNAPSHOT