001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.projection;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GridBagLayout;
007import java.awt.event.ActionListener;
008import java.util.ArrayList;
009import java.util.Arrays;
010import java.util.Collection;
011import java.util.List;
012
013import javax.swing.ButtonGroup;
014import javax.swing.JLabel;
015import javax.swing.JPanel;
016import javax.swing.JRadioButton;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.tools.GBC;
020
021public class UTMProjectionChoice extends ListProjectionChoice {
022
023    /** Earth emispheres **/
024    public enum Hemisphere {
025        /** North emisphere */
026        North,
027        /** South emisphere */
028        South
029    }
030
031    private static final Hemisphere DEFAULT_HEMISPHERE = Hemisphere.North;
032
033    private Hemisphere hemisphere;
034
035    private static final List<String> cbEntries = new ArrayList<>();
036    static {
037        for (int i = 1; i <= 60; i++) {
038            cbEntries.add(Integer.toString(i));
039        }
040    }
041
042    /**
043     * Constructs a new {@code UTMProjectionChoice}.
044     */
045    public UTMProjectionChoice() {
046        super(tr("UTM"), /* NO-ICON */ "core:utm", cbEntries.toArray(new String[0]), tr("UTM Zone"));
047    }
048
049    private class UTMPanel extends CBPanel {
050
051        public JRadioButton north, south;
052
053        public UTMPanel(String[] entries, int initialIndex, String label, ActionListener listener) {
054            super(entries, initialIndex, label, listener);
055
056            north = new JRadioButton();
057            north.setSelected(hemisphere == Hemisphere.North);
058            south = new JRadioButton();
059            south.setSelected(hemisphere == Hemisphere.South);
060
061            ButtonGroup group = new ButtonGroup();
062            group.add(north);
063            group.add(south);
064
065            JPanel bPanel = new JPanel();
066            bPanel.setLayout(new GridBagLayout());
067
068            bPanel.add(new JLabel(tr("North")), GBC.std().insets(5, 5, 0, 5));
069            bPanel.add(north, GBC.std().fill(GBC.HORIZONTAL));
070            bPanel.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
071            bPanel.add(new JLabel(tr("South")), GBC.std().insets(5, 5, 0, 5));
072            bPanel.add(south, GBC.std().fill(GBC.HORIZONTAL));
073            bPanel.add(GBC.glue(1, 1), GBC.eol().fill(GBC.BOTH));
074
075            this.add(new JLabel(tr("Hemisphere")), GBC.std().insets(5,5,0,5));
076            this.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
077            this.add(bPanel, GBC.eop().fill(GBC.HORIZONTAL));
078            this.add(GBC.glue(1, 1), GBC.eol().fill(GBC.BOTH));
079
080            if (listener != null) {
081                north.addActionListener(listener);
082                south.addActionListener(listener);
083            }
084        }
085    }
086
087    @Override
088    public JPanel getPreferencePanel(ActionListener listener) {
089        return new UTMPanel(entries, index, label, listener);
090    }
091
092    @Override
093    public String getCurrentCode() {
094        int zone = index + 1;
095        int code = 32600 + zone + (hemisphere == Hemisphere.South ? 100 : 0);
096        return "EPSG:" + Integer.toString(code);
097    }
098
099    @Override
100    public String getProjectionName() {
101        return tr("UTM");
102    }
103
104
105    @Override
106    public Collection<String> getPreferences(JPanel panel) {
107        if (!(panel instanceof UTMPanel)) {
108            throw new IllegalArgumentException("Unsupported panel: "+panel);
109        }
110        UTMPanel p = (UTMPanel) panel;
111        int idx = p.prefcb.getSelectedIndex();
112        Hemisphere hem = p.south.isSelected()?Hemisphere.South:Hemisphere.North;
113        return Arrays.asList(indexToZone(idx), hem.toString());
114    }
115
116    @Override
117    public String[] allCodes() {
118        List<String> projections = new ArrayList<>(60*4);
119        for (int zone = 1;zone <= 60; zone++) {
120            for (Hemisphere hem : Hemisphere.values()) {
121                projections.add("EPSG:" + (32600 + zone + (hem == Hemisphere.South?100:0)));
122            }
123        }
124        return projections.toArray(new String[projections.size()]);
125    }
126
127    @Override
128    public Collection<String> getPreferencesFromCode(String code) {
129
130        if (code.startsWith("EPSG:326") || code.startsWith("EPSG:327")) {
131            try {
132                Hemisphere hem = code.charAt(7)=='6'?Hemisphere.North:Hemisphere.South;
133                String zonestring = code.substring(8);
134                int zoneval = Integer.parseInt(zonestring);
135                if(zoneval > 0 && zoneval <= 60)
136                    return Arrays.asList(zonestring, hem.toString());
137            } catch(NumberFormatException e) {
138                Main.warn(e);
139            }
140        }
141        return null;
142    }
143
144    @Override
145    public void setPreferences(Collection<String> args) {
146        super.setPreferences(args);
147        Hemisphere hem = DEFAULT_HEMISPHERE;
148
149        if (args != null) {
150            String[] array = args.toArray(new String[args.size()]);
151
152            if (array.length > 1) {
153                hem = Hemisphere.valueOf(array[1]);
154            }
155        }
156        this.hemisphere = hem;
157    }
158
159    @Override
160    protected String indexToZone(int idx) {
161        return Integer.toString(idx + 1);
162    }
163
164    @Override
165    protected int zoneToIndex(String zone) {
166        try {
167            return Integer.parseInt(zone) - 1;
168        } catch(NumberFormatException e) {
169            Main.warn(e);
170        }
171        return defaultIndex;
172    }
173}