Giter Club home page Giter Club logo

ogr2ogr's Introduction

Build Status NPM NPM Downloads

Looking for V2 documentation? Click here.

ogr2ogr wraps the ogr2ogr GDAL tool to enable file conversion and re-projection of spatial data in simplified friendly API.

Installation

  1. Install GDAL tools (includes the ogr2ogr command line tool)

  2. Install package:

npm install ogr2ogr

Usage

ogr2ogr takes either a path, a stream, or a GeoJSON object. The result of the transformation will depend on the format returned.

// Using CommonJS modules
const ogr2ogr = require('ogr2ogr').default
// Using ECMAScript modules or Typescript
import ogr2ogr from 'ogr2ogr'

// Promise API
(async() {
  // Convert path to GeoJSON.
  let {data} = await ogr2ogr('/path/to/spatial/file')
  console.log(data)

  // Convert GeoJSON object to ESRI Shapefile stream.
  let {stream} = await ogr2ogr(data, {format: 'ESRI Shapefile'})

  // Convert ESRI Shapefile stream to KML text.
  let {text} = await ogr2ogr(stream, {format: 'KML'})
  console.log(text)
})()

// Callback API
ogr2ogr('/path/to/spatial/file').exec((err, {data}) => {
  console.log(data)
})

Formats

ogr2ogr has varying support for format input and output. Consult the particular driver you are interested in for more details. It is highly recommend to run the latest version of GDAL to get the best support. This project attempts to cast the widest net for support. Here are some notables:

Drivers Output Notes
GeoJSON data Default format returned when none specified
CSV, GeoRSS, GML, GMT, GPX, JML, KML, MapML, PDF, VDV text Drivers supporting /vsidout/ return text
Other stream All other drivers return a file stream

API

ogr2ogr(input, options?) -> Promise<output>

The input may be one of:

  • A path (string). This includes file paths and network paths including HTTP endpoints.
  • A ReadableStream.
  • A GeoJSON object.

The following options are available (none required):

  • format - Output format (default: GeoJSON)
  • timeout - Timeout, in milliseconds, before command forcibly terminated (default: 0)
  • maxBuffer - Max output size in bytes for stdout/stderr (default: 1024 * 1024 * 50)
  • options - Custom ogr2ogr arguments and driver options (e.g. ['--config', 'SHAPE_RESTORE_SHX', 'TRUE'])
  • env - Custom environmental variables (e.g. {ATTRIBUTES_SKIP: 'YES'})
  • destination - Select another output than the output object (e.g. useful for writing to databases).
  • command - Command to run (default: ogr2ogr)

The output object has the following properties:

  • cmd - The ogr2ogr command executed (useful for debugging).
  • text - Text output from drivers that support /vsistdout/ (see formats above)
  • data - Parsed GeoJSON output (used when format is GeoJSON)
  • stream - A ReadableStream of the output. Used for drivers that do not support /vsistdout/.
    • If a driver generates more than one file (like ESRI Shapefile), this will be a zip stream containing all the data.
  • extname - The file extension of the data returned.
  • details - Any text printed to STDERR. This includes any warnings reported by ogr2ogr when it ran.

ogr2ogr(input, options?).exec((err, output))

The callback API supports the same options as above but in a NodeJS style callback format.

Tips and tricks

Running ogr2ogr in a Docker container:

ogr2ogr("/home/.../path/to/spatial/file", {
  command: "docker run -v /home/:/home --rm osgeo/gdal ogr2ogr",
})

Converting an isolated .shp file:

ogr2ogr("/path/to/file.shp", {
  options: ["--config", "SHAPE_RESTORE_SHX", "TRUE"],
})

Getting more debug information by using the CPL_DEBUG option. Debug info added to details on the output object.

ogr2ogr("/path/to/file.shp", {
  options: ["--config", "CPL_DEBUG", "TRUE"],
})

Parsing custom geometry fields in a CSV. Use CSV driver options, like:

ogr2ogr("/path/to/file.csv", {
  options: ["-oo", "GEOM_POSSIBLE_NAMES=the_geom"],
})

Re-project geometry:

ogr2ogr("/path/to/file.shp", {
  options: ["-t_srs", "EPSG:4326"],
})

ogr2ogr's People

Contributors

bertday avatar dcorriveau-borealis avatar dependabot[bot] avatar ffflabs avatar jomel avatar kapouer avatar kriscarle avatar molynerd avatar rdewit avatar svycka avatar wavded avatar yocontra avatar zachsa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ogr2ogr's Issues

Unknown Error

I see the following in my error log. Any ideas?

{
  "message": "ENOENT: no such file or directory, scandir '/tmp/ogr_53c53644160'",
  "stack": "Error: ENOENT: no such file or directory, scandir '/tmp/ogr_53c53644160'\n    at module.exports.runLoopOnce (/home/onemap/services/node_modules/deasync/index.js:66:11)\n    at module.exports (/home/onemap/services/node_modules/deasync-promise/index.js:13:9)\n    at module.exports.interval (/home/onemap/services/node_modules/system-sleep/module.js:24:36)\n    at Object.startup (/home/onemap/services/app.js:3790:13)\n    at Object.<anonymous> (/home/onemap/services/bin/www:5:5)\n    at Module._compile (module.js:652:30)\n    at Object.Module._extensions..js (module.js:663:10)\n    at Module.load (module.js:565:32)\n    at tryModuleLoad (module.js:505:12)\n    at Function.Module._load (module.js:497:3)",
  "errno": -2,
  "code": "ENOENT",
  "syscall": "scandir",
  "path": "/tmp/ogr_53c53644160",
  "level": "error",
  "timestamp": "2018-05-17T06:51:44.927Z"
}

ogr2ogr Warning: organizePolygons()

Hey!

Does anyone has idea how to deal with this error:

Warning 1: organizePolygons() recieved an unexpected geometry. Either a polygon with interior rings or a polygon with less than 4 points or a non-Polygon geometry. Retrun arguments as collection.

What does it mean 'retrun arguments as collection?
I am using data in osm format. Error occurs for some polygons while using:

temp_path = path_to_folder
element = name_of_file
path = path_for_element

r'ogr2ogr {0} {1}.osm multipolygons -nln {2}_ply -lco ENCODING=UTF-8'.format(
        temp_path, os.path.join(path, element), element)

PROJ: proj_create_from_database: Cannot find proj.db

When trying to run the app locally, I'm getting this issue, when using the project function, however, ogr2ogr works on my cmd without issues. I also have the PROJ_LIB environments set in my Environment Variables on windows.

How do i set the PROJ_LIB variable for the app to find the correct location of proj.db?

Thanks. :)

Do I have to install/configure anything external to make sqlite output work?

Hi,

Do I have to install/configure anything external to make sqlite output work?

I can make it work properly for SHP but when I change the output format to sqlite I am getting:

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: ERROR 6: Read or update mode not supported on /vsistdout
ERROR 4: sqlite3_open(/vsistdout/) failed: unable to open database file
SQLite driver failed to create /vsistdout/

    at ChildProcess.<anonymous> (C:\node\ogr2ogr\node_modules\ogr2ogr\index.js:198:18)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:891:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)

My code:

var ogr = ogr2ogr('PG:dbname=xxxx host=xxxx port=xxxx user=xxxx password=xxxx tables=test')
                    .format('SQLite')
                    .options(['-nln', 'test'])
                    .skipfailures()
                    .stream()
    ogr.pipe(fs.createWriteStream('C:/Users/jaitor1/Desktop/test.sqlite'))

converting to geopakacge not working propaly

After hours of searching for the problem, I didn't find anything.
My problem is i want to convert this WFS layer to geopakacge, the conversation done correctly but the output table name is incorrect, i tried using ogr2ogr directly from the terminal everything worked with the correct table name .
I tried to put this command to change the table name but it's not working: -nln dist_2021
Edit: here is the command
ogr2ogr-f GPKG -skipfailures qqw.gpkg /vsicurl/https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/COVID19Surge_Florida_InterventionScenarios/FeatureServer/0/query?f=json&maxRecordCountFactor=30&outFields=*&outSR=4326&resultType=tile&returnExceededLimitFeatures=false&spatialRel=esriSpatialRelIntersects&where=1=1&geometryType=esriGeometryEnvelope --config -nln dist_2022

The program does not function properly

C:\Users\hhx\AppData\Roaming\npm\node_modules\ogr2ogr\examples>node geojson-obj.js

Error: Error: spawn ogr2ogr ENOENT
at ChildProcess. (C:\Users\hhx\AppData\Roaming\npm\node_modules\ogr2ogr\index.js:187:18)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:891:16)
at Socket. (internal/child_process.js:342:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at Pipe._handle.close [as _onclose] (net.js:497:12)
undefined

input stream

is it possible to use a stream as an input (instead of a file path) , as it is done for the output?

I need install gadl in the window?

H:\html\test\samples\sample.lonely.shp
events.js:174
throw er; // Unhandled 'error' event
^

Error: Error: spawn ogr2ogr ENOENT
at ChildProcess. (H:\html\koa\node_modules\ogr2ogr\index.js:222:18)
at ChildProcess.emit (events.js:189:13)
at maybeClose (internal/child_process.js:970:16)
at Socket.stream.socket.on (internal/child_process.js:389:11)
at Socket.emit (events.js:189:13)
at Pipe._handle.close (net.js:600:12)
Emitted 'error' event at:
at wrapUp (H:\html\koa\node_modules\ogr2ogr\index.js:237:15)
at H:\html\koa\node_modules\ogr2ogr\modules\util.js:56:5
at ChildProcess. (H:\html\koa\node_modules\ogr2ogr\index.js:222:7)
at ChildProcess.emit (events.js:189:13)
[... lines matching original stack trace ...]
at Pipe._handle.close (net.js:600:12)
[Finished in 0.8s]

Uncaught errors when opening a bad file

It seems this error type doesn't get caught and bubbled up through the stream, and isn't catchable with a try-catch.

Unable to open datasource `/private/var/folders/4h/83g6gdzn2qbdybd8z251g1lh0000gn/T/61ba5796-8d31-4078-8544-82262525fbae.gdb.zip' with the following drivers.
  -> `PCIDSK'
  -> `netCDF'
  -> `JPEG2000'
  -> `PDF'
  -> `MBTiles'
  ... and so on

Code:

ogr('gdb-empty.zip', 'ESRI Shapefile')
    .format('GeoJSON')
    .project('crs:84')
    .skipfailures()
    .timeout(86400000) // 1 day in ms
    .stream()
	.on('error', (err) => console.error(err))

The process will crash with the uncaught error, instead of catching it in the error event.

gdb-empty.zip

Working example of reading from PostgreSQL table

Is it posible to read from a PostgreSQL table, as in the example below?

ogr2ogr -overwrite output_shape PG:"user=example_user dbname=example_db" <input_table>

I couldn't find a way after looking at the examples/test folders.

Load KML and KMZ issue

when i load kml or kmz that contain server feature collection inside, it will only read the first feature.
The feature collection is separated by

ogr2ogr path in windows

This is more of a support question than an issue I think, so feel free to delete it if it's not appropriate. I'm creating an electron utility for fairly unsophisticated users to merge some GeoJSON files and then convert it to a shapefile. It works great, but having users going through the steps to install gdal/ogr2ogr on windows is a huge hassle. Having them trying to set the path is nearly impossible! It's easy enough to tell them to install OSGeo4W into c:\osgeo4w, is there any way I can tell this module to check there for ogr2ogr instead of having it in the path?

shz file saved as a directory on linux, breaking stream processing

I've been working with this package to convert GeoJson to Shapefile zip stream and it works great....just until I try to package it up in a Node.js Debian docker container. The error I'm getting when trying to convert a stream into a Buffer. It reports an EISDIR which is the stream trying to process it as a file while the OS reports back that it is a directory. I've verified that the .shz file being saved in the linux container as a directory, whereas in my MACOS environment it is saved as a file. The primary difference I can see is that the MAC installed a 3.2 version of ogr2ogr (when I run ogrinfo --version) whereas the linux version installed version 2.1. Not sure if that is the culprit but it seems like some accommodation may need to be made with this package to work in Docker. Here is the code that works on MacOS and not on Linux:

stream2Buffer(inStream) {
    return new Promise((resolve, reject) => {
      const buf = [];

      inStream.on('data', (chunk) => buf.push(chunk));
      inStream.on('end', () => resolve(Buffer.concat(buf)));
      inStream.on('error', (err) => reject(err));
    });
  }
 async convertGeoJsonToShapeFile({ geometry }) {
    const ogr2ogr = Ogr2ogr.default;

    const { stream } = await ogr2ogr(geometry, {
      format: 'ESRI Shapefile'
    });
    const buffer = await this.stream2Buffer(stream);
    return buffer;
 }

Or, if I'm missing something simple to make it work, happy to adjust.

Thanks for making this excellent library!

Currently can't provide custom args when specifying a custom command

Hi,

I previously submitted a pull request for allowing for switching the command to use ogr2ogr via Docker (#60). However I've just checked now and it's not working. Looking at the code I'm actually not sure that it ever worked... I apologise!

I would like to use this feature now though, so I would like to fix it.

Looking at the run function: https://github.com/wavded/ogr2ogr/blob/master/index.ts#L147-L170, it doesn't seem like it's possible to specify an alternative command that requires args.

for example, If I try to run via docker (this is currently in the readme):

ogr2ogr('/home/.../path/to/spatial/file', {
  command: 'docker run -v /home/:/home --rm osgeo/gdal ogr2ogr',
})

Then I get an error:

  Error: spawn docker run -v /home/:/home --rm osgeo/gdal ogr2ogr ENOENT
      at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
      at onErrorNT (node:internal/child_process:477:16)
      at processTicksAndRejections (node:internal/process/task_queues:83:21)

In the code

    let {stdout, stderr} = await new Promise<RunOutput>((res, rej) => {
      let proc = execFile(
        command,
        args,
        {env, timeout: this.timeout, maxBuffer: this.maxBuffer},
        (err, stdout, stderr) => {
          if (err) rej(err)
          res({stdout, stderr})
        }
      )
      if (this.inputStream && proc.stdin) this.inputStream.pipe(proc.stdin)
    })

It looks like the command should actually just be docker, and the args should be ['run', '-v', etc. etc., ... then the ogr2ogr args].

But currently there is no way of specifying this

Cannot send result directly to database

Result won't show up in target database even when setting

.format('PostgreSQL')
.destination('PG:host=127.0.0.1 user=postgres dbname=mydatabase')

It seems the arguments being built looks like this:

ogr2ogr -f PGDump -skipfailures PG:host=127.0.0.1 user=postgres dbname=geoportal

instead of this:

ogr2ogr -f PostgreSQL -skipfailures PG:host=127.0.0.1 user=postgres dbname=geoportal

A quick fix:

// fix PostgreSQL is set to PGDump
if(ogr2ogr._destination.indexOf('PG:') > -1)
    ogr2ogr._format = 'PostgreSQL'

inside

Ogr2ogr.prototype._run()

Or maybe I'm just doing something wrong.

Empty output files when running under Grunt

I'm trying to produce a Grunt plugin that wraps ogr2ogr functionality so I can use it without additional coding in my workflow. But I'm getting empty output files created, with no apparent errors or warnings.

As a standalone (and shabby) piece of code, the following works fine ...

var ogr2ogr = require('ogr2ogr');

var src = 'test/data/src/ne_110m_admin_0_sovereignty.shp';
var dest = 'tmp/ne_110m_admin_0_sovereignty.geojson';
var format = 'GeoJSON';

var ogr = ogr2ogr(src);
ogr.on('ogrinfo', console.error);
ogr.on('error', console.error);
ogr.format(format);
var output = ogr.stream();
output.pipe(fs.createWriteStream(dest));

However, the same code when invoked from within Grunt's environment produces no errors or warnings and while an output file is produced, it's empty.

'use strict';

module.exports = function(grunt) {
    var ogr2ogr = require('ogr2ogr');
    var fs = require('fs');
    var path = require('path');

    grunt.registerMultiTask('ogr2ogr', 'ogr2ogr wrapper task for Grunt', function() {
        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options({
            format: 'GeoJSON',
            // skipFailures: true,
            // projection: 'EPSG:4326',
            // options: null
            // timeout: 15000
        });

        // Iterate over all specified file groups.
        this.files.forEach(function(f) {
            var src = f.src.filter(function(filepath) {
                if (!grunt.file.exists(filepath)) {
                    grunt.log.warn('Source file "' + filepath + '" not found.');
                    return false;
                }
                else {
                    return true;
                }
            }).map(function(filepath, i) {
                grunt.file.mkdir(path.dirname(f.dest));

                var ogr = ogr2ogr(filepath);
                ogr.on('ogrinfo', console.error);
                ogr.on('error', console.error);
                ogr.format(options.format);
                var output = ogr.stream();
                output.pipe(fs.createWriteStream(f.dest));
            });
        });
    });

};

Adding some debug tracing shows that the source files exist and from the empty output I can see the right destination file is being created. But I'm now running into a brick wall of what to do next.

Thoughts and suggestions are welcomed!

Thanks

stream() from geojson

in v3 stream method is removed

I have a geojson data that I want formatted as per gdal format. in v2 I could take the stream output and save it in a file with that format.

Is it still possible with v3? It seems I can only get the data as a geojson object. But it is not what I need, I need it as a stream straight from ogr2ogr to save that particular formatting

DXF using ogr2ogr web client

I get this error when i try to convert to dxf

{"error":true,"msg":"ERROR 6: Read or update mode not supported on /vsistdout\nERROR 4: Failed to open '/vsistdout/' for writing.\nERROR 1: DXF driver failed to create /vsistdout/\n"}

please help!!!

How to write -update statement ?

i want to update my geoPackage using this command
ogr2ogr -skipfailures -update floridaData.gpkg "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/COVID19Surge_Florida_InterventionScenarios/FeatureServer/1/query?where=OBJECTID+%3C1000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelIntersects&outSR=4362&returnGeometry=true&sqlFormat=standard&f=json&maxRecordCountFactor=30&outFields=*&returnExceededLimitFeatures=false&resultType=tile" -nln 1
How i can write it ?

Ogr2ogr module doesn't give any output when doing promise?

I'm tryin to use the module in a lambda function but I'm having some issues with it. The way I am using the ogr2ogr module is by doing .promise(). However when I try to run my lambda function, I don't see anything in the logs. It seems like it just never hits the promise? Here is how my code looks like with the promise:

let data = await ogr2ogr(path)
	.destination(database)
	.options(['-f "PostgreSQL"', '-nlt PROMOTE_TO_MULTI', 'nln <schemaName>."' + tableName + '"', '-overwrite']).promise();
console.log(data);

I'm doing it exactly the way the documentation says but it still doesn't work. Something I should point out is that I tried to do

let ogr = ogr2ogr(path)
.destination(database)
.options(['-f "PostgreSQL"', '-nlt PROMOTE_TO_MULTI', 'nln ."' + tableName + '"', '-overwrite']);
console.log(ogr);

And I do see something in the logs:

EventEmitter {
      _inPath: '<path_of_file>',
      _onStderr: [Function (anonymous)],
      _driver: {},
      _args: [],
      _timeout: 15000,
      _format: 'GeoJSON',
      _skipfailures: false,
      _testClean: [Function (anonymous)],
      _destination: PG:host=<hostendpoint> user=<username> dbname=<db> password=<password>,
      _options: [
        '-f "PostgreSQL"',
        '-nlt PROMOTE_TO_MULTI',
        'nln schemaName.tableName',
        '-overwrite'
      ]
}

But if I try to do a callback like the documentation says, using the .exec() function, I don't see anything outputted. Is there an example that I can reference that uses a promise? Any help is greatly appreciated!

ENAMETOOLONG - When converting large GeoJSON to Shapefile

Thanks for this awesome package. It works very well for thing things that I need it to do, except I have run into an issue, and am hopeful that I can get it resolved. Running on Windows, GDAL 2.1.3, released 2017/20/01.

This works no problem with all my GeoJSON:
var newShape = ogr2ogr(currjson).format('ESRI Shapefile').skipfailures().stream(); newShape.pipe(fs.createWriteStream(filename + '.zip'));

However, there are a couple of instances lately where it is failing and I am getting an ENAMETOOLONG error. At first I thought that it was something in the GeoJSON, so I cleaned a few files and it worked no problem, however today, there is no cleaning possible. (Other files had a ridiculous number of properties that were not important - whereas today's issue has a file with over 2250 coordinate pairs!).

I've spent the last few hours looking for solutions, and can't seem to get one that works. I've updated my code as follows:
let newShape = ogr2ogr(currjson) .format('ESRI Shapefile') .skipfailures() .stream(); let outputStream = fs.createWriteStream(filename + '.zip'); newShape.pipe(outputStream) newShape.on('error', function(){ console.log('Well thats messed up'); })

and the on-error doesn't fire, and I still get the ENAMETOOLONG error, and it is coming from the .stream() portion (as far as I can tell).

Any pointers would be much appreciated.

ENOENT issue when writing shapefile

Thanks for creating the ogr2ogr module.

It works great on my Ubuntu VM and even in a windows environment, but in an Amazon S3 Ubuntu 13 instance, I’m getting an ENOENT, readdir ‘/tmp/ogr_4basfasdfasdf’ error when I run the following line:

shapefile.pipe(fileWriteStream); 

The shapefile error event is actually triggered 2 times - the first says Error: spawn ENOENT, and the second is the ENOENT, readdir that I mentioned above.

This happens when I run my project as sudo (as well as when not sudo).
It seems like it’s obviously a permissions problem, but I wanted to check with you to see if there’s something obvious I’m missing, or if you know how to get around this problem.

Is it because the file extension is missing?

Here’s my code snippet:

//Convert the GeoJSON object to a shapefile
var shapefile = ogr2ogr(myGeoJSONObject).format('ESRI Shapefile').stream();

 var filePath = "." + settings.application.topoJsonOutputFolder + 'shapefile_' + shortid.generate() + '.zip';
 var fileWriteStream = fs.createWriteStream(filePath);

 //Set the callback for when the shapefile is done writing
 fileWriteStream.on("finish", function () {
     flo.args.file = filePath;
     flo(); //Go to next block
 });

  //Set the callback for any errors
  fileWriteStream.on("error", function (err) {
      common.log("Error writing shapefile..." + err);
      flo.args.file = "";
      flo(); //Go to next block
   });

  shapefile.on("error", function (err) {
      common.log("Error piping shapefile..." + err);
      flo.args.file = "";
      flo(); //Go to next block
   });

   //Write
   shapefile.pipe(fileWriteStream); 

Thanks!

Convert GML to Shapefile using drv_wfs

This is more a question than a bug actually.

I am really interested in using this project (thanks for sharing it first of all).

What I need is a way to convert the GML response of a WFS GetFeature request into a Shapefile.
Something which I didn't try yet but I know it's feasiblethanks to this driver: https://www.gdal.org/drv_wfs.html.

The way to do it is described in this GIS Stackoverflow answer: https://gis.stackexchange.com/questions/147548/how-to-make-a-local-copy-of-a-large-wfs-dataset/181598#181598.

Do you think it's gonna be possible with your project?

Thanks.

Do not remove target projection when loading from csv

Even if no vrt is generated from a csv, do not delete the target SRS as this is giving errors in generating the target:

FAILURE: if -s_srs is specified, -t_srs must also be specified

This line should not be there (in index.js):

delete ogr2ogr._targetSrs

    else if (ogr2ogr._isCsvIn) {
      csv.makeVrt(fpath, function(err, vrt) {
        if (vrt && /\.vrt$/.test(vrt)) {
          // always set a source srs
          if (!ogr2ogr._sourceSrs) ogr2ogr._sourceSrs = ogr2ogr._targetSrs
        } else {
          // no geo data so no target srs
          delete ogr2ogr._targetSrs
        }
        one(err, vrt)
      })
    }

Error:
FAILURE: if -s_srs is specified, -t_srs must also be specified

at ChildProcess.<anonymous> (/home/ouser/onemapnginx/node_modules/ogr2ogr/index.js:187:18)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:886:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)

Performance problem

Hi,

I use your utility a lot and it works 99% on my side, except for the only 1% (which is actually creating a huge headace).

Example code to export from Postgresql to SHP, etc...:

shapefile = ogr2ogr('PG:host=localhost port=5432 user=pguser dbname=mydb password=pgpass')
    .format(targetformat)
    .timeout(12000000)
    .options(['-lco', 'GEOMETRY_NAME=the_geom', '-sql', sql])
    .project(targetprojection)
    .skipfailures()
    .destination(filename)
    .exec(function (er, data) {
        if (er) console.error(er);
        callback();
    });

Now, with the above code there is nothing wrong and it executes on 1 record or thousands of records.

Problem is, the moment I run the above on a large export job (where it is busy for some time), it creates all kinds of havoc throughout the nodejs web app and clients gets various errors (Mostly 502 Bad Gateway errors). I even tried running above in Async Series Task.

var async = require("async");

// ..... 

async.series([
    function (callback) {
        // Do some stuff prior to doing ogr2ogr, then call callback();
    },
    function (callback) {
        // Do the ogr2ogr export, then call callback()
        shapefile = ogr2ogr('PG:host=localhost port=5432 user=pguser dbname=mydb password=pgpass')
            .format(targetformat)
            .timeout(12000000)
            .options(['-lco', 'GEOMETRY_NAME=the_geom', '-sql', sql])
            .project(targetprojection)
            .skipfailures()
            .destination(filename)
            .exec(function (er, data) {
                if (er) console.error(er);
                callback();
            });
    }
    ], function (err) { //This is the final callback
        // Return success
    }
);

Extension: Support remote shapefile sources

Great work on this library.

I am collecting large shape files from a remote ftp source server - persisting to disk on a path - then invoking ogr2ogr with the path. It would be awesome if I could just give this library 1. a remote FTP path and 2. a set of credentials, and leave that extra legwork to the library.

Leaflet geojson incorrect polygon position on map

Hi y'all,

I've been using this awesome library (ogr2ogr) in order to translate a ShapeFile file into a GEOJSON file.

I used the following to generate the geojson file:
ogr2ogr -f "GeoJson" -t_srs EPSG:3857  100-geojson.json PARCEL_ALL.shp

At first it works fine for me but when you look at the details, on the map, there's a slight [offset.]
the result is as follows :
screen shot 2018-08-10 at 12 39 38

I know the shapefile is correct.
Anyone knows what can I do in order to make it more accurate?
Thanks you all !! :)

-clipsrc different result when running the CLI

When i run the following code :
var geojson = ogr2ogr('test.shp') .options(['--config', '-clipsrc', '5.900027 52.150202 6.049367 52.249765']) .timeout(50000) .onStderr((data: string) => { console.log(data); }) .stream(); geojson.pipe(fs.createWriteStream('test.geojson'));

The test.geojson = 853MB

The output isnt clipped when i run the following cli command:
ogr2ogr test.geojson test.shp -clipsrc 5.900027 52.150202 6.049367 52.249765

The test.geojson = 6.5MB

Version = GDAL 3.2.0, released 2020/10/26

NPM version out of date

Hey!
Do you plan to publish the latest version to NPM anytime soon?
It took me some time to realize why .onStderr(callback) wasn't working

TypeError: Path must be a string. Received undefined

Hi all. There is an issue that prevents me from handling an error case.

Reproduction steps:

  1. Obtain a .zip file, that doesn't actually contain any shapefiles.
  2. Use ogr2ogr(pathToZipFile).exec((error, data) =>{ ... } to read said zip file.
  3. The following error is produced and uncaught.
TypeError: Path must be a string. Received undefined
    at assertPath (path.js:7:11)
    at Object.dirname (path.js:1324:5)
    at Object.exports.rmParentDir (/home/totalpave/tp-server/node_modules/ogr2ogr/lib/util.js:21:57)
    at EventEmitter.Ogr2ogr._clean (/home/totalpave/tp-server/node_modules/ogr2ogr/index.js:231:10)
    at wrapUp (/home/totalpave/tp-server/node_modules/ogr2ogr/index.js:203:22)
    at /home/totalpave/tp-server/node_modules/ogr2ogr/index.js:156:20
    at /home/totalpave/tp-server/node_modules/ogr2ogr/lib/util.js:56:5
    at EventEmitter.<anonymous> (/home/totalpave/tp-server/node_modules/ogr2ogr/lib/zip.js:34:24)
    at emitNone (events.js:86:13)
    at EventEmitter.emit (events.js:185:7)
    at finish (/home/totalpave/tp-server/node_modules/ogr2ogr/node_modules/findit/index.js:107:17)
    at check (/home/totalpave/tp-server/node_modules/ogr2ogr/node_modules/findit/index.js:103:37)
    at onstat (/home/totalpave/tp-server/node_modules/ogr2ogr/node_modules/findit/index.js:184:13)
    at /home/totalpave/tp-server/node_modules/ogr2ogr/node_modules/findit/index.js:133:22
    at FSReqWrap.oncomplete (fs.js:123:15)

Other relevant information:

  • NodeJS Version 6.10.0 / NPM version 3.10.10
  • ogr2ogr GDAL 1.10.1, released 2013/08/26
  • og2ogr (node module) version 1.0.0
  • OS: Ubuntu 14.04

The callback to the .exec method is invoked, with a "No valid files found" error, as expected, but the NodeJS process then crashes due to the uncaught exception sometime later in that routine.

Example Exporting Postgresql Query to Shapefile

Hi,

Do you have an example where my source is Postgresql and destination is Shp. Problem is my Source is not a postgresql table, but a postgresql SELECT query. In ogr2ogr on the command line, I use to work with:

-sql "SELECT field1, field2 FROM sometable"

How would this be done in nodejs ogr2ogr as I cannot find any example of this?

allow output to postgis driver

This requires a different logic, as one has to be able to do something like

ogr2ogr -f PostgreSQL PG:dbname=warmerda abc.shp

which means having a .destination() function that allows specifying something else
than a file into ogr2ogr._ogrOutPath.
Successfull output of such a command would be empty, since the data is loaded
into the database.
I'm going to submit a PR but would like to get comments before, if any.

error with url geojson

Maybe I have this problem because my url is on localhost?

I have this geojson at the following url: http://localhost:3000/admin/711/lines.geojson

{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"LineString","coordinates":[[-7576433,6176485],[-7307069,6261483]]},"properties":{"id":38,"codecs":"711","featureId":"025c4e24-6c1e-be63-fe48-27500a55b957","styleId":"Nouvelles limites","createdAt":"2015-09-16T15:09:50.409Z","updatedAt":"2015-09-16T15:09:50.768Z"}}],"crs":{"type":"link","properties":{"href":"http://spatialreference.org/ref/sr-org/6864/proj4/","type":"proj4"}}}

Im doing like this:

var tableExport = ogr2ogr('http://localhost:3000/admin/711/lines.geojson')
    .format('MapInfo File')
    .stream()
    tableExport.pipe(fs.createWriteStream(mapInfoPath));

I have the following error:

events.js:85
throw er; // Unhandled 'error' event
^
Error: ERROR 1: HTTP error code : 504
FAILURE:
Unable to open datasource `http://localhost:3000/admin/711/lines.geojson' with t
he following drivers...

Convert SHP to Postgis UTF8

I have a shp file in iso-8859-1. How to import to Postgresql (UTF-8) ?

The problem is that my users can upload any character encoding shp file. So the utility should always convert to UTF-8, no matter what the shp encoding is.

Is it possible to generate shapefile via database table data?

For example; using commandline ogr2ogr, I am able to run this command:

ogr2ogr output.shp MYSQL:db,user=db_user,password=db_pass,port=3306 db_table

which generates 3 files: output.dbf, output.shp, and output.shx

Is this currently possible with this module?

converting

how to convert a WFS layer to GeoPackage ?

Possible to run serverless AWS Lambda ogr2ogr function?

I've been trying to run a AWS Lambda function that allows me to use ogr2ogr to post to an AWS RDS Postgres DB and am running up against some problems. Body being passed is a simple geoJSON for testing purposes.

I'm guessing it has to do with this:
ogr2ogr requires the command line tool ogr2ogr

Any hack-y way that I can get it running on a Lambda server? Example express "POST" function below:

app.post("/items", async function(req, res) {
	try {
		const ogr = ogr2ogr(req.body)
			.format("PostgreSQL")
			.destination(
				"PG:dbname=<dbname> user=<user> port=5432 password=<password> host=<host>"
			)
			.options(["-nln", "test"])
			.timeout(30000)
			.promise();

		ogr.resolve(resolve => {
			res.json({ success: "post call succeed!", url: req.url, body: req.body });
		});
	} catch (err) {
		console.log(err);
		res.json({ failure: err });
	}
});

Lambda log:

- 19:11:40 START Version: $LATEST
- 19:11:40 App started
- 19:11:40 EVENT: {"resource":"/items","path":"/items","httpMethod":"POST","headers":{"Accept":"application/json, text/plain, */*","Accept-Encoding":"gzip, deflate, br","Accept-Language":"en-US,en;q=0.9","CloudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile-Viewer":"false","CloudFront-Is-SmartTV-Viewer":"
- 19:11:41 Error: Error: spawn ogr2ogr ENOENT at ChildProcess.<anonymous> (/var/task/node_modules/ogr2ogr/index.js:222:18) at emitTwo (events.js:126:13) at ChildProcess.emit (events.js:214:7) at maybeClose (internal/child_process.js:925:16) at Socket.stream.socket.on (internal/child_process.js:346:11) at emitOne (events.js:
- 2019-06-25T19:11:41.150Z: 
- Error: Error: spawn ogr2ogr ENOENT
- at ChildProcess.<anonymous> (/var/task/node_modules/ogr2ogr/index.js:222:18)
- at emitTwo (events.js:126:13)
- at ChildProcess.emit (events.js:214:7)
- at maybeClose (internal/child_process.js:925:16)
- at Socket.stream.socket.on (internal/child_process.js:346:11)
- at emitOne (events.js:116:13)
- at Socket.emit (events.js:211:7)
- at Pipe._handle.close [as _onclose] (net.js:567:12)
- 19:11:41: END 
- 19:11:41: REPORT Duration: 771.88 ms	Billed Duration: 800 ms Memory Size: 128 MB	Max Memory Used: 76 MB

One additional note: I also am using the GDAL Lambda layer from Geolambda, but not sure if there's anything else I need to do to add other than connecting to the layer to the function

GPX to geoJSON conversion

GPX can have multiple layers (tracks, routes, waypoints), but even when only one layer is defined, the conversion fails :

"ERROR 6: GeoJSON driver doesn't support creating more than one layer",
"ERROR 1: Terminating translation prematurely after failed",
"translation of layer routes (use -skipfailures to skip errors)"

By specifying the layer on the command line, the conversion can be done by ogr2ogr. It would be great if we could add extra arguments to the ogr2ogr command line using the /convert api

Is there a plan to add promise support?

With Node now supporting Promises out of the box, would you consider adding promise support?
eg by retirning a promise if .exec() is called without a callback or with .promise() used instead of.exec()`

CSV support?

I'm trying to send a csv file over to my postgres but I noticed that I get the following error:

Unable to open datasource `fileName.csv' with the following drivers.
  -> `netCDF'
  -> `PDS4'
  -> `VICAR'
  -> `JP2OpenJPEG'
  -> `MBTiles'
  -> `BAG'
  -> `ESRI Shapefile'
  -> `MapInfo File'
  -> `OGR_VRT'
  -> `Memory'
  -> `GML'
  -> `KML'
  -> `GeoJSON'
  -> `GeoJSONSeq'
  -> `ESRIJSON'
  -> `TopoJSON'
  -> `GPKG'
  -> `SQLite'
  -> `PostgreSQL'
  -> `FlatGeobuf'
  -> `PGDUMP'
  -> `OGR_PDS'
  -> `MVT'

Is there no support for csv files?

GeoJSON Object Errors

With version 6.9.4 of node when I run from within examples...

node geojson-obj.js

Contents of geojson-obj.js

var ogr2ogr = require('../')

var geojson = {
  'type': 'FeatureCollection',
  'features': [{
    'type': 'Feature',
    'geometry': {
      'type': 'Point',
      'coordinates': [102.0, 0.5],
    },
    'properties': {'area': '51'},
  }],
}

var ogr = ogr2ogr(geojson).project('EPSG:3857')

ogr.exec(function(er, data) {
  if (er) console.error(er)
  console.log(data) // reprojected geojson data
})

I get the following error

⋊> ~/D/G/n/o/examples node geojson-obj.js                                                                                                                                  11:54:25
SyntaxError: Unexpected end of JSON input
    at Object.parse (native)
    at PassThrough.<anonymous> (/Users/danielrasmuson/Downloads/GeoJSONtoDXF/node_modules/ogr2ogr/index.js:91:27)
    at emitNone (events.js:91:20)
    at PassThrough.emit (events.js:185:7)
    at wrapUp (/Users/danielrasmuson/Downloads/GeoJSONtoDXF/node_modules/ogr2ogr/index.js:207:15)
    at /Users/danielrasmuson/Downloads/GeoJSONtoDXF/node_modules/ogr2ogr/lib/util.js:56:5
    at ChildProcess.<anonymous> (/Users/danielrasmuson/Downloads/GeoJSONtoDXF/node_modules/ogr2ogr/index.js:187:7)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
undefined

Allow for configuring the CLI command used to invoke GDAL ogr2ogr

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.

Quick Tip: piping to ogr2ogr

I was trying to transform a GeoJSON file to PGDump.

Usually I would feed ogr2ogr a filepath:

let inputFile = 'file.json';

let ogrStream = ogr2ogr(inputFile)
                .format('PGDump')
                .stream();


let outputFile = 'file.sql';
let outputStream= fs.createWriteStream(outputFile);
ogrStream.pipe(outputStream);

Or, I would feed ogr2ogr a readable Stream:

let inputFile = 'file.json';
let inputStream = fs.createReadStream(inputFile);

let ogrStream = ogr2ogr(inputStream)
                .format('PGDump')
                .stream();


let outputFile = 'file.sql';
let outputStream= fs.createWriteStream(outputFile);
ogrStream.pipe(outputStream);

However, this time I needed to process the GeoJSON file renaming its properties according to a given map of keys and values, so I needed to put a duplex stream between the readable Stream and ogr2ogr.

I tried to do:

let inputFile = 'file.json';
let inputStream = fs.createReadStream(inputFile);

let transformStream=transform((record, callback)=> {
  ... do things with record...
});

let ogrStream = ogr2ogr(transformStream)
                .format('PGDump')
                .stream();

let outputFile = 'file.sql';
let outputStream= fs.createWriteStream(outputFile);
ogrStream.pipe(outputStream);
inputStream.pipe(transformStream);

However this caused an error:

(node:6681) UnhandledPromiseRejectionWarning: TypeError: Path must be a string. Received undefined
    at assertPath (path.js:28:11)
    at Object.extname (path.js:1456:5)
    at new Ogr2ogr (/home/amenadiel/my_project/node_modules/ogr2ogr/index.js:24:45)
    at Ogr2ogr (/homeamenadiel/my_project/node_modules/ogr2ogr/index.js:17:42)

I found out that ogr2ogr was trying to figure out the input format from the input file or stream, BUT it also accepts an explicit input format as a second parameter. So, doing:

let inputFile = 'file.json';
let inputStream = fs.createReadStream(inputFile);

let transformStream=transform((record, callback)=> {
  ... do things with record...
});

let ogrStream = ogr2ogr(transformStream, 'GeoJSON') // explicit input format
                .format('PGDump')
                .stream();


let outputFile = 'file.sql';
let outputStream= fs.createWriteStream(outputFile);
ogrStream.pipe(outputStream);
inputStream.pipe(transformStream);

did the job seamlessly

ENOENT error on windows

I would like to know if this module is compatible with Windows?
I have GDAL 1.10 32bits installed on Windows 7.

Doing something like that:

var shapefile = ogr2ogr('c:/temp/test.geojson')
                .format('ESRI Shapefile')
                .skipfailures()
                .stream()
shapefile.pipe(fs.createWriteStream('c:/temp/shapefile.zip'))

returns

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: Error: spawn ogr2ogr ENOENT
    at ChildProcess.<anonymous> (c:\node\decoupage\node_modules\ogr2ogr\index.js
:187:28)
    at ChildProcess.emit (events.js:110:17)
    at maybeClose (child_process.js:1015:16)
    at Socket.<anonymous> (child_process.js:1183:11)
    at Socket.emit (events.js:107:17)
    at Pipe.close (net.js:485:12)
Program node ./bin/www exited with code 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.