Skip to content

Commit

Permalink
Merge pull request #6 from tyndare/match-optim
Browse files Browse the repository at this point in the history
NPE fix and match time optim
  • Loading branch information
don-vip authored Mar 6, 2017
2 parents 7c72f52 + 8f9f34a commit 1ca85d9
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 21 deletions.
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# the current plugin version. Increment if you create a new build to be rolled out
# via the OSM subversion repository
#
plugin.version=0.4.2
plugin.version=0.4.3

# the lowest JOSM version the curent plugin version is compatible with
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ private void clearListsContentAndListeners() {
primitivesRemovedSubjectOnly.clear();
primitivesRemovedMatchByReference.clear();
primitivesRemovedMatchBySubject.clear();
matches.removeAllConflationListChangedListener();
matches.clear();
matches.removeAllConflationListChangedListener();
referenceOnlyListModel.clear();
subjectOnlyListModel.clear();
updateTabTitles();
Expand Down Expand Up @@ -576,7 +576,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole
} else {
setBackground(table.getBackground());
setForeground(table.getForeground());
if (columnValue.equals("Conflicts!")) {
if ("Conflicts!".equals(columnValue)) {
setBackground(java.awt.Color.red);
} else {
setBackground(java.awt.Color.green);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
import static org.openstreetmap.josm.tools.I18n.tr;

import java.awt.Dimension;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.CompoundBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.vividsolutions.jcs.conflate.polygonmatch.AbstractDistanceMatcher;
import com.vividsolutions.jcs.conflate.polygonmatch.BasicFCMatchFinder;
Expand All @@ -26,10 +30,12 @@
import com.vividsolutions.jcs.conflate.polygonmatch.HausdorffDistanceMatcher;
import com.vividsolutions.jcs.conflate.polygonmatch.IdenticalFeatureFilter;
import com.vividsolutions.jcs.conflate.polygonmatch.OneToOneFCMatchFinder;
import com.vividsolutions.jcs.conflate.polygonmatch.WindowMatcher;

public class MatchFinderPanel extends JPanel {
private final JComboBox<String> matchFinderComboBox;
private final CentroidDistanceComponent centroidDistanceComponent;
private final HausdorffDistanceComponent hausdorffDistanceComponent;

public MatchFinderPanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Expand All @@ -51,12 +57,22 @@ public MatchFinderPanel() {
centroidDistanceComponent = new CentroidDistanceComponent();
centroidDistanceComponent.setAlignmentX(LEFT_ALIGNMENT);
add(centroidDistanceComponent);

hausdorffDistanceComponent = new HausdorffDistanceComponent();
hausdorffDistanceComponent.setAlignmentX(LEFT_ALIGNMENT);
add(hausdorffDistanceComponent);
}

public FCMatchFinder getMatchFinder() {
IdenticalFeatureFilter identical = new IdenticalFeatureFilter();
FeatureMatcher[] matchers = {centroidDistanceComponent.getFeatureMatcher(), identical};
ChainMatcher chain = new ChainMatcher(matchers);
ArrayList<FeatureMatcher> matchers = new ArrayList<>();
// Use a WindowMatcher limit the search area
matchers.add(new WindowMatcher(centroidDistanceComponent.getValue()));
matchers.add(centroidDistanceComponent.getFeatureMatcher());
if (hausdorffDistanceComponent.isSelected()) {
matchers.add(hausdorffDistanceComponent.getFeatureMatcher());
}
matchers.add(new IdenticalFeatureFilter());
ChainMatcher chain = new ChainMatcher(matchers.toArray(new FeatureMatcher[matchers.size()]));
BasicFCMatchFinder basicFinder = new BasicFCMatchFinder(chain);
FCMatchFinder finder;
// FIXME: use better method of specifying match finder
Expand All @@ -71,8 +87,9 @@ else if (matchFinderComboBox.getSelectedItem().equals("OneToOneFCMatchFinder"))

abstract class DistanceComponent extends AbstractScoreComponent {
SpinnerNumberModel threshDistanceSpinnerModel;
boolean selected;

DistanceComponent(String title) {
DistanceComponent(String title, boolean mandatory) {
setBorder(new CompoundBorder(
BorderFactory.createTitledBorder(tr(title)),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
Expand All @@ -83,6 +100,7 @@ abstract class DistanceComponent extends AbstractScoreComponent {
JLabel threshDistanceLabel = new JLabel(tr("Threshold distance"));
threshDistanceLabel.setToolTipText(
tr("Distances greater than this will result in a score of zero."));

//TODO: how to set reasonable default?
threshDistanceSpinnerModel = new SpinnerNumberModel(20, 0, Double.MAX_VALUE, 1);
JSpinner threshDistanceSpinner = new JSpinner(threshDistanceSpinnerModel);
Expand All @@ -91,35 +109,61 @@ abstract class DistanceComponent extends AbstractScoreComponent {
).getTextField();
spinnerTextField.setColumns(10);

selected = mandatory;
if (!mandatory) {
JCheckBox checkbox = new JCheckBox();
checkbox.setSelected(selected);
threshDistanceLabel.setEnabled(selected);
threshDistanceSpinner.setEnabled(selected);
checkbox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
selected = checkbox.isSelected();
threshDistanceLabel.setEnabled(selected);
threshDistanceSpinner.setEnabled(selected);
}
});
panel.add(checkbox);
panel.add(Box.createRigidArea(new Dimension(5, 0)));
}

panel.add(threshDistanceLabel);
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(threshDistanceSpinner);
add(panel);
}

double getValue() {
return threshDistanceSpinnerModel.getNumber().doubleValue();
}

boolean isSelected() {
return selected;
}
}

class CentroidDistanceComponent extends DistanceComponent {
CentroidDistanceComponent() {
super(tr("Centroid distance"));
super(tr("Centroid distance"), true);
}

@Override
FeatureMatcher getFeatureMatcher() {
AbstractDistanceMatcher matcher = new CentroidDistanceMatcher();
matcher.setMaxDistance(threshDistanceSpinnerModel.getNumber().doubleValue());
matcher.setMaxDistance(getValue());
return matcher;
}
}

class HausdorffDistanceComponent extends DistanceComponent {
HausdorffDistanceComponent() {
super(tr("Hausdorff distance"));
super(tr("Hausdorff distance"), false);
}

@Override
FeatureMatcher getFeatureMatcher() {
AbstractDistanceMatcher matcher = new HausdorffDistanceMatcher();
matcher.setMaxDistance(threshDistanceSpinnerModel.getNumber().doubleValue());
matcher.setMaxDistance(getValue());
return matcher;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;
import com.vividsolutions.jump.feature.IndexedFeatureCollection;
import com.vividsolutions.jump.task.TaskMonitor;

public final class MatchesComputation {

private MatchesComputation() {}

/**
* Generates a list of matches from the given user settings.
* @param settings the setting to use: list of objects to match, the match finder to use...
Expand All @@ -44,7 +45,7 @@ public static Collection<SimpleMatch> generateMatches(SimpleMatchSettings settin
allPrimitives.addAll(refPrimitives);
allPrimitives.addAll(subPrimitives);
FeatureCollection allFeatures = createFeatureCollection(allPrimitives);

FeatureCollection refColl = new FeatureDataset(allFeatures.getFeatureSchema());
FeatureCollection subColl = new FeatureDataset(allFeatures.getFeatureSchema());
for (Feature f : allFeatures.getFeatures()) {
Expand All @@ -54,8 +55,12 @@ public static Collection<SimpleMatch> generateMatches(SimpleMatchSettings settin
if (subPrimitives.contains(osmFeature.getPrimitive()))
subColl.add(osmFeature);
}

//TODO: pass to MatchFindrefPrimitiveserPanel to use as hint/default for DistanceMatchers

// Index the collection for efficient search with WindowMatcher
refColl = new IndexedFeatureCollection(refColl);
subColl = new IndexedFeatureCollection(subColl);

//TODO: pass to MatchFinderPanel to use as hint/default for DistanceMatchers
// get maximum possible distance so scores can be scaled (FIXME: not quite accurate)
// Envelope envelope = refColl.getEnvelope();
// envelope.expandToInclude(subColl.getEnvelope());
Expand Down Expand Up @@ -85,7 +90,7 @@ public static Collection<SimpleMatch> generateMatches(SimpleMatchSettings settin
entry.getValue().getTopScore()));
}
return list;
}
}

/**
* Create FeatureSchema using union of all keys from all selected primitives
Expand Down Expand Up @@ -117,15 +122,15 @@ private static FeatureCollection createFeatureCollection(Collection<OsmPrimitive
* Progress monitor for use with JCS linked to a JOSM ProgressMonitor.
*/
private static class TaskMonitorJosmAdapter implements TaskMonitor {

private final ProgressMonitor josmMonitor;
private final HashMap<String, String> translations = new HashMap<>();
{
translations.put("Finding matches", tr("Finding matches"));
translations.put("Sorting scores", tr("Sorting scores"));
translations.put("Discarding inferior matches", tr("Discarding inferior matches"));
translations.put("Discarding inferior matches", tr("Discarding inferior matches"));
}

TaskMonitorJosmAdapter(ProgressMonitor josmMonitor) {
this.josmMonitor = josmMonitor;
}
Expand Down Expand Up @@ -155,6 +160,6 @@ public boolean isCancelRequested() {
return josmMonitor.isCanceled();
}

}
}

}

0 comments on commit 1ca85d9

Please sign in to comment.