Best Way of Handling Shapefiles in Makie

Here I tried something out, the conversion method is inefficient because the GeoInterface seems to create lots of little arrays. But hopefully it’s correct:

using Shapefile
using CairoMakie
using DataFrames
using GeometryBasics: Polygon

# I downloaded this manually and extracted the shape file
url = "https://www2.census.gov/geo/tiger/GENZ2018/shp/cb_2018_us_state_5m.zip"

shapefile = "Downloads/cb_2018_us_state_5m/cb_2018_us_state_5m.shp"
table = DataFrame(Shapefile.Table(shapefile))
filter!(:NAME => (
    x -> x ∉ [
        "Alaska",
        "American Samoa",
        "Guam",
        "Commonwealth of the Northern Mariana Islands",
        "United States Virgin Islands",
        "Hawaii",
        "Puerto Rico",
        ]),
    table)

function Makie.convert_arguments(::Type{<:Poly}, p::Shapefile.Polygon)
    # this is inefficient because it creates an array for each point
    polys = Shapefile.GeoInterface.coordinates(p)
    ps = map(polys) do pol
        Polygon(
            Point2f0.(pol[1]), # interior
            map(x -> Point2f.(x), pol[2:end]))
    end
    (ps,)
end

let
    f = Figure()
    ax = Axis(f[1, 1])
    foreach(table.geometry) do geo
        poly!(ax, geo)
    end
    f
end

3 Likes