import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.nodes.SVGNode;
+import org.simantics.scenegraph.utils.NodeUtil;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
import org.slf4j.Logger;
@Override
public Rectangle2D getBounds(IElement e, Rectangle2D size) {
- DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE);
+ DistrictNetworkEdgeNode edgeNode = e.getHint(KEY_DN_EDGE_NODE);
if (size == null)
size = new Rectangle2D.Double();
- if (edge != null)
- size.setFrame(DistrictNetworkEdgeNode.calculatePath(edge, null).getBounds2D());
+ if (edgeNode != null)
+ size.setFrame(edgeNode.getBoundsInLocal());
else
LOGGER.debug("Element {} does not have edge!", e);
@Override
public Shape getElementShape(IElement e) {
- DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE);
- if (edge != null) {
- return DistrictNetworkEdgeNode.calculatePath(edge, null);
+ DistrictNetworkEdgeNode edgeNode = e.getHint(KEY_DN_EDGE_NODE);
+ if (edgeNode != null) {
+ return edgeNode.getPath();
} else {
return getBounds(e, null);
}
Rectangle2D bounds = getBounds(s);
switch (policy) {
case PICK_CONTAINED_OBJECTS: return pickContainedObjects(edge, bounds);
- case PICK_INTERSECTING_OBJECTS: return pickIntersectingObjects(edge, bounds);
+ case PICK_INTERSECTING_OBJECTS: return pickIntersectingObjects(e, edge, bounds);
}
return false;
}
return eminx >= bsminx && eminy >= boundsMinY && emaxx <= bsmaxx && emaxy <= boundsMaxY;
}
- private boolean pickIntersectingObjects(DistrictNetworkEdge edge, Rectangle2D bounds) {
- double tolerance = (bounds.getHeight() + bounds.getHeight()) * 1 / MapScalingTransform.getScaleX();
- Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint());
+ private boolean pickIntersectingObjects(IElement e, DistrictNetworkEdge edge, Rectangle2D bounds) {
+ double dx = bounds.getWidth() / MapScalingTransform.getScaleX();
+ double dy = bounds.getHeight() / MapScalingTransform.getScaleY();
+
+ // Half the diagonal + half of the line width
+ DistrictNetworkEdgeNode node = e.getHint(KEY_DN_EDGE_NODE);
+ AffineTransform at = NodeUtil.getLocalToGlobalTransform(node);
+
+ Path2D path = node.getPath();
+ if (path == null)
+ return false;
+
+ double lineWidth = node.getStrokeWidth(at, true);
+ double tolerance = Math.sqrt(dx * dx + dy * dy) / 2 + lineWidth / 2;
+
double sx = bounds.getCenterX() / MapScalingTransform.getScaleX();
double sy = bounds.getCenterY() / MapScalingTransform.getScaleY();
- double ssx = ModelledCRS.xToLongitude(sx);
- double ssy = ModelledCRS.yToLatitude(-sy); // Invert for Simantics diagram coordinate system
- double distSq = line.ptSegDistSq(ssx, ssy);
-// System.out.println("s: " + sx + ", " + sy);
-// System.out.println("ss: " + ssx + ", " + ssy);
-// System.out.println("p1: " + edge.getStartPoint());
-// System.out.println("p2: " + edge.getEndPoint());
-// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")");
-// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance);
- return distSq <= tolerance * tolerance;
+
+ double coords[] = new double[6];
+ Point2D prevPoint = new Point2D.Double(), curPoint = new Point2D.Double();
+ Line2D line = new Line2D.Double();
+ for (PathIterator it = path.getPathIterator(null); !it.isDone(); it.next()) {
+ int type = it.currentSegment(coords);
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ curPoint.setLocation(coords[0], coords[1]);
+ break;
+ case PathIterator.SEG_LINETO:
+ prevPoint.setLocation(curPoint);
+ curPoint.setLocation(coords[0], coords[1]);
+ line.setLine(prevPoint, curPoint);
+ double distSq = line.ptSegDistSq(sx, sy);
+// System.out.println("s: " + sx + ", " + sy);
+// System.out.println("ss: " + ssx + ", " + ssy);
+// System.out.println("p1: " + edge.getStartPoint());
+// System.out.println("p2: " + edge.getEndPoint());
+// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")");
+// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance);
+ if (distSq <= tolerance * tolerance)
+ return true;
+ break;
+ default:
+ LOGGER.error("Invalid edge path", new IllegalStateException());
+ return false;
+ }
+ }
+
+ return false;
}
private Rectangle2D getBounds(Shape shape) {