Changeset 29744 in osm for applications/editors


Ignore:
Timestamp:
2013-07-06T15:06:23+02:00 (11 years ago)
Author:
donvip
Message:

[josm_download_along] code cleanup/refactoring in order to fix plugin tickets

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  
    11<?xml version="1.0" encoding="utf-8"?>
    2 <!--
    3 ** This is a template build file for a JOSM  plugin.
    4 **
    5 ** Maintaining versions
    6 ** ====================
    7 ** see README.template
    8 **
    9 ** Usage
    10 ** =====
    11 ** To build it run
    12 **
    13 **    > ant  dist
    14 **
    15 ** To install the generated plugin locally (in you default plugin directory) run
    16 **
    17 **    > ant  install
    18 **
    19 ** The generated plugin jar is not automatically available in JOSMs plugin configuration
    20 ** 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 other
    23 ** JOSM users:
    24 **    set the properties commit.message and plugin.main.version
    25 ** and run
    26 **    > ant  publish
    27 **
    28 **
    29 -->
    302<project name="download_along" default="dist" basedir=".">
    313    <!-- enter the SVN commit message -->
     
    335    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    346    <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
    5110    -->
    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
    24023</project>
  • applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along/DownloadAlong.java

    r29729 r29744  
    11package org.openstreetmap.josm.plugin.download_along;
    22
    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 
    213import 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;
    284import org.openstreetmap.josm.gui.MainMenu;
    29 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
    305import org.openstreetmap.josm.plugins.Plugin;
    316import org.openstreetmap.josm.plugins.PluginInformation;
    32 import org.openstreetmap.josm.tools.GBC;
    33 import org.openstreetmap.josm.tools.Shortcut;
    347
    358public class DownloadAlong extends Plugin {
    36   private static final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "downloadAlong.downloadAlongTrack.distance";
    37   private static 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";
    3811
    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        }
    29316}
Note: See TracChangeset for help on using the changeset viewer.