/
combine_geo_data
executable file
·91 lines (77 loc) · 2.58 KB
/
combine_geo_data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env node
const path = require('path');
const fs = require('fs');
const axios = require('axios');
const topologyUrl = 'https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json';
const countryDataUrl = 'https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/all/all.json';
const cityDataPath = path.resolve(__dirname, 'simplemaps_worldcities_basicv1.6', 'worldcities.csv');
const outputPath = path.resolve(__dirname, '..', 'src', 'assets', 'world.json');
(async function () {
const { data: topology } = await axios.get(topologyUrl);
const { data: countryData } = await axios.get(countryDataUrl);
const countryGeometries = topology.objects.countries.geometries;
delete topology.objects.countries;
const continents = {};
const iso2ToCountries = {};
for (const {
'country-code': countryId,
'alpha-2': countryIso2,
'name': countryName,
'sub-region-code': subcontinentId,
'sub-region': subcontinentName,
'region-code': continentId,
'region': continentName,
} of countryData) {
const geometry = countryGeometries.find(geometry => geometry.id === countryId) ?? null;
if (geometry) {
delete geometry.properties;
}
const continent = continents[continentId] = {
name: continentName,
subcontinents: {},
...(continents[continentId] || {}),
};
const subcontinent = continent.subcontinents[subcontinentId] = {
name: subcontinentName,
countries: {},
...(continent.subcontinents[subcontinentId] || {}),
};
const country = subcontinent.countries[countryId] = {
name: countryName,
cities: {},
geometry,
};
iso2ToCountries[countryIso2] = country;
}
const citiesCsv = fs.readFileSync(cityDataPath, 'utf8');
csv2json(citiesCsv)
.filter(city => city.population > 100_000)
.forEach(city => {
const country = iso2ToCountries[city.iso2];
country.cities[city.id] = {
name: city.city_ascii,
lat: +city.lat,
lng: +city.lng,
population: +city.population,
};
});
const world = { continents, topology };
fs.writeFileSync(outputPath, JSON.stringify(world), 'utf8');
})().catch(console.error);
function csv2json(csv) {
const [headerRow, ...rows] = csv
.split('\r\n')
.map(v => {
const matches = [...v.matchAll(/"([^"]*)"/g)];
return matches.map(match => match[1]);
},
);
return rows
.map(values => {
const dictionary = {};
headerRow.forEach((label, i) => {
dictionary[label] = values[i];
});
return dictionary;
});
}