terragona 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 88715c69977bde03e32967c508e4f4a519fecd03
4
- data.tar.gz: e3fc05839b11f705c3e38ddac17bff854fadb179
3
+ metadata.gz: bacfcba592bdf78f9891f8065d8f9e8172fe049c
4
+ data.tar.gz: 9c8baebb11ad0b66b27635bab3c1c2bd918e4902
5
5
  SHA512:
6
- metadata.gz: bc40ce6a147fdfa8e55eb838b6f1f911a68b821b2e59dfda30618c2b2738c9fbbd8048afacc0eacac8c01ad7851e427d678c30cc3108bf7c686e8792d02c5399
7
- data.tar.gz: 069423d4fee2ca209821cae9d2e1d43626e2e90b0dbe66a9edb0c8ee7fb1d1550dc297c338296a2d788fbaa737ce926ef409f7d20ea05ba6359c2429db37a891
6
+ metadata.gz: 21c854dbc451bf049243d910ee0276c4214583a1f97695f81bd7ec522058c53fe0577a284c3fe3f0c7740442f795702181d77acd5f7d9690d3adb90f02a54c3d
7
+ data.tar.gz: b693d2a52d5481d861fe279b158b41b9d31da88cde5a4155053146d743697c96bcc1f2b1cda3c6c1f949c8d67668cea3685bc3be0ad7d76d7627dbcfbe348fc6
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  terragona
2
2
  =========
3
3
 
4
- Create polygons for [GeoNames](http://www.geonames.org) places.
5
- This means: Create concave polygons using geonames places and store them in a postgres/postgis database.
4
+ Create polygons from [GeoNames](http://www.geonames.org) places or other sources.
5
+ This means: Create concave polygons using, i.e., geonames places and store them in a postgres/postgis database.
6
6
  See [ST_Concave_Hull](http://postgis.net/docs/ST_ConcaveHull.html).
7
7
 
8
8
  ![alt tag](https://cloud.githubusercontent.com/assets/6061036/5606205/2216ff3c-9402-11e4-9123-fff91369208e.png)
@@ -19,17 +19,25 @@ Install
19
19
 
20
20
  or add `gem 'terragona'` to your Gemfile
21
21
 
22
+ News
23
+ ----
24
+
25
+ * Classes API and Dump are now nested inside a `Geonames` class.
26
+
22
27
  Usage
23
28
  -----
24
29
 
25
30
  First, create a db in postgres and install the postgis extension.
26
31
 
27
- You can use the GeoNames API, with the Terragona::API class, or download
28
- a dump, (Terragona::Dump class) and specify the dump file path in opts. The API is faster
29
- but less accurate (max 1000 points per request). The dump is more accurate but much slower (please,
30
- use country dumps, not the world dump: it's to big -~9 million points- and could take lots of time.). For example:
31
- with the API, the Italy polygon is drawn using 1000 points. With the dump, the input is ~95.000 points.
32
- You can use the `max_points` option to limit this number.
32
+ Right now, as sources you can use:
33
+ * GeoNames API, with the `Terragona::Geonames::API` class,
34
+ * A Geonames dump, (`Terragona::Geonames::Dump` class) and specify the dump file path in opts.
35
+ * A CSV (`Terragona::CSVParser` class) (with headers: `name,x,y`)
36
+
37
+ The API is faster but less accurate than the dump (max 1000 points per request).
38
+ The dump is more accurate but much slower (please, use country dumps, not the world dump: it's to big
39
+ -~9 million points- and could take lots of time.). For example: with the API, the Italy polygon is drawn
40
+ using 1000 points. With the dump, the input is ~95.000 points. You can use the `max_points` option to limit this number.
33
41
 
34
42
  The slow part of the process is when points are filtered: the ones that are isolated are discarded.
35
43
  This has to be refactored.
@@ -46,13 +54,12 @@ opts = {...}
46
54
  countries=[{:name=>'Argentina',:fcode=>'PCLI',:country=>'AR'},
47
55
  {:name=>'Uruguay',:fcode=>'PCLI',:country=>'UY'}]
48
56
 
49
- terragona = Terragona::API.new(opts)
57
+ terragona = Terragona::Geonames::API.new(opts)
50
58
  terragona.create_polygons_family(countries, 'countries', 'countries_subdivisions')
51
59
 
52
60
  ```
53
61
 
54
62
  With Dump, and using returned children places
55
-
56
63
  ```ruby
57
64
  require 'terragona'
58
65
 
@@ -67,16 +74,36 @@ opts={
67
74
 
68
75
  italy=[{:name=>'Italy',:fcode=>'PCLI'}]
69
76
 
70
- terragona=Terragona::Dump.new(opts)
71
- result=terragona.create_polygons_family(italy,'italy','italian_regions')
77
+ terragona = Terragona::Geonames::Dump.new(opts)
78
+ result = terragona.create_polygons_family(italy,'italy','italian_regions')
72
79
 
73
- italian_rest=[]
80
+ italian_rest = []
74
81
  result.each {|r|
75
82
  italian_rest.concat(r[:children_places])
76
83
  }
77
84
  terragona.create_polygons_family(italian_rest,'province','comuni')
78
85
  ```
79
86
 
87
+ With the CSVParser class
88
+
89
+ ```ruby
90
+ require 'terragona'
91
+
92
+ opts={
93
+ :target_percent=> 0.85,
94
+ :max_distance_ratio=>1.6,
95
+ :db_username=>'mydbuser',
96
+ :db_password=>'mydbpsswd',
97
+ :db_name=>'mydb',
98
+ :csv_filename=>'/path/to/csv/IT.csv'}
99
+
100
+ italy=[] #Don't need input but the csv.
101
+
102
+ terragona = Terragona::CSVParser.new(opts)
103
+ terragona.create_polygons_family(italy,'italy','italian_regions')
104
+
105
+ ```
106
+
80
107
  Methods
81
108
  -------
82
109
 
@@ -86,6 +113,9 @@ create_polygons(<array of places>, options)
86
113
  create_polygons_family(<array of places>, <first order geometries table name>, <second order geometries table name>, options)
87
114
  ```
88
115
 
116
+ Important: **With the CSVParser class the initial array of places is not used**.
117
+ Terragona tries to create the parent polygon using all points.
118
+
89
119
  Each place in the array of places is a hash with this keys:
90
120
 
91
121
  ```
@@ -110,10 +140,11 @@ Options
110
140
  ```
111
141
  dump Only for Dump. Path to dump file.
112
142
  max_points Only for Dump. Max number of points to consider from
113
- dump file.
114
- default_country Default country.
143
+ dump file.
144
+ csv_filename Only for CSV.
145
+ default_country Default country. Only for Geonames.
115
146
  geonames_username Only for API. Geonames API username.
116
- use_cache Boolean. Default: false.
147
+ use_cache Boolean. Default: false.
117
148
  cache_expiration_time Default: 7200.
118
149
  projection Default: EPSG 4326 (WGS84).
119
150
  target_percent Require to draw the concave polygons.
@@ -1,3 +1,4 @@
1
+ require_relative './generic'
1
2
  require_relative './geonames'
2
3
  require_relative './concave_hull'
3
4
  require_relative './version'
@@ -12,23 +13,20 @@ module Terragona
12
13
  def create_polygons(names,options={})
13
14
  opts=@options.merge(options)
14
15
 
15
- concave_hull = ConcaveHull.new(opts) if not opts[:dont_create_polygons]
16
+ concave_hull = ConcaveHull.new(opts)
16
17
 
17
- names.map{|n|
18
- name = @geonames.search(n)
19
-
20
- if name[:points].count < @minimal_polygon_points
21
- puts "No points for #{n[:name]}"
22
- next
23
- end
18
+ if (!names or names.empty?) and @input.class == Generic::CSVParser
19
+ n = {:name => 'CSV'}
20
+ name = @input.search(n)
21
+ process_points(n,name,concave_hull,opts)
22
+ return [name]
23
+ end
24
24
 
25
- unless opts[:dont_create_polygons]
26
- if concave_hull.perform(name[:points],name[:place_name],name[:place_id])
27
- puts "Polygon created for #{n[:name]}"
28
- end
29
- end
25
+ names.map{|n|
26
+ name = @input.search(n)
27
+ next unless process_points(n,name,concave_hull,opts)
30
28
  name
31
- }
29
+ }.compact
32
30
  end
33
31
 
34
32
  def create_polygons_family(names,parents_table,children_table,opts={})
@@ -39,20 +37,49 @@ module Terragona
39
37
  }
40
38
  create_polygons(children,opts.merge({:table => children_table}))
41
39
  end
40
+
41
+ private
42
+ def process_points(n, name, concave_hull, opts)
43
+ if name[:points].count < @minimal_polygon_points
44
+ puts "No points for #{n[:name]}"
45
+ return
46
+ end
47
+
48
+ unless opts[:dont_create_polygons]
49
+ if concave_hull.perform(name[:points],name[:place_name],name[:place_id])
50
+ puts "Polygon created for #{n[:name]}"
51
+ end
52
+ end
53
+
54
+ # Thought the polygon might have not been created, we return true
55
+ # (so we retrieve it's children). The only case where we don't want the children is if
56
+ # there are no enough points.
57
+
58
+ true
59
+
60
+ end
42
61
  end
43
-
44
- class API < Base
45
- def initialize (options={})
46
- super
47
- @geonames = GeoNames::API.new(options)
62
+
63
+ class Geonames
64
+ class API < Base
65
+ def initialize (options={})
66
+ super
67
+ @input = GeoNames::API.new(options)
68
+ end
69
+ end
70
+
71
+ class Dump < Base
72
+ def initialize (options={})
73
+ super
74
+ @input = GeoNames::Dump.new(options)
75
+ end
48
76
  end
49
77
  end
50
-
51
- class Dump < Base
78
+
79
+ class CSVParser < Base
52
80
  def initialize (options={})
53
81
  super
54
- @geonames = GeoNames::Dump.new(options)
82
+ @input = Generic::CSVParser.new(options)
55
83
  end
56
84
  end
57
-
58
85
  end
@@ -59,10 +59,6 @@ module Terragona
59
59
  puts "Error with #{tags}, Id: #{id}, #{count} points."
60
60
  end
61
61
  end
62
-
63
- def drop_points_table(table)
64
- @db << "DROP TABLE IF EXISTS #{table};"
65
- end
66
62
 
67
63
  def filter_points_by_distance(points)
68
64
  random_points = points.count > 200 ? (0..200).map {|e|
@@ -92,7 +88,7 @@ module Terragona
92
88
  end
93
89
 
94
90
  def clean_str(str)
95
- str.gsub("'",' ')
91
+ str.to_s.gsub("'",' ')
96
92
  end
97
93
  end
98
94
  end
@@ -0,0 +1,41 @@
1
+ require 'csv'
2
+
3
+ module Terragona
4
+ module Generic
5
+ class CSVParser
6
+ def initialize(args = {})
7
+ filename = args[:csv_filename]
8
+
9
+ abort "Missing CSV filename. Aborting." unless filename
10
+
11
+ @csv = CSV.table(filename)
12
+ @id_counter = 0
13
+ end
14
+ def search(options = {})
15
+ @id_counter +=1
16
+
17
+ name = options[:name]
18
+
19
+ points = []
20
+
21
+ if name == 'CSV'
22
+ children = []
23
+
24
+ @csv.each {|p|
25
+ points.push({:x => p[:x], :y => p[:y]})
26
+ children.push({:name => p[:name]})
27
+ }
28
+
29
+ children.uniq!
30
+
31
+ children_places = (children.count > 1 )? children : []
32
+ else
33
+ @csv.select{|row| row[:name] == name}.each {|p| points.push({:x => p[:x], :y => p[:y]})}
34
+ children_places = []
35
+ end
36
+
37
+ {:children_places=>children_places, :points => points, :place_name=> name, :place_id=>@id_counter}
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module Terragona
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terragona
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Salerno
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-16 00:00:00.000000000 Z
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -151,6 +151,7 @@ files:
151
151
  - lib/terragona.rb
152
152
  - lib/terragona/base.rb
153
153
  - lib/terragona/concave_hull.rb
154
+ - lib/terragona/generic.rb
154
155
  - lib/terragona/geonames.rb
155
156
  - lib/terragona/version.rb
156
157
  - terragona.gemspec