Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 9f2a9a7f7a
Fetching contributors…

Cannot retrieve contributors at this time

file 67 lines (55 sloc) 1.942 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
require './osm'
require 'xml/libxml'

module OSM
  ATTRIBUTES = {
    :id => ["id", :to_i],
    :changeset => ["changeset", :to_i],
    :timestamp => ["timestamp", :to_s],
    :visible => ["visible", Proc.new {|a| a == "true"}],
    :version => ["version", :to_i],
    :uid => ["uid", :to_i],
  }
  
  TYPES = {
    "node" => OSM::Node,
    "way" => OSM::Way,
    "relation" => OSM::Relation
  }

  def self.parse(xml)
    doc = XML::Parser.string(xml).parse
    doc.root.children.select {|e| e.element? }.map do |xml_elem|
      tags = Hash[xml_elem.children.
                  select {|ch| ch.element? && ch.name == "tag"}.
                  map {|ch| [ch["k"].to_s, ch["v".to_s]]}]
      
      attrs = Hash[ATTRIBUTES.collect do |k,v|
                     elt = xml_elem[v[0]]
                     val = elt.nil? ? nil : (v[1].class == Symbol) ? elt.send(v[1]) : v[1].call(elt)
                     [k, val]
                   end]
      
      case xml_elem.name
      when "node"
        OSM::Node[[xml_elem["lon"].to_r, xml_elem["lat"].to_r],
                  attrs.merge(tags)]
        
      when "way"
        nds = xml_elem.children.
          select {|ch| ch.element? && ch.name == "nd"}.
          map {|ch| ch["ref"].to_i}
        
        OSM::Way[nds, attrs.merge(tags)]
        
      when "relation"
        members = xml_elem.children.
          select {|ch| ch.element? && ch.name == "member"}.
          map {|ch| [TYPES[ch["type"]], ch["ref"].to_i, ch["role"]]}
        
        OSM::Relation[members, attrs.merge(tags)]

      when "bounds"
        # ignore

      else
        raise "Element type #{xml_elem.name.inspect} not expected! Was expecting one of 'node', 'way' or 'relation'."
      end
    end.compact
  end

  def self.user_id_from_changeset(xml)
    doc = XML::Parser.string(xml).parse
    cs = doc.root.children.select {|e| e.element? }.first
    uid = cs["uid"]
    uid.nil? ? 0 : uid.to_i
  end
end
Something went wrong with that request. Please try again.