source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/projection/CustomProjectionChoice.java@ 18365

Last change on this file since 18365 was 18365, checked in by Don-vip, 2 years ago

see #15182 - make JOSM callable as standalone validator (patch by taylor.smock)

  • Property svn:eol-style set to native
File size: 9.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.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.ActionListener;
10import java.util.Arrays;
11import java.util.Collection;
12import java.util.Collections;
13import java.util.List;
14
15import javax.swing.JButton;
16import javax.swing.JComponent;
17import javax.swing.JLabel;
18import javax.swing.JPanel;
19import javax.swing.plaf.basic.BasicComboBoxEditor;
20
21import org.openstreetmap.josm.data.projection.CustomProjection;
22import org.openstreetmap.josm.data.projection.Projection;
23import org.openstreetmap.josm.data.projection.ProjectionConfigurationException;
24import org.openstreetmap.josm.data.projection.Projections;
25import org.openstreetmap.josm.gui.ExtendedDialog;
26import org.openstreetmap.josm.gui.tagging.ac.AutoCompTextField;
27import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
28import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
29import org.openstreetmap.josm.gui.widgets.HtmlPanel;
30import org.openstreetmap.josm.gui.widgets.JosmTextField;
31import org.openstreetmap.josm.tools.GBC;
32import org.openstreetmap.josm.tools.ImageProvider;
33import org.openstreetmap.josm.tools.Logging;
34import org.openstreetmap.josm.tools.Utils;
35
36/**
37 * ProjectionChoice where a CRS can be defined using various parameters.
38 * <p>
39 * The configuration string mimics the syntax of the PROJ.4 project and should
40 * be mostly compatible.
41 * @see CustomProjection
42 */
43public class CustomProjectionChoice extends AbstractProjectionChoice implements SubPrefsOptions {
44
45 private String pref;
46
47 /**
48 * Constructs a new {@code CustomProjectionChoice}.
49 */
50 public CustomProjectionChoice() {
51 super(tr("Custom Projection"), /* NO-ICON */ "core:custom");
52 }
53
54 private static class PreferencePanel extends JPanel {
55
56 public AutoCompTextField<String> input;
57 private HistoryComboBox cbInput;
58
59 PreferencePanel(String initialText, ActionListener listener) {
60 build(initialText, listener);
61 }
62
63 private void build(String initialText, final ActionListener listener) {
64 input = new AutoCompTextField<>(30);
65 cbInput = new HistoryComboBox();
66 cbInput.setEditor(new BasicComboBoxEditor() {
67 @Override
68 protected JosmTextField createEditorComponent() {
69 return input;
70 }
71 });
72 List<String> samples = Arrays.asList(
73 "+proj=lonlat +ellps=WGS84 +datum=WGS84 +bounds=-180,-90,180,90",
74 "+proj=tmerc +lat_0=0 +lon_0=9 +k_0=1 +x_0=3500000 +y_0=0 +ellps=bessel +nadgrids=BETA2007.gsb");
75 cbInput.getModel().prefs().load("projection.custom.value.history", samples);
76 cbInput.setText(initialText == null ? "" : initialText);
77
78 final HtmlPanel errorsPanel = new HtmlPanel();
79 errorsPanel.setVisible(false);
80 final JLabel valStatus = new JLabel();
81 valStatus.setVisible(false);
82
83 final AbstractTextComponentValidator val = new AbstractTextComponentValidator(input, false, false, false) {
84
85 private String error;
86
87 @Override
88 public void validate() {
89 if (!isValid()) {
90 feedbackInvalid(tr("Invalid projection configuration: {0}", error));
91 } else {
92 feedbackValid(tr("Projection configuration is valid."));
93 }
94 listener.actionPerformed(null);
95 }
96
97 @Override
98 public boolean isValid() {
99 try {
100 CustomProjection test = new CustomProjection();
101 test.update(input.getText());
102 } catch (ProjectionConfigurationException ex) {
103 Logging.warn(ex);
104 error = ex.getMessage();
105 valStatus.setIcon(ImageProvider.get("data", "error"));
106 valStatus.setVisible(true);
107 errorsPanel.setText(error);
108 errorsPanel.setVisible(true);
109 return false;
110 }
111 errorsPanel.setVisible(false);
112 valStatus.setIcon(ImageProvider.get("misc", "green_check"));
113 valStatus.setVisible(true);
114 return true;
115 }
116 };
117
118 JButton btnCheck = new JButton(tr("Validate"));
119 btnCheck.addActionListener(e -> val.validate());
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(e -> {
125 CustomProjectionChoice.ParameterInfoDialog dlg = new CustomProjectionChoice.ParameterInfoDialog();
126 dlg.showDialog();
127 dlg.toFront();
128 });
129
130 this.setLayout(new GridBagLayout());
131 JPanel p2 = new JPanel(new GridBagLayout());
132 p2.add(cbInput, GBC.std().fill(GBC.HORIZONTAL).insets(0, 20, 5, 5));
133 p2.add(btnCheck, GBC.eol().insets(0, 20, 0, 5));
134 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
135 p2 = new JPanel(new GridBagLayout());
136 p2.add(valStatus, GBC.std().anchor(GBC.WEST).weight(0.0001, 0));
137 p2.add(errorsPanel, GBC.eol().fill(GBC.HORIZONTAL));
138 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
139 p2 = new JPanel(new GridBagLayout());
140 p2.add(btnInfo, GBC.std().insets(0, 20, 0, 0));
141 p2.add(GBC.glue(1, 0), GBC.eol().fill(GBC.HORIZONTAL));
142 this.add(p2, GBC.eol().fill(GBC.HORIZONTAL));
143 }
144
145 public void rememberHistory() {
146 cbInput.addCurrentItemToHistory();
147 cbInput.getModel().prefs().save("projection.custom.value.history");
148 }
149 }
150
151 public static class ParameterInfoDialog extends ExtendedDialog {
152
153 /**
154 * Constructs a new {@code ParameterInfoDialog}.
155 */
156 public ParameterInfoDialog() {
157 super(null, tr("Parameter information"), new String[] {tr("Close")}, false);
158 setContent(build());
159 }
160
161 private static JComponent build() {
162 StringBuilder s = new StringBuilder(1024);
163 s.append("<b>+proj=...</b> - <i>").append(tr("Projection name"))
164 .append("</i><br>&nbsp;&nbsp;&nbsp;&nbsp;").append(tr("Supported values:")).append(' ')
165 .append(Projections.listProjs())
166 .append("<br><b>+lat_0=..., +lat_1=..., +lat_2=...</b> - <i>").append(tr("Projection parameters"))
167 .append("</i><br><b>+x_0=..., +y_0=...</b> - <i>").append(tr("False easting and false northing"))
168 .append("</i><br><b>+lon_0=...</b> - <i>").append(tr("Central meridian"))
169 .append("</i><br><b>+k_0=...</b> - <i>").append(tr("Scaling factor"))
170 .append("</i><br><b>+ellps=...</b> - <i>").append(tr("Ellipsoid name"))
171 .append("</i><br>&nbsp;&nbsp;&nbsp;&nbsp;").append(tr("Supported values:")).append(' ')
172 .append(Projections.listEllipsoids())
173 .append("<br><b>+a=..., +b=..., +rf=..., +f=..., +es=...</b> - <i>").append(tr("Ellipsoid parameters"))
174 .append("</i><br><b>+datum=...</b> - <i>").append(tr("Datum name"))
175 .append("</i><br>&nbsp;&nbsp;&nbsp;&nbsp;").append(tr("Supported values:")).append(' ')
176 .append(Projections.listDatums())
177 .append("<br><b>+towgs84=...</b> - <i>").append(tr("3 or 7 term datum transform parameters"))
178 .append("</i><br><b>+nadgrids=...</b> - <i>").append(tr("NTv2 grid file"))
179 .append("</i><br>&nbsp;&nbsp;&nbsp;&nbsp;").append(tr("Built-in:")).append(' ')
180 .append(Projections.listNadgrids())
181 .append("<br><b>+bounds=</b>minlon,minlat,maxlon,maxlat - <i>").append(tr("Projection bounds (in degrees)"))
182 .append("</i><br><b>+wmssrs=</b>EPSG:123456 - <i>").append(tr("Sets the SRS=... parameter in the WMS request"))
183 .append("</i><br>");
184
185 return new HtmlPanel(s.toString());
186 }
187 }
188
189 @Override
190 public void setPreferences(Collection<String> args) {
191 if (!Utils.isEmpty(args)) {
192 pref = args.iterator().next();
193 }
194 }
195
196 @Override
197 public Projection getProjection() {
198 return new CustomProjection(pref);
199 }
200
201 @Override
202 public String getCurrentCode() {
203 // not needed - getProjection() is overridden
204 throw new UnsupportedOperationException();
205 }
206
207 @Override
208 public String getProjectionName() {
209 // not needed - getProjection() is overridden
210 throw new UnsupportedOperationException();
211 }
212
213 @Override
214 public JPanel getPreferencePanel(ActionListener listener) {
215 return new PreferencePanel(pref, listener);
216 }
217
218 @Override
219 public Collection<String> getPreferences(JPanel panel) {
220 if (!(panel instanceof PreferencePanel)) {
221 throw new IllegalArgumentException("Unsupported panel: "+panel);
222 }
223 PreferencePanel prefPanel = (PreferencePanel) panel;
224 String pref = prefPanel.input.getText();
225 prefPanel.rememberHistory();
226 return Collections.singleton(pref);
227 }
228
229 @Override
230 public String[] allCodes() {
231 return new String[0];
232 }
233
234 @Override
235 public Collection<String> getPreferencesFromCode(String code) {
236 return null;
237 }
238
239 @Override
240 public boolean showProjectionCode() {
241 return false;
242 }
243
244 @Override
245 public boolean showProjectionName() {
246 return false;
247 }
248}
Note: See TracBrowser for help on using the repository browser.