# What is the roundest country?

Posted on July 26, 2016

We can define roundness in many ways. For example, as you may know, the circle is the shape that given a fixed perimeter maximizes the area. This definition has many problems. One of the problems is that countries generally have chaotic perimeters (also known as borders), so they tend to be much longer than they seem to be.

For that reason, we have to define roundness some other way. Given a country, I will represent it as a plane region, more precisely a compact set $C \subset \mathbb{R}^2$, and I will define its roundness as

$roundness(C) = \max_{ x \in \mathbb{R}^2, r \in \mathbb{R}_{>0} } \frac{ area(C \cap D(x,r)) }{ \max \{ area(D(x,r)), area(C) \} }$

where $D(x, r)$ is the disk of center $x$ and radius $r$.

Note that:

• For all $C$, $0 \leq roundness(C) \leq 1$.
• If $C$ is a circle, then taking $D(x,r) = C$ maximizes the formula, so $roundness(C) = 1$.
• If $roundness(C) = 1$, then $C$ is a circle, because it overlaps completely with $D(x,r)$, for some $x$ and $r$.

Let’s see the results and then we will see the code I used to get them. You can scroll to see all the results, and sort by any column you like.

Rank Country Roundness Image
78 Sao Tome and Principe 0.788 %2BAmQ0TBQrW8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAug1YIQAAAAlwSFlzAAAPYQAAD2EBqD%2BnaQAAAZxJREFUeJzt3EtuwzAMRVEToj773zBLqk3b2B0kI5PoPUAz6OiFoCQ7AHUcAAAAAAAAAAAAqKvr6t3uTvEWa7KVSj1EbaxioafHHdUqrRJ/0u7O8QazqHGvVWnZNfb2aKVCd//ssu4O8g6Z8TmKhRZdsVMXao7j%2BDpZ9O4c74nto1ZzbGPuxQgAAAAAAAAAAAAAAAAAAAAAAPBfWKlJG8/bV5siWmhC6DF5KlJmvtBiQG%2BoNC%2B3px5353mFl3mu%2BTmqt2teYUyoiddX5yPqqDD51qWprF85Z/62NtVTQ1j%2BUg/f5k5LT9NP7E29FLalH43U6x6XfgjVG3ie/zez73p2PQIt/QFj1zlZ3/LKVdqX4Uje017X5572M92P8pvCvOp0QUcXNUt/JNrTqrO4tGMlb%2BkjSv3TH7b8G/T0hd6lfhQ2buuIh5HkyzD4s%2BjYMeNloHfN3xzH52EyPbbFO%2BIUrZB533qh36%2BIq0BvBIu7iSLwbKNI5Dhf1my%2B1ZUJHOI9QLIfgmexEpM/1/3BVrUfxAAAAAAAAAAAQGofboVDfcLUdRYAAAAASUVORK5CYII%3D
177 Saint Kitts and Nevis 0.540 9guw0E8tj3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYwycwAAAAlwSFlzAAAPYQAAD2EBqD%2BnaQAABThJREFUeJztnFuS4yAMRdvFy/vfsEZgOyEEEHYnfeUazsdMKomrr7EQQkj5%2BZlMJpPJZDKZTCaTyeR/hciFEIzhf5wntJoBWK9ZGJuIr0xwuoX7sKs8ZJJb4z0ED5XVgZyJ8t6HNd6K0Tncjm2ipYwcW4o%2B2WQW07UBz19QptpFwxU0OV2DHYfZygZAmgbb28UFVixZSBpsJX7E8wS0i%2BUx5P8EGyGrQzVrZssI6TWtko2oUB1l5q7OSzaCV01xubOvIiQbYdXQ2UgxtnhTQKG9ymxXIX0IazaLq3wg2Ihb1q9pEuE/vpjqJ8S%2BbW0PZwCaNUtummeykdaFSAMxtmocOz0bwRlINOnu5x0bCSgP4sU1uW0jhBrq1izMaQakxmKGuu7uClo24jAOhCrrSvV7VRshKz%2BmL%2BAHrGP/pq3YyAqZiidWiJqNYKaiXU58OdpIcY8Q%2B1jsqa%2B/2Ug4d/1HGDfpnRh55zaCMGq3nPa0r37EA5wej9v5qIdt5DH9EDMxWCdmOt6hbEUCzERjLsVqrPqwCgMRzSYysJAXPDe2INE8s36hGuDz0jhlD3scspvfQYm%2Blg%2BgzVsalOhDwDl8ughg08fD9Vc2qekigMt7rMJX3DVfZBCLy3MVXq/8dY4CLnie35INVLhiIWZw4/NZbDhesQspg2UZ3st/Vs8QuZv1Yjb9DYKIfomH5Wx6yei%2B%2BLMUs3/gxOWFuG38sKIRynxLP1NaYg0kNfaWb6nsXpv4xXmAz6vlW8YnZBxmyH68sjUdnZAUj8NWRGqMllB5c2hCpvutXv916kO1n4T28JtcyFQ8wvnybSPUdxzXQabiMWJv0Mqj3fZ/jyeESZ025xL5ONz1sqvnrWKy1A0D2T5rDHd2DWYq9jcuqarJpjo3Iu%2B9c%2Bsai8mew9s%2B0/sqrh9Mp9PznFj2Zh9O0WGGWlIdawv9albnvCcmLM6FZ4SHOpsTVWfsubynUYGsOu33Bp2APzaGz90wZC3ftYwEpRyY2Kcx79F0z/98l6Gg9DUEfOzhHWRZTIiDHYc5V8f3ud8CyO3tIjp1sLHctIi0Yz1A%2Br5HFhk262D3ytm3993%2BdOLKiZOd6mDZJefb9FSL3NB0nBzF64CyebjNVumd2F%2B35%2BhxuphuF1n6Rt4Fs1WqG7G%2BPu7P/PFCTyWqxGMnUJ6OaiZbyClA0k5XeEkKokKRs7h8dK%2Bc8iF4SQoScH08xcv2FluJOs7rRgBaiTpOUURx5Rj47ykz3WfLXzAUx6D3cHtF%2BvUeooucnr2F6GJLfg/RRRXFTUTnJ9Xk7uE9npWGlNow7zHSqRrVpTyr4i7RdzhSsmobRJvwDuAu%2B5YMup/kCZQ7GozfO/3NldouEGSXLU%2BVuh7v4Vry6srtnEz/7rHsa43LpXbVtdrbM0dSCKjaZKVbdasyW7XqZino%2BPHfn2PaCRt3sino7%2Bgl9NQm%2B3q7RFAno0i3tBp2mi7Qr22CNRX3cV1ZmHItkdCtUgZ1ukoIfRmYTlcJIcWk8jRJ7MvQuL6I7ZWAth4R0WYR7bkSoiaNnlp8%2Bhrdh%2Bgc%2BosPBBJXPIWi5TBOoWg5YFYoWi5EUBhSywERorlfQvRoGkWLsQew0rONtLqoFC1NNI0romgfgI7zAUK3ppo0xtOSfXidBUP93Abq17IkehEz7HfJJHq5DY1bgI32Uo5pOB%2BCoyZfO3fOOzjUQXvTlDUhxG4kvoHYmBSbqNRq/kn9abE9zWw/cr7fQ/Yj4tohig12yK6ByWQymUwmk8lkMplMJpPJWf4BjsowECKrhpwAAAAASUVORK5CYII%3D

## Dataset

First off, we need something that tells us the shape of each country. For that, I used the Natural Earth sovereign states dataset. It contains a .shp file, that for each country stores a sequence of points $\{(x_i, y_i)\}_{0 \leq i < N}$ and you have to connect the dots between them to get the shape of the country.

It also has information about the parts of each country (the $C$ we talked about before isn’t necessarily connected), it tells us which $(x_i, y_i)$ belong to each part.

Then, a country will be represented as a finite union of polygons, one polygon per part of the country.

To read the .shp file I used the pyshp library.

There’s a small problem too that I have to talk about. We cannot use those $(x_i, y_i)$ directly to draw the countries in a plane because they are in WGS84 format (a very accurate longitude-latitude system), so we would be doing an equirectangular projection of the Earth, which really distorts a lot of countries.

So what, for each country, I transform its points from the equirectangular projection to an azimutal projection centered in some point that depends on the country in question.

That point is obtained by computing the midpoint of two random points from the border of the country. This is not the best (if the country is not convex, then the midpoint isn’t necessarily inside it), but it works pretty well.

In order to do all the transformations I used the pyproj library.

## Algorithm

For each country, what we have to do is to find the circle that maximizes the formula at the top of the article. In order to do that, I use a regular gradient descent algorithm. I have two initial guesses and make them a little better each iteration.

But let’s talk about inscribed and circumscribed circles first. Given a geometrical shape (for example a rectangle), there is a circle that fits inside (resp. outside) and maximizes (resp. minimizes) its area. So, for each country we compute a frame that contains it (a rectangle) and compute the inscribed and circumscribed circles for that rectangle. Those two circles will be the initial guesses.

As we said, we apply a gradient descent algorithm to those circles. In order to use gradient descent, we have to define the neighbourhood of a circle, that is the circles to which we will try to move to make our guess better.

The neighbourhood of a circle will be the circles that we get by moving it a little up, down, left or right, and also making it a little bigger or smaller.

As always, the gradient method has the problem of local maxima, because it can get stuck in them. I don’t care about that, given that our dataset is prone to having only one maxima.

I also run the gradient descent algorithm with a couple more of guesses, that come from the inscribed and circumscribed circles of the frames of the largest parts of the country.

To compute areas of polygons, and intersection between polygons and circles, I used the shapely library, that is impressively good.

## Code

If you want to see the details of the implementation, feel free to take a look at the code. It outputs code to generate the table in this post, it is easy to change it to get the .png files.

## Epilogue

The idea of this post came from a great post that analyzes the rectangularness of countries. We both use gradient descent, to find an approximated solution to our problems, although the code is completely different. We used the same dataset though, so I should make the same clarification: all geopolitical decisions were outsourced to Natual Earth.

Edit (28 Jul 2016): Updated list and included a fix for projections. Now I use an azimuthal projection centered in each country, which allows a more precise representation. All the details can be seen in the gist, which has been updated accordingly. Also added an index for polygons to make intersection computation faster.
{"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 2, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0}