+
+ // Draw arrow
+ if (arrowLength != null) {
+ g2d.setColor(Color.BLACK);
+ float lw = STROKE.getLineWidth() / (float)scale;
+ g2d.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
+
+ double l = arrowLength;
+ double w = 2 * (double) lw * Math.signum(l);
+ if (Math.abs(w) > Math.abs(l)) w = l;
+ double offset = 2 * (double) lw;
+
+ Point2D centerPoint = getCenterPoint(zoomLevel);
+ Point2D direction = getDirection(zoomLevel);
+ double centerX = centerPoint.getX(), centerY = centerPoint.getY();
+ double deltaX = direction.getX(), deltaY = direction.getY();
+
+ // Ensure the line is always rendered on top of the edge
+ // to prevent overlap with static info rendered below it.
+ double odx = offset * deltaY;
+ double ody = offset * deltaX;
+ if (odx < 0) {
+ odx = -odx;
+ ody = -ody;
+ }
+
+ double x0 = centerX - l/2 * deltaX + ody;
+ double y0 = centerY - l/2 * deltaY - odx;
+ double x1 = centerX + (l/2 - w) * deltaX + ody;
+ double y1 = centerY + (l/2 - w) * deltaY - odx;
+
+ g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+
+ arrowPath = new Path2D.Double();
+ arrowPath.moveTo(x1 + w * deltaX, y1 + w * deltaY);
+ arrowPath.lineTo(x1 + w * deltaY, y1 - w * deltaX);
+ arrowPath.lineTo(x1 - w * deltaY, y1 + w * deltaX);
+ arrowPath.closePath();
+ g2d.fill(arrowPath);
+ }
+
+ // Reset
+ g2d.setStroke(oldStroke);
+ g2d.setColor(oldColor);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);