Class: Geoboundary
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Geoboundary
- Defined in:
- lib/has_geo_lookup/models/geoboundary.rb
Overview
Administrative boundary geometries from GeoBoundaries.org
This model stores precise administrative boundary polygons from GeoBoundaries.org, providing accurate geometric shapes for countries, states, counties, and municipalities worldwide. Each boundary includes PostGIS geometry data for spatial queries and containment testing.
GeoBoundaries provides multiple administrative levels:
- ADM0: Country boundaries
- ADM1: State/province boundaries (e.g., California, Ontario)
- ADM2: County/district boundaries (e.g., Los Angeles County)
- ADM3: Municipality boundaries (e.g., city limits)
- ADM4: Neighborhood/ward boundaries
- ADM5: Sub-neighborhood boundaries (city blocks, micro-districts)
The boundary geometries are stored using PostGIS and can be used for precise point-in-polygon queries to determine administrative containment.
Instance Attribute Summary collapse
-
#boundary ⇒ RGeo::Geos::CAPIGeometryMethods
PostGIS geometry (polygon/multipolygon).
-
#level ⇒ String
Administrative level (ADM0, ADM1, ADM2, ADM3, ADM4, ADM5).
-
#name ⇒ String
Official boundary name.
-
#shape_group ⇒ String
Grouping identifier for related boundaries.
-
#shape_iso ⇒ String
ISO3 country code for this boundary.
Instance Method Summary collapse
-
#area_km2 ⇒ Float
Calculate the area of this boundary in square kilometers.
-
#centroid ⇒ Array<Float>?
Get the centroid (center point) of this boundary.
-
#contains_point?(latitude, longitude) ⇒ Boolean
Check if this boundary contains the given coordinates.
-
#country? ⇒ Boolean
Check if this is a country-level boundary.
-
#county_district? ⇒ Boolean
Check if this is a county/district-level boundary.
-
#display_name ⇒ String
Returns a human-readable description of this boundary.
-
#municipality? ⇒ Boolean
Check if this is a municipality-level boundary.
-
#neighborhood? ⇒ Boolean
Check if this is a neighborhood-level boundary.
-
#state_province? ⇒ Boolean
Check if this is a state/province-level boundary.
-
#sub_neighborhood? ⇒ Boolean
Check if this is a sub-neighborhood-level boundary.
Instance Attribute Details
#boundary ⇒ RGeo::Geos::CAPIGeometryMethods
PostGIS geometry (polygon/multipolygon)
34 35 36 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 34 def boundary @boundary end |
#level ⇒ String
Administrative level (ADM0, ADM1, ADM2, ADM3, ADM4, ADM5)
34 35 36 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 34 def level @level end |
#name ⇒ String
Official boundary name
34 35 36 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 34 def name @name end |
#shape_group ⇒ String
Grouping identifier for related boundaries
34 35 36 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 34 def shape_group @shape_group end |
#shape_iso ⇒ String
ISO3 country code for this boundary
34 35 36 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 34 def shape_iso @shape_iso end |
Instance Method Details
#area_km2 ⇒ Float
Calculate the area of this boundary in square kilometers
Uses PostGIS ST_Area function with spheroid calculations for accurate area computation on the Earth's surface.
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 96 def area_km2 return nil unless boundary area_m2 = self.class.connection.select_value( "SELECT ST_Area(ST_Transform(ST_GeomFromText(?), 3857))", boundary.to_s ) area_m2 ? (area_m2 / 1_000_000).round(2) : nil rescue => e Rails.logger.warn "Error calculating boundary area: #{e.}" nil end |
#centroid ⇒ Array<Float>?
Get the centroid (center point) of this boundary
Uses PostGIS ST_Centroid function to find the geometric center of the boundary polygon.
120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 120 def centroid return nil unless boundary result = self.class.connection.select_one( "SELECT ST_Y(ST_Centroid(ST_GeomFromText(?))) AS lat, ST_X(ST_Centroid(ST_GeomFromText(?))) AS lng", boundary.to_s, boundary.to_s ) result ? [result['lat'].to_f, result['lng'].to_f] : nil rescue => e Rails.logger.warn "Error calculating boundary centroid: #{e.}" nil end |
#contains_point?(latitude, longitude) ⇒ Boolean
Check if this boundary contains the given coordinates
Uses MySQL ST_Contains function to perform precise geometric containment testing against the boundary polygon.
72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 72 def contains_point?(latitude, longitude) return false unless latitude && longitude && boundary point_wkt = "POINT(#{latitude} #{longitude})" self.class.connection.select_value( "SELECT ST_Contains(ST_GeomFromText(?), ST_GeomFromText(?, 4326)) AS contains", boundary.to_s, point_wkt ) == 1 rescue => e Rails.logger.warn "Error checking point containment: #{e.}" false end |
#country? ⇒ Boolean
Check if this is a country-level boundary
163 164 165 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 163 def country? level == "ADM0" end |
#county_district? ⇒ Boolean
Check if this is a county/district-level boundary
175 176 177 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 175 def county_district? level == "ADM2" end |
#display_name ⇒ String
Returns a human-readable description of this boundary
Includes the boundary name, administrative level, and country context for clear identification.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 144 def display_name level_description = case level when "ADM0" then "Country" when "ADM1" then "State/Province" when "ADM2" then "County/District" when "ADM3" then "Municipality" when "ADM4" then "Neighborhood/Ward" when "ADM5" then "Sub-Neighborhood/Block" else level end country_info = extract_country_from_shape_iso country_suffix = country_info ? ", #{country_info}" : "" "#{name} (#{level} - #{level_description}#{country_suffix})" end |
#municipality? ⇒ Boolean
Check if this is a municipality-level boundary
181 182 183 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 181 def municipality? level == "ADM3" end |
#neighborhood? ⇒ Boolean
Check if this is a neighborhood-level boundary
187 188 189 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 187 def neighborhood? level == "ADM4" end |
#state_province? ⇒ Boolean
Check if this is a state/province-level boundary
169 170 171 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 169 def state_province? level == "ADM1" end |
#sub_neighborhood? ⇒ Boolean
Check if this is a sub-neighborhood-level boundary
193 194 195 |
# File 'lib/has_geo_lookup/models/geoboundary.rb', line 193 def sub_neighborhood? level == "ADM5" end |