Changeset 32528 in osm for applications/editors/josm/plugins/imagery_offset_db
- Timestamp:
- 2016-07-02T03:55:03+02:00 (9 years ago)
- Location:
- applications/editors/josm/plugins/imagery_offset_db
- Files:
-
- 2 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/imagery_offset_db/.project
r32286 r32528 16 16 </arguments> 17 17 </buildCommand> 18 <buildCommand> 19 <name>net.sf.eclipsecs.core.CheckstyleBuilder</name> 20 <arguments> 21 </arguments> 22 </buildCommand> 18 23 </buildSpec> 19 24 <natures> 20 25 <nature>org.eclipse.jdt.core.javanature</nature> 26 <nature>net.sf.eclipsecs.core.CheckstyleNature</nature> 21 27 </natures> 22 28 </projectDescription> -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/CalibrationLayer.java
r29434 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 import java.awt.*; 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.BasicStroke; 7 import java.awt.Color; 8 import java.awt.Component; 9 import java.awt.Graphics; 10 import java.awt.Graphics2D; 11 import java.awt.Point; 12 import java.awt.RenderingHints; 13 import java.awt.Stroke; 4 14 import java.awt.event.ActionEvent; 5 15 import java.awt.geom.GeneralPath; 6 import javax.swing.*; 16 17 import javax.swing.AbstractAction; 18 import javax.swing.Action; 19 import javax.swing.Icon; 20 7 21 import org.openstreetmap.josm.Main; 8 22 import org.openstreetmap.josm.actions.AutoScaleAction; … … 14 28 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; 15 29 import org.openstreetmap.josm.gui.layer.Layer; 16 import static org.openstreetmap.josm.tools.I18n.tr;17 30 import org.openstreetmap.josm.tools.ImageProvider; 18 31 … … 29 42 private LatLon center; 30 43 31 public CalibrationLayer( 44 public CalibrationLayer(CalibrationObject obj) { 32 45 super(tr("Calibration Layer")); 33 46 color = Color.RED; … … 40 53 */ 41 54 @Override 42 public void paint( 55 public void paint(Graphics2D g, MapView mv, Bounds box) { 43 56 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 44 57 Stroke oldStroke = g.getStroke(); … … 46 59 g.setStroke(new BasicStroke(1)); 47 60 LatLon[] geometry = obj.getGeometry(); 48 if (geometry.length == 161 if (geometry.length == 1) { 49 62 // draw crosshair 50 63 Point p = mv.getPoint(geometry[0]); … … 54 67 g.drawLine(p.x, p.y - 10, p.x, p.y - 20); 55 68 g.drawLine(p.x, p.y + 10, p.x, p.y + 20); 56 } else if (geometry.length > 169 } else if (geometry.length > 1) { 57 70 // draw a line 58 71 GeneralPath path = new GeneralPath(); 59 for (int i = 0; i < geometry.length; i++72 for (int i = 0; i < geometry.length; i++) { 60 73 Point p = mv.getPoint(geometry[i]); 61 if ( i == 0)74 if (i == 0) 62 75 path.moveTo(p.x, p.y); 63 76 else … … 71 84 @Override 72 85 public Icon getIcon() { 73 if (icon == null86 if (icon == null) 74 87 icon = ImageProvider.get("calibration_layer"); 75 88 return icon; … … 77 90 78 91 @Override 79 public void mergeFrom( 80 } 81 82 @Override 83 public boolean isMergable( 92 public void mergeFrom(Layer from) { 93 } 94 95 @Override 96 public boolean isMergable(Layer other) { 84 97 return false; 85 98 } … … 89 102 */ 90 103 @Override 91 public void visitBoundingBox( 92 for (LatLon ll : obj.getGeometry())104 public void visitBoundingBox(BoundingXYVisitor v) { 105 for (LatLon ll : obj.getGeometry()) { 93 106 v.visit(ll); 107 } 94 108 } 95 109 … … 99 113 @Override 100 114 public String getToolTipText() { 101 if (obj.isDeprecated()115 if (obj.isDeprecated()) 102 116 return tr("A deprecated calibration geometry of {0} nodes by {1}", obj.getGeometry().length, obj.getAuthor()); 103 117 else … … 116 130 public Action[] getMenuEntries() { 117 131 return new Action[] { 118 LayerListDialog.getInstance().createShowHideLayerAction(), 119 LayerListDialog.getInstance().createDeleteLayerAction(), 120 SeparatorLayerAction.INSTANCE, 121 new ZoomToLayerAction(), 122 new SelectColorAction(Color.RED), 123 new SelectColorAction(Color.CYAN), 124 new SelectColorAction(Color.YELLOW), 125 SeparatorLayerAction.INSTANCE, 126 new LayerListPopup.InfoAction(this) 132 LayerListDialog.getInstance().createShowHideLayerAction(), 133 LayerListDialog.getInstance().createDeleteLayerAction(), 134 SeparatorLayerAction.INSTANCE, 135 new ZoomToLayerAction(), 136 new SelectColorAction(Color.RED), 137 new SelectColorAction(Color.CYAN), 138 new SelectColorAction(Color.YELLOW), 139 SeparatorLayerAction.INSTANCE, 140 new LayerListPopup.InfoAction(this) 127 141 }; 128 142 } … … 134 148 */ 135 149 public void panToCenter() { 136 if (center == null150 if (center == null) { 137 151 LatLon[] geometry = obj.getGeometry(); 138 152 double lat = 0.0; 139 153 double lon = 0.0; 140 for (int i = 0; i < geometry.length; i++154 for (int i = 0; i < geometry.length; i++) { 141 155 lon += geometry[i].lon(); 142 156 lat += geometry[i].lat(); … … 155 169 private Color c; 156 170 157 publicSelectColorAction(171 SelectColorAction(Color color) { 158 172 super(tr("Change Color")); 159 173 putValue(SMALL_ICON, new SingleColorIcon(color)); … … 161 175 } 162 176 163 public void actionPerformed( ActionEvent e ) { 177 @Override 178 public void actionPerformed(ActionEvent e) { 164 179 color = c; 165 180 Main.map.mapView.repaint(); … … 173 188 private Color color; 174 189 175 publicSingleColorIcon(190 SingleColorIcon(Color color) { 176 191 this.color = color; 177 192 } 178 193 179 public void paintIcon( Component c, Graphics g, int x, int y ) { 194 @Override 195 public void paintIcon(Component c, Graphics g, int x, int y) { 180 196 g.setColor(color); 181 197 g.fillRect(x, y, 24, 24); 182 198 } 183 199 200 @Override 184 201 public int getIconWidth() { 185 202 return 24; 186 203 } 187 204 205 @Override 188 206 public int getIconHeight() { 189 207 return 24; 190 208 } 191 192 209 } 193 210 … … 197 214 */ 198 215 class ZoomToLayerAction extends AbstractAction { 199 publicZoomToLayerAction() {216 ZoomToLayerAction() { 200 217 super(tr("Zoom to {0}", tr("layer"))); // to use translation from AutoScaleAction 201 218 putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale/layer")); 202 219 } 203 220 204 public void actionPerformed( ActionEvent e ) { 221 @Override 222 public void actionPerformed(ActionEvent e) { 205 223 AutoScaleAction.autoScale("layer"); 206 224 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/CalibrationObject.java
r29384 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 4 import java.util.Map; 5 4 6 import org.openstreetmap.josm.data.coor.LatLon; 5 7 import org.openstreetmap.josm.data.osm.Node; … … 28 30 * Initialize a calibration object from OSM primitive. 29 31 */ 30 public CalibrationObject( OsmPrimitive p ) { 31 if( p instanceof Node ) 32 geometry = new LatLon[] { ((Node)p).getCoor() }; 33 else if( p instanceof Way ) { 34 geometry = new LatLon[((Way)p).getNodesCount()]; 35 for( int i = 0; i < geometry.length; i++ ) 36 geometry[i] = ((Way)p).getNode(i).getCoor(); 32 public CalibrationObject(OsmPrimitive p) { 33 if (p instanceof Node) 34 geometry = new LatLon[] {((Node) p).getCoor()}; 35 else if (p instanceof Way) { 36 geometry = new LatLon[((Way) p).getNodesCount()]; 37 for (int i = 0; i < geometry.length; i++) { 38 geometry[i] = ((Way) p).getNode(i).getCoor(); 39 } 37 40 } else 38 41 throw new IllegalArgumentException("Calibration Object can be created either from node or a way"); … … 47 50 48 51 @Override 49 public void putServerParams( 52 public void putServerParams(Map<String, String> map) { 50 53 super.putServerParams(map); 51 54 StringBuilder sb = new StringBuilder(); 52 for (int i = 0; i < geometry.length; i++53 if ( i > 0)55 for (int i = 0; i < geometry.length; i++) { 56 if (i > 0) 54 57 sb.append(','); 55 58 sb.append(geometry[i].lon()).append(' ').append(geometry[i].lat()); … … 60 63 @Override 61 64 public String toString() { 62 return "CalibrationObject{" + geometry.length + "nodes; position=" + position + ", date=" + date + ", author=" + author + ", description=" + description + ", abandonDate=" + abandonDate + '}'; 65 return "CalibrationObject{" + geometry.length + "nodes; position=" + position + ", date=" + date + ", author=" + author + 66 ", description=" + description + ", abandonDate=" + abandonDate + '}'; 63 67 } 64 68 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/DeprecateOffsetAction.java
r29434 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 2 5 3 6 import java.awt.event.ActionEvent; 4 7 import java.io.UnsupportedEncodingException; 5 import java.net.*; 8 import java.net.URLEncoder; 9 6 10 import javax.swing.AbstractAction; 7 11 import javax.swing.JOptionPane; 12 8 13 import org.openstreetmap.josm.Main; 9 14 import org.openstreetmap.josm.gui.JosmUserIdentityManager; 10 import static org.openstreetmap.josm.tools.I18n.tr;11 15 import org.openstreetmap.josm.tools.ImageProvider; 12 16 13 17 /** 14 18 * A context-dependent action to deprecate an offset. 15 * 19 * 16 20 * @author Zverik 17 21 * @license WTFPL … … 20 24 private ImageryOffsetBase offset; 21 25 private QuerySuccessListener listener; 22 26 23 27 /** 24 28 * Initialize an action with an offset object. 25 29 */ 26 public DeprecateOffsetAction( 30 public DeprecateOffsetAction(ImageryOffsetBase offset) { 27 31 super(tr("Deprecate Offset")); 28 32 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete")); … … 37 41 * on a positive answer. 38 42 */ 43 @Override 39 44 public void actionPerformed(ActionEvent e) { 40 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()45 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()) 41 46 return; 42 47 43 48 String desc = offset instanceof ImageryOffset ? 44 49 tr("Are you sure this imagery offset is wrong?") : 45 tr("Are you sure this calibration geometry is aligned badly?"); 46 if(JOptionPane.showConfirmDialog(Main.parent,47 tr("Warning: deprecation is basically irreversible!")+ "\n" + desc, 48 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION 49 return; 50 } 51 deprecateOffset(offset, listener); 50 tr("Are you sure this calibration geometry is aligned badly?"); 51 if (JOptionPane.showConfirmDialog(Main.parent, 52 tr("Warning: deprecation is basically irreversible!")+ "\n" + desc, 53 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) { 54 return; 55 } 56 deprecateOffset(offset, listener); 52 57 } 53 58 … … 55 60 * Installs a listener to process successful deprecation event. 56 61 */ 57 public void setListener( 62 public void setListener(QuerySuccessListener listener) { 58 63 this.listener = listener; 59 64 } … … 61 66 /** 62 67 * Deprecate the given offset. 63 * @see #deprecateOffset(iodb.ImageryOffsetBase, iodb.QuerySuccessListener) 68 * @see #deprecateOffset(iodb.ImageryOffsetBase, iodb.QuerySuccessListener) 64 69 */ 65 public static void deprecateOffset( 70 public static void deprecateOffset(ImageryOffsetBase offset) { 66 71 deprecateOffset(offset, null); 67 72 } … … 71 76 * and executes {@link SimpleOffsetQueryTask} with a query to deprecate the offset. 72 77 */ 73 public static void deprecateOffset( 78 public static void deprecateOffset(ImageryOffsetBase offset, QuerySuccessListener listener) { 74 79 String userName = JosmUserIdentityManager.getInstance().getUserName(); 75 if( userName == null ) { 76 JOptionPane.showMessageDialog(Main.parent, tr("To store imagery offsets you must be a registered OSM user."), ImageryOffsetTools.DIALOG_TITLE, JOptionPane.ERROR_MESSAGE); 80 if (userName == null) { 81 JOptionPane.showMessageDialog(Main.parent, tr("To store imagery offsets you must be a registered OSM user."), 82 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.ERROR_MESSAGE); 77 83 return; 78 84 } … … 80 86 String message = offset instanceof ImageryOffset 81 87 ? tr("Please enter the reason why you mark this imagery offset as deprecated") 82 : tr("Please enter the reason why you mark this calibration geometry as deprecated"); 83 String reason = StoreImageryOffsetAction.queryDescription(message + ":"); 84 if(reason == null85 return; 86 87 try { 88 String query = "deprecate?id=" + offset.getId() 89 + "&author=" + URLEncoder.encode(userName, "UTF8") 90 + "&reason=" + URLEncoder.encode(reason, "UTF8"); 91 SimpleOffsetQueryTask depTask = new SimpleOffsetQueryTask(query, tr("Notifying the server of the deprecation...")); 92 if(listener != null93 depTask.setListener(listener); 94 Main.worker.submit(depTask); 95 } catch (UnsupportedEncodingException ex96 // WTF97 } 88 : tr("Please enter the reason why you mark this calibration geometry as deprecated"); 89 String reason = StoreImageryOffsetAction.queryDescription(message + ":"); 90 if (reason == null) 91 return; 92 93 try { 94 String query = "deprecate?id=" + offset.getId() 95 + "&author=" + URLEncoder.encode(userName, "UTF8") 96 + "&reason=" + URLEncoder.encode(reason, "UTF8"); 97 SimpleOffsetQueryTask depTask = new SimpleOffsetQueryTask(query, tr("Notifying the server of the deprecation...")); 98 if (listener != null) 99 depTask.setListener(listener); 100 Main.worker.submit(depTask); 101 } catch (UnsupportedEncodingException ex) { 102 Main.error(ex); 103 } 98 104 } 99 105 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/GetImageryOffsetAction.java
r30808 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 2 5 3 6 import java.awt.event.ActionEvent; … … 5 8 import java.io.InputStream; 6 9 import java.io.UnsupportedEncodingException; 7 import java.net.*; 8 import java.util.*; 10 import java.net.URLEncoder; 11 import java.util.List; 12 9 13 import javax.swing.Action; 10 14 import javax.swing.Icon; 11 15 import javax.swing.JOptionPane; 16 12 17 import org.openstreetmap.josm.Main; 13 18 import org.openstreetmap.josm.actions.JosmAction; … … 16 21 import org.openstreetmap.josm.data.projection.Projection; 17 22 import org.openstreetmap.josm.gui.layer.ImageryLayer; 18 import static org.openstreetmap.josm.tools.I18n.tr;19 23 import org.openstreetmap.josm.tools.ImageProvider; 20 24 import org.openstreetmap.josm.tools.Shortcut; … … 22 26 /** 23 27 * Download a list of imagery offsets for the current position, let user choose which one to use. 24 * 28 * 25 29 * @author Zverik 26 30 * @license WTFPL … … 29 33 private Icon iconOffsetOk; 30 34 private Icon iconOffsetBad; 31 35 32 36 /** 33 37 * Initialize the action. Sets "Ctrl+Alt+I" shortcut: the only shortcut in this plugin. … … 37 41 super(tr("Get Imagery Offset..."), "getoffset", tr("Download offsets for current imagery from a server"), 38 42 Shortcut.registerShortcut("imageryoffset:get", tr("Imagery: {0}", tr("Get Imagery Offset...")), 39 KeyEvent.VK_I, Shortcut.ALT_CTRL), true); 43 KeyEvent.VK_I, Shortcut.ALT_CTRL), true); 40 44 iconOffsetOk = new ImageProvider("getoffset").setSize(ImageProvider.ImageSizes.MENU).get(); 41 45 iconOffsetBad = new ImageProvider("getoffsetnow").setSize(ImageProvider.ImageSizes.MENU).get(); … … 46 50 * The action just executes {@link DownloadOffsetsTask}. 47 51 */ 52 @Override 48 53 public void actionPerformed(ActionEvent e) { 49 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()54 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()) 50 55 return; 51 56 Projection proj = Main.map.mapView.getProjection(); … … 53 58 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 54 59 String imagery = ImageryOffsetTools.getImageryID(layer); 55 if (imagery == null60 if (imagery == null) 56 61 return; 57 62 58 63 DownloadOffsetsTask download = new DownloadOffsetsTask(center, layer, imagery); 59 64 Main.worker.submit(download); … … 67 72 protected void updateEnabledState() { 68 73 boolean state = true; 69 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()74 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()) 70 75 state = false; 71 76 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 72 if (ImageryOffsetTools.getImageryID(layer) == null77 if (ImageryOffsetTools.getImageryID(layer) == null) 73 78 state = false; 74 79 setEnabled(state); 75 80 } 76 81 77 82 /** 78 83 * Display a dialog for choosing between offsets. If there are no offsets in … … 80 85 * @param offsets List of offset objects to choose from. 81 86 */ 82 private void showOffsetDialog( 83 if (offsets.isEmpty()87 private void showOffsetDialog(List<ImageryOffsetBase> offsets) { 88 if (offsets.isEmpty()) { 84 89 JOptionPane.showMessageDialog(Main.parent, 85 90 tr("No data for this region. Please adjust imagery layer and upload an offset."), … … 88 93 } 89 94 OffsetDialog offsetDialog = new OffsetDialog(offsets); 90 if (offsetDialog.showDialog() != null95 if (offsetDialog.showDialog() != null) 91 96 offsetDialog.applyOffset(); 92 97 } … … 95 100 * Update action icon based on an offset state. 96 101 */ 97 public void offsetStateChanged( boolean isOffsetGood ) { 102 @Override 103 public void offsetStateChanged(boolean isOffsetGood) { 98 104 putValue(Action.SMALL_ICON, isOffsetGood ? iconOffsetOk : iconOffsetBad); 99 105 } … … 122 128 * @param imagery Imagery ID for the layer. 123 129 */ 124 publicDownloadOffsetsTask(130 DownloadOffsetsTask(LatLon center, ImageryLayer layer, String imagery) { 125 131 super(null, tr("Loading imagery offsets...")); 126 132 try { 127 133 String query = "get?lat=" + center.latToString(CoordinateFormat.DECIMAL_DEGREES) 128 129 134 + "&lon=" + center.lonToString(CoordinateFormat.DECIMAL_DEGREES) 135 + "&imagery=" + URLEncoder.encode(imagery, "UTF8"); 130 136 int radius = Main.pref.getInteger("iodb.radius", -1); 131 if (radius > 0137 if (radius > 0) 132 138 query = query + "&radius=" + radius; 133 139 setQuery(query); 134 } catch (UnsupportedEncodingException e140 } catch (UnsupportedEncodingException e) { 135 141 throw new IllegalArgumentException(e); 136 142 } … … 142 148 @Override 143 149 protected void afterFinish() { 144 if (!cancelled && offsets != null150 if (!cancelled && offsets != null) 145 151 showOffsetDialog(offsets); 146 152 } 147 153 148 154 /** 149 155 * Parses the response with {@link IODBReader}. … … 152 158 */ 153 159 @Override 154 protected void processResponse( 160 protected void processResponse(InputStream inp) throws UploadException { 155 161 offsets = null; 156 162 try { 157 163 offsets = new IODBReader(inp).parse(); 158 } catch (Exception e164 } catch (Exception e) { 159 165 throw new UploadException(tr("Error processing XML response: {0}", e.getMessage())); 160 166 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/IODBReader.java
r30737 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 … … 8 9 import java.util.Date; 9 10 import java.util.List; 11 10 12 import javax.xml.parsers.ParserConfigurationException; 11 13 import javax.xml.parsers.SAXParserFactory; 14 12 15 import org.openstreetmap.josm.data.coor.LatLon; 13 16 import org.openstreetmap.josm.io.UTFInputStreamReader; … … 20 23 * Parses the server response. It expects XML in UTF-8 with several <offset> 21 24 * and <calibration> elements. 22 * 25 * 23 26 * @author Zverik 24 27 * @license WTFPL … … 27 30 private List<ImageryOffsetBase> offsets; 28 31 private InputSource source; 29 32 30 33 /** 31 34 * Initializes the parser. This constructor creates an input source on the input … … 34 37 * @throws IOException Thrown when something's wrong with the stream. 35 38 */ 36 public IODBReader( 39 public IODBReader(InputStream source) throws IOException { 37 40 this.source = new InputSource(UTFInputStreamReader.create(source, "UTF-8")); 38 41 this.offsets = new ArrayList<>(); … … 51 54 factory.newSAXParser().parse(source, parser); 52 55 return offsets; 53 } catch (ParserConfigurationException e56 } catch (ParserConfigurationException e) { 54 57 throw new SAXException(e); 55 58 } … … 93 96 @Override 94 97 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 95 if (!parsingOffset96 if (qName.equals("offset") || qName.equals("calibration")98 if (!parsingOffset) { 99 if (qName.equals("offset") || qName.equals("calibration")) { 97 100 parsingOffset = true; 98 101 parsingDeprecate = false; … … 100 103 fields.position = parseLatLon(attributes); 101 104 fields.id = Integer.parseInt(attributes.getValue("id")); 102 if (attributes.getValue("flagged") != null && attributes.getValue("flagged").equals("yes")105 if (attributes.getValue("flagged") != null && attributes.getValue("flagged").equals("yes")) 103 106 fields.flagged = true; 104 107 } 105 108 } else { 106 if (qName.equals("node")109 if (qName.equals("node")) { 107 110 fields.geometry.add(parseLatLon(attributes)); 108 } else if (qName.equals("imagery-position")111 } else if (qName.equals("imagery-position")) { 109 112 fields.imageryPos = parseLatLon(attributes); 110 } else if (qName.equals("imagery")113 } else if (qName.equals("imagery")) { 111 114 String minZoom = attributes.getValue("minzoom"); 112 115 String maxZoom = attributes.getValue("maxzoom"); 113 if (minZoom != null116 if (minZoom != null) 114 117 fields.minZoom = Integer.parseInt(minZoom); 115 if (maxZoom != null118 if (maxZoom != null) 116 119 fields.maxZoom = Integer.parseInt(maxZoom); 117 } else if (qName.equals("deprecated")120 } else if (qName.equals("deprecated")) { 118 121 parsingDeprecate = true; 119 122 } … … 121 124 accumulator.setLength(0); 122 125 } 123 126 124 127 @Override 125 128 public void characters(char[] ch, int start, int length) throws SAXException { 126 if (parsingOffset129 if (parsingOffset) 127 130 accumulator.append(ch, start, length); 128 131 } … … 130 133 @Override 131 134 public void endElement(String uri, String localName, String qName) throws SAXException { 132 if (parsingOffset133 if (qName.equals("author")134 if (!parsingDeprecate135 if (parsingOffset) { 136 if (qName.equals("author")) { 137 if (!parsingDeprecate) 135 138 fields.author = accumulator.toString(); 136 139 else 137 140 fields.abandonAuthor = accumulator.toString(); 138 } else if (qName.equals("description")141 } else if (qName.equals("description")) { 139 142 fields.description = accumulator.toString(); 140 } else if (qName.equals("reason") && parsingDeprecate143 } else if (qName.equals("reason") && parsingDeprecate) { 141 144 fields.abandonReason = accumulator.toString(); 142 } else if (qName.equals("date")145 } else if (qName.equals("date")) { 143 146 try { 144 if (!parsingDeprecate147 if (!parsingDeprecate) 145 148 fields.date = dateParser.parse(accumulator.toString()); 146 149 else … … 149 152 throw new SAXException(ex); 150 153 } 151 } else if (qName.equals("deprecated")154 } else if (qName.equals("deprecated")) { 152 155 parsingDeprecate = false; 153 } else if (qName.equals("imagery")156 } else if (qName.equals("imagery")) { 154 157 fields.imagery = accumulator.toString(); 155 } else if (qName.equals("offset") || qName.equals("calibration")158 } else if (qName.equals("offset") || qName.equals("calibration")) { 156 159 // store offset 157 160 try { 158 161 offsets.add(fields.constructObject()); 159 } catch (IllegalArgumentException ex162 } catch (IllegalArgumentException ex) { 160 163 // On one hand, we don't care, but this situation is one 161 164 // of those "it can never happen" cases. … … 167 170 } 168 171 } 169 172 170 173 /** 171 174 * An accumulator for parsed fields. When there's enough data, it can construct … … 191 194 * A constructor just calls {@link #clear()}. 192 195 */ 193 publicIOFields() {196 IOFields() { 194 197 clear(); 195 198 } 196 199 197 200 /** 198 201 * Clear all fields to <tt>null</tt> and <tt>-1</tt>. … … 220 223 */ 221 224 public ImageryOffsetBase constructObject() { 222 if (author == null || description == null || position == null || date == null225 if (author == null || description == null || position == null || date == null) 223 226 throw new IllegalArgumentException("Not enought arguments to build an object"); 224 227 ImageryOffsetBase result; 225 if (geometry.isEmpty()226 if (imagery == null || imageryPos == null228 if (geometry.isEmpty()) { 229 if (imagery == null || imageryPos == null) 227 230 throw new IllegalArgumentException("Both imagery and imageryPos should be specified for the offset"); 228 231 result = new ImageryOffset(imagery, imageryPos); 229 if (minZoom >= 0230 ((ImageryOffset)result).setMinZoom(minZoom); 231 if (maxZoom >= 0232 ((ImageryOffset)result).setMaxZoom(maxZoom); 232 if (minZoom >= 0) 233 ((ImageryOffset) result).setMinZoom(minZoom); 234 if (maxZoom >= 0) 235 ((ImageryOffset) result).setMaxZoom(maxZoom); 233 236 } else { 234 237 result = new CalibrationObject(geometry.toArray(new LatLon[0])); 235 238 } 236 if (id >= 0239 if (id >= 0) 237 240 result.setId(id); 238 241 result.setBasicInfo(position, author, description, date); 239 242 result.setDeprecated(abandonDate, abandonAuthor, abandonReason); 240 if (flagged243 if (flagged) 241 244 result.setFlagged(flagged); 242 245 return result; -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryIdGenerator.java
r30737 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 import java.util.*; 4 import java.util.Arrays; 5 import java.util.Map; 6 import java.util.Set; 7 import java.util.TreeMap; 8 import java.util.TreeSet; 9 4 10 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType; 5 11 … … 10 16 * @license WTFPL 11 17 */ 12 public class ImageryIdGenerator { 18 public final class ImageryIdGenerator { 13 19 14 public static String getImageryID( String url, ImageryType type ) { 15 if( url == null ) 20 private ImageryIdGenerator() { 21 // Hide default constructor for utilities classes 22 } 23 24 public static String getImageryID(String url, ImageryType type) { 25 if (url == null) 16 26 return null; 17 27 18 28 // predefined layers 19 if (ImageryType.BING.equals(type) || url.contains("tiles.virtualearth.net")29 if (ImageryType.BING.equals(type) || url.contains("tiles.virtualearth.net")) 20 30 return "bing"; 21 31 22 if (ImageryType.SCANEX.equals(type) && url.toLowerCase().equals("irs")32 if (ImageryType.SCANEX.equals(type) && url.toLowerCase().equals("irs")) 23 33 return "scanex_irs"; 24 34 25 if (ImageryType.TMS.equals(type) && url.toLowerCase().matches(".+tiles\\.mapbox\\.com/v[3-9]/openstreetmap\\.map.*")35 if (ImageryType.TMS.equals(type) && url.toLowerCase().matches(".+tiles\\.mapbox\\.com/v[3-9]/openstreetmap\\.map.*")) 26 36 return "mapbox"; 27 37 28 38 boolean isWMS = ImageryType.WMS.equals(type); 29 39 30 // System.out.println(url); 40 // System.out.println(url); 31 41 32 42 // Remove protocol … … 37 47 i = url.indexOf('?'); 38 48 String query = ""; 39 if ( i > 0) {49 if (i > 0) { 40 50 query = url.substring(i); 41 51 url = url.substring(0, i); … … 44 54 // Parse query parameters into a sorted map 45 55 final Set<String> removeWMSParams = new TreeSet<>(Arrays.asList(new String[] { 46 47 56 "srs", "width", "height", "bbox", "service", "request", "version", "format", "styles", "transparent" 57 })); 48 58 Map<String, String> qparams = new TreeMap<>(); 49 59 String[] qparamsStr = query.length() > 1 ? query.substring(1).split("&") : new String[0]; 50 for (String param : qparamsStr60 for (String param : qparamsStr) { 51 61 String[] kv = param.split("="); 52 62 kv[0] = kv[0].toLowerCase(); 53 63 // WMS: if this is WMS, remove all parameters except map and layers 54 if (isWMS && removeWMSParams.contains(kv[0])64 if (isWMS && removeWMSParams.contains(kv[0])) 55 65 continue; 56 66 // TMS: skip parameters with variable values 57 if (kv.length > 1 && kv[1].indexOf('{') >= 0 && kv[1].indexOf('}') > 067 if (kv.length > 1 && kv[1].indexOf('{') >= 0 && kv[1].indexOf('}') > 0) 58 68 continue; 59 69 qparams.put(kv[0].toLowerCase(), kv.length > 1 ? kv[1] : null); … … 62 72 // Reconstruct query parameters 63 73 StringBuilder sb = new StringBuilder(); 64 for (String qk : qparams.keySet()65 if (sb.length() > 074 for (String qk : qparams.keySet()) { 75 if (sb.length() > 0) 66 76 sb.append('&'); 67 else if (query.length() > 077 else if (query.length() > 0) 68 78 sb.append('?'); 69 79 sb.append(qk).append('=').append(qparams.get(qk)); … … 75 85 // TMS: remove variable parts 76 86 url = url.replaceAll("\\{[^}]+\\}", ""); 77 while (url.contains(".."))87 while (url.contains("..")) { 78 88 url = url.replace("..", "."); 79 if( url.startsWith(".") ) 89 } 90 if (url.startsWith(".")) 80 91 url = url.substring(1); 81 92 82 // System.out.println("-> " + url + query);83 93 return url + query; 84 94 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffset.java
r29384 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 4 import java.util.Map; 5 4 6 import org.openstreetmap.josm.data.coor.CoordinateFormat; 5 7 import org.openstreetmap.josm.data.coor.LatLon; … … 9 11 * of the position point on the imagery layer. The offset is then calculated 10 12 * as a difference between the two. 11 * 13 * 12 14 * @author Zverik 13 15 * @license WTFPL … … 18 20 private int minZoom, maxZoom; 19 21 20 public ImageryOffset( 22 public ImageryOffset(String imagery, LatLon imageryPos) { 21 23 this.imageryPos = imageryPos; 22 24 this.imagery = imagery; … … 24 26 this.maxZoom = 30; 25 27 } 26 28 27 29 public void setMaxZoom(int maxZoom) { 28 30 this.maxZoom = maxZoom; … … 32 34 this.minZoom = minZoom; 33 35 } 34 36 35 37 public LatLon getImageryPos() { 36 38 return imageryPos; … … 50 52 51 53 @Override 52 public void putServerParams( 54 public void putServerParams(Map<String, String> map) { 53 55 super.putServerParams(map); 54 56 map.put("imagery", imagery); 55 57 map.put("imlat", imageryPos.latToString(CoordinateFormat.DECIMAL_DEGREES)); 56 58 map.put("imlon", imageryPos.lonToString(CoordinateFormat.DECIMAL_DEGREES)); 57 if (minZoom > 059 if (minZoom > 0) 58 60 map.put("minzoom", String.valueOf(minZoom)); 59 if (maxZoom < 3061 if (maxZoom < 30) 60 62 map.put("maxzoom", String.valueOf(maxZoom)); 61 63 } … … 63 65 @Override 64 66 public String toString() { 65 return "ImageryOffset{" + "imageryPos=" + imageryPos + ", imagery=" + imagery + "position=" + position + ", date=" + date + ", author=" + author + ", description=" + description + ", abandonDate=" + abandonDate + '}'; 67 return "ImageryOffset{" + "imageryPos=" + imageryPos + ", imagery=" + imagery + "position=" + position + ", date=" + date + 68 ", author=" + author + ", description=" + description + ", abandonDate=" + abandonDate + '}'; 66 69 } 67 70 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetBase.java
r29388 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 4 import java.util.Date; 4 5 import java.util.Map; 6 5 7 import org.openstreetmap.josm.data.coor.CoordinateFormat; 6 8 import org.openstreetmap.josm.data.coor.LatLon; … … 10 12 * and {@link CalibrationObject} classes and contains common fields 11 13 * like position, author and description. 12 * 14 * 13 15 * @author Zverik 14 16 * @license WTFPL … … 24 26 protected String abandonReason; 25 27 protected boolean flagged; 26 28 27 29 /** 28 30 * Initialize object with the basic information. It's offset location, author, date 29 31 * and description. 30 32 */ 31 public void setBasicInfo( 33 public void setBasicInfo(LatLon position, String author, String description, Date date) { 32 34 this.position = position; 33 35 this.author = author; … … 38 40 } 39 41 40 public void setId( long id) {42 public void setId(long id) { 41 43 this.offsetId = id; 42 44 } … … 60 62 } 61 63 62 public void setFlagged( 64 public void setFlagged(boolean flagged) { 63 65 this.flagged = flagged; 64 66 } … … 75 77 return abandonReason; 76 78 } 77 79 78 80 /** 79 81 * Check that {@link #getAbandonDate()} is not null. Note that … … 96 98 } 97 99 98 public void setDescription( 100 public void setDescription(String description) { 99 101 this.description = description; 100 102 } … … 103 105 return position; 104 106 } 105 106 public void putServerParams( 107 108 public void putServerParams(Map<String, String> map) { 107 109 map.put("lat", position.latToString(CoordinateFormat.DECIMAL_DEGREES)); 108 110 map.put("lon", position.lonToString(CoordinateFormat.DECIMAL_DEGREES)); … … 113 115 @Override 114 116 public String toString() { 115 return "ImageryOffsetBase{" + "position=" + position + ", date=" + date + ", author=" + author + ", description=" + description + ", abandonDate=" + abandonDate + '}'; 117 return "ImageryOffsetBase{" + "position=" + position + ", date=" + date + ", author=" + author + 118 ", description=" + description + ", abandonDate=" + abandonDate + '}'; 116 119 } 117 120 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java
r31646 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 … … 31 32 * or completely unsuitable for imagery offset actions. 32 33 */ 33 public ImageryOffsetPlugin( 34 public ImageryOffsetPlugin(PluginInformation info) { 34 35 super(info); 35 36 … … 42 43 JMenu offsetMenu = version < 5803 43 44 ? Main.main.menu.addMenu("Offset", tr("Offset"), KeyEvent.VK_O, 6, "help") 44 : Main.main.menu.imageryMenu; 45 offsetMenu.add(getAction); 46 offsetMenu.add(storeAction); 45 : Main.main.menu.imageryMenu; 46 offsetMenu.add(getAction); 47 offsetMenu.add(storeAction); 47 48 48 // an ugly hack to add this plugin to the toolbar 49 if(Main.pref.getBoolean("iodb.modify.toolbar", true)50 Collection<String> toolbar = new LinkedList<>(ToolbarPreferences.getToolString()); 51 if(!toolbar.contains("getoffset")52 toolbar.add("getoffset"); 53 Main.pref.putCollection("toolbar", toolbar); 54 Main.toolbar.refreshToolbarControl(); 55 } 56 Main.pref.put("iodb.modify.toolbar", false); 57 } 49 // an ugly hack to add this plugin to the toolbar 50 if (Main.pref.getBoolean("iodb.modify.toolbar", true)) { 51 Collection<String> toolbar = new LinkedList<>(ToolbarPreferences.getToolString()); 52 if (!toolbar.contains("getoffset")) { 53 toolbar.add("getoffset"); 54 Main.pref.putCollection("toolbar", toolbar); 55 Main.toolbar.refreshToolbarControl(); 56 } 57 Main.pref.put("iodb.modify.toolbar", false); 58 } 58 59 } 59 60 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetTools.java
r32329 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 3 6 import java.text.MessageFormat; 4 import java.util.*; 7 import java.util.List; 8 5 9 import org.openstreetmap.josm.Main; 6 10 import org.openstreetmap.josm.data.coor.EastNorth; … … 9 13 import org.openstreetmap.josm.gui.MapView; 10 14 import org.openstreetmap.josm.gui.layer.ImageryLayer; 11 import static org.openstreetmap.josm.tools.I18n.tr;12 15 13 16 /** 14 17 * Some common static methods for querying and processing imagery layers. 15 * 18 * 16 19 * @author Zverik 17 20 * @license WTFPL 18 21 */ 19 public class ImageryOffsetTools { 22 public final class ImageryOffsetTools { 20 23 /** 21 24 * A title for all dialogs created in this plugin. 22 25 */ 23 26 public static final String DIALOG_TITLE = tr("Imagery Offset Database"); 24 27 28 private ImageryOffsetTools() { 29 // Hide default constructor for utilities classes 30 } 31 25 32 /** 26 33 * Returns the topmost visible imagery layer. … … 28 35 */ 29 36 public static ImageryLayer getTopImageryLayer() { 30 if (Main.map == null || Main.map.mapView == null37 if (Main.map == null || Main.map.mapView == null) 31 38 return null; 32 39 List<ImageryLayer> layers = Main.getLayerManager().getLayersOfType(ImageryLayer.class); 33 for (ImageryLayer layer : layers40 for (ImageryLayer layer : layers) { 34 41 String url = layer.getInfo().getUrl(); 35 if (layer.isVisible() && url != null && !url.contains("gps-")42 if (layer.isVisible() && url != null && !url.contains("gps-")) { 36 43 return layer; 37 44 } … … 39 46 return null; 40 47 } 41 48 42 49 /** 43 50 * Calculates the center of a visible map area. … … 49 56 ? new LatLon(0, 0) : proj.eastNorth2latlon(Main.map.mapView.getCenter()); 50 57 } 51 58 52 59 /** 53 60 * Calculates an imagery layer offset. … … 57 64 * @see #applyLayerOffset 58 65 */ 59 public static LatLon getLayerOffset( 66 public static LatLon getLayerOffset(ImageryLayer layer, LatLon center) { 60 67 Projection proj = Main.getProjection(); 61 68 EastNorth offsetCenter = Main.map.mapView.getCenter(); … … 64 71 return offsetLL; 65 72 } 66 73 67 74 /** 68 75 * Applies the offset to the imagery layer. … … 70 77 * @see #getLayerOffset 71 78 */ 72 public static void applyLayerOffset( 79 public static void applyLayerOffset(ImageryLayer layer, ImageryOffset offset) { 73 80 double[] dxy = calculateOffset(offset); 74 81 layer.setOffset(dxy[0], dxy[1]); … … 80 87 * @see #applyLayerOffset 81 88 */ 82 public static double[] calculateOffset( 89 public static double[] calculateOffset(ImageryOffset offset) { 83 90 Projection proj = Main.getProjection(); 84 91 EastNorth center = proj.latlon2eastNorth(offset.getPosition()); 85 92 EastNorth offsetPos = proj.latlon2eastNorth(offset.getImageryPos()); 86 return new double[] { 93 return new double[] {center.getX() - offsetPos.getX(), center.getY() - offsetPos.getY()}; 87 94 } 88 95 89 96 /** 90 97 * Generate unique imagery identifier based on its type and URL. … … 92 99 * @return imagery id. 93 100 */ 94 public static String getImageryID( 101 public static String getImageryID(ImageryLayer layer) { 95 102 return layer == null ? null : 96 103 ImageryIdGenerator.getImageryID(layer.getInfo().getUrl(), layer.getInfo().getImageryType()); 97 104 } 98 105 … … 134 141 * Converts distance in meters to a human-readable string. 135 142 */ 136 public static String formatDistance( double d ) { 137 if( d < 0.0095 ) return formatDistance(d * 1000, tr("mm"), true); 138 if( d < 0.095 ) return formatDistance(d * 100, tr("cm"), true ); 139 if( d < 0.95 ) return formatDistance(d * 100, tr("cm"), false); 140 if( d < 9.5 ) return formatDistance(d, tr("m"), true ); 141 if( d < 950 ) return formatDistance(d, tr("m"), false ); 142 if( d < 9500 ) return formatDistance(d / 1000, tr("km"), true); 143 if( d < 1e6 ) return formatDistance(d / 1000, tr("km"), false); 143 public static String formatDistance(double d) { 144 // CHECKSTYLE.OFF: SingleSpaceSeparator 145 if (d < 0.0095) return formatDistance(d * 1000, tr("mm"), true); 146 if (d < 0.095) return formatDistance(d * 100, tr("cm"), true); 147 if (d < 0.95) return formatDistance(d * 100, tr("cm"), false); 148 if (d < 9.5) return formatDistance(d, tr("m"), true); 149 if (d < 950) return formatDistance(d, tr("m"), false); 150 if (d < 9500) return formatDistance(d / 1000, tr("km"), true); 151 if (d < 1e6) return formatDistance(d / 1000, tr("km"), false); 152 // CHECKSTYLE.ON: SingleSpaceSeparator 144 153 return "\u221E"; 145 154 } … … 152 161 * @return A formatted string. 153 162 */ 154 private static String formatDistance( 163 private static String formatDistance(double d, String si, boolean floating) { 155 164 return MessageFormat.format(floating ? "{0,number,0.0} {1}" : "{0,number,0} {1}", d, si); 156 165 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetWatcher.java
r32462 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 … … 32 33 * @license WTFPL 33 34 */ 34 public class ImageryOffsetWatcher implements ZoomChangeListener, LayerChangeListener, ActiveLayerChangeListener, Destroyable { 35 public final class ImageryOffsetWatcher implements ZoomChangeListener, LayerChangeListener, ActiveLayerChangeListener, Destroyable { 35 36 private static final double THRESHOLD = 1e-8; 36 37 private static ImageryOffsetWatcher instance; … … 71 72 */ 72 73 public static ImageryOffsetWatcher getInstance() { 73 if (instance == null74 if (instance == null) { 74 75 instance = new ImageryOffsetWatcher(); 75 76 } … … 80 81 * Register an offset state listener. 81 82 */ 82 public void register( 83 public void register(OffsetStateListener listener) { 83 84 listeners.add(listener); 84 85 listener.offsetStateChanged(offsetGood); … … 88 89 * Unregister an offset state listener. 89 90 */ 90 public void unregister( 91 public void unregister(OffsetStateListener listener) { 91 92 listeners.remove(listener); 92 93 } … … 95 96 * Change stored offset state, notify listeners if needed. 96 97 */ 97 private void setOffsetGood( 98 if (good != offsetGood99 for (OffsetStateListener listener : listeners)98 private void setOffsetGood(boolean good) { 99 if (good != offsetGood) { 100 for (OffsetStateListener listener : listeners) { 100 101 listener.offsetStateChanged(good); 102 } 101 103 } 102 104 offsetGood = good; … … 107 109 */ 108 110 private synchronized void checkOffset() { 109 if (maxDistance <= 0111 if (maxDistance <= 0) { 110 112 setOffsetGood(true); 111 113 return; 112 114 } 113 115 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 114 if (layer == null116 if (layer == null) { 115 117 setOffsetGood(true); 116 118 return; … … 119 121 Integer hash = layer.hashCode(); 120 122 ImageryLayerData data = layers.get(hash); 121 if (data == null123 if (data == null) { 122 124 // create entry for this layer and mark as needing alignment 123 125 data = new ImageryLayerData(); … … 125 127 data.lastDy = layer.getDy(); 126 128 boolean r = false; 127 if (Math.abs(data.lastDx) + Math.abs(data.lastDy) > THRESHOLD129 if (Math.abs(data.lastDx) + Math.abs(data.lastDy) > THRESHOLD) { 128 130 data.lastChecked = center; 129 131 r = true; … … 133 135 } else { 134 136 // now, we have a returning layer. 135 if (Math.abs(data.lastDx - layer.getDx()) + Math.abs(data.lastDy - layer.getDy()) > THRESHOLD137 if (Math.abs(data.lastDx - layer.getDx()) + Math.abs(data.lastDy - layer.getDy()) > THRESHOLD) { 136 138 // offset has changed, record the current position 137 139 data.lastDx = layer.getDx(); … … 153 155 public void markGood() { 154 156 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 155 if (layer != null157 if (layer != null) { 156 158 LatLon center = ImageryOffsetTools.getMapCenter(); 157 159 Integer hash = layer.hashCode(); 158 160 ImageryLayerData data = layers.get(hash); 159 if (data == null161 if (data == null) { 160 162 // create entry for this layer and mark as good 161 163 data = new ImageryLayerData(); … … 216 218 * projections: nobody uses them anyway. 217 219 */ 218 private void storeLayerOffset( 220 private void storeLayerOffset(ImageryLayer layer) { 219 221 String id = ImageryOffsetTools.getImageryID(layer); 220 if (!Main.pref.getBoolean("iodb.remember.offsets", true) || id == null222 if (!Main.pref.getBoolean("iodb.remember.offsets", true) || id == null) 221 223 return; 222 224 Collection<String> offsets = new LinkedList<>(Main.pref.getCollection("iodb.stored.offsets")); 223 for (Iterator<String> iter = offsets.iterator(); iter.hasNext();225 for (Iterator<String> iter = offsets.iterator(); iter.hasNext();) { 224 226 String[] offset = iter.next().split(":"); 225 if (offset.length == 5 && offset[0].equals(id)227 if (offset.length == 5 && offset[0].equals(id)) 226 228 iter.remove(); 227 229 } … … 234 236 * Loads the current imagery layer offset from preferences. 235 237 */ 236 private void loadLayerOffset( 238 private void loadLayerOffset(ImageryLayer layer) { 237 239 String id = ImageryOffsetTools.getImageryID(layer); 238 if (!Main.pref.getBoolean("iodb.remember.offsets", true) || id == null240 if (!Main.pref.getBoolean("iodb.remember.offsets", true) || id == null) 239 241 return; 240 242 Collection<String> offsets = Main.pref.getCollection("iodb.stored.offsets"); 241 for (String offset : offsets243 for (String offset : offsets) { 242 244 String[] parts = offset.split(":"); 243 if (parts.length == 5 && parts[0].equals(id)245 if (parts.length == 5 && parts[0].equals(id)) { 244 246 double[] dparts = new double[4]; 245 247 try { 246 for (int i = 0; i < 4; i++)248 for (int i = 0; i < 4; i++) { 247 249 dparts[i] = Double.parseDouble(parts[i+1]); 248 } catch( Exception e ) { 250 } 251 } catch (Exception e) { 249 252 continue; 250 253 } 251 254 LatLon lastPos = new LatLon(dparts[0], dparts[1]); 252 if (lastPos.greatCircleDistance(ImageryOffsetTools.getMapCenter()) < Math.max(maxDistance, 3.0) * 1000255 if (lastPos.greatCircleDistance(ImageryOffsetTools.getMapCenter()) < Math.max(maxDistance, 3.0) * 1000) { 253 256 // apply offset 254 257 layer.setOffset(dparts[2], dparts[3]); … … 277 280 */ 278 281 public interface OffsetStateListener { 279 void offsetStateChanged( 282 void offsetStateChanged(boolean isOffsetGood); 280 283 } 281 284 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java
r32462 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 … … 72 73 * @param offsets The list of offset to choose from. 73 74 */ 74 public OffsetDialog( 75 public OffsetDialog(List<ImageryOffsetBase> offsets) { 75 76 super(JOptionPane.getFrameForComponent(Main.parent), ImageryOffsetTools.DIALOG_TITLE, 76 77 MODAL ? ModalityType.DOCUMENT_MODAL : ModalityType.MODELESS); … … 94 95 calibrationBox.addActionListener(new ActionListener() { 95 96 @Override 96 public void actionPerformed( 97 public void actionPerformed(ActionEvent e) { 97 98 Main.pref.put(PREF_CALIBRATION, calibrationBox.isSelected()); 98 99 updateButtonPanel(); … … 103 104 deprecatedBox.addActionListener(new ActionListener() { 104 105 @Override 105 public void actionPerformed( 106 public void actionPerformed(ActionEvent e) { 106 107 Main.pref.put(PREF_DEPRECATED, deprecatedBox.isSelected()); 107 108 updateButtonPanel(); … … 135 136 private void updateButtonPanel() { 136 137 List<ImageryOffsetBase> filteredOffsets = filterOffsets(); 137 if (buttonPanel == null138 if (buttonPanel == null) 138 139 buttonPanel = new JPanel(); 139 140 buttonPanel.removeAll(); 140 141 buttonPanel.setLayout(new GridLayout(filteredOffsets.size(), 1, 0, 5)); 141 for (ImageryOffsetBase offset : filteredOffsets142 for (ImageryOffsetBase offset : filteredOffsets) { 142 143 OffsetDialogButton button = new OffsetDialogButton(offset); 143 144 button.addActionListener(this); 144 145 JPopupMenu popupMenu = new JPopupMenu(); 145 146 popupMenu.add(new OffsetInfoAction(offset)); 146 if (!offset.isDeprecated()147 if (!offset.isDeprecated()) { 147 148 DeprecateOffsetAction action = new DeprecateOffsetAction(offset); 148 149 action.setListener(new DeprecateOffsetListener(offset)); … … 164 165 boolean showDeprecated = Main.pref.getBoolean(PREF_DEPRECATED, false); 165 166 List<ImageryOffsetBase> filteredOffsets = new ArrayList<>(); 166 for (ImageryOffsetBase offset : offsets167 if (offset.isDeprecated() && !showDeprecated167 for (ImageryOffsetBase offset : offsets) { 168 if (offset.isDeprecated() && !showDeprecated) 168 169 continue; 169 if (offset instanceof CalibrationObject && !showCalibration170 if (offset instanceof CalibrationObject && !showCalibration) 170 171 continue; 171 172 filteredOffsets.add(offset); 172 if (filteredOffsets.size() >= MAX_OFFSETS173 if (filteredOffsets.size() >= MAX_OFFSETS) 173 174 break; 174 175 } … … 182 183 @Override 183 184 public void zoomChanged() { 184 for (Component c : buttonPanel.getComponents()185 if (c instanceof OffsetDialogButton186 ((OffsetDialogButton)c).updateLocation(); 185 for (Component c : buttonPanel.getComponents()) { 186 if (c instanceof OffsetDialogButton) { 187 ((OffsetDialogButton) c).updateLocation(); 187 188 } 188 189 } … … 194 195 */ 195 196 @Override 196 public void paint( 197 if (offsets == null197 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 198 if (offsets == null) 198 199 return; 199 200 200 Graphics2D g2 = (Graphics2D)g.create(); 201 Graphics2D g2 = (Graphics2D) g.create(); 201 202 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 202 203 g2.setStroke(new BasicStroke(2)); 203 for (ImageryOffsetBase offset : filterOffsets()204 for (ImageryOffsetBase offset : filterOffsets()) { 204 205 Point p = mv.getPoint(offset.getPosition()); 205 206 g2.setColor(Color.BLACK); … … 221 222 prepareDialog(); 222 223 MapView.addZoomChangeListener(this); 223 if ( !MODAL) {224 if (!MODAL) { 224 225 Main.map.mapView.addTemporaryLayer(this); 225 226 Main.map.mapView.repaint(); … … 237 238 */ 238 239 @Override 239 public void actionPerformed( 240 if (e.getSource() instanceof OffsetDialogButton241 selectedOffset = ((OffsetDialogButton)e.getSource()).getOffset(); 240 public void actionPerformed(ActionEvent e) { 241 if (e.getSource() instanceof OffsetDialogButton) { 242 selectedOffset = ((OffsetDialogButton) e.getSource()).getOffset(); 242 243 } else 243 244 selectedOffset = null; … … 245 246 || selectedOffset instanceof CalibrationObject 246 247 || Main.pref.getBoolean("iodb.close.on.select", true); 247 if (closeDialog248 if (closeDialog) { 248 249 MapView.removeZoomChangeListener(this); 249 250 setVisible(false); 250 251 } 251 if ( !MODAL) {252 if (closeDialog252 if (!MODAL) { 253 if (closeDialog) { 253 254 Main.map.mapView.removeTemporaryLayer(this); 254 255 Main.map.mapView.repaint(); 255 256 } 256 if (selectedOffset != null257 if (selectedOffset != null) { 257 258 applyOffset(); 258 if (!closeDialog259 if (!closeDialog) 259 260 updateButtonPanel(); 260 261 } 261 262 } 262 263 } 263 264 264 265 265 /** … … 269 269 */ 270 270 public void applyOffset() { 271 if (selectedOffset instanceof ImageryOffset271 if (selectedOffset instanceof ImageryOffset) { 272 272 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 273 ImageryOffsetTools.applyLayerOffset(layer, (ImageryOffset)selectedOffset); 273 ImageryOffsetTools.applyLayerOffset(layer, (ImageryOffset) selectedOffset); 274 274 ImageryOffsetWatcher.getInstance().markGood(); 275 275 Main.map.repaint(); 276 if (!Main.pref.getBoolean("iodb.offset.message", false)276 if (!Main.pref.getBoolean("iodb.offset.message", false)) { 277 277 JOptionPane.showMessageDialog(Main.parent, 278 278 tr("The topmost imagery layer has been shifted to presumably match\n" … … 282 282 Main.pref.put("iodb.offset.message", true); 283 283 } 284 } else if (selectedOffset instanceof CalibrationObject285 CalibrationLayer clayer = new CalibrationLayer((CalibrationObject)selectedOffset); 284 } else if (selectedOffset instanceof CalibrationObject) { 285 CalibrationLayer clayer = new CalibrationLayer((CalibrationObject) selectedOffset); 286 286 Main.getLayerManager().addLayer(clayer); 287 287 clayer.panToCenter(); 288 if (!Main.pref.getBoolean("iodb.calibration.message", false)288 if (!Main.pref.getBoolean("iodb.calibration.message", false)) { 289 289 JOptionPane.showMessageDialog(Main.parent, 290 290 tr("A layer has been added with a calibration geometry. Hide data layers,\n" … … 305 305 * Initialize the listener with an offset. 306 306 */ 307 publicDeprecateOffsetListener(307 DeprecateOffsetListener(ImageryOffsetBase offset) { 308 308 this.offset = offset; 309 309 } … … 324 324 class HelpAction extends AbstractAction { 325 325 326 publicHelpAction() {326 HelpAction() { 327 327 super(tr("Help")); 328 328 putValue(SMALL_ICON, ImageProvider.get("help")); … … 330 330 331 331 @Override 332 public void actionPerformed( 332 public void actionPerformed(ActionEvent e) { 333 333 String base = Main.pref.get("url.openstreetmap-wiki", "http://wiki.openstreetmap.org/wiki/"); 334 334 String lang = LanguageInfo.getWikiLanguagePrefix(); … … 341 341 lang = ""; 342 342 } 343 } catch (IOException ex343 } catch (IOException ex) { 344 344 lang = ""; 345 345 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialogButton.java
r29432 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 3 import java.awt.*; 4 import javax.swing.*; 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.AlphaComposite; 7 import java.awt.BasicStroke; 8 import java.awt.BorderLayout; 9 import java.awt.Color; 10 import java.awt.Component; 11 import java.awt.Font; 12 import java.awt.Graphics; 13 import java.awt.Graphics2D; 14 import java.awt.Point; 15 import java.awt.RenderingHints; 16 17 import javax.swing.Box; 18 import javax.swing.BoxLayout; 19 import javax.swing.Icon; 20 import javax.swing.ImageIcon; 21 import javax.swing.JButton; 22 import javax.swing.JLabel; 23 import javax.swing.JPanel; 24 import javax.swing.SwingConstants; 25 5 26 import org.openstreetmap.josm.Main; 6 27 import org.openstreetmap.josm.data.coor.EastNorth; … … 9 30 import org.openstreetmap.josm.gui.layer.ImageryLayer; 10 31 import org.openstreetmap.josm.tools.ImageProvider; 11 import static org.openstreetmap.josm.tools.I18n.tr;12 32 13 33 /** 14 34 * A button which shows offset information. Must be spectacular, since it's the only 15 35 * non-JOptionPane GUI in the plugin. 16 * 36 * 17 37 * @author Zverik 18 38 * @license WTFPL 19 39 */ 20 40 public class OffsetDialogButton extends JButton { 21 41 22 42 private ImageryOffsetBase offset; 23 43 … … 29 49 * @param offset An offset to display on the button. 30 50 */ 31 public OffsetDialogButton( 51 public OffsetDialogButton(ImageryOffsetBase offset) { 32 52 this.offset = offset; 33 53 layoutComponents(); … … 57 77 String authorAndDate = offset.isDeprecated() 58 78 ? tr("Deprecated by {0} on {1}", offset.getAbandonAuthor(), 59 OffsetInfoAction.DATE_FORMAT.format(offset.getAbandonDate())) 60 : tr("Created by {0} on {1}", offset.getAuthor(), 61 OffsetInfoAction.DATE_FORMAT.format(offset.getDate())); 62 JLabel authorAndDateLabel = new JLabel(authorAndDate); 63 Font authorFont = new Font(authorAndDateLabel.getFont().getName(), Font.ITALIC, authorAndDateLabel.getFont().getSize()); 64 authorAndDateLabel.setFont(authorFont); 65 66 directionArrow = new DirectionIcon(offset.getPosition()); 67 distanceLabel = new JLabel("", directionArrow, SwingConstants.RIGHT); 68 distanceLabel.setHorizontalTextPosition(SwingConstants.LEFT); 69 Font distanceFont = new Font(distanceLabel.getFont().getName(), Font.PLAIN, distanceLabel.getFont().getSize()); 70 distanceLabel.setFont(distanceFont); 71 updateLocation(); 72 73 String description = offset.isDeprecated() ? offset.getAbandonReason() : offset.getDescription(); 74 description = description.replace("<", "<").replace(">", ">"); 75 JLabel descriptionLabel = new JLabel("<html><div style=\"width: 300px;\">"+description+"</div></html>"); 76 Font descriptionFont = new Font(descriptionLabel.getFont().getName(), Font.BOLD, descriptionLabel.getFont().getSize()); 77 descriptionLabel.setFont(descriptionFont); 78 79 OffsetIcon offsetIcon = new OffsetIcon(offset); 80 double offsetDistance = offset instanceof ImageryOffset 81 ? offsetIcon.getDistance() : 0.0; 82 // ? ((ImageryOffset)offset).getImageryPos().greatCircleDistance(offset.getPosition()) : 0.0; 83 JLabel offsetLabel = new JLabel(offsetDistance > 0.2 ? ImageryOffsetTools.formatDistance(offsetDistance) : "", 84 offsetIcon, SwingConstants.CENTER); 85 Font offsetFont = new Font(offsetLabel.getFont().getName(), Font.PLAIN, offsetLabel.getFont().getSize() - 2); 86 offsetLabel.setFont(offsetFont); 87 offsetLabel.setHorizontalTextPosition(SwingConstants.CENTER); 88 offsetLabel.setVerticalTextPosition(SwingConstants.BOTTOM); 89 90 Box topLine = new Box(BoxLayout.X_AXIS); 91 topLine.add(authorAndDateLabel); 92 topLine.add(Box.createHorizontalGlue()); 93 topLine.add(Box.createHorizontalStrut(10)); 94 topLine.add(distanceLabel); 95 96 JPanel p = new JPanel(new BorderLayout(10, 5)); 97 p.setOpaque(false); 98 p.add(topLine, BorderLayout.NORTH); 99 p.add(offsetLabel, BorderLayout.WEST); 100 p.add(descriptionLabel, BorderLayout.CENTER); 101 add(p); 79 OffsetInfoAction.DATE_FORMAT.format(offset.getAbandonDate())) 80 : tr("Created by {0} on {1}", offset.getAuthor(), 81 OffsetInfoAction.DATE_FORMAT.format(offset.getDate())); 82 JLabel authorAndDateLabel = new JLabel(authorAndDate); 83 Font authorFont = new Font(authorAndDateLabel.getFont().getName(), Font.ITALIC, authorAndDateLabel.getFont().getSize()); 84 authorAndDateLabel.setFont(authorFont); 85 86 directionArrow = new DirectionIcon(offset.getPosition()); 87 distanceLabel = new JLabel("", directionArrow, SwingConstants.RIGHT); 88 distanceLabel.setHorizontalTextPosition(SwingConstants.LEFT); 89 Font distanceFont = new Font(distanceLabel.getFont().getName(), Font.PLAIN, distanceLabel.getFont().getSize()); 90 distanceLabel.setFont(distanceFont); 91 updateLocation(); 92 93 String description = offset.isDeprecated() ? offset.getAbandonReason() : offset.getDescription(); 94 description = description.replace("<", "<").replace(">", ">"); 95 JLabel descriptionLabel = new JLabel("<html><div style=\"width: 300px;\">"+description+"</div></html>"); 96 Font descriptionFont = new Font(descriptionLabel.getFont().getName(), Font.BOLD, descriptionLabel.getFont().getSize()); 97 descriptionLabel.setFont(descriptionFont); 98 99 OffsetIcon offsetIcon = new OffsetIcon(offset); 100 double offsetDistance = offset instanceof ImageryOffset 101 ? offsetIcon.getDistance() : 0.0; 102 // ? ((ImageryOffset)offset).getImageryPos().greatCircleDistance(offset.getPosition()) : 0.0; 103 JLabel offsetLabel = new JLabel(offsetDistance > 0.2 ? ImageryOffsetTools.formatDistance(offsetDistance) : "", 104 offsetIcon, SwingConstants.CENTER); 105 Font offsetFont = new Font(offsetLabel.getFont().getName(), Font.PLAIN, offsetLabel.getFont().getSize() - 2); 106 offsetLabel.setFont(offsetFont); 107 offsetLabel.setHorizontalTextPosition(SwingConstants.CENTER); 108 offsetLabel.setVerticalTextPosition(SwingConstants.BOTTOM); 109 110 Box topLine = new Box(BoxLayout.X_AXIS); 111 topLine.add(authorAndDateLabel); 112 topLine.add(Box.createHorizontalGlue()); 113 topLine.add(Box.createHorizontalStrut(10)); 114 topLine.add(distanceLabel); 115 116 JPanel p = new JPanel(new BorderLayout(10, 5)); 117 p.setOpaque(false); 118 p.add(topLine, BorderLayout.NORTH); 119 p.add(offsetLabel, BorderLayout.WEST); 120 p.add(descriptionLabel, BorderLayout.CENTER); 121 add(p); 102 122 } 103 123 104 124 /** 105 125 * Calculates length and direction for two points in the imagery offset object. 106 * @see #getLengthAndDirection(iodb.ImageryOffset, double, double) 107 */ 108 private double[] getLengthAndDirection( 126 * @see #getLengthAndDirection(iodb.ImageryOffset, double, double) 127 */ 128 private double[] getLengthAndDirection(ImageryOffset offset) { 109 129 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 110 130 double[] dxy = layer == null ? new double[] {0.0, 0.0} : new double[] {layer.getDx(), layer.getDy()}; … … 118 138 * @see #getLengthAndDirection(iodb.ImageryOffset) 119 139 */ 120 public static double[] getLengthAndDirection( 140 public static double[] getLengthAndDirection(ImageryOffset offset, double dx, double dy) { 121 141 Projection proj = Main.getProjection(); 122 142 EastNorth pos = proj.latlon2eastNorth(offset.getPosition()); … … 124 144 double length = correctedCenterLL.greatCircleDistance(offset.getImageryPos()); 125 145 double direction = length < 1e-2 ? 0.0 : correctedCenterLL.heading(offset.getImageryPos()); 126 if (direction < 0146 if (direction < 0) 127 147 direction += Math.PI * 2; 128 148 return new double[] {length, direction}; 129 149 } 130 150 131 private static void drawArrow( 132 int dx = (int)Math.round(Math.sin(direction) * length / 2); 133 int dy = (int)Math.round(Math.cos(direction) * length / 2); 151 private static void drawArrow(Graphics g, int cx, int cy, double length, double direction) { 152 int dx = (int) Math.round(Math.sin(direction) * length / 2); 153 int dy = (int) Math.round(Math.cos(direction) * length / 2); 134 154 g.drawLine(cx - dx, cy - dy, cx + dx, cy + dy); 135 155 double wingLength = Math.max(length / 3, 4); 136 156 double d1 = direction - Math.PI / 6; 137 int dx1 = (int)Math.round(Math.sin(d1) * wingLength); 138 int dy1 = (int)Math.round(Math.cos(d1) * wingLength); 157 int dx1 = (int) Math.round(Math.sin(d1) * wingLength); 158 int dy1 = (int) Math.round(Math.cos(d1) * wingLength); 139 159 g.drawLine(cx + dx, cy + dy, cx + dx - dx1, cy + dy - dy1); 140 160 double d2 = direction + Math.PI / 6; 141 int dx2 = (int)Math.round(Math.sin(d2) * wingLength); 142 int dy2 = (int)Math.round(Math.cos(d2) * wingLength); 161 int dx2 = (int) Math.round(Math.sin(d2) * wingLength); 162 int dy2 = (int) Math.round(Math.cos(d2) * wingLength); 143 163 g.drawLine(cx + dx, cy + dy, cx + dx - dx2, cy + dy - dy2); 144 164 } … … 159 179 * of an arrow if they're needed. 160 180 */ 161 publicOffsetIcon(181 OffsetIcon(ImageryOffsetBase offset) { 162 182 isDeprecated = offset.isDeprecated(); 163 183 isCalibration = offset instanceof CalibrationObject; 164 if (offset instanceof ImageryOffset184 if (offset instanceof ImageryOffset) { 165 185 background = ImageProvider.get("offset"); 166 double[] ld = getLengthAndDirection((ImageryOffset)offset); 186 double[] ld = getLengthAndDirection((ImageryOffset) offset); 167 187 distance = ld[0]; 168 188 direction = ld[1]; … … 179 199 * Paints the base image and adds to it according to the offset. 180 200 */ 181 public void paintIcon( Component comp, Graphics g, int x, int y ) { 201 @Override 202 public void paintIcon(Component comp, Graphics g, int x, int y) { 182 203 background.paintIcon(comp, g, x, y); 183 204 184 Graphics2D g2 = (Graphics2D)g.create(); 205 Graphics2D g2 = (Graphics2D) g.create(); 185 206 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 186 if (!isCalibration207 if (!isCalibration) { 187 208 g2.setColor(Color.black); 188 209 Point c = new Point(x + getIconWidth() / 2, y + getIconHeight() / 2); 189 if (distance < 1e-2210 if (distance < 1e-2) { 190 211 // no offset 191 212 g2.fillOval(c.x - 3, c.y - 3, 7, 7); … … 197 218 } 198 219 } 199 if (isDeprecated220 if (isDeprecated) { 200 221 // big red X 201 222 g2.setColor(Color.red); … … 207 228 } 208 229 230 @Override 209 231 public int getIconWidth() { 210 232 return background.getIconWidth(); 211 233 } 212 234 235 @Override 213 236 public int getIconHeight() { 214 237 return background.getIconHeight(); … … 223 246 private double direction; 224 247 225 publicDirectionIcon(248 DirectionIcon(LatLon to) { 226 249 this.to = to; 227 250 } 228 251 229 public void updateIcon( 252 public void updateIcon(LatLon from) { 230 253 distance = from.greatCircleDistance(to); 231 254 direction = to.heading(from); … … 235 258 * Paints the base image and adds to it according to the offset. 236 259 */ 237 public void paintIcon( Component comp, Graphics g, int x, int y ) { 238 Graphics2D g2 = (Graphics2D)g.create(); 260 @Override 261 public void paintIcon(Component comp, Graphics g, int x, int y) { 262 Graphics2D g2 = (Graphics2D) g.create(); 239 263 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 240 264 g2.setColor(Color.black); 241 265 Point c = new Point(x + getIconWidth() / 2, y + getIconHeight() / 2); 242 if (distance < 1266 if (distance < 1) { 243 267 // no offset 244 268 int r = 2; … … 251 275 } 252 276 277 @Override 253 278 public int getIconWidth() { 254 279 return SIZE; 255 280 } 256 281 282 @Override 257 283 public int getIconHeight() { 258 284 return SIZE; -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetInfoAction.java
r29434 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 2 5 3 6 import java.awt.event.ActionEvent; … … 5 8 import java.net.URLEncoder; 6 9 import java.text.SimpleDateFormat; 10 7 11 import javax.swing.AbstractAction; 8 12 import javax.swing.JOptionPane; 13 9 14 import org.openstreetmap.josm.Main; 10 import static org.openstreetmap.josm.tools.I18n.tr;11 15 import org.openstreetmap.josm.tools.ImageProvider; 12 16 13 17 /** 14 18 * Display an information box for an offset. 15 * 19 * 16 20 * @author Zverik 17 21 * @license WTFPL … … 21 25 22 26 ImageryOffsetBase offset; 23 27 24 28 /** 25 29 * Initializes the action with an offset object. 26 30 * Calls {@link #getInformationObject(iodb.ImageryOffsetBase)}. 27 31 */ 28 public OffsetInfoAction( 32 public OffsetInfoAction(ImageryOffsetBase offset) { 29 33 super(tr("Offset Information")); 30 34 putValue(SMALL_ICON, ImageProvider.get("info")); … … 37 41 * to report the given offset. 38 42 */ 43 @Override 39 44 public void actionPerformed(ActionEvent e) { 40 45 Object info = offset == null ? null : getInformationObject(offset); 41 if (offset.isFlagged()46 if (offset.isFlagged()) 42 47 JOptionPane.showMessageDialog(Main.parent, info, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE); 43 48 else { 44 49 int result = JOptionPane.showOptionDialog(Main.parent, info, ImageryOffsetTools.DIALOG_TITLE, 45 50 JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, 46 new String[] { 47 if (result == 151 new String[] {"OK", tr("Report this offset")}, null); 52 if (result == 1) { 48 53 // ask for a reason 49 54 Object reason = JOptionPane.showInputDialog(Main.parent, 50 55 tr("You are to notify moderators of this offset. Why?"), 51 56 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE); 52 if (reason != null && reason.toString().length() > 057 if (reason != null && reason.toString().length() > 0) { 53 58 try { 54 59 String query = "report?id=" + offset.getId() 55 60 + "&reason=" + URLEncoder.encode(reason.toString(), "UTF8"); 56 61 SimpleOffsetQueryTask reportTask = 57 62 new SimpleOffsetQueryTask(query, tr("Reporting the offset...")); 58 63 Main.worker.submit(reportTask); 59 } catch (UnsupportedEncodingException ex60 // WTF64 } catch (UnsupportedEncodingException ex) { 65 Main.error(ex); 61 66 } 62 67 } … … 68 73 * Constructs a string with all information about the given offset. 69 74 */ 70 public static Object getInformationObject( 75 public static Object getInformationObject(ImageryOffsetBase offset) { 71 76 StringBuilder sb = new StringBuilder(); 72 if (offset instanceof ImageryOffset73 double odist = ((ImageryOffset)offset).getImageryPos().greatCircleDistance(offset.getPosition()); 74 if (odist < 1e-277 if (offset instanceof ImageryOffset) { 78 double odist = ((ImageryOffset) offset).getImageryPos().greatCircleDistance(offset.getPosition()); 79 if (odist < 1e-2) odist = 0.0; 75 80 sb.append(tr("An imagery offset of {0}", ImageryOffsetTools.formatDistance(odist))).append('\n'); 76 sb.append(tr("Imagery ID")).append(": ").append(((ImageryOffset)offset).getImagery()).append('\n'); 81 sb.append(tr("Imagery ID")).append(": ").append(((ImageryOffset) offset).getImagery()).append('\n'); 77 82 } else { 78 sb.append(tr("A calibration geometry of {0} nodes", ((CalibrationObject)offset).getGeometry().length)).append('\n'); 83 sb.append(tr("A calibration geometry of {0} nodes", ((CalibrationObject) offset).getGeometry().length)).append('\n'); 79 84 } 80 85 81 86 double dist = ImageryOffsetTools.getMapCenter().greatCircleDistance(offset.getPosition()); 82 87 sb.append(dist < 50 ? tr("Determined right here") : tr("Determined {0} away", 83 88 ImageryOffsetTools.formatDistance(dist))); 84 89 85 90 sb.append("\n\n"); 86 91 sb.append(tr("Created by {0} on {1}", offset.getAuthor(), 87 92 DATE_FORMAT.format(offset.getDate()))).append('\n'); 88 93 sb.append(tr("Description")).append(": ").append(offset.getDescription()); 89 90 if (offset.isDeprecated()94 95 if (offset.isDeprecated()) { 91 96 sb.append("\n\n"); 92 sb.append(tr("Deprecated by {0} on {1}",offset.getAbandonAuthor(), 97 sb.append(tr("Deprecated by {0} on {1}", offset.getAbandonAuthor(), 93 98 DATE_FORMAT.format(offset.getAbandonDate()))).append('\n'); 94 99 sb.append(tr("Reason")).append(": ").append(offset.getAbandonReason()); 95 100 } 96 101 97 if (offset.isFlagged()102 if (offset.isFlagged()) { 98 103 sb.append("\n\n").append(tr("This entry has been reported.")); 99 104 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/QuerySuccessListener.java
r29384 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/SimpleOffsetQueryTask.java
r29450 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 2 5 3 6 import java.io.IOException; 4 7 import java.io.InputStream; 5 import java.net.*; 6 import java.util.*; 7 import java.util.regex.*; 8 import java.net.HttpURLConnection; 9 import java.net.MalformedURLException; 10 import java.net.URL; 11 import java.util.Scanner; 12 import java.util.regex.Matcher; 13 import java.util.regex.Pattern; 14 8 15 import javax.swing.JOptionPane; 16 9 17 import org.openstreetmap.josm.Main; 10 18 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 11 import static org.openstreetmap.josm.tools.I18n.tr;12 19 13 20 /** … … 29 36 * @param title A title for the progress monitor. 30 37 */ 31 publicSimpleOffsetQueryTask(38 SimpleOffsetQueryTask(String query, String title) { 32 39 super(ImageryOffsetTools.DIALOG_TITLE); 33 40 this.query = query; … … 39 46 * In case a query was not specified when the object was constructed, 40 47 * it can be set with this method. 41 * @see #SimpleOffsetQueryTask(java.lang.String, java.lang.String) 48 * @see #SimpleOffsetQueryTask(java.lang.String, java.lang.String) 42 49 */ 43 public void setQuery( 50 public void setQuery(String query) { 44 51 this.query = query; 45 52 } … … 48 55 * Install a listener for successful responses. There can be only one. 49 56 */ 50 public void setListener( 57 public void setListener(QuerySuccessListener listener) { 51 58 this.listener = listener; 52 59 } … … 68 75 errorMessage = null; 69 76 doQuery(query); 70 } catch (UploadException e77 } catch (UploadException e) { 71 78 errorMessage = tr("Server has rejected the request") + ":\n" + e.getMessage(); 72 } catch (IOException e79 } catch (IOException e) { 73 80 errorMessage = tr("Unable to connect to the server") + "\n" + e.getMessage(); 74 81 } … … 78 85 * Sends a request to the imagery offset server. Processes exceptions and 79 86 * return codes, calls {@link #processResponse(java.io.InputStream)} on success. 80 * @param query81 * @throws iodb.SimpleOffsetQueryTask.UploadException82 * @throws IOException83 87 */ 84 private void doQuery( 88 private void doQuery(String query) throws UploadException, IOException { 85 89 try { 86 90 String serverURL = Main.pref.get("iodb.server.url", "http://offsets.textual.ru/"); 87 91 URL url = new URL(serverURL + query); 88 // Main.info("IODB URL = " + url); // todo: remove in release 89 HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 92 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 90 93 connection.connect(); 91 if (connection.getResponseCode() != 20094 if (connection.getResponseCode() != 200) { 92 95 throw new IOException("HTTP Response code " + connection.getResponseCode() + " (" + connection.getResponseMessage() + ")"); 93 96 } 94 97 InputStream inp = connection.getInputStream(); 95 if (inp == null98 if (inp == null) 96 99 throw new IOException("Empty response"); 97 100 try { 98 if (!cancelled101 if (!cancelled) 99 102 processResponse(inp); 100 103 } finally { 101 104 connection.disconnect(); 102 105 } 103 } catch (MalformedURLException ex106 } catch (MalformedURLException ex) { 104 107 throw new IOException("Malformed URL: " + ex.getMessage()); 105 108 } … … 120 123 @Override 121 124 protected void finish() { 122 if (errorMessage != null125 if (errorMessage != null) { 123 126 JOptionPane.showMessageDialog(Main.parent, errorMessage, 124 127 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.ERROR_MESSAGE); 125 } else if (listener != null128 } else if (listener != null) { 126 129 listener.queryPassed(); 127 130 } … … 133 136 * @throws iodb.SimpleOffsetQueryTask.UploadException Thrown if an error message was found. 134 137 */ 135 protected void processResponse( 138 protected void processResponse(InputStream inp) throws UploadException { 136 139 String response = ""; 137 if (inp != null140 if (inp != null) { 138 141 Scanner sc = new Scanner(inp).useDelimiter("\\A"); 139 142 response = sc.hasNext() ? sc.next() : ""; … … 141 144 Pattern p = Pattern.compile("<(\\w+)>([^<]+)</\\1>"); 142 145 Matcher m = p.matcher(response); 143 if (m.find()144 if (m.group(1).equals("error")146 if (m.find()) { 147 if (m.group(1).equals("error")) { 145 148 throw new UploadException(m.group(2)); 146 149 } … … 154 157 */ 155 158 public static class UploadException extends Exception { 156 publicUploadException(159 UploadException(String message) { 157 160 super(message); 158 161 } -
applications/editors/josm/plugins/imagery_offset_db/src/iodb/StoreImageryOffsetAction.java
r32462 r32528 1 // License: WTFPL. For details, see LICENSE file. 1 2 package iodb; 2 3 … … 48 49 @Override 49 50 public void actionPerformed(ActionEvent e) { 50 if (Main.map == null || Main.map.mapView == null51 if (Main.map == null || Main.map.mapView == null) 51 52 return; 52 53 53 54 ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer(); 54 if (layer == null55 if (layer == null) 55 56 return; 56 57 57 58 String userName = JosmUserIdentityManager.getInstance().getUserName(); 58 if (userName == null || userName.length() == 059 if (userName == null || userName.length() == 0) { 59 60 JOptionPane.showMessageDialog(Main.parent, 60 61 tr("To store imagery offsets you must be a registered OSM user."), … … 62 63 return; 63 64 } 64 if (userName.indexOf('@') > 065 if (userName.indexOf('@') > 0) 65 66 userName = userName.replace('@', ','); 66 67 … … 69 70 if (getLayerManager().getEditDataSet() != null) { 70 71 Collection<OsmPrimitive> selectedObjects = getLayerManager().getEditDataSet().getSelected(); 71 if (selectedObjects.size() == 172 if (selectedObjects.size() == 1) { 72 73 OsmPrimitive selection = selectedObjects.iterator().next(); 73 if ((selection instanceof Node || selection instanceof Way) && !selection.isIncomplete() && !selection.isReferredByWays(1)74 if ((selection instanceof Node || selection instanceof Way) && !selection.isIncomplete() && !selection.isReferredByWays(1)) { 74 75 String[] options = new String[] {tr("Store calibration geometry"), tr("Store imagery offset")}; 75 76 int result = JOptionPane.showOptionDialog(Main.parent, … … 77 78 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, 78 79 null, options, options[0]); 79 if (result == 2 || result == JOptionPane.CLOSED_OPTION80 if (result == 2 || result == JOptionPane.CLOSED_OPTION) 80 81 return; 81 if (result == 082 if (result == 0) 82 83 calibration = selection; 83 84 } … … 88 89 LatLon center = ImageryOffsetTools.getMapCenter(); 89 90 ImageryOffsetBase offsetObj; 90 if (calibration == null91 if (calibration == null) { 91 92 // register imagery offset 92 if (Math.abs(layer.getDx()) < 1e-8 && Math.abs(layer.getDy()) < 1e-893 if (JOptionPane.showConfirmDialog(Main.parent,93 if (Math.abs(layer.getDx()) < 1e-8 && Math.abs(layer.getDy()) < 1e-8) { 94 if (JOptionPane.showConfirmDialog(Main.parent, 94 95 tr("The topmost imagery layer has no offset. Are you sure you want to upload this?"), 95 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION 96 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) 96 97 return; 97 98 } … … 107 108 } 108 109 String description = queryDescription(message); 109 if (description == null110 if (description == null) 110 111 return; 111 112 offsetObj.setBasicInfo(center, userName, null, null); … … 117 118 offsetObj.putServerParams(params); 118 119 StringBuilder query = null; 119 for (String key : params.keySet()120 if (query == null120 for (String key : params.keySet()) { 121 if (query == null) { 121 122 query = new StringBuilder("store?"); 122 123 } else { … … 126 127 } 127 128 Main.worker.submit(new SimpleOffsetQueryTask(query.toString(), tr("Uploading a new offset..."))); 128 } catch (UnsupportedEncodingException ex129 // WTF129 } catch (UnsupportedEncodingException ex) { 130 Main.error(ex); 130 131 } 131 132 } … … 137 138 * @return Either null or a string 3 to 200 letters long. 138 139 */ 139 public static String queryDescription( 140 public static String queryDescription(Object message) { 140 141 String reason = null; 141 142 boolean iterated = false; 142 143 boolean ok = false; 143 while( !ok ) { 144 Object result = JOptionPane.showInputDialog(Main.parent, message, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE, null, null, reason); 145 if( result == null || result.toString().length() == 0 ) { 144 while (!ok) { 145 Object result = JOptionPane.showInputDialog(Main.parent, message, 146 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE, null, null, reason); 147 if (result == null || result.toString().length() == 0) { 146 148 return null; 147 149 } 148 150 reason = result.toString(); 149 if (reason.length() < 3 || reason.length() > 200150 if (!iterated151 if (reason.length() < 3 || reason.length() > 200) { 152 if (!iterated) { 151 153 message = message + "\n" + tr("This string should be 3 to 200 letters long."); 152 154 iterated = true; … … 165 167 protected void updateEnabledState() { 166 168 boolean state = true; 167 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()169 if (Main.map == null || Main.map.mapView == null || !Main.map.isVisible()) 168 170 state = false; 169 if (ImageryOffsetTools.getTopImageryLayer() == null171 if (ImageryOffsetTools.getTopImageryLayer() == null) 170 172 state = false; 171 173 setEnabled(state);
Note:
See TracChangeset
for help on using the changeset viewer.