Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use ogr2ogr with this module? #199

Closed
tsemerad opened this issue May 24, 2017 · 3 comments
Closed

Is it possible to use ogr2ogr with this module? #199

tsemerad opened this issue May 24, 2017 · 3 comments

Comments

@tsemerad
Copy link

I need to be able to run ogr2ogr commands in my node module, and I'll be deploying it to an environment where I can't separately install the ogr2ogr command line tool. I like how GDAL comes bundled with this library so that it works out of the box - does that mean I also have access to ogr2ogr?

Looking through the documentation, it doesn't appear to be the case. It looks like I can manually recreate what ogr2ogr does to an extent. However, I was hoping to be able to use ogr2ogr's powerful SQL functionality to rename and type cast fields like I do in the following command:

ogr2ogr -f "GeoJSON" ./outputFile.geojson ./inputFile.shp -sql "SELECT CAST(isActive AS boolean) AS active) FROM inputFile"
@brandonreavis
Copy link
Member

You are right that ogr2ogr isn't directly exposed, but much of its functionality is. Take a look at http://naturalatlas.github.io/node-gdal/classes/gdal.Dataset.html#method-executeSQL

That would be something like:

var inputDataset = gdal.open('./inputFile.shp');
var inputLayer = inputDataset.executeSQL('SELECT CAST(isActive AS boolean) AS active) FROM inputFile');
var outputDataset = gdal.open('./outputFile.geojson', 'w', 'GeoJSON');
// ... then create outputLayer and add features to it from inputLayer

@tsemerad
Copy link
Author

Thank you very much for the advice. That is exactly what I needed. I now have the following code which is working great:

const inputDataset = gdal.open('./inputFile.shp')
const inputLayer = inputDataset.executeSQL('SELECT CAST(isActive AS boolean) AS active) FROM inputFile')
const outputDataset = gdal.open('./outputFile.geojson', 'w', 'GeoJSON')
const outputLayer = outputDataset.layers.create('myTableName', null, inputLayer.geomType)

inputLayer.features.forEach(feature => {
  outputLayer.features.add(feature)
})

outputLayer.flush()
outputDataset.close()

@brandonreavis
Copy link
Member

Great! I'm glad that works!

I think the gdal GeoJSON driver is pretty flexible so what you did works, but for future reference you would probably want to set up the output schema before adding features to the output layer, and create the output feature specifically for the output layer.

Something like this:

const inputDataset = gdal.open('./inputFile.shp')
const inputLayer = inputDataset.executeSQL('SELECT CAST(isActive AS boolean) AS active) FROM inputFile')
const outputDataset = gdal.open('./outputFile.geojson', 'w', 'GeoJSON')
const outputLayer = outputDataset.layers.create('myTableName', inputLayer.srs, inputLayer.geomType)

// set up output schema
inputLayer.fields.forEach(field => outputLayer.fields.add(new gdal.FieldDefn(field.name, field.type)));

inputLayer.features.forEach(feature => {
  // create feature specifically for the output layer
  const outputFeature = new gdal.Feature(outputLayer);
  outputFeature.setGeometry(feature.getGeometry());
  outputFeature.fields.set(feature.fields.toObject());
  outputLayer.features.add(outputFeature)
})

// outputLayer.flush() - this is unnecessary because the dataset gets flushed when it is closed
outputDataset.close()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants