// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.fixAddresses;
import org.openstreetmap.josm.data.osm.Changeset;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.data.osm.visitor.Visitor;
/**
* GuessedValueHandler visits all nodes and ways in order to find a guessed value for a given tag.
* The guess is determined by finding the closest way/node with the given tag. If no appropriate node
* is found within maximum distance, no guess is made.
*
* The default maximum distance is 100m.
*/
public class GuessedValueHandler implements Visitor {
/** Default maximum distance (100m) */
private static final double DEFAULT_MAX_DIST = 100.0;
private String tag;
protected double minDist;
protected String currentValue;
private OSMAddress aNode;
private double maxDist = DEFAULT_MAX_DIST;
protected OsmPrimitive srcNode;
/**
* Instantiates a new guessed value handler without node and default maximum distance.
*
* @param tag the tag to find the guessed value for.
*/
public GuessedValueHandler(String tag) {
this(tag, null, DEFAULT_MAX_DIST);
}
/**
* Instantiates a new guessed value handler without node.
*
* @param tag the tag to find the guessed value for.
* @param maxDist the maximum distance for a node/way to be considered as guessed value.
*/
public GuessedValueHandler(String tag, double maxDist) {
this(tag, null, maxDist);
}
/**
* Instantiates a new guessed value handler.
*
* @param tag the tag to find the guessed value for.
* @param aNode the address node to guess the values for.
* @param maxDist the maximum distance for a node/way to be considered as guessed value.
*/
public GuessedValueHandler(String tag, OSMAddress aNode) {
this(tag, aNode, DEFAULT_MAX_DIST);
}
/**
* Instantiates a new guessed value handler.
*
* @param tag the tag to find the guessed value for.
* @param aNode the address node to guess the values for.
* @param maxDist the maximum distance for a node/way to be considered as guessed value.
*/
public GuessedValueHandler(String tag, OSMAddress aNode, double maxDist) {
super();
if (StringUtils.isNullOrEmpty(tag)) {
throw new RuntimeException("Tag must not be empty or null!");
}
if (maxDist < 1.0) { // clip value
maxDist = 1.0;
}
this.tag = tag;
this.maxDist = maxDist;
setAddressNode(aNode);
}
/**
* Gets the address node to make the guess for.
*
* @return the aNode
*/
protected OSMAddress getAddressNode() {
return aNode;
}
/**
* Sets the address node to make the guess for.
* @param aNode address node
*/
public void setAddressNode(OSMAddress aNode) {
this.aNode = aNode;
// reset search results
minDist = Double.MAX_VALUE;
srcNode = null;
currentValue = null;
}
/**
* Gets the max distance allowed to consider a node as guess.
* If the distance of the node is greater than maxDist, the
* node/way will be ignored.
*
* @return the maxDist
*/
protected double getMaxDistance() {
return maxDist;
}
/**
* Gets the tag name to use as guess.
*
* @return the tag
*/
protected String getTag() {
return tag;
}
/**
* Gets the distance of the node/way which has been used for the guessed value.
*
* @return the minDist
*/
protected double getMinimumDist() {
return minDist;
}
/**
* Gets the current guessed value or null, if no guess has been possible (so far).
*
* @return the currentValue
*/
public String getCurrentValue() {
return currentValue;
}
/**
* Gets the node/way which has been selected for the guess.
* @return The source node or null; if no appropriate source primitive has been found
*/
public OsmPrimitive getSourceNode() {
return srcNode;
}
/**
* Check if we need to visit the OSM data
*
* @return true, if successful
*/
public boolean needsGuess() {
return aNode.needsGuessedValue(tag);
}
@Override
public void visit(Node n) {
assert aNode != null;
if (n.hasKey(tag)) {
double dist = n.getCoor().greatCircleDistance(aNode.getCoor());
if (dist < minDist && dist < maxDist) {
minDist = dist;
currentValue = n.get(tag);
srcNode = n;
}
}
}
@Override
public void visit(Way w) {
assert aNode != null;
if (w.hasKey(tag)) {
double dist = OsmUtils.getMinimumDistanceToWay(aNode.getCoor(), w);
if (dist < minDist && dist < maxDist) {
minDist = dist;
currentValue = w.get(tag);
srcNode = w;
}
}
}
@Override
public void visit(Relation e) {
// nothing to do (yet)
}
@Override
public void visit(Changeset cs) {
// nothing to do (yet)
}
}