1
2 #define R_NO_REMAP
3 #include <R.h>
4 #include <Rinternals.h>
5 #include "wk-v1.h"
6
7 #define HANDLE_CONTINUE_OR_BREAK(expr) \
8 result = expr; \
9 if (result == WK_ABORT_FEATURE) continue; else if (result == WK_ABORT) break
10
wk_read_xy(SEXP data,wk_handler_t * handler)11 SEXP wk_read_xy(SEXP data, wk_handler_t* handler) {
12 R_xlen_t n_features = Rf_xlength(VECTOR_ELT(data, 0));
13 int coord_size = Rf_length(data);
14 double* data_ptr[coord_size];
15 for (int j = 0; j < coord_size; j++) {
16 data_ptr[j] = REAL(VECTOR_ELT(data, j));
17 }
18
19 wk_vector_meta_t vector_meta;
20 WK_VECTOR_META_RESET(vector_meta, WK_POINT);
21 vector_meta.size = n_features;
22
23 if (Rf_inherits(data, "wk_xyz") || Rf_inherits(data, "wk_xyzm")) {
24 vector_meta.flags |= WK_FLAG_HAS_Z;
25 }
26
27 if (Rf_inherits(data, "wk_xym") || Rf_inherits(data, "wk_xyzm")) {
28 vector_meta.flags |= WK_FLAG_HAS_M;
29 }
30
31 if (handler->vector_start(&vector_meta, handler->handler_data) == WK_CONTINUE) {
32 int result;
33 double coord[4];
34 wk_meta_t meta;
35 WK_META_RESET(meta, WK_POINT);
36 meta.flags = vector_meta.flags | WK_FLAG_HAS_BOUNDS;
37
38 for (R_xlen_t i = 0; i < n_features; i++) {
39 if (((i + 1) % 1000) == 0) R_CheckUserInterrupt();
40
41 HANDLE_CONTINUE_OR_BREAK(handler->feature_start(&vector_meta, i, handler->handler_data));
42
43 int coord_empty = 1;
44 for (int j = 0; j < coord_size; j++) {
45 coord[j] = data_ptr[j][i];
46 meta.bounds_min[j] = data_ptr[j][i];
47 meta.bounds_max[j] = data_ptr[j][i];
48
49 if (!ISNAN(coord[j])) {
50 coord_empty = 0;
51 }
52 }
53
54 if (coord_empty) {
55 meta.size = 0;
56 } else {
57 meta.size = 1;
58 }
59
60 HANDLE_CONTINUE_OR_BREAK(handler->geometry_start(&meta, WK_PART_ID_NONE, handler->handler_data));
61 if (!coord_empty) {
62 HANDLE_CONTINUE_OR_BREAK(handler->coord(&meta, coord, 0, handler->handler_data));
63 }
64 HANDLE_CONTINUE_OR_BREAK(handler->geometry_end(&meta, WK_PART_ID_NONE, handler->handler_data));
65
66 if (handler->feature_end(&vector_meta, i, handler->handler_data) == WK_ABORT) {
67 break;
68 }
69 }
70 }
71
72 SEXP result = PROTECT(handler->vector_end(&vector_meta, handler->handler_data));
73 UNPROTECT(1);
74 return result;
75 }
76
wk_c_read_xy(SEXP data,SEXP handlerXptr)77 SEXP wk_c_read_xy(SEXP data, SEXP handlerXptr) {
78 return wk_handler_run_xptr(&wk_read_xy, data, handlerXptr);
79 }
80