test(integration): geometry results in the parity harness; RS_WorldToRasterCoord + RS_RasterToWorldCoord catalogs - #1264
Conversation
| # (transport-only, like decode_raster_result's RS_AsGeoTiff) and | ||
| # re-tag the bytes as geoarrow.wkb — geometry results then render | ||
| # WKT through the same geoarrow path as every other engine. | ||
| import geoarrow.pyarrow as ga |
There was a problem hiding this comment.
This one can be a module level import (since pyarrow already is)
Also, isn't there already a "to geoarrow"? I PRed one into Sedona a few years ago but maybe it's gone now.
Review follow-up: sedona.spark.geoarrow.dataframe_to_arrow already does the EWKB conversion and geoarrow tagging, so the hand-rolled ST_AsBinary + re-tag path (and its geoarrow.pyarrow import) goes away. The positional rename stays, now wrapped around the utility: dataframe_to_arrow resolves columns by name and fails on Spark's dotted generated names (apache/sedona#3351).
|
Follow-up pushed (f7ebe5c): the hand-rolled ST_AsBinary + re-tag path is gone in favor of One wrinkle: |
Unblocks geometry-returning raster functions in the spark-parity suite and uses that to catalog the
RS_WorldToRasterCoord/RS_RasterToWorldCoordcombined forms — including the missing point-geometry overload.Harness: geometry results (first commit)
Probing showed the two sides fail asymmetrically:
geoarrow.wkbandresult_to_tuplesalready renders them as WKT.DataFrame.toArrow()ships aGeometryUDTcolumn as the UDT's internal serialization bytes — not ISO WKB — which the tuple path then tried to cast to string ("Invalid UTF8 payload").SedonaSpark.result_to_tablenow converts geometry columns to WKB in the JVM (ST_AsBinary, transport-only — the same patterndecode_raster_resultuses withRS_AsGeoTiff; the shared test SQL stays RS-only) and re-tags the bytes asgeoarrow.wkb, so both engines render WKT through the same geoarrow formatter. Columns are renamed positionally before the select because Spark's generated names (rs_worldtorastercoord(rast, 104.0, 494.0)) contain dots that every name-based lookup re-parses as a nested path; the original names are restored on the Arrow table.Everything downstream (
result_to_tuples,assert_result, WKTexpected=anchors,compare()) works unchanged. Full suite on this branch:174 passed, 84 xfailed— main's counts plus exactly the 7 new xfails.RS_WorldToRasterCoord (second commit)
All probed, every case an xfail stating both observed behaviors:
POINT (0 0)from SedonaDB andPOINT (1 1)from Sedona Spark; interior points likewise one pixel apart.POINT (-5 -1)); Spark floors before its 1-based shift (POINT (-4 -1)) — the rows agree by coincidence, the columns differ. A positive-fraction probe ((105, 493) → 2 vs 3) confirms the rules are truncation vs floor+1, not something else.RS_WorldToRasterCoord(raster, point)raises "No kernel matching arguments" on SedonaDB; Spark accepts it. The xfail notes RS_RasterToWorldCoord*/RS_WorldToRasterCoord* are 0-based; Sedona Spark, PostGIS, and RS_PixelAs* are 1-based #1235 still applies once the overload exists.RS_RasterToWorldCoord
The input side of #1235:
(1, 1)answersPOINT (102 497)from SedonaDB (0-based input) andPOINT (100 500)— the origin corner — from Spark (1-based input).Follow-ups this unblocks
The remaining geometry-returning functions can now get parity files the same way: RS_Envelope, RS_ConvexHull, RS_PixelAsPoint / RS_PixelAsCentroid / RS_PixelAsPolygon. (Item-level-CRS geometry outputs may need another look — these fixtures are CRS-less.) The
test_rs_worldtorastercoordx/ydocstrings still say the combined form is "deferred"; updating that line is left out here because #1262 touches the same sentence — whichever lands second gets the one-line fix.