import java.time.LocalDate;
import java.time.ZoneId;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
/** A Geonames administrative subdivision. */
public class GeonamesAdm {
- private Long geonameId;
- private String countryCode;
- private String admLevel;
- private Integer level;
- private String name;
- private String asciiName;
- private List<String> alternateNames;
- private Double lat;
- private Double lng;
- private LocalDate lastUpdated;
- private ZoneId timeZone;
+ private final Long geonameId;
+ private final String countryCode;
+ private final String adminCode1;
+ private final String admLevel;
+ private final Integer level;
+ private final String name;
+ private final String asciiName;
+ private final List<String> alternateNames;
+ private final Double lat;
+ private final Double lng;
+ private final LocalDate lastUpdated;
+ private final ZoneId timeZone;
+
+ private final Long[] upperLevelIds = new Long[5];
+ private final List<GeonamesAdm> upperLevels = new ArrayList<>();
private List<String> row;
- public GeonamesAdm() {
- }
-
/** Initialise from a row in the main Geonames table. */
public GeonamesAdm(List<String> row) {
geonameId = Long.parseLong(row.get(0));
admLevel = row.get(7);
countryCode = row.get(8);
- if (admLevel.startsWith("ADM") && !admLevel.endsWith("H")) {
- level = Integer.parseInt(admLevel.substring(3));
+ adminCode1 = row.get(10);
+ if (admLevel.startsWith("ADM")) {
+ if (admLevel.endsWith("H"))
+ level = Integer.parseInt(admLevel.substring(3, admLevel.length() - 1));
+ else
+ level = Integer.parseInt(admLevel.substring(3));
} else if (admLevel.equals("PCLI")) {
level = 0;
+ } else {
+ throw new IllegalArgumentException("Unsupported admin level " + admLevel);
}
name = row.get(1);
asciiName = row.get(2);
lng = Double.parseDouble(row.get(5));
lastUpdated = LocalDate.parse(row.get(18));
timeZone = ZoneId.of(row.get(17));
+ // upper levels
+ if (row.get(11) != null && !row.get(11).trim().equals(""))
+ upperLevelIds[2] = Long.parseLong(row.get(11));
+ if (row.get(12) != null && !row.get(12).trim().equals(""))
+ upperLevelIds[3] = Long.parseLong(row.get(12));
+ if (row.get(13) != null && !row.get(13).trim().equals(""))
+ upperLevelIds[4] = Long.parseLong(row.get(13));
this.row = row;
}
+ public void mapUpperLevels(Map<Long, GeonamesAdm> index) {
+ for (int i = 0; i < level; i++) {
+ Long geonameId = upperLevelIds[i];
+ upperLevels.add(i, index.get(geonameId));
+ }
+ }
+
public Long getGeonameId() {
return geonameId;
}
return name;
}
+ public String getName(Function<String, String> transform) {
+ if (transform != null)
+ return transform.apply(name);
+ else
+ return name;
+
+ }
+
public String getAsciiName() {
return asciiName;
}
return timeZone;
}
+ public String getAdminCode1() {
+ return adminCode1;
+ }
+
+ public Long[] getUpperLevelIds() {
+ return upperLevelIds;
+ }
+
+ public List<GeonamesAdm> getUpperLevels() {
+ return upperLevels;
+ }
+
@Override
public int hashCode() {
return geonameId.intValue();
/** Loads the data. */
public void parse(InputStream in) {
+ Map<String, Long> countryGeonameIds = new HashMap<>();
+ Map<String, Long> admin1GeonameIds = new HashMap<>();
CsvParser csvParser = new CsvParser() {
@Override
return;
GeonamesAdm geonamesAdm = new GeonamesAdm(tokens);
geonamesAdms.put(geonamesAdm.getGeonameId(), geonamesAdm);
-// String featureName = tokens.get(7);
-// String geonameId = tokens.get(0);
-// String name = tokens.get(1);
-// Double lat = Double.parseDouble(tokens.get(4));
-// Double lng = Double.parseDouble(tokens.get(5));
-// switch (featureName) {
-// case "ADM1":
-// case "ADM4":
-// String adminCode1 = tokens.get(10);
-// System.out.println(
-// geonameId + " " + featureName + " " + lat + "," + lng + " " + adminCode1 + " " + name);
-// break;
-// default:
-// break;
-// }
-
+ if (geonamesAdm.getAdmLevel().equals("PCLI"))
+ countryGeonameIds.put(geonamesAdm.getCountryCode(), geonamesAdm.getGeonameId());
+ if (geonamesAdm.getAdmLevel().equals("ADM1"))
+ admin1GeonameIds.put(geonamesAdm.getAdminCode1(), geonamesAdm.getGeonameId());
}
};
csvParser.setSeparator('\t');
csvParser.setNoHeader(true);
csvParser.parse(in, StandardCharsets.UTF_8);
+
+ // fill upper levels
+ for (GeonamesAdm adm : geonamesAdms.values()) {
+ adm.getUpperLevelIds()[0] = countryGeonameIds.get(adm.getCountryCode());
+ if (adm.getLevel() > 0)
+ adm.getUpperLevelIds()[1] = admin1GeonameIds.get(adm.getAdminCode1());
+ adm.mapUpperLevels(geonamesAdms);
+ }
+
}
public Map<Long, GeonamesAdm> getGeonamesAdms() {
}
public static void main(String[] args) throws IOException {
- String country = "allCountries";
- // String country = "CI";
- try (InputStream in = Files
- .newInputStream(Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + ".txt"));
- OutputStream out = Files.newOutputStream(
- Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
- ImportGeonamesAdmin.filterGeonamesAdm(in, out);
- }
-// try (InputStream in = Files.newInputStream(
-// Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
-// ImportGeonamesAdmin importGeonamesAdmin = new ImportGeonamesAdmin();
-// importGeonamesAdmin.parse(in);
+// String country = "allCountries";
+ String country = "CI";
+// try (InputStream in = Files
+// .newInputStream(Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + ".txt"));
+// OutputStream out = Files.newOutputStream(
+// Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
+// ImportGeonamesAdmin.filterGeonamesAdm(in, out);
// }
+ try (InputStream in = Files.newInputStream(
+ Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) {
+ ImportGeonamesAdmin importGeonamesAdmin = new ImportGeonamesAdmin();
+ importGeonamesAdmin.parse(in);
+ }
}
}