Skip to content

Using mapshaper programmatically

Matthew Bloch edited this page Apr 12, 2020 · 20 revisions

This page is for developers who want to use mapshaper's geoprocessing functions in their own applications. Updated for version 0.5.0

Option One: make

One way of scripting mapshaper is to call the mapshaper command line program from make or other build tool.

If you include mapshaper as a dependency in the package.json file of a Node.js project, the executable programs mapshaper and mapshaper-xl can be found in node_modules/.bin/ and node_modules/mapshaper/bin/.

Here's an example Makefile target:

europe.json: shp/europe.shp
	mapshaper snap $< encoding=utf8  \
	-rename-layers countries \
	-filter "CONTINENT == 'Europe'" \
	-simplify 15% keep-shapes \
	-o format=topojson $@

Option Two: Node API

Mapshaper has three API functions for running editing commands: runCommands(), applyCommands() and runCommandsXL(). All three functions take a commands option, which is a string containing the same command line options that are passed to the mapshaper command line program.

runCommands()

runCommands(commands[, input][, callback])

commands A command line string containing mapshaper commands (typically starting with -i and ending with -o).

input An optional JS object containing contents of files referenced by -i command(s), indexed by file name. Input files are read from the filesystem if they are not present in the input argument.

callback An optional Node-style callback: function(Error). If called without a callback, runCommands() returns a Promise.

// Example: converting a directory of Shapefiles to GeoJSON
var mapshaper = require('mapshaper');
mapshaper.runCommands('-i shapefiles/*.shp -o geojson/ format=geojson');

applyCommands()

applyCommands(commands[, input][, callback])

This function has the same signature as runCommands(). Instead of writing files generated by the -o command, mapshaper sends the output file contents to a callback (or Promise if a callback is not provided). File data is placed in a JavaScript object and indexed by filename.

// Example: converting a CSV string to GeoJSON
const input = {'input.csv': 'lat,lng,value\n40.3,-72.3,1000'};
const cmd = '-i input.csv -points x=lng y=lat -o output.geojson';

// using callback
mapshaper.applyCommands(cmd, input, function(err, output) {
	// do something with {"output.geojson": <Buffer>}
});

// using Promise
const output = await mapshaper.applyCommands(cmd, input);

runCommandsXL()

runCommandsXL(commands[, options][, callback])

This function runs commands in a sub-process that has a larger maximum heap size than Node's default. Calling this function is equivalent to running the mapshaper-xl command line program. You can override the default 8gb amount by passing an options object, like this: {xl: "16gb"}.

This function only takes input from the filesystem; unlike runCommands(), there is no input option.

Note on Shapefile input

To input a Shapefile using applyCommands() or runCommands(), in addition to passing the contents of the .shp file (as a Buffer or ArrayBuffer), you'll probably want to pass the .dbf file (as a Buffer or ArrayBuffer) and the .prj file (as a string). The .dbf file contains attribute data and the .prj file contains coordinate system data.