Changeset 29744 in osm for applications/editors
- Timestamp:
- 2013-07-06T15:06:23+02:00 (11 years ago)
- Location:
- applications/editors/josm/plugins/download_along
- Files:
-
- 7 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/download_along/build.xml
r29435 r29744 1 1 <?xml version="1.0" encoding="utf-8"?> 2 <!--3 ** This is a template build file for a JOSM plugin.4 **5 ** Maintaining versions6 ** ====================7 ** see README.template8 **9 ** Usage10 ** =====11 ** To build it run12 **13 ** > ant dist14 **15 ** To install the generated plugin locally (in you default plugin directory) run16 **17 ** > ant install18 **19 ** The generated plugin jar is not automatically available in JOSMs plugin configuration20 ** dialog. You have to check it in first.21 **22 ** Use the ant target 'publish' to check in the plugin and make it available to other23 ** JOSM users:24 ** set the properties commit.message and plugin.main.version25 ** and run26 ** > ant publish27 **28 **29 -->30 2 <project name="download_along" default="dist" basedir="."> 31 3 <!-- enter the SVN commit message --> … … 33 5 <!-- enter the *lowest* JOSM version this plugin is currently compatible with --> 34 6 <property name="plugin.main.version" value="4980"/> 35 <!-- 36 ************************************************ 37 ** should not be necessary to change the following properties 38 --> 39 <property name="josm" location="../../core/dist/josm-custom.jar"/> 40 <property name="plugin.build.dir" value="build"/> 41 <property name="plugin.src.dir" value="src"/> 42 <!-- this is the directory where the plugin jar is copied to --> 43 <property name="plugin.dist.dir" value="../../dist"/> 44 <property name="ant.build.javac.target" value="1.5"/> 45 <property name="plugin.dist.dir" value="../../dist"/> 46 <property name="plugin.jar" value="${plugin.dist.dir}/${ant.project.name}.jar"/> 47 <!-- 48 ********************************************************** 49 ** init - initializes the build 50 ********************************************************** 7 8 <!-- Configure these properties (replace "..." accordingly). 9 See http://josm.openstreetmap.de/wiki/DevelopersGuide/DevelopingPlugins 51 10 --> 52 <target name="init"> 53 <mkdir dir="${plugin.build.dir}"/> 54 </target> 55 <!-- 56 ********************************************************** 57 ** compile - complies the source tree 58 ********************************************************** 59 --> 60 <target name="compile" depends="init"> 61 <echo message="compiling sources for ${plugin.jar} ... "/> 62 <javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}"> 63 <compilerarg value="-Xlint:deprecation"/> 64 <compilerarg value="-Xlint:unchecked"/> 65 </javac> 66 </target> 67 <!-- 68 ********************************************************** 69 ** dist - creates the plugin jar 70 ********************************************************** 71 --> 72 <target name="dist" depends="compile,revision"> 73 <echo message="creating ${plugin.jar.name} ... "/> 74 <copy todir="${plugin.build.dir}/images"> 75 <fileset dir="images"/> 76 </copy> 77 <copy todir="${plugin.build.dir}/data"> 78 <fileset dir="data"/> 79 </copy> 80 <copy todir="${plugin.build.dir}"> 81 <fileset dir="."> 82 <include name="README"/> 83 <include name="LICENSE"/> 84 </fileset> 85 </copy> 86 <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}"> 87 <!-- 88 ************************************************ 89 ** configure these properties. Most of them will be copied to the plugins 90 ** manifest file. Property values will also show up in the list available 91 ** plugins: http://josm.openstreetmap.de/wiki/Plugins. 92 ** 93 ************************************************ 94 --> 95 <manifest> 96 <attribute name="Author" value="Nakor"/> 97 <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugin.download_along.DownloadAlong"/> 98 <attribute name="Plugin-Date" value="${version.entry.commit.date}"/> 99 <attribute name="Plugin-Description" value="Downloads OSM data along a way"/> 100 <attribute name="Plugin-Icon" value="images/download_along.png"/> 101 <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/DownloadAlong"/> 102 <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/> 103 <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/> 104 </manifest> 105 </jar> 106 </target> 107 <!-- 108 ********************************************************** 109 ** revision - extracts the current revision number for the 110 ** file build.number and stores it in the XML property 111 ** version.* 112 ********************************************************** 113 --> 114 <target name="revision"> 115 <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false"> 116 <env key="LANG" value="C"/> 117 <arg value="info"/> 118 <arg value="--xml"/> 119 <arg value="."/> 120 </exec> 121 <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/> 122 <delete file="REVISION"/> 123 </target> 124 <!-- 125 ********************************************************** 126 ** clean - clean up the build environment 127 ********************************************************** 128 --> 129 <target name="clean"> 130 <delete dir="${plugin.build.dir}"/> 131 <delete file="${plugin.jar}"/> 132 </target> 133 <!-- 134 ********************************************************** 135 ** install - install the plugin in your local JOSM installation 136 ********************************************************** 137 --> 138 <target name="install" depends="dist"> 139 <property environment="env"/> 140 <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins"> 141 <and> 142 <os family="windows"/> 143 </and> 144 </condition> 145 <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/> 146 </target> 147 <!-- 148 ************************** Publishing the plugin *********************************** 149 --> 150 <!-- 151 ** extracts the JOSM release for the JOSM version in ../core and saves it in the 152 ** property ${coreversion.info.entry.revision} 153 ** 154 --> 155 <target name="core-info"> 156 <exec append="false" output="core.info.xml" executable="svn" failifexecutionfails="false"> 157 <env key="LANG" value="C"/> 158 <arg value="info"/> 159 <arg value="--xml"/> 160 <arg value="../../core"/> 161 </exec> 162 <xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true"/> 163 <echo>Building against core revision ${coreversion.info.entry.revision}.</echo> 164 <echo>Plugin-Mainversion is set to ${plugin.main.version}.</echo> 165 <delete file="core.info.xml"/> 166 </target> 167 <!-- 168 ** commits the source tree for this plugin 169 --> 170 <target name="commit-current"> 171 <echo>Commiting the plugin source with message '${commit.message}' ...</echo> 172 <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false"> 173 <env key="LANG" value="C"/> 174 <arg value="commit"/> 175 <arg value="-m '${commit.message}'"/> 176 <arg value="."/> 177 </exec> 178 </target> 179 <!-- 180 ** updates (svn up) the source tree for this plugin 181 --> 182 <target name="update-current"> 183 <echo>Updating plugin source ...</echo> 184 <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false"> 185 <env key="LANG" value="C"/> 186 <arg value="up"/> 187 <arg value="."/> 188 </exec> 189 <echo>Updating ${plugin.jar} ...</echo> 190 <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false"> 191 <env key="LANG" value="C"/> 192 <arg value="up"/> 193 <arg value="../dist/${plugin.jar}"/> 194 </exec> 195 </target> 196 <!-- 197 ** commits the plugin.jar 198 --> 199 <target name="commit-dist"> 200 <echo> 201 ***** Properties of published ${plugin.jar} ***** 202 Commit message : '${commit.message}' 203 Plugin-Mainversion: ${plugin.main.version} 204 JOSM build version: ${coreversion.info.entry.revision} 205 Plugin-Version : ${version.entry.commit.revision} 206 ***** / Properties of published ${plugin.jar} ***** 207 208 Now commiting ${plugin.jar} ... 209 </echo> 210 <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false"> 211 <env key="LANG" value="C"/> 212 <arg value="-m '${commit.message}'"/> 213 <arg value="commit"/> 214 <arg value="${plugin.jar}"/> 215 </exec> 216 </target> 217 <!-- ** make sure svn is present as a command line tool ** --> 218 <target name="ensure-svn-present"> 219 <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code"> 220 <env key="LANG" value="C"/> 221 <arg value="--version"/> 222 </exec> 223 <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system."> 224 <!-- return code not set at all? Most likely svn isn't installed --> 225 <condition> 226 <not> 227 <isset property="svn.exit.code"/> 228 </not> 229 </condition> 230 </fail> 231 <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system."> 232 <!-- error code from SVN? Most likely svn is not what we are looking on this system --> 233 <condition> 234 <isfailure code="${svn.exit.code}"/> 235 </condition> 236 </fail> 237 </target> 238 <target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist"> 239 </target> 11 <property name="plugin.author" value="Nakor"/> 12 <property name="plugin.class" value="org.openstreetmap.josm.plugin.download_along.DownloadAlong"/> 13 <property name="plugin.description" value="Downloads OSM data along a way"/> 14 <property name="plugin.icon" value="images/download_along.png"/> 15 <property name="plugin.link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/DownloadAlong"/> 16 <!--<property name="plugin.early" value="..."/>--> 17 <!--<property name="plugin.requires" value="..."/>--> 18 <!--<property name="plugin.stage" value="..."/>--> 19 20 <!-- ** include targets that all plugins have in common ** --> 21 <import file="../build-common.xml"/> 22 240 23 </project> -
applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along/DownloadAlong.java
r29729 r29744 1 1 package org.openstreetmap.josm.plugin.download_along; 2 2 3 import java.awt.GridBagLayout;4 import java.awt.event.ActionEvent;5 import java.awt.event.KeyEvent;6 import java.awt.geom.Area;7 import java.awt.geom.Rectangle2D;8 import java.util.Collection;9 import java.util.ArrayList;10 import java.util.List;11 import java.util.concurrent.Future;12 13 import javax.swing.JLabel;14 import javax.swing.JList;15 import javax.swing.JMenuItem;16 import javax.swing.JOptionPane;17 import javax.swing.JPanel;18 19 import static org.openstreetmap.josm.tools.I18n.tr;20 21 3 import org.openstreetmap.josm.Main; 22 import org.openstreetmap.josm.actions.JosmAction;23 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList;24 import org.openstreetmap.josm.data.coor.LatLon;25 import org.openstreetmap.josm.data.osm.Node;26 import org.openstreetmap.josm.data.osm.OsmPrimitive;27 import org.openstreetmap.josm.data.osm.Way;28 4 import org.openstreetmap.josm.gui.MainMenu; 29 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;30 5 import org.openstreetmap.josm.plugins.Plugin; 31 6 import org.openstreetmap.josm.plugins.PluginInformation; 32 import org.openstreetmap.josm.tools.GBC;33 import org.openstreetmap.josm.tools.Shortcut;34 7 35 8 public class DownloadAlong extends Plugin { 36 privatestatic final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "downloadAlong.downloadAlongTrack.distance";37 privatestatic final String PREF_DOWNLOAD_ALONG_TRACK_AREA = "downloadAlong.downloadAlongTrack.area";9 static final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "downloadAlong.downloadAlongTrack.distance"; 10 static final String PREF_DOWNLOAD_ALONG_TRACK_AREA = "downloadAlong.downloadAlongTrack.area"; 38 11 39 JMenuItem DownloadAlong; 40 41 public DownloadAlong(PluginInformation info) { 42 super(info); 43 DownloadAlong = MainMenu.add(Main.main.menu.toolsMenu, 44 new DownloadAlongAction()); 45 46 } 47 48 private static class DownloadAlongAction extends JosmAction { 49 /** 50 * 51 */ 52 private static final long serialVersionUID = 1L; 53 54 public DownloadAlongAction() { 55 super(tr("Download along..."), "download_along", 56 tr("Download OSM data along the selected ways."), 57 Shortcut.registerShortcut("tools:download_along", tr("Tool: {0}", 58 tr("Download Along")), KeyEvent.VK_D, Shortcut.ALT_SHIFT), true); 59 } 60 61 public void actionPerformed(ActionEvent e) { 62 Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet() 63 .getSelected(); 64 65 int ways = 0; 66 for (OsmPrimitive prim : selection) { 67 if (prim instanceof Way) 68 ways++; 69 } 70 71 if (ways < 1) { 72 JOptionPane.showMessageDialog(Main.parent, 73 tr("Please select 1 or more ways to download along")); 74 return; 75 } 76 77 JPanel msg = new JPanel(new GridBagLayout()); 78 Integer dist[] = { 5000, 500, 50 }; 79 Integer area[] = { 20, 10, 5, 1 }; 80 81 msg.add(new JLabel(tr("Download everything within:")), GBC.eol()); 82 String s[] = new String[dist.length]; 83 for (int i = 0; i < dist.length; ++i) { 84 s[i] = tr("{0} meters", dist[i]); 85 } 86 JList buffer = new JList(s); 87 buffer.setSelectedIndex(Main.pref.getInteger( 88 PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, 0)); 89 msg.add(buffer, GBC.eol()); 90 91 msg.add(new JLabel(tr("Maximum area per request:")), GBC.eol()); 92 s = new String[area.length]; 93 for (int i = 0; i < area.length; ++i) { 94 s[i] = tr("{0} sq km", area[i]); 95 } 96 JList maxRect = new JList(s); 97 maxRect.setSelectedIndex(Main.pref.getInteger( 98 PREF_DOWNLOAD_ALONG_TRACK_AREA, 0)); 99 msg.add(maxRect, GBC.eol()); 100 101 int ret = JOptionPane.showConfirmDialog(Main.parent, msg, 102 tr("Download from OSM along this track"), 103 JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); 104 switch (ret) { 105 case JOptionPane.CANCEL_OPTION: 106 case JOptionPane.CLOSED_OPTION: 107 return; 108 default: 109 // continue 110 } 111 112 Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, buffer 113 .getSelectedIndex()); 114 Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_AREA, maxRect 115 .getSelectedIndex()); 116 117 /* 118 * Find the average latitude for the data we're contemplating, so we can 119 * know how many metres per degree of longitude we have. 120 */ 121 double latsum = 0; 122 int latcnt = 0; 123 124 for (OsmPrimitive prim : selection) { 125 if (prim instanceof Way) { 126 Way way = (Way) prim; 127 for (Node n : way.getNodes()) { 128 latsum += n.getCoor().lat(); 129 latcnt++; 130 } 131 } 132 } 133 134 double avglat = latsum / latcnt; 135 double scale = Math.cos(Math.toRadians(avglat)); 136 137 /* 138 * Compute buffer zone extents and maximum bounding box size. Note that 139 * the maximum we ever offer is a bbox area of 0.002, while the API 140 * theoretically supports 0.25, but as soon as you touch any built-up 141 * area, that kind of bounding box will download forever and then stop 142 * because it has more than 50k nodes. 143 */ 144 Integer i = buffer.getSelectedIndex(); 145 int buffer_dist = dist[i < 0 ? 0 : i]; 146 double buffer_y = buffer_dist / 100000.0; 147 double buffer_x = buffer_y / scale; 148 i = maxRect.getSelectedIndex(); 149 double max_area = area[i < 0 ? 0 : i] / 10000.0 / scale; 150 Area a = new Area(); 151 Rectangle2D r = new Rectangle2D.Double(); 152 153 /* 154 * Collect the combined area of all gpx points plus buffer zones around 155 * them. We ignore points that lie closer to the previous point than the 156 * given buffer size because otherwise this operation takes ages. 157 */ 158 LatLon previous = null; 159 for (OsmPrimitive prim : selection) { 160 Way way = (Way) prim; 161 for (Node p : way.getNodes()) { 162 LatLon c = p.getCoor(); 163 ArrayList<LatLon> intermediateNodes = new ArrayList<LatLon>(); 164 if (previous != null 165 && c.greatCircleDistance(previous) > buffer_dist) { 166 Double d = c.greatCircleDistance(previous) / buffer_dist; 167 int nbNodes = d.intValue(); 168 System.out.println(tr("{0} intermediate nodes to download.", nbNodes)); 169 System.out.println(tr("between {0} {1} and {2} {3}", c.lat(), c.lon(), previous.lat(), previous.lon())); 170 for (i = 1; i < nbNodes; i++) { 171 intermediateNodes.add(new LatLon(previous.lat()+(i * (c.lat() - previous.lat()) 172 / (nbNodes+1)), previous.lon()+(i * (c.lon() - previous.lon()) / (nbNodes+1)))); 173 System.out.println(tr(" adding {0} {1}", previous.lat()+(i * (c.lat() - previous.lat()) 174 / (nbNodes+1)), previous.lon()+(i * (c.lon() - previous.lon()) / (nbNodes+1)))); 175 } 176 } 177 intermediateNodes.add(c); 178 for (LatLon d : intermediateNodes) { 179 if (previous == null 180 || d.greatCircleDistance(previous) > buffer_dist) { 181 // we add a buffer around the point. 182 r.setRect(d.lon() - buffer_x, d.lat() - buffer_y, 2 * buffer_x, 183 2 * buffer_y); 184 a.add(new Area(r)); 185 previous = d; 186 } 187 } 188 previous = c; 189 } 190 } 191 192 /* 193 * Area "a" now contains the hull that we would like to download data for. 194 * however we can only download rectangles, so the following is an attempt 195 * at finding a number of rectangles to download. 196 * 197 * The idea is simply: Start out with the full bounding box. If it is too 198 * large, then split it in half and repeat recursively for each half until 199 * you arrive at something small enough to download. The algorithm is 200 * improved by always using the intersection between the rectangle and the 201 * actual desired area. For example, if you have a track that goes like 202 * this: +----+ | /| | / | | / | |/ | +----+ then we would first look at 203 * downloading the whole rectangle (assume it's too big), after that we 204 * split it in half (upper and lower half), but we donot request the full 205 * upper and lower rectangle, only the part of the upper/lower rectangle 206 * that actually has something in it. 207 */ 208 209 List<Rectangle2D> toDownload = new ArrayList<Rectangle2D>(); 210 211 addToDownload(a, a.getBounds(), toDownload, max_area); 212 213 msg = new JPanel(new GridBagLayout()); 214 215 msg.add(new JLabel(tr("<html>This action will require {0} individual<br>" 216 + "download requests. Do you wish<br>to continue?</html>", toDownload 217 .size())), GBC.eol()); 218 219 if (toDownload.size() > 1) { 220 ret = JOptionPane.showConfirmDialog(Main.parent, msg, 221 tr("Download from OSM along this track"), 222 JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 223 switch (ret) { 224 case JOptionPane.CANCEL_OPTION: 225 case JOptionPane.CLOSED_OPTION: 226 return; 227 default: 228 // continue 229 } 230 } 231 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor( 232 tr("Download data")); 233 final Future<?> future = new DownloadOsmTaskList().download(false, 234 toDownload, monitor); 235 Main.worker.submit(new Runnable() { 236 public void run() { 237 try { 238 future.get(); 239 } catch (Exception e) { 240 e.printStackTrace(); 241 return; 242 } 243 monitor.close(); 244 } 245 }); 246 } 247 248 private static void addToDownload(Area a, Rectangle2D r, 249 Collection<Rectangle2D> results, double max_area) { 250 Area tmp = new Area(r); 251 // intersect with sought-after area 252 tmp.intersect(a); 253 if (tmp.isEmpty()) 254 return; 255 Rectangle2D bounds = tmp.getBounds2D(); 256 if (bounds.getWidth() * bounds.getHeight() > max_area) { 257 // the rectangle gets too large; split it and make recursive call. 258 Rectangle2D r1; 259 Rectangle2D r2; 260 if (bounds.getWidth() > bounds.getHeight()) { 261 // rectangles that are wider than high are split into a left and right 262 // half, 263 r1 = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds 264 .getWidth() / 2, bounds.getHeight()); 265 r2 = new Rectangle2D.Double(bounds.getX() + bounds.getWidth() / 2, 266 bounds.getY(), bounds.getWidth() / 2, bounds.getHeight()); 267 } else { 268 // others into a top and bottom half. 269 r1 = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds 270 .getWidth(), bounds.getHeight() / 2); 271 r2 = new Rectangle2D.Double(bounds.getX(), bounds.getY() 272 + bounds.getHeight() / 2, bounds.getWidth(), 273 bounds.getHeight() / 2); 274 } 275 addToDownload(a, r1, results, max_area); 276 addToDownload(a, r2, results, max_area); 277 } else { 278 results.add(bounds); 279 } 280 } 281 282 @Override 283 protected void updateEnabledState() { 284 setEnabled(getEditLayer() != null); 285 } 286 287 @Override 288 protected void updateEnabledState( 289 Collection<? extends OsmPrimitive> selection) { 290 // do nothing 291 } 292 } 12 public DownloadAlong(PluginInformation info) { 13 super(info); 14 MainMenu.add(Main.main.menu.toolsMenu, new DownloadAlongAction()); 15 } 293 16 }
Note:
See TracChangeset
for help on using the changeset viewer.