-
Notifications
You must be signed in to change notification settings - Fork 165
Expand file tree
/
Copy pathmapnik_expression.cpp
More file actions
105 lines (92 loc) · 3.38 KB
/
mapnik_expression.cpp
File metadata and controls
105 lines (92 loc) · 3.38 KB
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
#include "utils.hpp"
#include "mapnik_expression.hpp"
#include "mapnik_feature.hpp"
#include "object_to_container.hpp"
// mapnik
#include <mapnik/attribute.hpp>
#include <mapnik/expression_string.hpp>
#include <mapnik/expression_evaluator.hpp>
Napi::FunctionReference Expression::constructor;
Napi::Object Expression::Initialize(Napi::Env env, Napi::Object exports, napi_property_attributes prop_attr)
{
// clang-format off
Napi::Function func = DefineClass(env, "Expression", {
InstanceMethod<&Expression::evaluate>("evaluate", prop_attr),
InstanceMethod<&Expression::toString>("toString", prop_attr)
});
// clang-format on
constructor = Napi::Persistent(func);
constructor.SuppressDestruct();
exports.Set("Expression", func);
return exports;
}
Expression::Expression(Napi::CallbackInfo const& info)
: Napi::ObjectWrap<Expression>(info)
{
Napi::Env env = info.Env();
if (info.Length() != 1 || !info[0].IsString())
{
Napi::TypeError::New(env, "invalid arguments: accepts a single argument of string type").ThrowAsJavaScriptException();
return;
}
try
{
expression_ = mapnik::parse_expression(info[0].As<Napi::String>());
}
catch (std::exception const& ex)
{
Napi::Error::New(env, ex.what()).ThrowAsJavaScriptException();
}
}
Napi::Value Expression::toString(Napi::CallbackInfo const& info)
{
Napi::Env env = info.Env();
Napi::EscapableHandleScope scope(env);
Napi::String str = Napi::String::New(env, mapnik::to_expression_string(*expression_));
return scope.Escape(str);
}
Napi::Value Expression::evaluate(Napi::CallbackInfo const& info)
{
Napi::Env env = info.Env();
Napi::EscapableHandleScope scope(env);
if (info.Length() < 1)
{
Napi::Error::New(env, "requires a mapnik.Feature as an argument").ThrowAsJavaScriptException();
return env.Undefined();
}
if (!info[0].IsObject())
{
Napi::TypeError::New(env, "first argument is invalid, must be a mapnik.Feature").ThrowAsJavaScriptException();
return env.Undefined();
}
Napi::Object obj = info[0].As<Napi::Object>();
if (!obj.InstanceOf(Feature::constructor.Value()))
{
Napi::TypeError::New(env, "first argument is invalid, must be a mapnik.Feature").ThrowAsJavaScriptException();
return env.Undefined();
}
Feature* f = Napi::ObjectWrap<Feature>::Unwrap(obj);
mapnik::attributes vars;
if (info.Length() > 1)
{
if (!info[1].IsObject())
{
Napi::TypeError::New(env, "optional second argument must be an options object").ThrowAsJavaScriptException();
return env.Undefined();
}
Napi::Object options = info[1].As<Napi::Object>();
if (options.Has("variables"))
{
Napi::Value bind_opt = options.Get("variables");
if (!bind_opt.IsObject())
{
Napi::TypeError::New(env, "optional arg 'variables' must be an object").ThrowAsJavaScriptException();
return env.Undefined();
}
object_to_container(vars, bind_opt.As<Napi::Object>());
}
}
using namespace mapnik;
value val = util::apply_visitor(mapnik::evaluate<feature_impl, value, attributes>(*f->impl(), vars), *expression_);
return scope.Escape(util::apply_visitor(node_mapnik::value_converter(env), val));
}