Как получить 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нулевой.

Другие вопросы по тегам