Class GeonamesUtility


  • public class GeonamesUtility
    extends java.lang.Object
    Author:
    ubaldino
    • Constructor Summary

      Constructors 
      Constructor Description
      GeonamesUtility()
      A utility class that offers many static routines; If you instantiate this class it will require metadata files for country-names and feature-codes in your classpath
    • Method Summary

      Modifier and Type Method Description
      protected void addLang​(java.lang.String langOrLocale, java.lang.String cc)  
      static int approximateLongitudeForUTCOffset​(int utc)
      This helps get the general area +/-5 degrees for a given UTC offset.
      java.util.Collection<java.lang.String> countriesInDSTOffset​(double dst)
      This check only makes sense if you have date/time which is in a period of daylight savings.
      java.util.Collection<java.lang.String> countriesInTimezone​(java.lang.String tz)
      List all countries in a particular TZ
      java.util.Collection<java.lang.String> countriesInUTCOffset​(double utc)
      List all countries in a particular UTC offset; These are usually -15.0 to 15.0 every 0.5 or 0.25 hrs.
      java.util.Collection<java.lang.String> countriesSpeaking​(java.lang.String lang)
      Examples: what countries speak french (fr)? what countries speak Rwandan French? (fr-RW)?
      boolean countrySpeaks​(java.lang.String lang, java.lang.String cc)
      Is language spoken in country ID'd by cc? See TextUtils for list of langauges provided by Library of Congress.
      java.lang.String FIPS2ISO​(java.lang.String fips)
      Find an ISO code for a given FIPS entry.
      java.util.List<Place> getAdmin1Metadata()
      Deprecated.
      Use getUSStateMetadata
      Place getAdmin1Place​(java.lang.String cc, java.lang.String adm1)
      Retrieve a Place object with the semi-official name (in Latin/Anglo terms) given CC and ADM1 code.
      Place getAdmin1PlaceByHASC​(java.lang.String path)
      Lookup by coded path, CC.ADM1.
      java.util.List<Country> getCountries()  
      Country getCountry​(java.lang.String isocode)
      Get Country by the default ISO digraph returns the Unknown country if you are not using an ISO2 code.
      Country getCountryByAnyCode​(java.lang.String cc)
      Find distinct country object by a code.
      Country getCountryByFIPS​(java.lang.String fips)  
      java.lang.String getDefaultCountryName​(java.lang.String cc_iso2)
      Finds a default country name for a CC if one exists.
      static java.lang.String getFeatureDesignation​(java.lang.String cls, java.lang.String code)  
      java.lang.String getFeatureName​(java.lang.String cls, java.lang.String code)
      Find a readable name or description of a class/code
      static java.lang.String getHASC​(java.lang.String c, java.lang.String adm1)
      Get a hiearchical path for a boundar or a place.
      static java.lang.String getHASC​(java.lang.String c, java.lang.String adm1, java.lang.String adm2)  
      java.util.Map<java.lang.String,​Country> getISOCountries()
      List all country names, official and variant names.
      protected static java.lang.String getLang​(java.lang.String langid)
      Parse lang ID from Locale.
      Place getProvince​(java.lang.String cc, java.lang.String adm1)
      Lookup by coded path, CC.ADM1.
      java.util.List<Place> getProvinceMetadata()
      Alias for getWorldAdmin1Metadata.
      java.util.List<Place> getUSStateMetadata()
      Provides access to a array of ADM1 metadata.
      java.util.List<Place> getWorldAdmin1Metadata()
      Get the array of Place objects representing ADM1 level boundaries.
      static boolean isAbbreviation​(char name_type)
      Check if name type is an Abbreviation
      static boolean isAbbreviation​(Place p)
      Wrapper for isAbbreviation(name type)
      static boolean isAdmin1​(java.lang.String featCode)
      Is this Place a State or Province?
      static boolean isAdmin1​(Place p)  
      static boolean isAdmin2​(java.lang.String featCode)  
      static boolean isAdministrative​(java.lang.String featClass)
      if a place or feature represents an administrative boundary.
      static boolean isCode​(char name_type)  
      static boolean isCountry​(java.lang.String featCode)
      Is this Place a Country?
      static boolean isCountry​(Place p)
      Wrapper for isCountry(feat code)
      static boolean isCountryNameCollision​(java.lang.String nm)
      Experimental.
      static boolean isLand​(java.lang.String fc)  
      static boolean isName​(char name_type)
      Check if name type is an Abbreviation
      static boolean isNationalCapital​(java.lang.String featCode)
      Is this Place a National Capital?
      static boolean isNationalCapital​(Place p)
      wrapper for isNationalCaptial( feat code )
      static boolean isPoliticalEntity​(java.lang.String featCode)
      Test if a feature is a political entity ~ country, territory, sovereign land
      static boolean isPoliticalEntity​(Place p)
      Test is Place feature is coded as PCL* (PCL, PCLIX, PCLH, PCLD, PCLF, PCLS, etc)
      static boolean isPopulated​(java.lang.String featClass)  
      static boolean isPostal​(java.lang.String fc)  
      static boolean isPostal​(Place g)  
      boolean isPrimaryLanguage​(java.lang.String lang, java.lang.String cc)
      If lang is primary lang.
      static boolean isSpot​(java.lang.String fc)  
      static boolean isUpperAdminLevel​(java.lang.String featCode)
      Macro for reasoning with upper common levels of boundaries - province, districts.
      static boolean isValue​(java.lang.String s)  
      java.util.Collection<java.lang.String> languagesInCountry​(java.lang.String cc)  
      void loadCountryLanguages()
      Parse metadata from geonames.org (file in CLASSPATH @ /geonames.org/countryInfo.txt) and populate existing Country objects with language metadata.
      static java.util.List<Place> loadMajorCities​(java.io.InputStream strm)
      Load the Geonames.org majorcities data file.
      static java.util.List<Place> loadMajorCities​(java.lang.String resourcePath)
      Geonames.org data set: citiesN.txt
      void loadUSStateMetadata()
      TODO: This is mildly informed by geonames.org, however even there we are still missing a mapping between ADM1 FIPS/ISO codes for a state and the Postal codes/abbreviations.
      void loadWorldAdmin1Metadata()
      Source: geonames.org ADM1 codes/names in anglo/ASCII form.
      static java.util.Map<java.lang.String,​Place> mapMajorCityIDs​(java.util.List<Place> cities)
      Convenience: prepare a map for lookup by ID.
      static java.util.Map<java.lang.String,​java.lang.Integer> mapPopulationByLocation​(java.util.List<Place> cities)
      See mapPopulationByLocation(list, int).
      static java.util.Map<java.lang.String,​java.lang.Integer> mapPopulationByLocation​(java.util.List<Place> cities, int ghResolution)
      This organizes population data by geohash.
      static java.lang.String normalizeAdminCode​(java.lang.String v)
      Convert and ADM1 or ADM2 id to a normalized form.
      static java.lang.String normalizeCountryName​(java.lang.String c)
      This may help revert to a more readable country name, e.g., if you are given upper case name and you want some version of it as a proper name But no need to use this if you have good reference data.
      java.lang.String primaryLangID​(java.lang.String cc)
      When lang ID will do.
      Language primaryLanguage​(java.lang.String cc)
      Primary language for a given country.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • UNK_Country

        public static final Country UNK_Country
      • COUNTRY_ADM0

        public static final java.util.Set<java.lang.String> COUNTRY_ADM0
      • COUNTRY_ADM0_NORM

        public static final java.lang.String COUNTRY_ADM0_NORM
        See Also:
        Constant Field Values
      • KNOWN_NAME_COLLISIONS

        public static final java.util.Map<java.lang.String,​java.lang.String> KNOWN_NAME_COLLISIONS
        Experimental. A trivial way of looking at mapping well-known name collisions to country codes
      • unknownLanguages

        public final java.util.HashSet<java.lang.String> unknownLanguages
        Given Country code (ISO2) list all language locales and primary languages spoken there. E.g., If 'en-AU' is spoken in Sydney Australia, then they at least speak some form of English ('en') as well as the local australian dialect. MAP: cc ===> set( l1, l2, l3...) KEYS: uppercase
    • Constructor Detail

      • GeonamesUtility

        public GeonamesUtility()
                        throws java.io.IOException
        A utility class that offers many static routines; If you instantiate this class it will require metadata files for country-names and feature-codes in your classpath
        Throws:
        java.io.IOException - if metadata files are not found or do not load.
    • Method Detail

      • normalizeCountryName

        public static java.lang.String normalizeCountryName​(java.lang.String c)
        This may help revert to a more readable country name, e.g., if you are given upper case name and you want some version of it as a proper name But no need to use this if you have good reference data.
        Parameters:
        c - country name
        Returns:
        capitalize the name of a country
      • getFeatureDesignation

        public static java.lang.String getFeatureDesignation​(java.lang.String cls,
                                                             java.lang.String code)
      • getFeatureName

        public java.lang.String getFeatureName​(java.lang.String cls,
                                               java.lang.String code)
        Find a readable name or description of a class/code
        Parameters:
        cls - feature class, e.g., P
        code - feature code, e.g., PPL
        Returns:
        name for a feature/code pair
      • approximateLongitudeForUTCOffset

        public static int approximateLongitudeForUTCOffset​(int utc)
        This helps get the general area +/-5 degrees for a given UTC offset. UTC offsets range from -12.00 to +14.00. This covers 360deg of planet over a 24 hour day. Each offset hour covers about 15deg. Any answer you get here is likely best used with a range of fuziness, e.g., +/- 5deg. REFERENCE: https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
        Parameters:
        utc - UTC offset
        Returns:
        approximated longitude, in degrees
      • countriesInTimezone

        public java.util.Collection<java.lang.String> countriesInTimezone​(java.lang.String tz)
        List all countries in a particular TZ
        Parameters:
        tz - TZ name
        Returns:
        list of country codes
      • countriesInUTCOffset

        public java.util.Collection<java.lang.String> countriesInUTCOffset​(double utc)
        List all countries in a particular UTC offset; These are usually -15.0 to 15.0 every 0.5 or 0.25 hrs.
        Parameters:
        utc - offset in decimal hours
        Returns:
        list of country codes found with the offset
      • countriesInDSTOffset

        public java.util.Collection<java.lang.String> countriesInDSTOffset​(double dst)
        This check only makes sense if you have date/time which is in a period of daylight savings. Then the UTC offset for that period can be used to see which countries adhere to that DST convention. E.g., Boston and New York US standard time: GMT-0500, DST: GMT-0400
        Parameters:
        dst - DST offset
        Returns:
        list of country codes observing DST at that offset
        See Also:
        countriesInUTCOffset(double)
      • isValue

        public static boolean isValue​(java.lang.String s)
      • loadMajorCities

        public static java.util.List<Place> loadMajorCities​(java.lang.String resourcePath)
                                                     throws java.io.IOException
        Geonames.org data set: citiesN.txt
        Parameters:
        resourcePath - CLASSPATH location of a resource.
        Returns:
        list of places
        Throws:
        java.io.IOException - if resource file is not found
      • mapMajorCityIDs

        public static java.util.Map<java.lang.String,​Place> mapMajorCityIDs​(java.util.List<Place> cities)
        Convenience: prepare a map for lookup by ID. If these are geonames.org place objects then the geonames IDs do not line up with those curated within OpenSextant Gazetteer geonames.org cities data is usually unique by row, so if you provide 1000 cities in a list your map will have 1000 city place IDs in the map. No duplicates expected.
        Parameters:
        cities - arra of Place objects
        Returns:
        map of place ID to Place object
      • mapPopulationByLocation

        public static java.util.Map<java.lang.String,​java.lang.Integer> mapPopulationByLocation​(java.util.List<Place> cities)
        See mapPopulationByLocation(list, int). Default geohash prefix length is 5, which yields about 6km grids or so.
        Parameters:
        cities - list of major cities
        Returns:
        map of population summation over geohash grids.
      • mapPopulationByLocation

        public static java.util.Map<java.lang.String,​java.lang.Integer> mapPopulationByLocation​(java.util.List<Place> cities,
                                                                                                      int ghResolution)
        This organizes population data by geohash. Geohash of N-char prefixes. If multiple cities are located on top of that grid, then the populations Geohash prefix = 4, yields about 30 KM, and 5 yields 6 KM.
        Parameters:
        cities - list of major cities
        ghResolution - number of geohash chars in prefix, for keys in map. Higher resolution means finer geohash grid
        Returns:
        map of population summation over geohash grids.
      • loadMajorCities

        public static java.util.List<Place> loadMajorCities​(java.io.InputStream strm)
                                                     throws java.io.IOException
        Load the Geonames.org majorcities data file. Mainly to acquire population and other metrics.
          Schema: http://download.geonames.org/export/dump/ pass in the files
         formatted in geonames.org format, and named citiesNNNN.zip (.txt) where
         NNNN is the population threshold.
         
        Parameters:
        strm - input stream for geonames.org cities file
        Returns:
        list of xponents Place obj
        Throws:
        java.io.IOException - if parsing goes wrong.
      • getAdmin1Metadata

        @Deprecated
        public java.util.List<Place> getAdmin1Metadata()
        Deprecated.
        Use getUSStateMetadata
        Provides access to a array of ADM1 metadata. This is a mutable list -- if you want to add MORE admin metadata (entries, postal code mappings, etc) then have at it. For now this is US + territories only (as of v2.8.17)
        Returns:
        Array of Admin Level 1 Place objects
        Since:
        2.8.17
      • getUSStateMetadata

        public java.util.List<Place> getUSStateMetadata()
        Provides access to a array of ADM1 metadata. This is a mutable list -- if you want to add MORE admin metadata (entries, postal code mappings, etc) then have at it. For now this is US + territories only (as of v2.8.17)
        Returns:
        Array of US States (Admin Level 1) Place objects
      • getProvinceMetadata

        public java.util.List<Place> getProvinceMetadata()
        Alias for getWorldAdmin1Metadata.
        Returns:
        list of Places.
      • getWorldAdmin1Metadata

        public java.util.List<Place> getWorldAdmin1Metadata()
        Get the array of Place objects representing ADM1 level boundaries. This is literally just Names, ADM1 codes and Country code data. No location information, except for US States. To get a province by code, use
        Returns:
        list of Places
      • loadWorldAdmin1Metadata

        public void loadWorldAdmin1Metadata()
                                     throws java.io.IOException
        Source: geonames.org ADM1 codes/names in anglo/ASCII form. These codes do NOT contain geodetic information (lat/lon, etc) CAVEAT -- using such Place metadata will provide a coordinate of (0,0)
        Throws:
        java.io.IOException - if geonames.org table cannot be found in classpath
      • getAdmin1Place

        public Place getAdmin1Place​(java.lang.String cc,
                                    java.lang.String adm1)
        Retrieve a Place object with the semi-official name (in Latin/Anglo terms) given CC and ADM1 code. You must load World ADM1 data first; use loadWorldAdmin1Metadata()
        Parameters:
        cc - ISO country code
        adm1 - ISO province code
        Returns:
        Place or null.
      • getProvince

        public Place getProvince​(java.lang.String cc,
                                 java.lang.String adm1)
        Lookup by coded path, CC.ADM1. You must load World ADM1 data first; use loadWorldAdmin1Metadata() These Admin Places do NOT contain geodetic information (lat/lon, etc) CAVEAT -- using such Place metadata will provide a coordinate of (0,0) Alias for getAdmin1Place(String, String)
        Parameters:
        cc - country code
        adm1 - ADM level 1 code
        Returns:
        Place for province
      • getAdmin1PlaceByHASC

        public Place getAdmin1PlaceByHASC​(java.lang.String path)
        Lookup by coded path, CC.ADM1. You must load World ADM1 data first; use loadWorldAdmin1Metadata()
        Parameters:
        path - hierarchical path
        Returns:
        adm1 place obj
      • loadUSStateMetadata

        public void loadUSStateMetadata()
                                 throws java.io.IOException
          TODO: This is mildly informed by geonames.org, however even there
         we are still missing a mapping between ADM1 FIPS/ISO codes for a state
         and the Postal codes/abbreviations.
        
         Aliases for the same US province: "US.25" = "MA" = "US.MA" =
         "Massachussetts" = "the Bay State"
        
         Easily mapping the coded data (e.g., 'MA' = '25') worldwide would be
         helpful.
        
         TODO: Make use of geonames.org or other sources for ADM1 postal code
         listings at top level.
         
        Throws:
        java.io.IOException - if CSV file not found in classpath
      • getDefaultCountryName

        public java.lang.String getDefaultCountryName​(java.lang.String cc_iso2)
        Finds a default country name for a CC if one exists.
        Parameters:
        cc_iso2 - country code.
        Returns:
        name of country
      • getISOCountries

        public java.util.Map<java.lang.String,​Country> getISOCountries()
        List all country names, official and variant names. This does not key any Territories. Territories that carry another nation's country code are attached to that country. Territories assigned their own ISO code are listed/keyed as Countries here.
        Returns:
        map of countries, keyed by ISO country code
      • getCountries

        public java.util.List<Country> getCountries()
      • getCountry

        public Country getCountry​(java.lang.String isocode)
        Get Country by the default ISO digraph returns the Unknown country if you are not using an ISO2 code. TODO: throw a GazetteerException of some sort. for null query or invalid code.
        Parameters:
        isocode - ISO code
        Returns:
        Country object
      • getCountryByAnyCode

        public Country getCountryByAnyCode​(java.lang.String cc)
        Find distinct country object by a code. Ambiguous codes will not do anything. This is really useful only if you have no idea what standard your data uses -- FIPS or ISO2/ISO3. If you know then use the API method corresponding to that standard. getCountry() is ISO by default.
        Parameters:
        cc - country code from any standard.
        Returns:
        found country object
      • getCountryByFIPS

        public Country getCountryByFIPS​(java.lang.String fips)
        Parameters:
        fips - FIPS code
        Returns:
        Country object
      • FIPS2ISO

        public java.lang.String FIPS2ISO​(java.lang.String fips)
        Find an ISO code for a given FIPS entry.
        Parameters:
        fips - FIPS code
        Returns:
        null if key does not exist.
      • normalizeAdminCode

        public static java.lang.String normalizeAdminCode​(java.lang.String v)
        Convert and ADM1 or ADM2 id to a normalized form. US.44 or US.00 gives you 44 or 00 for id part. In this case upper case code is returned. if code is a number alone, "0" is returned for "00", "000", etc. And other numbers are 0-padded as 2-digits
        Parameters:
        v - admin code
        Returns:
        fixed admin code
      • getHASC

        public static java.lang.String getHASC​(java.lang.String c,
                                               java.lang.String adm1)
        Get a hiearchical path for a boundar or a place. This presumes you have already normalized these values.
          CC.ADM1.ADM2.ADM3... etc. for example:
        
         'US.48.201' ... some county in Texas.
         
        Parameters:
        c - country code
        adm1 - ADM1 code
        Returns:
        HASC path
      • getHASC

        public static java.lang.String getHASC​(java.lang.String c,
                                               java.lang.String adm1,
                                               java.lang.String adm2)
      • isCountryNameCollision

        public static boolean isCountryNameCollision​(java.lang.String nm)
        Experimental. Given a normalized name phrase, does it collide with country name? Usage: Savannah is a great city. Georgia is lucky it has 10 Chic-fil-a restraunts in that metro area. Georgia is not a country, but a US State. So the logic caller might take: If "savannah" is found, then ignore georgia("GG") as a possible country isCountryNameCollision -- is intending to be objective. If you choose to ignore the country or not is up to caller. Hence this function is not "ignoreCountry(placenm)" TODO: replace with simple config file of such rules that are objective and can be generalized
        Parameters:
        nm - country name
        Returns:
        if country name is ambiguous and collides with other name
      • isName

        public static boolean isName​(char name_type)
        Check if name type is an Abbreviation
        Parameters:
        name_type - code
        Returns:
        true if code is abbreviation
      • isCode

        public static boolean isCode​(char name_type)
      • isAbbreviation

        public static boolean isAbbreviation​(char name_type)
        Check if name type is an Abbreviation
        Parameters:
        name_type - OpenSextant code
        Returns:
        true if code is abbreviation
      • isCountry

        public static boolean isCountry​(java.lang.String featCode)
        Is this Place a Country?
        Parameters:
        featCode - feat code or designation
        Returns:
        - true if this is a country or "country-like" place
      • isPoliticalEntity

        public static boolean isPoliticalEntity​(java.lang.String featCode)
        Test if a feature is a political entity ~ country, territory, sovereign land
        Parameters:
        featCode -
        Returns:
      • isAdmin1

        public static boolean isAdmin1​(java.lang.String featCode)
        Is this Place a State or Province?
        Parameters:
        featCode - feature code
        Returns:
        - true if this is a State, Province or other first level admin area
      • isAdmin2

        public static boolean isAdmin2​(java.lang.String featCode)
      • isUpperAdminLevel

        public static boolean isUpperAdminLevel​(java.lang.String featCode)
        Macro for reasoning with upper common levels of boundaries - province, districts.
        Parameters:
        featCode -
        Returns:
      • isNationalCapital

        public static boolean isNationalCapital​(java.lang.String featCode)
        Is this Place a National Capital?
        Parameters:
        featCode - feature code
        Returns:
        - true if this is a a national Capital area
      • isAbbreviation

        public static boolean isAbbreviation​(Place p)
        Wrapper for isAbbreviation(name type)
        Parameters:
        p - place
        Returns:
        true if is coded as abbreviation
      • isCountry

        public static boolean isCountry​(Place p)
        Wrapper for isCountry(feat code)
        Parameters:
        p - place
        Returns:
        true if is Country, e.g., PCLI
      • isPoliticalEntity

        public static boolean isPoliticalEntity​(Place p)
        Test is Place feature is coded as PCL* (PCL, PCLIX, PCLH, PCLD, PCLF, PCLS, etc)
        Parameters:
        p - Place
        Returns:
        true if place is a political boundary feature
      • isNationalCapital

        public static boolean isNationalCapital​(Place p)
        wrapper for isNationalCaptial( feat code )
        Parameters:
        p - place
        Returns:
        true if is PPLC or similar
      • isAdmin1

        public static boolean isAdmin1​(Place p)
        Parameters:
        p - place
        Returns:
        true if is ADM1
      • isAdministrative

        public static boolean isAdministrative​(java.lang.String featClass)
        if a place or feature represents an administrative boundary.
        Parameters:
        featClass - feature type in question
        Returns:
        true if is admin
      • isPopulated

        public static boolean isPopulated​(java.lang.String featClass)
        Parameters:
        featClass - geonames feature class, e.g., A, P, H, L, V, T, R
        Returns:
        true if P.
      • isSpot

        public static boolean isSpot​(java.lang.String fc)
      • isLand

        public static boolean isLand​(java.lang.String fc)
      • isPostal

        public static boolean isPostal​(Place g)
      • isPostal

        public static boolean isPostal​(java.lang.String fc)
      • countrySpeaks

        public boolean countrySpeaks​(java.lang.String lang,
                                     java.lang.String cc)
        Is language spoken in country ID'd by cc? See TextUtils for list of langauges provided by Library of Congress.
        Parameters:
        lang - mixed case langID or langID+Locale.
        cc - UPPERCASE country code.
        Returns:
        false if language is not known or not spoken in that country.
      • isPrimaryLanguage

        public boolean isPrimaryLanguage​(java.lang.String lang,
                                         java.lang.String cc)
        If lang is primary lang.
        Parameters:
        lang - Lang ID
        cc - Country code
        Returns:
        true if lang is the primary language of country named by cc
      • primaryLangID

        public java.lang.String primaryLangID​(java.lang.String cc)
        When lang ID will do. see primaryLanguage() if Language object is desired.
        Parameters:
        cc - Country code
        Returns:
        Lang ID
      • primaryLanguage

        public Language primaryLanguage​(java.lang.String cc)
        Primary language for a given country. By our convention, this will be the major language family, not the locale. E.g., primary language of Australia? 'en', not 'en_AU'; The hashmap records the first entry only which is language.
        Parameters:
        cc - Country code
        Returns:
        Language object
      • countriesSpeaking

        public java.util.Collection<java.lang.String> countriesSpeaking​(java.lang.String lang)
        Examples: what countries speak french (fr)? what countries speak Rwandan French? (fr-RW)?
        Parameters:
        lang - lang ID
        Returns:
        list of country codes speaking lang
      • languagesInCountry

        public java.util.Collection<java.lang.String> languagesInCountry​(java.lang.String cc)
        Parameters:
        cc - UPPERCASE country code.
        Returns:
        ISO Language codes for a country
      • loadCountryLanguages

        public void loadCountryLanguages()
                                  throws java.io.IOException
        Parse metadata from geonames.org (file in CLASSPATH @ /geonames.org/countryInfo.txt) and populate existing Country objects with language metadata. By the time you call this method Countries have names, codes, regions, aliases, timezones.
        Throws:
        java.io.IOException - if geonames.org resource file is not found
      • addLang

        protected void addLang​(java.lang.String langOrLocale,
                               java.lang.String cc)
        Parameters:
        langOrLocale - lang code
        cc - country code
      • getLang

        protected static java.lang.String getLang​(java.lang.String langid)
        Parse lang ID from Locale. Internal method; Ensure argument is not null;
        Parameters:
        langid - lang ID
        Returns:
        language family