/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package de.cismet.cismap.commons.gui.piccolo.eventlistener; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.TopologyException; import com.vividsolutions.jts.linearref.LengthIndexedLine; import edu.umd.cs.piccolo.util.PDimension; import java.awt.Color; import java.awt.Paint; import java.awt.Stroke; import java.util.Collection; import javax.swing.ImageIcon; import javax.swing.JComponent; import de.cismet.cismap.commons.Refreshable; import de.cismet.cismap.commons.features.*; import de.cismet.cismap.commons.gui.MappingComponent; import de.cismet.cismap.commons.gui.piccolo.PFeature; import de.cismet.cismap.commons.interaction.CismapBroker; /** * DOCUMENT ME! * * @author jruiz * @version $Revision$, $Date$ */ public class LinearReferencedLineFeature extends DefaultStyledFeature implements DrawSelectionFeature, XStyledFeature, SelfManipulatingFeature { //~ Static fields/initializers --------------------------------------------- public static final Color DEFAULT_COLOR = new Color(255, 91, 0); public static final boolean FROM = true; public static final boolean TO = false; private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger( LinearReferencedLineFeature.class); private static final ImageIcon ico = new javax.swing.ImageIcon(LinearReferencedLineFeature.class.getResource( "/de/cismet/cismap/commons/gui/res/linRefPointIcon.png")); // NOI18N //~ Instance fields -------------------------------------------------------- private LinearReferencedPointFeature fromFeature; private LinearReferencedPointFeature toFeature; private Geometry baseLineGeom; private FeatureCollectionListener featureCollectionListener; private boolean featCollLock = false; private LinearReferencedPointFeatureHandler fromPointListener; private LinearReferencedPointFeatureHandler toPointListener; //~ Constructors ----------------------------------------------------------- /** * Creates a new LinearReferencedLineFeature object. * * @param fromFeature DOCUMENT ME! * @param toFeature DOCUMENT ME! */ public LinearReferencedLineFeature(final LinearReferencedPointFeature fromFeature, final LinearReferencedPointFeature toFeature) { this.baseLineGeom = fromFeature.getLineGeometry(); setLineWidth(4); setLinePaint(DEFAULT_COLOR); setPrimaryAnnotationVisible(false); fromPointListener = new LinearReferencedPointFeatureHandler(FROM); toPointListener = new LinearReferencedPointFeatureHandler(TO); initFeatureCollectionListener(); setPointFeature(fromFeature, FROM); setPointFeature(toFeature, TO); } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @param pointFeature DOCUMENT ME! * @param isFrom DOCUMENT ME! */ public final void setPointFeature(final LinearReferencedPointFeature pointFeature, final boolean isFrom) { final LinearReferencedPointFeature oldFeature = (isFrom) ? fromFeature : toFeature; final LinearReferencedPointFeatureHandler listener = (isFrom) ? fromPointListener : toPointListener; if (oldFeature != null) { oldFeature.removeListener(listener); } if (pointFeature != null) { pointFeature.addListener(listener); } if (isFrom) { this.fromFeature = pointFeature; } else { this.toFeature = pointFeature; } updateGeometry(); } /** * DOCUMENT ME! * * @param isFrom DOCUMENT ME! * * @return DOCUMENT ME! */ public LinearReferencedPointFeature getPointFeature(final boolean isFrom) { return (isFrom) ? fromFeature : toFeature; } @Override public void setLinePaint(final Paint linePaint) { super.setLinePaint(linePaint); final MappingComponent mc = CismapBroker.getInstance().getMappingComponent(); final PFeature pFeature = mc.getPFeatureHM().get(this); if (pFeature != null) { pFeature.visualize(); } } /** * DOCUMENT ME! */ private void initFeatureCollectionListener() { featureCollectionListener = new FeatureCollectionAdapter() { @Override public void featureSelectionChanged(final FeatureCollectionEvent fce) { final Collection<Feature> features = fce.getEventFeatures(); final FeatureCollection collection = CismapBroker.getInstance() .getMappingComponent() .getFeatureCollection(); if (!featCollLock) { featCollLock = true; try { boolean addFeaturesToCollection = false; if (features != null) { for (final Feature feature : features) { if (collection.isSelected(feature) && (feature instanceof LinearReferencedLineFeature) && (((LinearReferencedLineFeature)feature) == LinearReferencedLineFeature.this)) { addFeaturesToCollection = true; } } } if (addFeaturesToCollection) { collection.addToSelection(fromFeature); collection.addToSelection(toFeature); } } finally { featCollLock = false; } } } }; CismapBroker.getInstance() .getMappingComponent() .getFeatureCollection() .addFeatureCollectionListener(featureCollectionListener); } /** * DOCUMENT ME! * * @param von DOCUMENT ME! * @param bis DOCUMENT ME! * @param auf DOCUMENT ME! * * @return DOCUMENT ME! */ public static Geometry createSubline(final double von, final double bis, final Geometry auf) { final LengthIndexedLine lil = new LengthIndexedLine(auf); return lil.extractLine(von, bis); } /** * DOCUMENT ME! */ public final void updateGeometry() { if (LOG.isDebugEnabled()) { LOG.debug("update Geometry"); } if ((fromFeature != null) && (toFeature != null)) { Geometry sublineGeom; if (fromFeature != toFeature) { double from = fromFeature.getCurrentPosition(); double to = toFeature.getCurrentPosition(); if (from == to) { if (from >= 1) { from = from - 1; } else { to = to + 1; } } sublineGeom = createSubline(from, to, baseLineGeom); } else { sublineGeom = fromFeature.getGeometry(); } setGeometry(sublineGeom); final MappingComponent mc = CismapBroker.getInstance().getMappingComponent(); final PFeature pFeature = mc.getPFeatureHM().get(this); if (pFeature != null) { pFeature.setCoordArr(0, 0, sublineGeom.getCoordinates()); pFeature.updatePath(); pFeature.syncGeometry(); pFeature.visualize(); } } } @Override public ImageIcon getIconImage() { return ico; } @Override public String getName() { return "Stationierte Linie"; } @Override public String getType() { return "Stationierte Linie"; } @Override public JComponent getInfoComponent(final Refreshable refresh) { return null; } @Override public Stroke getLineStyle() { return null; } @Override public boolean isDrawingSelection() { return false; } @Override public synchronized void moveTo(final Coordinate coord, final PDimension delta) { final Geometry originFromGeom = fromFeature.getGeometry(); final double fromX = fromFeature.getGeometry().getCoordinate().x; final double fromY = fromFeature.getGeometry().getCoordinate().y; final Coordinate fromCoord = new Coordinate(fromX + delta.getWidth(), fromY - delta.getHeight()); final Geometry originToGeom = toFeature.getGeometry(); final double length = toFeature.getCurrentPosition() - fromFeature.getCurrentPosition(); try { fromFeature.moveTo(fromCoord, delta); toFeature.moveToPosition(fromFeature.getCurrentPosition() + length); } catch (TopologyException e) { toFeature.moveTo(originToGeom.getCoordinate(), delta); fromFeature.moveTo(originFromGeom.getCoordinate(), delta); } final double newLength = toFeature.getCurrentPosition() - fromFeature.getCurrentPosition(); if (Math.abs(length - newLength) > 0.1) { fromFeature.setGeometry(originFromGeom); toFeature.setGeometry(originToGeom); } } @Override public void moveFinished() { fromFeature.moveFinished(); toFeature.moveFinished(); } //~ Inner Classes ---------------------------------------------------------- /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ class LinearReferencedPointFeatureHandler implements LinearReferencedPointFeatureListener { //~ Instance fields ---------------------------------------------------- private boolean isFrom; //~ Constructors ------------------------------------------------------- /** * Creates a new LinearReferencedPointFeatureHandler object. * * @param isFrom DOCUMENT ME! */ LinearReferencedPointFeatureHandler(final boolean isFrom) { this.isFrom = isFrom; } //~ Methods ------------------------------------------------------------ @Override public void featureMerged(final LinearReferencedPointFeature mergePoint, final LinearReferencedPointFeature withPoint) { setPointFeature(withPoint, isFrom); updateGeometry(); } @Override public void featureMoved(final LinearReferencedPointFeature pointFeature) { updateGeometry(); } } }