SVG Koordinaten auslesen

Tatsächlich. Hab’ nochmal geschaut: Da passiert ziemlich viel Magie intern, zu viel als dass ich die Details jetzt auf die Schnelle nachvollziehen und erklären könnte.

Der relevante Unterschied scheint (!) zu sein: Das europe.svg definiert keine viewBox. Aber das floor_plan.svg hat eine viewBox:

<svg version="1.1" id="Layer_1" 
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    x="0px" y="0px" width="1318.43359px" height="775.46094px" 
    viewBox="0 0 1318.43359 775.46094"
    ...
    >

Das scheint wohl die “Standardgröße” zu sein, und der JSVGCanvas berücksichtigt das irgendwie.

Das zeigt sich auch schon durch ein unterschiedliches Verhalten:

  • Wenn man beim europe.svg die Fenstergröße ändert, bleibt das gerenderte gleich groß (man sieht nur einen kleineren oder größeren Teil davon)
  • Wenn man beim floor_plan.svg die Fenstergröße ändert, ändert sich das gerenderte mit: Man sieht immer den gleichen Ausschnitt, aber es wird größer bzw. kleiner gezeichnet.

Welches Verhalten man haben will und wie man das ggf. umschaltet…!? Joa, das müßte man sich überlegen bzw. ansehen.

Wenn es erstmal nur um das Ziel geht, die Weltkoordinaten konsistent auszulesen, dann sollte es schon reichen, getRenderingTransform durch getViewBoxTransform zu ersetzen:

import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.nio.file.Paths;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

import org.apache.batik.swing.JSVGCanvas;

public class SvgCoordinatesTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JSVGCanvas canvas = new JSVGCanvas();
        canvas.setURI(Paths.get("floor_plan.svg").toUri().toString());
        canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);

        canvas.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mousePressed(MouseEvent e)
            {
                System.out.println("Screen coordinates: " + e.getPoint());
                AffineTransform at = canvas.getViewBoxTransform();
                Point2D worldCoordinates = null;
                try
                {
                    worldCoordinates = at.inverseTransform(e.getPoint(), null);
                }
                catch (NoninvertibleTransformException ex)
                {
                    ex.printStackTrace();
                }
                System.out.println("World coordinates: " + worldCoordinates);
            }
        });

        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(new JLabel(
            "<html>" + 
            "Arrow keys to translate<br>" + 
            "CTRL+I and CTRL+O to zoom" + 
            "</html>"), BorderLayout.NORTH);
        f.getContentPane().add(canvas, BorderLayout.CENTER);

        f.setSize(1000, 1000);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

Danke Marco13. Vielen, vielen Dank für Deine großartige Hilfe.