-
Notifications
You must be signed in to change notification settings - Fork 0
/
locations.js
65 lines (53 loc) · 1.8 KB
/
locations.js
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
import { promises as fs } from 'fs'
async function holdOn(time) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
async function queryServerLocations(addresses) {
return new Promise(async (resolve, reject) => {
const response = await fetch('http://ip-api.com/batch?fields=lat,lon,query', {
method: 'POST',
body: JSON.stringify(addresses)
})
const data = await response.json()
resolve(data)
})
}
function countIPs(addresses) {
const counts = new Map()
addresses.forEach((address) => {
const base = address.split(":")[0]
counts.set(base, (counts.get(base) || 0) + 1)
})
return counts
}
const fileName = process.argv[2]
fs.readFile(fileName).then(async (dataString) => {
const data = JSON.parse(dataString)
const counts = countIPs(data)
const uniqueIPs = [...counts.keys()]
const chunkSize = 100
let features = []
for (let i = 0; i < uniqueIPs.length; i += chunkSize) {
const chunk = uniqueIPs.slice(i, i + chunkSize)
const locations = await queryServerLocations(chunk)
const locationFeatures = locations.map((data) => {
return {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [data.lon, data.lat],
},
"properties": {
"count": counts.get(data.query),
"ip": data.query
}
}
})
features = features.concat(locationFeatures)
console.log('Processed', features.length)
await holdOn(5000)
}
await fs.writeFile(fileName.replace(".json", ".geojson"), JSON.stringify({ "type": "FeatureCollection", features: features }))
})