mirror of
https://github.com/BertoldVdb/ZoneDetect.git
synced 2026-04-27 14:57:40 +00:00
Add Node.JS API + binding
This commit is contained in:
parent
3230c7acfe
commit
c8668dd213
4 changed files with 187 additions and 0 deletions
27
node_js/geozone.js
Normal file
27
node_js/geozone.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
var express = require('express');
|
||||
var zd = require('node_binding')
|
||||
var router = express.Router();
|
||||
|
||||
zd.opendb("../library/timezone21.bin")
|
||||
|
||||
router.get('/', function(req, res, next) {
|
||||
if (typeof req.query === 'undefined') {
|
||||
return res.send([]);
|
||||
}
|
||||
|
||||
var lat = parseFloat(req.query.lat)
|
||||
var lon = parseFloat(req.query.lon)
|
||||
var compact = req.query.c === "1";
|
||||
|
||||
var replacer = function(key, val) {
|
||||
return val.toFixed ? Number(val.toFixed(6)) : val;
|
||||
}
|
||||
|
||||
var result = JSON.stringify(zd.lookup(lat, lon, !compact), replacer, compact?0:2)
|
||||
|
||||
res.set('Access-Control-Allow-Origin', '*');
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.send(result)
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
130
node_js/node_binding/binding.cpp
Normal file
130
node_js/node_binding/binding.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#include <napi.h>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include "zonedetect.h"
|
||||
using namespace Napi;
|
||||
|
||||
ZoneDetect* zdTimezone;
|
||||
|
||||
Object formatOutput(Env env, ZoneDetect* database, float lat, float lon, bool withNotice) {
|
||||
Object obj = Object::New(env);
|
||||
|
||||
if(lat > 90 || lat < -90 || lon > 180 || lon < -180 || std::isnan(lat) || std::isnan(lon)){
|
||||
return obj;
|
||||
}
|
||||
|
||||
float safezone;
|
||||
ZoneDetectResult* results = ZDLookup(database, lat, lon, &safezone);
|
||||
if(!results){
|
||||
return obj;
|
||||
}
|
||||
|
||||
unsigned int index = 0;
|
||||
std::vector<Object> sobjects;
|
||||
while(results[index].lookupResult != ZD_LOOKUP_END) {
|
||||
Object sobj = Object::New(env);
|
||||
sobj.Set(Napi::String::New(env, "Result"),
|
||||
Napi::String::New(env, ZDLookupResultToString(results[index].lookupResult)));
|
||||
|
||||
std::string finalTimezone;
|
||||
for(unsigned int i=0; i<results[index].numFields; i++){
|
||||
if(!results[index].fieldNames || !results[index].data){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(results[index].fieldNames[i] && results[index].data[i]){
|
||||
/* Combine zone with prefix */
|
||||
if(std::string(results[index].fieldNames[i]) == "TimezoneId"){
|
||||
finalTimezone += results[index].data[i];
|
||||
} else
|
||||
if(std::string(results[index].fieldNames[i]) == "TimezoneIdPrefix"){
|
||||
finalTimezone = results[index].data[i] + finalTimezone;
|
||||
} else {
|
||||
sobj.Set(Napi::String::New(env, results[index].fieldNames[i]),
|
||||
Napi::String::New(env, results[index].data[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
sobj.Set(Napi::String::New(env, "TimezoneId"), Napi::String::New(env, finalTimezone));
|
||||
|
||||
sobjects.push_back(sobj);
|
||||
index++;
|
||||
}
|
||||
|
||||
ZDFreeResults(results);
|
||||
|
||||
if(!index){
|
||||
std::string oceanTimezone = "Etc/GMT";
|
||||
int offsetGMT = (lon+187.5f)/15.0;
|
||||
offsetGMT -= 12;
|
||||
if(offsetGMT > 0){
|
||||
oceanTimezone += "-";
|
||||
oceanTimezone += std::to_string(offsetGMT);
|
||||
}
|
||||
if(offsetGMT < 0){
|
||||
oceanTimezone += "+";
|
||||
oceanTimezone += std::to_string(-offsetGMT);
|
||||
}
|
||||
|
||||
Object sobj = Object::New(env);
|
||||
sobj.Set(Napi::String::New(env, "Result"), Napi::String::New(env, "In zone"));
|
||||
sobj.Set(Napi::String::New(env, "CountryName"), Napi::String::New(env, "High seas"));
|
||||
sobj.Set(Napi::String::New(env, "TimezoneId"), Napi::String::New(env, oceanTimezone));
|
||||
sobjects.push_back(sobj);
|
||||
}
|
||||
|
||||
Array out = Array::New(env, sobjects.size());
|
||||
for(unsigned i=0; i<sobjects.size(); i++){
|
||||
out[i] = sobjects[i];
|
||||
}
|
||||
|
||||
obj.Set(Napi::String::New(env, "Zones"), out);
|
||||
obj.Set(Napi::String::New(env, "Safezone"),
|
||||
Napi::Number::New(env, (index)?safezone:-1));
|
||||
|
||||
|
||||
std::string notice = ZDGetNotice(database);
|
||||
if(withNotice && notice != ""){
|
||||
obj.Set(Napi::String::New(env, "Notice"),
|
||||
Napi::String::New(env, notice));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void OpenDB(const CallbackInfo& info) {
|
||||
std::string path;
|
||||
|
||||
path = info[0].As<String>().Utf8Value();
|
||||
zdTimezone = ZDOpenDatabase(path.c_str());
|
||||
}
|
||||
|
||||
void CloseDB(const CallbackInfo& info) {
|
||||
ZDCloseDatabase(zdTimezone);
|
||||
zdTimezone = nullptr;
|
||||
}
|
||||
|
||||
Object Lookup(const CallbackInfo& info) {
|
||||
Env env = info.Env();
|
||||
float lat = info[0].As<Number>();
|
||||
float lon = info[1].As<Number>();
|
||||
bool withNotice = info[2].As<Boolean>();
|
||||
|
||||
|
||||
if(zdTimezone){
|
||||
auto country = formatOutput(env, zdTimezone, lat, lon, withNotice);
|
||||
return country;
|
||||
}
|
||||
|
||||
|
||||
return Object::New(env);
|
||||
}
|
||||
|
||||
Object Init(Env env, Object exports) {
|
||||
exports.Set("opendb", Function::New(env, OpenDB));
|
||||
exports.Set("closedb", Function::New(env, CloseDB));
|
||||
exports.Set("lookup", Function::New(env, Lookup));
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(addon, Init)
|
||||
21
node_js/node_binding/binding.gyp
Normal file
21
node_js/node_binding/binding.gyp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "zd",
|
||||
"sources": [
|
||||
"binding.cpp",
|
||||
"../../library/zonedetect.c"
|
||||
],
|
||||
"include_dirs": [
|
||||
"<!@(nodejs -p \"require('node-addon-api').include\")",
|
||||
"../../library/"
|
||||
],
|
||||
"dependencies": [
|
||||
"<!(nodejs -p \"require('node-addon-api').gyp\")"
|
||||
],
|
||||
"cflags!": ["-fno-exceptions"],
|
||||
"cflags_cc!": ["-fno-exceptions"],
|
||||
"defines": ["NAPI_CPP_EXCEPTIONS"]
|
||||
}
|
||||
]
|
||||
}
|
||||
9
node_js/node_binding/package.json
Normal file
9
node_js/node_binding/package.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "zd",
|
||||
"version": "1.0.0",
|
||||
"private": false,
|
||||
"gypfile": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": ""
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue