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