source: josm/trunk/src/org/openstreetmap/josm/data/projection/CustomProjectionPrefGui.java@ 5228

Last change on this file since 5228 was 5228, checked in by bastiK, 12 years ago

improved custom projection

File size: 9.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.GridBagLayout;
8import java.awt.Insets;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.util.ArrayList;
12import java.util.Arrays;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.LinkedList;
16import java.util.List;
17import java.util.Map;
18
19import javax.swing.JButton;
20import javax.swing.JComponent;
21import javax.swing.JLabel;
22import javax.swing.JPanel;
23import javax.swing.JTextField;
24import javax.swing.plaf.basic.BasicComboBoxEditor;
25
26import org.openstreetmap.josm.Main;
27import org.openstreetmap.josm.gui.ExtendedDialog;
28import org.openstreetmap.josm.gui.preferences.projection.SubPrefsOptions;
29import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
30import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
31import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
32import org.openstreetmap.josm.gui.widgets.HtmlPanel;
33import org.openstreetmap.josm.tools.GBC;
34import org.openstreetmap.josm.tools.ImageProvider;
35import org.openstreetmap.josm.tools.Utils;
36
37public class CustomProjectionPrefGui extends CustomProjection implements ProjectionSubPrefs, SubPrefsOptions {
38
39 @Override
40 public void setupPreferencePanel(JPanel p, ActionListener listener) {
41 JPanel inner = new PreferencePanel(listener);
42 p.setLayout(new GridBagLayout());
43 p.add(inner, GBC.std().fill(GBC.HORIZONTAL));
44 }
45
46 private class PreferencePanel extends JPanel {
47
48 public JTextField input;
49 private HistoryComboBox cbInput;
50
51 public PreferencePanel(ActionListener listener) {
52 build(listener);
53 }
54
55 private void build(final ActionListener listener) {
56 input = new JTextField(30);
57 cbInput = new HistoryComboBox();
58 cbInput.setPrototypeDisplayValue(new AutoCompletionListItem("xxxx"));
59 cbInput.setEditor(new BasicComboBoxEditor() {
60 @Override
61 protected JTextField createEditorComponent() {
62 return input;
63 }
64 });
65 Collection<String> samples = Arrays.asList(
66 "+proj=lonlat +ellps=WGS84 +datum=WGS84 +bounds=-180,-90,180,90",
67 "+proj=tmerc +lat_0=0 +lon_0=9 +k_0=1 +x_0=3500000 +y_0=0 +ellps=bessel +nadgrids=BETA2007.gsb");
68 List<String> inputHistory = new LinkedList<String>(Main.pref.getCollection("projection.custom.value.history", samples));
69 Collections.reverse(inputHistory);
70 cbInput.setPossibleItems(inputHistory);
71 cbInput.setText(pref == null ? "" : pref);
72
73 final HtmlPanel errorsPanel = new HtmlPanel();
74 errorsPanel.setVisible(false);
75 final JLabel valStatus = new JLabel();
76 valStatus.setVisible(false);
77
78 final AbstractTextComponentValidator val = new AbstractTextComponentValidator(input, false, false, false) {
79
80 private String error;
81
82 @Override
83 public void validate() {
84 if (!isValid()) {
85 feedbackInvalid(tr("Invalid projection configuration: {0}",error));
86 } else {
87 feedbackValid(tr("Projection configuration is valid."));
88 }
89 listener.actionPerformed(null);
90 }
91
92 @Override
93 public boolean isValid() {
94 try {
95 CustomProjection test = new CustomProjection();
96 test.update(input.getText());
97 } catch (ProjectionConfigurationException ex) {
98 error = ex.getMessage();
99 valStatus.setIcon(ImageProvider.get("data", "error.png"));
100 valStatus.setVisible(true);
101 errorsPanel.setText(error);
102 errorsPanel.setVisible(true);
103 return false;
104 }
105 errorsPanel.setVisible(false);
106 valStatus.setIcon(ImageProvider.get("misc", "green_check.png"));
107 valStatus.setVisible(true);
108 return true;
109 }
110
111 };
112
113 JButton btnCheck = new JButton(tr("Validate"));
114 btnCheck.addActionListener(new ActionListener() {
115 @Override
116 public void actionPerformed(ActionEvent e) {
117 val.validate();
118 }
119 });
120 btnCheck.setLayout(new BorderLayout());
121 btnCheck.setMargin(new Insets(-1,0,-1,0));
122
123 JButton btnInfo = new JButton(tr("Parameter information..."));
124 btnInfo.addActionListener(new ActionListener() {
125 @Override
126 public void actionPerformed(ActionEvent e) {
127 ParameterInfoDialog dlg = new ParameterInfoDialog();
128 dlg.showDialog();
129 dlg.toFront();
130 }
131 });
132
133 this.setLayout(new GridBagLayout());
134 JPanel p2 = new JPanel(new GridBagLayout());
135 p2.add(cbInput, GBC.std().fill(GBC.HORIZONTAL).insets(0, 20, 5, 5));
136 p2.add(btnCheck, GBC.eol().insets(0, 20, 0, 5));
137 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
138 p2 = new JPanel(new GridBagLayout());
139 p2.add(valStatus, GBC.std().anchor(GBC.WEST).weight(0.0001, 0));
140 p2.add(errorsPanel, GBC.eol().fill(GBC.HORIZONTAL));
141 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
142 p2 = new JPanel(new GridBagLayout());
143 p2.add(btnInfo, GBC.std().insets(0, 20, 0, 0));
144 p2.add(GBC.glue(1, 0), GBC.eol().fill(GBC.HORIZONTAL));
145 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
146 }
147
148 public void rememberHistory() {
149 cbInput.addCurrentItemToHistory();
150 Main.pref.putCollection("projection.custom.value.history", cbInput.getHistory());
151 }
152 }
153
154 public class ParameterInfoDialog extends ExtendedDialog {
155
156 public ParameterInfoDialog() {
157 super(null, tr("Parameter information"), new String[] { tr("Close") }, false);
158 setContent(build());
159 }
160
161 private JComponent build() {
162 StringBuilder s = new StringBuilder();
163 s.append("<b>+proj=...</b> - <i>"+tr("Projection name")+"</i><br>");
164 s.append("&nbsp;&nbsp;&nbsp;&nbsp;"+tr("Supported values:")+" ");
165 s.append(listKeys(Projections.projs)+"<br>");
166 s.append("<b>+lat_0=..., +lat_1=..., +lat_2=...</b> - <i>"+tr("Projection parameters")+"</i><br>");
167 s.append("<b>+x_0=..., +y_0=...</b> - <i>"+tr("False easting and false northing")+"</i><br>");
168 s.append("<b>+lon_0=...</b> - <i>"+tr("Central meridian")+"</i><br>");
169 s.append("<b>+k_0=...</b> - <i>"+tr("Scaling factor")+"</i><br>");
170 s.append("<b>+ellps=...</b> - <i>"+tr("Ellipsoid name")+"</i><br>");
171 s.append("&nbsp;&nbsp;&nbsp;&nbsp;"+tr("Supported values:")+" ");
172 s.append(listKeys(Projections.ellipsoids)+"<br>");
173 s.append("<b>+a=..., +b=..., +rf=..., +f=..., +es=...</b> - <i>"+tr("Ellipsoid parameters")+"</i><br>");
174 s.append("<b>+datum=...</b> - <i>"+tr("Datum name")+"</i><br>");
175 s.append("&nbsp;&nbsp;&nbsp;&nbsp;"+tr("Supported values:")+" ");
176 s.append(listKeys(Projections.datums)+"<br>");
177 s.append("<b>+towgs84=...</b> - <i>"+tr("3 or 7 term datum transform parameters")+"</i><br>");
178 s.append("<b>+nadgrids=...</b> - <i>"+tr("NTv2 grid file")+"</i><br>");
179 s.append("&nbsp;&nbsp;&nbsp;&nbsp;"+tr("Build-in:")+" ");
180 s.append(listKeys(Projections.nadgrids)+"<br>");
181 s.append("<b>+bounds=</b>minlon,minlat,maxlon,maxlat - <i>"+tr("Projection bounds (in degrees)")+"</i><br>");
182
183 HtmlPanel info = new HtmlPanel(s.toString());
184 return info;
185 }
186
187 private String listKeys(Map<String, ?> map) {
188 List<String> keys = new ArrayList<String>(map.keySet());
189 Collections.sort(keys);
190 return Utils.join(", ", keys);
191 }
192 }
193
194 @Override
195 public Collection<String> getPreferences(JPanel p) {
196 PreferencePanel prefPanel = (PreferencePanel) p.getComponent(0);
197 String pref = prefPanel.input.getText();
198 prefPanel.rememberHistory();
199 return Collections.singleton(pref);
200 }
201
202 @Override
203 public void setPreferences(Collection<String> args) {
204 try {
205 if (args == null || args.isEmpty()) throw new ProjectionConfigurationException();
206 update(args.iterator().next());
207 } catch (ProjectionConfigurationException ex) {
208 System.err.println("Error: Parsing of custom projection failed, falling back to Mercator. Error message is: "+ex.getMessage());
209 try {
210 update(null);
211 } catch (ProjectionConfigurationException ex1) {
212 throw new RuntimeException(ex1);
213 }
214 }
215 }
216
217 @Override
218 public String[] allCodes() {
219 return new String[0];
220 }
221
222 @Override
223 public Collection<String> getPreferencesFromCode(String code) {
224 return null;
225 }
226
227 @Override
228 public boolean showProjectionCode() {
229 return false;
230 }
231
232}
Note: See TracBrowser for help on using the repository browser.