rats 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +181 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/lib/rats/base.rb +264 -0
- data/lib/rats/boundaries.rb +594 -0
- data/lib/rats/data/base.rb +89 -0
- data/lib/rats/data/meridian.rb +43 -0
- data/lib/rats/data/quarter.rb +67 -0
- data/lib/rats/data/range.rb +59 -0
- data/lib/rats/data/section.rb +134 -0
- data/lib/rats/data/township.rb +27 -0
- data/lib/rats/data.rb +10 -0
- data/lib/rats.rb +23 -0
- data/rats.gemspec +73 -0
- data/spec/data/data_spec.rb +122 -0
- data/spec/data/meridian_spec.rb +100 -0
- data/spec/data/quarter_spec.rb +76 -0
- data/spec/data/range_spec.rb +87 -0
- data/spec/data/section_spec.rb +111 -0
- data/spec/data/township_spec.rb +87 -0
- data/spec/rats_spec.rb +690 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +12 -0
- metadata +95 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mark
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
= rats
|
2
|
+
|
3
|
+
a.k.a. Ruby Alberta Township System
|
4
|
+
|
5
|
+
A ruby class to help with using the Alberta Township System
|
6
|
+
|
7
|
+
You may find it amusing that Alberta was Rat-free ... until now.
|
8
|
+
|
9
|
+
== ATS
|
10
|
+
|
11
|
+
Alberta Township system is a land survey grid used in Alberta, Canada that
|
12
|
+
divides the whole province into addressable locations.
|
13
|
+
|
14
|
+
A typical location looks like: NE 1-2-3 W4
|
15
|
+
|
16
|
+
Which can be broken down as follows ...
|
17
|
+
|
18
|
+
=== Meridian
|
19
|
+
|
20
|
+
from above example: [W4] West of the 4th Meridian
|
21
|
+
|
22
|
+
The Meridian is a constant line running perpendicular to the line of longitude,
|
23
|
+
and increments approx. every 4th line of longitude, from East to West.
|
24
|
+
|
25
|
+
Alberta contains 3 of these Meridians, W4 through W6.
|
26
|
+
|
27
|
+
=== Range
|
28
|
+
a.k.a Range Lines
|
29
|
+
|
30
|
+
from above example: [3]
|
31
|
+
|
32
|
+
The Range is the x-axis within the given Meridian. It increases East to West and
|
33
|
+
resets at the next Meridian. Each increase is approx. every 6 miles.
|
34
|
+
|
35
|
+
NOTE: The longitude lines are closer together the further North you get, so as
|
36
|
+
you go North, there is less Ranges from East to West.
|
37
|
+
|
38
|
+
=== Township
|
39
|
+
a.k.a. Township Lines
|
40
|
+
|
41
|
+
from above example: [2]
|
42
|
+
|
43
|
+
The Township is the y-axis with the Meridian. It increases South to North and
|
44
|
+
never resets, running from the Alberta-US border to the Northern border of Alberta.
|
45
|
+
Each increase is approx. every 6 miles.
|
46
|
+
|
47
|
+
NOTE: The 6x6 mile "square" indicated by the Township (line) + Range (line) +
|
48
|
+
Meridian is confusingly called a Township. So you have the Township line and
|
49
|
+
the 6x6 mile Township "square".
|
50
|
+
|
51
|
+
NOTE: Due to the longitude lines getting closer as you go North, there are small
|
52
|
+
correction made South to North which results in a non-uniform stacking of Townships.
|
53
|
+
Therefore you can not assume that going straight North from one Township to another
|
54
|
+
will result in a Township with the same Township-line number.
|
55
|
+
|
56
|
+
=== Section
|
57
|
+
|
58
|
+
from above example: [1]
|
59
|
+
|
60
|
+
The Section represents a number 1x1 miles "square" within the 6x6 mile Township.
|
61
|
+
There can be up to a maximum of 36 Sections in a township. The number starts with
|
62
|
+
1 in the South-East corner and travels West to number 6. It then increases to 7
|
63
|
+
North of number 6 and counts up West-to-East until the number 12. It snakes back
|
64
|
+
and forth until it finishes at number 36 in the North-East corner.
|
65
|
+
|
66
|
+
=== Quarter
|
67
|
+
a.k.a. Quarter Section
|
68
|
+
|
69
|
+
from above example: [NE]
|
70
|
+
|
71
|
+
The Quarter represents a 1/2 x 1/2 mile square within the 1x1 mile Section.
|
72
|
+
There can be 4 Quarters in a Section. They are identified by "NE", "NW", "SE"
|
73
|
+
and "SW".
|
74
|
+
|
75
|
+
== Purpose
|
76
|
+
|
77
|
+
The purpose of Rats is to make it easier to deal with location described using
|
78
|
+
the Alberta Township System, at the Quarter, Section or Township level.
|
79
|
+
|
80
|
+
=== Validation
|
81
|
+
|
82
|
+
Included is validations, only allowing you to describe locations that actually
|
83
|
+
exist.
|
84
|
+
|
85
|
+
For example, Range-line 30 is valid for Township-lines 1-18, but not 18-126.
|
86
|
+
|
87
|
+
=== Parsing
|
88
|
+
|
89
|
+
Included is string parsing, allowing you to extract and separate the different
|
90
|
+
fields from multiple string representations of the location.
|
91
|
+
|
92
|
+
For example, NE 1-2-3 W4 and 40300201NE are both recognized and parsed.
|
93
|
+
|
94
|
+
=== Display
|
95
|
+
|
96
|
+
Included is string creation that can create common representations of the
|
97
|
+
location.
|
98
|
+
|
99
|
+
=== Traversing
|
100
|
+
|
101
|
+
NOTE: This is experimental and can probably be improved and made more exact.
|
102
|
+
See 'Assumptions' to see where possible errors may exist.
|
103
|
+
|
104
|
+
In this case, traverse means go North, South, East or West of a given location
|
105
|
+
and know what the new location is.
|
106
|
+
|
107
|
+
Within a Township you can traverse any direction from:
|
108
|
+
- quarter to quarter
|
109
|
+
- quarter to section
|
110
|
+
- section to section
|
111
|
+
|
112
|
+
When leaving a Township, you can only traverse West and East from:
|
113
|
+
- quarter to quarter
|
114
|
+
- quarter to section
|
115
|
+
- quarter to township
|
116
|
+
- section to section
|
117
|
+
- section to township
|
118
|
+
- township to township
|
119
|
+
|
120
|
+
NOTE: The limitation in traversing from one Township to another is
|
121
|
+
due to correction lines and the nature that Townships due no run vertical
|
122
|
+
from North to South. It might be possible to include a way to allow this
|
123
|
+
but I do not currently need it.
|
124
|
+
|
125
|
+
= Usage
|
126
|
+
|
127
|
+
TODO: show examples
|
128
|
+
|
129
|
+
= Information
|
130
|
+
|
131
|
+
== links
|
132
|
+
|
133
|
+
http://en.wikipedia.org/wiki/Alberta_Township_System
|
134
|
+
|
135
|
+
== Road Map
|
136
|
+
|
137
|
+
Future:
|
138
|
+
- add support for Saskatchewan (no timeline)
|
139
|
+
- address bugs, if any
|
140
|
+
|
141
|
+
Except for the above, once this gem is finalized, I do not see future
|
142
|
+
development happening unless the North-South Township traversing needs
|
143
|
+
to be addressed or I want to add ATS to other-system conversions
|
144
|
+
(ie: latitude/longitude). Nothing else is planned.
|
145
|
+
|
146
|
+
Currently this point has not been reached and this gem is still in development.
|
147
|
+
|
148
|
+
== Assumptions
|
149
|
+
|
150
|
+
The only assumptions made are in respects to traversing. I do assume that
|
151
|
+
traversing within a township, that all sections and quarter sections are
|
152
|
+
perfectly aligned. If this is not correct, it must be pretty close, and
|
153
|
+
is close enough for my purpose.
|
154
|
+
|
155
|
+
I also assume that all townships are perfectly aligned from East to West.
|
156
|
+
|
157
|
+
Lastly, I assume that within every valid section, all four quarters are valid.
|
158
|
+
This may be the false. Even so, I do not have a list of which sections do not
|
159
|
+
have four quarters (let alone which ones are missing), so I couldn't do anything
|
160
|
+
about it anyway.
|
161
|
+
|
162
|
+
== Environment
|
163
|
+
|
164
|
+
This gem was created using:
|
165
|
+
- ruby 1.9.1-p378
|
166
|
+
- rspec 1.3.0
|
167
|
+
- rake 0.8.7
|
168
|
+
|
169
|
+
== Note on Patches/Pull Requests
|
170
|
+
|
171
|
+
* Fork the project.
|
172
|
+
* Make your feature addition or bug fix.
|
173
|
+
* Add tests for it. This is important so I don't break it in a
|
174
|
+
future version unintentionally.
|
175
|
+
* Commit, do not mess with rakefile, version, or history.
|
176
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
177
|
+
* Send me a pull request. Bonus points for topic branches.
|
178
|
+
|
179
|
+
== Copyright
|
180
|
+
|
181
|
+
Copyright (c) 2010 Mark. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rats"
|
8
|
+
gem.summary = "A ruby class to help with using the Alberta Township System"
|
9
|
+
gem.description = "A ruby class to help with using the Alberta Township System"
|
10
|
+
gem.email = "rats@attackcorp.com"
|
11
|
+
gem.homepage = "http://github.com/attack/rats"
|
12
|
+
gem.authors = ["Mark G"]
|
13
|
+
#gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec/rake/spectask'
|
22
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
spec.spec_opts = ["-c"]
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "rats #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/rats/base.rb
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
module Rats
|
2
|
+
class Base
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
return unless args.flatten!
|
6
|
+
@quarter = Rats::Quarter.new
|
7
|
+
@section = Rats::Section.new
|
8
|
+
@township = Rats::Township.new
|
9
|
+
@range = Rats::Range.new
|
10
|
+
@meridian = Rats::Meridian.new
|
11
|
+
if args.size == 1
|
12
|
+
parse_string(args.pop)
|
13
|
+
else
|
14
|
+
set_values(args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def q; @quarter; end
|
19
|
+
def s; @section; end
|
20
|
+
def t; @township; end
|
21
|
+
def r; @range; end
|
22
|
+
def m; @meridian; end
|
23
|
+
|
24
|
+
def q=(v); @quarter = v; end
|
25
|
+
def s=(v); @section = v; end
|
26
|
+
def t=(v); @township = v; end
|
27
|
+
def r=(v); @range = v; end
|
28
|
+
def m=(v); @meridian = v ; end
|
29
|
+
|
30
|
+
def quarter; @quarter.v; end
|
31
|
+
def section; @section.v; end
|
32
|
+
def township; @township.v; end
|
33
|
+
def range; @range.v; end
|
34
|
+
def meridian; @meridian.v; end
|
35
|
+
|
36
|
+
def quarter=(v); @quarter.v = v; end
|
37
|
+
def section=(v); @section.v = v; end
|
38
|
+
def township=(v); @township.v = v; end
|
39
|
+
def range=(v); @range.v = v; end
|
40
|
+
def meridian=(v); @meridian.v = v; end
|
41
|
+
|
42
|
+
def location(format = :long)
|
43
|
+
case format
|
44
|
+
when :short
|
45
|
+
short_location
|
46
|
+
when :long
|
47
|
+
long_location
|
48
|
+
else
|
49
|
+
long_location
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def location=(value)
|
54
|
+
return unless value
|
55
|
+
if value.is_a?(Array)
|
56
|
+
set_values(value)
|
57
|
+
else
|
58
|
+
parse_string(value)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
long_location
|
64
|
+
end
|
65
|
+
|
66
|
+
def scope
|
67
|
+
if self.meridian && self.range && self.township
|
68
|
+
if self.section
|
69
|
+
if self.quarter
|
70
|
+
:quarter
|
71
|
+
else
|
72
|
+
:section
|
73
|
+
end
|
74
|
+
else
|
75
|
+
:township
|
76
|
+
end
|
77
|
+
else
|
78
|
+
:unknown
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid?
|
83
|
+
self.meridian && self.range && self.township && self.exists?
|
84
|
+
end
|
85
|
+
|
86
|
+
# test that a location actually exists
|
87
|
+
#
|
88
|
+
def exists?
|
89
|
+
# make sure meridian exists
|
90
|
+
return false unless TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian]
|
91
|
+
|
92
|
+
# make sure range exists
|
93
|
+
return false unless TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian][self.range]
|
94
|
+
|
95
|
+
# make sure township exists
|
96
|
+
return false unless TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian][self.range][:townships].include?(self.township)
|
97
|
+
|
98
|
+
# make sure section exists
|
99
|
+
|
100
|
+
# it is possible all sections exists for all townships
|
101
|
+
if TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian][self.range].has_key?(:sections)
|
102
|
+
# NO, now see if this township has valid sections
|
103
|
+
if TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian][self.range][:sections].has_key?(self.township)
|
104
|
+
# YES, check further to see that this section is listed
|
105
|
+
return TOWNSHIPS_BY_RANGE_AND_MERIDIAN[self.meridian][self.range][:sections][self.township].include?(self.section)
|
106
|
+
else
|
107
|
+
# the township isn't listed, therefore it has all sections
|
108
|
+
return true
|
109
|
+
end
|
110
|
+
else
|
111
|
+
# looks like we exist
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def up(level=nil); self.traverse(:up, level); end
|
117
|
+
def down(level=nil); self.traverse(:down, level); end
|
118
|
+
def left(level=nil); self.traverse(:left, level); end
|
119
|
+
def right(level=nil); self.traverse(:right, level); end
|
120
|
+
alias north up
|
121
|
+
alias south down
|
122
|
+
alias west left
|
123
|
+
alias east right
|
124
|
+
|
125
|
+
# this just walks from location to location in the given direction until
|
126
|
+
# it finds the next valid location.
|
127
|
+
#
|
128
|
+
def traverse(direction, level=nil)
|
129
|
+
return unless direction
|
130
|
+
|
131
|
+
new_location = self.dup
|
132
|
+
# change the scope of the traverse
|
133
|
+
# eg. allow quarter section to traverse to a section
|
134
|
+
#
|
135
|
+
case level
|
136
|
+
when :section
|
137
|
+
# we are traversing by section, remove quarter
|
138
|
+
new_location.q.nil!
|
139
|
+
when :township
|
140
|
+
# we are traversing by section, remove quarter & section
|
141
|
+
new_location.q.nil!
|
142
|
+
new_location.s.nil!
|
143
|
+
end
|
144
|
+
|
145
|
+
the_scope = new_location.scope
|
146
|
+
begin
|
147
|
+
case the_scope
|
148
|
+
when :quarter
|
149
|
+
new_location._traverse_quarter(direction)
|
150
|
+
when :section
|
151
|
+
new_location._traverse_section(direction)
|
152
|
+
when :township
|
153
|
+
new_location._traverse_range(direction)
|
154
|
+
end
|
155
|
+
end until new_location.valid?
|
156
|
+
new_location
|
157
|
+
end
|
158
|
+
|
159
|
+
def _traverse_quarter(direction)
|
160
|
+
begin
|
161
|
+
self.q = self.q.send(direction)
|
162
|
+
rescue OutOfSection
|
163
|
+
self.q = self.q.send(direction.to_s + '!')
|
164
|
+
self._traverse_section(direction)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def _traverse_section(direction)
|
169
|
+
begin
|
170
|
+
self.s = self.s.send(direction)
|
171
|
+
rescue OutOfTownship
|
172
|
+
self.s = self.s.send(direction.to_s + '!')
|
173
|
+
self._traverse_range(direction)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def _traverse_range(direction)
|
178
|
+
begin
|
179
|
+
self.r = self.r.send(direction)
|
180
|
+
rescue OutOfMeridian
|
181
|
+
self.r = self.r.send(direction.to_s + '!')
|
182
|
+
self._traverse_meridian(direction)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def _traverse_meridian(direction)
|
187
|
+
begin
|
188
|
+
self.m = self.m.send(direction)
|
189
|
+
rescue
|
190
|
+
raise OutOfAlberta
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def to_a
|
195
|
+
[self.quarter, self.section, self.township, self.range, self.meridian].compact
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def parse_string(location)
|
201
|
+
return unless location.respond_to?('to_s')
|
202
|
+
|
203
|
+
case location_type?(location)
|
204
|
+
when :description
|
205
|
+
parse_description(location)
|
206
|
+
when :parcel_id
|
207
|
+
parse_parcel_id(location)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def location_type?(location)
|
212
|
+
location.to_s.match(/^\d{8}\D{2}/) ? :parcel_id : :description
|
213
|
+
end
|
214
|
+
|
215
|
+
def parse_description(description)
|
216
|
+
quarter = description.to_s.scan(/^\D{2}/)
|
217
|
+
self.quarter = quarter[0].upcase if quarter && quarter.size > 0
|
218
|
+
|
219
|
+
numbers = description.to_s.scan(/\d{1,3}/)
|
220
|
+
if numbers
|
221
|
+
self.meridian = numbers.pop.to_i if numbers.size > 0
|
222
|
+
self.range = numbers.pop.to_i if numbers.size > 0
|
223
|
+
self.township = numbers.pop.to_i if numbers.size > 0
|
224
|
+
self.section = numbers.pop.to_i if numbers.size > 0
|
225
|
+
end
|
226
|
+
true
|
227
|
+
end
|
228
|
+
|
229
|
+
def parse_parcel_id(parcel_id)
|
230
|
+
result = parcel_id.to_s.scan(/^(\d{1})(\d{2})(\d{3})(\d{2})(\D{2})/)
|
231
|
+
return unless result && result.size > 0
|
232
|
+
numbers = result.pop
|
233
|
+
self.meridian = numbers.shift.to_i if numbers.size > 0
|
234
|
+
self.range = numbers.shift.to_i if numbers.size > 0
|
235
|
+
self.township = numbers.shift.to_i if numbers.size > 0
|
236
|
+
self.section = numbers.shift.to_i if numbers.size > 0
|
237
|
+
self.quarter = numbers.shift.to_s if numbers.size > 0
|
238
|
+
true
|
239
|
+
end
|
240
|
+
|
241
|
+
def set_values(values)
|
242
|
+
#self.quarter = values.shift
|
243
|
+
self.quarter = values.shift.to_s if values.size > 0
|
244
|
+
self.section = values.shift.to_i if values.size > 0
|
245
|
+
self.township = values.shift.to_i if values.size > 0
|
246
|
+
self.range = values.shift.to_i if values.size > 0
|
247
|
+
self.meridian = values.shift.to_i if values.size > 0
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
def long_location
|
252
|
+
if self.quarter
|
253
|
+
"#{@quarter.to_s} #{[@section.to_s,@township.to_s,@range.to_s].compact.join('-')} #{@meridian.to_s}".strip
|
254
|
+
else
|
255
|
+
"#{[@section.to_s,@township.to_s,@range.to_s].compact.join('-')} #{@meridian.to_s}".strip
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def short_location
|
260
|
+
[@quarter.to_p,@section.to_p,@township.to_p,@range.to_p,@meridian.to_p].compact.join('').strip
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
end
|