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);
}
}