Handle<Value> Datasource::New(const Arguments& args)
{
    HandleScope scope;

    if (!args.IsConstructCall())
        return ThrowException(String::New("Cannot call constructor as function, you need to use 'new' keyword"));

    if (args[0]->IsExternal())
    {
        //std::clog << "external!\n";
        Local<External> ext = Local<External>::Cast(args[0]);
        void* ptr = ext->Value();
        Datasource* d =  static_cast<Datasource*>(ptr);
        d->Wrap(args.This());
        return args.This();
    }
    if (!args.Length() == 1){
        return ThrowException(Exception::TypeError(
          String::New("accepts only one argument, an object of key:value datasource options")));
    }

    if (!args[0]->IsObject())
        return ThrowException(Exception::TypeError(
          String::New("must provide an object, eg {type: 'shape', file : 'world.shp'}")));

    Local<Object> options = args[0]->ToObject();

    // TODO - maybe validate in js?

    bool bind=true;
    if (options->Has(String::New("bind")))
    {
        Local<Value> bind_opt = options->Get(String::New("bind"));
        if (!bind_opt->IsBoolean())
          return ThrowException(Exception::TypeError(
            String::New("'bind' must be a Boolean")));

        bind = bind_opt->BooleanValue();
    }

    mapnik::parameters params;
    Local<Array> names = options->GetPropertyNames();
    uint32_t i = 0;
    uint32_t a_length = names->Length();
    while (i < a_length) {
        Local<Value> name = names->Get(i)->ToString();
        Local<Value> value = options->Get(name);
        params[TOSTR(name)] = TOSTR(value);
        i++;
    }

    mapnik::datasource_ptr ds;
    try
    {
        ds = mapnik::datasource_cache::create(params, bind);
    }
    catch (const mapnik::config_error & ex )
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
    catch (const mapnik::datasource_exception & ex )
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
    catch (const std::runtime_error & ex )
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
    catch (const std::exception & ex)
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
    catch (...)
    {
        return ThrowException(Exception::Error(
          String::New("unknown exception happened, please file bug")));
    }
    if (ds)
    {
        Datasource* d = new Datasource();
        d->Wrap(args.This());
        d->datasource_ = ds;
        return args.This();
    }

    return Undefined();
}
Пример #2
0
Handle<Value> Datasource::New(const Arguments& args)
{
    HandleScope scope;

    if (!args.IsConstructCall())
        return ThrowException(String::New("Cannot call constructor as function, you need to use 'new' keyword"));

    if (args[0]->IsExternal())
    {
        //std::clog << "external!\n";
        Local<External> ext = Local<External>::Cast(args[0]);
        void* ptr = ext->Value();
        Datasource* d =  static_cast<Datasource*>(ptr);
        if (d->datasource_->type() == mapnik::datasource::Raster)
        {
            args.This()->Set(String::NewSymbol("type"),
                             String::NewSymbol("raster"),
                             static_cast<v8::PropertyAttribute>(v8::ReadOnly|v8::DontDelete));
        }
        else
        {
            args.This()->Set(String::NewSymbol("type"),
                             String::NewSymbol("vector"),
                             static_cast<v8::PropertyAttribute>(v8::ReadOnly|v8::DontDelete));
        }
        d->Wrap(args.This());
        return args.This();
    }
    if (args.Length() != 1){
        return ThrowException(Exception::TypeError(
                                  String::New("accepts only one argument, an object of key:value datasource options")));
    }

    if (!args[0]->IsObject())
        return ThrowException(Exception::TypeError(
                                  String::New("Must provide an object, eg {type: 'shape', file : 'world.shp'}")));

    Local<Object> options = args[0]->ToObject();

    mapnik::parameters params;
    Local<Array> names = options->GetPropertyNames();
    unsigned int i = 0;
    unsigned int a_length = names->Length();
    while (i < a_length) {
        Local<Value> name = names->Get(i)->ToString();
        Local<Value> value = options->Get(name);
        // TODO - don't treat everything as strings
        params[TOSTR(name)] = TOSTR(value);
        i++;
    }

    mapnik::datasource_ptr ds;
    try
    {
#if MAPNIK_VERSION >= 200200
        ds = mapnik::datasource_cache::instance().create(params);
#else
        ds = mapnik::datasource_cache::instance()->create(params);
#endif
    }
    catch (std::exception const& ex)
    {
        return ThrowException(Exception::Error(
                                  String::New(ex.what())));
    }

    if (ds)
    {
        if (ds->type() == mapnik::datasource::Raster)
        {
            args.This()->Set(String::NewSymbol("type"),
                             String::NewSymbol("raster"),
                             static_cast<v8::PropertyAttribute>(v8::ReadOnly|v8::DontDelete));
        }
        else
        {
            args.This()->Set(String::NewSymbol("type"),
                             String::NewSymbol("vector"),
                             static_cast<v8::PropertyAttribute>(v8::ReadOnly|v8::DontDelete));
        }
        Datasource* d = new Datasource();
        d->Wrap(args.This());
        d->datasource_ = ds;
        return args.This();
    }
    return Undefined();
}