#include "gdal_common.hpp"
#include "gdal_feature_defn.hpp"
#include "gdal_field_defn.hpp"
#include "collections/feature_defn_fields.hpp"
namespace node_gdal {
Nan::Persistent<FunctionTemplate> FeatureDefn::constructor;
void FeatureDefn::Initialize(Local<Object> target)
{
Nan::HandleScope scope;
Local<FunctionTemplate> lcons = Nan::New<FunctionTemplate>(FeatureDefn::New);
lcons->InstanceTemplate()->SetInternalFieldCount(1);
lcons->SetClassName(Nan::New("FeatureDefn").ToLocalChecked());
Nan::SetPrototypeMethod(lcons, "toString", toString);
Nan::SetPrototypeMethod(lcons, "clone", clone);
ATTR(lcons, "name", nameGetter, READ_ONLY_SETTER);
ATTR(lcons, "fields", fieldsGetter, READ_ONLY_SETTER);
ATTR(lcons, "styleIgnored", styleIgnoredGetter, styleIgnoredSetter);
ATTR(lcons, "geomIgnored", geomIgnoredGetter, geomIgnoredSetter);
ATTR(lcons, "geomType", geomTypeGetter, geomTypeSetter);
Nan::Set(target, Nan::New("FeatureDefn").ToLocalChecked(), Nan::GetFunction(lcons).ToLocalChecked());
constructor.Reset(lcons);
}
FeatureDefn::FeatureDefn(OGRFeatureDefn *def)
: Nan::ObjectWrap(),
this_(def),
owned_(true)
{
LOG("Created FeatureDefn [%p]", def);
}
FeatureDefn::FeatureDefn()
: Nan::ObjectWrap(),
this_(0),
owned_(true)
{
}
FeatureDefn::~FeatureDefn()
{
if(this_) {
LOG("Disposing FeatureDefn [%p] (%s)", this_, owned_ ? "owned" : "unowned");
if(owned_) this_->Release();
this_ = NULL;
LOG("Disposed FeatureDefn [%p]", this_);
}
}
/**
* Definition of a feature class or feature layer.
*
* @constructor
* @class gdal.FeatureDefn
*/
NAN_METHOD(FeatureDefn::New)
{
Nan::HandleScope scope;
FeatureDefn *f;
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();
f = static_cast<FeatureDefn *>(ptr);
} else {
if (info.Length() != 0) {
Nan::ThrowError("FeatureDefn constructor doesn't take any arguments");
return;
}
f = new FeatureDefn(new OGRFeatureDefn());
f->this_->Reference();
}
Local<Value> fields = FeatureDefnFields::New(info.This());
Nan::SetPrivate(info.This(), Nan::New("fields_").ToLocalChecked(), fields);
f->Wrap(info.This());
info.GetReturnValue().Set(info.This());
}
Local<Value> FeatureDefn::New(OGRFeatureDefn *def)
{
Nan::EscapableHandleScope scope;
return scope.Escape(FeatureDefn::New(def, false));
}
Local<Value> FeatureDefn::New(OGRFeatureDefn *def, bool owned)
{
Nan::EscapableHandleScope scope;
if (!def) {
return scope.Escape(Nan::Null());
}
//make a copy of featuredefn owned by a layer
// + no need to track when a layer is destroyed
// + no need to throw errors when a method trys to modify an owned read-only featuredefn
// - is slower
//TODO: cloning maybe unnecessary if reference counting is done right.
// def->Reference(); def->Release();
if (!owned) {
def = def->Clone();
}
FeatureDefn *wrapped = new FeatureDefn(def);
wrapped->owned_ = true;
def->Reference();
Local<Value> ext = Nan::New<External>(wrapped);
Local<Object> obj = Nan::NewInstance(Nan::GetFunction(Nan::New(FeatureDefn::constructor)).ToLocalChecked(), 1, &ext).ToLocalChecked();
return scope.Escape(obj);
}
NAN_METHOD(FeatureDefn::toString)
{
Nan::HandleScope scope;
info.GetReturnValue().Set(Nan::New("FeatureDefn").ToLocalChecked());
}
/**
* Clones the feature definition.
*
* @method clone
* @return {gdal.FeatureDefn}
*/
NAN_METHOD(FeatureDefn::clone)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
info.GetReturnValue().Set(FeatureDefn::New(def->this_->Clone()));
}
/**
* @readOnly
* @attribute name
* @type {String}
*/
NAN_GETTER(FeatureDefn::nameGetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
info.GetReturnValue().Set(SafeString::New(def->this_->GetName()));
}
/**
* WKB geometry type ({{#crossLink "Constants (wkbGeometryType)"}}see table{{/crossLink}})
*
* @attribute geomType
* @type {Integer}
*/
NAN_GETTER(FeatureDefn::geomTypeGetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Integer>(def->this_->GetGeomType()));
}
/**
* @attribute geomIgnored
* @type {Boolean}
*/
NAN_GETTER(FeatureDefn::geomIgnoredGetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Boolean>(def->this_->IsGeometryIgnored()));
}
/**
* @attribute styleIgnored
* @type {Boolean}
*/
NAN_GETTER(FeatureDefn::styleIgnoredGetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Boolean>(def->this_->IsStyleIgnored()));
}
/**
* @readOnly
* @attribute fields
* @type {gdal.FeatureDefnFields}
*/
NAN_GETTER(FeatureDefn::fieldsGetter)
{
Nan::HandleScope scope;
info.GetReturnValue().Set(Nan::GetPrivate(info.This(), Nan::New("fields_").ToLocalChecked()).ToLocalChecked());
}
NAN_SETTER(FeatureDefn::geomTypeSetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
if(!value->IsInt32()){
Nan::ThrowError("geomType must be an integer");
return;
}
def->this_->SetGeomType(OGRwkbGeometryType(Nan::To<int64_t>(value).ToChecked()));
}
NAN_SETTER(FeatureDefn::geomIgnoredSetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
if(!value->IsBoolean()){
Nan::ThrowError("geomIgnored must be a boolean");
return;
}
def->this_->SetGeometryIgnored(Nan::To<int64_t>(value).ToChecked());
}
NAN_SETTER(FeatureDefn::styleIgnoredSetter)
{
Nan::HandleScope scope;
FeatureDefn *def = Nan::ObjectWrap::Unwrap<FeatureDefn>(info.This());
if(!value->IsBoolean()){
Nan::ThrowError("styleIgnored must be a boolean");
return;
}
def->this_->SetStyleIgnored(Nan::To<int64_t>(value).ToChecked());
}
} // namespace node_gdal