react-typescript-datamaps
Version:
react wrapper component for the 'datamaps' library (Interactive maps for data visualizations). Out of the box it includes advance arc-attack-plugin and demo mode.
1,715 lines (1,704 loc) • 81.9 kB
JavaScript
import React from 'react';
import Datamaps from 'datamaps';
import d3 from 'd3';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function handleArcsAdvance(layer, data, options) {
var self = this;
var defaultOptions = __assign({ arcLabels: {
fontSize: 12,
fontFamily: 'monospace',
fill: '#fefefe0',
strokeColor: '#fefefe',
fillKey: '#a90300'
}, destinationCircle: {
r: 3.5,
fillColor: '#a90300',
strokeColor: '#a90300'
}, arcStrokeColor: '#a90300', arcStrokeWidth: 1.5, arcSharpness: 0.8 }, options);
var arcs = layer.selectAll('path.datamaps-arc').data(data, JSON.stringify);
var enter = arcs.enter();
/**
* Adding origin label
*/
enter.append("text")
.attr('x', function (arc) {
return self.latLngToXY(arc.origin.latitude, arc.origin.longitude)[0] - 12;
})
.attr('y', function (arc) {
return self.latLngToXY(arc.origin.latitude, arc.origin.longitude)[1] + 10;
})
.style('font-size', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fontSize) || defaultOptions.arcLabels.fontSize;
})
.style('font-family', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fontFamily) || defaultOptions.arcLabels.fontFamily;
})
.style('fill', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fill) || defaultOptions.arcLabels.fill;
})
.style('stroke', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.strokeColor) || defaultOptions.arcLabels.strokeColor;
})
.text(function (arc) {
return arc.origin.name;
})
.transition()
.delay(2000)
.style('opacity', 0)
.remove();
/**
* Adding destination label
*/
enter.append("text")
.attr('x', function (arc) {
return self.latLngToXY(arc.destination.latitude, arc.destination.longitude)[0] - 12;
})
.attr('y', function (arc) {
return self.latLngToXY(arc.destination.latitude, arc.destination.longitude)[1] + 10;
})
.style('font-size', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fontSize) || defaultOptions.arcLabels.fontSize;
})
.style('font-family', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fontFamily) || defaultOptions.arcLabels.fontFamily;
})
.style('fill', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.fill) || defaultOptions.arcLabels.fill;
})
.style('stroke', function (arc) {
var _a, _b;
return ((_b = (_a = arc.options) === null || _a === void 0 ? void 0 : _a.arcLabels) === null || _b === void 0 ? void 0 : _b.strokeColor) || defaultOptions.arcLabels.strokeColor;
})
.transition()
.delay(500)
.text(function (arc) {
return arc.destination.name;
})
.transition()
.delay(2000)
.style('opacity', 0)
.remove();
enter.append('circle')
.transition()
.delay(700)
.attr('cx', function (arc) {
return self.latLngToXY(arc.destination.latitude, arc.destination.longitude)[0];
})
.attr('cy', function (arc) {
return self.latLngToXY(arc.destination.latitude, arc.destination.longitude)[1];
})
.attr('r', function (arc) {
var _a, _b, _c;
return ((_b = (_a = arc === null || arc === void 0 ? void 0 : arc.options) === null || _a === void 0 ? void 0 : _a.destinationCircle) === null || _b === void 0 ? void 0 : _b.r) || ((_c = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.destinationCircle) === null || _c === void 0 ? void 0 : _c.r);
})
.style('fill', function (arc) {
var _a, _b, _c;
return ((_b = (_a = arc === null || arc === void 0 ? void 0 : arc.options) === null || _a === void 0 ? void 0 : _a.destinationCircle) === null || _b === void 0 ? void 0 : _b.fillColor) || ((_c = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.destinationCircle) === null || _c === void 0 ? void 0 : _c.fillColor);
})
.style('fill-opacity', 0.6)
.style('stroke', function (arc) {
var _a, _b, _c;
return ((_b = (_a = arc === null || arc === void 0 ? void 0 : arc.options) === null || _a === void 0 ? void 0 : _a.destinationCircle) === null || _b === void 0 ? void 0 : _b.strokeColor) || ((_c = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.destinationCircle) === null || _c === void 0 ? void 0 : _c.strokeColor);
})
.transition()
.duration(250)
.style("stroke-width", 0)
.style('stroke-opacity', 0.2)
.transition()
.duration(250)
.style("stroke-width", 0)
.style('stroke-opacity', 0.5)
.transition()
.duration(2000)
.style("stroke-width", 25)
.style('stroke-opacity', 0)
.style('fill-opacity', 1e-6)
.ease(Math.sqrt)
.remove();
/**
* Adding arc label
*/
enter.append('svg:path')
.attr('class', 'datamaps-arc')
.style('stroke-linecap', 'round')
.style('stroke', function (arc) {
var _a;
return ((_a = arc === null || arc === void 0 ? void 0 : arc.options) === null || _a === void 0 ? void 0 : _a.arcStrokeColor) || defaultOptions.arcStrokeColor;
})
.style('fill', 'none')
.style('stroke-width', function (arc) {
var _a;
return ((_a = arc === null || arc === void 0 ? void 0 : arc.options) === null || _a === void 0 ? void 0 : _a.arcStrokeWidth) || defaultOptions.arcStrokeWidth;
})
.attr('d', function (arc) {
var originXY = self.latLngToXY(arc.origin.latitude, arc.origin.longitude);
var destXY = self.latLngToXY(arc.destination.latitude, arc.destination.longitude);
var midXY = [(originXY[0] + destXY[0]) / 2, (originXY[1] + destXY[1]) / 2];
return "M" + originXY[0] + ',' + originXY[1] + "S" + (midXY[0] + (50 * options.arcSharpness)) + "," + (midXY[1] - (75 * options.arcSharpness)) + "," + destXY[0] + "," + destXY[1];
})
.transition()
.delay(100)
.style('fill', function () {
/*
Thank you Jake Archibald, this is awesome.
Source: http://jakearchibald.com/2013/animated-line-drawing-svg/
*/
// const item = nodes[index];
var length = this.getTotalLength();
this.style.transition = this.style.WebkitTransition = 'none';
this.style.strokeDasharray = length + ' ' + length;
this.style.strokeDashoffset = length;
this.getBoundingClientRect();
this.style.transition = this.style.WebkitTransition = 'stroke-dashoffset ' + options.animationSpeed + 'ms ease-out';
this.style.strokeDashoffset = '0';
return 'none';
})
.transition()
.delay(2000)
.style('opacity', 0)
.remove();
arcs.exit()
.transition()
.style('opacity', 0)
.remove();
}
var MAP_CLEARING_PROPS = [
'height', 'scope', 'setProjection', 'width'
];
var propChangeRequiresMapClear = function (oldProps, newProps) {
return MAP_CLEARING_PROPS.some(function (key) {
return oldProps[key] !== newProps[key];
});
};
var map;
var DataMapsWrapper = function (props) {
var containerRef = React.useRef(null);
var prevProps = React.useRef(props);
var clear = function () {
var e_1, _a;
var container = containerRef.current;
if (container) {
try {
for (var _b = __values(Array.from(container.childNodes)), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
container.removeChild(child);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
map = null;
}
};
var drawMap = function () {
var arc = props.arc, arcOptions = props.arcOptions, attacks = props.attacks, bubbles = props.bubbles, bubbleOptions = props.bubbleOptions, data = props.data, graticule = props.graticule, labels = props.labels, updateChoroplethOptions = props.updateChoroplethOptions, restProps = __rest(props, ["arc", "arcOptions", "attacks", "bubbles", "bubbleOptions", "data", "graticule", "labels", "updateChoroplethOptions"]);
if (!map) {
map = new Datamaps(__assign(__assign({}, restProps), { data: data, element: containerRef.current }));
map.addPlugin('handleArcsAdvance', handleArcsAdvance);
}
else {
map.updateChoropleth(data, updateChoroplethOptions);
}
if (arc) {
map.arc(arc, arcOptions);
}
if (bubbles) {
map.bubbles(bubbles, bubbleOptions);
}
if (graticule) {
map.graticule();
}
if (labels) {
map.labels();
}
if (attacks) {
map.handleArcsAdvance(attacks, {
arcSharpness: 1.4,
greatArc: true,
animationSpeed: 600,
});
}
};
var resizeMap = function () {
map.resize();
};
React.useEffect(function () {
if (props.responsive) {
window.addEventListener('resize', resizeMap);
}
drawMap();
}, []);
React.useEffect(function () {
if (propChangeRequiresMapClear(prevProps.current, props)) {
clear();
}
prevProps.current = props;
}, [props]);
React.useEffect(function () {
drawMap();
});
React.useEffect(function () {
// return a function to execute at unmount
return function () {
clear();
if (props.responsive) {
window.removeEventListener('resize', resizeMap);
}
};
}, []);
return (React.createElement("div", { ref: containerRef, style: __assign({ height: '100%', position: 'relative', width: '100%' }, props.style) }));
};
var MAX_TABLE_ITEMS = 3;
var AttackTicker = function (props) {
var _a = __read(React.useState([]), 2), items = _a[0], setItems = _a[1];
React.useEffect(function () {
if (items.length < MAX_TABLE_ITEMS) {
setItems(items.concat(props.addItems));
}
else {
var nextItems = items.concat(props.addItems);
nextItems.splice(0, props.addItems.length);
setItems(nextItems);
}
}, [props.addItems]);
var filler = [];
for (var index = 0; index < MAX_TABLE_ITEMS - items.length; index++) {
filler.push(React.createElement("tr", { key: "save-place-" + index },
React.createElement("td", null),
React.createElement("td", null),
React.createElement("td", null)));
}
return (React.createElement("div", { className: "react-attack-map-ticker" },
React.createElement("table", { className: "react-attack-map-table-container" },
React.createElement("thead", null,
React.createElement("tr", null,
React.createElement("th", null,
React.createElement("h1", null, "Attack Type")),
React.createElement("th", null,
React.createElement("h1", null, "Origin")),
React.createElement("th", null,
React.createElement("h1", null, "Target")))),
React.createElement("tbody", null,
items.map(function (item) {
return React.createElement("tr", { key: item.id },
React.createElement("td", null,
React.createElement("div", { className: "react-table-type-wrapper" },
React.createElement("div", { style: { background: item.color, borderColor: item.color }, className: "react-table-type react-table-type-" + item.color }),
React.createElement("div", null, item.type))),
React.createElement("td", null, item.origin),
React.createElement("td", null, item.destination));
}),
filler))));
};
var cyberThreats = [
{
name: 'Ransomware',
color: 'red',
},
{
name: 'Malware',
color: 'orange',
},
{
name: 'Phishing',
color: 'yellow',
},
{
name: 'DDoS',
color: 'pink',
}
];
var world = [
{
"city": "Tokyo",
"latitude": "35.6897",
"longitude": "139.6922",
"country": "Japan",
"iso2": "JP",
"iso3": "JPN",
"capital": "primary",
"population": "37977000",
"id": "1392685764"
},
{
"city": "Jakarta",
"latitude": "-6.2146",
"longitude": "106.8451",
"country": "Indonesia",
"iso2": "ID",
"iso3": "IDN",
"capital": "primary",
"population": "34540000",
"id": "1360771077"
},
{
"city": "Manila",
"latitude": "14.5958",
"longitude": "120.9772",
"country": "Philippines",
"iso2": "PH",
"iso3": "PHL",
"capital": "primary",
"population": "23088000",
"id": "1608618140"
},
{
"city": "Seoul",
"latitude": "37.5833",
"longitude": "127",
"country": "Korea, South",
"iso2": "KR",
"iso3": "KOR",
"capital": "primary",
"population": "21794000",
"id": "1410836482"
},
{
"city": "Mexico City",
"latitude": "19.4333",
"longitude": "-99.1333",
"country": "Mexico",
"iso2": "MX",
"iso3": "MEX",
"capital": "primary",
"population": "20996000",
"id": "1484247881"
},
{
"city": "Beijing",
"latitude": "39.905",
"longitude": "116.3914",
"country": "China",
"iso2": "CN",
"iso3": "CHN",
"capital": "primary",
"population": "19433000",
"id": "1156228865"
},
{
"city": "Cairo",
"latitude": "30.0561",
"longitude": "31.2394",
"country": "Egypt",
"iso2": "EG",
"iso3": "EGY",
"capital": "primary",
"population": "19372000",
"id": "1818253931"
},
{
"city": "Moscow",
"latitude": "55.7558",
"longitude": "37.6178",
"country": "Russia",
"iso2": "RU",
"iso3": "RUS",
"capital": "primary",
"population": "17125000",
"id": "1643318494"
},
{
"city": "Bangkok",
"latitude": "13.75",
"longitude": "100.5167",
"country": "Thailand",
"iso2": "TH",
"iso3": "THA",
"capital": "primary",
"population": "17066000",
"id": "1764068610"
},
{
"city": "Buenos Aires",
"latitude": "-34.5997",
"longitude": "-58.3819",
"country": "Argentina",
"iso2": "AR",
"iso3": "ARG",
"capital": "primary",
"population": "16157000",
"id": "1032717330"
},
{
"city": "Dhaka",
"latitude": "23.7161",
"longitude": "90.3961",
"country": "Bangladesh",
"iso2": "BD",
"iso3": "BGD",
"capital": "primary",
"population": "15443000",
"id": "1050529279"
},
{
"city": "Tehran",
"latitude": "35.7",
"longitude": "51.4167",
"country": "Iran",
"iso2": "IR",
"iso3": "IRN",
"capital": "primary",
"population": "13633000",
"id": "1364305026"
},
{
"city": "Kinshasa",
"latitude": "-4.3317",
"longitude": "15.3139",
"country": "Congo (Kinshasa)",
"iso2": "CD",
"iso3": "COD",
"capital": "primary",
"population": "13528000",
"id": "1180000363"
},
{
"city": "Paris",
"latitude": "48.8566",
"longitude": "2.3522",
"country": "France",
"iso2": "FR",
"iso3": "FRA",
"capital": "primary",
"population": "11020000",
"id": "1250015082"
},
{
"city": "London",
"latitude": "51.5072",
"longitude": "-0.1275",
"country": "United Kingdom",
"iso2": "GB",
"iso3": "GBR",
"capital": "primary",
"population": "10979000",
"id": "1826645935"
},
{
"city": "Lima",
"latitude": "-12.05",
"longitude": "-77.0333",
"country": "Peru",
"iso2": "PE",
"iso3": "PER",
"capital": "primary",
"population": "9848000",
"id": "1604728603"
},
{
"city": "Bogotá",
"latitude": "4.6126",
"longitude": "-74.0705",
"country": "Colombia",
"iso2": "CO",
"iso3": "COL",
"capital": "primary",
"population": "9464000",
"id": "1170483426"
},
{
"city": "Luanda",
"latitude": "-8.8383",
"longitude": "13.2344",
"country": "Angola",
"iso2": "AO",
"iso3": "AGO",
"capital": "primary",
"population": "8417000",
"id": "1024949724"
},
{
"city": "Kuala Lumpur",
"latitude": "3.1478",
"longitude": "101.6953",
"country": "Malaysia",
"iso2": "MY",
"iso3": "MYS",
"capital": "primary",
"population": "8285000",
"id": "1458988644"
},
{
"city": "Hanoi",
"latitude": "21.0245",
"longitude": "105.8412",
"country": "Vietnam",
"iso2": "VN",
"iso3": "VNM",
"capital": "primary",
"population": "7785000",
"id": "1704413791"
},
{
"city": "Khartoum",
"latitude": "15.6031",
"longitude": "32.5265",
"country": "Sudan",
"iso2": "SD",
"iso3": "SDN",
"capital": "primary",
"population": "7282000",
"id": "1729268475"
},
{
"city": "Santiago",
"latitude": "-33.45",
"longitude": "-70.6667",
"country": "Chile",
"iso2": "CL",
"iso3": "CHL",
"capital": "primary",
"population": "7007000",
"id": "1152554349"
},
{
"city": "Riyadh",
"latitude": "24.65",
"longitude": "46.71",
"country": "Saudi Arabia",
"iso2": "SA",
"iso3": "SAU",
"capital": "primary",
"population": "6881000",
"id": "1682999334"
},
{
"city": "Dar es Salaam",
"latitude": "-6.8",
"longitude": "39.2833",
"country": "Tanzania",
"iso2": "TZ",
"iso3": "TZA",
"capital": "primary",
"population": "6698000",
"id": "1834843853"
},
{
"city": "Baghdad",
"latitude": "33.35",
"longitude": "44.4167",
"country": "Iraq",
"iso2": "IQ",
"iso3": "IRQ",
"capital": "primary",
"population": "5796000",
"id": "1368596238"
},
{
"city": "Singapore",
"latitude": "1.3",
"longitude": "103.8",
"country": "Singapore",
"iso2": "SG",
"iso3": "SGP",
"capital": "primary",
"population": "5745000",
"id": "1702341327"
},
{
"city": "Nairobi",
"latitude": "-1.2864",
"longitude": "36.8172",
"country": "Kenya",
"iso2": "KE",
"iso3": "KEN",
"capital": "primary",
"population": "5545000",
"id": "1404000661"
},
{
"city": "Ankara",
"latitude": "39.93",
"longitude": "32.85",
"country": "Turkey",
"iso2": "TR",
"iso3": "TUR",
"capital": "primary",
"population": "5503985",
"id": "1792572891"
},
{
"city": "Rangoon",
"latitude": "16.8",
"longitude": "96.15",
"country": "Burma",
"iso2": "MM",
"iso3": "MMR",
"capital": "primary",
"population": "5430000",
"id": "1104616656"
},
{
"city": "Washington",
"latitude": "38.9047",
"longitude": "-77.0163",
"country": "United States",
"iso2": "US",
"iso3": "USA",
"capital": "primary",
"population": "5379184",
"id": "1840006060"
},
{
"city": "Abidjan",
"latitude": "5.3364",
"longitude": "-4.0267",
"country": "Côte D’Ivoire",
"iso2": "CI",
"iso3": "CIV",
"capital": "primary",
"population": "4980000",
"id": "1384207980"
},
{
"city": "Amman",
"latitude": "31.95",
"longitude": "35.9333",
"country": "Jordan",
"iso2": "JO",
"iso3": "JOR",
"capital": "primary",
"population": "4007526",
"id": "1400522593"
},
{
"city": "Kabul",
"latitude": "34.5328",
"longitude": "69.1658",
"country": "Afghanistan",
"iso2": "AF",
"iso3": "AFG",
"capital": "primary",
"population": "3678034",
"id": "1004993580"
},
{
"city": "Berlin",
"latitude": "52.5167",
"longitude": "13.3833",
"country": "Germany",
"iso2": "DE",
"iso3": "DEU",
"capital": "primary",
"population": "3644826",
"id": "1276451290"
},
{
"city": "Algiers",
"latitude": "36.7764",
"longitude": "3.0586",
"country": "Algeria",
"iso2": "DZ",
"iso3": "DZA",
"capital": "primary",
"population": "3415811",
"id": "1012973369"
},
{
"city": "Madrid",
"latitude": "40.4189",
"longitude": "-3.6919",
"country": "Spain",
"iso2": "ES",
"iso3": "ESP",
"capital": "primary",
"population": "3266126",
"id": "1724616994"
},
{
"city": "Addis Ababa",
"latitude": "9.0272",
"longitude": "38.7369",
"country": "Ethiopia",
"iso2": "ET",
"iso3": "ETH",
"capital": "primary",
"population": "3041002",
"id": "1231824991"
},
{
"city": "Brasília",
"latitude": "-15.7744",
"longitude": "-48.0773",
"country": "Brazil",
"iso2": "BR",
"iso3": "BRA",
"capital": "primary",
"population": "3015268",
"id": "1076144436"
},
{
"city": "Kyiv",
"latitude": "50.45",
"longitude": "30.5236",
"country": "Ukraine",
"iso2": "UA",
"iso3": "UKR",
"capital": "primary",
"population": "2967000",
"id": "1804382913"
},
{
"city": "Sanaa",
"latitude": "15.35",
"longitude": "44.2",
"country": "Yemen",
"iso2": "YE",
"iso3": "YEM",
"capital": "primary",
"population": "2957000",
"id": "1887750814"
},
{
"city": "Rome",
"latitude": "41.8931",
"longitude": "12.4828",
"country": "Italy",
"iso2": "IT",
"iso3": "ITA",
"capital": "primary",
"population": "2872800",
"id": "1380382862"
},
{
"city": "La Paz",
"latitude": "-16.4942",
"longitude": "-68.1475",
"country": "Bolivia",
"iso2": "BO",
"iso3": "BOL",
"capital": "primary",
"population": "2867504",
"id": "1068000064"
},
{
"city": "Pyongyang",
"latitude": "39.03",
"longitude": "125.73",
"country": "Korea, North",
"iso2": "KP",
"iso3": "PRK",
"capital": "primary",
"population": "2863000",
"id": "1408738594"
},
{
"city": "Taipei",
"latitude": "25.0478",
"longitude": "121.5319",
"country": "Taiwan",
"iso2": "TW",
"iso3": "TWN",
"capital": "primary",
"population": "2684567",
"id": "1158881289"
},
{
"city": "Antananarivo",
"latitude": "-18.9386",
"longitude": "47.5214",
"country": "Madagascar",
"iso2": "MG",
"iso3": "MDG",
"capital": "primary",
"population": "2610000",
"id": "1450978461"
},
{
"city": "Santo Domingo",
"latitude": "18.4764",
"longitude": "-69.8933",
"country": "Dominican Republic",
"iso2": "DO",
"iso3": "DOM",
"capital": "primary",
"population": "2581827",
"id": "1214636202"
},
{
"city": "Guatemala City",
"latitude": "14.6099",
"longitude": "-90.5252",
"country": "Guatemala",
"iso2": "GT",
"iso3": "GTM",
"capital": "primary",
"population": "2450212",
"id": "1320197916"
},
{
"city": "Yaoundé",
"latitude": "3.8578",
"longitude": "11.5181",
"country": "Cameroon",
"iso2": "CM",
"iso3": "CMR",
"capital": "primary",
"population": "2440462",
"id": "1120298240"
},
{
"city": "Tashkent",
"latitude": "41.3",
"longitude": "69.2667",
"country": "Uzbekistan",
"iso2": "UZ",
"iso3": "UZB",
"capital": "primary",
"population": "2424100",
"id": "1860331871"
},
{
"city": "Accra",
"latitude": "5.6037",
"longitude": "-0.187",
"country": "Ghana",
"iso2": "GH",
"iso3": "GHA",
"capital": "primary",
"population": "2291352",
"id": "1288299415"
},
{
"city": "Baku",
"latitude": "40.3667",
"longitude": "49.8352",
"country": "Azerbaijan",
"iso2": "AZ",
"iso3": "AZE",
"capital": "primary",
"population": "2181800",
"id": "1031946365"
},
{
"city": "Havana",
"latitude": "23.1367",
"longitude": "-82.3589",
"country": "Cuba",
"iso2": "CU",
"iso3": "CUB",
"capital": "primary",
"population": "2141652",
"id": "1192752771"
},
{
"city": "Phnom Penh",
"latitude": "11.5696",
"longitude": "104.921",
"country": "Cambodia",
"iso2": "KH",
"iso3": "KHM",
"capital": "primary",
"population": "2129371",
"id": "1116260534"
},
{
"city": "Mogadishu",
"latitude": "2.0408",
"longitude": "45.3425",
"country": "Somalia",
"iso2": "SO",
"iso3": "SOM",
"capital": "primary",
"population": "2120000",
"id": "1706893395"
},
{
"city": "Minsk",
"latitude": "53.9022",
"longitude": "27.5618",
"country": "Belarus",
"iso2": "BY",
"iso3": "BLR",
"capital": "primary",
"population": "2020600",
"id": "1112348503"
},
{
"city": "Bamako",
"latitude": "12.6458",
"longitude": "-7.9922",
"country": "Mali",
"iso2": "ML",
"iso3": "MLI",
"capital": "primary",
"population": "2009109",
"id": "1466965925"
},
{
"city": "Quito",
"latitude": "-0.2186",
"longitude": "-78.5097",
"country": "Ecuador",
"iso2": "EC",
"iso3": "ECU",
"capital": "primary",
"population": "2011388",
"id": "1218441993"
},
{
"city": "Caracas",
"latitude": "10.5",
"longitude": "-66.9333",
"country": "Venezuela",
"iso2": "VE",
"iso3": "VEN",
"capital": "primary",
"population": "1943901",
"id": "1862748204"
},
{
"city": "Bucharest",
"latitude": "44.4",
"longitude": "26.0833",
"country": "Romania",
"iso2": "RO",
"iso3": "ROU",
"capital": "primary",
"population": "1883425",
"id": "1642414442"
},
{
"city": "Asunción",
"latitude": "-25.3",
"longitude": "-57.6333",
"country": "Paraguay",
"iso2": "PY",
"iso3": "PRY",
"capital": "primary",
"population": "1870000",
"id": "1600057911"
},
{
"city": "Vienna",
"latitude": "48.2083",
"longitude": "16.3731",
"country": "Austria",
"iso2": "AT",
"iso3": "AUT",
"capital": "primary",
"population": "1840573",
"id": "1040261752"
},
{
"city": "Brazzaville",
"latitude": "-4.2667",
"longitude": "15.2833",
"country": "Congo (Brazzaville)",
"iso2": "CG",
"iso3": "COG",
"capital": "primary",
"population": "1827000",
"id": "1178340306"
},
{
"city": "Warsaw",
"latitude": "52.2167",
"longitude": "21.0333",
"country": "Poland",
"iso2": "PL",
"iso3": "POL",
"capital": "primary",
"population": "1790658",
"id": "1616024847"
},
{
"city": "Damascus",
"latitude": "33.5131",
"longitude": "36.2919",
"country": "Syria",
"iso2": "SY",
"iso3": "SYR",
"capital": "primary",
"population": "1754000",
"id": "1760685964"
},
{
"city": "Budapest",
"latitude": "47.4983",
"longitude": "19.0408",
"country": "Hungary",
"iso2": "HU",
"iso3": "HUN",
"capital": "primary",
"population": "1752286",
"id": "1348611435"
},
{
"city": "Lusaka",
"latitude": "-15.4167",
"longitude": "28.2833",
"country": "Zambia",
"iso2": "ZM",
"iso3": "ZMB",
"capital": "primary",
"population": "1742979",
"id": "1894157390"
},
{
"city": "Conakry",
"latitude": "9.5092",
"longitude": "-13.7122",
"country": "Guinea",
"iso2": "GN",
"iso3": "GIN",
"capital": "primary",
"population": "1667864",
"id": "1324568159"
},
{
"city": "Kampala",
"latitude": "0.3136",
"longitude": "32.5811",
"country": "Uganda",
"iso2": "UG",
"iso3": "UGA",
"capital": "primary",
"population": "1659600",
"id": "1800406299"
},
{
"city": "Rabat",
"latitude": "34.0253",
"longitude": "-6.8361",
"country": "Morocco",
"iso2": "MA",
"iso3": "MAR",
"capital": "primary",
"population": "1628000",
"id": "1504023252"
},
{
"city": "Ouagadougou",
"latitude": "12.3572",
"longitude": "-1.5353",
"country": "Burkina Faso",
"iso2": "BF",
"iso3": "BFA",
"capital": "primary",
"population": "1626950",
"id": "1854029208"
},
{
"city": "Harare",
"latitude": "-17.8292",
"longitude": "31.0522",
"country": "Zimbabwe",
"iso2": "ZW",
"iso3": "ZWE",
"capital": "primary",
"population": "1606000",
"id": "1716196799"
},
{
"city": "Muscat",
"latitude": "23.6139",
"longitude": "58.5922",
"country": "Oman",
"iso2": "OM",
"iso3": "OMN",
"capital": "primary",
"population": "1421409",
"id": "1512035506"
},
{
"city": "The Hague",
"latitude": "52.08",
"longitude": "4.27",
"country": "Netherlands",
"iso2": "NL",
"iso3": "NLD",
"capital": "primary",
"population": "1406000",
"id": "1528799905"
},
{
"city": "Ulaanbaatar",
"latitude": "47.9203",
"longitude": "106.9172",
"country": "Mongolia",
"iso2": "MN",
"iso3": "MNG",
"capital": "primary",
"population": "1396288",
"id": "1496024767"
},
{
"city": "Belgrade",
"latitude": "44.8167",
"longitude": "20.4667",
"country": "Serbia",
"iso2": "RS",
"iso3": "SRB",
"capital": "primary",
"population": "1378682",
"id": "1688374696"
},
{
"city": "Islamabad",
"latitude": "33.6989",
"longitude": "73.0369",
"country": "Pakistan",
"iso2": "PK",
"iso3": "PAK",
"capital": "primary",
"population": "1365000",
"id": "1586306717"
},
{
"city": "Sofia",
"latitude": "42.6975",
"longitude": "23.3241",
"country": "Bulgaria",
"iso2": "BG",
"iso3": "BGR",
"capital": "primary",
"population": "1355142",
"id": "1100762037"
},
{
"city": "Prague",
"latitude": "50.0833",
"longitude": "14.4167",
"country": "Czechia",
"iso2": "CZ",
"iso3": "CZE",
"capital": "primary",
"population": "1324277",
"id": "1203744823"
},
{
"city": "Montevideo",
"latitude": "-34.8667",
"longitude": "-56.1667",
"country": "Uruguay",
"iso2": "UY",
"iso3": "URY",
"capital": "primary",
"population": "1319108",
"id": "1858107000"
},
{
"city": "Doha",
"latitude": "25.3",
"longitude": "51.5333",
"country": "Qatar",
"iso2": "QA",
"iso3": "QAT",
"capital": "primary",
"population": "1312947",
"id": "1634459660"
},
{
"city": "Abuja",
"latitude": "9.0556",
"longitude": "7.4914",
"country": "Nigeria",
"iso2": "NG",
"iso3": "NGA",
"capital": "primary",
"population": "1235880",
"id": "1566342270"
},
{
"city": "Tunis",
"latitude": "36.8008",
"longitude": "10.18",
"country": "Tunisia",
"iso2": "TN",
"iso3": "TUN",
"capital": "primary",
"population": "1200000",
"id": "1788742103"
},
{
"city": "Maputo",
"latitude": "-25.9153",
"longitude": "32.5764",
"country": "Mozambique",
"iso2": "MZ",
"iso3": "MOZ",
"capital": "primary",
"population": "1191613",
"id": "1508074843"
},
{
"city": "Dublin",
"latitude": "53.3425",
"longitude": "-6.2658",
"country": "Ireland",
"iso2": "IE",
"iso3": "IRL",
"capital": "primary",
"population": "1173179",
"id": "1372595407"
},
{
"city": "Nay Pyi Taw",
"latitude": "19.8028",
"longitude": "96.1583",
"country": "Burma",
"iso2": "MM",
"iso3": "MMR",
"capital": "primary",
"population": "1160242",
"id": "1104838105"
},
{
"city": "Dakar",
"latitude": "14.7319",
"longitude": "-17.4572",
"country": "Senegal",
"iso2": "SN",
"iso3": "SEN",
"capital": "primary",
"population": "1146053",
"id": "1686604760"
},
{
"city": "Tegucigalpa",
"latitude": "14.0942",
"longitude": "-87.2067",
"country": "Honduras",
"iso2": "HN",
"iso3": "HND",
"capital": "primary",
"population": "1126534",
"id": "1340344059"
},
{
"city": "Tripoli",
"latitude": "32.8752",
"longitude": "13.1875",
"country": "Libya",
"iso2": "LY",
"iso3": "LBY",
"capital": "primary",
"population": "1126000",
"id": "1434201852"
},
{
"city": "Tbilisi",
"latitude": "41.7225",
"longitude": "44.7925",
"country": "Georgia",
"iso2": "GE",
"iso3": "GEO",
"capital": "primary",
"population": "1118035",
"id": "1268203191"
},
{
"city": "N’Djamena",
"latitude": "12.11",
"longitude": "15.05",
"country": "Chad",
"iso2": "TD",
"iso3": "TCD",
"capital": "primary",
"population": "1092066",
"id": "1148708596"
},
{
"city": "Copenhagen",
"latitude": "55.6786",
"longitude": "12.5635",
"country": "Denmark",
"iso2": "DK",
"iso3": "DNK",
"capital": "primary",
"population": "1085000",
"id": "1208763942"
},
{
"city": "Yerevan",
"latitude": "40.1814",
"longitude": "44.5144",
"country": "Armenia",
"iso2": "AM",
"iso3": "ARM",
"capital": "primary",
"population": "1075800",
"id": "1051074169"
},
{
"city": "Nur-Sultan",
"latitude": "51.1333",
"longitude": "71.4333",
"country": "Kazakhstan",
"iso2": "KZ",
"iso3": "KAZ",
"capital": "primary",
"population": "1078362",
"id": "1398516045"
},
{
"city": "Nouakchott",
"latitude": "18.0783",
"longitude": "-15.9744",
"country": "Mauritania",
"iso2": "MR",
"iso3": "MRT",
"capital": "primary",
"population": "1077169",
"id": "1478414984"
},
{
"city": "Bishkek",
"latitude": "42.8667",
"longitude": "74.5667",
"country": "Kyrgyzstan",
"iso2": "KG",
"iso3": "KGZ",
"capital": "primary",
"population": "1027200",
"id": "1417191971"
},
{
"city": "Amsterdam",
"latitude": "52.35",
"longitude": "4.9166",
"country": "Netherlands",
"iso2": "NL",
"iso3": "NLD",
"capital": "primary",
"population": "1031000",
"id": "1528355309"
},
{
"city": "Ashgabat",
"latitude": "37.95",
"longitude": "58.3833",
"country": "Turkmenistan",
"iso2": "TM",
"iso3": "TKM",
"capital": "primary",
"population": "1031992",
"id": "1795049992"
},
{
"city": "Niamey",
"latitude": "13.5086",
"longitude": "2.1111",
"country": "Niger",
"iso2": "NE",
"iso3": "NER",
"capital": "primary",
"population": "1026848",
"id": "1562932886"
},
{
"city": "Managua",
"latitude": "12.15",
"longitude": "-86.2667",
"country": "Nicaragua",
"iso2": "NI",
"iso3": "NIC",
"capital": "primary",
"population": "1028808",
"id": "1558296252"
},
{
"city": "Monrovia",
"latitude": "6.3106",
"longitude": "-10.8047",
"country": "Liberia",
"iso2": "LR",
"iso3": "LBR",
"capital": "primary",
"population": "1021762",
"id": "1430477826"
},
{
"city": "Port-au-Prince",
"latitude": "18.5425",
"longitude": "-72.3386",
"country": "Haiti",
"iso2": "HT",
"iso3": "HTI",
"capital": "primary",
"population": "987310",
"id": "1332401940"
},
{
"city": "Kathmandu",
"latitude": "27.7167",
"longitude": "85.3667",
"country": "Nepal",
"iso2": "NP",
"iso3": "NPL",
"capital": "primary",
"population": "975453",
"id": "1524589448"
},
{
"city": "Abu Dhabi",
"latitude": "24.4781",
"longitude": "54.3686",
"country": "United Arab Emirates",
"iso2": "AE",
"iso3": "ARE",
"capital": "primary",
"population": "1000000",
"id": "1784176710"
},
{
"city": "Stockholm",
"latitude": "59.3294",
"longitude": "18.0686",
"country": "Sweden",
"iso2": "SE",
"iso3": "SWE",
"capital": "primary",
"population": "972647",
"id": "1752425602"
},
{
"city": "Asmara",
"latitude": "15.3333",
"longitude": "38.9167",
"country": "Eritrea",
"iso2": "ER",
"iso3": "ERI",
"capital": "primary",
"population": "963000",
"id": "1232791236"
},
{
"city": "Freetown",
"latitude": "8.4833",
"longitude": "-13.2331",
"country": "Sierra Leone",
"iso2": "SL",
"iso3": "SLE",
"capital": "primary",
"population": "951000",
"id": "1694085071"
},
{
"city": "Jerusalem",
"latitude": "31.7833",
"longitude": "35.2167",
"country": "Israel",
"iso2": "IL",
"iso3": "ISR",
"capital": "primary",
"population": "919438",
"id": "1376261644"
},
{
"city": "Panama City",
"latitude": "9",
"longitude": "-79.5",
"country": "Panama",
"iso2": "PA",
"iso3": "PAN",
"capital": "primary",
"population": "880691",
"id": "1591672475"
},
{
"city": "Lomé",
"latitude": "6.1319",
"longitude": "1.2228",
"country": "Togo",
"iso2": "TG",
"iso3": "TGO",
"capital": "primary",
"population": "837437",
"id": "1768409132"
},
{
"city": "Libreville",
"latitude": "0.3901",
"longitude": "9.4544",
"country": "Gabon",
"iso2": "GA",
"iso3": "GAB",
"capital": "primary",
"population": "797003",
"id": "1266952885"
},
{
"city": "Zagreb",
"latitude": "45.8",
"longitude": "15.95",
"country": "Croatia",
"iso2": "HR",
"iso3": "HRV",
"capital": "primary",
"population": "790017",
"id": "1191233290"
},
{
"city": "Dushanbe",
"latitude": "38.5731",
"longitude": "68.7864",
"country": "Tajikistan",
"iso2": "TJ",
"iso3": "TJK",
"capital": "primary",
"population": "780000",
"id": "1762930616"
},
{
"city": "Lilongwe",
"latitude": "-13.9833",
"longitude": "33.7833",
"country": "Malawi",
"iso2": "MW",
"iso3": "MWI",
"capital": "primary",
"population": "781538",
"id": "1454688499"
},
{
"city": "Cotonou",
"latitude": "6.4",
"longitude": "2.52",
"country": "Benin",
"iso2": "BJ",
"iso3": "BEN",
"capital": "primary",
"population": "762000",
"id": "1204955174"
},
{
"city": "Vientiane",
"latitude": "17.9667",
"longitude": "102.6",
"country": "Laos",
"iso2": "LA",
"iso3": "LAO",
"capital": "primary",
"population": "760000",
"id": "1418732714"
},
{
"city": "Colombo",
"latitude": "6.9167",
"longitude": "79.8333",
"country": "Sri Lanka",
"iso2": "LK",
"iso3": "LKA",
"capital": "primary",
"population": "752993",
"id": "1144251314"
},
{
"city": "Kigali",
"latitude": "-1.9536",
"longitude": "30.0606",
"country": "Rwanda",
"iso2": "RW",
"iso3": "RWA",
"capital": "primary",
"population": "745261",
"id": "1646923541"
},
{
"city": "Pretoria",
"latitude": "-25.7464",
"longitude": "28.1881",
"country": "South Africa",
"iso2": "ZA",
"iso3": "ZAF",
"capital": "primary",
"population": "741651",
"id": "1710176249"
},
{
"city": "Bangui",
"latitude": "4.3732",
"longitude": "18.5628",
"country": "Central African Republic",
"iso2": "CF",
"iso3": "CAF",
"capital": "primary",
"population": "734350",
"id": "1140080881"
},
{
"city": "Riga",
"latitude": "56.9475",
"longitude": "24.1069",
"country": "Latvia",
"iso2": "LV",
"iso3": "LVA",
"capital": "primary",
"population": "698529",
"id": "1428586192"
},
{
"city": "Oslo",
"latitude"