package org.openstreetmap.josm.gui.bbox; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.util.Vector; import org.openstreetmap.gui.jmapviewer.Coordinate; import org.openstreetmap.gui.jmapviewer.JMapViewer; import org.openstreetmap.gui.jmapviewer.MapMarkerDot; import org.openstreetmap.gui.jmapviewer.MemoryTileCache; import org.openstreetmap.gui.jmapviewer.OsmFileCacheTileLoader; import org.openstreetmap.gui.jmapviewer.OsmMercator; import org.openstreetmap.gui.jmapviewer.OsmTileLoader; import org.openstreetmap.gui.jmapviewer.OsmTileSource; import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker; import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader; import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.LatLon; public class SlippyMapBBoxChooser extends JMapViewer implements BBoxChooser{ static private TileSource[] TILE_SOURCES = { new OsmTileSource.Mapnik(), new OsmTileSource.TilesAtHome(), new OsmTileSource.CycleMap() }; // standard dimension private Dimension iDownloadDialogDimension; private TileLoader cachedLoader; private TileLoader uncachedLoader; private SizeButton iSizeButton = new SizeButton(); private SourceButton iSourceButton = new SourceButton(); private Bounds bbox; // upper left and lower right corners of the selection rectangle (x/y on // ZOOM_MAX) Point iSelectionRectStart; Point iSelectionRectEnd; public SlippyMapBBoxChooser() { super(); try { cachedLoader = new OsmFileCacheTileLoader(this); } catch (SecurityException e) { // set to null if a SecurityException was thrown // while creating the cachedLoader // cachedLoader = null; } uncachedLoader = new OsmTileLoader(this); setZoomContolsVisible(false); setMapMarkerVisible(false); setMinimumSize(new Dimension(350, 350 / 2)); // We need to set an initial size - this prevents a wrong zoom selection // for // the area before the component has been displayed the first time setBounds(new Rectangle(getMinimumSize())); if (cachedLoader == null) { setFileCacheEnabled(false); } else { setFileCacheEnabled(Main.pref.getBoolean("slippy_map_chooser.file_cache", true)); } setMaxTilesInMemory(Main.pref.getInteger("slippy_map_chooser.max_tiles", 1000)); String mapStyle = Main.pref.get("slippy_map_chooser.mapstyle", "mapnik"); if (mapStyle.equals("osmarender")) { iSourceButton.setMapStyle(SourceButton.OSMARENDER); this.setTileSource(TILE_SOURCES[1]); } else if (mapStyle.equals("cyclemap")) { iSourceButton.setMapStyle(SourceButton.CYCLEMAP); this.setTileSource(TILE_SOURCES[2]); } else { if (!mapStyle.equals("mapnik")) { Main.pref.put("slippy_map_chooser", "mapnik"); } } new SlippyMapControler(this, this, iSizeButton, iSourceButton); } protected Point getTopLeftCoordinates() { return new Point(center.x - (getWidth() / 2), center.y - (getHeight() / 2)); } /** * Draw the map. */ @Override public void paint(Graphics g) { try { super.paint(g); // draw selection rectangle if (iSelectionRectStart != null && iSelectionRectEnd != null) { int zoomDiff = MAX_ZOOM - zoom; Point tlc = getTopLeftCoordinates(); int x_min = (iSelectionRectStart.x >> zoomDiff) - tlc.x; int y_min = (iSelectionRectStart.y >> zoomDiff) - tlc.y; int x_max = (iSelectionRectEnd.x >> zoomDiff) - tlc.x; int y_max = (iSelectionRectEnd.y >> zoomDiff) - tlc.y; int w = x_max - x_min; int h = y_max - y_min; g.setColor(new Color(0.9f, 0.7f, 0.7f, 0.6f)); g.fillRect(x_min, y_min, w, h); g.setColor(Color.BLACK); g.drawRect(x_min, y_min, w, h); } iSizeButton.paint(g); iSourceButton.paint(g); } catch (Exception e) { e.printStackTrace(); } } public void setFileCacheEnabled(boolean enabled) { if (enabled) { setTileLoader(cachedLoader); } else { setTileLoader(uncachedLoader); } } public void setMaxTilesInMemory(int tiles) { ((MemoryTileCache) getTileCache()).setCacheSize(tiles); } /** * Callback for the OsmMapControl. (Re-)Sets the start and end point of the * selection rectangle. * * @param aStart * @param aEnd */ public void setSelection(Point aStart, Point aEnd) { if (aStart == null || aEnd == null || aStart.x == aEnd.x || aStart.y == aEnd.y) return; Point p_max = new Point(Math.max(aEnd.x, aStart.x), Math.max(aEnd.y, aStart.y)); Point p_min = new Point(Math.min(aEnd.x, aStart.x), Math.min(aEnd.y, aStart.y)); Point tlc = getTopLeftCoordinates(); int zoomDiff = MAX_ZOOM - zoom; Point pEnd = new Point(p_max.x + tlc.x, p_max.y + tlc.y); Point pStart = new Point(p_min.x + tlc.x, p_min.y + tlc.y); pEnd.x <<= zoomDiff; pEnd.y <<= zoomDiff; pStart.x <<= zoomDiff; pStart.y <<= zoomDiff; iSelectionRectStart = pStart; iSelectionRectEnd = pEnd; Coordinate l1 = getPosition(p_max); Coordinate l2 = getPosition(p_min); Bounds b = new Bounds( new LatLon( Math.min(l2.getLat(), l1.getLat()), Math.min(l1.getLon(), l2.getLon()) ), new LatLon( Math.max(l2.getLat(), l1.getLat()), Math.max(l1.getLon(), l2.getLon())) ); Bounds oldValue = this.bbox; this.bbox = b; firePropertyChange(BBOX_PROP, oldValue, this.bbox); repaint(); } /** * Performs resizing of the DownloadDialog in order to enlarge or shrink the * map. */ public void resizeSlippyMap() { int w, h; // retrieve the size of the display Dimension iScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); // enlarge if(iDownloadDialogDimension == null) { // make the each dimension 90% of the absolute display size w = iScreenSize.width * 90 / 100; h = iScreenSize.height * 90 / 100; } // shrink else { // set the size back to the initial dimensions w = iDownloadDialogDimension.width; h = iDownloadDialogDimension.height; iDownloadDialogDimension = null; } repaint(); } public void toggleMapSource(int mapSource) { this.tileController.setTileCache(new MemoryTileCache()); if (mapSource == SourceButton.MAPNIK) { this.setTileSource(TILE_SOURCES[0]); Main.pref.put("slippy_map_chooser.mapstyle", "mapnik"); } else if (mapSource == SourceButton.CYCLEMAP) { this.setTileSource(TILE_SOURCES[2]); Main.pref.put("slippy_map_chooser.mapstyle", "cyclemap"); } else { this.setTileSource(TILE_SOURCES[1]); Main.pref.put("slippy_map_chooser.mapstyle", "osmarender"); } } public Bounds getBoundingBox() { return bbox; } /** * Sets the current bounding box in this bbox chooser without * emiting a property change event. * * @param bbox the bounding box. null to reset the bounding box */ public void setBoundingBox(Bounds bbox) { if (bbox == null) { this.bbox = null; return; } // test if a bounding box has been set if (bbox.getMin().lat() == 0.0 && bbox.getMin().lon() == 0.0 && bbox.getMax().lat() == 0.0 && bbox.getMax().lon() == 0.0) { this.bbox = null; } int y1 = OsmMercator.LatToY(bbox.getMin().lat(), MAX_ZOOM); int y2 = OsmMercator.LatToY(bbox.getMax().lat(), MAX_ZOOM); int x1 = OsmMercator.LonToX(bbox.getMin().lon(), MAX_ZOOM); int x2 = OsmMercator.LonToX(bbox.getMax().lon(), MAX_ZOOM); iSelectionRectStart = new Point(Math.min(x1, x2), Math.min(y1, y2)); iSelectionRectEnd = new Point(Math.max(x1, x2), Math.max(y1, y2)); // calc the screen coordinates for the new selection rectangle MapMarkerDot xmin_ymin = new MapMarkerDot(bbox.getMin().lat(), bbox.getMin().lon()); MapMarkerDot xmax_ymax = new MapMarkerDot(bbox.getMax().lat(), bbox.getMax().lon()); Vector<MapMarker> marker = new Vector<MapMarker>(2); marker.add(xmin_ymin); marker.add(xmax_ymax); setMapMarkerList(marker); setDisplayToFitMapMarkers(); zoomOut(); this.bbox = bbox; } }