diff --git a/README.md b/README.md index 00ee259..2117cd2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This package provides basic functionality for parsing, viewing, and working with [OpenStreetMap](http://www.openstreetmap.org) map data. The package is intended mainly for researchers who want to incorporate this rich, global data into their work, and has been designed with both speed and simplicity in mind, especially for those who might be new to Julia. -**Note:** Our automated tests currently fail on Julia 0.4, but these problems appear to be contained to the test system and are caused by a dependent package. OpenStreetMap.jl should run without issue on both Julia 0.3 and 0.4. +**Note:** Our automated tests currently fail on Julia 0.4, but these problems appear to be contained to the Travis test system and are caused by a dependent package. OpenStreetMap.jl should run without issue on both Julia 0.3 and 0.4, and the tests pass on local machines for Julia 0.3.7 and 0.4.2 on OS X 10.11 and Ubuntu 14.04. ### Capabilities * Parse an [OpenStreetMap XML datafile](http://wiki.openstreetmap.org/wiki/OSM_XML) (OSM files) diff --git a/src/crop.jl b/src/crop.jl index 0491abb..bc7d7b9 100644 --- a/src/crop.jl +++ b/src/crop.jl @@ -3,20 +3,19 @@ ### Copyright 2014 ### ### Crop map elements without copying data ### -function cropMap!(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}), - bounds::Bounds; - highways::Union(Nothing,Dict{Int,Highway})=nothing, - buildings::Union(Nothing,Dict{Int,Building})=nothing, - features::Union(Nothing,Dict{Int,Feature})=nothing, +function cropMap!(nodes::@compat(Union{Dict{Int,LLA},Dict{Int,ENU}}), bounds::Bounds; + highways::@compat(Union{@compat(Void),Dict{Int,Highway}}) = nothing, + buildings::@compat(Union{@compat(Void),Dict{Int,Building}}) = nothing, + features::@compat(Union{@compat(Void),Dict{Int,Feature}}) = nothing, delete_nodes::Bool=true) - if !isa(highways, Nothing) + if !isa(highways, @compat(Void)) crop!(nodes, bounds, highways) end - if !isa(buildings, Nothing) + if !isa(buildings, @compat(Void)) crop!(nodes, bounds, buildings) end - if !isa(features, Nothing) + if !isa(features, @compat(Void)) crop!(nodes, bounds, features) end diff --git a/src/highways.jl b/src/highways.jl index 78e2eb0..c6e55ed 100644 --- a/src/highways.jl +++ b/src/highways.jl @@ -57,8 +57,8 @@ end function findHighwaySets( highways::Dict{Int,Highway} ) clusters = HighwaySet[] - street_names = (String,String,Int)[] - + street_names = @compat Tuple{@compat(AbstractString), @compat(AbstractString), Int}[] + for (key, highway) in highways if length(highway.name) > 0 && highway.oneway push!(street_names,(highway.name,highway.class,key)) @@ -82,7 +82,7 @@ function findHighwaySets( highways::Dict{Int,Highway} ) end end end - + if length(cluster) > 1 push!(clusters,HighwaySet(Set(cluster))) end @@ -90,5 +90,3 @@ function findHighwaySets( highways::Dict{Int,Highway} ) return clusters end - - diff --git a/src/nodes.jl b/src/nodes.jl index d47abb0..2844997 100644 --- a/src/nodes.jl +++ b/src/nodes.jl @@ -4,7 +4,7 @@ ### Find the nearest node to a given location ### -function nearestNode{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, loc::T) +function nearestNode{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, loc::T) min_dist = Inf best_ind = 0 @@ -21,7 +21,7 @@ end ### Find nearest node in a list of nodes ### -function nearestNode{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, +function nearestNode{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, loc::T, node_list::Vector{Int}) min_dist = Inf @@ -40,7 +40,7 @@ end ### Find nearest node serving as a vertex in a routing network ### -function nearestNode{T<:Union(ENU,ECEF)}( nodes::Dict{Int,T}, +function nearestNode{T<:@compat(Union{ENU,ECEF})}( nodes::Dict{Int,T}, loc::T, network::Network ) return nearestNode(nodes,loc,collect(keys(network.v))) @@ -48,7 +48,7 @@ end ### Find all nodes within range of a location ### -function nodesWithinRange{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, +function nodesWithinRange{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, loc::T, range::Float64=Inf) if range == Inf @@ -63,10 +63,10 @@ function nodesWithinRange{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, end return indices end - + ### Find nodes within range of a location using a subset of nodes ### -function nodesWithinRange{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, +function nodesWithinRange{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, loc::T, node_list::Vector{Int}, range::Float64=Inf) @@ -85,7 +85,7 @@ end ### Find vertices of a routing network within range of a location ### -function nodesWithinRange{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, +function nodesWithinRange{T <: @compat(Union{ENU,ECEF}) }(nodes::Dict{Int,T}, loc::T, network::Network, range::Float64=Inf) @@ -94,9 +94,9 @@ end ### Add a new node ### -function addNewNode!{T<:Union(LLA,ENU)}(nodes::Dict{Int,T}, - loc::T, - start_id::Int=abs(int(hash(loc))) ) +function addNewNode!{T <: @compat(Union{LLA,ENU}) }(nodes::Dict{Int,T}, + loc::T, + start_id::Int = reinterpret(@compat(Int), hash(loc)) ) id = start_id while id <= typemax(Int) if !haskey(nodes, id) @@ -107,12 +107,12 @@ function addNewNode!{T<:Union(LLA,ENU)}(nodes::Dict{Int,T}, end msg = "Unable to add new node to map, $(typemax(Int)) nodes is the current limit." - throw(OverflowError(msg)) + throw(error(msg)) end ### Compute centroid of list of nodes ### -function centroid{T<:Union(LLA,ENU)}(nodes::Dict{Int,T}, node_list::Vector{Int}) +function centroid{T<:@compat(Union{LLA,ENU})}(nodes::Dict{Int,T}, node_list::Vector{Int}) sum_1 = 0 sum_2 = 0 sum_3 = 0 @@ -135,5 +135,3 @@ function centroid{T<:Union(LLA,ENU)}(nodes::Dict{Int,T}, node_list::Vector{Int}) return ENU(sum_1/length(node_list),sum_2/length(node_list),sum_3/length(node_list)) end end - - diff --git a/src/parseMap.jl b/src/parseMap.jl index 30652bd..1b9b367 100644 --- a/src/parseMap.jl +++ b/src/parseMap.jl @@ -48,31 +48,31 @@ end ### PARSE XML ELEMENTS ### -function parse_node(attr::OSMattributes, attrs_in::Dict{String,String}) +function parse_node(attr::OSMattributes, attrs_in::Dict{@compat(AbstractString),@compat(AbstractString)}) attr.visible = true attr.element = :Node if haskey(attrs_in, "id") - attr.id = int(attrs_in["id"]) + attr.id = @compat( parse(Int,attrs_in["id"]) ) attr.lat = float(attrs_in["lat"]) attr.lon = float(attrs_in["lon"]) end end -function parse_way(attr::OSMattributes, attrs_in::Dict{String,String}) +function parse_way(attr::OSMattributes, attrs_in::Dict{@compat(AbstractString),@compat(AbstractString)}) attr.visible = true attr.element = :Way if haskey(attrs_in, "id") - attr.id = int(attrs_in["id"]) + attr.id = @compat( parse(Int,attrs_in["id"]) ) end end -function parse_nd(attr::OSMattributes, attrs_in::Dict{String,String}) +function parse_nd(attr::OSMattributes, attrs_in::Dict{@compat(AbstractString),@compat(AbstractString)}) if haskey(attrs_in, "ref") - push!(attr.way_nodes, int64(attrs_in["ref"])) + push!(attr.way_nodes, @compat( parse(Int64,attrs_in["ref"]) ) ) end end -function parse_tag(attr::OSMattributes, attrs_in::Dict{String,String}) +function parse_tag(attr::OSMattributes, attrs_in::Dict{@compat(AbstractString),@compat(AbstractString)}) if haskey(attrs_in, "k") && haskey(attrs_in, "v") k, v = attrs_in["k"], attrs_in["v"] if k == "name" @@ -97,7 +97,7 @@ end ### PARSE OSM ENTITIES ### -function parse_highway(attr::OSMattributes, k::String, v::String) +function parse_highway(attr::OSMattributes, k::@compat(AbstractString), v::@compat(AbstractString)) if k == "highway" attr.class = v if v == "services" # Highways marked "services" are not traversable @@ -126,21 +126,21 @@ function parse_highway(attr::OSMattributes, k::String, v::String) elseif k == "bicycle" attr.bicycle = v elseif k == "lanes" && length(v)==1 && '1' <= v[1] <= '9' - attr.lanes = int(v) + attr.lanes = @compat parse(Int,v) else return end attr.parent = :Highway end -function parse_building(attr::OSMattributes, v::String) +function parse_building(attr::OSMattributes, v::@compat(AbstractString)) attr.parent = :Building if isempty(attr.class) attr.class = v end end -function parse_feature(attr::OSMattributes, k::String, v::String) +function parse_feature(attr::OSMattributes, k::@compat(AbstractString), v::@compat(AbstractString)) attr.parent = :Feature attr.class = k attr.detail = v @@ -148,7 +148,7 @@ end ### LibExpat.XPStreamHandlers ### -function parseElement(handler::LibExpat.XPStreamHandler, name::String, attrs_in::Dict{String,String}) +function parseElement(handler::LibExpat.XPStreamHandler, name::@compat(AbstractString), attrs_in::Dict{@compat(AbstractString),@compat(AbstractString)}) attr = handler.data.attr::OSMattributes if attr.visible if name == "nd" @@ -165,7 +165,7 @@ function parseElement(handler::LibExpat.XPStreamHandler, name::String, attrs_in: end # no work done for "relations" yet end -function collectValues(handler::LibExpat.XPStreamHandler, name::String) +function collectValues(handler::LibExpat.XPStreamHandler, name::@compat(AbstractString)) # println(typeof(name)) osm = handler.data::OSMdata attr = osm.attr::OSMattributes @@ -193,7 +193,7 @@ function collectValues(handler::LibExpat.XPStreamHandler, name::String) end ### Parse the data from an openStreetMap XML file ### -function parseMapXML(filename::String) +function parseMapXML(filename::@compat(AbstractString)) # Parse the file street_map = LightXML.parse_file(filename) @@ -205,7 +205,7 @@ function parseMapXML(filename::String) return street_map end -function getOSMData(filename::String; args...) +function getOSMData(filename::@compat(AbstractString); args...) osm = OSMdata() callbacks = LibExpat.XPCallbacks() diff --git a/src/plot.jl b/src/plot.jl index 6a7034b..f0dd1a9 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -4,25 +4,25 @@ ### Functions for plotting using the Winston package ### -typealias Styles Union(Style, Dict{Int,Style}) +typealias Styles @compat(Union{Style, Dict{Int,Style}}) ### Generic Map Plot ### -function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); - highways::Union(Nothing,Dict{Int,Highway})=nothing, - buildings::Union(Nothing,Dict{Int,Building})=nothing, - features::Union(Nothing,Dict{Int,Feature})=nothing, - bounds::Union(Nothing,Bounds)=nothing, - intersections::Union(Nothing,Dict{Int,Intersection})=nothing, +function plotMap(nodes::@compat(Union{Dict{Int,LLA},Dict{Int,ENU}}) ; + highways::@compat(Union{@compat(Void),Dict{Int,Highway}}) = nothing, + buildings::@compat(Union{@compat(Void),Dict{Int,Building}}) = nothing, + features::@compat(Union{@compat(Void),Dict{Int,Feature}}) = nothing, + bounds::@compat(Union{@compat(Void),Bounds}) = nothing, + intersections::@compat(Union{@compat(Void),Dict{Int,Intersection}}) = nothing, roadways=nothing, cycleways=nothing, walkways=nothing, - feature_classes::Union(Nothing,Dict{Int,Int})=nothing, - building_classes::Union(Nothing,Dict{Int,Int})=nothing, - route::Union(Nothing,Vector{Int},Vector{Vector{Int}})=nothing, + feature_classes::@compat(Union{@compat(Void),Dict{Int,Int}}) = nothing, + building_classes::@compat(Union{@compat(Void),Dict{Int,Int}}) = nothing, + route::@compat(Union{@compat(Void),Vector{Int},Vector{Vector{Int}}}) = nothing, highway_style::Styles=Style(0x007CFF, 1.5, "-"), building_style::Styles=Style(0x000000, 1, "-"), feature_style::Styles=Style(0xCC0000, 2.5, "."), - route_style::Union(Style,Vector{Style})=Style(0xFF0000, 3, "-"), + route_style::@compat(Union{Style,Vector{Style}}) = Style(0xFF0000, 3, "-"), intersection_style::Style=Style(0x000000, 3, "."), width::Integer=500, fontsize::Integer=0, @@ -39,12 +39,16 @@ function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); end # Waiting for Winston to add capability to force equal scales. For now: - height = isa(bounds, Nothing) ? width : int(width / aspectRatio(bounds)) + if VERSION.minor < 4 + height = isa(bounds, @compat(Void)) ? width : int(width / aspectRatio(bounds)) + else + height = isa(bounds, @compat(Void)) ? width : round(Int, width / aspectRatio(bounds)) + end # Create the figure fignum = Winston.figure(name="OpenStreetMap Plot", width=width, height=height) - if isa(bounds, Nothing) + if isa(bounds, @compat(Void)) p = Winston.FramedPlot("xlabel", xlab, "ylabel", ylab) else # Limit plot to specified bounds Winston.xlim(bounds.min_x, bounds.max_x) @@ -62,8 +66,8 @@ function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); end # Iterate over all buildings and draw - if !isa(buildings, Nothing) - if !isa(building_classes, Nothing) + if !isa(buildings, @compat(Void)) + if !isa(building_classes, @compat(Void)) if isa(building_style, Dict{Int,Style}) drawWayLayer(p, nodes, buildings, building_classes, building_style, km, realtime) else @@ -81,23 +85,23 @@ function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); end # Iterate over all highways and draw - if !isa(highways, Nothing) + if !isa(highways, @compat(Void)) if !(nothing == roadways == cycleways == walkways) - if !isa(roadways, Nothing) + if !isa(roadways, @compat(Void)) if isa(highway_style, Dict{Int,Style}) drawWayLayer(p, nodes, highways, roadways, highway_style, km, realtime) else drawWayLayer(p, nodes, highways, roadways, LAYER_STANDARD, km, realtime) end end - if !isa(cycleways, Nothing) + if !isa(cycleways, @compat(Void)) if isa(highway_style, Dict{Int,Style}) drawWayLayer(p, nodes, highways, cycleways, highway_style, km, realtime) else drawWayLayer(p, nodes, highways, cycleways, LAYER_CYCLE, km, realtime) end end - if !isa(walkways, Nothing) + if !isa(walkways, @compat(Void)) if isa(highway_style, Dict{Int,Style}) drawWayLayer(p, nodes, highways, walkways, highway_style, km, realtime) else @@ -116,8 +120,8 @@ function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); end # Iterate over all features and draw - if !isa(features, Nothing) - if !isa(feature_classes, Nothing) + if !isa(features, @compat(Void)) + if !isa(feature_classes, @compat(Void)) if isa(feature_style, Dict{Int,Style}) drawFeatureLayer(p, nodes, features, feature_classes, feature_style, km, realtime) else @@ -150,7 +154,7 @@ function plotMap(nodes::Union(Dict{Int,LLA},Dict{Int,ENU}); end # Iterate over all intersections and draw - if !isa(intersections, Nothing) + if !isa(intersections, @compat(Void)) coords = Array(Float64, length(intersections), 2) k = 1 for key in keys(intersections) diff --git a/src/routing.jl b/src/routing.jl index a6dfa85..2e0faaf 100644 --- a/src/routing.jl +++ b/src/routing.jl @@ -70,7 +70,7 @@ function createGraph(nodes, highways::Dict{Int,Highway}, classes, levels, revers weight = distance(nodes, node0, node1) push!(w, weight) push!(g_classes, class) - node_set = Set(node0, node1) + # node_set = Set(node0, node1) if !highway.oneway edge = Graphs.make_edge(g, v[node1], v[node0]) @@ -111,7 +111,7 @@ function createGraph(segments::Vector{Segment}, intersections, reverse::Bool=fal weight = segment.dist push!(w, weight) push!(class, segment.class) - node_set = Set(node0, node1) + # node_set = Set(node0, node1) if !segment.oneway edge = Graphs.make_edge(g, v[node1], v[node0]) @@ -143,7 +143,7 @@ end ### Get distance between two nodes ### # ENU Coordinates -function Geodesy.distance{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, node0, node1) +function Geodesy.distance{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, node0, node1) loc0 = nodes[node0] loc1 = nodes[node1] @@ -151,7 +151,7 @@ function Geodesy.distance{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, node0, node1) end ### Compute the distance of a route ### -function Geodesy.distance{T<:Union(ENU,ECEF)}(nodes::Dict{Int,T}, route::Vector{Int}) +function Geodesy.distance{T<:@compat(Union{ENU,ECEF})}(nodes::Dict{Int,T}, route::Vector{Int}) if length(route) == 0 return Inf end diff --git a/src/simulate.jl b/src/simulate.jl index 4ebc6dc..31e3ad1 100644 --- a/src/simulate.jl +++ b/src/simulate.jl @@ -32,14 +32,14 @@ function simCityGrid(classes_north, classes_east) k = 0 # Highway ID counter for n = 1:N k += 1 - col_nodes = [(n*M-(M-1)):n*M] + col_nodes = @compat( collect( (n*M-(M-1)):n*M ) ) highways[k] = Highway("", 1, false, "", "", "", "North_$(n)", col_nodes) roadways[k] = classes_north[n] end for m = 1:M k += 1 - row_nodes = [m:M:N*M] + row_nodes = @compat( collect(m:M:N*M) ) highways[k] = Highway("", 1, false, "", "", "", "East_$(m)", row_nodes) roadways[k] = classes_east[m] end diff --git a/src/transforms.jl b/src/transforms.jl index c7423a7..f35abf6 100644 --- a/src/transforms.jl +++ b/src/transforms.jl @@ -41,7 +41,7 @@ end ##################################### # Given a reference point -function Geodesy.ENU{T<:Union(LLA,ECEF)}(nodes::Dict{Int,T}, +function Geodesy.ENU{T<:@compat Union{LLA,ECEF}}(nodes::Dict{Int,T}, lla_ref::LLA, datum::Ellipsoid = WGS84) r = Dict{Int,ENU}() diff --git a/src/types.jl b/src/types.jl index bf50047..41a120e 100644 --- a/src/types.jl +++ b/src/types.jl @@ -3,13 +3,13 @@ ### Copyright 2014 ### type Highway - class::String # Type of highway + @compat class::AbstractString # Type of highway lanes::Int # Number of lanes (1 if unspecified) oneway::Bool # True if road is one-way - sidewalk::String # Sidewalk classifier, if available - cycleway::String # Cycleway classifier, if available - bicycle::String # Bicycle classifier, if available - name::String # Name, if available + @compat sidewalk::AbstractString # Sidewalk classifier, if available + @compat cycleway::AbstractString # Cycleway classifier, if available + @compat bicycle::AbstractString # Bicycle classifier, if available + @compat name::AbstractString # Name, if available nodes::Vector{Int} # List of nodes end @@ -24,14 +24,14 @@ type Segment end type Feature - class::String # Shop, amenity, crossing, etc. - detail::String # Class qualifier - name::String # Name + @compat class::AbstractString # Shop, amenity, crossing, etc. + @compat detail::AbstractString # Class qualifier + @compat name::AbstractString # Name end type Building - class::String # Building type (usually "yes") - name::String # Building name (usually unavailable) + @compat class::AbstractString # Building type (usually "yes") + @compat name::AbstractString # Building name (usually unavailable) nodes::Vector{Int} # List of nodes end @@ -54,8 +54,8 @@ end ### Rendering style data type Style - color::Uint32 + @compat color::UInt32 width::Real - spec::String + @compat spec::AbstractString end Style(x, y) = Style(x, y, "-") diff --git a/test/crop_map.jl b/test/crop_map.jl index 3263410..de5edc8 100644 --- a/test/crop_map.jl +++ b/test/crop_map.jl @@ -31,7 +31,7 @@ let bounds = Bounds(0, 1, 0, 1) ] hwy = first(values(hwys)) - hwy.nodes = [1:length(coords)] + hwy.nodes = collect(1:length(coords)) highways = Compat.@Dict(1 => hwy) nodes = Dict{Int,LLA}([(hwy.nodes[i], coords[i]) for i in 1:length(coords)]) @@ -43,7 +43,11 @@ let bounds = Bounds(0, 1, 0, 1) @test isempty(symdiff(keys(nodes), hwy_nodes)) # everything ends up in bounds - @test all(map(x -> inBounds(x, bounds), values(nodes))) + if VERSION.minor < 4 + @test all(map(x -> inBounds(x, bounds), values(nodes))) + else + @test all(x -> inBounds(x, bounds), values(nodes)) + end # proper interpolation @test getY(nodes[hwy_nodes[1]]) == 0.0