TigerFetch.jl

Download TIGER/Line shapefiles from the US Census Bureau
Log | Files | Refs | README | LICENSE

simple_map.md (3180B)


      1 # Drawing a simple map
      2 
      3 
      4 ```@setup simplemap
      5 import Pkg; 
      6 Pkg.add(["CairoMakie", "DataFrames", "DataFramesMeta"])
      7 Pkg.add(["GADM", "GeoMakie", "GeometryOps", "GeoJSON", "Shapefile", "ZipFile"]);
      8 nothing; #hide
      9 ```
     10 
     11 You will need a bunch of libraries to plot these; maybe setup a temporary environment, because it is not fun waiting for Makie to recompile at every startup.
     12 ```@example simplemap
     13 using CairoMakie, DataFrames, DataFramesMeta
     14 using GADM, GeoMakie, GeometryOps, GeoJSON, Shapefile, ZipFile
     15 using TigerFetch
     16 tmp_dir = mktempdir(); map_dir = joinpath(tmp_dir, "map"); 
     17 nothing; #hide
     18 ```
     19 
     20 ## Plotting county subdivisions
     21 
     22 We are downloading the county shapefiles (which is a national file), subsets it to Minnesota and plot it.
     23 ```@example simplemap;
     24 tigerdownload("county"; output=map_dir) ;
     25 isfile(joinpath(map_dir, "tl_2024_us_county.zip"))
     26 nothing; #hide
     27 ```
     28 
     29 First, we process the file which is national to only keep counties in the state
     30 ```@example simplemap;
     31 df_shp_cty = Shapefile.Table(joinpath(map_dir, "tl_2024_us_county.zip")) |> DataFrame;
     32 @rsubset!(df_shp_cty, :STATEFP=="27");
     33 nothing; #hide
     34 ```
     35 
     36 ```@example simplemap;
     37 fig = Figure(size=(750,900));
     38 homerule_centroid = GeometryOps.centroid(df_shp_cty.geometry);
     39 ga = GeoAxis(fig[1, 1]; 
     40     dest = "+proj=ortho +lon_0=$(homerule_centroid[1]) +lat_0=$(homerule_centroid[2])",
     41     xticksvisible = false, xgridvisible = false, xticks=[0],
     42    yticksvisible = false, ygridvisible = false, yticks=[0]);
     43 poly!(ga, df_shp_cty.geometry;
     44       color=:white,
     45       strokecolor = :black, strokewidth = 0.5, shading = NoShading, 
     46       colormap = :dense, alpha = 0.5);
     47 save("p1.svg", fig); nothing # hide
     48 ```
     49 ![](p1.svg)
     50 
     51 
     52 ## Addings water areas and roads
     53 
     54 ### Roads
     55 Roads are at the state level and water areas at the county level, so this will complete the example.
     56 
     57 From simple to more complicated we start with primary and secondary roads
     58 ```@example simplemap;
     59 tigerdownload("primarysecondaryroads"; state="MN", output=map_dir);
     60 df_shp_roads = Shapefile.Table(joinpath(map_dir, "tl_2024_27_prisecroads.zip")) |> DataFrame;
     61 lines!(ga, df_shp_roads.geometry; color=RGBf(255/255, 203/255, 71/255), alpha=0.75, linewidth=0.2);
     62 save("p2.svg", fig); nothing # hide
     63 ```
     64 ![](p2.svg)
     65 
     66 
     67 ### Water
     68 And the water areas; we download them in a separate directory because there is one file per county:
     69 ```@example simplemap;
     70 mkpath(joinpath(map_dir, "MN"));
     71 tigerdownload("areawater"; state="MN", output=joinpath(map_dir, "MN"));
     72 nothing; #hide
     73 ```
     74 
     75 Then we read all of the downloaded shapefiles in the dictionary and keep only the subset of the largest lakes or rivers:
     76 ```@example simplemap
     77 df_shp_water = [ DataFrame(Shapefile.Table(joinpath(map_dir, "MN", f))) 
     78                  for f in readdir(joinpath(map_dir, "MN")) ];
     79 df_shp_water = reduce(vcat, df_shp_water, cols=:union);       
     80 @rsubset!(df_shp_water, :AWATER > 1_000_000); # only keep larger water 
     81 nothing; #hide
     82 ```
     83 
     84 And now the plot:
     85 ```@example simplemap
     86 poly!(ga, df_shp_water.geometry;
     87       color=RGBf(170/255, 218/255, 255/255),
     88       strokewidth=0.25, strokecolor=RGBf(144/255, 202/255, 249/255));
     89 save("p3.svg", fig); nothing # hide
     90 ```
     91 ![](p3.svg)
     92 
     93