Module: HasGeoLookup::DataCoverage
Overview
Utilities for analyzing geographic data coverage and availability
This module provides methods to check the availability of GeoBoundaries.org and Geonames.org data for different countries. These utilities are gem-ready and don't depend on any specific application models or business logic.
Instance Method Summary collapse
-
#boundary_coverage_by_level(iso2) ⇒ Hash
Get detailed boundary coverage by ADM level for a country.
-
#coverage_status(iso2) ⇒ Hash
Get comprehensive coverage status for a country.
-
#has_boundary_data?(iso2, level = nil) ⇒ Boolean
Check if boundary data exists for a country.
-
#has_geonames_data?(iso2) ⇒ Boolean
Check if geonames data exists for a country.
-
#missing_adm_levels(iso2) ⇒ Array<String>
Get list of missing ADM levels for a country.
Instance Method Details
#boundary_coverage_by_level(iso2) ⇒ Hash
Get detailed boundary coverage by ADM level for a country
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
# File 'lib/has_geo_lookup/concern.rb', line 820 def boundary_coverage_by_level(iso2) # Special cases for territories territories_without_boundaries = %w[PR VI GU AS MP TC] if territories_without_boundaries.include?(iso2) return %w[ADM1 ADM2 ADM3 ADM4 ADM5].index_with { |_| 1 } # Assume coverage end # Convert ISO2 to ISO3 country = Iso3166.for_code(iso2) return {} unless country iso3 = country.code3 # Count boundaries by level for this country boundaries_by_level = Geoboundary.where("shape_iso LIKE ? OR shape_group LIKE ?", "%#{iso3}%", "%#{iso3}%") .group(:level) .count # Ensure all ADM levels are represented (with 0 counts for missing) %w[ADM1 ADM2 ADM3 ADM4 ADM5].index_with do |level| boundaries_by_level[level] || 0 end end |
#coverage_status(iso2) ⇒ Hash
Get comprehensive coverage status for a country
882 883 884 885 886 887 888 889 890 891 892 893 894 895 |
# File 'lib/has_geo_lookup/concern.rb', line 882 def coverage_status(iso2) boundaries = has_boundary_data?(iso2) geonames = has_geonames_data?(iso2) boundary_coverage = boundary_coverage_by_level(iso2) missing_levels = missing_adm_levels(iso2) { boundaries: boundaries, geonames: geonames, complete: boundaries && geonames && missing_levels.empty?, boundary_coverage: boundary_coverage, missing_adm_levels: missing_levels } end |
#has_boundary_data?(iso2, level = nil) ⇒ Boolean
Check if boundary data exists for a country
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 |
# File 'lib/has_geo_lookup/concern.rb', line 795 def has_boundary_data?(iso2, level = nil) # Special cases for territories that don't have separate boundary data territories_without_boundaries = %w[PR VI GU AS MP TC] # US territories + others return true if territories_without_boundaries.include?(iso2) # Convert ISO2 to ISO3 to check boundaries country = Iso3166.for_code(iso2) return true unless country # If we can't convert, assume it exists to avoid infinite loops iso3 = country.code3 # Build query for boundaries with optional level filter query = Geoboundary.where("shape_iso LIKE ? OR shape_group LIKE ?", "%#{iso3}%", "%#{iso3}%") query = query.where(level: level) if level query.exists? end |
#has_geonames_data?(iso2) ⇒ Boolean
Check if geonames data exists for a country
860 861 862 863 864 865 866 867 |
# File 'lib/has_geo_lookup/concern.rb', line 860 def has_geonames_data?(iso2) # Special cases for territories that might not have separate geonames data territories_without_separate_geonames = %w[PR VI GU AS MP] # US territories return true if territories_without_separate_geonames.include?(iso2) # Check if we have geonames data for this country Geoname.where(country_code: iso2).exists? end |
#missing_adm_levels(iso2) ⇒ Array<String>
Get list of missing ADM levels for a country
851 852 853 854 |
# File 'lib/has_geo_lookup/concern.rb', line 851 def missing_adm_levels(iso2) coverage = boundary_coverage_by_level(iso2) coverage.select { |_level, count| count == 0 }.keys end |