Skip to content

Instantly share code, notes, and snippets.

@emamd
Last active March 9, 2021 19:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emamd/03b546890ed9f89734536224dfefd62e to your computer and use it in GitHub Desktop.
Save emamd/03b546890ed9f89734536224dfefd62e to your computer and use it in GitHub Desktop.
Getting started with mapshaper

Getting started with mapshaper

Mapshaper is a javascript library for editing GIS data formats including GeoJSON, TopoJSON, Shapefiles and others. It's easier to install and can replace some of the functionality of ogr2ogr, allowing for integration into node-based workflows.

There's also an online gui at mapshaper.org you can use.

Mapshaper command reference

Some practical examples

Installation

You can install mapshaper globally with npm

$ npm install -g mapshaper

If you're going to be using mapshaper in several different projects, however, I'd recommend installing locally on a per-project basis, and using npx to run the commands. I'll be using the npx format here.

$ npm install mapshaper

Then you can run any subsequent commands with npx mapshaper ... to use your local installation.

Setup files

We'll use another command line program, curl to download shapefiles for U.S. counties and Congressional Districts.

$ curl -O https://www2.census.gov/geo/tiger/GENZ2017/shp/cb_2017_us_cd115_500k.zip
$ curl -O https://www2.census.gov/geo/tiger/GENZ2016/shp/cb_2016_us_county_500k.zip

Then unzip them

$ unzip cb_2016_us_county_500k.zip
$ unzip cb_2017_us_cd115_500k.zip

Convert file types

Now we can use mapshaper to convert both of these shapes to geojson. The * is a wildcard operator we can use to run the command on all files ending in .shp at once:

$ npx mapshaper -i *.shp -o format=geojson

Filter data

You can also filter fields from the data. In this case, instead of overwriting the json files, I'm going to create a new file indicating that this has been filtered in the filename.

When specifying fieldnames, make sure not to leave spaces between commas or it will throw an error.

# For the county layer
$ npx mapshaper -i cb_2016_us_county_500k.json \
	-filter-fields STATEFP,COUNTYFP,GEOID,NAME \
	-o us_counties_filtered.json format=geojson

# For congressional districts
$ npx mapshaper -i cb_2017_us_cd115_500k.json \
	-filter-fields STATEFP,CD115FP,GEOID,CDSESSN \
	-o congressional_districts_filtered.json format=geojson

You could also filter by a data field, for example, to get a geojson of California counties:

$ npx mapshaper -i us_counties_filtered.json \
	-filter 'STATEFP == "06"' \
	-o california_counties.json format=geojson

Simplify shapes

These shapefiles are big! To use them on a map we'll have to simplify. That's easy in mapshaper too. This time, to avoid overwriting data, we'll have to specify the input and output filenames.

# keep 10% of vertices in the output
$ npx mapshaper congressional_districts_filtered.json \
	-simplify 10% \
	-clean \
	-o congressional_districts_simplified.json
	
$ npx mapshaper us_counties_filtered.json \
	-simplify 10% \
	-clean \
	-o counties_simplified.json 

You'll have to try different values to see what exactly will work. The Mapshaper GUI is a good way to test this.

Projection

You can reproject too, using either a projection string or a number of common aliases you can see by typing npx mapshaper -projections.

Let's try converting to Albers USA.

$ npx mapshaper counties_simplified.json -proj albersusa -o us_counties_albers.json

We can also convert the California file we created into California Albers

$ npx mapshaper california_counties.json -proj +init=EPSG:3310 -o california_counties_projected.json

Combining features

One thing I like to do is create state shapes by dissolving the county shapes together, this makes sure our states have consistent borders with the counties.

$ npx mapshaper us_counties_albers.json \
	-dissolve STATEFP -o states_albers.json

Bringing into Illustrator

You can then convert your end result into an SVG and import into Illustrator.

$ npx mapshaper us_counties_albers.json -o us_counties_albers.svg

Next steps

So what else can you do with this? I like to arrange data processing steps into make files, allowing me to set file inputs and outputs separately. This command, for example, takes three shapefiles and combines them into one topojson file. You could call this with make project-files/topojson/districts-merged.topojson

# files after the colon are the input files used in the command
topojson/merged_districts.topojson: cb_2017_us_cd115_500k.shp \
	cb_2016_us_county_500k.shp 
	
  	# Make the output directory if it doesn't exist
	@mkdir -p $(dir $@)
	@rm -f $@

	# ^i is a variable representing the input files, 
  	# $@ represents the output file
	npx mapshaper \
		-i $^ combine-files snap \
		-o $@ format=topojson

This is only the barest bones of what you can do with Mapshaper. Creator Matt Bloch has detailed many more examples here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment