geon 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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