For coastal countries with a lot of islands, CountryData[tag,"Polygon"]
gives something of the form Polygon[{island1, island2, island3,...}]
, where island1
and the like is another list of latitudes and longitudes.
The case is simpler for inland countries. CountryData[tag,"Polygon"]
gives Polygon[{island1}]
, where island1 is simply the mainland, and is itself a list of latitudes and longitudes.
An example can be given using UK and Venezuela:
Table[Length /@ First[CountryData[country, "Polygon"]], {country, {"UnitedKingdom", "Venezuela"}}]
The result is:
{{20, 25, 31, 54, 52, 63, 141, 195, 1927}, {491}}
which means that UK is made up of 9 polygons/islands, and Venezuela only 1.
To fill a country's land with its own flag, we must be careful to apply the flag texture to all the islands. The important thing is to treat each island of a country one by one.
To apply a texture to any polygon, we must first come up with a function that can yield the correct VertexTextureCoordinates
. For example:
countryRescale1[polygon_] := (Transpose[Rescale /@ Transpose[First[polygon]]])
The function accepts as argument a polygon of an island of a country, which is of the form Polygon[{{x1,y1},{x2,y2},...}}]
. We obtain the list of coordinates with First[]
.
We apply transpose to the list of coordinates {{x1,y1},{x2,y2},...}}
, so that we group all the x's together, and y's together: {{x1, x2, x3, ...}, {y1, y2, y3, ...}}
. We apply to it Rescale[]
, so that x's and y's are both rescaled from 0 to 1 separately. Then apply transpose to group them back into {{x1,y1},{x2,y2},...}}
, where x
and y
is now in [0,1]
.
Then we can overlay the flag onto a country. Let's use Hong Kong (though not a country, but it has many islands) as an example. The important thing is to treat each island of a country one by one.
Graphics[{EdgeForm[Black], Texture[CountryData["HongKong", "Flag"]],
Polygon[#, VertexTextureCoordinates -> countryRescale1[Polygon[#]]] & /@
First[CountryData["HongKong", "Polygon"]]}]
We map the pure function Polygon[#, VertexTextureCoordinates -> countryRescale1[Polygon[#]]]&
to the expression First[CountryData["HongKong", "Polygon"]]
, which in itself is a list of islands { {{x1, y1}, {x2, y2}, ..., {xn,yn}}, {{x1, y1}, {x2, y2}, ...}, ... }.
So it's just like:
Graphics[{EdgeForm[Black], Texture[CountryData["HongKong", "Flag"]],
{Polygon[], Polygon[], Polygon[] ... }]
The result looks like this:
For Argentina, the island province Tierra del Fuego (the bottom right triangular piece of land) is also treated with the flag:
The final thing left to do is to apply this to all countries to make a world flag map:
Graphics[{EdgeForm[Black], Table[{Texture[CountryData[c, "Flag"]],
Polygon[#, VertexTextureCoordinates -> countryRescale1[Polygon[#]]] & /@
First[CountryData[c, "FullPolygon"]]}, {c, CountryData[]}]}, ImageSize -> 700]
The result looks like this:
For better flags, one can refer to this post: Why do some CountryData flags render at low resolution?
ImagePad
useful if you want small flags inside country borders $\endgroup$