Search code examples
javagoogle-mapsmouseeventzoomingjmapviewer

JMapViewer disable zoom


Is there a way to prevent the map from zooming outside from a certian zoom level? I've tried to cancel the mouse wheel scrolling event (in case its a zoom out), and to hide the zoom in/out control.

map.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent arg0) {
    int newZoom = map.getZoom();
    if (lastZoom < newZoom) {
        zoomIn = true;
    } else {
        arg0.consume();
        zoomIn = false;
    }

Just to make sure: I want to allow zooming, but until specific zoom level only.

Thanks,


Solution

  • You can extend JMapViewer to override setZoom() method. For example:

    import java.awt.Point;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import org.openstreetmap.gui.jmapviewer.JMapViewer;
    
    public class TestMapZoom {
    
        static class CustomMap extends JMapViewer {
            private int maxZoomLevel;
    
            public CustomMap() {
                this.maxZoomLevel = 7;
            }
    
            public int getMaxZoomLevel() {
                return maxZoomLevel;
            }
    
            public void setMaxZoomLevel(int maxZoom) {
                this.maxZoomLevel = maxZoom;
            }
    
            @Override
            public void setZoom(int zoom, Point mapPoint) {
                if (zoom < getMaxZoomLevel())
                    super.setZoom(zoom, mapPoint);
            }
        }
    
        private static void createAndShowUI() {
            JFrame frame = new JFrame("Demo");
            CustomMap viewer = new CustomMap();
    
            frame.add(viewer);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationByPlatform(true);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }
    

    EDIT: version without JMapViewer extension

    Another, slightly cleaner approach that does not require extension of JMapViewer may be a replacement of the controller used by the map. Default JMapViewer constructor installs DefaultMapController, this example uses another constructor and extended version of the controller:

    import java.awt.event.MouseWheelEvent;
    
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    import org.openstreetmap.gui.jmapviewer.DefaultMapController;
    import org.openstreetmap.gui.jmapviewer.JMapViewer;
    import org.openstreetmap.gui.jmapviewer.MemoryTileCache;
    
    public class TestMapZoom2 {
    
        static class CustomMapController extends DefaultMapController {
            private int maxZoomLevel;
    
            public CustomMapController(JMapViewer map) {
                super(map);
                this.maxZoomLevel = 7;
            }
    
            public int getMaxZoomLevel() {
                return maxZoomLevel;
            }
    
            public void setMaxZoomLevel(int maxZoom) {
                this.maxZoomLevel = maxZoom;
            }
    
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) { 
                if (e.getWheelRotation() < 0 && map.getZoom() >= getMaxZoomLevel())
                    return;
                super.mouseWheelMoved(e);   
            }
        }
    
        private static void createAndShowUI() {
            JFrame frame = new JFrame("Demo");
            JMapViewer viewer = new JMapViewer(new MemoryTileCache(), 8);
            new CustomMapController(viewer);
    
            frame.add(viewer);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationByPlatform(true);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }