Modify algorithm for addresses missing a street with a matching name

Signed-off-by: Taylor Smock <taylor.smock@kaart.com>
pull/1/head
Taylor Smock 2020-04-02 09:39:49 -06:00
rodzic eaa92aaeef
commit cdd6915588
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
5 zmienionych plików z 184 dodań i 262 usunięć

Wyświetl plik

@ -12,7 +12,9 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openstreetmap.josm.data.osm.BBox;
import org.openstreetmap.josm.data.osm.IPrimitive;
import org.openstreetmap.josm.data.osm.IWay;
import org.openstreetmap.josm.data.osm.Node;
@ -42,7 +44,7 @@ public class StreetAddressOrder extends Test {
public void visit(Way way) {
if (way.isUsable() && way.hasTag("highway", StreetAddressTest.CLASSIFIED_HIGHWAYS) && way.hasTag("name")) {
String name = way.get("name");
List<IPrimitive> addresses = StreetAddressTest.getNearbyAddresses(way).stream().filter(Objects::nonNull)
List<IPrimitive> addresses = getNearbyAddresses(way).stream().filter(Objects::nonNull)
.filter(w -> w.hasTag("addr:housenumber")).filter(w -> name.equals(w.get("addr:street")))
.sorted(Comparator.comparing(p -> convertAddrHouseNumberToDouble(p.get("addr:housenumber"))))
.collect(Collectors.toList());
@ -54,6 +56,46 @@ public class StreetAddressOrder extends Test {
}
}
/**
* Get nearby addresses to a way
*
* @param way The way to get nearby addresses from
* @return The primitives that have appropriate addr tags near to the way
*/
public static List<IPrimitive> getNearbyAddresses(Way way) {
BBox bbox = StreetAddressTest.expandBBox(way.getBBox(), StreetAddressTest.BBOX_EXPANSION);
List<Node> addrNodes = way.getDataSet().searchNodes(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
List<Way> addrWays = way.getDataSet().searchWays(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
List<Relation> addrRelations = way.getDataSet().searchRelations(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
return Stream.of(addrNodes, addrWays, addrRelations).flatMap(List::parallelStream)
.filter(prim -> isNearestRoad(way, prim)).collect(Collectors.toList());
}
/**
* Check if a way is the nearest road to a primitive
*
* @param way The way to check
* @param prim The primitive to get the distance from
* @return {@code true} if the primitive is the nearest way
*/
public static boolean isNearestRoad(Way way, OsmPrimitive prim) {
BBox primBBox = StreetAddressTest.expandBBox(prim.getBBox(), StreetAddressTest.BBOX_EXPANSION);
List<Pair<Way, Double>> sorted = way.getDataSet().searchWays(primBBox).parallelStream()
.filter(StreetAddressTest::isHighway).map(iway -> StreetAddressTest.distanceToWay(iway, prim))
.sorted(Comparator.comparing(p -> p.b)).collect(Collectors.toList());
if (!sorted.isEmpty()) {
double minDistance = sorted.get(0).b;
List<Way> nearby = sorted.stream().filter(p -> p.b - minDistance < StreetAddressTest.BBOX_EXPANSION * 0.05)
.map(p -> p.a).collect(Collectors.toList());
return nearby.contains(way);
}
return false;
}
/**
* Convert a housenumber (addr:housenumber) to a double
*
@ -61,12 +103,12 @@ public class StreetAddressOrder extends Test {
* @return The double representation, or {@link Double#NaN} if not convertible.
*/
public static double convertAddrHouseNumberToDouble(String housenumber) {
String[] parts = housenumber.split(" ");
String[] parts = housenumber.split(" ", -1);
double number = 0;
for (String part : parts) {
try {
if (part.contains("/")) {
String[] fractional = part.split("/");
String[] fractional = part.split("/", -1);
double tmp = Double.parseDouble(fractional[0]);
for (int i = 1; i < fractional.length; i++) {
tmp = tmp / Double.parseDouble(fractional[i]);

Wyświetl plik

@ -4,19 +4,18 @@ package org.openstreetmap.josm.plugins.mapwithai.data.validation.tests;
import static org.openstreetmap.josm.tools.I18n.marktr;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openstreetmap.josm.data.osm.BBox;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.IPrimitive;
import org.openstreetmap.josm.data.osm.IWay;
import org.openstreetmap.josm.data.osm.Node;
@ -27,147 +26,87 @@ import org.openstreetmap.josm.data.validation.Severity;
import org.openstreetmap.josm.data.validation.Test;
import org.openstreetmap.josm.data.validation.TestError;
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
import org.openstreetmap.josm.spi.preferences.Config;
import org.openstreetmap.josm.tools.Geometry;
import org.openstreetmap.josm.tools.Pair;
public class StreetAddressTest extends Test {
private static final double BBOX_EXPANSION = 0.001;
/** Standard bbox expansion */
public static final double BBOX_EXPANSION = 0.001;
private static final String ADDR_STREET = "addr:street";
private final Set<OsmPrimitive> namePrimitiveMap = new HashSet<>();
/**
* Classified highways in order of importance
*
* Copied from {@link org.openstreetmap.josm.data.validation.tests.Highways}
*/
public static final List<String> CLASSIFIED_HIGHWAYS = Collections.unmodifiableList(
Arrays.asList("motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary",
"secondary_link", "tertiary", "tertiary_link", "unclassified", "residential", "living_street"));
public static final List<String> CLASSIFIED_HIGHWAYS = Collections.unmodifiableList(Arrays.asList("motorway",
"motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link",
"tertiary", "tertiary_link", "unclassified", "residential", "living_street", "service", "road"));
public StreetAddressTest() {
super(tr("Mismatched street/street addresses ({0})", MapWithAIPlugin.NAME),
tr("Check for addr:street/street name mismatches"));
}
@Override
public void visit(Relation relation) {
realVisit(relation);
}
@Override
public void visit(Way way) {
if (way.isUsable() && isHighway(way)) {
List<IPrimitive> addresses = getNearbyAddresses(way);
Map<String, Integer> addressOccurance = getAddressOccurance(addresses);
createError(way, addressOccurance, addresses);
}
realVisit(way);
}
public void createError(Way way, Map<String, Integer> occurances, List<IPrimitive> addresses) {
String name = way.get("name");
Collection<String> likelyNames = getLikelyNames(occurances);
TestError.Builder error = null;
if (name == null) {
error = TestError.builder(this, Severity.WARNING, 65446500);
error.message(tr("{0} (experimental)", MapWithAIPlugin.NAME),
marktr("Street with no name with {0} tags nearby, name possibly {1}"), ADDR_STREET, likelyNames)
.highlight(getAddressPOI(likelyNames, addresses));
} else if (!likelyNames.contains(name)) {
error = TestError.builder(this, Severity.WARNING, 65446501);
error.message(tr("{0} (experimental)", MapWithAIPlugin.NAME),
marktr("Street name does not match most likely name, name possibly {0}"), likelyNames)
.highlight(getAddressPOI(likelyNames, addresses));
}
if (error != null && !likelyNames.isEmpty()) {
error.primitives(way);
errors.add(error.build());
}
@Override
public void visit(Node node) {
realVisit(node);
}
/**
* Get a list of likely names from a map of occurrences
*
* @param occurances The map of Name to occurrences
* @return The string(s) with the most occurrences
*/
public static List<String> getLikelyNames(Map<String, Integer> occurances) {
List<String> likelyNames = new ArrayList<>();
Integer max = 0;
for (Entry<String, Integer> entry : occurances.entrySet()) {
if (entry.getKey() == null || entry.getKey().trim().isEmpty()) {
continue;
}
if (entry.getValue() > max) {
max = entry.getValue();
likelyNames.clear();
likelyNames.add(entry.getKey());
} else if (max.equals(entry.getValue())) {
likelyNames.add(entry.getKey());
@Override
public void endTest() {
Map<String, List<OsmPrimitive>> values = namePrimitiveMap.parallelStream()
.collect(Collectors.groupingBy(p -> p.get(ADDR_STREET)));
values.forEach(this::createError);
namePrimitiveMap.clear();
}
public void createError(String addrStreet, List<OsmPrimitive> primitives) {
errors.add(TestError.builder(this, Severity.WARNING, 2136232)
.message(tr("{0} (experimental)", MapWithAIPlugin.NAME),
marktr("Addresses are not nearby a matching road ({0})"), addrStreet)
.primitives(primitives).build());
}
public void realVisit(OsmPrimitive primitive) {
if (primitive.isUsable() && hasStreetAddressTags(primitive)) {
Collection<Way> surroundingWays = getSurroundingHighways(primitive);
Collection<String> names = getWayNames(surroundingWays);
if (!names.contains(primitive.get(ADDR_STREET))) {
namePrimitiveMap.add(primitive);
}
}
return likelyNames;
}
/**
* Get address points relevant to a set of names
*
* @param names The street names of interest
* @param addresses Potential address points
* @return POI's for the street names
*/
public static List<OsmPrimitive> getAddressPOI(Collection<String> names, Collection<IPrimitive> addresses) {
return addresses.stream().filter(OsmPrimitive.class::isInstance).map(OsmPrimitive.class::cast)
.filter(p -> names.contains(p.get(ADDR_STREET))).collect(Collectors.toList());
public static Collection<String> getWayNames(Collection<Way> ways) {
return ways.parallelStream().flatMap(w -> w.getInterestingTags().entrySet().parallelStream())
.filter(e -> e.getKey().contains("name") && !e.getKey().contains("tiger")).map(Map.Entry::getValue)
.collect(Collectors.toSet());
}
/**
* Count the street address occurances
*
* @param addressPOI The list to count
* @return A map of street names with a count
*/
public static Map<String, Integer> getAddressOccurance(Collection<IPrimitive> addressPOI) {
Map<String, Integer> count = new HashMap<>();
for (IPrimitive prim : addressPOI) {
if (prim.hasTag(ADDR_STREET)) {
int current = count.getOrDefault(prim.get(ADDR_STREET), 0);
count.put(prim.get(ADDR_STREET), ++current);
}
public static Collection<Way> getSurroundingHighways(OsmPrimitive address) {
Objects.requireNonNull(address.getDataSet(), "Node must be part of a dataset");
DataSet ds = address.getDataSet();
BBox addrBox = expandBBox(address.getBBox(), BBOX_EXPANSION);
int expansions = 0;
int maxExpansions = Config.getPref().getInt("mapwithai.validator.streetaddresstest.maxexpansions", 20);
while (ds.searchWays(addrBox).parallelStream().filter(StreetAddressTest::isHighway).count() == 0
&& expansions < maxExpansions) {
expandBBox(addrBox, BBOX_EXPANSION);
expansions++;
}
return count;
}
/**
* Get nearby addresses to a way
*
* @param way The way to get nearby addresses from
* @return The primitives that have appropriate addr tags near to the way
*/
public static List<IPrimitive> getNearbyAddresses(Way way) {
BBox bbox = expandBBox(way.getBBox(), BBOX_EXPANSION);
List<Node> addrNodes = way.getDataSet().searchNodes(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
List<Way> addrWays = way.getDataSet().searchWays(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
List<Relation> addrRelations = way.getDataSet().searchRelations(bbox).parallelStream()
.filter(StreetAddressTest::hasStreetAddressTags).collect(Collectors.toList());
return Stream.of(addrNodes, addrWays, addrRelations).flatMap(List::parallelStream)
.filter(prim -> StreetAddressTest.isNearestRoad(way, prim)).collect(Collectors.toList());
}
/**
* Check if a way is the nearest road to a primitive
*
* @param way The way to check
* @param prim The primitive to get the distance from
* @return {@code true} if the primitive is the nearest way
*/
public static boolean isNearestRoad(Way way, OsmPrimitive prim) {
BBox primBBox = expandBBox(prim.getBBox(), BBOX_EXPANSION);
List<Pair<Way, Double>> sorted = way.getDataSet().searchWays(primBBox).parallelStream()
.filter(StreetAddressTest::isHighway).map(iway -> distanceToWay(iway, prim))
.sorted(Comparator.comparing(p -> p.b)).collect(Collectors.toList());
if (!sorted.isEmpty()) {
double minDistance = sorted.get(0).b;
List<Way> nearby = sorted.stream().filter(p -> p.b - minDistance < BBOX_EXPANSION * 0.05).map(p -> p.a)
.collect(Collectors.toList());
return nearby.contains(way);
}
return false;
return ds.searchWays(addrBox).parallelStream().filter(StreetAddressTest::isHighway).collect(Collectors.toSet());
}
/**

Wyświetl plik

@ -23,7 +23,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.Version;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.gpx.GpxData;
import org.openstreetmap.josm.data.gpx.WayPoint;
@ -87,7 +86,7 @@ public class MapWithAIDataUtilsTest {
final BBox testBBox = getTestBBox();
final BBox testBBox2 = new BBox(-108.4495519, 39.095376, -108.4422314, 39.0987811);
final DataSet ds = new DataSet(MapWithAIDataUtils.getData(Arrays.asList(testBBox, testBBox2)));
int expectedBounds = Version.getInstance().getVersion() >= 15_609 ? 2 : 4;
int expectedBounds = 2;
assertEquals(expectedBounds, ds.getDataSourceBounds().size(), "There should be two data sources");
}

Wyświetl plik

@ -7,6 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@ -30,6 +31,7 @@ import org.openstreetmap.josm.tools.Geometry;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
public class StreetAddressOrderTest {
private static final String ADDR_STREET = "addr:street";
@Rule
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
public JOSMTestRules test = new JOSMTestRules().projection();
@ -43,7 +45,7 @@ public class StreetAddressOrderTest {
Node tNode = new Node(new LatLon(0, 0.00001));
ds.addPrimitive(tNode);
tNode = new Node(tNode, true);
tNode.put("addr:street", "Test Road");
tNode.put(ADDR_STREET, "Test Road");
ds.addPrimitive(tNode);
tNode = new Node(tNode, true);
@ -190,4 +192,72 @@ public class StreetAddressOrderTest {
assertEquals(1, StreetAddressOrder.getNeighbors(primitives.get(2), primitives).size());
}
@Test
public void testGetNearbyAddresses() {
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
DataSet ds = new DataSet();
way1.getNodes().forEach(ds::addPrimitive);
ds.addPrimitive(way1);
assertTrue(StreetAddressOrder.getNearbyAddresses(way1).isEmpty());
Node node1 = new Node(new LatLon(1, 2));
node1.put(ADDR_STREET, "Test1");
ds.addPrimitive(node1);
assertTrue(StreetAddressOrder.getNearbyAddresses(way1).isEmpty());
Node node2 = new Node(new LatLon(1, 1.0001));
node2.put(ADDR_STREET, "Test2");
ds.addPrimitive(node2);
assertEquals(1, StreetAddressOrder.getNearbyAddresses(way1).size());
assertSame(node2, StreetAddressOrder.getNearbyAddresses(way1).get(0));
Node node3 = new Node(new LatLon(1, 0.9999));
ds.addPrimitive(node3);
assertSame(node2, StreetAddressOrder.getNearbyAddresses(way1).get(0));
assertEquals(1, StreetAddressOrder.getNearbyAddresses(way1).size());
node3.put(ADDR_STREET, "Test3");
assertTrue(StreetAddressOrder.getNearbyAddresses(way1).containsAll(Arrays.asList(node2, node3)));
assertEquals(2, StreetAddressOrder.getNearbyAddresses(way1).size());
}
@Test
public void testIsNearestRoad() {
Node node1 = new Node(new LatLon(0, 0));
DataSet ds = new DataSet(node1);
double boxCorners = 0.0009;
Way way1 = TestUtils.newWay("", new Node(new LatLon(boxCorners, boxCorners)),
new Node(new LatLon(boxCorners, -boxCorners)));
Way way2 = TestUtils.newWay("", new Node(new LatLon(-boxCorners, boxCorners)),
new Node(new LatLon(-boxCorners, -boxCorners)));
for (Way way : Arrays.asList(way1, way2)) {
way.getNodes().forEach(ds::addPrimitive);
ds.addPrimitive(way);
}
assertFalse(StreetAddressOrder.isNearestRoad(way1, node1));
assertFalse(StreetAddressOrder.isNearestRoad(way2, node1));
way1.put("highway", "residential");
way2.put("highway", "motorway");
assertTrue(StreetAddressOrder.isNearestRoad(way1, node1));
assertTrue(StreetAddressOrder.isNearestRoad(way2, node1));
node1.setCoor(new LatLon(boxCorners * 0.9, boxCorners * 0.9));
assertTrue(StreetAddressOrder.isNearestRoad(way1, node1));
assertFalse(StreetAddressOrder.isNearestRoad(way2, node1));
node1.setCoor(new LatLon(-boxCorners * 0.9, -boxCorners * 0.9));
assertTrue(StreetAddressOrder.isNearestRoad(way2, node1));
assertFalse(StreetAddressOrder.isNearestRoad(way1, node1));
node1.setCoor(new LatLon(0.00005, 0.00005));
assertFalse(StreetAddressOrder.isNearestRoad(way2, node1));
assertTrue(StreetAddressOrder.isNearestRoad(way1, node1));
}
}

Wyświetl plik

@ -8,12 +8,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
@ -22,7 +16,6 @@ import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.AbstractPrimitive;
import org.openstreetmap.josm.data.osm.BBox;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.IPrimitive;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.testutils.JOSMTestRules;
@ -49,25 +42,30 @@ public class StreetAddressTestTest {
node1.put(ADDR_STREET, "Test");
ds.addPrimitive(node1);
test.visit(way1);
test.endTest();
assertTrue(test.getErrors().isEmpty());
way1.put("highway", "residential");
test.visit(way1);
test.visit(node1);
test.endTest();
assertFalse(test.getErrors().isEmpty());
way1.put("name", "Test1");
test.clear();
test.visit(way1);
test.visit(node1);
test.endTest();
assertFalse(test.getErrors().isEmpty());
way1.put("name", "Test");
test.clear();
test.visit(way1);
test.visit(node1);
test.endTest();
assertTrue(test.getErrors().isEmpty());
node1.remove(ADDR_STREET);
test.clear();
test.visit(way1);
test.visit(node1);
test.endTest();
assertTrue(test.getErrors().isEmpty());
way1.put("name", "Test1");
@ -77,137 +75,11 @@ public class StreetAddressTestTest {
setIncomplete.setAccessible(true);
setIncomplete.invoke(firstNode, true);
assertTrue(way1.firstNode().isIncomplete());
test.visit(way1);
test.visit(node1);
test.endTest();
assertTrue(test.getErrors().isEmpty());
}
@Test
public void testGetLikelyNames() {
Map<String, Integer> likelyNames = new HashMap<>();
assertTrue(StreetAddressTest.getLikelyNames(likelyNames).isEmpty());
likelyNames.put("Test Name 1", 0);
assertEquals("Test Name 1", StreetAddressTest.getLikelyNames(likelyNames).get(0));
likelyNames.put("Test Name 2", 1);
assertEquals("Test Name 2", StreetAddressTest.getLikelyNames(likelyNames).get(0));
assertEquals(1, StreetAddressTest.getLikelyNames(likelyNames).size());
likelyNames.put("Test Name 3", 1);
likelyNames.put(null, 50000);
likelyNames.put(" ", 20000);
assertEquals(2, StreetAddressTest.getLikelyNames(likelyNames).size());
assertTrue(
StreetAddressTest.getLikelyNames(likelyNames).containsAll(Arrays.asList("Test Name 2", "Test Name 3")));
}
@Test
public void testGetAddressPOI() {
Node poi1 = new Node(new LatLon(0, 0));
assertTrue(StreetAddressTest.getAddressPOI(Collections.singleton("Test Street"), Collections.singleton(poi1))
.isEmpty());
poi1.put(ADDR_STREET, "Test Street");
assertEquals(poi1, StreetAddressTest
.getAddressPOI(Collections.singleton("Test Street"), Collections.singleton(poi1)).get(0));
assertEquals(poi1, StreetAddressTest.getAddressPOI(Collections.singleton("Test Street"),
Arrays.asList(new Node(new LatLon(0, 0)), poi1, new Node(new LatLon(1, 1)))).get(0));
}
@Test
public void testGetAddressOccurance() {
Collection<IPrimitive> holder = new HashSet<>();
assertTrue(StreetAddressTest.getAddressOccurance(holder).isEmpty());
Node tNode = new Node(new LatLon(0, 0));
holder.add(tNode);
assertTrue(StreetAddressTest.getAddressOccurance(holder).isEmpty());
tNode.put(ADDR_STREET, "Test Road 1");
assertEquals(1, StreetAddressTest.getAddressOccurance(holder).get("Test Road 1"));
for (int i = 0; i < 10; i++) {
Node tNode2 = new Node(tNode);
tNode2.clearOsmMetadata();
holder.add(tNode2);
}
assertEquals(11, StreetAddressTest.getAddressOccurance(holder).get("Test Road 1"));
tNode = new Node(tNode);
tNode.clearOsmMetadata();
tNode.remove(ADDR_STREET);
holder.add(tNode);
assertEquals(11, StreetAddressTest.getAddressOccurance(holder).get("Test Road 1"));
assertEquals(1, StreetAddressTest.getAddressOccurance(holder).size());
tNode.put(ADDR_STREET, "Test Road 2");
assertEquals(11, StreetAddressTest.getAddressOccurance(holder).get("Test Road 1"));
assertEquals(1, StreetAddressTest.getAddressOccurance(holder).get("Test Road 2"));
assertEquals(2, StreetAddressTest.getAddressOccurance(holder).size());
}
@Test
public void testGetNearbyAddresses() {
Way way1 = TestUtils.newWay("highway=residential", new Node(new LatLon(0, 0)), new Node(new LatLon(1, 1)));
DataSet ds = new DataSet();
way1.getNodes().forEach(ds::addPrimitive);
ds.addPrimitive(way1);
assertTrue(StreetAddressTest.getNearbyAddresses(way1).isEmpty());
Node node1 = new Node(new LatLon(1, 2));
node1.put(ADDR_STREET, "Test1");
ds.addPrimitive(node1);
assertTrue(StreetAddressTest.getNearbyAddresses(way1).isEmpty());
Node node2 = new Node(new LatLon(1, 1.0001));
node2.put(ADDR_STREET, "Test2");
ds.addPrimitive(node2);
assertEquals(1, StreetAddressTest.getNearbyAddresses(way1).size());
assertSame(node2, StreetAddressTest.getNearbyAddresses(way1).get(0));
Node node3 = new Node(new LatLon(1, 0.9999));
ds.addPrimitive(node3);
assertSame(node2, StreetAddressTest.getNearbyAddresses(way1).get(0));
assertEquals(1, StreetAddressTest.getNearbyAddresses(way1).size());
node3.put(ADDR_STREET, "Test3");
assertTrue(StreetAddressTest.getNearbyAddresses(way1).containsAll(Arrays.asList(node2, node3)));
assertEquals(2, StreetAddressTest.getNearbyAddresses(way1).size());
}
@Test
public void testIsNearestRoad() {
Node node1 = new Node(new LatLon(0, 0));
DataSet ds = new DataSet(node1);
double boxCorners = 0.0009;
Way way1 = TestUtils.newWay("", new Node(new LatLon(boxCorners, boxCorners)),
new Node(new LatLon(boxCorners, -boxCorners)));
Way way2 = TestUtils.newWay("", new Node(new LatLon(-boxCorners, boxCorners)),
new Node(new LatLon(-boxCorners, -boxCorners)));
for (Way way : Arrays.asList(way1, way2)) {
way.getNodes().forEach(ds::addPrimitive);
ds.addPrimitive(way);
}
assertFalse(StreetAddressTest.isNearestRoad(way1, node1));
assertFalse(StreetAddressTest.isNearestRoad(way2, node1));
way1.put("highway", "residential");
way2.put("highway", "motorway");
assertTrue(StreetAddressTest.isNearestRoad(way1, node1));
assertTrue(StreetAddressTest.isNearestRoad(way2, node1));
node1.setCoor(new LatLon(boxCorners * 0.9, boxCorners * 0.9));
assertTrue(StreetAddressTest.isNearestRoad(way1, node1));
assertFalse(StreetAddressTest.isNearestRoad(way2, node1));
node1.setCoor(new LatLon(-boxCorners * 0.9, -boxCorners * 0.9));
assertTrue(StreetAddressTest.isNearestRoad(way2, node1));
assertFalse(StreetAddressTest.isNearestRoad(way1, node1));
node1.setCoor(new LatLon(0.00005, 0.00005));
assertFalse(StreetAddressTest.isNearestRoad(way2, node1));
assertTrue(StreetAddressTest.isNearestRoad(way1, node1));
}
@Test
public void testDistanceToWay() {
Node node1 = new Node(new LatLon(0, 0));