Initial commit - Added logic to look up world city locations via csv
All checks were successful
Locusworks Team/world-cities/pipeline/head This commit looks good
All checks were successful
Locusworks Team/world-cities/pipeline/head This commit looks good
This commit is contained in:
43
src/main/java/net/locusworks/worldcities/WorldCities.java
Normal file
43
src/main/java/net/locusworks/worldcities/WorldCities.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package net.locusworks.worldcities;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.locusworks.worldcities.csv.CityFileReader;
|
||||
import net.locusworks.worldcities.entities.City;
|
||||
|
||||
public class WorldCities {
|
||||
|
||||
private static List<City> WORLD_CITY_LIST;
|
||||
static {
|
||||
try {
|
||||
WORLD_CITY_LIST = CityFileReader.readCities();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static City findByCityName(String cityName) {
|
||||
return WORLD_CITY_LIST.stream().filter(c -> c.getCityName().equalsIgnoreCase(cityName))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static City findByCityAndCountry(String cityName, String country) {
|
||||
return WORLD_CITY_LIST.stream()
|
||||
.filter(c -> c.getCityName().equalsIgnoreCase(cityName))
|
||||
.filter(c -> c.getCountryName().equalsIgnoreCase(country))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static List<City> findByCityNameLike(String cityName) {
|
||||
return WORLD_CITY_LIST.stream().filter(c -> c.getCityName().toLowerCase()
|
||||
.contains(cityName.toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<City> findCitiesByCountry(String countryName) {
|
||||
return WORLD_CITY_LIST.stream().filter(c -> c.getCountryName()
|
||||
.equalsIgnoreCase(countryName.toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.locusworks.worldcities.csv;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
|
||||
import net.locusworks.worldcities.entities.City;
|
||||
import net.locusworks.worldcities.entities.Location;
|
||||
|
||||
public class CityFileReader {
|
||||
|
||||
private static final String[] HEADERS = {"city","city_ascii","lat","lng","country","iso2","iso3","admin_name","capital","population","id"};
|
||||
|
||||
private static List<City> worldCities;
|
||||
|
||||
public static List<City> readCities() throws IOException {
|
||||
if (worldCities != null && worldCities.size() > 0) return worldCities;
|
||||
|
||||
InputStream is = CityFileReader.class.getClassLoader().getResourceAsStream("worldcities.csv");
|
||||
|
||||
Iterable<CSVRecord> records = CSVFormat.DEFAULT
|
||||
.withHeader(HEADERS)
|
||||
.withFirstRecordAsHeader()
|
||||
.parse(new InputStreamReader(is));
|
||||
|
||||
worldCities = StreamSupport.stream(records.spliterator(), false)
|
||||
.map(r -> toCity(r))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return worldCities;
|
||||
}
|
||||
|
||||
private static City toCity(CSVRecord record) {
|
||||
String city = record.get("city_ascii");
|
||||
float lat = Float.valueOf(record.get("lat"));
|
||||
float lng = Float.valueOf(record.get("lng"));;
|
||||
String country = record.get("country");
|
||||
String iso2 = record.get("iso2");
|
||||
String iso3 = record.get("iso3");
|
||||
long id = Long.valueOf(record.get("id"));
|
||||
|
||||
return new City(id, city, country, iso2, iso3, new Location(lat, lng));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
132
src/main/java/net/locusworks/worldcities/entities/City.java
Normal file
132
src/main/java/net/locusworks/worldcities/entities/City.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package net.locusworks.worldcities.entities;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class City {
|
||||
|
||||
private long id;
|
||||
private String cityName;
|
||||
private String countryName;
|
||||
private String iso2;
|
||||
private String iso3;
|
||||
private Location location;
|
||||
|
||||
public City(long id, String cityName, String countryName, Location location) {
|
||||
this(id, cityName, countryName, null, null, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param cityName
|
||||
* @param countryName
|
||||
* @param iso2
|
||||
* @param iso3
|
||||
* @param location
|
||||
*/
|
||||
public City(long id, String cityName, String countryName, String iso2, String iso3, Location location) {
|
||||
this.id = id;
|
||||
this.cityName = cityName;
|
||||
this.countryName = countryName;
|
||||
this.iso2 = iso2;
|
||||
this.iso3 = iso3;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cityName
|
||||
*/
|
||||
public String getCityName() {
|
||||
return cityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cityName the cityName to set
|
||||
*/
|
||||
public void setCityName(String cityName) {
|
||||
this.cityName = cityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the countryName
|
||||
*/
|
||||
public String getCountryName() {
|
||||
return countryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param countryName the countryName to set
|
||||
*/
|
||||
public void setCountryName(String countryName) {
|
||||
this.countryName = countryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the iso2
|
||||
*/
|
||||
public String getIso2() {
|
||||
return iso2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iso2 the iso2 to set
|
||||
*/
|
||||
public void setIso2(String iso2) {
|
||||
this.iso2 = iso2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the iso3
|
||||
*/
|
||||
public String getIso3() {
|
||||
return iso3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iso3 the iso3 to set
|
||||
*/
|
||||
public void setIso3(String iso3) {
|
||||
this.iso3 = iso3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location the location to set
|
||||
*/
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
try {
|
||||
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package net.locusworks.worldcities.entities;
|
||||
|
||||
public class Location {
|
||||
|
||||
private float latitude;
|
||||
private float longitude;
|
||||
|
||||
public Location(float latitude, float longitude) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public float getLatitude() {
|
||||
return this.latitude;
|
||||
}
|
||||
|
||||
public float getLongitude() {
|
||||
return this.longitude;
|
||||
}
|
||||
|
||||
public String toDMS() {
|
||||
String lat = toDegreesMinutesAndSeconds(this.latitude);
|
||||
String latCardinal = this.latitude >= 0 ? "N" : "S";
|
||||
|
||||
String lng = toDegreesMinutesAndSeconds(this.longitude);
|
||||
String lngiCardinal = this.longitude >= 0 ? "E" : "W";
|
||||
|
||||
return String.format("%s%s%s%s", lat, latCardinal, lng, lngiCardinal);
|
||||
}
|
||||
|
||||
private String toDegreesMinutesAndSeconds(float coordinate) {
|
||||
float absolute = Math.abs(coordinate);
|
||||
double degrees = Math.floor(absolute);
|
||||
double minutesNotTruncated = (absolute - degrees) * 60;
|
||||
double minutes = Math.floor(minutesNotTruncated);
|
||||
double seconds = Math.floor((minutesNotTruncated - minutes) * 60);
|
||||
|
||||
return String.format("%2s%2s%s", (long)degrees, (long)minutes, seconds);
|
||||
}
|
||||
|
||||
}
|
||||
15494
src/main/resources/worldcities.csv
Normal file
15494
src/main/resources/worldcities.csv
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
package net.locusworks.worldcities.tests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import net.locusworks.worldcities.csv.CityFileReader;
|
||||
|
||||
class CityFileReaderTest {
|
||||
|
||||
@Test
|
||||
void testReadCities() throws IOException {
|
||||
assertTrue(CityFileReader.readCities().size() > 0);
|
||||
|
||||
CityFileReader.readCities().forEach(c -> System.out.println(c));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package net.locusworks.worldcities.tests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import net.locusworks.worldcities.WorldCities;
|
||||
import net.locusworks.worldcities.entities.City;
|
||||
|
||||
class WorldCitiesTest {
|
||||
|
||||
@Test
|
||||
void testFindByCityName() {
|
||||
City city = WorldCities.findByCityName("Cheremoshna");
|
||||
assertNotNull(city);
|
||||
assertEquals(city.getCityName(), "Cheremoshna");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindByCityNameLike() {
|
||||
List<City> cities = WorldCities.findByCityNameLike("Cher");
|
||||
assertTrue(cities.size() == 33);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindCitiesByCountry() throws IOException {
|
||||
List<City> cities = WorldCities.findCitiesByCountry("Ukraine");
|
||||
assertTrue(cities.size() == 51);
|
||||
|
||||
Path file = Paths.get("ukraine.txt");
|
||||
|
||||
try(BufferedWriter bos = new BufferedWriter(Files.newBufferedWriter(file))) {
|
||||
for (City c : cities) {
|
||||
bos.write(String.format("%s%n", c));
|
||||
System.out.println(c.getLocation().toDMS());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user