From 371b68ffd067cc0e57796cd68b160824341572be Mon Sep 17 00:00:00 2001 From: Ted Steiner Date: Tue, 13 Jan 2015 14:15:05 -0500 Subject: [PATCH] Tests and documentation for intersection clustering. Changed type HighwayCluster to HighwaySet. Intersection clustering requires nodes to be in ENU coordinates. Issue #31. Signed-off-by: Ted Steiner --- docs/data.rst | 14 ++++++++++++++ src/OpenStreetMap.jl | 1 + src/highways.jl | 8 ++++---- src/intersections.jl | 11 +++++++---- src/types.jl | 2 +- test/intersections.jl | 36 ++++++++++++++++++++++++++++++++++++ test/runtests.jl | 1 + 7 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 test/intersections.jl diff --git a/docs/data.rst b/docs/data.rst index a351225..6997582 100644 --- a/docs/data.rst +++ b/docs/data.rst @@ -36,6 +36,20 @@ The only required input is the highway dictionary returned by "getOSMData()." A dictionary of "Intersection" types is returned, intexed by the node ID of the intersection. +In some cases, such as boulevards and other divided roads, OpenStreetMap represents a street as two one-way highways. This can result in multiple "intersections" detected per true intersection. If desired, these intersections can be "clustered," replacing these multiple intersection-lets with a single node. To do this, we must first cluster the highways, by gathering all highways with a common name (note that this is dependent on the quality of street name tags in your source data). +We then search for proximal instances of these highway sets crossing one another. Flag max_dist can be used to change the required proximity of the nodes to be considered an intersection (the default is 15 meters). Note that this proximity is the maximum distance the node can be from the centroid of all nodes in the intersection at the time the node is added. + +The code to accomplish this is as follows: + +.. code-block:: python + + highway_sets = findHighwaySets(highways) + intersection_mapping, intersection_nodes = findIntersectionClusters(nodes,intersections,highway_sets,max_dist=15) + replaceHighwayNodes!(highways,intersection_mapping) + +The optional flag "max_dist" is in the units of your "nodes" object. + + Working with Segments --------------------- diff --git a/src/OpenStreetMap.jl b/src/OpenStreetMap.jl index d641bc7..8b55ade 100644 --- a/src/OpenStreetMap.jl +++ b/src/OpenStreetMap.jl @@ -19,6 +19,7 @@ export lla2enu, lla2ecef, ecef2lla, ecef2enu export roadways, walkways, cycleways, classify export createGraph, shortestRoute, fastestRoute, distance, routeEdges export nodesWithinRange, nodesWithinDrivingDistance, nodesWithinDrivingTime +export findHighwaySets, findIntersectionClusters, replaceHighwayNodes! export simCityGrid include("types.jl") diff --git a/src/highways.jl b/src/highways.jl index e0445bd..78e2eb0 100644 --- a/src/highways.jl +++ b/src/highways.jl @@ -53,9 +53,9 @@ function cycleways(highways::Dict{Int,Highway}) return cycles end -### Find Highway Pairs (two one-way highways with same name) ### -function findHighwayPairs( highways::Dict{Int,Highway} ) - clusters = HighwayCluster[] +### Find sets of same-named highways ### +function findHighwaySets( highways::Dict{Int,Highway} ) + clusters = HighwaySet[] street_names = (String,String,Int)[] @@ -84,7 +84,7 @@ function findHighwayPairs( highways::Dict{Int,Highway} ) end if length(cluster) > 1 - push!(clusters,HighwayCluster(Set(cluster))) + push!(clusters,HighwaySet(Set(cluster))) end end diff --git a/src/intersections.jl b/src/intersections.jl index 3c57044..e050358 100644 --- a/src/intersections.jl +++ b/src/intersections.jl @@ -39,7 +39,7 @@ function findIntersections(highways::Dict{Int,Highway}) end ### Generate a new list of highways divided up by intersections -function segmentHighways(nodes, highways, intersections, classes, levels=Set(1:10)) +function segmentHighways(nodes, highways::Dict{Int,Highway}, intersections, classes, levels=Set(1:10)) segments = Segment[] inters = Set(keys(intersections)) @@ -70,7 +70,7 @@ function segmentHighways(nodes, highways, intersections, classes, levels=Set(1:1 end ### Generate a list of highways from segments, for plotting purposes -function highwaySegments(segments::Vector{Segment}) +function highwaySegments( segments::Vector{Segment} ) highways = Dict{Int,Highway}() for k = 1:length(segments) @@ -82,7 +82,10 @@ end ### Cluster highway intersections into higher-level intersections ### -function findIntersectionClusters(nodes, intersections_in, highway_clusters; max_dist=15.0) +function findIntersectionClusters( nodes::Dict{Int,ENU}, + intersections_in::Dict{Int,Intersection}, + highway_clusters::Vector{HighwaySet}; + max_dist=15.0 ) hwy_cluster_mapping = Dict{Int,Int}() for k = 1:length(highway_clusters) hwys = [highway_clusters[k].highways...] @@ -176,7 +179,7 @@ end ### Replace Nodes in Highways Using Node Remapping -function replaceHighwayNodes!(highways::Dict{Int,Highway}, node_map::Dict{Int,Int}) +function replaceHighwayNodes!( highways::Dict{Int,Highway}, node_map::Dict{Int,Int} ) for (key,hwy) in highways all_equal = true for k = 1:length(hwy.nodes) diff --git a/src/types.jl b/src/types.jl index 380ba10..c80ae9f 100644 --- a/src/types.jl +++ b/src/types.jl @@ -40,7 +40,7 @@ type Intersection end Intersection() = Intersection(Set{Int}()) -type HighwayCluster # Multiple highways representing a single "street" with a common name +type HighwaySet # Multiple highways representing a single "street" with a common name highways::Set{Int} end diff --git a/test/intersections.jl b/test/intersections.jl new file mode 100644 index 0000000..f6aedb3 --- /dev/null +++ b/test/intersections.jl @@ -0,0 +1,36 @@ +# Test intersection detection and clustering + +module TestIntersections + +using OpenStreetMap +using Base.Test +using Compat + +import OpenStreetMap: Bounds, centerBounds + +MAP_FILENAME = "tech_square.osm" + +bounds = Bounds(42.3637, 42.3655, -71.0919, -71.0893) + +bounds_ENU = lla2enu(bounds) + +nodesLLA, hwys, builds, feats = getOSMData(MAP_FILENAME) +nodes = lla2enu(nodesLLA,centerBounds(bounds)) + +# Find intersections in map +intersections = findIntersections(hwys) +@test length(intersections) == 91 + +# Find Highway Sets +highway_sets = findHighwaySets(hwys) +@test length(highway_sets) == 4 + +# Cluster intersections +intersection_cluster_mapping, intersection_cluster_nodes = findIntersectionClusters(nodes,intersections,highway_sets,max_dist=15) +replaceHighwayNodes!(hwys,intersection_cluster_mapping) +intersections_clustered = findIntersections(hwys) +@test length(intersections_clustered) == 82 + +end # module TestIntersections + + diff --git a/test/runtests.jl b/test/runtests.jl index a364efd..9fb3002 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,7 @@ tests = [ "crop_map", "classes", "coordinates", + "intersections", "routes", "plots" ]