-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generic
GeoArrowArrayReader
to use any array with the visitor p…
…attern (#56) * start on generic handler * theoretical support for WKT/WKB visiting * add array reader * test some of the visiting * with wkb test * use array reader to simplify kernel * run apt-get update in ubuntu job
- Loading branch information
1 parent
0ba1870
commit 0b31fea
Showing
9 changed files
with
321 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
|
||
#include "geoarrow.h" | ||
|
||
#include "nanoarrow.h" | ||
|
||
struct GeoArrowArrayReaderPrivate { | ||
struct GeoArrowWKTReader wkt_reader; | ||
struct GeoArrowWKBReader wkb_reader; | ||
}; | ||
|
||
static GeoArrowErrorCode GeoArrowArrayViewVisitWKT(struct GeoArrowArrayView* array_view, | ||
int64_t offset, int64_t length, | ||
struct GeoArrowWKTReader* reader, | ||
struct GeoArrowVisitor* v) { | ||
struct GeoArrowStringView item; | ||
const int32_t* offset_begin = array_view->offsets[0] + array_view->offset[0] + offset; | ||
|
||
for (int64_t i = 0; i < length; i++) { | ||
if (!array_view->validity_bitmap || | ||
ArrowBitGet(array_view->validity_bitmap, array_view->offset[0] + offset + i)) { | ||
item.data = (const char*)(array_view->data + offset_begin[i]); | ||
item.size_bytes = offset_begin[i + 1] - offset_begin[i]; | ||
NANOARROW_RETURN_NOT_OK(GeoArrowWKTReaderVisit(reader, item, v)); | ||
} else { | ||
NANOARROW_RETURN_NOT_OK(v->feat_start(v)); | ||
NANOARROW_RETURN_NOT_OK(v->null_feat(v)); | ||
NANOARROW_RETURN_NOT_OK(v->feat_end(v)); | ||
} | ||
} | ||
|
||
return GEOARROW_OK; | ||
} | ||
|
||
static GeoArrowErrorCode GeoArrowArrayViewVisitWKB(struct GeoArrowArrayView* array_view, | ||
int64_t offset, int64_t length, | ||
struct GeoArrowWKBReader* reader, | ||
struct GeoArrowVisitor* v) { | ||
struct GeoArrowBufferView item; | ||
const int32_t* offset_begin = array_view->offsets[0] + array_view->offset[0] + offset; | ||
|
||
for (int64_t i = 0; i < length; i++) { | ||
if (!array_view->validity_bitmap || | ||
ArrowBitGet(array_view->validity_bitmap, array_view->offset[0] + offset + i)) { | ||
item.data = array_view->data + offset_begin[i]; | ||
item.size_bytes = offset_begin[i + 1] - offset_begin[i]; | ||
NANOARROW_RETURN_NOT_OK(GeoArrowWKBReaderVisit(reader, item, v)); | ||
} else { | ||
NANOARROW_RETURN_NOT_OK(v->feat_start(v)); | ||
NANOARROW_RETURN_NOT_OK(v->null_feat(v)); | ||
NANOARROW_RETURN_NOT_OK(v->feat_end(v)); | ||
} | ||
} | ||
|
||
return GEOARROW_OK; | ||
} | ||
|
||
GeoArrowErrorCode GeoArrowArrayReaderInit(struct GeoArrowArrayReader* reader) { | ||
struct GeoArrowArrayReaderPrivate* private_data = | ||
(struct GeoArrowArrayReaderPrivate*)ArrowMalloc( | ||
sizeof(struct GeoArrowArrayReaderPrivate)); | ||
|
||
if (private_data == NULL) { | ||
return ENOMEM; | ||
} | ||
|
||
int result = GeoArrowWKTReaderInit(&private_data->wkt_reader); | ||
if (result != GEOARROW_OK) { | ||
ArrowFree(private_data); | ||
return result; | ||
} | ||
|
||
result = GeoArrowWKBReaderInit(&private_data->wkb_reader); | ||
if (result != GEOARROW_OK) { | ||
GeoArrowWKTReaderReset(&private_data->wkt_reader); | ||
ArrowFree(private_data); | ||
return result; | ||
} | ||
|
||
reader->private_data = private_data; | ||
return GEOARROW_OK; | ||
} | ||
|
||
void GeoArrowArrayReaderReset(struct GeoArrowArrayReader* reader) { | ||
struct GeoArrowArrayReaderPrivate* private_data = | ||
(struct GeoArrowArrayReaderPrivate*)reader->private_data; | ||
GeoArrowWKBReaderReset(&private_data->wkb_reader); | ||
GeoArrowWKTReaderReset(&private_data->wkt_reader); | ||
ArrowFree(reader->private_data); | ||
} | ||
|
||
GeoArrowErrorCode GeoArrowArrayReaderVisit(struct GeoArrowArrayReader* reader, | ||
struct GeoArrowArrayView* array_view, | ||
int64_t offset, int64_t length, | ||
struct GeoArrowVisitor* v) { | ||
struct GeoArrowArrayReaderPrivate* private_data = | ||
(struct GeoArrowArrayReaderPrivate*)reader->private_data; | ||
|
||
switch (array_view->schema_view.type) { | ||
case GEOARROW_TYPE_WKT: | ||
return GeoArrowArrayViewVisitWKT(array_view, offset, length, | ||
&private_data->wkt_reader, v); | ||
case GEOARROW_TYPE_WKB: | ||
return GeoArrowArrayViewVisitWKB(array_view, offset, length, | ||
&private_data->wkb_reader, v); | ||
default: | ||
return GeoArrowArrayViewVisit(array_view, offset, length, v); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include "geoarrow.h" | ||
|
||
#include "wkx_testing.hpp" | ||
|
||
TEST(ArrayReaderTest, ArrayReaderTestBasic) { | ||
struct GeoArrowArrayReader reader; | ||
ASSERT_EQ(GeoArrowArrayReaderInit(&reader), GEOARROW_OK); | ||
GeoArrowArrayReaderReset(&reader); | ||
} | ||
|
||
TEST(ArrayReaderTest, ArrayReaderTestVisitWKT) { | ||
struct ArrowSchema schema; | ||
struct ArrowArray array; | ||
enum GeoArrowType type = GEOARROW_TYPE_WKT; | ||
|
||
// Build the array for [POINT (30 10), null] | ||
ASSERT_EQ(GeoArrowSchemaInit(&schema, type), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayInitFromSchema(&array, &schema, nullptr), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayStartAppending(&array), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayAppendString(&array, ArrowCharView("POINT (30 10)")), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayAppendNull(&array, 1), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayFinishBuildingDefault(&array, nullptr), GEOARROW_OK); | ||
|
||
// Set the array view | ||
struct GeoArrowArrayView array_view; | ||
EXPECT_EQ(GeoArrowArrayViewInitFromType(&array_view, type), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayViewSetArray(&array_view, &array, nullptr), GEOARROW_OK); | ||
|
||
// Check its contents | ||
WKXTester tester; | ||
struct GeoArrowArrayReader reader; | ||
ASSERT_EQ(GeoArrowArrayReaderInit(&reader), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayReaderVisit(&reader, &array_view, 0, array.length, | ||
tester.WKTVisitor()), | ||
GEOARROW_OK); | ||
auto values = tester.WKTValues("<null value>"); | ||
ASSERT_EQ(values.size(), 2); | ||
EXPECT_EQ(values[0], "POINT (30 10)"); | ||
EXPECT_EQ(values[1], "<null value>"); | ||
|
||
schema.release(&schema); | ||
array.release(&array); | ||
GeoArrowArrayReaderReset(&reader); | ||
} | ||
|
||
TEST(ArrayReaderTest, ArrayReaderTestVisitWKB) { | ||
struct ArrowSchema schema; | ||
struct ArrowArray array; | ||
enum GeoArrowType type = GEOARROW_TYPE_WKB; | ||
|
||
std::basic_string<uint8_t> point({0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x3e, 0x40, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40}); | ||
struct ArrowBufferView point_view; | ||
point_view.data.as_uint8 = point.data(); | ||
point_view.size_bytes = point.size(); | ||
|
||
// Build the array for [POINT (30 10), null] | ||
ASSERT_EQ(GeoArrowSchemaInit(&schema, type), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayInitFromSchema(&array, &schema, nullptr), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayStartAppending(&array), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayAppendBytes(&array, point_view), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayAppendNull(&array, 1), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayFinishBuildingDefault(&array, nullptr), GEOARROW_OK); | ||
|
||
// Set the array view | ||
struct GeoArrowArrayView array_view; | ||
EXPECT_EQ(GeoArrowArrayViewInitFromType(&array_view, type), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayViewSetArray(&array_view, &array, nullptr), GEOARROW_OK); | ||
|
||
// Check its contents | ||
WKXTester tester; | ||
struct GeoArrowArrayReader reader; | ||
ASSERT_EQ(GeoArrowArrayReaderInit(&reader), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayReaderVisit(&reader, &array_view, 0, array.length, | ||
tester.WKTVisitor()), | ||
GEOARROW_OK); | ||
auto values = tester.WKTValues("<null value>"); | ||
ASSERT_EQ(values.size(), 2); | ||
EXPECT_EQ(values[0], "POINT (30 10)"); | ||
EXPECT_EQ(values[1], "<null value>"); | ||
|
||
schema.release(&schema); | ||
array.release(&array); | ||
GeoArrowArrayReaderReset(&reader); | ||
} | ||
|
||
TEST(ArrayReaderTest, ArrayReaderTestVisitGeoArrow) { | ||
struct ArrowSchema schema; | ||
struct ArrowArray array; | ||
enum GeoArrowType type = GEOARROW_TYPE_POINT; | ||
|
||
// Build the array for [POINT (30 10), null] | ||
ASSERT_EQ(GeoArrowSchemaInit(&schema, type), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayInitFromSchema(&array, &schema, nullptr), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayStartAppending(&array), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayAppendDouble(array.children[0], 30), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayAppendDouble(array.children[1], 10), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayFinishElement(&array), GEOARROW_OK); | ||
ASSERT_EQ(ArrowArrayAppendNull(&array, 1), GEOARROW_OK); | ||
|
||
ASSERT_EQ(ArrowArrayFinishBuildingDefault(&array, nullptr), GEOARROW_OK); | ||
|
||
// Set the array view | ||
struct GeoArrowArrayView array_view; | ||
EXPECT_EQ(GeoArrowArrayViewInitFromType(&array_view, type), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayViewSetArray(&array_view, &array, nullptr), GEOARROW_OK); | ||
|
||
// Check its contents | ||
WKXTester tester; | ||
struct GeoArrowArrayReader reader; | ||
ASSERT_EQ(GeoArrowArrayReaderInit(&reader), GEOARROW_OK); | ||
EXPECT_EQ(GeoArrowArrayReaderVisit(&reader, &array_view, 0, array.length, | ||
tester.WKTVisitor()), | ||
GEOARROW_OK); | ||
auto values = tester.WKTValues("<null value>"); | ||
ASSERT_EQ(values.size(), 2); | ||
EXPECT_EQ(values[0], "POINT (30 10)"); | ||
EXPECT_EQ(values[1], "<null value>"); | ||
|
||
schema.release(&schema); | ||
array.release(&array); | ||
GeoArrowArrayReaderReset(&reader); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.