Как получить SVG-узел по координатам с батиком
У меня есть SVG и точка (например (x,y) = (250 112)). Можно ли с помощью BATIK получить узел (элемент DOM) в заданной точке?
2 ответа
Я нашел ответ на форуме пользователей батика, разработанный пользователем templth, я не возражаю, я просто перепостил решение здесь, чтобы оно могло быть более значительным.
public Element elementAtPosition(Document doc, Point2D point) {
UserAgent userAgent = new UserAgentAdapter();
DocumentLoader loader = new DocumentLoader(userAgent);
BridgeContext context = new BridgeContext(userAgent, loader);
context.setDynamicState(BridgeContext.DYNAMIC);
GVTBuilder builder = new GVTBuilder();
GraphicsNode rootGraphicsNode = builder.build(context, doc);
// rootGraphicsNode can be offseted relative to coordinate system
// that means calling this method on coordinates taken directly from the svg file might not work
// check the bounds of rootGraphicsNode to determine where the elements actually are
// System.out.println(rootGraphicsNode.getBounds());
GraphicsNode graphicsNode = rootGraphicsNode.nodeHitAt(point);
if (graphicsNode != null) {
return context.getElement(graphicsNode);
} else {
// if graphicsNode is null there is no element at this position
return null;
}
}
Проверено на батике 1.9. Этот метод возвращает только самый верхний элемент в указанной позиции. В качестве обходного пути вы можете удалить элемент и снова вызвать nodeHitAt.
private static class SVGMouseListener implements MouseListener {
private final JSVGCanvas svgCanvas;
public SVGMouseListener(JSVGCanvas jsvgCanvas) {
this.svgCanvas = jsvgCanvas;
}
@Override
public void mouseClicked(MouseEvent e) {
// Get the BridgeContext
BridgeContext bridgeContext = svgCanvas.getUpdateManager().getBridgeContext();
// Get the GraphicsNode at the SVG coordinates
GraphicsNode gvtRoot = svgCanvas.getGraphicsNode();
GraphicsNode svgNode = gvtRoot.nodeHitAt(new Point2D.Float(e.getX(), e.getY()));
// Handle the element
if (svgNode != null) {
Element element = bridgeContext.getElement(svgNode);
if (element != null) {
System.out.println("Clicked on element with ID: " + element.getAttribute("id"));
}
}
}
Вам нужно было позвонитьsvgCanvas.setDocumentState(JSVGComponent.ALWAYS_DYNAMIC)
, в противном случаеUpdateManager
принадлежащийsvgCanvas
нулевой.