chilean_cities 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +674 -0
- data/README.md +133 -0
- data/Rakefile +43 -0
- data/lib/chilean_cities.rb +7 -0
- data/lib/chilean_cities/comuna.rb +27 -0
- data/lib/chilean_cities/comunas_list.rb +14 -0
- data/lib/chilean_cities/factory.rb +46 -0
- data/lib/chilean_cities/provincia.rb +23 -0
- data/lib/chilean_cities/provincia_part.rb +11 -0
- data/lib/chilean_cities/provincias_list.rb +14 -0
- data/lib/chilean_cities/region.rb +27 -0
- data/lib/chilean_cities/region_part.rb +6 -0
- data/lib/chilean_cities/version.rb +3 -0
- data/lib/schemas/place.rb +10 -0
- data/lib/schemas/thing.rb +6 -0
- data/spec/factories/comunas.rb +10 -0
- data/spec/factories/provincias.rb +9 -0
- data/spec/factories/regiones.rb +10 -0
- data/spec/lib/chilean_cities/comuna_spec.rb +67 -0
- data/spec/lib/chilean_cities/factory_spec.rb +46 -0
- data/spec/lib/chilean_cities/provincia_spec.rb +59 -0
- data/spec/lib/chilean_cities/region_spec.rb +66 -0
- data/spec/lib/chilean_cities_spec.rb +5 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/factory_girl.rb +18 -0
- data/spec/support/schemas/README.md +13 -0
- data/spec/support/schemas/spec_for_administrative_area_interface.rb +6 -0
- data/spec/support/schemas/spec_for_city_interface.rb +6 -0
- data/spec/support/schemas/spec_for_place_interface.rb +14 -0
- data/spec/support/schemas/spec_for_state_interface.rb +6 -0
- data/spec/support/schemas/spec_for_thing_interface.rb +8 -0
- data/spec/support/spec_for_list_of_comunas_interface.rb +22 -0
- data/spec/support/spec_for_list_of_provincias_interface.rb +24 -0
- data/spec/support/spec_for_part_of_provincia_interface.rb +14 -0
- data/spec/support/spec_for_part_of_region_interface.rb +12 -0
- metadata +190 -0
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
Comunas de Chile
|
2
|
+
================
|
3
|
+
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/chilean_cities.svg)](http://badge.fury.io/rb/chilean_cities)
|
5
|
+
[![Build Status](https://api.travis-ci.org/gonzalo-bulnes/chilean_cities.png?branch=master)](https://travis-ci.org/gonzalo-bulnes/chilean_cities)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/gonzalo-bulnes/chilean_cities.png)](https://codeclimate.com/github/gonzalo-bulnes/chilean_cities)
|
7
|
+
[![Inline docs](http://inch-ci.org/github/gonzalo-bulnes/chilean_cities.svg?branch=master)](http://inch-ci.org/github/gonzalo-bulnes/chilean_cities)
|
8
|
+
|
9
|
+
A Ruby representation of the Chilean _administrative areas_ as described by the [SUBDERE][subdere].
|
10
|
+
|
11
|
+
[subdere]: http://www.subdere.gov.cl
|
12
|
+
|
13
|
+
Disclaimer
|
14
|
+
----------
|
15
|
+
|
16
|
+
This library is not developed, supported nor endorsed in any way by the Chilean [Subsecretaría de Desarrollo Regional y Administrativo (SUBDERE)][subdere], nor any related institution.
|
17
|
+
|
18
|
+
Data Sources
|
19
|
+
------------
|
20
|
+
|
21
|
+
This library is based on the publicly available information from the SUBDERE related to the [Codificación Única Territorial][source]. The sources quoted by [the document on which this library is based][ref] are:
|
22
|
+
|
23
|
+
- Decreto Supremo No 1439, del Ministerio del Interior, publicado en el Diario Oficial del 8 de Mayo de 2000
|
24
|
+
- Decreto Supremo No 1352, del Ministerio del Interior, publicado en el Diario Oficial del 23 de Agosto de 2008
|
25
|
+
- Decreto Exento No 910, del Ministerio del Interior, publicado en el Diario Oficial del 14 de Junio de 2007
|
26
|
+
- Decreto Exento No 817, del Ministerio del Interior, publicado en el Diario Oficial del 26 de Marzo de 2010
|
27
|
+
|
28
|
+
[source]: http://www.subdere.gov.cl/documentacion/regiones-provincias-y-comunas-de-chile
|
29
|
+
[ref]: http://www.subdere.gov.cl/sites/default/files/documentos/articles-73111_recurso_2.pdf
|
30
|
+
|
31
|
+
Usage
|
32
|
+
-----
|
33
|
+
|
34
|
+
Add the gem to your Gemfile:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# Gemfile
|
38
|
+
|
39
|
+
gem 'chilean_cities', '~> 1.0' # see semver.org
|
40
|
+
```
|
41
|
+
|
42
|
+
Then generate the chilean administrative areas:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
require 'chilean_cities'
|
46
|
+
|
47
|
+
chile = ChileanCities::Factory.instance
|
48
|
+
|
49
|
+
chile.generate!
|
50
|
+
|
51
|
+
# and use them as you want : )
|
52
|
+
|
53
|
+
chile.regiones.select{ |region| region.iso_3166_2 == 'CL-LL' }.first.name
|
54
|
+
# => "Región de los Lagos"
|
55
|
+
|
56
|
+
chile.provincias.select{ |provincia| provincia.name =~ /Magallanes/ }.first.comunas.map{ |comuna| comuna.name }
|
57
|
+
# => ["Punta Arenas", "Laguna Blanca", "Río Verde", "San Gregorio"]
|
58
|
+
```
|
59
|
+
|
60
|
+
### Schema.org
|
61
|
+
|
62
|
+
The generated administrative areas representations do _partially_ enforce the **Place schema** (see [schema.org][schema] and [the schemas specs][schema-specs] for details):
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
# comunas, provincias and regiones do implement the `contained_in` method:
|
66
|
+
|
67
|
+
chile.comunas.select{ |comuna| comuna.name == 'Quellón' }.first.contained_in.name
|
68
|
+
# => "Chiloé"
|
69
|
+
```
|
70
|
+
|
71
|
+
[schema]: http://schema.org
|
72
|
+
[schema-specs]: spec/support/schemas
|
73
|
+
|
74
|
+
**Note about the previous version** (`v0.1.0`)
|
75
|
+
|
76
|
+
If you were using this gem in the past and are looking for its ancient behaviour, please modify your `Gemfile` to checkout the `v0.1.0` tag (it's been a few years, so this is not recommended):
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
# Gemfile
|
80
|
+
|
81
|
+
gem 'chilean_cities', git: 'https://github.com/gonzalo-bulnes/chilean_cities.git', tag: 'v0.1.0'
|
82
|
+
```
|
83
|
+
The same tag does also [point to the corresponding documentation][deprecated-doc].
|
84
|
+
|
85
|
+
[deprecated-doc]: https://github.com/gonzalo-bulnes/chilean_cities/blob/v0.1.0/README.md
|
86
|
+
|
87
|
+
Code of Conduct
|
88
|
+
---------------
|
89
|
+
|
90
|
+
Please note that by participating in this project, you agree to abide by its [code of conduct]. That is true for pull requests, and also when participating in issues.
|
91
|
+
|
92
|
+
[code of conduct]: ./CODE_OF_CONDUCT.md
|
93
|
+
|
94
|
+
See Also
|
95
|
+
--------
|
96
|
+
|
97
|
+
- The Wikipedia article about the [ISO 3166-2][iso] standard
|
98
|
+
- Comunas de Chile ([gist][json]) (a Ruby on Rails seed and a JSON document)
|
99
|
+
- The Schema.org [AdministrativeArea schema][schema]
|
100
|
+
- An interesting overview of [how the administrative areas can be categorized for mapping][administrative_mapping]
|
101
|
+
- The [OpenStreetMap relations][osm_boundaries] corresponding to the described administrative areas
|
102
|
+
|
103
|
+
[iso]: https://en.wikipedia.org/wiki/ISO_3166-2:CL
|
104
|
+
[json]: https://gist.github.com/gonzalo-bulnes/337ea1e916e3890fdefa
|
105
|
+
[schema]: http://schema.org/AdministrativeArea
|
106
|
+
[administrative_mapping]: http://wiki.openstreetmap.org/wiki/Tag:admin%20level=8?uselang=en-US
|
107
|
+
[osm_boundaries]: http://www.openstreetmap.org/relation/164609
|
108
|
+
|
109
|
+
Credits
|
110
|
+
-------
|
111
|
+
|
112
|
+
Part of this gem was crafted during my 10% _free focus_ work time at [Acid Labs][acidlabs]. Thanks @acidlabs!
|
113
|
+
|
114
|
+
[acidlabs]: https://github.com/acidlabs
|
115
|
+
|
116
|
+
License
|
117
|
+
-------
|
118
|
+
|
119
|
+
ChileanCities provides a Ruby representation of the Chilean _administrative areas_.
|
120
|
+
Copyright (C) 2013, 2020 Gonzalo Bulnes Guilpain
|
121
|
+
|
122
|
+
This program is free software: you can redistribute it and/or modify
|
123
|
+
it under the terms of the GNU General Public License as published by
|
124
|
+
the Free Software Foundation, either version 3 of the License, or
|
125
|
+
(at your option) any later version.
|
126
|
+
|
127
|
+
This program is distributed in the hope that it will be useful,
|
128
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
129
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
130
|
+
GNU General Public License for more details.
|
131
|
+
|
132
|
+
You should have received a copy of the GNU General Public License
|
133
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'Provide private interfaces documentation'
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
namespace :spec do
|
10
|
+
desc 'Provide public interfaces documentation'
|
11
|
+
RSpec::Core::RakeTask.new(:public) do |t|
|
12
|
+
t.rspec_opts = "--tag public"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
namespace :spec do
|
17
|
+
desc 'Provide private interfaces documentation for development purpose'
|
18
|
+
RSpec::Core::RakeTask.new(:development) do |t|
|
19
|
+
t.rspec_opts = "--tag protected --tag private"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
desc 'RSpec rake task not available'
|
24
|
+
task :spec do
|
25
|
+
abort 'RSpec rake task is not available. Be sure to install rspec-core as a gem or plugin'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'inch/rake'
|
31
|
+
|
32
|
+
Inch::Rake::Suggest.new(:inch) do |suggest|
|
33
|
+
suggest.args << "--private"
|
34
|
+
suggest.args << "--pedantic"
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
desc 'Inch rake task not available'
|
38
|
+
task :inch do
|
39
|
+
abort 'Inch rake task is not available. Be sure to install inch as a gem or plugin'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => ['spec:public', 'spec:development', :inch]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
require 'chilean_cities/provincia_part'
|
4
|
+
require 'chilean_cities/region_part'
|
5
|
+
require 'schemas/place'
|
6
|
+
|
7
|
+
module ChileanCities
|
8
|
+
|
9
|
+
class Comuna
|
10
|
+
include ActiveModel::Model
|
11
|
+
|
12
|
+
include ProvinciaPart
|
13
|
+
include RegionPart
|
14
|
+
include Schemas::Place
|
15
|
+
|
16
|
+
attr_accessor :code
|
17
|
+
|
18
|
+
def initialize(*args)
|
19
|
+
@name = args.shift
|
20
|
+
@code = args.shift
|
21
|
+
@provincia = args.shift
|
22
|
+
@region = args.shift
|
23
|
+
end
|
24
|
+
|
25
|
+
validates_presence_of :code, :name
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ChileanCities
|
2
|
+
module ComunasList
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
raise NotImplementedError, 'ComunasList must implement initialize()'
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :comunas
|
9
|
+
|
10
|
+
def append_comuna(comuna)
|
11
|
+
@comunas << comuna unless @comunas.include? comuna
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module ChileanCities
|
4
|
+
|
5
|
+
class Factory
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
attr_reader :regiones
|
9
|
+
attr_reader :provincias
|
10
|
+
attr_reader :comunas
|
11
|
+
|
12
|
+
def generate!
|
13
|
+
|
14
|
+
@regiones = []
|
15
|
+
@provincias = []
|
16
|
+
@comunas = []
|
17
|
+
|
18
|
+
data_file = File.read('data/comunas.json')
|
19
|
+
|
20
|
+
data = MultiJson.load(data_file, symbolize_keys: true)
|
21
|
+
|
22
|
+
data.each do |datum|
|
23
|
+
comuna = Comuna.new(datum[:name], datum[:code])
|
24
|
+
|
25
|
+
provincia = @provincias.select { |provincia| provincia.name == datum[:provincia] }.first ||
|
26
|
+
Provincia.new(datum[:provincia])
|
27
|
+
|
28
|
+
region = @regiones.select { |region| region.name == datum[:region] }.first ||
|
29
|
+
Region.new(datum[:region], datum[:region_iso_3166_2])
|
30
|
+
|
31
|
+
comuna.region = region
|
32
|
+
comuna.provincia = comuna.contained_in = provincia
|
33
|
+
@comunas << comuna unless @comunas.include? comuna
|
34
|
+
|
35
|
+
provincia.region = provincia.contained_in = region
|
36
|
+
provincia.append_comuna(comuna)
|
37
|
+
@provincias << provincia unless @provincias.include? provincia
|
38
|
+
|
39
|
+
region.append_comuna(comuna)
|
40
|
+
region.append_provincia(provincia)
|
41
|
+
@regiones << region unless @regiones.include? region
|
42
|
+
end
|
43
|
+
{ comunas_count: @comunas.count, provincias_count: @provincias.count, regiones_count: @regiones.count }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
require 'chilean_cities/comunas_list'
|
4
|
+
require 'chilean_cities/region_part'
|
5
|
+
|
6
|
+
module ChileanCities
|
7
|
+
|
8
|
+
class Provincia
|
9
|
+
include ActiveModel::Model
|
10
|
+
|
11
|
+
include ComunasList
|
12
|
+
include RegionPart
|
13
|
+
include Schemas::Place
|
14
|
+
|
15
|
+
def initialize(*args)
|
16
|
+
@name = args.shift
|
17
|
+
@comunas = []
|
18
|
+
@region = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
validates_presence_of :name
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ChileanCities
|
2
|
+
module ProvinciasList
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
raise NotImplementedError, 'ProvinciasList must implement initialize()'
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :provincias
|
9
|
+
|
10
|
+
def append_provincia(provincia)
|
11
|
+
@provincias << provincia unless @provincias.include? provincia
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
require 'chilean_cities/comunas_list'
|
4
|
+
require 'chilean_cities/provincias_list'
|
5
|
+
|
6
|
+
module ChileanCities
|
7
|
+
|
8
|
+
class Region
|
9
|
+
include ActiveModel::Model
|
10
|
+
|
11
|
+
include ComunasList
|
12
|
+
include ProvinciasList
|
13
|
+
include Schemas::Place
|
14
|
+
|
15
|
+
attr_accessor :iso_3166_2
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
@name = args.shift
|
19
|
+
@iso_3166_2 = args.shift
|
20
|
+
@comunas = []
|
21
|
+
@provincias = []
|
22
|
+
end
|
23
|
+
|
24
|
+
validates_presence_of :iso_3166_2, :name
|
25
|
+
validates_format_of :iso_3166_2, with: /\ACL-[A-Z][A-Z]\z/ # ISO 3166-2:CL
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChileanCities::Comuna do
|
4
|
+
|
5
|
+
describe 'provides a Schema.org interface', public: true do
|
6
|
+
it_behaves_like 'a City'
|
7
|
+
end
|
8
|
+
|
9
|
+
it_behaves_like 'part of a ChileanCities::Provincia'
|
10
|
+
|
11
|
+
it 'responds to :code', public: true do
|
12
|
+
expect(subject).to respond_to :code
|
13
|
+
end
|
14
|
+
|
15
|
+
# validations
|
16
|
+
|
17
|
+
it 'has a valid factory', private: true do
|
18
|
+
expect(FactoryGirl.build(:comuna)).to be_valid
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'requires a name', private: true do
|
22
|
+
expect(FactoryGirl.build(:comuna, name: nil)).not_to be_valid
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'requires a code', private: true do
|
26
|
+
expect(FactoryGirl.build(:comuna, code: nil)).not_to be_valid
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#provincia', data: true, private: true do
|
30
|
+
|
31
|
+
it 'returns a ChileanCities::Provincia' do
|
32
|
+
chile = ChileanCities::Factory.instance
|
33
|
+
chile.generate!
|
34
|
+
|
35
|
+
subject = chile.comunas.sample
|
36
|
+
|
37
|
+
expect(subject.provincia).not_to be_nil
|
38
|
+
expect(subject.provincia).to be_instance_of ChileanCities::Provincia
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#region', data: true, private: true do
|
43
|
+
|
44
|
+
it 'returns a ChileanCities::Region' do
|
45
|
+
chile = ChileanCities::Factory.instance
|
46
|
+
chile.generate!
|
47
|
+
|
48
|
+
subject = chile.comunas.sample
|
49
|
+
|
50
|
+
expect(subject.region).not_to be_nil
|
51
|
+
expect(subject.region).to be_instance_of ChileanCities::Region
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#contained_in', data: true, private: true do
|
56
|
+
|
57
|
+
it 'returns a ChileanCities::Provincia' do
|
58
|
+
chile = ChileanCities::Factory.instance
|
59
|
+
chile.generate!
|
60
|
+
|
61
|
+
subject = chile.comunas.sample
|
62
|
+
|
63
|
+
expect(subject.contained_in).not_to be_nil
|
64
|
+
expect(subject.contained_in).to be_instance_of ChileanCities::Provincia
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|