Changeset 23961 in osm


Ignore:
Timestamp:
2010-10-31T14:56:39+01:00 (14 years ago)
Author:
oliverw
Message:
  • Run the guess action as PleaseWaitRunnable/show progress
  • AddressEditTableModel: Update only row on entity change event
  • INodeEntity.java: Added getCoor method
Location:
applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressEditContainer.java

    r23947 r23961  
    6363        private List<AddressNode> unresolvedAddresses = new ArrayList<AddressNode>(100);
    6464        private List<AddressNode> incompleteAddresses = new ArrayList<AddressNode>(100);
     65       
     66        private HashMap<String, StreetNode> shadowStreetDict = new HashMap<String, StreetNode>(100);
     67        private List<AddressNode> shadowUnresolvedAddresses = new ArrayList<AddressNode>(100);
     68        private List<AddressNode> shadowIncompleteAddresses = new ArrayList<AddressNode>(100);
     69       
    6570        private HashMap<String, AddressNode> addressCache = new HashMap<String, AddressNode>();
    6671        private HashSet<Node> visitedNodes = new HashSet<Node>();
     
    145150                        if (!assignAddressToStreet(aNode)) {
    146151                                // Assignment failed: Street is not known (yet) -> add to 'unresolved' list
    147                                 unresolvedAddresses.add(aNode);
     152                                shadowUnresolvedAddresses.add(aNode);
    148153                        }
    149154
    150155                        if (!aNode.isComplete()) {
    151                                 incompleteAddresses.add(aNode);
     156                                shadowIncompleteAddresses.add(aNode);
    152157                        }
    153158                } else {
     
    181186        }
    182187
     188        /**
     189         * Creates the node from an OSM way instance.
     190         *
     191         * @param w the w
     192         */
    183193        private void createNodeFromWay(Way w) {
    184194                StreetSegmentNode newSegment = NodeFactory.createNodeFromWay(w);
     
    189199                       
    190200                        StreetNode sNode = null;
    191                         if (streetDict.containsKey(name)) {
    192                                 sNode = streetDict.get(name);
    193                         } else {
     201                        if (shadowStreetDict.containsKey(name)) { // street exists?
     202                                sNode = shadowStreetDict.get(name);
     203                        } else { // new street name -> add to dict
    194204                                sNode = new StreetNode(w);
    195                                 streetDict.put(name, sNode);
     205                                shadowStreetDict.put(name, sNode);
    196206                        }
    197207                       
     
    242252        }
    243253       
     254        /**
     255         * Gets the unresolved (addresses without valid street name) addresses.
     256         *
     257         * @return the unresolved addresses
     258         */
    244259        public List<AddressNode> getUnresolvedAddresses() {
    245260                return unresolvedAddresses;
    246261        }
    247262
     263        /**
     264         * Gets the list with incomplete addresses.
     265         *
     266         * @return the incomplete addresses
     267         */
    248268        public List<AddressNode> getIncompleteAddresses() {
    249269                return incompleteAddresses;
    250270        }
    251271
    252         public List<StreetNode> getStreetList() {
    253                
     272        /**
     273         * Gets the street list.
     274         *
     275         * @return the street list
     276         */
     277        public List<StreetNode> getStreetList() {               
    254278                ArrayList<StreetNode> sortedList = new ArrayList<StreetNode>(streetDict.values());
    255279                Collections.sort(sortedList);
     
    257281        }
    258282
     283        /**
     284         * Gets all addresses without valid street.
     285         * @return
     286         */
    259287        public List<AddressNode> getUnresolvedItems() {
    260288                return unresolvedAddresses;
    261289        }
    262290
     291        /**
     292         * Gets the tags used in the data layer.
     293         * @return
     294         */
    263295        public HashSet<String> getTags() {
    264296                return tags;
     
    363395                if (osmData == null || osmData.isEmpty())
    364396                        return;
    365                
    366                 clearData();
    367                 for (OsmPrimitive osmPrimitive : osmData) {
    368                         osmPrimitive.visit(this);
    369                 }
    370                
    371                 resolveAddresses();
    372                
    373                 Collections.sort(incompleteAddresses);
    374                 Collections.sort(unresolvedAddresses);
    375                
    376                 fireContainerChanged();
     397
     398                synchronized (this) {
     399                        clearData();
     400                        for (OsmPrimitive osmPrimitive : osmData) {
     401                                osmPrimitive.visit(this);
     402                        }
     403
     404                        resolveAddresses();
     405                        // sort lists
     406                        Collections.sort(shadowIncompleteAddresses);
     407                        Collections.sort(shadowIncompleteAddresses);
     408
     409                        // put results from shadow copy into real lists
     410                        incompleteAddresses = new ArrayList<AddressNode>(shadowIncompleteAddresses);
     411                        unresolvedAddresses = new ArrayList<AddressNode>(shadowUnresolvedAddresses);
     412                        streetDict = new HashMap<String, StreetNode>(shadowStreetDict);
     413                        // remove temp data
     414                        shadowStreetDict.clear();
     415                        shadowUnresolvedAddresses.clear();
     416                        shadowIncompleteAddresses.clear();
     417                        // update clients
     418                        fireContainerChanged();
     419                }
    377420        }
    378421       
    379422        public void clearData() {
    380                 streetDict.clear();
    381                 unresolvedAddresses.clear();
    382                 incompleteAddresses.clear();
     423                shadowStreetDict.clear();
     424                shadowUnresolvedAddresses.clear();
     425                shadowIncompleteAddresses.clear();
    383426                visitedNodes.clear();
    384427                visitedWays.clear();
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressFinderThread.java

    r23949 r23961  
    1414package org.openstreetmap.josm.plugins.fixAddresses;
    1515
     16import static org.openstreetmap.josm.tools.I18n.tr;
     17
     18import java.io.IOException;
     19import java.util.ArrayList;
    1620import java.util.ConcurrentModificationException;
     21import java.util.List;
    1722
    1823import org.openstreetmap.josm.Main;
     
    2429import org.openstreetmap.josm.data.osm.Way;
    2530import org.openstreetmap.josm.data.osm.visitor.Visitor;
     31import org.openstreetmap.josm.gui.PleaseWaitRunnable;
     32import org.openstreetmap.josm.io.OsmTransferException;
     33import org.xml.sax.SAXException;
    2634
    27 public class AddressFinderThread implements Runnable, Visitor {
    28         private AddressNode addressNode;
     35public class AddressFinderThread extends PleaseWaitRunnable implements Visitor {
     36        private AddressEditContainer container;
    2937        private double minDist;
    3038        private Node nearestNode;
    31         private Node osmAddressNode;
     39        private AddressNode curAddressNode;
    3240        private boolean isRunning = false;
    3341        private String nearestName = null;
    3442        private String currentName = null;
     43        private boolean cancelled;
    3544       
    3645        /**
    37          * @param addressNode
     46         * @param AddressEditContainer
    3847         */
    39         public AddressFinderThread(AddressNode addressNode) {
    40                 super();
    41                 setAddressNode(addressNode);           
     48        public AddressFinderThread(AddressEditContainer AddressEditContainer, String title) {
     49                super(title != null ? title : tr("Searching"));
     50                setAddressEditContainer(AddressEditContainer);         
    4251        }
    4352
    44         public AddressFinderThread() {
    45                 this(null);
    46         }
    47 
    48         public void setAddressNode(AddressNode addressNode) {
     53        public void setAddressEditContainer(AddressEditContainer AddressEditContainer) {
    4954                if (isRunning) {
    5055                        throw new ConcurrentModificationException();
    5156                }
    52                 this.addressNode = addressNode;
    53                 if (addressNode != null && addressNode.getOsmObject() instanceof Node) {
    54                         osmAddressNode = (Node) addressNode.getOsmObject();
    55                 }
     57                this.container = AddressEditContainer;         
    5658        }
    5759
    58         public AddressNode getAddressNode() {
    59                 return addressNode;
     60        public AddressEditContainer getAddressEditContainer() {
     61                return container;
    6062        }
    61        
    62         public double getMinDist() {
    63                 return minDist;
    64         }
    65 
    66         public Node getNearestNode() {
    67                 return nearestNode;
    68         }
    69 
    70         /**
    71          * @return the nearestName
    72          */
    73         public String getGuessedName() {
    74                 return nearestName;
    75         }
    76 
    7763        /**
    7864         * @return the isRunning
     
    8268        }
    8369
    84         @Override
    85         public void run() {
    86                 if (Main.main.getCurrentDataSet() == null || osmAddressNode == null) return;
    87 
    88                 isRunning = true;
    89                 synchronized(this) {                   
    90                         try {
    91                                 minDist = Double.MAX_VALUE;
    92                                 for (OsmPrimitive osmPrimitive : Main.main.getCurrentDataSet().getWays()) {
    93                                         osmPrimitive.visit(this);
    94                                 }
    95                                
    96                                 if (nearestName != null) {
    97                                         addressNode.setGuessedStreetName(nearestName);
    98                                 }
    99                         } finally {
    100                                 isRunning = false;
    101                         }
    102                 }
    103         }
    104 
    105 
     70        /* (non-Javadoc)
     71         * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Node)
     72         */
    10673        @Override
    10774        public void visit(Node n) {
    10875                if (n == null) return;
     76                if (curAddressNode == null) return;
    10977
    11078                // If the coordinates are null, we are screwed anyway
    111                 double dist = osmAddressNode.getCoor().greatCircleDistance(n.getCoor());
     79                LatLon ll = curAddressNode.getCoor();
     80                if (ll == null) return;
     81               
     82                double dist = ll.greatCircleDistance(n.getCoor());
    11283               
    11384                if (dist < minDist) {
     
    11889        }
    11990
    120 
     91        /* (non-Javadoc)
     92         * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Way)
     93         */
    12194        @Override
    12295        public void visit(Way w) {
     
    128101                for (Node node : w.getNodes()) {
    129102                        visit(node);
    130                 }
    131                
     103                }               
    132104        }
    133105
    134 
     106        /* (non-Javadoc)
     107         * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Relation)
     108         */
    135109        @Override
    136110        public void visit(Relation e) {
    137                 // TODO Auto-generated method stub
    138                
     111                // nothing to do yet           
    139112        }
    140113
    141 
     114        /* (non-Javadoc)
     115         * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Changeset)
     116         */
    142117        @Override
    143118        public void visit(Changeset cs) {
    144                 // TODO Auto-generated method stub
    145                
     119                // nothing to do yet
    146120        }
    147121
     122        /* (non-Javadoc)
     123         * @see org.openstreetmap.josm.gui.PleaseWaitRunnable#cancel()
     124         */
     125        @Override
     126        protected void cancel() {
     127                cancelled = true;               
     128        }
     129
     130        /* (non-Javadoc)
     131         * @see org.openstreetmap.josm.gui.PleaseWaitRunnable#finish()
     132         */
     133        @Override
     134        protected void finish() {
     135                // nothing to do yet
     136        }
     137
     138        /* (non-Javadoc)
     139         * @see org.openstreetmap.josm.gui.PleaseWaitRunnable#realRun()
     140         */
     141        @Override
     142        protected void realRun() throws SAXException, IOException,
     143                        OsmTransferException {
     144                if (Main.main.getCurrentDataSet() == null || container == null) return;
     145
     146                isRunning = true;
     147                cancelled = false;
     148               
     149                progressMonitor.subTask(tr("Searching") + "...");
     150               
     151                try {
     152                        progressMonitor.setTicksCount(container.getNumberOfUnresolvedAddresses());
     153                       
     154                        List<AddressNode> shadowCopy = new ArrayList<AddressNode>(container.getUnresolvedAddresses());
     155                        for (AddressNode aNode : shadowCopy) {                                 
     156                                minDist = Double.MAX_VALUE;
     157                                curAddressNode = aNode;
     158                               
     159                                // check for cancel
     160                                if (cancelled) {
     161                                        break;
     162                                }
     163
     164                                // visit osm data
     165                                for (OsmPrimitive osmPrimitive : Main.main.getCurrentDataSet().getWays()) {
     166                                        if (cancelled) {
     167                                                break;
     168                                        }
     169                                        osmPrimitive.visit(this);
     170
     171                                }
     172                               
     173                                // we found something
     174                                if (nearestName != null) {
     175                                        progressMonitor.subTask(String.format("%s: %s (%4.1f m)", tr("Guess"), nearestName, minDist));
     176                                        aNode.setGuessedStreetName(nearestName);
     177                                        nearestName = null;
     178                                }
     179                                // report progress
     180                                progressMonitor.worked(1);                             
     181                        }
     182                        // request container update
     183                        container.invalidate();
     184                } finally {
     185                        isRunning = false;
     186                }
     187        }
    148188}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressNode.java

    r23957 r23961  
    7575        public void setGuessedStreetName(String guessedStreetName) {
    7676                this.guessedStreetName = guessedStreetName;
    77                 fireEntityChanged(this);
     77                //fireEntityChanged(this);
    7878        }
    7979       
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/INodeEntity.java

    r23933 r23961  
    1616import java.util.List;
    1717
     18import org.openstreetmap.josm.data.coor.LatLon;
    1819import org.openstreetmap.josm.data.osm.OsmPrimitive;
     20
     21/**
     22 * Base interface for all node entities. A node entity is a lightweight wrapper
     23 * around OSM objects in order to ease up some tasks like tag handling.
     24 * @author Oliver Wieland <oliver.wieland@online.de>
     25 *
     26 */
    1927
    2028public interface INodeEntity extends Comparable<INodeEntity> {
     
    4250         */
    4351        public List<INodeEntity> getChildren();
     52       
     53        /**
     54         * Gets the coordinate of the node. If the the underlying object is a
     55         * node, it just returns the node coordinate. For ways and areas, this
     56         * method returns the coordinate of the center (balance point).
     57         * @return
     58         */
     59        public LatLon getCoor();
    4460}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/NodeEntityBase.java

    r23933 r23961  
    2121import org.openstreetmap.josm.Main;
    2222import org.openstreetmap.josm.command.ChangeCommand;
     23import org.openstreetmap.josm.data.coor.LatLon;
     24import org.openstreetmap.josm.data.osm.BBox;
    2325import org.openstreetmap.josm.data.osm.Node;
    2426import org.openstreetmap.josm.data.osm.OsmPrimitive;
     27import org.openstreetmap.josm.data.osm.Way;
    2528
    2629public class NodeEntityBase implements INodeEntity, Comparable<INodeEntity> {
     
    126129        }
    127130
     131        /* (non-Javadoc)
     132         * @see java.lang.Comparable#compareTo(java.lang.Object)
     133         */
    128134        @Override
    129135        public int compareTo(INodeEntity o) {
     
    132138        }
    133139
    134        
     140        /* (non-Javadoc)
     141         * @see org.openstreetmap.josm.plugins.fixAddresses.INodeEntity#getCoor()
     142         */
     143        @Override
     144        public LatLon getCoor() {
     145                OsmPrimitive osm = getOsmObject();
     146                if (osm == null) return null;
     147               
     148                if (osm instanceof Node) {
     149                        return ((Node)osm).getCoor();
     150                // way: return center
     151                } else if (osm instanceof Way) {
     152                        Way w = (Way) osm;
     153                        BBox bb = w.getBBox();
     154                        return bb.getBottomRight().getCenter(bb.getTopLeft());
     155                }
     156                // relations??
     157                return null;
     158        }
    135159}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/AddressEditTableModel.java

    r23933 r23961  
    3636        @Override
    3737        public void containerChanged(AddressEditContainer container) {
    38                 fireTableDataChanged();
     38                fireTableDataChanged(); // update model
    3939        }
    4040
    4141        @Override
    4242        public void entityChanged(INodeEntity entity) {
    43                 fireTableDataChanged();
     43                int row = getRowOfEntity(entity);
     44                if (row != -1) { // valid row? -> update model
     45                        System.out.println("Update row " + row);
     46                        fireTableRowsUpdated(row, row);
     47                } // else we don't do anything
    4448        }
    4549       
     
    5054         */
    5155        public abstract INodeEntity getEntityOfRow(int row);
     56       
     57        /**
     58         * Gets the row for the given node entity or -1; if the model does not contain the entity.
     59         * @param entity The entity to get the row for.
     60         * @return
     61         */
     62        public abstract int getRowOfEntity(INodeEntity entity);
    5263}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/GuessAddressDataAction.java

    r23944 r23961  
    1616import static org.openstreetmap.josm.tools.I18n.tr;
    1717
    18 import java.util.ArrayList;
    1918import java.util.List;
    2019
     20import org.openstreetmap.josm.Main;
    2121import org.openstreetmap.josm.plugins.fixAddresses.AddressEditContainer;
    2222import org.openstreetmap.josm.plugins.fixAddresses.AddressFinderThread;
     
    4747        }
    4848
     49        /* (non-Javadoc)
     50         * @see org.openstreetmap.josm.plugins.fixAddresses.gui.AbstractAddressEditAction#updateEnabledState(org.openstreetmap.josm.plugins.fixAddresses.AddressEditContainer)
     51         */
    4952        @Override
    5053        protected void updateEnabledState(AddressEditContainer container) {
     
    5255        }
    5356
     57        /* (non-Javadoc)
     58         * @see org.openstreetmap.josm.plugins.fixAddresses.gui.AbstractAddressEditAction#addressEditActionPerformed(org.openstreetmap.josm.plugins.fixAddresses.AddressEditContainer)
     59         */
    5460        @Override
    5561        public void addressEditActionPerformed(AddressEditContainer container) {
     
    6066        }
    6167
     68        /* (non-Javadoc)
     69         * @see org.openstreetmap.josm.plugins.fixAddresses.gui.AbstractAddressEditAction#addressEditActionPerformed(org.openstreetmap.josm.plugins.fixAddresses.gui.AddressEditSelectionEvent)
     70         */
    6271        @Override
    6372        public void addressEditActionPerformed(AddressEditSelectionEvent ev) {
     
    6574               
    6675                // guess tags for selected addresses only
    67                 internalGuessAddresses(ev.getSelectedUnresolvedAddresses());
     76                internalGuessAddresses(ev.getSelectedUnresolvedAddresses());           
    6877        }
    6978       
     
    7382         */
    7483        private void internalGuessAddresses(List<AddressNode> nodes) {
    75                 // setup thread pool
    76                 for (int i = 0; i < threads.length; i++) {
    77                         threads[i] = new AddressFinderThread();
    78                 }
    79                
    80                 // work on a shadowed copy
    81                 List<AddressNode> addrNodes = new ArrayList<AddressNode>(nodes);
    82                 for (AddressNode aNode : addrNodes) {
    83                         if (aNode.hasStreetName()) continue;
    84                        
    85                         while(!scheduleNode(aNode)) {
    86                                 try {
    87                                         Thread.sleep(100);
    88                                 } catch (InterruptedException e) {
    89                                         return;
    90                                 }
    91                         }
    92                 }
    93                 container.containerChanged(container);
     84                Main.worker.submit(new AddressFinderThread(container, tr("Guess street names")));               
    9485        }
    95 
    96         private boolean scheduleNode(AddressNode aNode) {
    97                 for (int i = 0; i < threads.length; i++) {
    98                         if (!threads[i].isRunning()) {
    99                                 threads[i].setAddressNode(aNode);
    100                                 threads[i].run();
    101                                 return true;
    102                         }
    103                 }
    104                 return false;
    105         }
    106 
    10786}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/IncompleteAddressesTableModel.java

    r23933 r23961  
    105105                        return null;
    106106                }
    107                 if (row < 0 || row > addressContainer.getNumberOfIncompleteAddresses()) {
     107                if (row < 0 || row >= addressContainer.getNumberOfIncompleteAddresses()) {
    108108                        return null;
    109109                }
    110110                return addressContainer.getIncompleteAddresses().get(row);
    111111        }
     112
     113        @Override
     114        public int getRowOfEntity(INodeEntity entity) {
     115                if (addressContainer == null || addressContainer.getIncompleteAddresses() == null) {
     116                        return -1;
     117                }
     118               
     119                return addressContainer.getIncompleteAddresses().indexOf(entity);
     120        }
    112121}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/StreetTableModel.java

    r23933 r23961  
    111111                        return null;
    112112                }
    113                 if (row < 0 || row > addressContainer.getNumberOfStreets()) {
     113                if (row < 0 || row >= addressContainer.getNumberOfStreets()) {
    114114                        return null;
    115115                }
    116116                return addressContainer.getStreetList().get(row);       
    117117        }
     118       
     119        @Override
     120        public int getRowOfEntity(INodeEntity entity) {
     121                if (addressContainer == null || addressContainer.getStreetList() == null) {
     122                        return -1;
     123                }
     124               
     125                return addressContainer.getStreetList().indexOf(entity);
     126        }
    118127}
  • applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/UnresolvedAddressesTableModel.java

    r23944 r23961  
    147147                        return null;
    148148                }
    149                 if (row < 0 || row > addressContainer.getNumberOfUnresolvedAddresses()) {
     149                if (row < 0 || row >= addressContainer.getNumberOfUnresolvedAddresses()) {
    150150                        return null;
    151151                }
    152152                return addressContainer.getUnresolvedAddresses().get(row);     
    153153        }
     154       
     155        @Override
     156        public int getRowOfEntity(INodeEntity entity) {
     157                if (addressContainer == null || addressContainer.getUnresolvedAddresses() == null) {
     158                        return -1;
     159                }
     160               
     161                return addressContainer.getUnresolvedAddresses().indexOf(entity);
     162        }
    154163}
Note: See TracChangeset for help on using the changeset viewer.