Skip to main content

location4j 🌎4️⃣♨️

GitHub branch check runs Bugs Quality Gate Status javadoc GitHub commit activity GitHub License

location4j is a simple Java library designed for efficient and accurate geographical data lookups for countries, states, and cities. πŸ—ΊοΈ

Unlike other libraries, it operates without relying on third-party APIs, making it both cost-effective and fast. 🏎️

Its built-in dataset provides quick lookups and no need for external HTTP calls. πŸ“€

Setup πŸš€β€‹

Get the latest version of the location4j library by adding it to your Maven pom.xml


<dependency>
<groupId>com.tomaytotomato</groupId>
<artifactId>location4j</artifactId>
<version>1.0.5</version>
</dependency>

Gradle

implementation group: 'com.tomaytotomato', name: 'location4j', version: '1.0.5'

Quick Example πŸ—β€‹

import com.tomaytotomato.SearchLocationService;

public class Main {

public static void main(String[] args) {
SearchLocationService searchLocationService = SearchLocationService.builder().build();

// Find all locations named San Francisco
List<Location> results = searchLocationService.search("san francisco");
printResults(results);

// Narrow search to the US
results = searchLocationService.search("san francisco, us");
printResults(results);

// Narrow search further to California
results = searchLocationService.search("san francisco, us california");
printResults(results);
}

private static void printResults(List<Location> results) {
System.out.println("Locations found: " + results.size());
results.forEach(location -> {
System.out.println("Country: " + location.getCountryName());
System.out.println("State: " + location.getStateName());
System.out.println("City: " + location.getCityName());
});
}
}

Features πŸ”¬β€‹

FeatureSupportedObjectExample
Search (free text)βœ…Locationsearch("kyiv") -> "Kyiv, Ukraine, Europe, UA"
Find All Countriesβœ…CountryfindAllCountries() -> ["Belgium", "Canada", ...]
Find Country by Idβœ…CountryfindCountryById(1) -> ["Afghanistan"]
Find Country by ISO2 codeβœ…CountryfindCountryByISO2Code("CA") -> ["Canada"]
Find Country by ISO3 codeβœ…CountryfindCountryByISO3Code("CAN") -> ["Canada"]
Find Country by Nameβœ…CountryfindCountryByName("Canada") -> ["Canada"]
Find Country by Localised nameβœ…CountryfindCountryByLocalisedName("Belgique") -> ["Belgium"]
Find Countries by State nameβœ…CountryfindAllCountriesByStateName("Texas") -> ["USA"]
Find States by State nameβœ…StatefindAllStatesByStateName("Texas") -> ["Texas", "USA"]
Find State by State Idβœ…StatefindStateById(5) -> ["California", "USA"]
Find States by State codeβœ…StatefindAllStatesByStateCode("CA") -> ["California", "USA"]
Find City by City Idβœ…CityfindCityById(10) -> ["Los Angeles", "California"]
Find City by latitude/longitudeβœ…CityfindClosestCityByLatLong(30.438, -84.280) -> ["Tallahassee", "Florida"]
Find Cities by City nameβœ…CityfindAllCitiesByCityName("San Francisco") -> ["San Francisco", "California"]

🟒 location4j can parse free text strings with or without punctuation or capitalisation e.g.

San Francisco, CA, USA

ca united states san francisco

US, San Francisco, california

🟒 Latitude/Longitude searches can use double, BigDecimal, or String inputs for both values; the types must match ( you can't mix a String latitude with a BigDecimal or double longitude) but the API will accept any of the three types.

πŸ”΄ location4j cannot find a location based on a small town, street, or zipcode/postcode.

More Examples πŸ§ͺ​

Lookup countries

For simple lookups the LocationService can act like a repository, allow the retrieval of countries, states and city information.


import com.tomaytotomato.LocationService;

public class LocationServiceExample {

public static void main(String[] args) {
LocationService locationService = LocationService.builder().build();

// Get all countries
List<Country> countries = locationService.findAllCountries();

// Filter European countries
List<Country> europeanCountries = countries.stream()
.filter(country -> "Europe".equals(country.getRegion()))
.toList();

// Find Afghanistan by ID
Country afghanistan = locationService.findCountryById(1);

// Find all cities named San Francisco
List<City> cities = locationService.findAllCities("San Francisco");

}
}

Search locations

Search any text for a location, the SearchLocationService can handle formatted or unformatted text. It will try and find matches against a variety of keywords it has in its dataset.


import com.tomaytotomato.SearchLocationService;

public class SearchLocationServiceExample {

public static void main(String[] args) {
SearchLocationService searchLocationService = SearchLocationService.builder()
.withTextNormaliser(new DefaultTextNormaliser())
.build();

// Search for Santa Clara
List<Location> results = searchLocationService.search("Santa Clara");

// Search for Santa Clara in the USA
List<Location> resultsUnitedStates = searchLocationService.search("Santa Clara USA");

// Search for Santa Clara in California (it works with ISO2 or ISO3) codes
List<Location> resultsCalifornia = searchLocationService.search("Santa Clara US CA");
}
}

Motivation πŸŒ±β€‹

Parsing location data efficiently is crucial for many applications, yet it can be complex and time-consuming.

Third-party services like Google Location API can be costly, and using large language models can introduce significant latency.

location4j offers a practical solution with its own dataset, enabling fast and cost-effective geographical lookups to a city/town level (which is sufficient in most cases).

This allows applications to be built without another external dependency and the overheads that come with it.

I may add other functionality in the future if needed e.g. geolocation to nearest place, geofencing etc.

Credits πŸ™β€‹

Country data sourced from dr5shn/countries-states-cities-database License: ODbL

License πŸ“œβ€‹

MIT License