The file mapshaper-browserify.js
is generated from the mapshaper
node module (see LICENSE
file) using the browserify
node module, as suggested in the V8 vignette:
The license for mapshaper
and its dependencies, as well as their licenses, are listed in node_packages.csv
.
The modules to include in the browserify
call are listed here:
https://github.com/mbloch/mapshaper/blob/17bbd1ffb7bd7e7b755f44b2b2e6e45eb707fd4b/package.json#L31 (TODO: automate this)
npm install -g browserify
npm install mapshaper
echo "global.mapshaper = require('mapshaper');" > in.js
browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r kdbush -r @tmcw/togeojson -r @placemarkio/tokml -r idb-keyval in.js -o inst/mapshaper/mapshaper-browserify.js
rm in.js
To make this work in V8, which does not have all of the capability of Node, a couple of modifications are required:
Because the functions setTimeout
and setImmediate
are not available in the V8 engine, the definition of reduceAsync
(approximately line 6579
in the browserified file) must be slightly modified to avoid them. Thanks to @timelyportfolio for figuring this out:
utils.reduceAsync = function(arr, memo, iter, done) {
// For V8 in R: commented out the next line wich looks for setTimeout / setImmediate
//var call = typeof setImmediate == 'undefined' ? setTimeout : setImmediate;
var i=0;
next(null, memo);
function next(err, memo) {
// Detach next operation from call stack to prevent overflow
// Don't use setTimeout(, 0) if setImmediate is available
// (setTimeout() can introduce a long delay if previous operation was slow,
// as of Node 0.10.32 -- a bug?)
if (err) {
return done(err, null);
}
// For V8 in R: comment out the `call` call, and replace with anonymous function
/*
call(function() {
if (i < arr.length === false) {
done(null, memo);
} else {
iter(memo, arr[i++], next);
}
}, 0);
*/
(function() {
if (i < arr.length === false) {
done(null, memo);
} else {
iter(memo, arr[i++], next);
}
})();
}
};
In mapshaper-browserify.js
, on line 13713 in the internal.exportGeoJSON
function
definition, where internal.exportDatasetAsGeoJSON
is called, change ofmt
argument
from 'buffer'
to 'geojson'
, so the line looks like this:
content: internal.exportDatasetAsGeoJSON(d, opts, 'geojson'),
In mapshaper-browserify.js
, on lines 28506-28508, comment out the call to
internal.printStartupMessages()
:
// if (!internal.runningInBrowser()) {
// internal.printStartupMessages();
// }
Finally, minify (uglify() the javascript to make it smaller and faster:
npm install -g uglify-js
cd inst/mapshaper
uglifyjs mapshaper-browserify.js -o mapshaper-browserify.min.js -b beautify=false,ascii_only=true
rm mapshaper-browserify.js
(the ascii_only=true
is necessary to make it run on Windows)
The Version of mapshaper does not appear to be programmatically accessible from
runCommands()
or applyCommands()
as of version 0.6.25, so it must be manually updated in the bundled_ms_version()
function.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.