inst/mapshaper/README.md

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

Modifications to mapshaper:

To make this work in V8, which does not have all of the capability of Node, a couple of modifications are required:

setTimout and setImmediate

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);
      }
    })();
  }
};

Output to geojson, not buffer:

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'),

Don't try to print startup messages (throws errors)

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.



ateucher/rmapshaper documentation built on Nov. 2, 2023, 4:23 p.m.