/
mapnik_js_datasource.cpp
124 lines (99 loc) · 3.6 KB
/
mapnik_js_datasource.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
#include <mapnik/datasource_cache.hpp>
#include "mapnik_js_datasource.hpp"
#include "utils.hpp"
#include "mem_datasource.hpp"
Persistent<FunctionTemplate> JSDatasource::constructor;
void JSDatasource::Initialize(Handle<Object> target) {
HandleScope scope;
constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(JSDatasource::New));
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("JSDatasource"));
// methods
NODE_SET_PROTOTYPE_METHOD(constructor, "next", next);
target->Set(String::NewSymbol("JSDatasource"),constructor->GetFunction());
}
JSDatasource::JSDatasource() :
ObjectWrap(),
ds_ptr_() {}
JSDatasource::~JSDatasource()
{
}
Handle<Value> JSDatasource::New(const Arguments& args)
{
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();
JSDatasource* d = static_cast<JSDatasource*>(ptr);
d->Wrap(args.This());
return args.This();
}
if (!args.Length() == 2){
return ThrowException(Exception::TypeError(
String::New("two argument required: an object of key:value datasource options and a callback function for features")));
}
if (!args[0]->IsObject())
return ThrowException(Exception::TypeError(
String::New("Must provide an object, eg {extent: '-180,-90,180,90'}")));
Local<Object> options = args[0]->ToObject();
// function callback
if (!args[args.Length()-1]->IsFunction())
return ThrowException(Exception::TypeError(
String::New("last argument must be a callback function")));
// 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;
params["type"] = "js";
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_ptr(new js_datasource(params,bind,args[args.Length()-1]));
}
catch (std::exception const& ex)
{
return ThrowException(Exception::Error(
String::New(ex.what())));
}
catch (...)
{
return ThrowException(Exception::Error(
String::New("unknown exception happened, please file bug")));
}
if (ds)
{
JSDatasource* d = new JSDatasource();
d->Wrap(args.This());
d->ds_ptr_ = ds;
return args.This();
}
return Undefined();
}
Handle<Value> JSDatasource::next(const Arguments& args)
{
HandleScope scope;
JSDatasource* d = ObjectWrap::Unwrap<JSDatasource>(args.This());
js_datasource *js = dynamic_cast<js_datasource *>(d->ds_ptr_.get());
return scope.Close((*js->cb_)->Call(Context::GetCurrent()->Global(), 0, NULL));
}
*/