jxmapviewer2 icon indicating copy to clipboard operation
jxmapviewer2 copied to clipboard

Divided by zero ArithmeticException in AbstractTileFactory (v2.6)

Open Ulathar opened this issue 4 years ago • 2 comments

Hi there,

I am getting a divided by zero Exception in the AbstractTileFactory whenever the JXMapViewer is not visible (hidden/collapsed in the UI):

java.lang.ArithmeticException: / by zero
	org.jxmapviewer.viewer.AbstractTileFactory.getTile(AbstractTileFactory.java:92)
	org.jxmapviewer.viewer.AbstractTileFactory.getTile(AbstractTileFactory.java:78)
	org.jxmapviewer.JXMapViewer.drawMapTiles(JXMapViewer.java:234)
	org.jxmapviewer.JXMapViewer.doPaintComponent(JXMapViewer.java:168)
	org.jxmapviewer.JXMapViewer.paintComponent(JXMapViewer.java:151)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1075)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JSplitPane.paintChildren(JSplitPane.java:1024)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:590)
	java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:908)
	java.desktop/javax.swing.JComponent.paint(JComponent.java:1084)
	java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5256)
	java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1633)
	java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1608)
	java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1546)
	java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1313)
	java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5204)
	java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5014)
	java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:857)
	java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:840)
	java.base/java.security.AccessController.doPrivileged(Native Method)
	java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
	java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:840)
	java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:815)
	java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:764)
	java.desktop/javax.swing.RepaintManager.access$1200(RepaintManager.java:69)
	java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1880)
	java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764)
	java.desktop/java.awt.EventQueue.access$500(EventQueue.java:97)
	java.desktop/java.awt.EventQueue$3.run(EventQueue.java:717)
	java.desktop/java.awt.EventQueue$3.run(EventQueue.java:711)
	java.base/java.security.AccessController.doPrivileged(Native Method)
	java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
	java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:734)
	eu.sag.mmfw.proxy.EventQueueProxy.dispatchEvent(EventQueueProxy.java:40)
	java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:199)
	java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Taking a closer look it seems like there is no check in the AbstractTileFactory for the case that (int) getMapSize(zoom).getWidth() returns 0 resulting in divided by zero at tileX = tileX % numTilesWide;:

private Tile getTile(int tpx, int tpy, int zoom, boolean eagerLoad)
    {
        // wrap the tiles horizontally --> mod the X with the max width
        // and use that
        int tileX = tpx;// tilePoint.getX();
        int numTilesWide = (int) getMapSize(zoom).getWidth();
        if (tileX < 0)
        {
            tileX = numTilesWide - (Math.abs(tileX) % numTilesWide);
        }

        tileX = tileX % numTilesWide;
...
}

Is this supposed to happen and the error is on m side?

Ulathar avatar Oct 19 '21 10:10 Ulathar

Thanks for the detailed report! Looks like a bug to me. It should be fairly easy to fix ... do you want to give it a try and open a PR?

msteiger avatar Oct 21 '21 07:10 msteiger

Yes I can / will do that but will take some days, don't have much time at the moment.

Ulathar avatar Nov 04 '21 09:11 Ulathar