Class: Rosemary::Element
- Inherits:
-
Object
- Object
- Rosemary::Element
- Includes:
- ActiveModel::Validations, Comparable
- Defined in:
- lib/rosemary/element.rb
Overview
This is a virtual parent class for the OSM objects Node, Way and Relation.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#changeset ⇒ Object
The changeset the last change of this object was made with.
-
#id ⇒ Fixnum
Unique ID.
-
#tags ⇒ Object
readonly
Tags for this object.
-
#timestamp ⇒ Time
Last change of this object (as read from file, it is not updated by operations to this object).
-
#uid ⇒ Object
The user id of the user who last edited this object (as read from file, it is not updated by operations to this object) API 0.6 and above only.
-
#user ⇒ Rosemary::User
The user who last edited this element (as read from file, it is not updated by operations to this object).
-
#version ⇒ Fixnum
The version of this object (as read from file, it is not updated by operations to this object) API 0.6 and above only.
Class Method Summary collapse
-
.from_api(id, api = Rosemary::API.new) ⇒ Object
Get Rosemary::Element from API.
- .from_xml(xml) ⇒ Object
Instance Method Summary collapse
- #<=>(another_element) ⇒ Object
-
#[](key) ⇒ Object
Get tag value.
-
#[]=(key, value) ⇒ Object
Set tag.
-
#add_tags(new_tags) ⇒ Object
Add one or more tags to this object.
-
#attribute_list ⇒ Object
The list of attributes for this object.
-
#attributes ⇒ Object
Returns a hash of all non-nil attributes of this object.
-
#get_history_from_api(api = Rosemary::API.new) ⇒ Object
Get the history of this object from the API.
-
#get_relations_from_api(api = Rosemary::API.new) ⇒ Object
Get all relations from the API that have his object as members.
-
#initialize(attrs = {}) ⇒ Element
constructor
:nodoc:.
- #initialize_copy(from) ⇒ Object
-
#is_tagged? ⇒ Boolean
Has this object any tags?.
-
#method_missing(method, *args) ⇒ Object
All other methods are mapped so its easy to access tags: For instance obj.name is the same as obj.tags.
-
#shape(geom, attributes) ⇒ Object
Create a new GeoRuby::Shp4r::ShpRecord with the geometry of this object and the given attributes.
- #update_attributes(attribute_hash) ⇒ Object
Constructor Details
#initialize(attrs = {}) ⇒ Element
:nodoc:
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rosemary/element.rb', line 46 def initialize(attrs = {}) #:nodoc: raise NotImplementedError.new('Element is a virtual base class for the Node, Way, and Relation classes') if self.class == Rosemary::Element attrs = {'version' => 1, 'uid' => 1}.merge(attrs.stringify_keys!) @id = attrs['id'].to_i if attrs['id'] @version = attrs['version'].to_i @uid = attrs['uid'].to_i @user = attrs['user'] @timestamp = Time.parse(attrs['timestamp']) rescue nil @changeset = attrs['changeset'].to_i @tags = Tags.new (attrs['tag']) if attrs['tag'] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
All other methods are mapped so its easy to access tags: For instance obj.name is the same as obj.tags. This works for getting and setting tags.
node = Rosemary::Node.new
node.( 'highway' => 'residential', 'name' => 'Main Street' )
node.highway #=> 'residential'
node.highway = 'unclassified' #=> 'unclassified'
node.name #=> 'Main Street'
In addition methods of the form key?
are used to check boolean tags. For instance oneway
can be ‘true’ or ‘yes’ or ‘1’, all meaning the same.
way.oneway?
will check this. It returns true if the value of this key is either ‘true’, ‘yes’ or ‘1’.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rosemary/element.rb', line 227 def method_missing(method, *args) methodname = method.to_s if methodname.slice(-1, 1) == '=' if args.size != 1 raise ArgumentError.new("wrong number of arguments (#{args.size} for 1)") end [methodname.chop] = args[0] elsif methodname.slice(-1, 1) == '?' if args.size != 0 raise ArgumentError.new("wrong number of arguments (#{args.size} for 0)") end [methodname.chop] =~ /^(true|yes|1)$/ else if args.size != 0 raise ArgumentError.new("wrong number of arguments (#{args.size} for 0)") end [methodname] end end |
Instance Attribute Details
#changeset ⇒ Object
The changeset the last change of this object was made with.
33 34 35 |
# File 'lib/rosemary/element.rb', line 33 def changeset @changeset end |
#id ⇒ Fixnum
Unique ID
9 10 11 |
# File 'lib/rosemary/element.rb', line 9 def id @id end |
#tags ⇒ Object (readonly)
Tags for this object
36 37 38 |
# File 'lib/rosemary/element.rb', line 36 def @tags end |
#timestamp ⇒ Time
Last change of this object (as read from file, it is not updated by operations to this object)
30 31 32 |
# File 'lib/rosemary/element.rb', line 30 def @timestamp end |
#uid ⇒ Object
The user id of the user who last edited this object (as read from file, it is not updated by operations to this object) API 0.6 and above only
25 26 27 |
# File 'lib/rosemary/element.rb', line 25 def uid @uid end |
#user ⇒ Rosemary::User
The user who last edited this element (as read from file, it is not updated by operations to this object)
20 21 22 |
# File 'lib/rosemary/element.rb', line 20 def user @user end |
#version ⇒ Fixnum
The version of this object (as read from file, it is not updated by operations to this object) API 0.6 and above only
15 16 17 |
# File 'lib/rosemary/element.rb', line 15 def version @version end |
Class Method Details
.from_api(id, api = Rosemary::API.new) ⇒ Object
Get Rosemary::Element from API
41 42 43 44 |
# File 'lib/rosemary/element.rb', line 41 def self.from_api(id, api=Rosemary::API.new) #:nodoc: raise NotImplementedError.new('Element is a virtual base class for the Node, Way, and Relation classes') if self.class == Rosemary::Element api.get_object(type, id) end |
.from_xml(xml) ⇒ Object
252 253 254 |
# File 'lib/rosemary/element.rb', line 252 def self.from_xml(xml) Parser.call(xml, :xml) end |
Instance Method Details
#<=>(another_element) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/rosemary/element.rb', line 59 def <=>(another_element) attribute_list.each do |attrib| next if self.send(attrib) == another_element.send(attrib) if self.send(attrib) < another_element.send(attrib) return -1 else return 1 end end 0 end |
#[](key) ⇒ Object
Get tag value
107 108 109 |
# File 'lib/rosemary/element.rb', line 107 def [](key) [key] end |
#[]=(key, value) ⇒ Object
Set tag
112 113 114 |
# File 'lib/rosemary/element.rb', line 112 def []=(key, value) [key] = value end |
#add_tags(new_tags) ⇒ Object
Add one or more tags to this object.
call-seq: add_tags(Hash) -> OsmObject
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/rosemary/element.rb', line 120 def () case when Array # Called with an array # Call recursively for each entry .each do |tag_hash| (tag_hash) end when Hash # Called with a hash #check if it is weird {'k' => 'key', 'v' => 'value'} syntax if (.size == 2 && .keys.include?('k') && .keys.include?('v')) # call recursively with values from k and v keys. ({['k'] => ['v']}) else # OK, this seems to be a proper ruby hash with a single entry .each do |k,v| self.[k] = v end end end self # return self so calls can be chained end |
#attribute_list ⇒ Object
The list of attributes for this object
85 86 87 |
# File 'lib/rosemary/element.rb', line 85 def attribute_list # :nodoc: [:id, :version, :uid, :user, :timestamp, :changeset, :tags] end |
#attributes ⇒ Object
Returns a hash of all non-nil attributes of this object.
Keys of this hash are :id
, :user
, and :timestamp
. For a Node also :lon
and :lat
.
call-seq: attributes -> Hash
97 98 99 100 101 102 103 104 |
# File 'lib/rosemary/element.rb', line 97 def attributes attrs = Hash.new attribute_list.each do |attribute| value = self.send(attribute) attrs[attribute] = value unless value.nil? end attrs end |
#get_history_from_api(api = Rosemary::API.new) ⇒ Object
Get the history of this object from the API.
The optional parameter is an Rosemary::API object. If none is specified the default OSM API is used.
Returns an array of Rosemary::Node, Rosemary::Way, or Rosemary::Relation objects with all the versions.
205 206 207 |
# File 'lib/rosemary/element.rb', line 205 def get_history_from_api(api=Rosemary::API.new) api.get_history(type, self.id.to_i) end |
#get_relations_from_api(api = Rosemary::API.new) ⇒ Object
Get all relations from the API that have his object as members.
The optional parameter is an Rosemary::API object. If none is specified the default OSM API is used.
Returns an array of Relation objects or an empty array.
194 195 196 |
# File 'lib/rosemary/element.rb', line 194 def get_relations_from_api(api=Rosemary::API.new) api.get_relations_referring_to_object(type, self.id.to_i) end |
#initialize_copy(from) ⇒ Object
247 248 249 250 |
# File 'lib/rosemary/element.rb', line 247 def initialize_copy(from) super @tags = from..dup end |
#is_tagged? ⇒ Boolean
Has this object any tags?
158 159 160 |
# File 'lib/rosemary/element.rb', line 158 def is_tagged? ! @tags.empty? end |
#shape(geom, attributes) ⇒ Object
Create a new GeoRuby::Shp4r::ShpRecord with the geometry of this object and the given attributes.
This only works if the GeoRuby library is included.
- geom
-
Geometry
- attributes
-
Hash with attributes
call-seq: shape(attributes) -> GeoRuby::Shp4r::ShpRecord
Example:
require 'rubygems'
require 'geo_ruby'
node = Node(nil, nil, nil, 7.84, 54.34)
g = node.point
node.shape(g, :type => 'Pharmacy', :name => 'Hyde Park Pharmacy')
179 180 181 182 183 184 185 |
# File 'lib/rosemary/element.rb', line 179 def shape(geom, attributes) fields = Hash.new attributes.each do |key, value| fields[key.to_s] = value end GeoRuby::Shp4r::ShpRecord.new(geom, fields) end |
#update_attributes(attribute_hash) ⇒ Object
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/rosemary/element.rb', line 142 def update_attributes(attribute_hash) dirty = false attribute_hash.each do |key,value| if self.send(key).to_s != value.to_s self.send("#{key}=", value.to_s) dirty = true end end dirty end |