/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package mobac.gui.actions; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import mobac.data.gpx.gpx11.TrkType; import mobac.data.gpx.gpx11.TrksegType; import mobac.data.gpx.interfaces.GpxPoint; import mobac.exceptions.InvalidNameException; import mobac.gui.MainGUI; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.components.JDistanceSlider; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.gpxtree.TrkEntry; import mobac.gui.gpxtree.TrksegEntry; import mobac.gui.mapview.layer.MapAreaHighlightingLayer; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Layer; import mobac.program.model.MapPolygon; import mobac.program.model.SelectedZoomLevels; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters; import mobac.program.model.UnitSystem; import mobac.utilities.I18nUtils; public class AddGpxTrackPolygonMap implements ActionListener { public static final AddGpxTrackPolygonMap INSTANCE = new AddGpxTrackPolygonMap(); private MapAreaHighlightingLayer msl = null; public void actionPerformed(ActionEvent event) { final MainGUI mg = MainGUI.getMainGUI(); GpxEntry entry = mg.gpxPanel.getSelectedEntry(); if (entry == null) return; TrksegType trk = null; TrkType t = null; if (entry instanceof TrksegEntry) { trk = ((TrksegEntry) entry).getTrkSeg(); } else if (entry instanceof GpxRootEntry) { GpxRootEntry re = (GpxRootEntry) entry; List<TrkType> tlist = re.getLayer().getGpx().getTrk(); if (tlist.size() > 1) { JOptionPane .showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_too_many_track")); return; } else if (tlist.size() == 1) t = tlist.get(0); } if (entry instanceof TrkEntry) t = ((TrkEntry) entry).getTrk(); if (t != null) { if (t.getTrkseg().size() > 1) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_too_many_segment")); return; } else if (t.getTrkseg().size() == 1) trk = t.getTrkseg().get(0); } if (trk == null) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_no_select"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } JAtlasTree jAtlasTree = mg.jAtlasTree; final String mapNameFmt = "%s %02d"; AtlasInterface atlasInterface = jAtlasTree.getAtlas(); String name = mg.getUserText(); final MapSource mapSource = mg.getSelectedMapSource(); SelectedZoomLevels sZL = mg.getSelectedZoomLevels(); int[] zoomLevels = sZL.getZoomLevels(); if (zoomLevels.length == 0) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected")); return; } List<? extends GpxPoint> points = trk.getTrkpt(); final EastNorthCoordinate[] trackPoints = new EastNorthCoordinate[points.size()]; EastNorthCoordinate minCoordinate = new EastNorthCoordinate(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); EastNorthCoordinate maxCoordinate = new EastNorthCoordinate(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); for (int i = 0; i < trackPoints.length; i++) { GpxPoint gpxPoint = points.get(i); EastNorthCoordinate c = new EastNorthCoordinate(gpxPoint.getLat().doubleValue(), gpxPoint.getLon() .doubleValue()); minCoordinate.lat = Math.min(minCoordinate.lat, c.lat); minCoordinate.lon = Math.min(minCoordinate.lon, c.lon); maxCoordinate.lat = Math.max(maxCoordinate.lat, c.lat); maxCoordinate.lon = Math.max(maxCoordinate.lon, c.lon); trackPoints[i] = c; } final int maxZoom = zoomLevels[zoomLevels.length - 1]; final MapSpace mapSpace = mapSource.getMapSpace(); Point p1 = maxCoordinate.toTileCoordinate(mapSpace, maxZoom); Point p2 = minCoordinate.toTileCoordinate(mapSpace, maxZoom); final int centerY = p1.y + ((p1.y - p2.y) / 2); final UnitSystem unitSystem = Settings.getInstance().getUnitSystem(); final TileImageParameters customTileParameters = mg.getSelectedTileImageParameters(); JPanel panel = new JPanel(new BorderLayout()); panel.setPreferredSize(new Dimension(300, 100)); final JLabel label = new JLabel(""); final JDistanceSlider slider = new JDistanceSlider(mapSource.getMapSpace(), maxZoom, centerY, unitSystem, 5, 500); ChangeListener cl = new ChangeListener() { public void stateChanged(ChangeEvent e) { double d = mapSpace.horizontalDistance(maxZoom, centerY, slider.getValue()); d *= unitSystem.earthRadius * unitSystem.unitFactor; String unitName = unitSystem.unitSmall; if (d > unitSystem.unitFactor) { d /= unitSystem.unitFactor; unitName = unitSystem.unitLarge; } label.setText(String.format(I18nUtils.localizedStringForKey("dlg_gpx_track_select_distance"), ((int) d), unitName)); } }; final JButton previewButton = new JButton(I18nUtils.localizedStringForKey("dlg_gpx_track_select_preview")); previewButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int distance = slider.getValue(); MapPolygon maxZoomMap = MapPolygon.createTrackEnclosure(null, "Dummy", mapSource, maxZoom, trackPoints, distance, customTileParameters); if (msl != null) msl.setObject(maxZoomMap); msl = new MapAreaHighlightingLayer(maxZoomMap); mg.previewMap.repaint(); } }); cl.stateChanged(null); slider.addChangeListener(cl); panel.add(label, BorderLayout.NORTH); panel.add(slider, BorderLayout.CENTER); panel.add(previewButton, BorderLayout.SOUTH); int result = JOptionPane.showConfirmDialog(mg, panel, I18nUtils.localizedStringForKey("dlg_gpx_track_select_title"), JOptionPane.OK_CANCEL_OPTION); if (msl != null) { mg.previewMap.mapLayers.remove(msl); msl.setObject(null); } if (result != JOptionPane.OK_OPTION) return; int distance = slider.getValue(); MapPolygon maxZoomMap = MapPolygon.createTrackEnclosure(null, "Dummy", mapSource, maxZoom, trackPoints, distance, customTileParameters); String layerName = name; int c = 1; Layer layer = null; boolean success = false; do { try { layer = new Layer(atlasInterface, layerName); success = true; } catch (InvalidNameException e) { layerName = name + "_" + Integer.toString(c++); } } while (!success); int width = maxZoomMap.getMaxTileCoordinate().x - maxZoomMap.getMinTileCoordinate().x; int height = maxZoomMap.getMaxTileCoordinate().y - maxZoomMap.getMinTileCoordinate().y; if (Math.max(width, height) > Settings.getInstance().maxMapSize) { String msg = I18nUtils.localizedStringForKey("msg_add_gpx_polygon_maxsize"); result = JOptionPane.showConfirmDialog(mg, msg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_maxsize_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (result != JOptionPane.YES_OPTION) return; } for (int zoom : zoomLevels) { String mapName = String.format(mapNameFmt, new Object[] { layerName, zoom }); MapInterface map = MapPolygon.createFromMapPolygon(layer, mapName, zoom, maxZoomMap); layer.addMap(map); } atlasInterface.addLayer(layer); mg.jAtlasTree.getTreeModel().notifyNodeInsert(layer); } }