Package com.vividsolutions.jcs.conflate.polygonmatch

Source Code of com.vividsolutions.jcs.conflate.polygonmatch.OneToOneFCMatchFinder


/*
* The Java Conflation Suite (JCS) is a library of Java classes that
* can be used to build automated or semi-automated conflation solutions.
*
* Copyright (C) 2003 Vivid Solutions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC  V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/

package com.vividsolutions.jcs.conflate.polygonmatch;

import com.vividsolutions.jts.util.Assert;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.IndexedFeatureCollection;
import com.vividsolutions.jump.task.TaskMonitor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* Enforces a one-to-one relationship between target features and
* matched candidate features, in the returned result set. The one-to-one
* constraint is achieved by discarding all matches except the top match,
* for each feature (target and candidate).
* <P>
* Example: OneToOneFCMatchFinder wraps a FCMatchFinder that returns the
* following matches (and scores): T1-C1 (0.8), T2-C1 (0.9), T2-C2 (0.8),
* T2-C3 (1.0), T3-C4 (0.5). T1 and T2 are from the target dataset, whereas
* C1, C2, and C3 are from the candidate dataset. OneToOneFCMatchFinder filters
* out all matches except the top ones, for each feature, leaving:
* T2-C3 (1.0), T3-C4 (0.5).
*/
public class OneToOneFCMatchFinder implements FCMatchFinder {

  private FCMatchFinder matchFinder;

  public OneToOneFCMatchFinder(FCMatchFinder matchFinder) {
    this.matchFinder = matchFinder;
  }

  @Override
  public Map match(FeatureCollection targetFC, FeatureCollection candidateFC, TaskMonitor monitor) {
    Map targetToMatchesMap = matchFinder.match(targetFC, candidateFC, monitor);
    monitor.allowCancellationRequests();
    monitor.report("Finding best forward matches");
    Map bestForwardMatches = filterMatches(targetToMatchesMap, monitor);
    monitor.report("Finding best reverse matches");
    Map bestReverseMatches = filterMatches(invert(targetToMatchesMap, monitor), monitor);
    monitor.report("Finding common best matches");
    //Want matches that are "best" regardless of whether forward or reverse.
    //This is the only scheme I can think of right now that will satisfy
    //the case described in the class comment. [Jon Aquino]
    return commonMatches(bestForwardMatches, invert(bestReverseMatches, monitor), monitor);
  }

  private Map commonMatches(Map featureToMatchesMap1, Map featureToMatchesMap2, TaskMonitor monitor) {
    int featuresProcessed = 0;
    int totalFeatures = featureToMatchesMap1.size();
    Map commonMatches = new HashMap();
    for (Iterator i = featureToMatchesMap1.keySet().iterator(); i.hasNext() && ! monitor.isCancelRequested(); ) {
      Feature key1 = (Feature) i.next();
      featuresProcessed++;
      monitor.report(featuresProcessed, totalFeatures, "features");
      if (! featureToMatchesMap2.containsKey(key1)) { continue; }
      Matches matches1 = (Matches) featureToMatchesMap1.get(key1);
      Matches matches2 = (Matches) featureToMatchesMap2.get(key1);
      if (matches1.getTopMatch() == matches2.getTopMatch()) {
        Assert.isTrue(matches1.getTopScore() == matches2.getTopScore());
        commonMatches.put(key1, matches1);
      }
    }
    return commonMatches;
  }

  private Map filterMatches(Map featureToMatchesMap, TaskMonitor monitor) {
    int featuresProcessed = 0;
    int totalFeatures = featureToMatchesMap.size();
    HashMap newMap = new HashMap();
    if (featureToMatchesMap.isEmpty()) { return newMap; }
    for (Iterator i = featureToMatchesMap.keySet().iterator(); i.hasNext() && ! monitor.isCancelRequested(); ) {
      Feature feature = (Feature) i.next();
      featuresProcessed++;
      monitor.report(featuresProcessed, totalFeatures, "features filtered");
      Matches oldMatches = (Matches) featureToMatchesMap.get(feature);
      if (oldMatches.isEmpty()) { continue; }
      Matches newMatches = new Matches(oldMatches.getFeatureSchema());
      newMatches.add(oldMatches.getTopMatch(), oldMatches.getTopScore());
      newMap.put(feature, newMatches);
    }
    return newMap;
  }

  protected Map invert(Map featureToMatchesMap, TaskMonitor monitor) {
    int featuresProcessed = 0;
    int totalFeatures = featureToMatchesMap.size();
    HashMap newMap = new HashMap();
    if (featureToMatchesMap.isEmpty()) { return newMap; }
    for (Iterator i = featureToMatchesMap.keySet().iterator(); i.hasNext() && ! monitor.isCancelRequested(); ) {
      Feature oldKey = (Feature) i.next();
      featuresProcessed++;
      monitor.report(featuresProcessed, totalFeatures, "features inverted");
      Matches oldMatches = (Matches) featureToMatchesMap.get(oldKey);
      for (int j = 0; j < oldMatches.size(); j++) {
        Feature newKey = (Feature) oldMatches.getFeature(j);
        Matches newMatches = (Matches) newMap.get(newKey);
        if (newMatches == null) {
          newMatches = new Matches(oldKey.getSchema());
        }
        newMatches.add(oldKey, oldMatches.getScore(j));
        newMap.put(newKey, newMatches);
      }
    }
    return newMap;
  }
}
TOP

Related Classes of com.vividsolutions.jcs.conflate.polygonmatch.OneToOneFCMatchFinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.