Skip to content

Commit

Permalink
Merge pull request #5 from tyndare/ui-list-model-optim
Browse files Browse the repository at this point in the history
UI list model optim
  • Loading branch information
don-vip authored Mar 5, 2017
2 parents cc0443e + 8c23864 commit 7c72f52
Show file tree
Hide file tree
Showing 8 changed files with 698 additions and 329 deletions.
6 changes: 3 additions & 3 deletions build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
# the current plugin version. Increment if you create a new build to be rolled out
# via the OSM subversion repository
#
plugin.version=0.4.1
plugin.version=0.4.2

# the lowest JOSM version the curent plugin version is compatible with
#
josm.required.version=10580
josm.required.version=11609

# the full path to the JOSM jar against which this plugin is built
#
Expand All @@ -26,4 +26,4 @@ local.osm.svn.path=../../dist
# the full local path where the plugin shall be installed inorder to test it
# withing a JOSM instance
#
local.install.path=/full/path/to/local/installation/josm/plugins
local.install.path=/full/path/to/local/installation/josm/plugins
545 changes: 304 additions & 241 deletions src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java

Large diffs are not rendered by default.

160 changes: 160 additions & 0 deletions src/org/openstreetmap/josm/plugins/conflation/MatchesComputation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// License: GPL. For details, see LICENSE file.
// Copyright 2012 by Josh Doe and others.
package org.openstreetmap.josm.plugins.conflation;

import static org.openstreetmap.josm.tools.I18n.tr;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.gui.progress.ProgressMonitor;
import org.openstreetmap.josm.plugins.jts.JTSConverter;

import com.vividsolutions.jcs.conflate.polygonmatch.FCMatchFinder;
import com.vividsolutions.jcs.conflate.polygonmatch.Matches;
import com.vividsolutions.jump.feature.AttributeType;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;
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...
* @param monitor progress monitor for report
* @return the list of match found
*/
public static Collection<SimpleMatch> generateMatches(SimpleMatchSettings settings, ProgressMonitor monitor) {
monitor.subTask("Generating matches");

// create Features and collections from primitive selections
HashSet<OsmPrimitive> allPrimitives = new HashSet<>();
HashSet<OsmPrimitive> refPrimitives = new HashSet<>(settings.getReferenceSelection());
HashSet<OsmPrimitive> subPrimitives = new HashSet<>(settings.getSubjectSelection());
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()) {
OsmFeature osmFeature = (OsmFeature) f;
if (refPrimitives.contains(osmFeature.getPrimitive()))
refColl.add(osmFeature);
if (subPrimitives.contains(osmFeature.getPrimitive()))
subColl.add(osmFeature);
}

//TODO: pass to MatchFindrefPrimitiveserPanel 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());
// double maxDistance = Point2D.distance(
// envelope.getMinX(),
// envelope.getMinY(),
// envelope.getMaxX(),
// envelope.getMaxY());

// build matcher
FCMatchFinder finder = settings.getMatchFinder();

// FIXME: ignore/filter duplicate objects (i.e. same object in both sets)
// FIXME: fix match functions to work on point/linestring features as well
// find matches
Map<Feature, Matches> map = finder.match(refColl, subColl, new TaskMonitorJosmAdapter(monitor));

monitor.subTask("Finishing");

// convert to simple one-to-one match
ArrayList<SimpleMatch> list = new ArrayList<>();
for (Map.Entry<Feature, Matches> entry: map.entrySet()) {
OsmFeature target = (OsmFeature) entry.getKey();
OsmFeature subject = (OsmFeature) entry.getValue().getTopMatch();
if (target != null && subject != null)
list.add(new SimpleMatch(target.getPrimitive(), subject.getPrimitive(),
entry.getValue().getTopScore()));
}
return list;
}

/**
* Create FeatureSchema using union of all keys from all selected primitives
*/
private static FeatureSchema createSchema(Collection<OsmPrimitive> prims) {
Set<String> keys = new HashSet<>();
for (OsmPrimitive prim : prims) {
keys.addAll(prim.getKeys().keySet());
}
FeatureSchema schema = new FeatureSchema();
schema.addAttribute("__GEOMETRY__", AttributeType.GEOMETRY);
for (String key : keys) {
schema.addAttribute(key, AttributeType.STRING);
}
return schema;
}

private static FeatureCollection createFeatureCollection(Collection<OsmPrimitive> prims) {
FeatureDataset dataset = new FeatureDataset(createSchema(prims));
//TODO: use factory instead of passing converter
JTSConverter converter = new JTSConverter(true);
for (OsmPrimitive prim : prims) {
dataset.add(new OsmFeature(prim, converter));
}
return dataset;
}

/**
* 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"));
}

TaskMonitorJosmAdapter(ProgressMonitor josmMonitor) {
this.josmMonitor = josmMonitor;
}

@Override
public void report(String description) {
josmMonitor.subTask(translations.getOrDefault(description, description));
}

@Override
public void report(int itemsDone, int totalItems, String itemDescription) {
josmMonitor.setTicksCount(totalItems);
josmMonitor.setTicks(itemsDone);
}

@Override
public void report(Exception exception) {
throw new UnsupportedOperationException("Not supported yet.", exception);
}

@Override
public void allowCancellationRequests() {
}

@Override
public boolean isCancelRequested() {
return josmMonitor.isCanceled();
}

}

}
37 changes: 28 additions & 9 deletions src/org/openstreetmap/josm/plugins/conflation/SimpleMatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
package org.openstreetmap.josm.plugins.conflation;

import org.openstreetmap.josm.data.osm.OsmPrimitive;
import static org.openstreetmap.josm.tools.I18n.tr;
import org.openstreetmap.josm.tools.CheckParameterUtil;

/**
* This class represents a potential match, i.e. a pair of primitives, a score
* and related information.
*/
public class SimpleMatch {
public class SimpleMatch implements Comparable<SimpleMatch> {

OsmPrimitive referenceObject;
OsmPrimitive subjectObject;
double score;
double distance;
final OsmPrimitive referenceObject;
final OsmPrimitive subjectObject;
final double score;
final double distance;

public SimpleMatch(OsmPrimitive referenceObject,
OsmPrimitive subjectObject, double score) {
if (referenceObject == null || subjectObject == null) {
throw new IllegalArgumentException(tr("Invalid reference or subject"));
}
CheckParameterUtil.ensureParameterNotNull(referenceObject, "referenceObject");
CheckParameterUtil.ensureParameterNotNull(subjectObject, "subjectObject");
this.referenceObject = referenceObject;
this.subjectObject = subjectObject;
this.score = score;
Expand All @@ -43,4 +42,24 @@ public Object getScore() {
public Object getDistance() {
return distance;
}

@Override
public int compareTo(SimpleMatch o) {
int comp = Double.compare(this.score, o.score);
if (comp == 0) {
comp = -Double.compare(this.distance, o.distance); // (-) greater distance is no good
if (comp == 0) {
comp = referenceObject.compareTo(o.referenceObject);
if (comp == 0) {
comp = subjectObject.compareTo(o.subjectObject);
}
}
}
return comp;
}

@Override
public int hashCode() {
return referenceObject.hashCode() ^ subjectObject.hashCode();
}
}
Loading

0 comments on commit 7c72f52

Please sign in to comment.