wavded / ogr2ogr

An ogr2ogr wrapper library
MIT License
214 stars 46 forks source link

Allow for configuring the CLI command used to invoke GDAL ogr2ogr #58

Closed zachsa closed 3 years ago

zachsa commented 3 years ago

Hi,

Thank you for your library! I'm just starting to look into GDAL (I'm an absolute beginner!) and this library will make that easier.

My preference for invoking GDAL would be via a Docker Image rather than installing the GDAL CLI. Looking at the source code: https://github.com/wavded/ogr2ogr/blob/master/index.js#L211:

let s = cp.spawn('ogr2ogr', logCommand(args), commandOptions)

I would need to alias the ogr2ogr command as part of my server configuration to allow for using the GDAL Docker image:

# .bash_profile
alias ogr2ogr="docker run --rm osgeo/gdal:alpine-small-latest ogr2ogr"

Would it be useful to allow for configuring the command passed to cp.spawn? i.e. something like this?

var ogr2ogr = require('ogr2ogr')

var shapefile = ogr2ogr('/path/to/spatial/file.geojson')
  .gdal('docker run --rm osgeo/gdal:alpine-small-latest')
  .format('ESRI Shapefile')
  .skipfailures()
  .stream()

I think something like this would work:

Ogr2ogr.prototype.gdal = function (str) {
  this._gdal = str
  return this
}

let cmd = this._gdal ? `${this._gdal} ogr2ogr` : 'ogr2ogr'
let s = cp.spawn(cmd, logCommand(args), commandOptions)

Please let me know if you think this is a good idea and if you would accept a pull request for this.

zachsa commented 3 years ago

Actually I have just tested this, and the command is not set this way

wavded commented 3 years ago

I'd be open to PR that allows you to switch the base command from the default.

zachsa commented 3 years ago

I've added some code that as far as I can tell will work. (I'm sure that it allows for switching the base command).

However, I'm not able to get the examples to run -, related to this thread: https://github.com/wavded/ogr2ogr/issues/26

If I replace this statement:

let s = cp.spawn('ogr2ogr', logCommand(args), commandOptions)

With this statment (i.e. provide a command that I know exists on the $PATH of the invoking user):

let s = cp.spawn('docker run -v /tmp/:/tmp --rm osgeo/gdal:alpine-small-latest ogr2ogr', logCommand(args), commandOptions)

Running the examples I get the ENOENT error (the docker command appears not to be findable). If I replace cp.spawn with cp.exec then I get an error from the GDAL ogr2ogr client:

let s = cp.exec('docker run -v /tmp/:/tmp --rm osgeo/gdal:alpine-small-latest ogr2ogr', logCommand(args), commandOptions)

FAILURE: no target datasource provided

I think that the spawn command is not working as expected. I'm using Node.js 14.15 on WSL2 Ubuntu 20.04

zachsa commented 3 years ago

I've adjusted the API like this:

// examples/docker.js
const ogr2ogr = require('../')

ogr2ogr('../test/samples/sample.shp.zip')
  .command('docker run -v /tmp/:/tmp --rm osgeo/gdal:alpine-small-latest ogr2ogr') // <= This is the addition
  .exec(function (er, data) {
    if (er) {
      console.log('er', er)
    } else {
      console.log('data', data)
    }
  })
wavded commented 3 years ago

Release in v2.1.0

zachsa commented 3 years ago

Thanks very much!