mapplz 0.1.2 → 0.1.3
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.
- checksums.yaml +4 -4
- data/README.md +51 -3
- data/lib/mapplz.rb +274 -106
- metadata +2 -5
- data/app/assets/javascripts/mapplz/mapplz.js +0 -4
- data/app/assets/stylesheets/mapplz/mapplz.css.erb +0 -12
- data/app/views/mapplz/map.html.haml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5045761f3327fe2be26fb1769108ca424ab1689
|
4
|
+
data.tar.gz: 6cf61d9ec132edbd8911b73e0317681c3c68ec43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 872d06ba820f726ade5184ee11b6d1977009e8209a7b0792b900eb43180abceeffcf77f3096c4b24c1b29bdd8991614af4bcbc725bfe7d9f68e0961fddea30cd
|
7
|
+
data.tar.gz: ae3c23126048c4a306701e3cf64f22ce7184bb45ab3143fed845826194555bb289273110e51ebd0e7197e3074da82a53ed3a25b0c35cb55f26629f529d83320e
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ mapstore << [[point1, point2, point3]]
|
|
22
22
|
mapstore << [[point1, point2, point3, point1]]
|
23
23
|
mapstore << { path: [point1, point2], label: 'hello world' }
|
24
24
|
|
25
|
-
# GeoJSON string or
|
25
|
+
# GeoJSON string or hash
|
26
26
|
mapstore << { type: "Feature", geometry: { type: "Point", coordinates: [lng, lat] } }
|
27
27
|
```
|
28
28
|
|
@@ -51,6 +51,14 @@ You can output the data anytime as GeoJSON:
|
|
51
51
|
@mapper.to_geojson
|
52
52
|
```
|
53
53
|
|
54
|
+
Each mapped item can be exported as GeoJSON or WKT
|
55
|
+
|
56
|
+
```
|
57
|
+
pt = @mapper << { lat: 40, lng: -70 }
|
58
|
+
pt.to_wkt
|
59
|
+
pt.to_geojson
|
60
|
+
```
|
61
|
+
|
54
62
|
You can add interactive, HTML+JavaScript maps which use Leaflet.js
|
55
63
|
|
56
64
|
```
|
@@ -93,6 +101,9 @@ All of these would appear as clickable map features with popups:
|
|
93
101
|
All of these are valid ways to query geodata:
|
94
102
|
|
95
103
|
```
|
104
|
+
# return all
|
105
|
+
mapplz.query
|
106
|
+
|
96
107
|
# with a value
|
97
108
|
mapplz.where('layer = ?', name_of_layer)
|
98
109
|
|
@@ -101,6 +112,13 @@ mapplz.count
|
|
101
112
|
mapplz.count('layer = ?', name_of_layer)
|
102
113
|
```
|
103
114
|
|
115
|
+
Queries are returned as an array of GeoItems, which each can be exported as GeoJSON or WKT
|
116
|
+
|
117
|
+
```
|
118
|
+
my_features = @mapper.where('points > 10')
|
119
|
+
collection = { type: 'FeatureCollection', features: my_features.map { |feature| JSON.parse(feature.to_geojson) } }
|
120
|
+
```
|
121
|
+
|
104
122
|
## Databases
|
105
123
|
|
106
124
|
You can store geodata in SQLite/Spatialite, Postgres/PostGIS, or MongoDB.
|
@@ -118,6 +136,35 @@ mapplz.choose_db('postgis')
|
|
118
136
|
pt = mapstore << [lat, lng]
|
119
137
|
pt.name = "Sears Tower"
|
120
138
|
pt.save!
|
139
|
+
pt.delete_item
|
140
|
+
```
|
141
|
+
|
142
|
+
### Database Setup
|
143
|
+
|
144
|
+
```
|
145
|
+
# MongoDB
|
146
|
+
require 'mongo'
|
147
|
+
mongo_client = Mongo::MongoClient.new
|
148
|
+
database = mongo_client['mapplz']
|
149
|
+
collection = database['geoitems']
|
150
|
+
mapstore = MapPLZ.new(collection)
|
151
|
+
mapstore.choose_db('mongodb')
|
152
|
+
|
153
|
+
# PostGIS
|
154
|
+
require 'pg'
|
155
|
+
conn = PG.connect(dbname: 'your_db')
|
156
|
+
conn.exec('CREATE TABLE mapplz (id SERIAL PRIMARY KEY, label VARCHAR(30), geom public.geometry)')
|
157
|
+
mapstore = MapPLZ.new(conn)
|
158
|
+
mapstore.choose_db('postgis')
|
159
|
+
|
160
|
+
# Spatialite
|
161
|
+
require 'sqlite3'
|
162
|
+
db = SQLite3::Database.new('data/mapplz.sqlite')
|
163
|
+
db.execute(".load 'libspatialite.so'")
|
164
|
+
db.execute('CREATE TABLE mapplz (id INTEGER PRIMARY KEY AUTOINCREMENT, label VARCHAR(30), geom BLOB NOT NULL)')
|
165
|
+
db.execute("SELECT CreateSpatialIndex('mapplz', 'geom')")
|
166
|
+
mapstore = MapPLZ.new(db)
|
167
|
+
mapstore.choose_db('spatialite')
|
121
168
|
```
|
122
169
|
|
123
170
|
### COMING SOON
|
@@ -135,12 +182,13 @@ You can make a map super quickly by using the MapPLZ language. A MapPLZ map
|
|
135
182
|
can be described using as simply as this:
|
136
183
|
|
137
184
|
```
|
138
|
-
map
|
185
|
+
mymap = """map
|
139
186
|
marker
|
140
187
|
"The Statue of Liberty"
|
141
188
|
[40, -70]
|
142
189
|
plz
|
143
|
-
plz
|
190
|
+
plz"""
|
191
|
+
@mapper << mymap
|
144
192
|
```
|
145
193
|
|
146
194
|
## License
|
data/lib/mapplz.rb
CHANGED
@@ -8,11 +8,17 @@ include Leaflet::ViewHelpers
|
|
8
8
|
class MapPLZ
|
9
9
|
DATABASES = %w(array postgres postgresql postgis sqlite spatialite mongodb)
|
10
10
|
|
11
|
-
def initialize
|
11
|
+
def initialize(db = {})
|
12
12
|
@db_type = 'array'
|
13
|
-
@
|
13
|
+
@db_client = db
|
14
|
+
@db = {
|
15
|
+
client: @db_client,
|
16
|
+
type: @db_type
|
17
|
+
}
|
14
18
|
@my_array = []
|
15
19
|
|
20
|
+
@parser = SqlParser.new
|
21
|
+
|
16
22
|
choose_db(ActiveRecord::Base.connection.adapter_name) if defined?(ActiveRecord)
|
17
23
|
end
|
18
24
|
|
@@ -21,12 +27,32 @@ class MapPLZ
|
|
21
27
|
fail 'Database type not supported by MapPLZ' unless DATABASES.include?(db)
|
22
28
|
db = 'postgis' if db == 'postgres' || db == 'postgresql'
|
23
29
|
db = 'spatialite' if db == 'sqlite'
|
30
|
+
db = 'mongodb' if db == 'mongo'
|
24
31
|
@db_type = db
|
32
|
+
@db[:type] = db
|
25
33
|
end
|
26
34
|
|
27
35
|
def add(user_geo, lonlat = false)
|
28
36
|
geo_objects = standardize_geo(user_geo, lonlat)
|
29
|
-
|
37
|
+
|
38
|
+
if @db_type == 'array'
|
39
|
+
@my_array += geo_objects
|
40
|
+
elsif @db_type == 'mongodb'
|
41
|
+
geo_objects.each do |geo_object|
|
42
|
+
reply = @db_client.insert(geo_object)
|
43
|
+
geo_object[:_id] = reply.to_s
|
44
|
+
end
|
45
|
+
elsif @db_type == 'postgis' || @db_type == 'spatialite'
|
46
|
+
geo_objects.each do |geo_object|
|
47
|
+
geom = geo_object.to_wkt
|
48
|
+
if @db_type == 'postgis'
|
49
|
+
reply = @db_client.exec("INSERT INTO mapplz (label, geom) VALUES ('#{geo_object[:label] || ''}', ST_GeomFromText('#{geom}')) RETURNING id")
|
50
|
+
elsif @db_type == 'spatialite'
|
51
|
+
reply = @db_client.execute("INSERT INTO mapplz (label, geom) VALUES ('#{geo_object[:label] || ''}', AsText('#{geom}')) RETURNING id")
|
52
|
+
end
|
53
|
+
geo_object[:id] = reply[0]['id']
|
54
|
+
end
|
55
|
+
end
|
30
56
|
|
31
57
|
if geo_objects.length == 1
|
32
58
|
geo_objects[0]
|
@@ -39,26 +65,98 @@ class MapPLZ
|
|
39
65
|
results = query(where_clause, add_on)
|
40
66
|
if @db_type == 'array'
|
41
67
|
results.length
|
68
|
+
elsif @db_type == 'mongodb'
|
69
|
+
if where_clause.present?
|
70
|
+
# @db_client.find().count
|
71
|
+
else
|
72
|
+
@db_client.count
|
73
|
+
end
|
42
74
|
else
|
43
75
|
results.count
|
44
76
|
end
|
45
77
|
end
|
46
78
|
|
47
|
-
def query(where_clause, add_on = nil)
|
79
|
+
def query(where_clause = nil, add_on = nil)
|
48
80
|
if where_clause.present?
|
49
81
|
if @db_type == 'array'
|
50
|
-
query_array(where_clause, add_on)
|
82
|
+
geo_results = query_array(where_clause, add_on)
|
83
|
+
elsif @db_type == 'mongodb'
|
84
|
+
conditions = parse_sql(where_clause, add_on = nil)
|
85
|
+
mongo_conditions = {}
|
86
|
+
conditions.each do |condition|
|
87
|
+
field = condition[:field]
|
88
|
+
compare_value = add_on || condition[:value]
|
89
|
+
operator = condition[:operator].to_s
|
90
|
+
|
91
|
+
mongo_conditions[field] = compare_value if operator == '='
|
92
|
+
mongo_conditions[field] = { '$lt' => compare_value } if operator == '<'
|
93
|
+
mongo_conditions[field] = { '$lte' => compare_value } if operator == '<='
|
94
|
+
mongo_conditions[field] = { '$gt' => compare_value } if operator == '>'
|
95
|
+
mongo_conditions[field] = { '$gte' => compare_value } if operator == '>='
|
96
|
+
end
|
97
|
+
|
98
|
+
cursor = @db_client.find(mongo_conditions)
|
99
|
+
elsif @db_type == 'postgis' || @db_type == 'spatialite'
|
100
|
+
if add_on.is_a?(String)
|
101
|
+
where_clause = where_clause.gsub('?', "'#{add_on}'")
|
102
|
+
elsif add_on.is_a?(Integer) || add_on.is_a?(Float)
|
103
|
+
where_clause = where_clause.gsub('?', "#{add_on}")
|
104
|
+
end
|
105
|
+
|
106
|
+
cursor = @db_client.exec("SELECT id, ST_AsText(geom) AS geom, label FROM mapplz WHERE #{where_clause}") if @db_type == 'postgis'
|
107
|
+
cursor = @db_client.execute("SELECT id, AsText(geom) AS geom, label FROM mapplz WHERE #{where_clause}") if @db_type == 'spatialite'
|
51
108
|
else
|
52
109
|
# @my_db.where(where_clause, add_on)
|
53
110
|
end
|
54
111
|
else
|
55
|
-
#
|
112
|
+
# query all
|
56
113
|
if @db_type == 'array'
|
57
|
-
@my_array
|
114
|
+
geo_results = @my_array
|
115
|
+
elsif @db_type == 'mongodb'
|
116
|
+
cursor = @db_client.find
|
117
|
+
elsif @db_type == 'postgis'
|
118
|
+
cursor = @db_client.exec('SELECT id, ST_AsText(geom) AS geom, label FROM mapplz')
|
119
|
+
elsif @db_type == 'spatialite'
|
120
|
+
cursor = @db_client.execute('SELECT id, AsText(geom) AS geom, label FROM mapplz')
|
58
121
|
else
|
59
122
|
# @my_db.all
|
60
123
|
end
|
61
124
|
end
|
125
|
+
|
126
|
+
unless cursor.nil?
|
127
|
+
geo_results = []
|
128
|
+
cursor.each do |geo_result|
|
129
|
+
geo_item = GeoItem.new
|
130
|
+
geo_result.keys.each do |key|
|
131
|
+
next if [:geom].include?(key.to_sym)
|
132
|
+
geo_item[key.to_sym] = geo_result[key]
|
133
|
+
end
|
134
|
+
|
135
|
+
if @db_type == 'postgis' || @db_type == 'spatialite'
|
136
|
+
geom = (geo_result['geom'] || geo_result[:geom]).upcase
|
137
|
+
if geom.index('POINT')
|
138
|
+
coordinates = geom.gsub('POINT', '').gsub('(', '').gsub(')', '').split(' ')
|
139
|
+
geo_item[:lat] = coordinates[1].to_f
|
140
|
+
geo_item[:lng] = coordinates[0].to_f
|
141
|
+
elsif geom.index('LINESTRING')
|
142
|
+
line_nodes = geom.gsub('LINESTRING', '').gsub('(', '').gsub(')', '').split(',')
|
143
|
+
geo_item[:path] = line_nodes.map do |pt|
|
144
|
+
pt = pt.split(' ')
|
145
|
+
[pt[1].to_f, pt[0].to_f]
|
146
|
+
end
|
147
|
+
elsif geom.index('POLYGON')
|
148
|
+
line_nodes = geom.gsub('POLYGON', '').gsub('(', '').gsub(')', '').split(', ')
|
149
|
+
geo_item[:path] = line_nodes.map do |pt|
|
150
|
+
pt = pt.split(' ')
|
151
|
+
[pt[1].to_f, pt[0].to_f]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
geo_results << geo_item
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
geo_results
|
62
160
|
end
|
63
161
|
|
64
162
|
def code(mapplz_code)
|
@@ -74,13 +172,7 @@ class MapPLZ
|
|
74
172
|
end
|
75
173
|
|
76
174
|
def to_geojson
|
77
|
-
|
78
|
-
if @db_type == 'array'
|
79
|
-
@my_array.each do |feature|
|
80
|
-
feature_list << as_geojson(feature)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
geojson = { type: 'FeatureCollection', features: feature_list }
|
175
|
+
geojson = { type: 'FeatureCollection', features: query.map { |feature| JSON.parse(feature.to_geojson) } }
|
84
176
|
geojson.to_json
|
85
177
|
end
|
86
178
|
|
@@ -110,7 +202,7 @@ class MapPLZ
|
|
110
202
|
options[:markers] << { latlng: feature['geometry']['coordinates'].reverse, popup: label }
|
111
203
|
end
|
112
204
|
|
113
|
-
render_text = map(options)
|
205
|
+
render_text = map(options).gsub('</script>', '')
|
114
206
|
|
115
207
|
# add clickable lines and polygons after
|
116
208
|
# Leaflet-Rails does not support clickable lines or any polygons
|
@@ -151,18 +243,22 @@ class MapPLZ
|
|
151
243
|
flip_coordinates.map! { |coord| coord.reverse }
|
152
244
|
end
|
153
245
|
|
154
|
-
if feature['geometry']['type'] == '
|
246
|
+
if feature['geometry']['type'] == 'LineString'
|
155
247
|
render_text += ('line = L.polyline(' + flip_coordinates.to_json + ", #{path_options.to_json}).addTo(map);\n").html_safe
|
156
248
|
render_text += "line.bindPopup('#{label}');\n".html_safe unless label.nil?
|
157
249
|
elsif feature['geometry']['type'] == 'Polygon'
|
158
250
|
render_text += ('polygon = L.polygon(' + flip_coordinates[0].to_json + ", #{path_options.to_json}).addTo(map);\n").html_safe
|
159
251
|
render_text += "polygon.bindPopup('#{label}');\n".html_safe unless label.nil?
|
160
252
|
end
|
161
|
-
|
162
|
-
render_text
|
163
253
|
end
|
164
254
|
|
165
|
-
render_text
|
255
|
+
render_text + '</script>'
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.flip_path(path)
|
259
|
+
path.map! do |pt|
|
260
|
+
[pt[1].to_f, pt[0].to_f]
|
261
|
+
end
|
166
262
|
end
|
167
263
|
|
168
264
|
# alias methods
|
@@ -177,7 +273,7 @@ class MapPLZ
|
|
177
273
|
end
|
178
274
|
|
179
275
|
# aliases for query
|
180
|
-
def where(where_clause, add_on = nil)
|
276
|
+
def where(where_clause = nil, add_on = nil)
|
181
277
|
query(where_clause, add_on)
|
182
278
|
end
|
183
279
|
|
@@ -199,13 +295,32 @@ class MapPLZ
|
|
199
295
|
|
200
296
|
# internal map object record
|
201
297
|
class GeoItem < Hash
|
202
|
-
def initialize(db)
|
203
|
-
@
|
298
|
+
def initialize(db = { type: 'array', client: nil })
|
299
|
+
@db = db
|
300
|
+
@db_type = db[:type]
|
301
|
+
@db_client = db[:client]
|
204
302
|
end
|
205
303
|
|
206
304
|
def save!
|
207
305
|
# update record in database
|
208
|
-
|
306
|
+
if @db_type == 'mongodb'
|
307
|
+
consistent_id = self[:_id]
|
308
|
+
delete(:_id)
|
309
|
+
@db[:client].update({ _id: BSON::ObjectId(consistent_id) }, self)
|
310
|
+
self[:_id] = consistent_id
|
311
|
+
elsif @db_type == 'postgis' || @db_type == 'spatialite'
|
312
|
+
updaters = []
|
313
|
+
keys.each do |key|
|
314
|
+
next if [:id, :lat, :lng, :path, :type].include?(key)
|
315
|
+
updaters << "#{key} = '#{self[key]}'" if self[key].is_a?(String)
|
316
|
+
updaters << "#{key} = #{self[key]}" if self[key].is_a?(Integer) || self[key].is_a?(Float)
|
317
|
+
end
|
318
|
+
updaters << "geom = ST_GeomFromText('#{to_wkt}')" if @db_type == 'postgis'
|
319
|
+
updaters << "geom = AsText('#{to_wkt}')" if @db_type == 'spatialite'
|
320
|
+
if updaters.length > 0
|
321
|
+
@db_client.exec("UPDATE mapplz SET #{updaters.join(', ')} WHERE id = #{self[:id]}") if @db_type == 'postgis'
|
322
|
+
@db_client.execute("UPDATE mapplz SET #{updaters.join(', ')} WHERE id = #{self[:id]}") if @db_type == 'spatialite'
|
323
|
+
end
|
209
324
|
end
|
210
325
|
end
|
211
326
|
|
@@ -214,9 +329,69 @@ class MapPLZ
|
|
214
329
|
keys.each do |key|
|
215
330
|
delete(key)
|
216
331
|
end
|
217
|
-
|
332
|
+
elsif @db_type == 'mongodb'
|
218
333
|
# update record in database
|
334
|
+
@db[:client].remove(_id: BSON::ObjectId(self[:_id]))
|
335
|
+
elsif @db_type == 'postgis'
|
336
|
+
@db_client.exec("DELETE FROM mapplz WHERE id = #{self[:id]}")
|
337
|
+
elsif @db_type == 'spatialite'
|
338
|
+
@db_client.execute("DELETE FROM mapplz WHERE id = #{self[:id]}")
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def to_wkt
|
343
|
+
if self[:type] == 'point'
|
344
|
+
geom = "POINT(#{self[:lng]} #{self[:lat]})"
|
345
|
+
elsif self[:type] == 'polyline'
|
346
|
+
linestring = self[:path].map do |path_pt|
|
347
|
+
"#{path_pt[1]} #{path_pt[0]}"
|
348
|
+
end
|
349
|
+
geom = "LINESTRING(#{linestring.join(', ')})"
|
350
|
+
elsif self[:type] == 'polygon'
|
351
|
+
linestring = self[:path][0].map do |path_pt|
|
352
|
+
"#{path_pt[1]} #{path_pt[0]}"
|
353
|
+
end
|
354
|
+
geom = "POLYGON((#{linestring.join(', ')}))"
|
219
355
|
end
|
356
|
+
geom
|
357
|
+
end
|
358
|
+
|
359
|
+
def to_geojson
|
360
|
+
if key?(:properties)
|
361
|
+
property_list = { properties: self[:properties] }
|
362
|
+
else
|
363
|
+
property_list = self.clone
|
364
|
+
property_list.delete(:lat)
|
365
|
+
property_list.delete(:lng)
|
366
|
+
property_list.delete(:path)
|
367
|
+
property_list.delete(:type)
|
368
|
+
end
|
369
|
+
|
370
|
+
output_geo = {
|
371
|
+
type: 'Feature',
|
372
|
+
properties: property_list
|
373
|
+
}
|
374
|
+
|
375
|
+
if self[:type] == 'point'
|
376
|
+
# point
|
377
|
+
output_geo[:geometry] = {
|
378
|
+
type: 'Point',
|
379
|
+
coordinates: [self[:lng], self[:lat]]
|
380
|
+
}
|
381
|
+
elsif self[:type] == 'polyline'
|
382
|
+
# line
|
383
|
+
output_geo[:geometry] = {
|
384
|
+
type: 'LineString',
|
385
|
+
coordinates: MapPLZ.flip_path(self[:path])
|
386
|
+
}
|
387
|
+
elsif self[:type] == 'polygon'
|
388
|
+
# polygon
|
389
|
+
output_geo[:geometry] = {
|
390
|
+
type: 'Polygon',
|
391
|
+
coordinates: [MapPLZ.flip_path(self[:path])]
|
392
|
+
}
|
393
|
+
end
|
394
|
+
output_geo.to_json
|
220
395
|
end
|
221
396
|
end
|
222
397
|
|
@@ -266,21 +441,21 @@ class MapPLZ
|
|
266
441
|
if codeline.index('plz') || codeline.index('please')
|
267
442
|
|
268
443
|
if @code_level == 'marker'
|
269
|
-
geoitem = GeoItem.new(@
|
444
|
+
geoitem = GeoItem.new(@db)
|
270
445
|
geoitem[:lat] = @code_latlngs[0][0]
|
271
446
|
geoitem[:lng] = @code_latlngs[0][1]
|
272
447
|
geoitem[:label] = @code_label || ''
|
273
448
|
|
274
449
|
@code_layers << geoitem
|
275
450
|
elsif @code_level == 'line'
|
276
|
-
geoitem = GeoItem.new(@
|
451
|
+
geoitem = GeoItem.new(@db)
|
277
452
|
geoitem[:path] = @code_latlngs
|
278
453
|
geoitem[:stroke_color] = (@code_color || '')
|
279
454
|
geoitem[:label] = @code_label || ''
|
280
455
|
|
281
456
|
@code_layers << geoitem
|
282
457
|
elsif @code_level == 'shape'
|
283
|
-
geoitem = GeoItem.new(@
|
458
|
+
geoitem = GeoItem.new(@db)
|
284
459
|
geoitem[:paths] = @code_latlngs
|
285
460
|
geoitem[:stroke_color] = (@code_color || '')
|
286
461
|
geoitem[:fill_color] = (@code_color || '')
|
@@ -376,7 +551,7 @@ class MapPLZ
|
|
376
551
|
geo_type = 'polyline'
|
377
552
|
end
|
378
553
|
|
379
|
-
geoitem = GeoItem.new(@
|
554
|
+
geoitem = GeoItem.new(@db)
|
380
555
|
geoitem[:path] = path_pts
|
381
556
|
geoitem[:type] = geo_type
|
382
557
|
geoitem
|
@@ -398,7 +573,7 @@ class MapPLZ
|
|
398
573
|
validate_lng = user_geo[1].to_f != 0 || user_geo[1].to_s == '0'
|
399
574
|
|
400
575
|
if validate_lat && validate_lng
|
401
|
-
geo_object = GeoItem.new(@
|
576
|
+
geo_object = GeoItem.new(@db)
|
402
577
|
geo_object[:type] = 'point'
|
403
578
|
|
404
579
|
if lonlat
|
@@ -440,7 +615,7 @@ class MapPLZ
|
|
440
615
|
|
441
616
|
if validate_lat && validate_lng
|
442
617
|
# single hash
|
443
|
-
geo_object = GeoItem.new(@
|
618
|
+
geo_object = GeoItem.new(@db)
|
444
619
|
geo_object[:lat] = user_geo[validate_lat].to_f
|
445
620
|
geo_object[:lng] = user_geo[validate_lng].to_f
|
446
621
|
geo_object[:type] = 'point'
|
@@ -473,7 +648,7 @@ class MapPLZ
|
|
473
648
|
geo_type = 'polyline'
|
474
649
|
end
|
475
650
|
|
476
|
-
geoitem = GeoItem.new(@
|
651
|
+
geoitem = GeoItem.new(@db)
|
477
652
|
geoitem[:path] = path_pts
|
478
653
|
geoitem[:type] = geo_type
|
479
654
|
|
@@ -488,6 +663,16 @@ class MapPLZ
|
|
488
663
|
geo_objects << geoitem
|
489
664
|
else
|
490
665
|
# try GeoJSON
|
666
|
+
if user_geo.key?(:type)
|
667
|
+
user_geo['type'] = user_geo[:type] || ''
|
668
|
+
user_geo['features'] = user_geo[:features] if user_geo.key?(:features)
|
669
|
+
user_geo['properties'] = user_geo[:properties] || {}
|
670
|
+
if user_geo.key?(:geometry)
|
671
|
+
user_geo['geometry'] = user_geo[:geometry]
|
672
|
+
user_geo['geometry']['type'] = user_geo[:geometry][:type]
|
673
|
+
user_geo['geometry']['coordinates'] = user_geo[:geometry][:coordinates]
|
674
|
+
end
|
675
|
+
end
|
491
676
|
if user_geo.key?('type')
|
492
677
|
if user_geo['type'] == 'FeatureCollection' && user_geo.key?('features')
|
493
678
|
# recursive onto features
|
@@ -495,46 +680,68 @@ class MapPLZ
|
|
495
680
|
geo_objects += standardize_geo(feature)
|
496
681
|
end
|
497
682
|
elsif user_geo.key?('geometry') && user_geo['geometry'].key?('coordinates')
|
498
|
-
#
|
499
|
-
geo_object = GeoItem.new(@db_type)
|
683
|
+
# each feature
|
500
684
|
coordinates = user_geo['geometry']['coordinates']
|
501
|
-
if user_geo.key?('properties')
|
502
|
-
user_geo['properties'].keys.each do |key|
|
503
|
-
geo_object[key.to_sym] = user_geo['properties'][key]
|
504
|
-
end
|
505
|
-
end
|
506
685
|
|
507
686
|
if user_geo['geometry']['type'] == 'Point'
|
687
|
+
geo_object = GeoItem.new(@db)
|
508
688
|
geo_object[:lat] = coordinates[1].to_f
|
509
689
|
geo_object[:lng] = coordinates[0].to_f
|
510
690
|
geo_object[:type] = 'point'
|
691
|
+
geo_objects << geo_object
|
692
|
+
elsif user_geo['geometry']['type'] == 'LineString'
|
693
|
+
geo_object = GeoItem.new(@db)
|
694
|
+
MapPLZ.flip_path(coordinates)
|
695
|
+
geo_object[:path] = coordinates
|
696
|
+
geo_object[:type] = 'polyline'
|
697
|
+
geo_objects << geo_object
|
698
|
+
elsif user_geo['geometry']['type'] == 'Polygon'
|
699
|
+
geo_object = GeoItem.new(@db)
|
700
|
+
coordinates.map! do |ring|
|
701
|
+
MapPLZ.flip_path(ring)
|
702
|
+
end
|
703
|
+
geo_object[:path] = coordinates
|
704
|
+
geo_object[:type] = 'polygon'
|
705
|
+
geo_objects << geo_object
|
706
|
+
elsif user_geo['geometry']['type'] == 'MultiPoint'
|
707
|
+
coordinates.each do |point|
|
708
|
+
geo_object = GeoItem.new(@db)
|
709
|
+
geo_object[:lat] = point[1].to_f
|
710
|
+
geo_object[:lng] = point[0].to_f
|
711
|
+
geo_object[:type] = 'point'
|
712
|
+
geo_objects << geo_object
|
713
|
+
end
|
714
|
+
elsif user_geo['geometry']['type'] == 'MultiLineString'
|
715
|
+
coordinates.each do |line|
|
716
|
+
geo_object = GeoItem.new(@db)
|
717
|
+
geo_object[:path] = MapPLZ.flip_path(line)
|
718
|
+
geo_object[:type] = 'polyline'
|
719
|
+
geo_objects << geo_object
|
720
|
+
end
|
721
|
+
elsif user_geo['geometry']['type'] == 'MultiPolygon'
|
722
|
+
coordinates.each do |poly|
|
723
|
+
geo_object = GeoItem.new(@db)
|
724
|
+
poly.map! do |ring|
|
725
|
+
MapPLZ.flip_path(ring)
|
726
|
+
end
|
727
|
+
geo_object[:path] = poly
|
728
|
+
geo_object[:type] = 'polygon'
|
729
|
+
geo_objects << geo_object
|
730
|
+
end
|
511
731
|
end
|
512
732
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
user_geo[:features].each do |feature|
|
519
|
-
geo_objects += standardize_geo(feature)
|
520
|
-
end
|
521
|
-
elsif user_geo.key?(:geometry) && user_geo[:geometry].key?(:coordinates)
|
522
|
-
# individual feature
|
523
|
-
geo_object = GeoItem.new(@db_type)
|
524
|
-
coordinates = user_geo[:geometry][:coordinates]
|
525
|
-
if user_geo.key?(:properties)
|
526
|
-
user_geo[:properties].keys.each do |key|
|
527
|
-
geo_object[key.to_sym] = user_geo[:properties][key]
|
733
|
+
# store properties on all generated geometries
|
734
|
+
prop_keys = {}
|
735
|
+
if user_geo.key?('properties')
|
736
|
+
user_geo['properties'].keys.each do |key|
|
737
|
+
prop_keys[key.to_sym] = user_geo['properties'][key]
|
528
738
|
end
|
529
739
|
end
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
geo_object[:type] = 'point'
|
740
|
+
geo_objects.each do |geo|
|
741
|
+
prop_keys.keys.each do |key|
|
742
|
+
geo[key] = prop_keys[key]
|
743
|
+
end
|
535
744
|
end
|
536
|
-
|
537
|
-
geo_objects << geo_object
|
538
745
|
end
|
539
746
|
end
|
540
747
|
end
|
@@ -543,57 +750,18 @@ class MapPLZ
|
|
543
750
|
geo_objects
|
544
751
|
end
|
545
752
|
|
546
|
-
def
|
547
|
-
if geo_object.key?(:properties)
|
548
|
-
property_list = { properties: geo_object[:properties] }
|
549
|
-
else
|
550
|
-
property_list = geo_object.clone
|
551
|
-
property_list.delete(:lat)
|
552
|
-
property_list.delete(:lng)
|
553
|
-
property_list.delete(:path)
|
554
|
-
end
|
555
|
-
|
556
|
-
output_geo = {
|
557
|
-
type: 'Feature',
|
558
|
-
properties: property_list
|
559
|
-
}
|
560
|
-
|
561
|
-
if geo_object[:type] == 'point'
|
562
|
-
# point
|
563
|
-
output_geo[:geometry] = {
|
564
|
-
type: 'Point',
|
565
|
-
coordinates: [geo_object[:lng], geo_object[:lat]]
|
566
|
-
}
|
567
|
-
elsif geo_object[:type] == 'polyline'
|
568
|
-
# line
|
569
|
-
output_geo[:geometry] = {
|
570
|
-
type: 'Polyline',
|
571
|
-
coordinates: flip_path(geo_object[:path])
|
572
|
-
}
|
573
|
-
elsif geo_object[:type] == 'polygon'
|
574
|
-
# polygon
|
575
|
-
output_geo[:geometry] = {
|
576
|
-
type: 'Polygon',
|
577
|
-
coordinates: [flip_path(geo_object[:path])]
|
578
|
-
}
|
579
|
-
end
|
580
|
-
output_geo
|
581
|
-
end
|
582
|
-
|
583
|
-
def flip_path(path)
|
584
|
-
path.map! do |pt|
|
585
|
-
pt.reverse
|
586
|
-
end
|
587
|
-
end
|
588
|
-
|
589
|
-
def query_array(where_clause, add_on = nil)
|
590
|
-
# prepare where clause for parse
|
753
|
+
def parse_sql(where_clause, add_on = nil)
|
591
754
|
where_clause.downcase! unless where_clause.blank?
|
592
755
|
where_clause = where_clause.gsub('?', '\'?\'') if add_on.present?
|
593
756
|
where_clause = 'select * from bogus_table where ' + where_clause
|
594
757
|
|
595
758
|
# parse where conditions
|
596
|
-
|
759
|
+
@parser.parse(where_clause).tree[:conditions]
|
760
|
+
end
|
761
|
+
|
762
|
+
def query_array(where_clause, add_on = nil)
|
763
|
+
# prepare where clause for parse
|
764
|
+
conditions = parse_sql(where_clause, add_on)
|
597
765
|
|
598
766
|
# filter array
|
599
767
|
@my_array.select do |geo_obj|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mapplz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Doiron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -116,9 +116,6 @@ extensions: []
|
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
118
|
- lib/mapplz.rb
|
119
|
-
- app/assets/javascripts/mapplz/mapplz.js
|
120
|
-
- app/assets/stylesheets/mapplz/mapplz.css.erb
|
121
|
-
- app/views/mapplz/map.html.haml
|
122
119
|
- README.md
|
123
120
|
homepage: https://github.com/mapmeld/mapplz-ruby
|
124
121
|
licenses:
|
@@ -1 +0,0 @@
|
|
1
|
-
#main_map.mapplz
|