-
Notifications
You must be signed in to change notification settings - Fork 1
fix: handle conversion of native geometry columns #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
be4c31d
1bdf551
1acc8e1
85f1ffa
0590f1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -185,6 +185,11 @@ function geomExpr(geoColumn, encoding) { | |
| const col = `"${geoColumn}"`; | ||
| // Lambda fragment: converts a point struct {x, y} to a WKT coordinate string "x y". | ||
| const ptToWkt = `pt -> CAST(pt.x AS VARCHAR) || ' ' || CAST(pt.y AS VARCHAR)`; | ||
| const ringToWkt = (inner) => | ||
| `ring -> '(' || array_to_string(list_transform(ring, ${inner}), ', ') || ')'`; | ||
| const wrapGeom = (wktExpr) => | ||
| `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText(${wktExpr}) ELSE NULL END`; | ||
| const arr = (expr, lambda) => `array_to_string(list_transform(${expr}, ${lambda}), ', ')`; | ||
|
Comment on lines
+188
to
+192
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this do?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an abstraction helper functions to avoid having to repeated the same code multiple times on the different cases of the native geoArrow. ringToWkt: Helper to transform list of points or lines into lambda strings that can be easily converted to duckDB's Geometry type.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. Any reason these are redefined on each function call instead of defining them once?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are referring to having them defined on both the db.js and converter.worker.js, frankly was planning to have a single buildGeomExpr function that can be invoked on either files to avoid multiple definition, but didn't follow through as was experience some errors after refactor and I decided to not waste more time on such.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I meant why you use inline functions. |
||
|
|
||
| switch (encoding?.toLowerCase()) { | ||
| case 'wkb': | ||
|
|
@@ -204,32 +209,28 @@ function geomExpr(geoColumn, encoding) { | |
|
|
||
| case 'linestring': | ||
| // LIST(STRUCT(x,y)) → LINESTRING(x1 y1, x2 y2, ...) | ||
| return `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText('LINESTRING(' || array_to_string(list_transform(${col}, ${ptToWkt}), ', ') || ')') ELSE NULL END`; | ||
| return wrapGeom(`'LINESTRING(' || ${arr(col, ptToWkt)} || ')'`); | ||
|
|
||
| case 'polygon': | ||
| // LIST(LIST(STRUCT(x,y))) → POLYGON((x1 y1, ...), (x2 y2, ...)) | ||
| return ( | ||
| `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText('POLYGON(' || array_to_string(list_transform(${col}, ` + | ||
| `ring -> '(' || array_to_string(list_transform(ring, ${ptToWkt}), ', ') || ')'), ', ') || ')') ELSE NULL END` | ||
| ); | ||
| return wrapGeom(`'POLYGON(' || ${arr(col, ringToWkt(ptToWkt))} || ')'`); | ||
|
|
||
| case 'multipoint': | ||
| // LIST(STRUCT(x,y)) → MULTIPOINT((x1 y1), (x2 y2), ...) | ||
| return `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText('MULTIPOINT(' || array_to_string(list_transform(${col}, pt -> '(' || CAST(pt.x AS VARCHAR) || ' ' || CAST(pt.y AS VARCHAR) || ')'), ', ') || ')') ELSE NULL END`; | ||
| return wrapGeom( | ||
| `'MULTIPOINT(' || ${arr(col, `pt -> '(' || CAST(pt.x AS VARCHAR) || ' ' || CAST(pt.y AS VARCHAR) || ')'`)} || ')'` | ||
| ); | ||
|
|
||
| case 'multilinestring': | ||
| // LIST(LIST(STRUCT(x,y))) → MULTILINESTRING((x1 y1, x2 y2), (...)) | ||
| return ( | ||
| `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText('MULTILINESTRING(' || array_to_string(list_transform(${col}, ` + | ||
| `line -> '(' || array_to_string(list_transform(line, ${ptToWkt}), ', ') || ')'), ', ') || ')') ELSE NULL END` | ||
| return wrapGeom( | ||
| `'MULTILINESTRING(' || ${arr(col, `line -> '(' || ${arr('line', ptToWkt)} || ')'`)} || ')'` | ||
| ); | ||
|
|
||
| case 'multipolygon': | ||
| // LIST(LIST(LIST(STRUCT(x,y)))) → MULTIPOLYGON(((x y, ...), (...)), ((...))) | ||
| return ( | ||
| `CASE WHEN ${col} IS NOT NULL AND len(${col}) > 0 THEN ST_GeomFromText('MULTIPOLYGON(' || array_to_string(list_transform(${col}, ` + | ||
| `poly -> '(' || array_to_string(list_transform(poly, ` + | ||
| `ring -> '(' || array_to_string(list_transform(ring, ${ptToWkt}), ', ') || ')'), ', ') || ')'), ', ') || ')') ELSE NULL END` | ||
| return wrapGeom( | ||
| `'MULTIPOLYGON(' || ${arr(col, `poly -> '(' || ${arr('poly', ringToWkt(ptToWkt))} || ')'`)} || ')'` | ||
| ); | ||
|
|
||
| default: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So was pass in "native geoArrow"? I thought it would be "point", "polygon", etc...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, isn't the list (points, linestrings, multipoints, etc )considered native geoArrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can update it. I just thought native geoArrow reflects the list that's not wkt or wkb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should reflect the API as is.