From 03656593406ef6fa58d2b1679b73194d55c4bb44 Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Thu, 7 May 2020 17:32:10 +0800 Subject: [PATCH 1/6] add fishnet map --- cpp/src/CMakeLists.txt | 3 + cpp/src/arrow/render_api.cpp | 395 ++- cpp/src/arrow/render_api.h | 30 +- cpp/src/render/2d/fishnet_map/fishnet_map.cpp | 276 ++ cpp/src/render/2d/fishnet_map/fishnet_map.h | 58 + cpp/src/render/render_builder.h | 34 +- cpp/src/render/render_builder_impl.h | 162 +- cpp/src/render/utils/agg/agg_handler.cpp | 33 + cpp/src/render/utils/agg/agg_handler.h | 200 ++ cpp/src/render/utils/color/color_gradient.cpp | 8 + cpp/src/render/utils/color/color_gradient.h | 1 + cpp/src/render/utils/render_utils.cpp | 20 + cpp/src/render/utils/render_utils.h | 6 + .../vega_fishnet_map/vega_fishnet_map.cpp | 113 + .../vega/vega_fishnet_map/vega_fishnet_map.h | 57 + cpp/unittest/render/CMakeLists.txt | 2 + cpp/unittest/render/fishnetmap_test.cpp | 740 +++++ cpp/unittest/render/heatmap_test.cpp | 850 ----- cpp/unittest/render/iconviz_test.cpp | 67 +- cpp/unittest/render/pointmap_test.cpp | 236 +- .../render/render_builder_api_test.cpp | 2389 ++++++++++++++ .../render/weighted_pointmap_test.cpp | 2750 ----------------- python/arctern/_wrapper_func.py | 162 +- python/arctern/cython/arctern_core_.pyx | 25 +- python/arctern/cython/arctern_core__.pxd | 5 +- python/arctern/cython/render.h | 11 +- python/arctern/util/vega/_vega_functions.py | 23 + .../arctern/util/vega/fishnetmap/__init__.py | 13 + .../util/vega/fishnetmap/vega_fishnetmap.py | 131 + python/arctern/util/vega/vega_node.py | 2 +- python/tests/geo/render_test.py | 32 +- spark/pyspark/arctern_pyspark/render_func.py | 51 + spark/pyspark/examples/render/nyc_taxi.py | 23 +- 33 files changed, 4559 insertions(+), 4349 deletions(-) create mode 100644 cpp/src/render/2d/fishnet_map/fishnet_map.cpp create mode 100644 cpp/src/render/2d/fishnet_map/fishnet_map.h create mode 100644 cpp/src/render/utils/agg/agg_handler.cpp create mode 100644 cpp/src/render/utils/agg/agg_handler.h create mode 100644 cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp create mode 100644 cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.h create mode 100644 cpp/unittest/render/fishnetmap_test.cpp create mode 100644 cpp/unittest/render/render_builder_api_test.cpp create mode 100644 python/arctern/util/vega/fishnetmap/__init__.py create mode 100644 python/arctern/util/vega/fishnetmap/vega_fishnetmap.py diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 7986ac153..2feff2cf2 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -18,6 +18,7 @@ include_directories(${ARCTERN_THIRDPARTY_SRC}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(render_src + render/2d/fishnet_map/fishnet_map.cpp render/2d/scatter_plot/pointmap.cpp render/2d/scatter_plot/weighted_pointmap.cpp render/2d/choropleth_map/choropleth_map.cpp @@ -25,7 +26,9 @@ set(render_src render/2d/heatmap/heatmap.cpp render/2d/heatmap/set_color.cpp render/2d/icon/icon_viz.cpp + render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp render/utils/render_utils.cpp + render/utils/agg/agg_handler.cpp render/utils/vega/vega_scatter_plot/vega_pointmap.cpp render/utils/vega/vega_scatter_plot/vega_weighted_pointmap.cpp render/utils/vega/vega_choropleth_map/vega_choropleth_map.cpp diff --git a/cpp/src/arrow/render_api.cpp b/cpp/src/arrow/render_api.cpp index 79ad4e204..deecee12a 100644 --- a/cpp/src/arrow/render_api.cpp +++ b/cpp/src/arrow/render_api.cpp @@ -24,6 +24,7 @@ #include #include "render/render_builder.h" +#include "render/utils/agg/agg_handler.h" #include "render/utils/render_utils.h" #include "arrow/render_api.h" @@ -107,7 +108,7 @@ template std::pair render_weighted_pointmap( const std::vector& points, const std::vector& weights, const std::string& conf) { - auto data = weight_agg(points, weights); + auto data = AggHandler::weight_agg(points, weights); auto num_point = data.first.size(); std::vector input_x(num_point); @@ -119,13 +120,13 @@ std::pair render_weighted_pointmap( rapidjson::Value mark_enter; mark_enter = document["marks"][0]["encode"]["enter"]; auto agg = mark_enter["aggregation_type"]["value"].GetString(); - AggType type_agg = agg_type(agg); + AggHandler::AggType type_agg = AggHandler::agg_type(agg); const auto& result_wkb = data.first; const auto& result_weight = data.second; switch (type_agg) { - case AggType::MAX: { + case AggHandler::AggType::MAX: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -134,7 +135,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::MIN: { + case AggHandler::AggType::MIN: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -143,7 +144,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::COUNT: { + case AggHandler::AggType::COUNT: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -152,7 +153,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::SUM: { + case AggHandler::AggType::SUM: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -161,7 +162,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::STDDEV: { + case AggHandler::AggType::STDDEV: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -175,7 +176,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::AVG: { + case AggHandler::AggType::AVG: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -194,7 +195,7 @@ template std::pair render_weighted_pointmap( const std::vector& points, const std::vector& arr_c, const std::vector& arr_s, const std::string& conf) { - auto agg_res = weight_agg_multiple_column(points, arr_c, arr_s); + auto agg_res = AggHandler::weight_agg_multiple_column(points, arr_c, arr_s); auto num_point = std::get<0>(agg_res).size(); std::vector input_x(num_point); @@ -207,14 +208,14 @@ std::pair render_weighted_pointmap( rapidjson::Value mark_enter; mark_enter = document["marks"][0]["encode"]["enter"]; auto agg = mark_enter["aggregation_type"]["value"].GetString(); - AggType type_agg = agg_type(agg); + AggHandler::AggType type_agg = AggHandler::agg_type(agg); const auto& result_wkb = std::get<0>(agg_res); const auto& result_c = std::get<1>(agg_res); const auto& result_s = std::get<2>(agg_res); switch (type_agg) { - case AggType::MAX: { + case AggHandler::AggType::MAX: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -224,7 +225,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::MIN: { + case AggHandler::AggType::MIN: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -234,7 +235,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::COUNT: { + case AggHandler::AggType::COUNT: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -244,7 +245,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::SUM: { + case AggHandler::AggType::SUM: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -254,7 +255,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::STDDEV: { + case AggHandler::AggType::STDDEV: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -277,7 +278,7 @@ std::pair render_weighted_pointmap( } break; } - case AggType::AVG: { + case AggHandler::AggType::AVG: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -299,7 +300,7 @@ template std::pair render_heatmap(const std::vector& points, const std::vector& arr_c, const std::string& conf) { - auto data = weight_agg(points, arr_c); + auto data = AggHandler::weight_agg(points, arr_c); auto num_point = data.first.size(); std::vector input_x(num_point); @@ -311,13 +312,13 @@ std::pair render_heatmap(const std::vector& poin rapidjson::Value mark_enter; mark_enter = document["marks"][0]["encode"]["enter"]; auto agg = mark_enter["aggregation_type"]["value"].GetString(); - AggType type_agg = agg_type(agg); + AggHandler::AggType type_agg = AggHandler::agg_type(agg); const auto& result_wkb = data.first; const auto& result_weight = data.second; switch (type_agg) { - case AggType::MAX: { + case AggHandler::AggType::MAX: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -326,7 +327,7 @@ std::pair render_heatmap(const std::vector& poin } break; } - case AggType::MIN: { + case AggHandler::AggType::MIN: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -335,7 +336,7 @@ std::pair render_heatmap(const std::vector& poin } break; } - case AggType::COUNT: { + case AggHandler::AggType::COUNT: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -344,7 +345,7 @@ std::pair render_heatmap(const std::vector& poin } break; } - case AggType::SUM: { + case AggHandler::AggType::SUM: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -353,7 +354,7 @@ std::pair render_heatmap(const std::vector& poin } break; } - case AggType::STDDEV: { + case AggHandler::AggType::STDDEV: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -367,7 +368,7 @@ std::pair render_heatmap(const std::vector& poin } break; } - case AggType::AVG: { + case AggHandler::AggType::AVG: { for (int i = 0; i < num_point; i++) { input_x[i] = result_wkb[i]->toPoint()->getX(); input_y[i] = result_wkb[i]->toPoint()->getY(); @@ -386,7 +387,7 @@ template std::pair render_choroplethmap(const std::vector& arr_wkb, const std::vector& arr_c, const std::string& conf) { - auto data = weight_agg(arr_wkb, arr_c); + auto data = AggHandler::weight_agg(arr_wkb, arr_c); auto num_geo = data.second.size(); std::vector input_c(num_geo); @@ -396,37 +397,37 @@ std::pair render_choroplethmap(const std::vector rapidjson::Value mark_enter; mark_enter = document["marks"][0]["encode"]["enter"]; auto agg = mark_enter["aggregation_type"]["value"].GetString(); - AggType type_agg = agg_type(agg); + AggHandler::AggType type_agg = AggHandler::agg_type(agg); const auto& result_weight = data.second; std::size_t i = 0; switch (type_agg) { - case AggType::MAX: { + case AggHandler::AggType::MAX: { for (auto& item : result_weight) { input_c[i++] = *max_element(item.begin(), item.end()); } break; } - case AggType::MIN: { + case AggHandler::AggType::MIN: { for (auto& item : result_weight) { input_c[i++] = *min_element(item.begin(), item.end()); } break; } - case AggType::COUNT: { + case AggHandler::AggType::COUNT: { for (auto& item : result_weight) { input_c[i++] = item.size(); } break; } - case AggType::SUM: { + case AggHandler::AggType::SUM: { for (auto& item : result_weight) { input_c[i++] = accumulate(item.begin(), item.end(), 0); } break; } - case AggType::STDDEV: { + case AggHandler::AggType::STDDEV: { for (auto& item : result_weight) { T sum = accumulate(item.begin(), item.end(), 0); T mean = sum / item.size(); @@ -437,7 +438,7 @@ std::pair render_choroplethmap(const std::vector } break; } - case AggType::AVG: { + case AggHandler::AggType::AVG: { for (auto& item : result_weight) { T sum_data = accumulate(item.begin(), item.end(), 0); input_c[i++] = sum_data / item.size(); @@ -449,6 +450,93 @@ std::pair render_choroplethmap(const std::vector return choroplethmap(data.first, &input_c[0], num_geo, conf); } +template +std::pair render_fishnetmap(const std::vector& points, + const std::vector& arr_c, + const std::string& conf) { + auto data = AggHandler::weight_agg(points, arr_c); + auto num_point = data.first.size(); + + std::vector input_x(num_point); + std::vector input_y(num_point); + std::vector input_c(num_point); + + rapidjson::Document document; + document.Parse(conf.c_str()); + rapidjson::Value mark_enter; + mark_enter = document["marks"][0]["encode"]["enter"]; + auto agg = mark_enter["aggregation_type"]["value"].GetString(); + AggHandler::AggType type_agg = AggHandler::agg_type(agg); + + const auto& result_wkb = data.first; + const auto& result_weight = data.second; + + switch (type_agg) { + case AggHandler::AggType::MAX: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + input_c[i] = *max_element(result_weight[i].begin(), result_weight[i].end()); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + case AggHandler::AggType::MIN: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + input_c[i] = *min_element(result_weight[i].begin(), result_weight[i].end()); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + case AggHandler::AggType::COUNT: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + input_c[i] = result_weight[i].size(); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + case AggHandler::AggType::SUM: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + input_c[i] = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + case AggHandler::AggType::STDDEV: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + T sum = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); + T mean = sum / result_weight[i].size(); + T accum = 0; + std::for_each(std::begin(result_weight[i]), std::end(result_weight[i]), + [&](const T d) { accum += (d - mean) * (d - mean); }); + input_c[i] = sqrt(accum / result_weight[i].size()); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + case AggHandler::AggType::AVG: { + for (int i = 0; i < num_point; i++) { + input_x[i] = result_wkb[i]->toPoint()->getX(); + input_y[i] = result_wkb[i]->toPoint()->getY(); + T sum_data = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); + input_c[i] = sum_data / result_weight[i].size(); + OGRGeometryFactory::destroyGeometry(result_wkb[i]); + } + break; + } + } + + return fishnetmap(&input_x[0], &input_y[0], &input_c[0], num_point, conf); +} + const std::vector> projection( const std::vector>& geos, const std::string& bottom_right, const std::string& top_left, const int& height, @@ -491,23 +579,6 @@ std::shared_ptr point_map( return out_pic(result); } -std::shared_ptr point_map(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::string& conf) { - auto x_length = arr_x->length(); - auto y_length = arr_y->length(); - auto x_type = arr_x->type_id(); - auto y_type = arr_y->type_id(); - assert(x_length == y_length); - assert(x_type == arrow::Type::UINT32); - assert(y_type == arrow::Type::UINT32); - - auto input_x = (uint32_t*)arr_x->data()->GetValues(1); - auto input_y = (uint32_t*)arr_y->data()->GetValues(1); - - return out_pic(pointmap(input_x, input_y, x_length, conf)); -} - std::shared_ptr weighted_point_map( const std::vector>& points_vector, const std::string& conf) { @@ -655,100 +726,6 @@ std::shared_ptr weighted_point_map( } } -std::shared_ptr weighted_point_map( - const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::shared_ptr& arr_c, - const std::shared_ptr& arr_s, const std::string& conf) { - auto x_length = arr_x->length(); - auto y_length = arr_y->length(); - auto c_length = arr_c->length(); - auto s_length = arr_c->length(); - - auto x_type = arr_x->type_id(); - auto y_type = arr_y->type_id(); - auto c_type = arr_c->type_id(); - auto s_type = arr_c->type_id(); - - assert(x_length == y_length); - assert(x_length == c_length); - assert(c_length == s_length); - assert(x_type == arrow::Type::UINT32); - assert(y_type == arrow::Type::UINT32); - assert(c_type == s_type); - - auto input_x = (uint32_t*)arr_x->data()->GetValues(1); - auto input_y = (uint32_t*)arr_y->data()->GetValues(1); - - switch (c_type) { - case arrow::Type::INT8: { - auto input_c = (int8_t*)arr_c->data()->GetValues(1); - auto input_s = (int8_t*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::INT16: { - auto input_c = (int16_t*)arr_c->data()->GetValues(1); - auto input_s = (int16_t*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::INT32: { - auto input_c = (int32_t*)arr_c->data()->GetValues(1); - auto input_s = (int32_t*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::INT64: { - auto input_c = (int64_t*)arr_c->data()->GetValues(1); - auto input_s = (int64_t*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::UINT8: { - auto input_c = (uint8_t*)arr_c->data()->GetValues(1); - auto input_s = (uint8_t*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::UINT16: { - auto input_c = (uint16_t*)arr_c->data()->GetValues(1); - auto input_s = (uint16_t*)arr_s->data()->GetValues(1); - return out_pic(weighted_pointmap(input_x, input_y, input_c, input_s, - x_length, conf)); - } - case arrow::Type::UINT32: { - auto input_c = (uint32_t*)arr_c->data()->GetValues(1); - auto input_s = (uint32_t*)arr_s->data()->GetValues(1); - return out_pic(weighted_pointmap(input_x, input_y, input_c, input_s, - x_length, conf)); - } - case arrow::Type::UINT64: { - auto input_c = (uint64_t*)arr_c->data()->GetValues(1); - auto input_s = (uint64_t*)arr_s->data()->GetValues(1); - return out_pic(weighted_pointmap(input_x, input_y, input_c, input_s, - x_length, conf)); - } - case arrow::Type::FLOAT: { - auto input_c = (float*)arr_c->data()->GetValues(1); - auto input_s = (float*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - case arrow::Type::DOUBLE: { - auto input_c = (double*)arr_c->data()->GetValues(1); - auto input_s = (double*)arr_s->data()->GetValues(1); - return out_pic( - weighted_pointmap(input_x, input_y, input_c, input_s, x_length, conf)); - } - default: - std::string err_msg = - "type error of count while running weighted_pointmap, type = " + - std::to_string(c_type); - throw std::runtime_error(err_msg); - } -} - std::shared_ptr heat_map( const std::vector>& points_vector, const std::vector>& weights_vector, @@ -805,72 +782,6 @@ std::shared_ptr heat_map( } } -std::shared_ptr heat_map(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::shared_ptr& arr_c, - const std::string& conf) { - auto x_length = arr_x->length(); - auto y_length = arr_y->length(); - auto c_length = arr_c->length(); - auto x_type = arr_x->type_id(); - auto y_type = arr_y->type_id(); - auto c_type = arr_c->type_id(); - assert(x_length == y_length); - assert(x_length == c_length); - assert(x_type == arrow::Type::UINT32); - assert(y_type == arrow::Type::UINT32); - - auto input_x = (uint32_t*)arr_x->data()->GetValues(1); - auto input_y = (uint32_t*)arr_y->data()->GetValues(1); - - switch (c_type) { - case arrow::Type::INT8: { - auto input_c_int8 = (int8_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_int8, x_length, conf)); - } - case arrow::Type::INT16: { - auto input_c_int16 = (int16_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_int16, x_length, conf)); - } - case arrow::Type::INT32: { - auto input_c_int32 = (int32_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_int32, x_length, conf)); - } - case arrow::Type::INT64: { - auto input_c_int64 = (int64_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_int64, x_length, conf)); - } - case arrow::Type::UINT8: { - auto input_c_uint8 = (uint8_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_uint8, x_length, conf)); - } - case arrow::Type::UINT16: { - auto input_c_uint16 = (uint16_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_uint16, x_length, conf)); - } - case arrow::Type::UINT32: { - auto input_c_uint32 = (uint32_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_uint32, x_length, conf)); - } - case arrow::Type::UINT64: { - auto input_c_uint64 = (uint64_t*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_uint64, x_length, conf)); - } - case arrow::Type::FLOAT: { - auto input_c_float = (float*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_float, x_length, conf)); - } - case arrow::Type::DOUBLE: { - auto input_c_double = (double*)arr_c->data()->GetValues(1); - return out_pic(heatmap(input_x, input_y, input_c_double, x_length, conf)); - } - default: - std::string err_msg = - "type error of count while running heatmap, type = " + std::to_string(c_type); - throw std::runtime_error(err_msg); - } -} - std::shared_ptr choropleth_map( const std::vector>& polygons_vector, const std::vector>& weights_vector, @@ -949,22 +860,60 @@ std::shared_ptr icon_viz( return out_pic(result); } -std::shared_ptr icon_viz(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::string& conf) { - auto x_length = arr_x->length(); - auto y_length = arr_y->length(); - auto x_type = arr_x->type_id(); - auto y_type = arr_y->type_id(); - - assert(x_length == y_length); - assert(x_type == arrow::Type::UINT32); - assert(y_type == arrow::Type::UINT32); +std::shared_ptr fishnet_map( + const std::vector>& points_vector, + const std::vector>& weights_vector, + const std::string& conf) { + const auto& wkb_vec = WkbExtraction(points_vector); - auto input_x = (uint32_t*)arr_x->data()->GetValues(1); - auto input_y = (uint32_t*)arr_y->data()->GetValues(1); + auto weight_data_type = weights_vector[0]->type_id(); - return out_pic(iconviz(input_x, input_y, x_length, conf)); + switch (weight_data_type) { + case arrow::Type::INT8: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::INT16: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::INT32: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::INT64: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::UINT8: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::UINT16: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::UINT32: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::UINT64: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::FLOAT: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + case arrow::Type::DOUBLE: { + const auto& arr_c = WeightExtraction(weights_vector); + return out_pic(render_fishnetmap(wkb_vec, arr_c, conf)); + } + default: + std::string err_msg = "type error of count while running square_map, type = " + + std::to_string(weight_data_type); + throw std::runtime_error(err_msg); + } } } // namespace render diff --git a/cpp/src/arrow/render_api.h b/cpp/src/arrow/render_api.h index ec513fb7c..fc118b10d 100644 --- a/cpp/src/arrow/render_api.h +++ b/cpp/src/arrow/render_api.h @@ -37,10 +37,6 @@ const std::vector> transform_and_projection( const std::string& dst_rs, const std::string& bottom_right, const std::string& top_left, const int& height, const int& width); -std::shared_ptr point_map(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::string& conf); - std::shared_ptr point_map( const std::vector>& points_vector, const std::string& conf); @@ -50,32 +46,19 @@ std::shared_ptr weighted_point_map( const std::vector>& points_vector, const std::string& conf); -// three args api: point_map(x, y, conf), point_map(wkt, c, conf), point_map(wkt, s, conf) +// three args api: point_map(wkt, c, conf), point_map(wkt, s, conf) std::shared_ptr weighted_point_map( const std::vector>& points_vector, const std::vector>& weights_vector, const std::string& conf); -// four args api: point_map(x, y, c, conf), point_map(x, y, s, conf), point_map(wkt, c, s, -// conf) +// four args api: point_map(wkt, c, s, conf) std::shared_ptr weighted_point_map( const std::vector>& points_vector, const std::vector>& color_weights_vector, const std::vector>& size_weights_vector, const std::string& conf); -// five args api: point_map(x, y, c, s, conf) -std::shared_ptr weighted_point_map( - const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::shared_ptr& arr_c, - const std::shared_ptr& arr_s, const std::string& conf); - -std::shared_ptr heat_map(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::shared_ptr& arr_c, - const std::string& conf); - std::shared_ptr heat_map( const std::vector>& points_vector, const std::vector>& weights_vector, @@ -86,13 +69,14 @@ std::shared_ptr choropleth_map( const std::vector>& weights_vector, const std::string& conf); -std::shared_ptr icon_viz(const std::shared_ptr& arr_x, - const std::shared_ptr& arr_y, - const std::string& conf); - std::shared_ptr icon_viz( const std::vector>& points_vector, const std::string& conf); +std::shared_ptr fishnet_map( + const std::vector>& polygons_vector, + const std::vector>& weights_vector, + const std::string& conf); + } // namespace render } // namespace arctern diff --git a/cpp/src/render/2d/fishnet_map/fishnet_map.cpp b/cpp/src/render/2d/fishnet_map/fishnet_map.cpp new file mode 100644 index 000000000..a11bdf350 --- /dev/null +++ b/cpp/src/render/2d/fishnet_map/fishnet_map.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#define GL_GLEXT_PROTOTYPES +#include +#include + +#include "render/2d/fishnet_map/fishnet_map.h" +#include "render/utils/color/color_gradient.h" + +namespace arctern { +namespace render { + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template class FishNetMap; + +template +FishNetMap::FishNetMap(uint32_t* input_x, uint32_t* input_y, T* count, + int64_t num_vertices) + : vertices_x_(input_x), + vertices_y_(input_y), + count_(count), + num_vertices_(num_vertices) {} + +template +FishNetMap::~FishNetMap() { + free(vertices_x_); + free(vertices_y_); + free(colors_); +} + +template +void set_colors(float* colors, uint32_t* input_x, uint32_t* input_y, T* input_c, + int64_t num, VegaFishNetMap& vega_fishnet_map) { + WindowParams window_params = vega_fishnet_map.window_params(); + int64_t width = window_params.width(); + int64_t height = window_params.height(); + int64_t window_size = width * height; + int cell_size = vega_fishnet_map.cell_size(); + int cell_spacing = vega_fishnet_map.cell_spacing(); + + std::vector weights(num); + memcpy(&weights[0], input_c, num * sizeof(T)); + std::sort(weights.begin(), weights.end()); + int max = (int)(num * 99 / 100); + T max_pix = weights[max]; + T min_pix = weights[0]; + T count_range = max_pix - min_pix; + ColorGradient color_gradient; + color_gradient.createDefaultHeatMapGradient(); + + for (int i = 0; i < num; i++) { + float value = input_c[i] > max_pix ? 1.0f : (input_c[i] - min_pix) / count_range; + float color_r, color_g, color_b; + color_gradient.getColorAtValue(value, color_r, color_g, color_b); + + if (input_y[i] * cell_size >= height || input_x[i] * cell_size >= width) { + continue; + } + int index = cell_size * input_y[i] * width + input_x[i] * cell_size; + for (int m = 0; m < cell_size - cell_spacing; m++) { + for (int n = 0; n < cell_size - cell_spacing; n++) { + int index_in = (index + m * width + n) * 4; + colors[index_in++] = color_r; + colors[index_in++] = color_g; + colors[index_in++] = color_b; + colors[index_in++] = vega_fishnet_map.opacity(); + } + } + } +} + +template +void FishNetMap::DataInit() { + WindowParams window_params = fishnet_vega_.window_params(); + int64_t width = window_params.width(); + int64_t height = window_params.height(); + int64_t window_size = width * height; + + colors_ = (float*)malloc(window_size * 4 * sizeof(float)); + set_colors(colors_, vertices_x_, vertices_y_, count_, num_vertices_, fishnet_vega_); + vertices_x_ = (uint32_t*)malloc(window_size * sizeof(uint32_t)); + vertices_y_ = (uint32_t*)malloc(window_size * sizeof(uint32_t)); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + vertices_x_[i * width + j] = j; + vertices_y_[i * width + j] = i; + } + } + num_vertices_ = window_size; +} + +template +void FishNetMap::Draw() { + // glEnable(GL_PROGRAM_POINT_SIZE); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_POINT_SMOOTH); + +#ifdef USE_GPU + glDrawArrays(GL_POINTS, 0, num_vertices_); + glFlush(); + + glDeleteVertexArrays(1, &VAO_); + glDeleteBuffers(2, VBO_); +#else + glOrtho(0, window()->window_params().width(), 0, window()->window_params().height(), -1, + 1); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + int offset = 0; + std::vector vertices(num_vertices_ * 2); + for (auto i = 0; i < num_vertices_; i++) { + vertices[offset++] = vertices_x_[i]; + vertices[offset++] = vertices_y_[i]; + } + glColorPointer(4, GL_FLOAT, 0, colors_); + glVertexPointer(2, GL_INT, 0, &vertices[0]); + + glDrawArrays(GL_POINTS, 0, num_vertices_); + glFlush(); +#endif +} + +#ifdef USE_GPU +template +void FishNetMap::Shader() { + const char* vertexShaderSource = + "#version 430 core\n" + "layout (location = 0) in uint posX;\n" + "layout (location = 1) in uint posY;\n" + "layout (location = 2) in vec4 point_color;\n" + "layout (location = 3) uniform vec2 screen_info;\n" + "out vec4 color;\n" + "void main()\n" + "{\n" + " float tmp_x = posX;\n" + " float tmp_y = posY;\n" + " gl_Position = vec4(((tmp_x * 2) / screen_info.x) - 1, ((tmp_y * 2) / " + "screen_info.y) - 1, 0, 1);\n" + " color=point_color;\n" + "}"; + + const char* fragmentShaderSource = + "#version 430 core\n" + "in vec4 color;\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = color;\n" + "}"; + + int success; + int vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); + glCompileShader(vertexShader); + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); +#ifdef DEBUG_RENDER + if (!success) { + std::string err_msg = "vertex shader compile failed"; + throw std::runtime_error(err_msg); + } +#endif + int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); + glCompileShader(fragmentShader); + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); +#ifdef DEBUG_RENDER + if (!success) { + std::string err_msg = "fragment shader compile failed"; + throw std::runtime_error(err_msg); + } +#endif + int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); +#ifdef DEBUG_RENDER + if (!success) { + std::string err_msg = "shader program link failed"; + throw std::runtime_error(err_msg); + } +#endif + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + glGenVertexArrays(1, &VAO_); + glGenBuffers(3, VBO_); + + glBindVertexArray(VAO_); + glBindBuffer(GL_ARRAY_BUFFER, VBO_[0]); + glBufferData(GL_ARRAY_BUFFER, num_vertices_ * 1 * sizeof(uint32_t), vertices_x_, + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]); + glBufferData(GL_ARRAY_BUFFER, num_vertices_ * 1 * sizeof(uint32_t), vertices_y_, + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_[2]); + glBufferData(GL_ARRAY_BUFFER, num_vertices_ * 4 * sizeof(float), colors_, + GL_STATIC_DRAW); + + glGenVertexArrays(1, &VAO_); + glBindVertexArray(VAO_); + + glBindBuffer(GL_ARRAY_BUFFER, VBO_[0]); + glVertexAttribPointer(0, 1, GL_FLOAT, GL_TRUE, 1 * sizeof(uint32_t), (void*)0); + glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_TRUE, 1 * sizeof(uint32_t), (void*)0); + glBindBuffer(GL_ARRAY_BUFFER, VBO_[2]); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 1); + glBindVertexArray(1); + + glUseProgram(shaderProgram); + glUniform2f(3, window()->window_params().width(), window()->window_params().height()); + glBindVertexArray(VAO_); +} +#endif + +template +uint8_t* FishNetMap::Render() { + WindowsInit(fishnet_vega_.window_params()); + DataInit(); +#ifdef USE_GPU + Shader(); +#endif + Draw(); + Finalize(); + return Output(); +} + +} // namespace render +} // namespace arctern diff --git a/cpp/src/render/2d/fishnet_map/fishnet_map.h b/cpp/src/render/2d/fishnet_map/fishnet_map.h new file mode 100644 index 000000000..030e2be1b --- /dev/null +++ b/cpp/src/render/2d/fishnet_map/fishnet_map.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "render/2d/general_2d.h" +#include "render/utils/vega/vega_fishnet_map/vega_fishnet_map.h" + +namespace arctern { +namespace render { + +template +class FishNetMap : public General2D { + public: + FishNetMap() = delete; + + FishNetMap(uint32_t* input_x, uint32_t* input_y, T* count, int64_t num_vertices); + + ~FishNetMap(); + + void DataInit(); + + uint8_t* Render() final; + + void Shader(); + + void Draw() final; + + public: + VegaFishNetMap& mutable_fishnet_vega() { return fishnet_vega_; } + + private: +#ifdef USE_GPU + unsigned int VAO_; + unsigned int VBO_[3]; +#endif + uint32_t* vertices_x_; + uint32_t* vertices_y_; + T* count_; + float* colors_; + int64_t num_vertices_; + VegaFishNetMap fishnet_vega_; +}; + +} // namespace render +} // namespace arctern diff --git a/cpp/src/render/render_builder.h b/cpp/src/render/render_builder.h index cee621f75..6b4647b99 100644 --- a/cpp/src/render/render_builder.h +++ b/cpp/src/render/render_builder.h @@ -26,6 +26,7 @@ #include #include "render/2d/choropleth_map/choropleth_map.h" +#include "render/2d/fishnet_map/fishnet_map.h" #include "render/2d/heatmap/heatmap.h" #include "render/2d/icon/icon_viz.h" #include "render/2d/scatter_plot/pointmap.h" @@ -34,38 +35,19 @@ namespace arctern { namespace render { -enum AggType { - SUM = 0, - MIN, - MAX, - COUNT, - STDDEV, - AVG, -}; - void Projection(const std::vector& geos, const std::string& bottom_right, const std::string& top_left, const int& height, const int& width); +std::shared_ptr Projection(const std::shared_ptr& geos, + const std::string& bottom_right, + const std::string& top_left, const int& height, + const int& width); + void TransformAndProjection(const std::vector& geos, const std::string& src_rs, const std::string& dst_rs, const std::string& bottom_right, const std::string& top_left, const int& height, const int& width); -template -std::pair, std::vector>> weight_agg( - const std::shared_ptr& geos, - const std::shared_ptr& arr_c); - -template -std::pair, std::vector>> weight_agg( - const std::vector& wkb_arr, const std::vector& arr_c); - -template -std::tuple, std::vector>, - std::vector>> -weight_agg_multiple_column(const std::vector& geos, - const std::vector& arr_c, const std::vector& arr_s); - std::pair pointmap(uint32_t* arr_x, uint32_t* arr_y, int64_t num_vertices, const std::string& conf); @@ -95,6 +77,10 @@ std::pair choroplethmap(const std::vector& arr_ std::pair iconviz(uint32_t* arr_x, uint32_t* arr_y, int64_t num_vertices, const std::string& conf); +template +std::pair fishnetmap(uint32_t* arr_x, uint32_t* arr_y, T* arr, + int64_t num_vertices, const std::string& conf); + } // namespace render } // namespace arctern diff --git a/cpp/src/render/render_builder_impl.h b/cpp/src/render/render_builder_impl.h index 2ae691054..ed879cd9b 100644 --- a/cpp/src/render/render_builder_impl.h +++ b/cpp/src/render/render_builder_impl.h @@ -31,37 +31,6 @@ namespace arctern { namespace render { -AggType agg_type(std::string type) { - if (type == "mean") return AggType::AVG; - if (type == "sum") return AggType::SUM; - if (type == "max") return AggType::MAX; - if (type == "min") return AggType::MIN; - if (type == "count") return AggType::COUNT; - if (type == "std") return AggType::STDDEV; - std::string err_msg = "unknow agg type = " + type; - throw std::runtime_error(err_msg); -} - -void pointXY_from_wkt_with_transform(const std::string& wkt, double& x, double& y, - void* poCT) { - OGRGeometry* res_geo = nullptr; - CHECK_GDAL(OGRGeometryFactory::createFromWkt(wkt.c_str(), nullptr, &res_geo)); - CHECK_GDAL(OGR_G_Transform(res_geo, (OGRCoordinateTransformation*)poCT)); - auto rst_pointer = reinterpret_cast(res_geo); - x = rst_pointer->getX(); - y = rst_pointer->getY(); - OGRGeometryFactory::destroyGeometry(res_geo); -} - -void pointXY_from_wkt(const std::string& wkt, double& x, double& y) { - OGRGeometry* res_geo = nullptr; - CHECK_GDAL(OGRGeometryFactory::createFromWkt(wkt.c_str(), nullptr, &res_geo)); - auto rst_pointer = reinterpret_cast(res_geo); - x = rst_pointer->getX(); - y = rst_pointer->getY(); - OGRGeometryFactory::destroyGeometry(res_geo); -} - void Projection(const std::vector& geos, const std::string& bottom_right, const std::string& top_left, const int& height, const int& width) { double top_left_x, top_left_y, bottom_right_x, bottom_right_y; @@ -137,7 +106,6 @@ void TransformAndProjection(const std::vector& geos, } else { // 1. transform CHECK_GDAL(OGR_G_Transform(geo, (OGRCoordinateTransformation*)poCT)); - // 2. projection auto type = wkbFlatten(geo->getGeometryType()); if (type == wkbPoint) { @@ -167,121 +135,6 @@ void TransformAndProjection(const std::vector& geos, OCTDestroyCoordinateTransformation(poCT); } -template -std::pair, std::vector>> weight_agg( - const std::shared_ptr& geos, - const std::shared_ptr& arr_c) { - auto geo_arr = std::static_pointer_cast(geos); - auto c_arr = (T*)arr_c->data()->GetValues(1); - auto geos_size = geos->length(); - auto geo_type = geos->type_id(); - auto c_size = arr_c->length(); - assert(geo_type == arrow::Type::BINARY); - assert(geos_size == c_size); - - std::unordered_map> wkb_map; - for (size_t i = 0; i < geos_size; i++) { - std::string geo_wkb = geo_arr->GetString(i); - if (wkb_map.find(geo_wkb) == wkb_map.end()) { - std::vector weight; - weight.emplace_back(c_arr[i]); - wkb_map[geo_wkb] = weight; - } else { - auto& weight = wkb_map[geo_wkb]; - weight.emplace_back(c_arr[i]); - } - } - - std::vector results_wkb(wkb_map.size()); - std::vector> results_weight(wkb_map.size()); - int i = 0; - for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { - OGRGeometry* res_geo; - CHECK_GDAL(OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); - results_wkb[i] = res_geo; - results_weight[i] = iter->second; - i++; - } - - return std::make_pair(results_wkb, results_weight); -} - -template -std::pair, std::vector>> weight_agg( - const std::vector& wkb_arr, const std::vector& arr_c) { - assert(wkb_arr.size() == arr_c.size()); - - std::unordered_map> wkb_map; - for (size_t i = 0; i < wkb_arr.size(); i++) { - std::string wkb = wkb_arr[i]; - if (wkb_map.find(wkb) == wkb_map.end()) { - std::vector weight; - weight.emplace_back(arr_c[i]); - wkb_map[wkb] = weight; - } else { - auto& weight = wkb_map[wkb]; - weight.emplace_back(arr_c[i]); - } - } - - std::vector results_wkb(wkb_map.size()); - std::vector> results_weight(wkb_map.size()); - int i = 0; - for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { - OGRGeometry* res_geo; - CHECK_GDAL(OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); - results_wkb[i] = res_geo; - results_weight[i] = iter->second; - i++; - } - - return std::make_pair(results_wkb, results_weight); -} - -template -std::tuple, std::vector>, - std::vector>> -weight_agg_multiple_column(const std::vector& geos, - const std::vector& arr_c, const std::vector& arr_s) { - assert(geos.size() == arr_c.size()); - assert(arr_c.size() == arr_s.size()); - - using vector_pair = std::pair, std::vector>; - std::unordered_map wkb_map; - - for (size_t i = 0; i < geos.size(); i++) { - std::string geo_wkb = geos[i]; - if (wkb_map.find(geo_wkb) == wkb_map.end()) { - std::vector weight_c; - std::vector weight_s; - weight_c.emplace_back(arr_c[i]); - weight_s.emplace_back(arr_s[i]); - wkb_map[geo_wkb] = std::make_pair(weight_c, weight_s); - } else { - auto& weight_c = wkb_map[geo_wkb].first; - auto& weight_s = wkb_map[geo_wkb].second; - weight_c.emplace_back(arr_c[i]); - weight_s.emplace_back(arr_s[i]); - } - } - - std::vector results_wkb(wkb_map.size()); - std::vector> results_weight_c(wkb_map.size()); - std::vector> results_weight_s(wkb_map.size()); - - int i = 0; - for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { - OGRGeometry* res_geo; - CHECK_GDAL(OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); - results_wkb[i] = res_geo; - results_weight_c[i] = iter->second.first; - results_weight_s[i] = iter->second.second; - i++; - } - - return std::make_tuple(results_wkb, results_weight_c, results_weight_s); -} - std::pair pointmap(uint32_t* arr_x, uint32_t* arr_y, int64_t num, const std::string& conf) { VegaPointmap vega_pointmap(conf); @@ -397,5 +250,20 @@ std::pair iconviz(uint32_t* arr_x, uint32_t* arr_y, int64_t n return std::make_pair(render, ret_size); } +template +std::pair fishnetmap(uint32_t* arr_x, uint32_t* arr_y, T* arr, + int64_t num_vertices, const std::string& conf) { + VegaFishNetMap vega_fishnet_map(conf); + if (!vega_fishnet_map.is_valid()) { + return std::make_pair(nullptr, -1); + } + + FishNetMap fishnet_map(arr_x, arr_y, arr, num_vertices); + fishnet_map.mutable_fishnet_vega() = vega_fishnet_map; + const auto& render = fishnet_map.Render(); + const auto& ret_size = fishnet_map.output_image_size(); + return std::make_pair(render, ret_size); +} + } // namespace render } // namespace arctern diff --git a/cpp/src/render/utils/agg/agg_handler.cpp b/cpp/src/render/utils/agg/agg_handler.cpp new file mode 100644 index 000000000..db1e96f79 --- /dev/null +++ b/cpp/src/render/utils/agg/agg_handler.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "render/utils/agg/agg_handler.h" + +namespace arctern { +namespace render { + +AggHandler::AggType AggHandler::agg_type(std::string type) { + if (type == "mean") return AggType::AVG; + if (type == "sum") return AggType::SUM; + if (type == "max") return AggType::MAX; + if (type == "min") return AggType::MIN; + if (type == "count") return AggType::COUNT; + if (type == "std") return AggType::STDDEV; + std::string err_msg = "unknow agg type = " + type; + throw std::runtime_error(err_msg); +} + +} // namespace render +} // namespace arctern diff --git a/cpp/src/render/utils/agg/agg_handler.h b/cpp/src/render/utils/agg/agg_handler.h new file mode 100644 index 000000000..eed4ab443 --- /dev/null +++ b/cpp/src/render/utils/agg/agg_handler.h @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arrow/array.h" +#include "utils/check_status.h" + +namespace arctern { +namespace render { + +class AggHandler { + public: + enum AggType { + SUM = 0, + MIN, + MAX, + COUNT, + STDDEV, + AVG, + }; + + static AggType agg_type(std::string type); + + static std::pair, std::vector> weight_agg( + const std::shared_ptr& geos) { + auto geo_arr = std::static_pointer_cast(geos); + auto geos_size = geos->length(); + auto geo_type = geos->type_id(); + assert(geo_type == arrow::Type::BINARY); + + std::unordered_map wkb_map; + for (size_t i = 0; i < geos_size; i++) { + std::string geo_wkb = geo_arr->GetString(i); + if (wkb_map.find(geo_wkb) == wkb_map.end()) { + wkb_map[geo_wkb] = 1; + } else { + wkb_map[geo_wkb] += 1; + } + } + + std::vector results_wkb(wkb_map.size()); + std::vector results_weight(wkb_map.size()); + int i = 0; + for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { + OGRGeometry* res_geo; + CHECK_GDAL( + OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); + results_wkb[i] = res_geo; + results_weight[i] = iter->second; + i++; + } + + return std::make_pair(results_wkb, results_weight); + } + + template + static std::pair, std::vector>> weight_agg( + const std::shared_ptr& geos, + const std::shared_ptr& arr_c) { + auto geo_arr = std::static_pointer_cast(geos); + auto c_arr = (T*)arr_c->data()->GetValues(1); + auto geos_size = geos->length(); + auto geo_type = geos->type_id(); + auto c_size = arr_c->length(); + assert(geo_type == arrow::Type::BINARY); + assert(geos_size == c_size); + + std::unordered_map> wkb_map; + for (size_t i = 0; i < geos_size; i++) { + std::string geo_wkb = geo_arr->GetString(i); + if (wkb_map.find(geo_wkb) == wkb_map.end()) { + std::vector weight; + weight.emplace_back(c_arr[i]); + wkb_map[geo_wkb] = weight; + } else { + auto& weight = wkb_map[geo_wkb]; + weight.emplace_back(c_arr[i]); + } + } + + std::vector results_wkb(wkb_map.size()); + std::vector> results_weight(wkb_map.size()); + int i = 0; + for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { + OGRGeometry* res_geo; + CHECK_GDAL( + OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); + results_wkb[i] = res_geo; + results_weight[i] = iter->second; + i++; + } + + return std::make_pair(results_wkb, results_weight); + } + + template + static std::pair, std::vector>> weight_agg( + const std::vector& wkb_arr, const std::vector& arr_c) { + assert(wkb_arr.size() == arr_c.size()); + + std::unordered_map> wkb_map; + for (size_t i = 0; i < wkb_arr.size(); i++) { + std::string wkb = wkb_arr[i]; + if (wkb_map.find(wkb) == wkb_map.end()) { + std::vector weight; + weight.emplace_back(arr_c[i]); + wkb_map[wkb] = weight; + } else { + auto& weight = wkb_map[wkb]; + weight.emplace_back(arr_c[i]); + } + } + + std::vector results_wkb(wkb_map.size()); + std::vector> results_weight(wkb_map.size()); + int i = 0; + for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { + OGRGeometry* res_geo; + CHECK_GDAL( + OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); + results_wkb[i] = res_geo; + results_weight[i] = iter->second; + i++; + } + + return std::make_pair(results_wkb, results_weight); + } + + template + std::tuple, std::vector>, + std::vector>> static weight_agg_multiple_column(const std::vector& + geos, + const std::vector& arr_c, + const std::vector& arr_s) { + assert(geos.size() == arr_c.size()); + assert(arr_c.size() == arr_s.size()); + + using vector_pair = std::pair, std::vector>; + std::unordered_map wkb_map; + + for (size_t i = 0; i < geos.size(); i++) { + std::string geo_wkb = geos[i]; + if (wkb_map.find(geo_wkb) == wkb_map.end()) { + std::vector weight_c; + std::vector weight_s; + weight_c.emplace_back(arr_c[i]); + weight_s.emplace_back(arr_s[i]); + wkb_map[geo_wkb] = std::make_pair(weight_c, weight_s); + } else { + auto& weight_c = wkb_map[geo_wkb].first; + auto& weight_s = wkb_map[geo_wkb].second; + weight_c.emplace_back(arr_c[i]); + weight_s.emplace_back(arr_s[i]); + } + } + + std::vector results_wkb(wkb_map.size()); + std::vector> results_weight_c(wkb_map.size()); + std::vector> results_weight_s(wkb_map.size()); + + int i = 0; + for (auto iter = wkb_map.begin(); iter != wkb_map.end(); iter++) { + OGRGeometry* res_geo; + CHECK_GDAL( + OGRGeometryFactory::createFromWkb(iter->first.c_str(), nullptr, &res_geo)); + results_wkb[i] = res_geo; + results_weight_c[i] = iter->second.first; + results_weight_s[i] = iter->second.second; + i++; + } + + return std::make_tuple(results_wkb, results_weight_c, results_weight_s); + } +}; + +} // namespace render +} // namespace arctern diff --git a/cpp/src/render/utils/color/color_gradient.cpp b/cpp/src/render/utils/color/color_gradient.cpp index f0b4fb65f..233921b92 100644 --- a/cpp/src/render/utils/color/color_gradient.cpp +++ b/cpp/src/render/utils/color/color_gradient.cpp @@ -31,6 +31,14 @@ void ColorGradient::createDefaultHeatMapGradient() { color.push_back(Color(1, 0, 0, 1.0f)); // Red. } +void ColorGradient::createSquareMapGradient(std::vector color) { + color.clear(); + + color.push_back(Color(0, 1, 0, 0.0f)); // Green. + color.push_back(Color(1, 1, 0, 0.5f)); // Yellow. + color.push_back(Color(1, 0, 0, 1.0f)); // Red. +} + void ColorGradient::getColorAtValue(const float value, float& red, float& green, float& blue) { if (color.size() == 0) return; diff --git a/cpp/src/render/utils/color/color_gradient.h b/cpp/src/render/utils/color/color_gradient.h index fdc4bdea0..7c38810ff 100644 --- a/cpp/src/render/utils/color/color_gradient.h +++ b/cpp/src/render/utils/color/color_gradient.h @@ -32,6 +32,7 @@ class ColorGradient { ColorGradient() { createDefaultHeatMapGradient(); } void createDefaultHeatMapGradient(); + void createSquareMapGradient(std::vector color); void getColorAtValue(const float value, float& red, float& green, float& blue); }; diff --git a/cpp/src/render/utils/render_utils.cpp b/cpp/src/render/utils/render_utils.cpp index 695b0109f..fe22d425e 100644 --- a/cpp/src/render/utils/render_utils.cpp +++ b/cpp/src/render/utils/render_utils.cpp @@ -104,5 +104,25 @@ std::vector> GeometryExport( return arrays; } +void pointXY_from_wkt_with_transform(const std::string& wkt, double& x, double& y, + void* poCT) { + OGRGeometry* res_geo = nullptr; + CHECK_GDAL(OGRGeometryFactory::createFromWkt(wkt.c_str(), nullptr, &res_geo)); + CHECK_GDAL(OGR_G_Transform(res_geo, (OGRCoordinateTransformation*)poCT)); + auto rst_pointer = reinterpret_cast(res_geo); + x = rst_pointer->getX(); + y = rst_pointer->getY(); + OGRGeometryFactory::destroyGeometry(res_geo); +} + +void pointXY_from_wkt(const std::string& wkt, double& x, double& y) { + OGRGeometry* res_geo = nullptr; + CHECK_GDAL(OGRGeometryFactory::createFromWkt(wkt.c_str(), nullptr, &res_geo)); + auto rst_pointer = reinterpret_cast(res_geo); + x = rst_pointer->getX(); + y = rst_pointer->getY(); + OGRGeometryFactory::destroyGeometry(res_geo); +} + } // namespace render } // namespace arctern diff --git a/cpp/src/render/utils/render_utils.h b/cpp/src/render/utils/render_utils.h index 8e4669cbc..0a33963c2 100644 --- a/cpp/src/render/utils/render_utils.h +++ b/cpp/src/render/utils/render_utils.h @@ -22,6 +22,7 @@ #include #include "arrow/render_api.h" +#include "utils/check_status.h" namespace arctern { namespace render { @@ -58,5 +59,10 @@ std::vector WeightExtraction(const std::vector> return res; } +void pointXY_from_wkt_with_transform(const std::string& wkt, double& x, double& y, + void* poCT); + +void pointXY_from_wkt(const std::string& wkt, double& x, double& y); + } // namespace render } // namespace arctern diff --git a/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp new file mode 100644 index 000000000..3137db0b1 --- /dev/null +++ b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "render/utils/vega/vega_fishnet_map/vega_fishnet_map.h" + +namespace arctern { +namespace render { + +VegaFishNetMap::VegaFishNetMap(const std::string& json) { Parse(json); } + +void VegaFishNetMap::Parse(const std::string& json) { + rapidjson::Document document; + document.Parse(json.c_str()); + + if (document.Parse(json.c_str()).HasParseError()) { + is_valid_ = false; + std::string err_msg = "json format error"; + throw std::runtime_error(err_msg); + } + + if (!JsonLabelCheck(document, "width") || !JsonLabelCheck(document, "height") || + !JsonNullCheck(document["width"]) || !JsonNullCheck(document["height"]) || + !JsonTypeCheck(document["width"], rapidjson::Type::kNumberType) || + !JsonTypeCheck(document["height"], rapidjson::Type::kNumberType)) { + return; + } + window_params_.mutable_width() = document["width"].GetInt(); + window_params_.mutable_height() = document["height"].GetInt(); + + if (!JsonLabelCheck(document, "marks") || + !JsonTypeCheck(document["marks"], rapidjson::Type::kArrayType) || + !JsonSizeCheck(document["marks"], "marks", 1) || + !JsonLabelCheck(document["marks"][0], "encode") || + !JsonLabelCheck(document["marks"][0]["encode"], "enter")) { + return; + } + rapidjson::Value mark_enter; + mark_enter = document["marks"][0]["encode"]["enter"]; + + // parse color gradient + if (!JsonLabelCheck(mark_enter, "color_gradient") || + !JsonLabelCheck(mark_enter["color_gradient"], "value") || + !JsonTypeCheck(mark_enter["color_gradient"]["value"], + rapidjson::Type::kArrayType)) { + return; + } + + auto color_gradient_size = mark_enter["color_gradient"]["value"].Size(); + if (color_gradient_size == 1 && JsonTypeCheck(mark_enter["color_gradient"]["value"][0], + rapidjson::Type::kStringType)) { + auto color = + ColorParser(mark_enter["color_gradient"]["value"][0].GetString()).color(); + color.a = mark_enter["opacity"]["value"].GetDouble(); + color_gradient_.emplace_back(color); + } else if (color_gradient_size == 2 && + JsonTypeCheck(mark_enter["color_gradient"]["value"][0], + rapidjson::Type::kStringType) && + JsonTypeCheck(mark_enter["color_gradient"]["value"][1], + rapidjson::Type::kStringType)) { + auto color_start = + ColorParser(mark_enter["color_gradient"]["value"][0].GetString()).color(); + auto color_end = + ColorParser(mark_enter["color_gradient"]["value"][1].GetString()).color(); + auto opacity = mark_enter["opacity"]["value"].GetDouble(); + color_start.a = opacity; + color_end.a = opacity; + color_gradient_.emplace_back(color_start); + color_gradient_.emplace_back(color_end); + } else { + std::string err_msg = "unsupported color gradient"; + throw std::runtime_error(err_msg); + } + + if (!JsonLabelCheck(mark_enter, "cell_size") || + !JsonLabelCheck(mark_enter["cell_size"], "value") || + !JsonTypeCheck(mark_enter["cell_size"]["value"], rapidjson::Type::kNumberType)) { + return; + } + cell_size_ = mark_enter["cell_size"]["value"].GetInt(); + + if (!JsonLabelCheck(mark_enter, "cell_spacing") || + !JsonLabelCheck(mark_enter["cell_spacing"], "value") || + !JsonTypeCheck(mark_enter["cell_spacing"]["value"], rapidjson::Type::kNumberType)) { + return; + } + cell_spacing_ = mark_enter["cell_spacing"]["value"].GetInt(); + + // parse opacity + if (!JsonLabelCheck(mark_enter, "opacity") || + !JsonLabelCheck(mark_enter["opacity"], "value") || + !JsonTypeCheck(mark_enter["opacity"]["value"], rapidjson::Type::kNumberType)) { + return; + } + opacity_ = mark_enter["opacity"]["value"].GetDouble(); +} + +} // namespace render +} // namespace arctern diff --git a/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.h b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.h new file mode 100644 index 000000000..4a59bf373 --- /dev/null +++ b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include + +#include "render/utils/color/color.h" +#include "render/utils/vega/vega.h" + +namespace arctern { +namespace render { + +class VegaFishNetMap : public Vega { + public: + VegaFishNetMap() = default; + + explicit VegaFishNetMap(const std::string& json); + + // TODO: add Build() api to build a vega json string. + // std::string Build() final; + + int cell_size() { return cell_size_; } + + int cell_spacing() { return cell_spacing_; } + + const double& opacity() const { return opacity_; } + + const std::vector& color_gradient() { return color_gradient_; } + + private: + // vega json to vega struct + void Parse(const std::string& json) final; + + private: + int cell_size_; + int cell_spacing_; + std::vector color_gradient_; + double opacity_; +}; + +} // namespace render +} // namespace arctern diff --git a/cpp/unittest/render/CMakeLists.txt b/cpp/unittest/render/CMakeLists.txt index 8d5eed6fb..d34919835 100644 --- a/cpp/unittest/render/CMakeLists.txt +++ b/cpp/unittest/render/CMakeLists.txt @@ -20,6 +20,8 @@ set(render_tests_src coordinate_projection_test.cpp weighted_pointmap_test.cpp iconviz_test.cpp + render_builder_api_test.cpp + fishnetmap_test.cpp ) add_executable(render_tests ${render_tests_src}) diff --git a/cpp/unittest/render/fishnetmap_test.cpp b/cpp/unittest/render/fishnetmap_test.cpp new file mode 100644 index 000000000..f2ca1a9ab --- /dev/null +++ b/cpp/unittest/render/fishnetmap_test.cpp @@ -0,0 +1,740 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "arrow/render_api.h" + +TEST(FISHNETMAP_TEST, INT8) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::Int8Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, INT16) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::Int16Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, INT32) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::Int32Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, INT64) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::Int64Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, UINT8) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::UInt8Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, UINT16) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::UInt16Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, UINT32) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::UInt32Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, UINT64) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::UInt64Builder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, FLOAT) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::FloatBuilder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} + +TEST(FISHNETMAP_TEST, DOUBLE) { + // param1: wkt string + std::string wkt1 = "POINT (10 10)"; + std::string wkt2 = "POINT (30 30)"; + std::string wkt3 = "POINT (50 50)"; + std::string wkt4 = "POINT (70 70)"; + std::string wkt5 = "POINT (90 90)"; + arrow::StringBuilder string_builder; + auto status = string_builder.Append(wkt1); + status = string_builder.Append(wkt2); + status = string_builder.Append(wkt3); + status = string_builder.Append(wkt4); + status = string_builder.Append(wkt5); + + std::shared_ptr string_array; + status = string_builder.Finish(&string_array); + + // param2: color + arrow::DoubleBuilder color_builder; + status = color_builder.Append(1); + status = color_builder.Append(2); + status = color_builder.Append(3); + status = color_builder.Append(4); + status = color_builder.Append(5); + + std::shared_ptr c_array; + status = color_builder.Finish(&c_array); + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 1900,\n" + " \"height\": 1410,\n" + " \"description\": \"fishnet_map_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"building\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": {\"value\": " + "[-73.984092,40.753893,-73.977588,40.756342]},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"cell_size\": {\"value\": 4.0},\n" + " \"cell_spacing\": {\"value\": 1.0},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"aggregation_type\": {\"value\": \"sum\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + auto wkb = arctern::render::WktToWkb(string_array); + + std::vector> point_vec{wkb}; + std::vector> color_vec{c_array}; + + arctern::render::fishnet_map(point_vec, color_vec, vega); +} diff --git a/cpp/unittest/render/heatmap_test.cpp b/cpp/unittest/render/heatmap_test.cpp index 1f1a80104..2a604a5a7 100644 --- a/cpp/unittest/render/heatmap_test.cpp +++ b/cpp/unittest/render/heatmap_test.cpp @@ -17,856 +17,6 @@ #include "arrow/render_api.h" -TEST(HEATMAP_TEST, RAW_POINT_INT8_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (int8_t*)malloc(5 * sizeof(int8_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(int8_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::int8(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_INT16_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (int16_t*)malloc(5 * sizeof(int16_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(int16_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::int16(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_INT32_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(data_type, 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (int32_t*)malloc(5 * sizeof(int32_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(int32_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::int32(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_INT64_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (int64_t*)malloc(5 * sizeof(int64_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(int64_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::int64(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_UINT8_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (uint8_t*)malloc(5 * sizeof(uint8_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(uint8_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::uint8(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_UINT16_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (uint16_t*)malloc(5 * sizeof(uint16_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(uint16_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::uint16(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_UINT32_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(uint32_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_UINT64_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (uint64_t*)malloc(5 * sizeof(uint64_t)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(uint64_t)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::uint64(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_FLOAT_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (float*)malloc(5 * sizeof(float)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(float)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::float32(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - -TEST(HEATMAP_TEST, RAW_POINT_DOUBLE_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - auto bit_map3 = new uint8_t{0xff}; - - auto buff_data3 = (double*)malloc(5 * sizeof(double)); - for (int i = 0; i < 5; ++i) { - buff_data3[i] = i + 50; - } - auto buffer30 = std::make_shared(bit_map3, 1 * sizeof(uint8_t)); - auto buffer31 = - std::make_shared((uint8_t*)buff_data3, 5 * sizeof(double)); - std::vector> buffers3; - buffers3.emplace_back(buffer30); - buffers3.emplace_back(buffer31); - auto array_data3 = arrow::ArrayData::Make(arrow::float64(), 5, buffers3); - auto array3 = arrow::MakeArray(array_data3); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"map_zoom_level\": {\"value\": 10}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::heat_map(array1, array2, array3, vega); -} - // TEST(HEATMAP_TEST, RAW_POINT_INVALID_DATA_TYPE_TEST) { // // param1: x // arrow::UInt32Builder x_builder; diff --git a/cpp/unittest/render/iconviz_test.cpp b/cpp/unittest/render/iconviz_test.cpp index f367a1c08..f23cc7696 100644 --- a/cpp/unittest/render/iconviz_test.cpp +++ b/cpp/unittest/render/iconviz_test.cpp @@ -17,71 +17,6 @@ #include "arrow/render_api.h" -TEST(ICON_VIZ_TEST, RAW_POINT_TEST) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(0); - status = x_builder.Append(100); - status = x_builder.Append(200); - status = x_builder.Append(300); - status = x_builder.Append(400); - status = x_builder.Append(500); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(0); - status = y_builder.Append(100); - status = y_builder.Append(200); - status = y_builder.Append(300); - status = y_builder.Append(400); - status = y_builder.Append(500); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - std::string path = __FILE__; - path.resize(path.size() - 16); - std::string icon_path = path + "images/taxi.png"; - - // param2: vega - const std::string vega = - "{\n" - " \"width\": 800,\n" - " \"height\": 600,\n" - " \"description\": \"icon\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"icon\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"c0\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"icon_path\": {\"value\": \"" + - icon_path + - "\"},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::icon_viz(x_array, y_array, vega); -} - TEST(ICON_VIZ_TEST, WKT_TEST) { // param1: wkt string std::string wkt1 = "POINT (100 100)"; @@ -103,7 +38,7 @@ TEST(ICON_VIZ_TEST, WKT_TEST) { path.resize(path.size() - 16); std::string icon_path = path + "images/taxi.png"; - // param2: vega + // param2: conf const std::string vega = "{\n" " \"width\": 800,\n" diff --git a/cpp/unittest/render/pointmap_test.cpp b/cpp/unittest/render/pointmap_test.cpp index 18258cdf5..dab6da6a6 100644 --- a/cpp/unittest/render/pointmap_test.cpp +++ b/cpp/unittest/render/pointmap_test.cpp @@ -17,151 +17,97 @@ #include "arrow/render_api.h" -TEST(POINTMAP_TEST, RAW_POINT_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"point_color\": {\"value\": \"#ff0000\"},\n" - " \"point_size\": {\"value\": 30},\n" - " \"opacity\": {\"value\": 0.5}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::point_map(array1, array2, vega); -} - -TEST(POINTMAP_TEST, INVALID_COLOR_TEST) { - auto bit_map = new uint8_t{0xff}; - - auto data_type = arrow::uint32(); - - auto buff_data1 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data1[i] = i + 50; - } - auto buffer0 = std::make_shared(bit_map, 1 * sizeof(uint8_t)); - auto buffer1 = - std::make_shared((uint8_t*)buff_data1, 5 * sizeof(uint32_t)); - std::vector> buffers1; - buffers1.emplace_back(buffer0); - buffers1.emplace_back(buffer1); - auto array_data1 = arrow::ArrayData::Make(data_type, 5, buffers1); - auto array1 = arrow::MakeArray(array_data1); - - auto bit_map2 = new uint8_t{0xff}; - - auto buff_data2 = (uint32_t*)malloc(5 * sizeof(uint32_t)); - for (int i = 0; i < 5; ++i) { - buff_data2[i] = i + 50; - } - auto buffer20 = std::make_shared(bit_map2, 1 * sizeof(uint8_t)); - auto buffer21 = - std::make_shared((uint8_t*)buff_data2, 5 * sizeof(uint32_t)); - std::vector> buffers2; - buffers2.emplace_back(buffer20); - buffers2.emplace_back(buffer21); - auto array_data2 = arrow::ArrayData::Make(arrow::uint32(), 5, buffers2); - auto array2 = arrow::MakeArray(array_data2); - - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"circle_2d\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"data\",\n" - " \"url\": \"data/data.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"point_color\": {\"value\": \"#xxxxxx\"},\n" - " \"point_size\": {\"value\": 30},\n" - " \"opacity\": {\"value\": 0.5}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::point_map(array1, array2, vega); -} +// TEST(POINTMAP_TEST, RAW_POINT_TEST) { +// // param1: x, y +// std::vector x{50, 51, 52, 53, 54}; +// std::vector y{50, 51, 52, 53, 54}; +// +// // param2: conf +// const std::string vega = +// "{\n" +// " \"width\": 300,\n" +// " \"height\": 200,\n" +// " \"description\": \"circle_2d\",\n" +// " \"data\": [\n" +// " {\n" +// " \"name\": \"data\",\n" +// " \"url\": \"data/data.csv\"\n" +// " }\n" +// " ],\n" +// " \"scales\": [\n" +// " {\n" +// " \"name\": \"x\",\n" +// " \"type\": \"linear\",\n" +// " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" +// " },\n" +// " {\n" +// " \"name\": \"y\",\n" +// " \"type\": \"linear\",\n" +// " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" +// " }\n" +// " ],\n" +// " \"marks\": [\n" +// " {\n" +// " \"encode\": {\n" +// " \"enter\": {\n" +// " \"shape\": {\"value\": \"circle\"},\n" +// " \"point_color\": {\"value\": \"#ff0000\"},\n" +// " \"point_size\": {\"value\": 30},\n" +// " \"opacity\": {\"value\": 0.5}\n" +// " }\n" +// " }\n" +// " }\n" +// " ]\n" +// "}"; +// +// arctern::render::pointmap(x.data(), y.data(), 5, vega); +//} +// +// TEST(POINTMAP_TEST, INVALID_COLOR_TEST) { +// // param1: x, y +// std::vector x{50, 51, 52, 53, 54}; +// std::vector y{50, 51, 52, 53, 54}; +// +// // param2: conf +// const std::string vega = +// "{\n" +// " \"width\": 300,\n" +// " \"height\": 200,\n" +// " \"description\": \"circle_2d\",\n" +// " \"data\": [\n" +// " {\n" +// " \"name\": \"data\",\n" +// " \"url\": \"data/data.csv\"\n" +// " }\n" +// " ],\n" +// " \"scales\": [\n" +// " {\n" +// " \"name\": \"x\",\n" +// " \"type\": \"linear\",\n" +// " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" +// " },\n" +// " {\n" +// " \"name\": \"y\",\n" +// " \"type\": \"linear\",\n" +// " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" +// " }\n" +// " ],\n" +// " \"marks\": [\n" +// " {\n" +// " \"encode\": {\n" +// " \"enter\": {\n" +// " \"shape\": {\"value\": \"circle\"},\n" +// " \"point_color\": {\"value\": \"#xxxxxx\"},\n" +// " \"point_size\": {\"value\": 30},\n" +// " \"opacity\": {\"value\": 0.5}\n" +// " }\n" +// " }\n" +// " }\n" +// " ]\n" +// "}"; +// +// arctern::render::pointmap(x.data(), y.data(), 5, vega); +//} // TEST(POINTMAP_TEST, RAW_POINT_INVALID_JSON_TEST) { // auto bit_map = new uint8_t{0xff}; diff --git a/cpp/unittest/render/render_builder_api_test.cpp b/cpp/unittest/render/render_builder_api_test.cpp new file mode 100644 index 000000000..4bc6aa657 --- /dev/null +++ b/cpp/unittest/render/render_builder_api_test.cpp @@ -0,0 +1,2389 @@ +/* + * Copyright (C) 2019-2020 Zilliz. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "render/render_builder.h" + +TEST(POINTMAP_TEST, RAW_POINT_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"point_color\": {\"value\": \"#ff0000\"},\n" + " \"point_size\": {\"value\": 30},\n" + " \"opacity\": {\"value\": 0.5}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::pointmap(x.data(), y.data(), 5, vega); +} + +TEST(POINTMAP_TEST, INVALID_COLOR_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"point_color\": {\"value\": \"#xxxxxx\"},\n" + " \"point_size\": {\"value\": 30},\n" + " \"opacity\": {\"value\": 0.5}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::pointmap(x.data(), y.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, SINGLE_COLOR_SINGLE_POINTSIZE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#FFD700\"]},\n" + " \"color_bound\": {\"value\": [-1, -1]},\n" + " \"size_bound\": {\"value\": [5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, MULTIPLE_COLOR_SINGLE_POINTSIZE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2, 5]},\n" + " \"size_bound\": {\"value\": [8]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, SINGLE_COLOR_MULTIPLE_POINTSIZE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: point size + std::vector c{6, 8, 10, 12, 14}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#FFD700\"]},\n" + " \"color_bound\": {\"value\": [-1, -1]},\n" + " \"size_bound\": {\"value\": [0, 10]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, MULTIPLE_COLOR_MULTIPLE_POINTSIZE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, INT8) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, INT16) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, INT32) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, INT64) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, UINT8) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, UINT16) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, UINT32) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, UINT64) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, FLOAT) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, DOUBLE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT8) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT16) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT32) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT64) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT8) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT16) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT32) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT64) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, FLOAT) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, DOUBLE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, BLUE_TO_RED) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, SKYBLUE_TO_RED) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#B4E7F5\", \"#FFFFFF\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, PURPLE_TO_YELLOW) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#FF00FF\", \"#FFFF00\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, RED_TRANSPARENCY) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#FF0000\", \"#FF0000\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, BLUE_TRANSPARENCY) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#0000FF\", \"#0000FF\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, BLUE_GREEN_YELLOW) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#115F9A\", \"#D0F401\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, WHITE_BLUE) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#E2E2E2\", \"#115F9A\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, BLUE_WHITE_RED) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#1984C5\", \"#C23728\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(POINTMAP_RAW_POINT_TEST, GREEN_YELLOW_RED) { + // param1: x, y + std::vector x{10, 40, 70, 100, 130}; + std::vector y{10, 40, 70, 100, 130}; + + // param2: color + std::vector c{1, 2, 3, 4, 5}; + + // param3: size + std::vector s{6, 8, 10, 12, 14}; + + // param4: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"weighted_pointmap\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"shape\": {\"value\": \"circle\"},\n" + " \"color_gradient\": {\"value\": [\"#4D904F\", \"#C23728\"]},\n" + " \"color_bound\": {\"value\": [2.5, 5]},\n" + " \"size_bound\": {\"value\": [2.5, 5]},\n" + " \"opacity\": {\"value\": 1.0},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::weighted_pointmap(x.data(), y.data(), c.data(), s.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_INT8_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_INT16_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_INT32_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_INT64_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_UINT8_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_UINT16_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_UINT32_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_UINT64_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_FLOAT_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(HEATMAP_TEST, RAW_POINT_DOUBLE_TEST) { + // param1: x, y + std::vector x{50, 51, 52, 53, 54}; + std::vector y{50, 51, 52, 53, 54}; + + // param2: count + std::vector c{50, 51, 52, 53, 54}; + + // param3: conf + const std::string vega = + "{\n" + " \"width\": 300,\n" + " \"height\": 200,\n" + " \"description\": \"circle_2d\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"data\",\n" + " \"url\": \"data/data.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"x\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"map_zoom_level\": {\"value\": 10}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::heatmap(x.data(), y.data(), c.data(), 5, vega); +} + +TEST(ICON_VIZ_TEST, RAW_POINT_TEST) { + // param1: x, y + std::vector x{100, 200, 300, 400, 500}; + std::vector y{100, 200, 300, 400, 500}; + + std::string path = __FILE__; + path.resize(path.size() - 27); + std::string icon_path = path + "images/taxi.png"; + + // param2: conf + const std::string vega = + "{\n" + " \"width\": 800,\n" + " \"height\": 600,\n" + " \"description\": \"icon\",\n" + " \"data\": [\n" + " {\n" + " \"name\": \"nyc_taxi\",\n" + " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" + " }\n" + " ],\n" + " \"scales\": [\n" + " {\n" + " \"name\": \"icon\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"c0\"}\n" + " }\n" + " ],\n" + " \"marks\": [\n" + " {\n" + " \"encode\": {\n" + " \"enter\": {\n" + " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" + " \"icon_path\": {\"value\": \"" + + icon_path + + "\"},\n" + " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"; + + arctern::render::iconviz(x.data(), y.data(), 5, vega); +} diff --git a/cpp/unittest/render/weighted_pointmap_test.cpp b/cpp/unittest/render/weighted_pointmap_test.cpp index 4a9dbeb85..5e22ea05c 100644 --- a/cpp/unittest/render/weighted_pointmap_test.cpp +++ b/cpp/unittest/render/weighted_pointmap_test.cpp @@ -19,2756 +19,6 @@ #include "arrow/render_api.h" -// TEST(POINTMAP_RAW_POINT_TEST, SINGLE_COLOR_SINGLE_POINTSIZE) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#FFD700\"]},\n" -// " \"color_bound\": {\"value\": [-1, -1]},\n" -// " \"size_bound\": {\"value\": [5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST, MULTIPLE_COLOR_SINGLE_POINTSIZE) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: count -// arrow::UInt32Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2, 5]},\n" -// " \"size_bound\": {\"value\": [8]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST, SINGLE_COLOR_MULTIPLE_POINTSIZE) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: point_size -// arrow::UInt32Builder ps_builder; -// status = ps_builder.Append(2); -// status = ps_builder.Append(4); -// status = ps_builder.Append(6); -// status = ps_builder.Append(8); -// status = ps_builder.Append(10); -// -// std::shared_ptr s_array; -// status = ps_builder.Finish(&s_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#FFD700\"]},\n" -// " \"color_bound\": {\"value\": [-1, -1]},\n" -// " \"size_bound\": {\"value\": [0, 10]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, s_array, vega); -//} - -TEST(POINTMAP_RAW_POINT_TEST, MULTIPLE_COLOR_MULTIPLE_POINTSIZE) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::UInt32Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::UInt32Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, INT8) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::Int8Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::Int8Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, INT16) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::Int16Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::Int16Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, INT32) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::Int32Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::Int32Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, INT64) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::Int64Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::Int64Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, UINT8) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::UInt8Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::UInt8Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, UINT16) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::UInt16Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::UInt16Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, UINT32) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::UInt32Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::UInt32Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, UINT64) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::UInt64Builder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::UInt64Builder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, FLOAT) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::FloatBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::FloatBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, DOUBLE) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT8) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::Int8Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT16) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::Int16Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT32) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::Int32Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, INT64) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::Int64Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT8) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::UInt8Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT16) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::UInt16Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT32) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::UInt32Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, UINT64) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::UInt64Builder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, FLOAT) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::FloatBuilder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} -// -// TEST(POINTMAP_RAW_POINT_TEST_MULTIPLE_COLOR, DOUBLE) { -// // param1: x, y -// arrow::UInt32Builder x_builder; -// auto status = x_builder.Append(10); -// status = x_builder.Append(40); -// status = x_builder.Append(70); -// status = x_builder.Append(100); -// status = x_builder.Append(130); -// -// std::shared_ptr x_array; -// status = x_builder.Finish(&x_array); -// -// arrow::UInt32Builder y_builder; -// status = y_builder.Append(10); -// status = y_builder.Append(40); -// status = y_builder.Append(70); -// status = y_builder.Append(100); -// status = y_builder.Append(130); -// -// std::shared_ptr y_array; -// status = y_builder.Finish(&y_array); -// -// // param2: color -// arrow::DoubleBuilder color_builder; -// status = color_builder.Append(1); -// status = color_builder.Append(2); -// status = color_builder.Append(3); -// status = color_builder.Append(4); -// status = color_builder.Append(5); -// -// std::shared_ptr c_array; -// status = color_builder.Finish(&c_array); -// -// // param3: conf -// const std::string vega = -// "{\n" -// " \"width\": 300,\n" -// " \"height\": 200,\n" -// " \"description\": \"weighted_pointmap\",\n" -// " \"data\": [\n" -// " {\n" -// " \"name\": \"nyc_taxi\",\n" -// " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" -// " }\n" -// " ],\n" -// " \"scales\": [\n" -// " {\n" -// " \"name\": \"x\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" -// " },\n" -// " {\n" -// " \"name\": \"y\",\n" -// " \"type\": \"linear\",\n" -// " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" -// " }\n" -// " ],\n" -// " \"marks\": [\n" -// " {\n" -// " \"encode\": {\n" -// " \"enter\": {\n" -// " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" -// " \"shape\": {\"value\": \"circle\"},\n" -// " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" -// " \"color_bound\": {\"value\": [2.5, 5]},\n" -// " \"size_bound\": {\"value\": [2.5]},\n" -// " \"opacity\": {\"value\": 1.0},\n" -// " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" -// " }\n" -// " }\n" -// " }\n" -// " ]\n" -// "}"; -// -// arctern::render::weighted_point_map(x_array, y_array, c_array, vega); -//} - -TEST(POINTMAP_RAW_POINT_TEST, BLUE_TO_RED) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, SKYBLUE_TO_RED) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#B4E7F5\", \"#FFFFFF\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, PURPLE_TO_YELLOW) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#FF00FF\", \"#FFFF00\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, RED_TRANSPARENCY) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#FF0000\", \"#FF0000\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, BLUE_TRANSPARENCY) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#0000FF\", \"#0000FF\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, BLUE_GREEN_YELLOW) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#115F9A\", \"#D0F401\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, WHITE_BLUE) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#E2E2E2\", \"#115F9A\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, BLUE_WHITE_RED) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#1984C5\", \"#C23728\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - -TEST(POINTMAP_RAW_POINT_TEST, GREEN_YELLOW_RED) { - // param1: x, y - arrow::UInt32Builder x_builder; - auto status = x_builder.Append(10); - status = x_builder.Append(40); - status = x_builder.Append(70); - status = x_builder.Append(100); - status = x_builder.Append(130); - - std::shared_ptr x_array; - status = x_builder.Finish(&x_array); - - arrow::UInt32Builder y_builder; - status = y_builder.Append(10); - status = y_builder.Append(40); - status = y_builder.Append(70); - status = y_builder.Append(100); - status = y_builder.Append(130); - - std::shared_ptr y_array; - status = y_builder.Finish(&y_array); - - // param2: color - arrow::DoubleBuilder color_builder; - status = color_builder.Append(1); - status = color_builder.Append(2); - status = color_builder.Append(3); - status = color_builder.Append(4); - status = color_builder.Append(5); - - std::shared_ptr c_array; - status = color_builder.Finish(&c_array); - - // param3: point size - arrow::DoubleBuilder point_size_builder; - status = point_size_builder.Append(2); - status = point_size_builder.Append(4); - status = point_size_builder.Append(6); - status = point_size_builder.Append(8); - status = point_size_builder.Append(10); - - std::shared_ptr s_array; - status = point_size_builder.Finish(&s_array); - - // param4: conf - const std::string vega = - "{\n" - " \"width\": 300,\n" - " \"height\": 200,\n" - " \"description\": \"weighted_pointmap\",\n" - " \"data\": [\n" - " {\n" - " \"name\": \"nyc_taxi\",\n" - " \"url\": \"data/nyc_taxi_0_5m.csv\"\n" - " }\n" - " ],\n" - " \"scales\": [\n" - " {\n" - " \"name\": \"x\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"longitude_pickup\"}\n" - " },\n" - " {\n" - " \"name\": \"y\",\n" - " \"type\": \"linear\",\n" - " \"domain\": {\"data\": \"nyc_taxi\", \"field\": \"latitude_pickup\"}\n" - " }\n" - " ],\n" - " \"marks\": [\n" - " {\n" - " \"encode\": {\n" - " \"enter\": {\n" - " \"bounding_box\": [-73.998427, 40.730309, -73.954348, 40.780816],\n" - " \"shape\": {\"value\": \"circle\"},\n" - " \"color_gradient\": {\"value\": [\"#4D904F\", \"#C23728\"]},\n" - " \"color_bound\": {\"value\": [2.5, 5]},\n" - " \"size_bound\": {\"value\": [2.5, 5]},\n" - " \"opacity\": {\"value\": 1.0},\n" - " \"coordinate_system\": {\"value\": \"EPSG:3857\"}\n" - " }\n" - " }\n" - " }\n" - " ]\n" - "}"; - - arctern::render::weighted_point_map(x_array, y_array, c_array, s_array, vega); -} - TEST(POINTMAP_WKT_TEST, SINGLE_COLOR_SINGLE_POINTSIZE) { // param1: wkt string std::string wkt1 = "POINT (10 10)"; diff --git a/python/arctern/_wrapper_func.py b/python/arctern/_wrapper_func.py index 0170bce32..2f627f8ff 100644 --- a/python/arctern/_wrapper_func.py +++ b/python/arctern/_wrapper_func.py @@ -53,6 +53,7 @@ "heat_map_layer", "choropleth_map_layer", "icon_viz_layer", + "fishnet_map_layer", "projection", "transform_and_projection", "wkt2wkb", @@ -1201,21 +1202,10 @@ def projection(geos, bottom_right, top_left, height, width): bounding_box_max = bytes(bottom_right, encoding="utf8") bounding_box_min = bytes(top_left, encoding="utf8") - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) geos = arctern_core_.projection(geos_rs, bounding_box_max, bounding_box_min, height, width) - pd_rs = geos[0].to_pandas() - if len(geos) >= 2: - for i in range(1, len(geos)): - pd_rs.append(geos[i].to_pandas()) - - return pd_rs + return _to_pandas_series(geos) def transform_and_projection(geos, src_rs, dst_rs, bottom_right, top_left, height, width): @@ -1228,21 +1218,10 @@ def transform_and_projection(geos, src_rs, dst_rs, bottom_right, top_left, heigh bounding_box_max = bytes(bottom_right, encoding="utf8") bounding_box_min = bytes(top_left, encoding="utf8") - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) geos = arctern_core_.transform_and_projection(geos_rs, src, dst, bounding_box_max, bounding_box_min, height, width) - pd_rs = geos[0].to_pandas() - if len(geos) >= 2: - for i in range(1, len(geos)): - pd_rs.append(geos[i].to_pandas()) - - return pd_rs + return _to_pandas_series(geos) def wkt2wkb(arr_wkt): @@ -1264,13 +1243,7 @@ def point_map_layer(vega, points, transform=True): geos = pa.array(points, type='binary') # transform and projection handler - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) if transform: bounding_box = vega.bounding_box() @@ -1308,13 +1281,7 @@ def weighted_point_map_layer(vega, points, transform=True, **kwargs): geos = pa.array(points, type='binary') # transform and projection handler - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) if transform: bounding_box = vega.bounding_box() @@ -1338,7 +1305,6 @@ def weighted_point_map_layer(vega, points, transform=True, **kwargs): if color_weights is None and size_weights is None: rs = arctern_core_.weighted_point_map(vega_string, geos_rs) - elif color_weights is not None and size_weights is not None: if color_weights.dtypes == 'float64': arr_c = pa.array(color_weights, type='double') @@ -1348,44 +1314,22 @@ def weighted_point_map_layer(vega, points, transform=True, **kwargs): arr_s = pa.array(size_weights, type='double') else: arr_s = pa.array(size_weights, type='int64') - color_weights_rs = [] - size_weights_rs = [] - if isinstance(arr_c, pa.lib.ChunkedArray): - for chunk_idx in range(arr_c.num_chunks): - color_weights_rs.append(arr_c.chunk(chunk_idx)) - else: - color_weights_rs.append(arr_c) - if isinstance(arr_s, pa.lib.ChunkedArray): - for chunk_idx in range(arr_s.num_chunks): - size_weights_rs.append(arr_s.chunk(chunk_idx)) - else: - size_weights_rs.append(arr_s) + color_weights_rs = _to_arrow_array_list(arr_c) + size_weights_rs = _to_arrow_array_list(arr_s) rs = arctern_core_.weighted_color_size_point_map(vega_string, geos_rs, color_weights_rs, size_weights_rs) - elif color_weights is None and size_weights is not None: if size_weights.dtypes == 'float64': arr_s = pa.array(size_weights, type='double') else: arr_s = pa.array(size_weights, type='int64') - size_weights_rs = [] - if isinstance(arr_s, pa.lib.ChunkedArray): - for chunk_idx in range(arr_s.num_chunks): - size_weights_rs.append(arr_s.chunk(chunk_idx)) - else: - size_weights_rs.append(arr_s) + size_weights_rs = _to_arrow_array_list(arr_s) rs = arctern_core_.weighted_size_point_map(vega_string, geos_rs, size_weights_rs) - else: if color_weights.dtypes == 'float64': arr_c = pa.array(color_weights, type='double') else: arr_c = pa.array(color_weights, type='int64') - color_weights_rs = [] - if isinstance(arr_c, pa.lib.ChunkedArray): - for chunk_idx in range(arr_c.num_chunks): - color_weights_rs.append(arr_c.chunk(chunk_idx)) - else: - color_weights_rs.append(arr_c) + color_weights_rs = _to_arrow_array_list(arr_c) rs = arctern_core_.weighted_color_point_map(vega_string, geos_rs, color_weights_rs) return base64.b64encode(rs.buffers()[1].to_pybytes()) @@ -1396,13 +1340,7 @@ def heat_map_layer(vega, points, weights, transform=True): geos = pa.array(points, type='binary') # transform and projection handler - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) if transform: bounding_box = vega.bounding_box() @@ -1430,12 +1368,7 @@ def heat_map_layer(vega, points, weights, transform=True): else: arr = pa.array(weights, type='int64') - weights_rs = [] - if isinstance(arr, pa.lib.ChunkedArray): - for chunk_idx in range(arr.num_chunks): - weights_rs.append(arr.chunk(chunk_idx)) - else: - weights_rs.append(arr) + weights_rs = _to_arrow_array_list(arr) vega_string = vega.build().encode('utf-8') rs = arctern_core_.heat_map(vega_string, geos_rs, weights_rs) @@ -1447,13 +1380,7 @@ def choropleth_map_layer(vega, region_boundaries, weights, transform=True): geos = pa.array(region_boundaries, type='binary') # transform and projection handler - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) if transform: bounding_box = vega.bounding_box() @@ -1479,16 +1406,11 @@ def choropleth_map_layer(vega, region_boundaries, weights, transform=True): # weights handler if weights.dtypes == 'float64': - arr_c = pa.array(weights, type='double') + arr = pa.array(weights, type='double') else: - arr_c = pa.array(weights, type='int64') + arr = pa.array(weights, type='int64') - weights_rs = [] - if isinstance(arr_c, pa.lib.ChunkedArray): - for chunk_idx in range(arr_c.num_chunks): - weights_rs.append(arr_c.chunk(chunk_idx)) - else: - weights_rs.append(arr_c) + weights_rs = _to_arrow_array_list(arr) rs = arctern_core_.choropleth_map(vega_string, geos_rs, weights_rs) return base64.b64encode(rs.buffers()[1].to_pybytes()) @@ -1499,13 +1421,7 @@ def icon_viz_layer(vega, points, transform=True): geos = pa.array(points, type='binary') # transform and projection handler - geos_rs = [] - # pylint: disable=c-extension-no-member - if isinstance(geos, pa.lib.ChunkedArray): - for chunk_idx in range(geos.num_chunks): - geos_rs.append(geos.chunk(chunk_idx)) - else: - geos_rs.append(geos) + geos_rs = _to_arrow_array_list(geos) if transform: bounding_box = vega.bounding_box() @@ -1531,3 +1447,45 @@ def icon_viz_layer(vega, points, transform=True): rs = arctern_core_.icon_viz(vega_string, geos_rs) return base64.b64encode(rs.buffers()[1].to_pybytes()) + +def fishnet_map_layer(vega, points, weights, transform=True): + import pyarrow as pa + geos = pa.array(points, type='binary') + + # transform and projection handler + geos_rs = _to_arrow_array_list(geos) + + if transform: + bounding_box = vega.bounding_box() + top_left = 'POINT (' + str(bounding_box[0]) + ' ' + str(bounding_box[3]) + ')' + bottom_right = 'POINT (' + str(bounding_box[2]) + ' ' + str(bounding_box[1]) + ')' + + # height = vega.height() + # width = vega.width() + cell_size = vega.cell_size() + height = int(vega.height() / cell_size) + width = int(vega.width() / cell_size) + coor = vega.coor() + + src = bytes(coor, encoding="utf8") + dst = bytes('EPSG:3857', encoding="utf8") + bounding_box_min = bytes(top_left, encoding="utf8") + bounding_box_max = bytes(bottom_right, encoding="utf8") + + # transform and projection + if coor != 'EPSG:3857': + geos_rs = arctern_core_.transform_and_projection(geos_rs, src, dst, bounding_box_max, bounding_box_min, height, width) + else: + geos_rs = arctern_core_.projection(geos_rs, bounding_box_max, bounding_box_min, height, width) + + # weights handler + if weights.dtypes == 'float64': + arr = pa.array(weights, type='double') + else: + arr = pa.array(weights, type='int64') + + weights_rs = _to_arrow_array_list(arr) + + vega_string = vega.build().encode('utf-8') + rs = arctern_core_.fishnet_map(vega_string, geos_rs, weights_rs) + return base64.b64encode(rs.buffers()[1].to_pybytes()) diff --git a/python/arctern/cython/arctern_core_.pyx b/python/arctern/cython/arctern_core_.pyx index ad6c9550f..c99601f8a 100644 --- a/python/arctern/cython/arctern_core_.pyx +++ b/python/arctern/cython/arctern_core_.pyx @@ -27,11 +27,8 @@ def projection(geos_list, bottom_right, top_left, height, width): arr = pyarrow_unwrap_array(geos) geos_vector.push_back(arr) cdef vector[shared_ptr[CArray]] output_geos - output_geos = arctern_core_pxd.projection(geos_vector, bottom_right, top_left, height, width) - res = [] - for i in range(output_geos.size()): - res.append(pyarrow_wrap_array(output_geos[i])) - return res + result = arctern_core_pxd.projection(geos_vector, bottom_right, top_left, height, width) + return [pyarrow_wrap_array(ptr) for ptr in result] def transform_and_projection(geos_list, src_rs, dst_rs, bottom_right, top_left, height, width): cdef vector[shared_ptr[CArray]] geos_vector @@ -39,11 +36,8 @@ def transform_and_projection(geos_list, src_rs, dst_rs, bottom_right, top_left, arr = pyarrow_unwrap_array(geos) geos_vector.push_back(arr) cdef vector[shared_ptr[CArray]] output_geos - output_geos = arctern_core_pxd.transform_and_projection(geos_vector, src_rs, dst_rs, bottom_right, top_left, height, width) - res = [] - for i in range(output_geos.size()): - res.append(pyarrow_wrap_array(output_geos[i])) - return res + result = arctern_core_pxd.transform_and_projection(geos_vector, src_rs, dst_rs, bottom_right, top_left, height, width) + return [pyarrow_wrap_array(ptr) for ptr in result] def wkt2wkb(arr_wkt): return pyarrow_wrap_array(arctern_core_pxd.WktToWkb(pyarrow_unwrap_array(arr_wkt))) @@ -134,7 +128,16 @@ def icon_viz(vega, points_list): return pyarrow_wrap_array(arctern_core_pxd.icon_viz(points_vector, vega)) - +def fishnet_map(vega, points_list, weights_list): + cdef vector[shared_ptr[CArray]] points_vector + cdef vector[shared_ptr[CArray]] weights_vector + for points in points_list: + arr = pyarrow_unwrap_array(points) + points_vector.push_back(arr) + for weights in weights_list: + arr = pyarrow_unwrap_array(weights) + weights_vector.push_back(arr) + return pyarrow_wrap_array(arctern_core_pxd.fishnet_map(points_vector, weights_vector, vega)) # gis api: def ST_Point(object arr_x,object arr_y): diff --git a/python/arctern/cython/arctern_core__.pxd b/python/arctern/cython/arctern_core__.pxd index e6e877443..cf0c65e66 100644 --- a/python/arctern/cython/arctern_core__.pxd +++ b/python/arctern/cython/arctern_core__.pxd @@ -16,7 +16,6 @@ from pyarrow.lib cimport (shared_ptr, CArray, int32_t) from libcpp.string cimport string from libcpp.vector cimport vector - cdef extern from "render.h" namespace "arctern::render": # func api: const vector[shared_ptr[CArray]] projection(const vector[shared_ptr[CArray]] &geos,const string &bottom_right,const string &top_left,const int &height,const int &width) except + @@ -31,8 +30,8 @@ cdef extern from "render.h" namespace "arctern::render": shared_ptr[CArray] weighted_point_map(const vector[shared_ptr[CArray]] &points_vector, const vector[shared_ptr[CArray]] &color_weights_vector, const vector[shared_ptr[CArray]] &size_weights_vector, const string &vega) except + shared_ptr[CArray] heat_map(const vector[shared_ptr[CArray]] &points_vector, const vector[shared_ptr[CArray]] &weights_vector, const string &vega) except + shared_ptr[CArray] choropleth_map(const vector[shared_ptr[CArray]] ®ion_boundaries_vector, const vector[shared_ptr[CArray]] &weights_vector, const string &vega) except + - shared_ptr[CArray] icon_viz(const vector[shared_ptr[CArray]] &points_vector, const string &conf) except + - + shared_ptr[CArray] icon_viz(const vector[shared_ptr[CArray]] &points_vector, const string &vega) except + + shared_ptr[CArray] fishnet_map(const vector[shared_ptr[CArray]] &points_vector, const vector[shared_ptr[CArray]] &weights_vector, const string &vega) except + cdef extern from "gis.h" namespace "arctern::gis": vector[shared_ptr[CArray]] ST_Point(const vector[shared_ptr[CArray]] &ptr_x, \ diff --git a/python/arctern/cython/render.h b/python/arctern/cython/render.h index 7fabcaada..5dfa472ff 100644 --- a/python/arctern/cython/render.h +++ b/python/arctern/cython/render.h @@ -65,10 +65,17 @@ std::shared_ptr weighted_point_map( std::shared_ptr choropleth_map( const std::vector>& region_boundaries, - const std::vector>& weights, const std::string& vega); + const std::vector>& weights, + const std::string& vega); std::shared_ptr icon_viz( - const std::vector>& points, const std::string& conf); + const std::vector>& points_vector, + const std::string& vega); + +std::shared_ptr fishnet_map( + const std::vector>& points_vector, + const std::vector>& weights_vector, + const std::string& vega); } // namespace render } // namespace arctern diff --git a/python/arctern/util/vega/_vega_functions.py b/python/arctern/util/vega/_vega_functions.py index c63b01d18..838fe2684 100644 --- a/python/arctern/util/vega/_vega_functions.py +++ b/python/arctern/util/vega/_vega_functions.py @@ -18,6 +18,7 @@ "vega_heatmap", "vega_choroplethmap", "vega_icon", + "vega_fishnetmap" ] from arctern.util.vega.pointmap.vega_pointmap import VegaPointMap @@ -25,6 +26,7 @@ from arctern.util.vega.heatmap.vega_heatmap import VegaHeatMap from arctern.util.vega.choroplethmap.vega_choroplethmap import VegaChoroplethMap from arctern.util.vega.icon.vega_icon import VegaIcon +from arctern.util.vega.fishnetmap.vega_fishnetmap import VegaFishNetMap def vega_pointmap(width, @@ -108,3 +110,24 @@ def vega_icon(width, height, bounding_box, icon_path, coordinate_system) + +def vega_fishnetmap(width, + height, + bounding_box, + color_gradient=None, + cell_size=4, + cell_spacing=1, + opacity=1.0, + coordinate_system="EPSG:3857", + aggregation_type="sum"): + if color_gradient is None: + color_gradient = ["#00FF00", "FF0000"] + return VegaFishNetMap(width, + height, + bounding_box, + color_gradient, + cell_size, + cell_spacing, + opacity, + coordinate_system, + aggregation_type) diff --git a/python/arctern/util/vega/fishnetmap/__init__.py b/python/arctern/util/vega/fishnetmap/__init__.py new file mode 100644 index 000000000..10254c9e9 --- /dev/null +++ b/python/arctern/util/vega/fishnetmap/__init__.py @@ -0,0 +1,13 @@ +# Copyright (C) 2019-2020 Zilliz. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py b/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py new file mode 100644 index 000000000..39245eaa9 --- /dev/null +++ b/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py @@ -0,0 +1,131 @@ +# Copyright (C) 2019-2020 Zilliz. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from arctern.util.vega.vega_node import (Width, Height, Description, Data, + Scales, RootMarks, Root) + + +class Marks(RootMarks): + """ + Top-Level Vega Specification Property: Marks + """ + + class Encode: + class Value: + def __init__(self, v: int or float or str): + self.v = v + + def to_dict(self): + dic = { + "value": self.v + } + return dic + + def __init__(self, bounding_box: Value, color_gradient: Value, + cell_size: Value, cell_spacing: Value, opacity: Value, coordinate_system: Value, aggregation_type: Value): + if not (isinstance(bounding_box.v, list) + and isinstance(color_gradient.v, list) + and isinstance(cell_size.v, int) + and isinstance(cell_spacing.v, int) + and isinstance(opacity.v, float) + and isinstance(coordinate_system.v, str) + and isinstance(aggregation_type.v, str)): + # TODO error log here + assert 0, "illegal" + self._bounding_box = bounding_box + self._color_gradient = color_gradient + self._cell_size = cell_size + self._cell_spacing = cell_spacing + self._opacity = opacity + self._coordinate_system = coordinate_system + self._aggregation_type = aggregation_type + + def to_dict(self): + dic = { + "enter": { + "bounding_box": self._bounding_box.to_dict(), + "color_gradient": self._color_gradient.to_dict(), + "cell_size": self._cell_size.to_dict(), + "cell_spacing": self._cell_spacing.to_dict(), + "opacity": self._opacity.to_dict(), + "coordinate_system": self._coordinate_system.to_dict(), + "aggregation_type": self._aggregation_type.to_dict() + } + } + return dic + + def __init__(self, encode: Encode): + self.encode = encode + + def to_dict(self): + dic = [{ + "encode": self.encode.to_dict() + }] + return dic + + +class VegaFishNetMap: + def __init__(self, width: int, height: int, bounding_box: list, color_gradient: list, + cell_size: int, cell_spacing: int, opacity: float, coordinate_system: str, aggregation_type: str): + self._width = width + self._height = height + self._bounding_box = bounding_box + self._cell_size = cell_size + self._cell_spacing = cell_spacing + self._color_gradient = color_gradient + self._opacity = opacity + self._coordinate_system = coordinate_system + self._aggregation_type = aggregation_type + + def build(self): + description = Description(desc="fishnet_map_2d") + data = Data(name="data", url="/data/data.csv") + domain = Scales.Scale.Domain("data", "c0") + scale = Scales.Scale("building", "linear", domain) + scales = Scales([scale]) + encode = Marks.Encode(bounding_box=Marks.Encode.Value(self._bounding_box), + color_gradient=Marks.Encode.Value(self._color_gradient), + cell_size=Marks.Encode.Value(self._cell_size), + cell_spacing=Marks.Encode.Value(self._cell_spacing), + opacity=Marks.Encode.Value(self._opacity), + coordinate_system=Marks.Encode.Value(self._coordinate_system), + aggregation_type=Marks.Encode.Value(self._aggregation_type)) + marks = Marks(encode) + root = Root(Width(self._width), Height(self._height), description, + data, scales, marks) + + root_json = json.dumps(root.to_dict(), indent=2) + return root_json + + def coor(self): + return self._coordinate_system + + def bounding_box(self): + return self._bounding_box + + def cell_size(self): + return self._cell_size + + def cell_spacing(self): + return self._cell_spacing + + def height(self): + return self._height + + def width(self): + return self._width + + def aggregation_type(self): + return self._aggregation_type diff --git a/python/arctern/util/vega/vega_node.py b/python/arctern/util/vega/vega_node.py index 41db32675..d0a684524 100644 --- a/python/arctern/util/vega/vega_node.py +++ b/python/arctern/util/vega/vega_node.py @@ -65,7 +65,7 @@ class Description: ' building_weighted_2d', 'heatmap_2d', 'get_building_shape')) """ render_type = {"icon_2d", "circle_2d", "multi_color_circles_2d", "weighted_color_circles_2d", - "building_weighted_2d", "heat_map_2d", "get_building_shape"} + "building_weighted_2d", "heat_map_2d", "get_building_shape", "fishnet_map_2d"} def __init__(self, desc: str): if desc not in self.render_type: diff --git a/python/tests/geo/render_test.py b/python/tests/geo/render_test.py index fe76cabae..ecce89bd7 100644 --- a/python/tests/geo/render_test.py +++ b/python/tests/geo/render_test.py @@ -16,7 +16,7 @@ import arctern from arctern.util import save_png -from arctern.util.vega import vega_pointmap, vega_weighted_pointmap, vega_heatmap, vega_choroplethmap, vega_icon +from arctern.util.vega import vega_pointmap, vega_weighted_pointmap, vega_heatmap, vega_choroplethmap, vega_icon, vega_fishnetmap def test_projection(): @@ -186,3 +186,33 @@ def test_icon_viz(): icon_buf = arctern.icon_viz_layer(vega, points) save_png(icon_buf, "/tmp/test_icon_viz.png") + +def test_fishnet_map(): + x_data = [] + y_data = [] + c_data = [] + + x_data.append(-73.96524) + x_data.append(-73.96118) + x_data.append(-73.97324) + x_data.append(-73.98456) + + y_data.append(40.73747) + y_data.append(40.74507) + y_data.append(40.75890) + y_data.append(40.77654) + + c_data.append(10) + c_data.append(20) + c_data.append(30) + c_data.append(40) + + arr_x = pandas.Series(x_data) + arr_y = pandas.Series(y_data) + arr_c = pandas.Series(c_data) + points = arctern.ST_Point(arr_x, arr_y) + + vega = vega_fishnetmap(1024, 896, bounding_box=[-73.998427, 40.730309, -73.954348, 40.780816], color_gradient=["#0000FF", "#FF0000"], cell_size=4, cell_spacing=1, opacity=1.0, coordinate_system='EPSG:4326') + heat_map1 = arctern.fishnet_map_layer(vega, points, arr_c) + + save_png(heat_map1, "/tmp/test_fishnetmap.png") diff --git a/spark/pyspark/arctern_pyspark/render_func.py b/spark/pyspark/arctern_pyspark/render_func.py index fee4d3d44..02102aa20 100644 --- a/spark/pyspark/arctern_pyspark/render_func.py +++ b/spark/pyspark/arctern_pyspark/render_func.py @@ -18,6 +18,7 @@ "heatmap", "choroplethmap", "icon_viz", + "fishnetmap", ] def pointmap(vega, df): @@ -333,3 +334,53 @@ def iconviz(point, conf=vega): df = df.rdd.coalesce(1, shuffle=True).toDF() hex_data = df.agg(iconviz(df[col_point])).collect()[0][0] return hex_data + +def fishnetmap(vega, df): + if df.rdd.isEmpty(): + return None + + if len(df.schema.names) != 2: + return None + + col_point = df.schema.names[0] + col_count = df.schema.names[1] + + from pyspark.sql.functions import pandas_udf, PandasUDFType, lit, col + from pyspark.sql.types import (StructType, StructField, BinaryType, IntegerType) + from ._wrapper_func import TransformAndProjection, Projection + + bounding_box = vega.bounding_box() + top_left = 'POINT (' + str(bounding_box[0]) + ' ' + str(bounding_box[3]) + ')' + bottom_right = 'POINT (' + str(bounding_box[2]) + ' ' + str(bounding_box[1]) + ')' + + cell_size = vega.cell_size() + height = int(vega.height() / cell_size) + width = int(vega.width() / cell_size) + coor = vega.coor() + aggregation_type = vega.aggregation_type() + + if coor != 'EPSG:3857': + df = df.select(TransformAndProjection(col(col_point), lit(str(coor)), lit('EPSG:3857'), lit(bottom_right), lit(top_left), lit(int(height)), lit(int(width))).alias(col_point), col(col_count)) + else: + df = df.select(Projection(col(col_point), lit(bottom_right), lit(top_left), lit(int(height)), lit(int(width))).alias(col_point), col(col_count)) + + agg_schema = StructType([StructField(col_point, BinaryType(), True), + StructField(col_count, IntegerType(), True)]) + + @pandas_udf(agg_schema, PandasUDFType.MAP_ITER) + def render_agg_UDF(batch_iter): + for pdf in batch_iter: + dd = pdf.groupby([col_point]) + dd = dd[col_count].agg([aggregation_type]).reset_index() + dd.columns = [col_point, col_count] + yield dd + + @pandas_udf("string", PandasUDFType.GROUPED_AGG) + def fishnetmap_wkb(point, w, conf=vega): + from arctern import fishnet_map_layer + return fishnet_map_layer(conf, point, w, False) + + agg_df = df.mapInPandas(render_agg_UDF) + agg_df = agg_df.rdd.coalesce(1, shuffle=True).toDF() + hex_data = agg_df.agg(fishnetmap_wkb(agg_df[col_point], agg_df[col_count])).collect()[0][0] + return hex_data diff --git a/spark/pyspark/examples/render/nyc_taxi.py b/spark/pyspark/examples/render/nyc_taxi.py index e858e5101..ded338aa6 100644 --- a/spark/pyspark/examples/render/nyc_taxi.py +++ b/spark/pyspark/examples/render/nyc_taxi.py @@ -16,7 +16,7 @@ from pyspark.sql import SparkSession from arctern.util import save_png -from arctern.util.vega import vega_pointmap, vega_heatmap, vega_choroplethmap, vega_weighted_pointmap, vega_icon +from arctern.util.vega import vega_pointmap, vega_heatmap, vega_choroplethmap, vega_weighted_pointmap, vega_icon, vega_fishnetmap from arctern_pyspark import register_funcs @@ -25,6 +25,7 @@ from arctern_pyspark import choroplethmap from arctern_pyspark import weighted_pointmap from arctern_pyspark import icon_viz +from arctern_pyspark import fishnetmap def draw_point_map(spark): start_time = time.time() @@ -141,6 +142,25 @@ def draw_icon_viz(spark): spark.catalog.dropGlobalTempView("nyc_taxi") print("--- %s seconds ---" % (time.time() - start_time)) +def draw_fishnet_map(spark): + start_time = time.time() + df = spark.read.format("csv").option("header", True).option("delimiter", ",").schema( + "VendorID string, tpep_pickup_datetime timestamp, tpep_dropoff_datetime timestamp, passenger_count long, trip_distance double, pickup_longitude double, pickup_latitude double, dropoff_longitude double, dropoff_latitude double, fare_amount double, tip_amount double, total_amount double, buildingid_pickup long, buildingid_dropoff long, buildingtext_pickup string, buildingtext_dropoff string").load( + "file:///tmp/0_5M_nyc_taxi_and_building.csv").cache() + df.createOrReplaceTempView("nyc_taxi") + + register_funcs(spark) + res = spark.sql("select ST_Point(pickup_longitude, pickup_latitude) as point, passenger_count as w from nyc_taxi where ST_Within(ST_Point(pickup_longitude, pickup_latitude), ST_GeomFromText('POLYGON ((-73.998427 40.730309, -73.954348 40.730309, -73.954348 40.780816 ,-73.998427 40.780816, -73.998427 40.730309))'))") + + res.show() + + vega = vega_fishnetmap(1024, 896, bounding_box=[-73.998427, 40.730309, -73.954348, 40.780816], color_gradient=["#0000FF", "#FF0000"], cell_size=4, cell_spacing=1, opacity=1.0, coordinate_system='EPSG:4326') + res = fishnetmap(vega, res) + save_png(res, '/tmp/fishnetmap.png') + + spark.sql("show tables").show() + spark.catalog.dropGlobalTempView("nyc_taxi") + print("--- %s seconds ---" % (time.time() - start_time)) if __name__ == "__main__": spark_session = SparkSession \ @@ -155,5 +175,6 @@ def draw_icon_viz(spark): draw_choropleth_map(spark_session) draw_weighted_point_map(spark_session) draw_icon_viz(spark_session) + draw_fishnet_map(spark_session) spark_session.stop() From 794313a5ae640e6703f61e102a38034c03da5edc Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Thu, 7 May 2020 17:46:21 +0800 Subject: [PATCH 2/6] add restful api for fishnetmap --- gui/server/app/codegen.py | 19 +++++++++++++++++-- gui/server/app/scope.py | 10 ++++++++++ gui/server/app/service.py | 18 ++++++++++++++++-- gui/server/tests/restful/test_scope.py | 23 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/gui/server/app/codegen.py b/gui/server/app/codegen.py index e3c1cb1e7..8e559408e 100644 --- a/gui/server/app/codegen.py +++ b/gui/server/app/codegen.py @@ -21,8 +21,8 @@ def generate_session_code(session_name="spark"): import socket localhost_ip = socket.gethostbyname(socket.gethostname()) - session_code = 'from arctern.util.vega import vega_choroplethmap, vega_heatmap, vega_pointmap, vega_weighted_pointmap\n' - session_code += 'from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap\n' + session_code = 'from arctern.util.vega import vega_choroplethmap, vega_heatmap, vega_pointmap, vega_weighted_pointmap, vega_fishnetmap\n' + session_code += 'from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap, fishnet_map\n' session_code += 'from arctern_pyspark import register_funcs\n' session_code += 'from pyspark.sql import SparkSession\n' session_code += '{} = SparkSession.builder'.format(session_name) @@ -147,3 +147,18 @@ def generate_weighted_map_code(sql, params, session_name='spark'): params.get('coordinate_system') ) return sql_code, vega_code + +def generate_fishnetmap_code(sql, params, session_name='spark'): + sql_code = generate_run_sql_code(sql, session_name) + vega_code = 'vega_fishnetmap({}, {}, {}, {}, {}, {}, {}, "{}", "{}")'.format( + int(params.get('width')), + int(params.get('height')), + params.get('bounding_box'), + params.get('color_gradient'), + int(params.get('cell_size')), + int(params.get('cell_spacing')), + float(params.get('opacity')), + params.get('coordinate_system'), + params.get('aggregation_type') + ) + return sql_code, vega_code diff --git a/gui/server/app/scope.py b/gui/server/app/scope.py index 1bfd2e391..286e09dda 100644 --- a/gui/server/app/scope.py +++ b/gui/server/app/scope.py @@ -196,6 +196,7 @@ def render(payload, render_type): "heatmap": codegen.generate_heatmap_code, "choroplethmap": codegen.generate_choropleth_map_code, "weighted_pointmap": codegen.generate_weighted_map_code, + "fishnetmap": codegen.generate_fishnetmap_code, } log.INSTANCE.info("POST /{}: {}".format(render_type, payload)) @@ -261,3 +262,12 @@ def weighted_pointmap(): code=code, result=result, ) + +@API.route('/fishnetmap', methods=['POST']) +def fishnetmap(): + status, code, result = render(request.json, 'fishnetmap') + return jsonify( + status=status, + code=code, + result=result, + ) diff --git a/gui/server/app/service.py b/gui/server/app/service.py index c46c2f10d..40840f158 100644 --- a/gui/server/app/service.py +++ b/gui/server/app/service.py @@ -19,8 +19,8 @@ import json from flask import Blueprint, jsonify, request -from arctern.util.vega import vega_choroplethmap, vega_heatmap, vega_pointmap, vega_weighted_pointmap, vega_icon -from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap, icon_viz +from arctern.util.vega import vega_choroplethmap, vega_heatmap, vega_pointmap, vega_weighted_pointmap, vega_icon, vega_fishnetmap +from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap, icon_viz, fishnetmap from app import account from app.common import spark, token, utils, db, log @@ -253,6 +253,20 @@ def db_query(): ) data = icon_viz(vega, res) content['result'] = data + elif query_type == 'fishnet': + vega = vega_fishnetmap( + int(query_params['width']), + int(query_params['height']), + query_params['fishnet']['bounding_box'], + query_params['fishnet']['color_gradient'], + query_params['fishnet']['cell_size'], + query_params['fishnet']['cell_spacing'], + query_params['fishnet']['opacity'], + query_params['fishnet']['coordinate_system'], + query_params['fishnet']['aggregation_type'] + ) + data = fishnetmap(vega, res) + content['result'] = data else: return jsonify(status="error", code=-1, diff --git a/gui/server/tests/restful/test_scope.py b/gui/server/tests/restful/test_scope.py index 1fa5ab82a..4fc53d654 100644 --- a/gui/server/tests/restful/test_scope.py +++ b/gui/server/tests/restful/test_scope.py @@ -212,6 +212,29 @@ def test_choroplethmap(self, host, port): print(r.text) # assert r.json()["result"] is not None + @pytest.mark.run(order=11) + def test_fishnetmap(self, host, port): + url = "http://" + host + ":" + port + "/fishnetmap" + payload = { + "scope": SCOPE, + "sql": "select ST_Point(pickup_longitude, pickup_latitude) as point, passenger_count as w from {} where ST_Within(ST_Point(pickup_longitude, pickup_latitude), ST_GeomFromText('POLYGON ((-73.998427 40.730309, -73.954348 40.730309, -73.954348 40.780816 ,-73.998427 40.780816, -73.998427 40.730309))'))".format(table_name), + "params": { + "width": 1024, + "height": 896, + "bounding_box": [-80.37976, 35.191296, -70.714099, 45.897445], + "color_gradient": ["#0000FF", "#FF0000"], + "cell_size": 4, + "cell_spacing": 1, + "opacity": 1.0, + "coordinate_system": "EPSG:4326", + "aggregation_type": "sum" + } + } + r = requests.post(url=url, json=payload) + assert r.status_code == 200 + print(r.text) + # assert r.json()["result"] is not None + @pytest.mark.run(order=11) def test_drop_table(self, host, port): url = "http://" + host + ":" + port + '/query' From 241533a2ea4a687df78b6153d54c6928744e3597 Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Thu, 7 May 2020 19:13:11 +0800 Subject: [PATCH 3/6] add restful api for fishnetmap --- gui/server/app/codegen.py | 2 +- gui/server/app/service.py | 6 ++-- gui/server/tests/restful/test_service.py | 35 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/gui/server/app/codegen.py b/gui/server/app/codegen.py index 8e559408e..d7a554a42 100644 --- a/gui/server/app/codegen.py +++ b/gui/server/app/codegen.py @@ -22,7 +22,7 @@ def generate_session_code(session_name="spark"): localhost_ip = socket.gethostbyname(socket.gethostname()) session_code = 'from arctern.util.vega import vega_choroplethmap, vega_heatmap, vega_pointmap, vega_weighted_pointmap, vega_fishnetmap\n' - session_code += 'from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap, fishnet_map\n' + session_code += 'from arctern_pyspark import choroplethmap, heatmap, pointmap, weighted_pointmap, fishnetmap\n' session_code += 'from arctern_pyspark import register_funcs\n' session_code += 'from pyspark.sql import SparkSession\n' session_code += '{} = SparkSession.builder'.format(session_name) diff --git a/gui/server/app/service.py b/gui/server/app/service.py index 40840f158..39d8025e3 100644 --- a/gui/server/app/service.py +++ b/gui/server/app/service.py @@ -259,9 +259,9 @@ def db_query(): int(query_params['height']), query_params['fishnet']['bounding_box'], query_params['fishnet']['color_gradient'], - query_params['fishnet']['cell_size'], - query_params['fishnet']['cell_spacing'], - query_params['fishnet']['opacity'], + int(query_params['fishnet']['cell_size']), + int(query_params['fishnet']['cell_spacing']), + float(query_params['fishnet']['opacity']), query_params['fishnet']['coordinate_system'], query_params['fishnet']['aggregation_type'] ) diff --git a/gui/server/tests/restful/test_service.py b/gui/server/tests/restful/test_service.py index 273788cca..3a31e6045 100644 --- a/gui/server/tests/restful/test_service.py +++ b/gui/server/tests/restful/test_service.py @@ -315,3 +315,38 @@ def test_query(load, host, port, headers, dbid, table_name): ) assert response.status_code == 200 assert response.json()['data']['result'] is not None + + # case 6: fishnet_map + fishnet_map_request_dict = { + 'id': dbid, + 'query': { + 'sql': ''' + select ST_Point(pickup_longitude, pickup_latitude) as point, tip_amount as c + from {} + where ST_Within( + ST_Point(pickup_longitude, pickup_latitude), + ST_GeomFromText('POLYGON ((-73.998427 40.730309, -73.954348 40.730309, -73.954348 40.780816 ,-73.998427 40.780816, -73.998427 40.730309))')) + '''.format(table_name), + 'type': 'fishnet', + 'params': { + 'width': 1024, + 'height': 896, + 'fishnet': { + 'bounding_box': [-75.37976, 40.191296, -71.714099, 41.897445], + 'color_gradient': ["#0000FF", "#FF0000"], + 'cell_size': 5, + 'cell_spacing': 2, + 'opacity': 1.0, + 'coordinate_system': 'EPSG:4326', + 'aggregation_type': 'sum' + } + } + } + } + response = requests.post( + url=url, + json=fishnet_map_request_dict, + headers=headers, + ) + assert response.status_code == 200 + assert response.json()['data']['result'] is not None From 6a8670a2cc81c47186fa874ff940cd7e173fa86e Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Thu, 7 May 2020 20:11:03 +0800 Subject: [PATCH 4/6] fix pylint --- gui/server/app/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/server/app/service.py b/gui/server/app/service.py index 39d8025e3..17bd4647e 100644 --- a/gui/server/app/service.py +++ b/gui/server/app/service.py @@ -157,7 +157,7 @@ def db_table_info(): return jsonify(status="error", code=-1, message='there is no database whose id equal to ' + str(request.json['id'])) - +# pylint: disable=too-many-branches @API.route("/db/query", methods=['POST']) @token.AUTH.login_required def db_query(): From 85229672baf039918870910f906606415a904904 Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Sat, 9 May 2020 15:25:29 +0800 Subject: [PATCH 5/6] fix fishnet error when cell_size is not an index of 2 --- cpp/src/arrow/render_api.cpp | 99 +++++++++++-------- cpp/src/render/2d/fishnet_map/fishnet_map.cpp | 77 ++++++--------- cpp/src/render/utils/agg/agg_handler.h | 37 +++++++ .../vega_fishnet_map/vega_fishnet_map.cpp | 4 +- cpp/unittest/render/fishnetmap_test.cpp | 70 +++++++++++-- python/arctern/_wrapper_func.py | 7 +- .../util/vega/fishnetmap/vega_fishnetmap.py | 8 +- spark/pyspark/arctern_pyspark/render_func.py | 5 +- 8 files changed, 196 insertions(+), 111 deletions(-) diff --git a/cpp/src/arrow/render_api.cpp b/cpp/src/arrow/render_api.cpp index deecee12a..6d1cbd968 100644 --- a/cpp/src/arrow/render_api.cpp +++ b/cpp/src/arrow/render_api.cpp @@ -454,81 +454,94 @@ template std::pair render_fishnetmap(const std::vector& points, const std::vector& arr_c, const std::string& conf) { - auto data = AggHandler::weight_agg(points, arr_c); - auto num_point = data.first.size(); - - std::vector input_x(num_point); - std::vector input_y(num_point); - std::vector input_c(num_point); - rapidjson::Document document; document.Parse(conf.c_str()); rapidjson::Value mark_enter; mark_enter = document["marks"][0]["encode"]["enter"]; auto agg = mark_enter["aggregation_type"]["value"].GetString(); + int cell_size = mark_enter["cell_size"]["value"].GetDouble(); + int cell_spacing = mark_enter["cell_spacing"]["value"].GetDouble(); + auto region_size = cell_size + cell_spacing; AggHandler::AggType type_agg = AggHandler::agg_type(agg); - const auto& result_wkb = data.first; - const auto& result_weight = data.second; + auto data = AggHandler::region_agg(points, arr_c, region_size); + auto num_point = data.size(); + + std::vector input_x(num_point); + std::vector input_y(num_point); + std::vector input_c(num_point); + int i = 0; switch (type_agg) { case AggHandler::AggType::MAX: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - input_c[i] = *max_element(result_weight[i].begin(), result_weight[i].end()); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + input_c[i] = *max_element(result_weight.begin(), result_weight.end()); + i++; } break; } case AggHandler::AggType::MIN: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - input_c[i] = *min_element(result_weight[i].begin(), result_weight[i].end()); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + input_c[i] = *min_element(result_weight.begin(), result_weight.end()); + i++; } break; } case AggHandler::AggType::COUNT: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - input_c[i] = result_weight[i].size(); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + input_c[i] = result_weight.size(); + i++; } break; } case AggHandler::AggType::SUM: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - input_c[i] = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + input_c[i] = accumulate(result_weight.begin(), result_weight.end(), 0); + i++; } break; } case AggHandler::AggType::STDDEV: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - T sum = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); - T mean = sum / result_weight[i].size(); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + T sum = accumulate(result_weight.begin(), result_weight.end(), 0); + T mean = sum / result_weight.size(); T accum = 0; - std::for_each(std::begin(result_weight[i]), std::end(result_weight[i]), + std::for_each(std::begin(result_weight), std::end(result_weight), [&](const T d) { accum += (d - mean) * (d - mean); }); - input_c[i] = sqrt(accum / result_weight[i].size()); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + input_c[i] = sqrt(accum / result_weight.size()); + i++; } break; } case AggHandler::AggType::AVG: { - for (int i = 0; i < num_point; i++) { - input_x[i] = result_wkb[i]->toPoint()->getX(); - input_y[i] = result_wkb[i]->toPoint()->getY(); - T sum_data = accumulate(result_weight[i].begin(), result_weight[i].end(), 0); - input_c[i] = sum_data / result_weight[i].size(); - OGRGeometryFactory::destroyGeometry(result_wkb[i]); + for (auto iter = data.begin(); iter != data.end(); iter++) { + auto result_point = iter->first; + auto result_weight = iter->second; + input_x[i] = result_point.first; + input_y[i] = result_point.second; + T sum_data = accumulate(result_weight.begin(), result_weight.end(), 0); + input_c[i] = sum_data / result_weight.size(); + i++; } break; } diff --git a/cpp/src/render/2d/fishnet_map/fishnet_map.cpp b/cpp/src/render/2d/fishnet_map/fishnet_map.cpp index a11bdf350..f12e78b8e 100644 --- a/cpp/src/render/2d/fishnet_map/fishnet_map.cpp +++ b/cpp/src/render/2d/fishnet_map/fishnet_map.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #define GL_GLEXT_PROTOTYPES #include @@ -57,8 +58,6 @@ FishNetMap::FishNetMap(uint32_t* input_x, uint32_t* input_y, T* count, template FishNetMap::~FishNetMap() { - free(vertices_x_); - free(vertices_y_); free(colors_); } @@ -71,6 +70,7 @@ void set_colors(float* colors, uint32_t* input_x, uint32_t* input_y, T* input_c, int64_t window_size = width * height; int cell_size = vega_fishnet_map.cell_size(); int cell_spacing = vega_fishnet_map.cell_spacing(); + int block_size = cell_size + cell_spacing; std::vector weights(num); memcpy(&weights[0], input_c, num * sizeof(T)); @@ -83,23 +83,15 @@ void set_colors(float* colors, uint32_t* input_x, uint32_t* input_y, T* input_c, color_gradient.createDefaultHeatMapGradient(); for (int i = 0; i < num; i++) { + if (input_y[i] * block_size >= height || input_x[i] * block_size >= width) continue; float value = input_c[i] > max_pix ? 1.0f : (input_c[i] - min_pix) / count_range; float color_r, color_g, color_b; color_gradient.getColorAtValue(value, color_r, color_g, color_b); - - if (input_y[i] * cell_size >= height || input_x[i] * cell_size >= width) { - continue; - } - int index = cell_size * input_y[i] * width + input_x[i] * cell_size; - for (int m = 0; m < cell_size - cell_spacing; m++) { - for (int n = 0; n < cell_size - cell_spacing; n++) { - int index_in = (index + m * width + n) * 4; - colors[index_in++] = color_r; - colors[index_in++] = color_g; - colors[index_in++] = color_b; - colors[index_in++] = vega_fishnet_map.opacity(); - } - } + auto index = i * 4; + colors[index++] = color_r; + colors[index++] = color_g; + colors[index++] = color_b; + colors[index++] = vega_fishnet_map.opacity(); } } @@ -110,27 +102,16 @@ void FishNetMap::DataInit() { int64_t height = window_params.height(); int64_t window_size = width * height; - colors_ = (float*)malloc(window_size * 4 * sizeof(float)); + colors_ = (float*)malloc(num_vertices_ * 4 * sizeof(float)); set_colors(colors_, vertices_x_, vertices_y_, count_, num_vertices_, fishnet_vega_); - vertices_x_ = (uint32_t*)malloc(window_size * sizeof(uint32_t)); - vertices_y_ = (uint32_t*)malloc(window_size * sizeof(uint32_t)); - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - vertices_x_[i * width + j] = j; - vertices_y_[i * width + j] = i; - } - } - num_vertices_ = window_size; } template void FishNetMap::Draw() { - // glEnable(GL_PROGRAM_POINT_SIZE); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_POINT_SMOOTH); - + glBlendFunc(GL_SRC_ALPHA, GL_ZERO); + glLineWidth(20); #ifdef USE_GPU glDrawArrays(GL_POINTS, 0, num_vertices_); glFlush(); @@ -138,22 +119,28 @@ void FishNetMap::Draw() { glDeleteVertexArrays(1, &VAO_); glDeleteBuffers(2, VBO_); #else - glOrtho(0, window()->window_params().width(), 0, window()->window_params().height(), -1, - 1); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - int offset = 0; - std::vector vertices(num_vertices_ * 2); - for (auto i = 0; i < num_vertices_; i++) { - vertices[offset++] = vertices_x_[i]; - vertices[offset++] = vertices_y_[i]; + int width = window()->window_params().width(); + int height = window()->window_params().height(); + int cell_size = fishnet_vega_.cell_size(); + int cell_spacing = fishnet_vega_.cell_spacing(); + int block_size = cell_size + cell_spacing; + double spacing = (double)cell_spacing / 2; + + glOrtho(0, width, 0, height, -1, 1); + for (int i = 0; i < num_vertices_; i++) { + if (vertices_x_[i] * block_size >= width || vertices_y_[i] * block_size >= height) + continue; + glColor4f(colors_[i * 4], colors_[i * 4 + 1], colors_[i * 4 + 2], colors_[i * 4 + 3]); + glBegin(GL_POLYGON); + double x = vertices_x_[i] * block_size + spacing; + double y = vertices_y_[i] * block_size + spacing; + glVertex2d(x + (double)cell_size, y + (double)cell_size); + glVertex2d(x + (double)cell_size, y); + glVertex2d(x, y); + glVertex2d(x, y + (double)cell_size); + glEnd(); } - glColorPointer(4, GL_FLOAT, 0, colors_); - glVertexPointer(2, GL_INT, 0, &vertices[0]); - - glDrawArrays(GL_POINTS, 0, num_vertices_); - glFlush(); + glFinish(); #endif } diff --git a/cpp/src/render/utils/agg/agg_handler.h b/cpp/src/render/utils/agg/agg_handler.h index eed4ab443..8ad23456b 100644 --- a/cpp/src/render/utils/agg/agg_handler.h +++ b/cpp/src/render/utils/agg/agg_handler.h @@ -43,6 +43,43 @@ class AggHandler { static AggType agg_type(std::string type); + struct hash_pair { + template + size_t operator()(const std::pair& point) const { + auto hash_x = std::hash{}(point.first); + auto hash_y = std::hash{}(point.second); + return hash_x ^ hash_y; + } + }; + + template + static std::unordered_map, std::vector, hash_pair> + region_agg(const std::vector& wkb_arr, const std::vector& arr_c, + int region_size) { + assert(wkb_arr.size() == arr_c.size()); + + std::unordered_map, std::vector, hash_pair> result; + for (size_t i = 0; i < wkb_arr.size(); i++) { + std::string wkb = wkb_arr[i]; + OGRGeometry* geo; + CHECK_GDAL(OGRGeometryFactory::createFromWkb(wkb.c_str(), nullptr, &geo)); + uint32_t x = geo->toPoint()->getX() / region_size; + uint32_t y = geo->toPoint()->getY() / region_size; + OGRGeometryFactory::destroyGeometry(geo); + auto point = std::make_pair(x, y); + if (result.find(point) == result.end()) { + std::vector weight; + weight.emplace_back(arr_c[i]); + result[point] = weight; + } else { + auto& weight = result[point]; + weight.emplace_back(arr_c[i]); + } + } + + return result; + } + static std::pair, std::vector> weight_agg( const std::shared_ptr& geos) { auto geo_arr = std::static_pointer_cast(geos); diff --git a/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp index 3137db0b1..d54fa3378 100644 --- a/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp +++ b/cpp/src/render/utils/vega/vega_fishnet_map/vega_fishnet_map.cpp @@ -91,14 +91,14 @@ void VegaFishNetMap::Parse(const std::string& json) { !JsonTypeCheck(mark_enter["cell_size"]["value"], rapidjson::Type::kNumberType)) { return; } - cell_size_ = mark_enter["cell_size"]["value"].GetInt(); + cell_size_ = mark_enter["cell_size"]["value"].GetDouble(); if (!JsonLabelCheck(mark_enter, "cell_spacing") || !JsonLabelCheck(mark_enter["cell_spacing"], "value") || !JsonTypeCheck(mark_enter["cell_spacing"]["value"], rapidjson::Type::kNumberType)) { return; } - cell_spacing_ = mark_enter["cell_spacing"]["value"].GetInt(); + cell_spacing_ = mark_enter["cell_spacing"]["value"].GetDouble(); // parse opacity if (!JsonLabelCheck(mark_enter, "opacity") || diff --git a/cpp/unittest/render/fishnetmap_test.cpp b/cpp/unittest/render/fishnetmap_test.cpp index f2ca1a9ab..0c3eb25bb 100644 --- a/cpp/unittest/render/fishnetmap_test.cpp +++ b/cpp/unittest/render/fishnetmap_test.cpp @@ -61,9 +61,14 @@ TEST(FISHNETMAP_TEST, INT8) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -133,9 +138,14 @@ TEST(FISHNETMAP_TEST, INT16) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -205,9 +215,14 @@ TEST(FISHNETMAP_TEST, INT32) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -277,9 +292,14 @@ TEST(FISHNETMAP_TEST, INT64) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -349,9 +369,14 @@ TEST(FISHNETMAP_TEST, UINT8) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -421,9 +446,14 @@ TEST(FISHNETMAP_TEST, UINT16) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -493,9 +523,14 @@ TEST(FISHNETMAP_TEST, UINT32) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -565,9 +600,14 @@ TEST(FISHNETMAP_TEST, UINT64) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -637,9 +677,14 @@ TEST(FISHNETMAP_TEST, FLOAT) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" @@ -709,9 +754,14 @@ TEST(FISHNETMAP_TEST, DOUBLE) { " ],\n" " \"scales\": [\n" " {\n" - " \"name\": \"building\",\n" + " \"name\": \"x\",\n" " \"type\": \"linear\",\n" " \"domain\": {\"data\": \"data\", \"field\": \"c0\"}\n" + " },\n" + " {\n" + " \"name\": \"y\",\n" + " \"type\": \"linear\",\n" + " \"domain\": {\"data\": \"data\", \"field\": \"c1\"}\n" " }\n" " ],\n" " \"marks\": [\n" diff --git a/python/arctern/_wrapper_func.py b/python/arctern/_wrapper_func.py index 2f627f8ff..8f93ef0f7 100644 --- a/python/arctern/_wrapper_func.py +++ b/python/arctern/_wrapper_func.py @@ -1460,11 +1460,8 @@ def fishnet_map_layer(vega, points, weights, transform=True): top_left = 'POINT (' + str(bounding_box[0]) + ' ' + str(bounding_box[3]) + ')' bottom_right = 'POINT (' + str(bounding_box[2]) + ' ' + str(bounding_box[1]) + ')' - # height = vega.height() - # width = vega.width() - cell_size = vega.cell_size() - height = int(vega.height() / cell_size) - width = int(vega.width() / cell_size) + height = vega.height() + width = vega.width() coor = vega.coor() src = bytes(coor, encoding="utf8") diff --git a/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py b/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py index 39245eaa9..8b6952571 100644 --- a/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py +++ b/python/arctern/util/vega/fishnetmap/vega_fishnetmap.py @@ -92,9 +92,11 @@ def __init__(self, width: int, height: int, bounding_box: list, color_gradient: def build(self): description = Description(desc="fishnet_map_2d") data = Data(name="data", url="/data/data.csv") - domain = Scales.Scale.Domain("data", "c0") - scale = Scales.Scale("building", "linear", domain) - scales = Scales([scale]) + domain1 = Scales.Scale.Domain("data", "c0") + domain2 = Scales.Scale.Domain("data", "c1") + scale1 = Scales.Scale("x", "linear", domain1) + scale2 = Scales.Scale("y", "linear", domain2) + scales = Scales([scale1, scale2]) encode = Marks.Encode(bounding_box=Marks.Encode.Value(self._bounding_box), color_gradient=Marks.Encode.Value(self._color_gradient), cell_size=Marks.Encode.Value(self._cell_size), diff --git a/spark/pyspark/arctern_pyspark/render_func.py b/spark/pyspark/arctern_pyspark/render_func.py index 02102aa20..1ea35ce55 100644 --- a/spark/pyspark/arctern_pyspark/render_func.py +++ b/spark/pyspark/arctern_pyspark/render_func.py @@ -353,9 +353,8 @@ def fishnetmap(vega, df): top_left = 'POINT (' + str(bounding_box[0]) + ' ' + str(bounding_box[3]) + ')' bottom_right = 'POINT (' + str(bounding_box[2]) + ' ' + str(bounding_box[1]) + ')' - cell_size = vega.cell_size() - height = int(vega.height() / cell_size) - width = int(vega.width() / cell_size) + height = vega.height() + width = vega.width() coor = vega.coor() aggregation_type = vega.aggregation_type() From f546f81570405bdbda3e39088fd0e1f985ab4fd5 Mon Sep 17 00:00:00 2001 From: xge-zilliz Date: Sat, 9 May 2020 17:10:48 +0800 Subject: [PATCH 6/6] rerun jenkins --- python/arctern/util/vega/_vega_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/arctern/util/vega/_vega_functions.py b/python/arctern/util/vega/_vega_functions.py index 838fe2684..64aa06689 100644 --- a/python/arctern/util/vega/_vega_functions.py +++ b/python/arctern/util/vega/_vega_functions.py @@ -121,7 +121,7 @@ def vega_fishnetmap(width, coordinate_system="EPSG:3857", aggregation_type="sum"): if color_gradient is None: - color_gradient = ["#00FF00", "FF0000"] + color_gradient = ["#0000FF", "FF0000"] return VegaFishNetMap(width, height, bounding_box,