const path = require('path')
const fs = require('fs')
const binary = require('@mapbox/node-pre-gyp')
const binding_path = binary.find(path.join(__dirname, '../package.json'))
const data_path = path.resolve(__dirname, '../deps/libgdal/gdal/data')
const proj_path = path.resolve(__dirname, '../deps/libproj/proj/data')
if (process.env.GDAL_DATA === undefined && !fs.existsSync(data_path)) {
throw new Error(
`The bundled data path for node-gdal is missing '${data_path}' and GDAL_DATA environment is not set`
)
}
const proj_lib_env_undefined = process.env.PROJ_LIB === undefined
if (proj_lib_env_undefined && !fs.existsSync(proj_path)) {
throw new Error(
`The bundled proj data path for node-gdal is missing '${proj_path}' and PROJ_LIB environment is not set`
)
}
const gdal = module.exports = require(binding_path)
if (proj_lib_env_undefined) {
gdal.setPROJSearchPath(proj_path)
}
gdal.Point.Multi = gdal.MultiPoint
gdal.LineString.Multi = gdal.MultiLineString
gdal.LinearRing.Multi = gdal.MultiLineString
gdal.Polygon.Multi = gdal.MultiPolygon
gdal.quiet()
gdal.config = {}
/**
* Gets a GDAL configuration setting.
*
* @example
* ```
* data_path = gdal.config.get('GDAL_DATA');```
*
* @for gdal
* @static
* @method config.get
* @param {string} key
* @return {string}
*/
gdal.config.get = gdal.getConfigOption
/**
* Sets a GDAL configuration setting.
*
* @example
* ```
* gdal.config.set('GDAL_DATA', data_path);```
*
* @for gdal
* @static
* @method config.set
* @param {string} key
* @param {string} value
* @return {mixed}
*/
gdal.config.set = gdal.setConfigOption
delete gdal.getConfigOption
delete gdal.setConfigOption
if (process.env.GDAL_DATA === undefined) {
gdal.config.set('GDAL_DATA', data_path)
}
gdal.Envelope = require('./envelope.js')(gdal)
gdal.Envelope3D = require('./envelope_3d.js')(gdal)
const getEnvelope = gdal.Geometry.prototype.getEnvelope
gdal.Geometry.prototype.getEnvelope = function () {
const obj = getEnvelope.apply(this, arguments)
return new gdal.Envelope(obj)
}
const getEnvelope3D = gdal.Geometry.prototype.getEnvelope3D
gdal.Geometry.prototype.getEnvelope3D = function () {
const obj = getEnvelope3D.apply(this, arguments)
return new gdal.Envelope3D(obj)
}
const getExtent = gdal.Layer.prototype.getExtent
gdal.Layer.prototype.getExtent = function () {
const obj = getExtent.apply(this, arguments)
return new gdal.Envelope(obj)
}
// --- add additional functionality to collections ---
function defaultForEach(callback) {
const n = this.count()
for (let i = 0; i < n; i++) {
if (callback(this.get(i), i) === false) return
}
}
function defaultMap(callback) {
const result = []
this.forEach((value, i) => {
result.push(callback(value, i))
})
return result
}
function defaultToArray() {
const array = []
this.forEach((geom) => {
array.push(geom)
})
return array
}
/**
* Iterates through all bands using a callback function.
* Note: GDAL band indexes start at 1, not 0.
*
* @example
* ```
* dataset.bands.forEach(function(band, i) { ... });```
*
* @for gdal.DatasetBands
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.RasterBand"}}RasterBand{{/crossLink}}
*/
gdal.DatasetBands.prototype.forEach = function (callback) {
const n = this.count()
for (let i = 1; i <= n; i++) {
if (callback(this.get(i), i) === false) return
}
}
/**
* Iterates through all bands using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = dataset.bands.map(function(band, i) {
* return value;
* });```
*
* @for gdal.DatasetBands
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.RasterBand"}}RasterBand{{/crossLink}}
*/
gdal.DatasetBands.prototype.map = defaultMap
/**
* Iterates through all features using a callback function.
*
* @example
* ```
* layer.features.forEach(function(feature, i) { ... });```
*
* @for gdal.LayerFeatures
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Feature"}}Feature{{/crossLink}}
*/
gdal.LayerFeatures.prototype.forEach = function (callback) {
let i = 0
let feature = this.first()
while (feature) {
if (callback(feature, i++) === false) return
feature = this.next()
}
}
/**
* Iterates through all features using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = layer.features.map(function(band, i) {
* return value;
* });```
*
* @for gdal.LayerFeatures
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Feature"}}Feature{{/crossLink}}
*/
gdal.LayerFeatures.prototype.map = defaultMap
/**
* Iterates through all fields using a callback function.
*
* @example
* ```
* layer.features.get(0).fields.forEach(function(value, key) { ... });```
*
* @for gdal.FeatureFields
* @method forEach
* @param {Function} callback The callback to be called with each feature `value` and `key`.
*/
gdal.FeatureFields.prototype.forEach = function (callback) {
const obj = this.toObject()
Object.entries(obj).every(([ k, v ]) =>
callback(v, k) !== false
)
}
/**
* Iterates through all fields using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = layer.features.get(0).fields.map(function(value, key) {
* return value;
* });```
*
* @for gdal.FeatureFields
* @method map
* @param {Function} callback The callback to be called with each feature `value` and `key`.
*/
gdal.FeatureFields.prototype.map = defaultMap
/**
* Outputs the fields as a serialized JSON string.
*
* @for gdal.FeatureFields
* @method toJSON
* @return {String} Serialized JSON
*/
gdal.FeatureFields.prototype.toJSON = function () {
return JSON.stringify(this.toObject())
}
/**
* Converts the geometry to a GeoJSON object representation.
*
* @for gdal.Geometry
* @method toObject
* @return {Object} GeoJSON
*/
gdal.Geometry.prototype.toObject = function () {
return JSON.parse(this.toJSON())
}
/**
* Iterates through all field definitions using a callback function.
*
* @example
* ```
* layer.fields.forEach(function(field, i) { ... });```
*
* @for gdal.LayerFields
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.FieldDefn"}}FieldDefn{{/crossLink}}
*/
gdal.LayerFields.prototype.forEach = defaultForEach
/**
* Iterates through all field definitions using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = layer.fields.map(function(field, i) {
* return value;
* });```
*
* @for gdal.LayerFields
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.FieldDefn"}}FieldDefn{{/crossLink}}
*/
gdal.LayerFields.prototype.map = defaultMap
/**
* Iterates through all layers using a callback function.
*
* @example
* ```
* dataset.layers.forEach(function(layer, i) { ... });```
*
* @for gdal.DatasetLayers
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Layer"}}Layer{{/crossLink}}
*/
gdal.DatasetLayers.prototype.forEach = defaultForEach
/**
* Iterates through all layers using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = dataset.layers.map(function(field, i) {
* return value;
* });```
*
* @for gdal.DatasetLayers
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Layer"}}Layer{{/crossLink}}
*/
gdal.DatasetLayers.prototype.map = defaultMap
/**
* Iterates through all field definitions using a callback function.
*
* @example
* ```
* featureDefn.forEach(function(field, i) { ... });```
*
* @for gdal.FeatureDefnFields
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.FieldDefn"}}FieldDefn{{/crossLink}}
*/
gdal.FeatureDefnFields.prototype.forEach = defaultForEach
/**
* Iterates through all field definitions using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = dataset.layers.map(function(field, i) {
* return value;
* });```
*
* @for gdal.FeatureDefnFields
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.FieldDefn"}}FieldDefn{{/crossLink}}
*/
gdal.FeatureDefnFields.prototype.map = defaultMap
/**
* Iterates through all rings using a callback function.
*
* @example
* ```
* polygon.rings.forEach(function(ring, i) { ... });```
*
* @for gdal.PolygonRings
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.LineString"}}LineString{{/crossLink}}
*/
gdal.PolygonRings.prototype.forEach = defaultForEach
/**
* Iterates through all rings using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = polygon.rings.map(function(ring, i) {
* return value;
* });```
*
* @for gdal.LineStringPoints
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.LineString"}}LineString{{/crossLink}}
*/
gdal.PolygonRings.prototype.map = defaultMap
/**
* Iterates through all points using a callback function.
*
* @example
* ```
* lineString.points.forEach(function(point, i) { ... });```
*
* @for gdal.LineStringPoints
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Point"}}Point{{/crossLink}}
*/
gdal.LineStringPoints.prototype.forEach = defaultForEach
/**
* Iterates through all points using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = lineString.points.map(function(point, i) {
* return value;
* });```
*
* @for gdal.LineStringPoints
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Point"}}Point{{/crossLink}}
*/
gdal.LineStringPoints.prototype.map = defaultMap
/**
* Iterates through all child geometries using a callback function.
*
* @example
* ```
* geometryCollection.children.forEach(function(geometry, i) { ... });```
*
* @for gdal.GeometryCollectionChildren
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Geometry"}}Geometry{{/crossLink}}
*/
gdal.GeometryCollectionChildren.prototype.forEach = defaultForEach
/**
* Iterates through all child geometries using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = geometryCollection.children.map(function(geometry, i) {
* return value;
* });```
*
* @for gdal.GeometryCollectionChildren
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Geometry"}}Geometry{{/crossLink}}
*/
gdal.GeometryCollectionChildren.prototype.map = defaultMap
/**
* Iterates through all overviews using a callback function.
*
* @example
* ```
* band.overviews.forEach(function(overviewBand, i) { ... });```
*
* @for gdal.RasterBandOverviews
* @method forEach
* @param {Function} callback
*/
gdal.RasterBandOverviews.prototype.forEach = defaultForEach
/**
* Iterates through all raster overviews using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = band.overviews.map(function(overviewBand, i) {
* return value;
* });```
*
* @for gdal.RasterBandOverviews
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Geometry"}}Geometry{{/crossLink}}
*/
gdal.RasterBandOverviews.prototype.map = defaultMap
/**
* Iterates through all registered drivers using a callback function.
*
* @example
* ```
* gdal.drivers.forEach(function(driver, i) { ... });```
*
* @for gdal.GDALDrivers
* @method forEach
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Driver"}}Driver{{/crossLink}}
*/
gdal.GDALDrivers.prototype.forEach = defaultForEach
/**
* Iterates through all drivers using a callback function and builds
* an array of the returned values.
*
* @example
* ```
* var result = gdal.drivers.map(function(driver, i) {
* return value;
* });```
*
* @for gdal.GDALDrivers
* @method map
* @param {Function} callback The callback to be called with each {{#crossLink "gdal.Driver"}}Driver{{/crossLink}}
*/
gdal.GDALDrivers.prototype.map = defaultMap
/**
* Outputs all geometries as a regular javascript array.
*
* @for gdal.GeometryCollectionChildren
* @method toArray
* @return {Array} List of {{#crossLink "gdal.Geometry"}}Geometry{{/crossLink}} instances.
*/
gdal.GeometryCollectionChildren.prototype.toArray = defaultToArray
/**
* Outputs all points as a regular javascript array.
*
* @for gdal.LineStringPoints
* @method toArray
* @return {Array} List of {{#crossLink "gdal.Point"}}Point{{/crossLink}} instances.
*/
gdal.LineStringPoints.prototype.toArray = defaultToArray
/**
* Outputs all rings as a regular javascript array.
*
* @for gdal.PolygonRings
* @method toArray
* @return {Array} List of {{#crossLink "gdal.LineString"}}LineString{{/crossLink}} instances.
*/
gdal.PolygonRings.prototype.toArray = defaultToArray
/**
* Creates or opens a dataset. Dataset should be explicitly closed with `dataset.close()` method if opened in `"w"` mode to flush any changes. Otherwise, datasets are closed when (and if) node decides to garbage collect them.
*
* @example
* ```
* var dataset = gdal.open('./data.shp');```
*
* @example
* ```
* var dataset = gdal.open(fs.readFileSync('./data.shp'));```
*
* @for gdal
* @throws Error
* @method open
* @static
* @param {String|Buffer} path Path to dataset or in-memory Buffer to open
* @param {String} [mode="r"] The mode to use to open the file: `"r"`, `"r+"`, or `"w"`
* @param {String|Array} [drivers] Driver name, or list of driver names to attempt to use.
*
* @param {Integer} [x_size] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [y_size] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [band_count] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [data_type] Used when creating a raster dataset with the `"w"` mode.
* @param {String[]|object} [creation_options] Used when creating a dataset with the `"w"` mode.
*
* @return {gdal.Dataset}
*/
gdal.open = (function () {
const open = gdal.open
// add 'w' mode to gdal.open() method and also GDAL2-style driver selection
return function (
filename,
mode,
drivers /* , x_size, y_size, n_bands, datatype, options */
) {
if (filename instanceof Buffer) {
const buffer = filename
arguments[0] = gdal._getMemFileName(filename)
const ds = gdal.open.apply(gdal, arguments)
ds.buffer = buffer
return ds
}
if (typeof drivers === 'string') {
drivers = [ drivers ]
} else if (drivers && !Array.isArray(drivers)) {
throw new Error('driver(s) must be a string or list of strings')
}
if (mode === 'w') {
// create file with given driver
if (!drivers) {
throw new Error('Driver must be specified')
}
if (drivers.length !== 1) {
throw new Error('Only one driver can be used to create a file')
}
const driver = gdal.drivers.get(drivers[0])
if (!driver) {
throw new Error(`Cannot find driver: ${drivers[0]}`)
}
const args = Array.prototype.slice.call(arguments, 3) // x_size, y_size, ...
args.unshift(filename)
return driver.create.apply(driver, args)
}
if (arguments.length > 2) {
// open file with driver list
// loop through given drivers trying to open file
let ds
drivers.forEach((driver_name) => {
const driver = gdal.drivers.get(driver_name)
if (!driver) {
throw new Error(`Cannot find driver: ${driver_name}`)
}
try {
ds = driver.open(filename, mode)
return false
} catch (err) {
/* skip driver */
}
})
if (!ds) throw new Error('Error opening dataset')
return ds
}
// call gdal.open() method normally
return open.apply(gdal, arguments)
}
})()
/**
* Standard async request callback
* @callback requestCallback
* @param {error} error error or undefined when the operation is successful
* @param {object} result result of the asynchronous operation or undefined on error
*/
const promisify = require('util').promisify
const callbackify = require('util').callbackify
gdal.Driver.prototype.createAsync = (function () {
const driverCreateCb = gdal.Driver.prototype.createAsync
const driverCreatePromise = promisify(gdal.Driver.prototype.createAsync)
return function (
filename,
x_size,
y_size,
n_bands,
datatype,
options,
callback
) {
if (typeof arguments[arguments.length - 1] === 'function' && callback === undefined) {
callback = arguments[arguments.length - 1]
arguments[arguments.length - 1] = undefined
}
if (callback) {
return driverCreateCb.call(this, filename, x_size, y_size,
n_bands, datatype, options, callback)
}
return driverCreatePromise.call(this, filename, x_size, y_size,
n_bands, datatype, options)
}
})()
gdal.Driver.prototype.createCopyAsync = (function () {
const driverCreateCopyCb = gdal.Driver.prototype.createCopyAsync
const driverCreateCopyPromise = promisify(gdal.Driver.prototype.createCopyAsync)
return function (
filename,
src,
options,
callback
) {
if (typeof arguments[arguments.length - 1] === 'function' && callback === undefined) {
callback = arguments[arguments.length - 1]
arguments[arguments.length - 1] = undefined
}
if (callback) {
return driverCreateCopyCb.call(this, filename, src, options, callback)
}
return driverCreateCopyPromise.call(this, filename, src, options)
}
})()
gdal.Driver.prototype.openAsync = (function () {
const driverOpenCb = gdal.Driver.prototype.openAsync
const driverOpenPromise = promisify(gdal.Driver.prototype.openAsync)
return function (
filename,
mode,
callback
) {
if (typeof arguments[arguments.length - 1] === 'function' && callback === undefined) {
callback = arguments[arguments.length - 1]
arguments[arguments.length - 1] = undefined
}
if (callback) {
return driverOpenCb.call(this, filename, mode, callback)
}
return driverOpenPromise.apply(this, filename, mode)
}
})()
/**
* Asynchronously creates or opens a dataset. Dataset should be explicitly closed with `dataset.close()` method if opened in `"w"` mode to flush any changes. Otherwise, datasets are closed when (and if) node decides to garbage collect them.
* If the last parameter is a callback, then this callback is called on completion and undefined is returned. Otherwise the function returns a Promise resolved with the result.
*
* @example
* ```
* var dataset = await gdal.openAsync('./data.shp');```
*
* @example
* ```
* var dataset = await gdal.openAsync(await fd.readFile('./data.shp'));```
*
* @example
* ```
* gdal.openAsync('./data.shp', (err, ds) => {...});```
*
* @for gdal
* @method openAsync
* @static
* @param {String|Buffer} path Path to dataset or in-memory Buffer to open
* @param {String} [mode="r"] The mode to use to open the file: `"r"`, `"r+"`, or `"w"`
* @param {String|Array} [drivers] Driver name, or list of driver names to attempt to use.
*
* @param {Integer} [x_size] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [y_size] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [band_count] Used when creating a raster dataset with the `"w"` mode.
* @param {Integer} [data_type] Used when creating a raster dataset with the `"w"` mode.
* @param {String[]|object} [creation_options] Used when creating a dataset with the `"w"` mode.
* @param {requestCallback} [callback] Promisifiable callback, always the last parameter, can be specified even if
* certain optional parameters are omitted
*
* @return {gdal.Dataset}
*/
gdal.openAsync = (function () {
const openPromise = (function () {
const openPromise = promisify(gdal.openAsync)
// add 'w' mode to gdal.open() method and also GDAL2-style driver selection
return function (
filename,
mode,
drivers,
_x_size,
_y_size,
_n_bands,
_datatype,
_options
) {
if (filename instanceof Buffer) {
const buffer = filename
try {
// getMemFileName is always synchronous
arguments[0] = gdal._getMemFileName(filename)
} catch (e) {
return Promise.reject(e)
}
return gdal.openAsync.apply(gdal, arguments).then((ds) => {
ds.buffer = buffer
return ds
})
}
if (typeof drivers === 'string') {
drivers = [ drivers ]
} else if (drivers && !Array.isArray(drivers)) {
throw new Error('driver(s) must be a string or list of strings')
}
if (mode === 'w') {
// create file with given driver
if (!drivers) {
throw new Error('Driver must be specified')
}
if (drivers.length !== 1) {
throw new Error('Only one driver can be used to create a file')
}
const driver = gdal.drivers.get(drivers[0])
if (!driver) {
throw new Error(`Cannot find driver: ${drivers[0]}`)
}
const args = Array.prototype.slice.call(arguments, 3) // x_size, y_size, ...
args.unshift(filename)
return gdal.Driver.prototype.createAsync.apply(driver, args)
}
if (arguments.length > 2 && drivers) {
const p = []
for (const driver_name of drivers) {
const driver = gdal.drivers.get(driver_name)
if (!driver) {
throw new Error(`Cannot find driver: ${driver_name}`)
}
p.push(gdal.Driver.prototype.openAsync.call(driver, filename, mode))
}
// first driver to open the file wins
// normally, there are no formats supported by two drivers
return Promise.any(p).catch(() => {
throw new Error('Error opening dataset')
})
}
// call gdal.open() method normally
return openPromise.call(gdal, filename, mode)
}
})()
const openCb = callbackify(openPromise)
return function (filename,
mode,
drivers,
x_size,
y_size,
n_bands,
datatype,
options,
callback) {
if (typeof arguments[arguments.length - 1] === 'function' && callback === undefined) {
callback = arguments[arguments.length - 1]
arguments[arguments.length - 1] = undefined
}
if (callback) {
const args = arguments
Array.prototype.push.call(args, callback)
return openCb.apply(gdal, args)
}
return openPromise.apply(gdal, arguments)
}
})()
function fieldTypeFromValue(val) {
const type = typeof val
if (type === 'number') {
if (val % 1 === 0) return gdal.OFTInteger
return gdal.OFTReal
} else if (type === 'string') {
return gdal.OFTString
} else if (type === 'boolean') {
return gdal.OFTInteger
} else if (val instanceof Date) {
return gdal.OFTDateTime
} else if (val instanceof Array) {
const sub_type = fieldTypeFromValue(val[0])
switch (sub_type) {
case gdal.OFTString:
return gdal.OFTStringList
case gdal.OFTInteger:
return gdal.OFTIntegerList
case gdal.OFTReal:
return gdal.OFTRealList
default:
throw new Error('Array element cannot be converted into OGRFieldType')
}
} else if (val instanceof Buffer) {
return gdal.OFTBinary
}
throw new Error('Value cannot be converted into OGRFieldType')
}
/**
* Creates a LayerFields instance from an object of keys and values.
*
* @method fromJSON
* @for gdal.LayerFields
* @param {Object} object
* @param {Boolean} [approx_ok=false]
*/
gdal.LayerFields.prototype.fromJSON = (function () {
let warned = false
return function (obj, approx_ok) {
if (!warned) {
console.warn(
'NODE-GDAL Deprecation Warning: LayerFields fromJSON() is deprecated, use fromObject() instead'
)
warned = true
}
return this.fromObject(obj, approx_ok)
}
})()
gdal.LayerFields.prototype.fromObject = function (obj, approx_ok) {
approx_ok = approx_ok || false
Object.entries(obj).forEach(([ k, v ]) => {
const type = fieldTypeFromValue(v)
const def = new gdal.FieldDefn(k, type)
this.add(def, approx_ok)
})
}
gdal.Point.wkbType = gdal.wkbPoint
gdal.LineString.wkbType = gdal.wkbLineString
gdal.LinearRing.wkbType = gdal.wkbLinearRing
gdal.Polygon.wkbType = gdal.wkbPolygon
gdal.MultiPoint.wkbType = gdal.wkbMultiPoint
gdal.MultiLineString.wkbType = gdal.wkbMultiLineString
gdal.MultiPolygon.wkbType = gdal.wkbMultiPolygon
gdal.GeometryCollection.wkbType = gdal.wkbGeometryCollection
// enable passing geometry constructors as the geometry type
gdal.DatasetLayers.prototype.create = (function () {
const create = gdal.DatasetLayers.prototype.create
return function (name, srs, geom_type /* , creation_options */) {
if (arguments.length > 2 && geom_type instanceof Function) {
if (typeof geom_type.wkbType === 'undefined') {
throw new Error('Function must be a geometry constructor')
}
arguments[2] = geom_type.wkbType
}
return create.apply(this, arguments)
}
})()
function getTypedArrayType(array) {
if (array instanceof Uint8Array) return 1 // gdal.GDT_Byte
if (array instanceof Int8Array) return 1 // gdal.GDT_Byte
if (array instanceof Int16Array) return 3 // gdal.GDT_Int16
if (array instanceof Uint16Array) return 2 // gdal.GDT_UInt16
if (array instanceof Int32Array) return 5 // gdal.GDT_Int32
if (array instanceof Uint32Array) return 4 // gdal.GDT_UInt32
if (array instanceof Float32Array) return 6 // gdal.GDT_Float32
if (array instanceof Float64Array) return 7 // gdal.GDT_Float64
return 0 // gdal.GDT_Unknown
}
gdal.RasterBandPixels.prototype.read = (function () {
const read = gdal.RasterBandPixels.prototype.read
return function (x, y, width, height, data, options) {
if (!options) options = {}
if (data) data._gdal_type = getTypedArrayType(data)
return read.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.type,
options.pixel_space,
options.line_space
])
}
})()
gdal.RasterBandPixels.prototype.readAsync = (function () {
const readCb = gdal.RasterBandPixels.prototype.readAsync
const readPromise = promisify(gdal.RasterBandPixels.prototype.readAsync)
return function (x, y, width, height, data, options, cb) {
if (typeof arguments[arguments.length - 1] === 'function' && cb === undefined) {
cb = arguments[arguments.length - 1]
/* This has the desired effect of unsetting that argument */
arguments[arguments.length - 1] = undefined
}
if (!options) options = {}
if (data) data._gdal_type = getTypedArrayType(data)
if (cb) {
return readCb.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.type,
options.pixel_space,
options.line_space,
cb
])
}
return readPromise.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.type,
options.pixel_space,
options.line_space
])
}
})()
gdal.RasterBandPixels.prototype.write = (function () {
const write = gdal.RasterBandPixels.prototype.write
return function (x, y, width, height, data, options) {
if (!options) options = {}
if (data) data._gdal_type = getTypedArrayType(data)
return write.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.pixel_space,
options.line_space
])
}
})()
gdal.RasterBandPixels.prototype.writeAsync = (function () {
const writeCb = gdal.RasterBandPixels.prototype.writeAsync
const writePromise = promisify(gdal.RasterBandPixels.prototype.writeAsync)
return function (x, y, width, height, data, options, cb) {
if (typeof arguments[arguments.length - 1] === 'function' && cb === undefined) {
cb = arguments[arguments.length - 1]
arguments[arguments.length - 1] = undefined
}
if (!options) options = {}
if (data) data._gdal_type = getTypedArrayType(data)
if (cb) {
return writeCb.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.pixel_space,
options.line_space,
cb
])
}
return writePromise.apply(this, [
x,
y,
width,
height,
data,
options.buffer_width,
options.buffer_height,
options.pixel_space,
options.line_space
])
}
})()
gdal.RasterBandPixels.prototype.readBlock = (function () {
const readBlock = gdal.RasterBandPixels.prototype.readBlock
return function (x, y, data) {
if (data) data._gdal_type = getTypedArrayType(data)
return readBlock.apply(this, arguments)
}
})()
gdal.RasterBandPixels.prototype.writeBlock = (function () {
const writeBlock = gdal.RasterBandPixels.prototype.writeBlock
return function (x, y, data) {
data._gdal_type = getTypedArrayType(data)
return writeBlock.apply(this, arguments)
}
})()