Skip to content

Commit

Permalink
v0.6.57
Browse files Browse the repository at this point in the history
  • Loading branch information
mbloch committed Dec 8, 2023
1 parent 0762e1f commit 8cf9255
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 28 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
v0.6.57
* Added io.ifile() method for creating dynamic input files in the run command

v0.6.56
* Added support for importing ES modules using the -require command.
* Removed the -require init= function.
Expand Down
29 changes: 15 additions & 14 deletions REFERENCE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# COMMAND REFERENCE

This documentation applies to version 0.6.56 of mapshaper's command line program. Run `mapshaper -v` to check your version. For an introduction to the command line tool, read [this page](https://github.com/mbloch/mapshaper/wiki/Introduction-to-the-Command-Line-Tool) first.
This documentation applies to version 0.6.57 of mapshaper's command line program. Run `mapshaper -v` to check your version. For an introduction to the command line tool, read [this page](https://github.com/mbloch/mapshaper/wiki/Introduction-to-the-Command-Line-Tool) first.

## Command line syntax

Expand Down Expand Up @@ -1072,7 +1072,7 @@ Common options: `target=`

Expression context:

`target` object
`target` object provides data and information about the command's target layer
- `target.layer_name` Name of layer
- `target.geojson` (getter) Returns a GeoJSON FeatureCollection for the layer
- `target.geometry_type` One of: polygon, polyline, point, `undefined`
Expand All @@ -1082,11 +1082,10 @@ Expression context:
- `target.bbox` GeoJSON-style bounding box
- `target.proj4` PROJ-formatted string giving the CRS (coordinate reference system) of the layer

`io` object (useful for importing dynamically generated datasets; see example below)
- `io.addInputFile(<filename>, <data>)` Add JSON data that can be referenced by filename in the command string generated by `-run`.
`io` object has a method for passing data to the `-i` command.
- `io.ifile(<filename>, <data>)` Create a temp file to use as input in a `-run` command (see example 2 below)


**Example 1:** Apply a custom projection based on the layer extent
**Example 1:** Apply a custom projection based on the layer extent.

```bash
$ mapshaper -i country.shp -require projection.js -run '-proj {tmerc(target.bbox)}' -o
Expand All @@ -1101,19 +1100,22 @@ module.exports.tmerc = function(bbox) {
};
```

**Example 2:** Convert points to a Voronoi diagram
**Example 2:** Convert points to a Voronoi diagram using a template expression
together with an external script.

```bash
$ mapshaper -i points.geojson -require script.js -run '-i {voronoi(target, io)}' -o
$ mapshaper points.geojson \
-require script.js \
-run '-i {io.ifile("voronoi.json", voronoi(target.geojson, target.bbox))}' \
-o
```

```javascript
// contents of script.js file
module.exports.voronoi = async function(target, io) {
module.exports.voronoi = async function(points, bbox) {
const d3 = await import('d3-delaunay'); // installed locally
const points = target.geojson; // assume 'Point' geometry
const coords = input.features.map(feat => feat.geometry.coordinates);
const voronoi = d3.Delaunay.from(coords).voronoi(target.bbox); // constrain to data bounds
const coords = points.features.map(feat => feat.geometry.coordinates);
const voronoi = d3.Delaunay.from(coords).voronoi(bbox);
const features = Array.from(voronoi.cellPolygons()).map(function(ring, i) {
return {
type: 'Feature',
Expand All @@ -1124,8 +1126,7 @@ module.exports.voronoi = async function(target, io) {
}
};
});
io.addInputFile('polygons.json', {type: 'FeatureCollection', features: features})
return 'polygons.json';
return {type: 'FeatureCollection', features: features};
};
```

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mapshaper",
"version": "0.6.56",
"version": "0.6.57",
"description": "A tool for editing vector datasets for mapping and GIS.",
"keywords": [
"shapefile",
Expand Down
2 changes: 1 addition & 1 deletion src/commands/mapshaper-run.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { parseCommands } from '../cli/mapshaper-parse-commands';
import { stop, message, truncateString } from '../utils/mapshaper-logging';
import utils from '../utils/mapshaper-utils';
import cmd from '../mapshaper-cmd';
import { getIOProxy } from '../expressions/mapshaper-job-proxy';
import { getIOProxy } from '../expressions/mapshaper-io-proxy';
import { evalTemplateExpression } from '../expressions/mapshaper-template-expressions';
import { commandTakesFileInput } from '../cli/mapshaper-command-info';

Expand Down
17 changes: 17 additions & 0 deletions src/expressions/mapshaper-io-proxy.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import utils from '../utils/mapshaper-utils';

export function getIOProxy(job) {
async function addInputFile(filename, content) {
if (utils.isPromise(content)) {
content = await content;
}
io._cache[filename] = content;
return filename; // return filename to support -run '-i {io.ifile()}'
}
var io = {
_cache: {},
addInputFile,
ifile: addInputFile // ifile() is an alias for addInputFile
};
return io;
}
10 changes: 0 additions & 10 deletions src/expressions/mapshaper-job-proxy.mjs

This file was deleted.

12 changes: 12 additions & 0 deletions test/run-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ describe('mapshaper-run.js', function () {
assert.deepEqual(JSON.parse(out['selection.json']), [{foo: 'bam'}])
})

it('supports io.ifile() alias', async function() {
var data = [{foo: 'bar'}, {foo: 'baz'}, {foo: 'bam'}];
var include = '{ \
subset: async function(fc) { \
return [fc.features[2].properties]; \
}}';
var cmd = `-i data.json -include include.js
-run '{io.ifile("selection.json", subset(target.geojson))}' -o`;
var out = await api.applyCommands(cmd, {'include.js': include, 'data.json': data});
assert.deepEqual(JSON.parse(out['selection.json']), [{foo: 'bam'}])
})

it('supports creating a command on-the-fly and running it', function (done) {
var data = [{foo: 'bar'}];
var include = '{ \
Expand Down

0 comments on commit 8cf9255

Please sign in to comment.