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