Changeset 28036 in osm for applications


Ignore:
Timestamp:
2012-03-11T02:30:20+01:00 (12 years ago)
Author:
joshdoe
Message:

conflation: refactoring

Location:
applications/editors/josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationLayer.java

    r27971 r28036  
    3434    protected ConflationCandidate selectedCandidate = null;
    3535   
    36     public ConflationLayer(DataSet ds, ConflationCandidateList candidates) {
     36    public ConflationLayer(ConflationCandidateList candidates) {
    3737        super(tr("Conflation"));
    3838        MapView.addLayerChangeListener(this);
    3939        this.candidates = candidates;
     40    }
     41   
     42    public ConflationLayer() {
     43        this(null);
    4044    }
    4145
     
    143147    }
    144148
     149    @Override
    145150    public void activeLayerChange(Layer layer, Layer layer1) {
    146151        //TODO: possibly change arrow styling depending on active layer?
    147152    }
    148153
     154    @Override
    149155    public void layerAdded(Layer layer) {
    150156        // shouldn't have to do anything here
    151157    }
    152158
     159    @Override
    153160    public void layerRemoved(Layer layer) {
    154161        //TODO: if ref or non-ref layer removed, remove arrows
     
    164171    }
    165172   
     173    public void setCandidates(ConflationCandidateList candidates) {
     174        this.candidates = candidates;
     175        // TODO: does repaint automatically occur?
     176    }
     177   
    166178    public void setSelectedCandidate(ConflationCandidate c) {
    167179        selectedCandidate = c;
  • applications/editors/josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java

    r28029 r28036  
    33import java.awt.Component;
    44import java.awt.Dialog;
    5 import java.awt.event.ActionEvent;
    6 import java.awt.event.KeyEvent;
    7 import java.util.ArrayList;
     5import java.awt.event.*;
    86import java.util.Arrays;
    97import java.util.Collection;
     
    1614import org.openstreetmap.josm.actions.JosmAction;
    1715import org.openstreetmap.josm.data.SelectionChangedListener;
    18 import org.openstreetmap.josm.data.osm.DataSet;
    1916import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2017import org.openstreetmap.josm.data.osm.event.*;
    2118import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    22 import org.openstreetmap.josm.gui.ExtendedDialog;
    2319import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
    2420import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
     
    4137    MatchTableModel tableModel;
    4238    ConflationCandidateList candidates;
    43     ConflationOptionsDialog optionsDialog;
     39    ConflationSettings settings;
     40    SettingsDialog settingsDialog;
    4441
    4542    public ConflationToggleDialog(String name, String iconName, String tooltip,
     
    5047//        candidates.addConflationListChangedListener(this);
    5148
    52         optionsDialog = new ConflationOptionsDialog();
    53         optionsDialog.setModalityType(Dialog.ModalityType.MODELESS);
     49        settingsDialog = new SettingsDialog();
     50        settingsDialog.setModalityType(Dialog.ModalityType.MODELESS);
     51        settingsDialog.addWindowListener(new WindowAdapter() {
     52        public void windowClosed(WindowEvent e) {
     53                if (settingsDialog.getValue() == 1) {
     54                    settings = settingsDialog.getSettings();
     55                    performConflation();
     56                }
     57        }});
    5458
    5559        tableModel = new MatchTableModel();
    56         tableModel.setCandidates(candidates);
    57         candidates.addConflationListChangedListener(tableModel);
    5860
    5961        resultsTable = new JTable(tableModel);
     
    9698        @Override
    9799        public void actionPerformed(ActionEvent e) {
    98             optionsDialog.setVisible(true);
     100            settingsDialog.setVisible(true);
    99101        }
    100102    }
     
    159161
    160162        @Override
    161         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     163        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
     164                boolean hasFocus, int row, int column) {
    162165            Object columnValue = table.getValueAt(row, table.getColumnModel().getColumnIndex(columnName));
    163166
     
    195198        }
    196199    }
    197    
     200
    198201    class ConflationAction extends JosmAction {
     202
    199203        public ConflationAction() {
    200204            super(tr("Replace Geometry"), null, tr("Replace geometry"),
     
    202206                    KeyEvent.VK_F, Shortcut.ALT_CTRL), false);
    203207        }
     208
    204209        @Override
    205210        public void actionPerformed(ActionEvent e) {
     
    216221        }
    217222    }
    218    
    219     public class ConflationOptionsDialog extends ExtendedDialog {
    220 
    221         private JPanel costsPanel;
    222         private JCheckBox distanceCheckBox;
    223         private JButton freezeReferenceButton;
    224         private JButton freezeSubjectButton;
    225         private JPanel jPanel3;
    226         private JPanel jPanel5;
    227         private JButton restoreReferenceButton;
    228         private JButton restoreSubjectButton;
    229         private JLabel referenceLayerLabel;
    230         private JPanel referencePanel;
    231         private JLabel referenceSelectionLabel;
    232         private JLabel subjectLayerLabel;
    233         private JPanel subjectPanel;
    234         private JLabel subjectSelectionLabel;
    235         ArrayList<OsmPrimitive> subjectSelection = null;
    236         ArrayList<OsmPrimitive> referenceSelection = null;
    237         OsmDataLayer referenceLayer;
    238         DataSet subjectDataSet;
    239         OsmDataLayer subjectLayer;
    240         DataSet referenceDataSet;
    241 
    242         public ConflationOptionsDialog() {
    243             super(Main.parent,
    244                     tr("Configure conflation options"),
    245                     new String[]{tr("Conflate"), tr("Cancel")},
    246                     false);
    247             initComponents();
    248         }
    249 
    250         private void initComponents() {
    251             referencePanel = new JPanel();
    252             referenceLayerLabel = new JLabel();
    253             referenceSelectionLabel = new JLabel();
    254             jPanel3 = new JPanel();
    255             restoreReferenceButton = new JButton(new RestoreReferenceAction());
    256             freezeReferenceButton = new JButton(new FreezeReferenceAction());
    257             subjectPanel = new JPanel();
    258             subjectLayerLabel = new JLabel();
    259             subjectSelectionLabel = new JLabel();
    260             jPanel5 = new JPanel();
    261             restoreSubjectButton = new JButton(new RestoreSubjectAction());
    262             freezeSubjectButton = new JButton(new FreezeSubjectAction());
    263             costsPanel = new JPanel();
    264             distanceCheckBox = new JCheckBox();
    265 
    266             JPanel pnl = new JPanel();
    267             pnl.setLayout(new BoxLayout(pnl, BoxLayout.PAGE_AXIS));
    268 
    269             referencePanel.setBorder(BorderFactory.createTitledBorder(tr("Reference")));
    270             referencePanel.setLayout(new BoxLayout(referencePanel, BoxLayout.PAGE_AXIS));
    271 
    272             referenceLayerLabel.setText("(none)");
    273             referencePanel.add(referenceLayerLabel);
    274 
    275             referenceSelectionLabel.setText("Rel.:0 / Ways:0 / Nodes: 0");
    276             referencePanel.add(referenceSelectionLabel);
    277 
    278             jPanel3.setLayout(new BoxLayout(jPanel3, BoxLayout.LINE_AXIS));
    279 
    280             restoreReferenceButton.setText(tr("Restore"));
    281             jPanel3.add(restoreReferenceButton);
    282 
    283             jPanel3.add(freezeReferenceButton);
    284 
    285             referencePanel.add(jPanel3);
    286 
    287             pnl.add(referencePanel);
    288 
    289             subjectPanel.setBorder(BorderFactory.createTitledBorder(tr("Subject")));
    290             subjectPanel.setLayout(new BoxLayout(subjectPanel, BoxLayout.PAGE_AXIS));
    291 
    292             subjectLayerLabel.setText("(none)");
    293             subjectPanel.add(subjectLayerLabel);
    294 
    295             subjectSelectionLabel.setText("Rel.:0 / Ways:0 / Nodes: 0");
    296             subjectPanel.add(subjectSelectionLabel);
    297 
    298             jPanel5.setLayout(new BoxLayout(jPanel5, BoxLayout.LINE_AXIS));
    299 
    300             restoreSubjectButton.setText(tr("Restore"));
    301             jPanel5.add(restoreSubjectButton);
    302 
    303             freezeSubjectButton.setText(tr("Freeze"));
    304             jPanel5.add(freezeSubjectButton);
    305 
    306             subjectPanel.add(jPanel5);
    307 
    308             pnl.add(subjectPanel);
    309 
    310             costsPanel.setBorder(BorderFactory.createTitledBorder(tr("Costs")));
    311             costsPanel.setLayout(new BoxLayout(costsPanel, BoxLayout.LINE_AXIS));
    312 
    313             distanceCheckBox.setSelected(true);
    314             distanceCheckBox.setText(tr("Distance"));
    315             distanceCheckBox.setEnabled(false);
    316             costsPanel.add(distanceCheckBox);
    317 
    318             pnl.add(costsPanel);
    319 
    320             setContent(pnl);
    321             setupDialog();
    322         }
    323 
    324         @Override
    325         protected void buttonAction(int buttonIndex, ActionEvent evt) {
    326             super.buttonAction(buttonIndex, evt);
    327             if (buttonIndex == 0) {
    328                 performConflation();
    329             }
    330         }
    331 
    332         private void performConflation() {
    333 
    334             // some initialization
    335             int n = subjectSelection.size();
    336             int m = referenceSelection.size();
    337             double cost[][] = new double[n][m];
    338 
    339             // calculate cost matrix
    340             for (int i = 0; i < n; i++) {
    341                 for (int j = 0; j < m; j++) {
    342                     cost[i][j] = ConflationUtils.calcCost(subjectSelection.get(i), referenceSelection.get(j));
    343                 }
    344             }
    345 
    346             // perform assignment using Hungarian algorithm
    347             int[][] assignment = HungarianAlgorithm.hgAlgorithm(cost, "min");
    348             OsmPrimitive subObject, refObject;
    349             candidates.clear();
    350             for (int i = 0; i < n; i++) {
    351                 int subIdx = assignment[i][0];
    352                 int refIdx = assignment[i][1];
    353                 if (subIdx < n) {
    354                     subObject = subjectSelection.get(subIdx);
    355                 } else {
    356                     subObject = null;
    357                 }
    358                 if (refIdx < m) {
    359                     refObject = referenceSelection.get(refIdx);
    360                 } else {
    361                     refObject = null;
    362                 }
    363 
    364                 if (subObject != null && refObject != null) {
    365                     // TODO: do something!
    366                     if (!(candidates.hasCandidate(refObject, subObject) || candidates.hasCandidate(subObject, refObject))) {
    367                         candidates.add(new ConflationCandidate(refObject, referenceLayer, subObject, subjectLayer, cost[subIdx][refIdx]));
    368                     }
    369                 }
    370             }
    371 
    372             // add conflation layer
    373             try {
    374                 conflationLayer = new ConflationLayer(subjectLayer.data, candidates);
    375                 Main.main.addLayer(conflationLayer);
    376             } catch (Exception ex) {
    377                 JOptionPane.showMessageDialog(Main.parent, ex.toString(),
    378                         "Error adding conflation layer", JOptionPane.ERROR_MESSAGE);
    379             }
    380 
    381             // print list of matched pairsalong with distance
    382             // upon selection of one pair, highlight them and draw arrow
    383 
    384 //            if (resultsPanel != null) {
    385 //                resultsTabPanel.setSelectedComponent(resultsPanel);
    386 //            }
    387         }
    388 
    389         class RestoreSubjectAction extends JosmAction {
    390 
    391             public RestoreSubjectAction() {
    392                 super(tr("Restore"), null, tr("Restore subject selection"), null, false);
    393             }
    394 
    395             @Override
    396             public void actionPerformed(ActionEvent e) {
    397                 if (subjectLayer != null && subjectDataSet != null && subjectSelection != null && !subjectSelection.isEmpty()) {
    398                     Main.map.mapView.setActiveLayer(subjectLayer);
    399                     subjectLayer.setVisible(true);
    400                     subjectDataSet.setSelected(subjectSelection);
    401                 }
    402             }
    403         }
    404 
    405         class RestoreReferenceAction extends JosmAction {
    406 
    407             public RestoreReferenceAction() {
    408                 super(tr("Restore"), null, tr("Restore reference selection"), null, false);
    409             }
    410 
    411             @Override
    412             public void actionPerformed(ActionEvent e) {
    413                 if (referenceLayer != null && referenceDataSet != null && referenceSelection != null && !referenceSelection.isEmpty()) {
    414                     Main.map.mapView.setActiveLayer(referenceLayer);
    415                     referenceLayer.setVisible(true);
    416                     referenceDataSet.setSelected(referenceSelection);
    417                 }
    418             }
    419         }
    420 
    421         class FreezeSubjectAction extends JosmAction {
    422 
    423             public FreezeSubjectAction() {
    424                 super(tr("Freeze"), null, tr("Freeze subject selection"), null, false);
    425             }
    426 
    427             @Override
    428             public void actionPerformed(ActionEvent e) {
    429                 if (subjectDataSet != null && subjectDataSet == Main.main.getCurrentDataSet()) {
    430 //                subjectDataSet.removeDataSetListener(this); FIXME:
    431                 }
    432                 subjectDataSet = Main.main.getCurrentDataSet();
    433 //            subjectDataSet.addDataSetListener(tableModel); FIXME:
    434                 subjectLayer = Main.main.getEditLayer();
    435                 if (subjectDataSet == null || subjectLayer == null) {
    436                     JOptionPane.showMessageDialog(Main.parent, tr("No valid OSM data layer present."),
    437                             tr("Error freezing selection"), JOptionPane.ERROR_MESSAGE);
    438                     return;
    439                 }
    440                 subjectSelection = new ArrayList<OsmPrimitive>(subjectDataSet.getSelected());
    441                 if (subjectSelection.isEmpty()) {
    442                     JOptionPane.showMessageDialog(Main.parent, tr("Nothing is selected, please try again."),
    443                             tr("Empty selection"), JOptionPane.ERROR_MESSAGE);
    444                     return;
    445                 }
    446 
    447                 int numNodes = 0;
    448                 int numWays = 0;
    449                 int numRelations = 0;
    450                 for (OsmPrimitive p : subjectSelection) {
    451                     switch (p.getType()) {
    452                         case NODE:
    453                             numNodes++;
    454                             break;
    455                         case WAY:
    456                             numWays++;
    457                             break;
    458                         case RELATION:
    459                             numRelations++;
    460                             break;
    461                     }
    462                 }
    463 
    464                 // FIXME: translate correctly
    465                 subjectLayerLabel.setText(subjectLayer.getName());
    466                 subjectSelectionLabel.setText(String.format("Rel.: %d / Ways: %d / Nodes: %d", numRelations, numWays, numNodes));
    467             }
    468         }
    469 
    470         class FreezeReferenceAction extends JosmAction {
    471 
    472             public FreezeReferenceAction() {
    473                 super(tr("Freeze"), null, tr("Freeze subject selection"), null, false);
    474             }
    475 
    476             @Override
    477             public void actionPerformed(ActionEvent e) {
    478                 if (referenceDataSet != null && referenceDataSet == Main.main.getCurrentDataSet()) {
    479 //                referenceDataSet.removeDataSetListener(this); FIXME:
    480                 }
    481                 referenceDataSet = Main.main.getCurrentDataSet();
    482 //            referenceDataSet.addDataSetListener(this); FIXME:
    483                 referenceLayer = Main.main.getEditLayer();
    484                 if (referenceDataSet == null || referenceLayer == null) {
    485                     JOptionPane.showMessageDialog(Main.parent, tr("No valid OSM data layer present."),
    486                             tr("Error freezing selection"), JOptionPane.ERROR_MESSAGE);
    487                     return;
    488                 }
    489                 referenceSelection = new ArrayList<OsmPrimitive>(referenceDataSet.getSelected());
    490                 if (referenceSelection.isEmpty()) {
    491                     JOptionPane.showMessageDialog(Main.parent, tr("Nothing is selected, please try again."),
    492                             tr("Empty selection"), JOptionPane.ERROR_MESSAGE);
    493                     return;
    494                 }
    495 
    496                 int numNodes = 0;
    497                 int numWays = 0;
    498                 int numRelations = 0;
    499                 for (OsmPrimitive p : referenceSelection) {
    500                     switch (p.getType()) {
    501                         case NODE:
    502                             numNodes++;
    503                             break;
    504                         case WAY:
    505                             numWays++;
    506                             break;
    507                         case RELATION:
    508                             numRelations++;
    509                             break;
    510                     }
    511                 }
    512 
    513                 // FIXME: translate correctly
    514                 referenceLayerLabel.setText(referenceLayer.getName());
    515                 referenceSelectionLabel.setText(String.format("Rel.: %d / Ways: %d / Nodes: %d", numRelations, numWays, numNodes));
    516             }
    517         }
    518     }
    519223
    520224    @Override
     
    533237            }
    534238        }
    535         tableModel.fireTableDataChanged();
    536239    }
    537240
     
    559262    public void dataChanged(DataChangedEvent event) {
    560263    }
     264
     265    private ConflationCandidateList generateCandidates(ConflationSettings settings) {
     266        ConflationCandidateList cands = new ConflationCandidateList();
     267
     268        // some initialization
     269        int n = settings.getSubjectSelection().size();
     270        int m = settings.getReferenceSelection().size();
     271        double[][] cost = new double[n][m];
     272        // calculate cost matrix
     273        for (int i = 0; i < n; i++) {
     274            for (int j = 0; j < m; j++) {
     275                cost[i][j] = ConflationUtils.calcCost(
     276                        settings.getSubjectSelection().get(i), settings.getReferenceSelection().get(j));
     277            }
     278        }
     279        // perform assignment using Hungarian algorithm
     280        int[][] assignment = HungarianAlgorithm.hgAlgorithm(cost, "min");
     281        OsmPrimitive subObject;
     282        OsmPrimitive refObject;
     283        for (int i = 0; i < n; i++) {
     284            int subIdx = assignment[i][0];
     285            int refIdx = assignment[i][1];
     286            if (subIdx < n) {
     287                subObject = settings.getSubjectSelection().get(subIdx);
     288            } else {
     289                subObject = null;
     290            }
     291            if (refIdx < m) {
     292                refObject = settings.getReferenceSelection().get(refIdx);
     293            } else {
     294                refObject = null;
     295            }
     296            if (subObject != null && refObject != null) {
     297                // TODO: do something!
     298                if (!(cands.hasCandidate(refObject, subObject) || cands.hasCandidate(subObject, refObject))) {
     299                    cands.add(new ConflationCandidate(
     300                            refObject, settings.getReferenceLayer(),
     301                            subObject, settings.getSubjectLayer(), cost[subIdx][refIdx]));
     302                }
     303            }
     304        }
     305        return cands;
     306    }
     307
     308    private void performConflation() {
     309        candidates = generateCandidates(settings);
     310        tableModel.setCandidates(candidates);
     311        candidates.addConflationListChangedListener(tableModel);
     312        settings.getSubjectDataSet().addDataSetListener(this);
     313        settings.getReferenceDataSet().addDataSetListener(this);
     314        // add conflation layer
     315        try {
     316            if (conflationLayer == null) {
     317                conflationLayer = new ConflationLayer();
     318                Main.main.addLayer(conflationLayer);
     319            }
     320        } catch (Exception ex) {
     321            JOptionPane.showMessageDialog(Main.parent, ex.toString(), "Error adding conflation layer", JOptionPane.ERROR_MESSAGE);
     322        }
     323        conflationLayer.setCandidates(candidates);
     324//        candidates.addConflationListChangedListener(conflationLayer);
     325
     326               
     327    }
    561328}
Note: See TracChangeset for help on using the changeset viewer.