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