#include "../gdal_common.hpp"
#include "../gdal_driver.hpp"
#include "gdal_drivers.hpp"
namespace node_gdal {
Nan::Persistent<FunctionTemplate> GDALDrivers::constructor;
void GDALDrivers::Initialize(Local<Object> target)
{
Nan::HandleScope scope;
Local<FunctionTemplate> lcons = Nan::New<FunctionTemplate>(GDALDrivers::New);
lcons->InstanceTemplate()->SetInternalFieldCount(1);
lcons->SetClassName(Nan::New("GDALDrivers").ToLocalChecked());
Nan::SetPrototypeMethod(lcons, "toString", toString);
Nan::SetPrototypeMethod(lcons, "count", count);
Nan::SetPrototypeMethod(lcons, "get", get);
Nan::SetPrototypeMethod(lcons, "getNames", getNames);
GDALAllRegister();
#if GDAL_VERSION_MAJOR < 2
OGRRegisterAll();
#endif
Nan::Set(target, Nan::New("GDALDrivers").ToLocalChecked(), Nan::GetFunction(lcons).ToLocalChecked());
constructor.Reset(lcons);
}
GDALDrivers::GDALDrivers()
: Nan::ObjectWrap()
{}
GDALDrivers::~GDALDrivers()
{}
/**
* An collection of all {{#crossLink "gdal.Driver"}}drivers{{/crossLink}} registered with GDAL.
*
* @class gdal.GDALDrivers
*/
NAN_METHOD(GDALDrivers::New)
{
Nan::HandleScope scope;
if (!info.IsConstructCall()) {
Nan::ThrowError("Cannot call constructor as function, you need to use 'new' keyword");
return;
}
if (info[0]->IsExternal()) {
Local<External> ext = info[0].As<External>();
void* ptr = ext->Value();
GDALDrivers *f = static_cast<GDALDrivers *>(ptr);
f->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
Nan::ThrowError("Cannot create GDALDrivers directly");
return;
}
}
Local<Value> GDALDrivers::New()
{
Nan::EscapableHandleScope scope;
GDALDrivers *wrapped = new GDALDrivers();
v8::Local<v8::Value> ext = Nan::New<External>(wrapped);
v8::Local<v8::Object> obj = Nan::NewInstance(Nan::GetFunction(Nan::New(GDALDrivers::constructor)).ToLocalChecked(), 1, &ext).ToLocalChecked();
return scope.Escape(obj);
}
NAN_METHOD(GDALDrivers::toString)
{
Nan::HandleScope scope;
info.GetReturnValue().Set(Nan::New("GDALDrivers").ToLocalChecked());
}
/**
* Returns a driver with the specified name.
*
* Note: Prior to GDAL2.x there is a separate driver for vector VRTs and raster VRTs.
* Use `"VRT:vector"` to fetch the vector VRT driver and `"VRT:raster"` to fetch the raster VRT driver.
*
* @method get
* @param {Integer|string} index 0-based index or driver name
* @return {gdal.Driver}
*/
NAN_METHOD(GDALDrivers::get)
{
Nan::HandleScope scope;
#if GDAL_VERSION_MAJOR < 2
OGRSFDriver *ogr_driver;
#endif
GDALDriver *gdal_driver;
if (info.Length() == 0) {
Nan::ThrowError("Either driver name or index must be provided");
return;
}
if(info[0]->IsString()){
//try getting OGR driver first, and then GDAL driver if it fails
//A driver named "VRT" exists for both GDAL and OGR, so if building
//with <2.0 require user to specify which driver to pick
std::string name = *Nan::Utf8String(info[0]);
#if GDAL_VERSION_MAJOR < 2
if(name == "VRT") {
Nan::ThrowError("Name \"VRT\" is ambiguous before GDAL 2.0. Use VRT:raster or VRT:vector instead");
return;
}
ogr_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(name.c_str());
if(ogr_driver) {
info.GetReturnValue().Set(Driver::New(ogr_driver));
return;
}
#endif
if(name == "VRT:vector") {
#if GDAL_VERSION_MAJOR < 2
ogr_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("VRT");
if(ogr_driver) {
info.GetReturnValue().Set(Driver::New(ogr_driver));
return;
}
#else
name = "VRT";
#endif
}
if (name == "VRT:raster") {
name = "VRT";
}
gdal_driver = GetGDALDriverManager()->GetDriverByName(name.c_str());
if(gdal_driver) {
info.GetReturnValue().Set(Driver::New(gdal_driver));
return;
}
} else if(info[0]->IsNumber()) {
int i = static_cast<int>(Nan::To<int64_t>(info[0]).ToChecked());
gdal_driver = GetGDALDriverManager()->GetDriver(i);
if(gdal_driver) {
info.GetReturnValue().Set(Driver::New(gdal_driver));
return;
}
#if GDAL_VERSION_MAJOR < 2
i -= GetGDALDriverManager()->GetDriverCount();
ogr_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i);
if(ogr_driver) {
info.GetReturnValue().Set(Driver::New(ogr_driver));
return;
}
#endif
} else {
Nan::ThrowError("Argument must be string or integer");
return;
}
info.GetReturnValue().Set(Nan::Null());
}
/**
* Returns an array with the names of all the drivers registered with GDAL.
*
* @method getNames
* @return {string[]}
*/
NAN_METHOD(GDALDrivers::getNames)
{
Nan::HandleScope scope;
int gdal_count = GetGDALDriverManager()->GetDriverCount();
int i, ogr_count = 0;
std::string name;
#if GDAL_VERSION_MAJOR < 2
ogr_count = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
#endif
int n = gdal_count + ogr_count;
Local<Array> driver_names = Nan::New<Array>(n);
for (i = 0; i < gdal_count; ++i) {
GDALDriver *driver = GetGDALDriverManager()->GetDriver(i);
name = driver->GetDescription();
#if GDAL_VERSION_MAJOR < 2
if(name == "VRT") name = "VRT:raster";
#endif
Nan::Set(driver_names, i, SafeString::New(name.c_str()));
}
#if GDAL_VERSION_MAJOR < 2
for (; i < n; ++i) {
OGRSFDriver *driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i - gdal_count);
name = driver->GetName();
if(name == "VRT") name = "VRT:vector";
Nan::Set(driver_names, i, SafeString::New(name.c_str()));
}
#endif
info.GetReturnValue().Set(driver_names);
}
/**
* Returns the number of drivers registered with GDAL.
*
* @method count
* @return {Integer}
*/
NAN_METHOD(GDALDrivers::count)
{
Nan::HandleScope scope;
int count = GetGDALDriverManager()->GetDriverCount();
#if GDAL_VERSION_MAJOR < 2
count += OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
#endif
info.GetReturnValue().Set(Nan::New<Integer>(count));
}
} // namespace node_gdal