geon 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ .idea
2
+ coverage
3
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'nokogiri'
4
+
5
+ group :test do
6
+ gem 'test-unit'
7
+ gem 'rspec'
8
+ gem "minitest"
9
+ gem "minitest-reporters", '>= 0.5.0'
10
+ gem 'simplecov', :require => false, :group => :test
11
+ end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'geon'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'geon'
7
+ gem.author = 'Alexander Suslov'
8
+ gem.email = ['a.s.suslov@gmail.com']
9
+ gem.description = %q{Geo data provider}
10
+ gem.summary = gem.description
11
+ gem.homepage = 'https://github.com/AlmazKo/geon'
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.test_files = `git ls-files -- spec/*_spec.rb`.split($\)
14
+ gem.require_paths = ['lib']
15
+ gem.version = Geon::VERSION
16
+ gem.license = 'MIT'
17
+ end
@@ -0,0 +1,10 @@
1
+ module Geon
2
+ VERSION = '0.1'
3
+ end
4
+
5
+ require 'net/http'
6
+
7
+ require 'geon/http_loader'
8
+ require 'geon/wikimapia'
9
+
10
+
@@ -0,0 +1,13 @@
1
+ module Geon
2
+ class HttpLoader
3
+ def initialize(host, port = 80)
4
+ @http = Net::HTTP.new(host, port)
5
+ @headers = {
6
+ "Accept" => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
7
+ "Accept-Charset" => "utf-8;q=0.7,*;q=0.3",
8
+ "User-Agent" => "Geon #{Geon::VERSION}"
9
+ }
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,149 @@
1
+ require 'nokogiri'
2
+
3
+
4
+ module Nokogiri::XML
5
+
6
+ class Document
7
+
8
+ def to_hash
9
+ self.root.element? ? self.root.to_hash : {self.root.name => self.root.text}
10
+ end
11
+
12
+ end
13
+
14
+ class Element
15
+
16
+ def to_hash
17
+ {self.name => self.collect_attributes}
18
+ end
19
+
20
+ def collect_attributes
21
+ arr = []
22
+ self.children.each do |child|
23
+ next if child.name == 'text'
24
+ hash = {}
25
+ if child.element? && child.children.length > 1
26
+ hash[child.name] = child.collect_attributes
27
+ else
28
+ hash[child.name] = child.text.strip
29
+ end
30
+ arr << hash
31
+ end
32
+ arr
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ module Geon
40
+ class Wikimapia
41
+
42
+ # @param [Cipa::Gateway::Downloader] downloader
43
+ # @param [String] service_key
44
+ def initialize(downloader, service_key)
45
+ @downloader, @service_key = downloader, service_key
46
+ end
47
+
48
+ # @example
49
+ # place_getnearest(55.753141,37.625299) #Red square
50
+ #
51
+ def place_getnearest(lat = 0.0, lon = 0.0, service_key = @service_key)
52
+ response = @downloader.get({function: 'place.getnearest', key: service_key, lat: lat, lon: lon})
53
+ reader = Nokogiri::XML::Reader(response, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS)
54
+
55
+ node = reader.read
56
+
57
+ raise 'place.getnearest: wrong response' unless node.name == 'wm'
58
+
59
+ # slide cursor
60
+ 4.times { reader.read }
61
+
62
+
63
+ places = []
64
+ place = {}
65
+
66
+ current_place = nil
67
+ loop do
68
+
69
+ node = reader.read
70
+ break unless node
71
+
72
+ node_name = node.name
73
+
74
+ case node_name
75
+ when 'id'
76
+ node = reader.read
77
+ place[:id] = node.value.to_i
78
+ when 'title'
79
+ node = reader.read
80
+ place[:title] = node.value
81
+ when 'language'
82
+ node = reader.read
83
+ place[:language] = node.value
84
+ when 'distance'
85
+ node = reader.read
86
+ place[:distance] = node.value.to_i
87
+ when 'location'
88
+ place[:location] = parse_location(reader)
89
+ when 'polygon'
90
+ place[:polygon] = parse_polygon(reader)
91
+ else
92
+
93
+ if node_name =~ /places_(\d+)/
94
+ if current_place == $1.to_i
95
+ places << place
96
+ else
97
+ current_place = $1.to_i
98
+ place = {}
99
+ end
100
+
101
+ next
102
+ end
103
+
104
+ reader.read
105
+ end
106
+
107
+ reader.read
108
+ end
109
+
110
+ places
111
+ end
112
+
113
+ def parse_location(reader)
114
+ location = {}
115
+ 6.times {
116
+ node = reader.read
117
+ location[node.name.to_sym] = reader.read.value.to_f
118
+ reader.read
119
+ }
120
+
121
+ location
122
+ end
123
+
124
+ def parse_polygon(reader)
125
+ polygon = []
126
+
127
+ 4.times {
128
+ point = {}
129
+ reader.read
130
+
131
+ 2.times {
132
+ node = reader.read
133
+ node_name = node.name
134
+
135
+ point[node_name.to_sym] = reader.read.value.to_f
136
+ reader.read
137
+ }
138
+
139
+ reader.read
140
+
141
+ polygon << point
142
+ }
143
+
144
+ polygon
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,10 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ require "rspec"
4
+ require 'geon'
5
+
6
+ $specs_dir = File.dirname(__FILE__)
7
+
8
+ def sample(name)
9
+ IO.read ("#{$specs_dir}/samples/#{name}")
10
+ end
@@ -0,0 +1,183 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <wm>
3
+ <language>en</language>
4
+ <places>
5
+ <places_0>
6
+ <id>24434033</id>
7
+ <title>Звёздный бул., 30, корпус 1</title>
8
+ <language_id>1</language_id>
9
+ <language>ru</language>
10
+ <urlhtml>&lt;a class=&quot;wikimapia-link&quot; href=&quot;http://wikimapia.org/24434033/ru/Звёздный_бул.,_30,_корпус_1&quot;&gt;Звёздный
11
+ бул., 30, корпус 1&lt;/a&gt;</urlhtml>
12
+ <distance>10</distance>
13
+ <location>
14
+ <north>55.8146558</north>
15
+ <south>55.8143825</south>
16
+ <east>37.626803</east>
17
+ <west>37.6263677</west>
18
+ <lon>37.62658535</lon>
19
+ <lat>55.81451915</lat>
20
+ </location>
21
+ <polygon>
22
+ <polygon_0>
23
+ <x>37.6265575</x>
24
+ <y>55.8146559</y>
25
+ </polygon_0>
26
+ <polygon_1>
27
+ <x>37.6263677</x>
28
+ <y>55.8145822</y>
29
+ </polygon_1>
30
+ <polygon_2>
31
+ <x>37.6266132</x>
32
+ <y>55.8143826</y>
33
+ </polygon_2>
34
+ <polygon_3>
35
+ <x>37.626803</x>
36
+ <y>55.8144563</y>
37
+ </polygon_3>
38
+ </polygon>
39
+ </places_0>
40
+ <places_1>
41
+ <id>22293099</id>
42
+ <title>Звёздный бул., 28</title>
43
+ <language_id>1</language_id>
44
+ <language>ru</language>
45
+ <urlhtml>&lt;a class=&quot;wikimapia-link&quot; href=&quot;http://wikimapia.org/22293099/ru/Звёздный_бул.,_28&quot;&gt;Звёздный
46
+ бул., 28&lt;/a&gt;</urlhtml>
47
+ <distance>52</distance>
48
+ <location>
49
+ <north>55.8150601</north>
50
+ <south>55.814682</south>
51
+ <east>37.627384</east>
52
+ <west>37.6265592</west>
53
+ <lon>37.6269716</lon>
54
+ <lat>55.81487105</lat>
55
+ </location>
56
+ <polygon>
57
+ <polygon_0>
58
+ <x>37.627384</x>
59
+ <y>55.8149648</y>
60
+ </polygon_0>
61
+ <polygon_1>
62
+ <x>37.6272622</x>
63
+ <y>55.8150602</y>
64
+ </polygon_1>
65
+ <polygon_2>
66
+ <x>37.6265592</x>
67
+ <y>55.8147775</y>
68
+ </polygon_2>
69
+ <polygon_3>
70
+ <x>37.6266811</x>
71
+ <y>55.8146821</y>
72
+ </polygon_3>
73
+ </polygon>
74
+ </places_1>
75
+ <places_2>
76
+ <id>24813607</id>
77
+ <title>Звёздный бул., 32</title>
78
+ <language_id>1</language_id>
79
+ <language>ru</language>
80
+ <urlhtml>&lt;a class=&quot;wikimapia-link&quot; href=&quot;http://wikimapia.org/24813607/ru/Звёздный_бул.,_32&quot;&gt;Звёздный
81
+ бул., 32&lt;/a&gt;</urlhtml>
82
+ <distance>59</distance>
83
+ <location>
84
+ <north>55.8143134</north>
85
+ <south>55.8140949</south>
86
+ <east>37.6263735</east>
87
+ <west>37.6259416</west>
88
+ <lon>37.62615755</lon>
89
+ <lat>55.81420415</lat>
90
+ </location>
91
+ <polygon>
92
+ <polygon_0>
93
+ <x>37.6259416</x>
94
+ <y>55.8141854</y>
95
+ </polygon_0>
96
+ <polygon_1>
97
+ <x>37.6262581</x>
98
+ <y>55.8143135</y>
99
+ </polygon_1>
100
+ <polygon_2>
101
+ <x>37.6263735</x>
102
+ <y>55.8142201</y>
103
+ </polygon_2>
104
+ <polygon_3>
105
+ <x>37.626057</x>
106
+ <y>55.814095</y>
107
+ </polygon_3>
108
+ </polygon>
109
+ </places_2>
110
+ <places_3>
111
+ <id>22326504</id>
112
+ <title>Звёздный бул., 30, корпус 2</title>
113
+ <language_id>1</language_id>
114
+ <language>ru</language>
115
+ <urlhtml>&lt;a class=&quot;wikimapia-link&quot; href=&quot;http://wikimapia.org/22326504/ru/Звёздный_бул.,_30,_корпус_2&quot;&gt;Звёздный
116
+ бул., 30, корпус 2&lt;/a&gt;</urlhtml>
117
+ <distance>94</distance>
118
+ <location>
119
+ <north>55.8152643</north>
120
+ <south>55.8148002</south>
121
+ <east>37.6262838</east>
122
+ <west>37.6256102</west>
123
+ <lon>37.625947</lon>
124
+ <lat>55.81503225</lat>
125
+ </location>
126
+ <polygon>
127
+ <polygon_0>
128
+ <x>37.6262838</x>
129
+ <y>55.8148707</y>
130
+ </polygon_0>
131
+ <polygon_1>
132
+ <x>37.626107</x>
133
+ <y>55.8148003</y>
134
+ </polygon_1>
135
+ <polygon_2>
136
+ <x>37.6256102</x>
137
+ <y>55.815194</y>
138
+ </polygon_2>
139
+ <polygon_3>
140
+ <x>37.625787</x>
141
+ <y>55.8152644</y>
142
+ </polygon_3>
143
+ </polygon>
144
+ </places_3>
145
+ <places_4>
146
+ <id>22280394</id>
147
+ <title>Звёздный бул., 26, корпус 2</title>
148
+ <language_id>1</language_id>
149
+ <language>ru</language>
150
+ <urlhtml>&lt;a class=&quot;wikimapia-link&quot; href=&quot;http://wikimapia.org/22280394/ru/Звёздный_бул.,_26,_корпус_2&quot;&gt;Звёздный
151
+ бул., 26, корпус 2&lt;/a&gt;</urlhtml>
152
+ <distance>100</distance>
153
+ <location>
154
+ <north>55.8157029</north>
155
+ <south>55.8152389</south>
156
+ <east>37.6273834</east>
157
+ <west>37.6267099</west>
158
+ <lon>37.62704665</lon>
159
+ <lat>55.8154709</lat>
160
+ </location>
161
+ <polygon>
162
+ <polygon_0>
163
+ <x>37.6273834</x>
164
+ <y>55.8153093</y>
165
+ </polygon_0>
166
+ <polygon_1>
167
+ <x>37.6272066</x>
168
+ <y>55.8152389</y>
169
+ </polygon_1>
170
+ <polygon_2>
171
+ <x>37.6267099</x>
172
+ <y>55.8156325</y>
173
+ </polygon_2>
174
+ <polygon_3>
175
+ <x>37.6268867</x>
176
+ <y>55.8157029</y>
177
+ </polygon_3>
178
+ </polygon>
179
+ </places_4>
180
+ </places>
181
+ <found>0</found>
182
+ <count>5</count>
183
+ </wm>
@@ -0,0 +1,39 @@
1
+ require 'rspec'
2
+ describe 'My behaviour' do
3
+ before(:all) do
4
+ @key = "XXXX"
5
+ end
6
+
7
+ it 'should do something' do
8
+ loader = double("Geon::HttpLoader")
9
+ loader.stub(:get) { sample('wikimapia/place.getnearest__good.xml') }
10
+
11
+ wikimapia = Geon::Wikimapia.new(loader, @key)
12
+
13
+ places = wikimapia.place_getnearest(55.814447, 37.626651)
14
+
15
+
16
+ expected = {
17
+ id: 24434033,
18
+ title: 'Звёздный бул., 30, корпус 1',
19
+ language: 'ru',
20
+ distance: 10,
21
+ location: {
22
+ north: 55.8146558,
23
+ south: 55.8143825,
24
+ east: 37.626803,
25
+ west: 37.6263677,
26
+ lon: 37.62658535,
27
+ lat: 55.81451915},
28
+ polygon: [
29
+ {x: 37.6265575, y: 55.8146559},
30
+ {x: 37.6263677, y: 55.8145822},
31
+ {x: 37.6266132, y: 55.8143826},
32
+ {x: 37.626803, y: 55.8144563},
33
+ ],
34
+ }
35
+
36
+ places.should have(5).places
37
+ places[0].should eq expected
38
+ end
39
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geon
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alexander Suslov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Geo data provider
15
+ email:
16
+ - a.s.suslov@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - geon.gemspec
24
+ - lib/geon.rb
25
+ - lib/geon/http_loader.rb
26
+ - lib/geon/wikimapia.rb
27
+ - spec/helper.rb
28
+ - spec/samples/wikimapia/place.getnearest__good.xml
29
+ - spec/wikimapia_spec.rb
30
+ homepage: https://github.com/AlmazKo/geon
31
+ licenses:
32
+ - MIT
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 1.8.23
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Geo data provider
55
+ test_files:
56
+ - spec/wikimapia_spec.rb