GeoJSON I/O Support #164
Replies: 7 comments
-
Good idea! Let's discuss it here. There was some functionality implemented in TC at the beginning moved later to TMD (filling missing values, pretty printing numbers, and some more). |
Beta Was this translation helpful? Give feedback.
-
I think @willcohen has been exploring related questions and may comment about it (possibly available in Zulip if not here). We described some related usage patterns in this tutorial draft. |
Beta Was this translation helpful? Give feedback.
-
One thing we can learn from the tutorial above, is that sometimes geometries are worth representing as jts objects (useful for coordinate transformations, indexing, and other operations), and sometimes as plain EDN (useful for visualization, for example). |
Beta Was this translation helpful? Give feedback.
-
related Zulip thread: |
Beta Was this translation helpful? Give feedback.
-
I am disinclined to introduce a dependency on JTS or any other spatial data structure library for the purposes of any code that would be contributed to With this in mind, here's the sketch of I/O as I see it: Input(require '[tablecloth.api :as tc] '[charred.api :as json])
(defn geojson->ds
"Reads a GeoJSON file from the given input path and converts it to a dataset.
Derives column data from the \"properties\" entry of each Feature.
Geometry is stored in a :geometry column."
[input opts]
(let [geojson-data (json/read-json input)]
(tc/dataset (map (fn feature->map [{:keys [geometry properties]}]
(assoc properties :geometry geometry))
(geojson-data :features))))) Output(defn ds->geojson
"Writes the given dataset to GeoJSON at the given output location.
By default, assumes that the geometry is in a column called \"geometry\",
and is already in the Clojure equivalent format of a RFC7946§3.1 Geometry.
Otherwise, calls geometry-fn on the geometry to convert it to this format."
[ds output
{:keys [geometry-fn geometry-col]
:or {geometry-fn identity geometry-col "geometry"}}]
(let [feature-data
(map (fn map->feature [r]
(let [geom (r geometry-col)]
; disregard, a null geometry is a valid GeoJSON feature per RFC7946§3.2
; (if (nil? geom)
; (throw (ex-info "Non-nil geometry column must be specified"
; {:column-names (tc/column-names ds)
; :geometry-column geometry-col})))
{:type "Feature"
:geometry (geometry-fn geom)
:properties (dissoc r geometry-col)}))
(tc/rows ds :as-maps))])
(json/write-json output {:type "FeatureCollection" :features feature-data})
output) The general idea here is that conversion to and from spatial types like those provided by JTS can come after input or before output. If you are working with libraries like JTS and I think keeping the scope small for this contribution makes sense - what do you think @daslu @genmeblog? |
Beta Was this translation helpful? Give feedback.
-
Also, for reference, the GeoJSON spec: https://www.rfc-editor.org/rfc/rfc7946 |
Beta Was this translation helpful? Give feedback.
-
That is so nice. If we are talking about an addition to Tablecloth itself, this is probably the kind of functions that would make sense. In my habits and use cases, JTS would often be preferable, and the only case I am aware of where plain Clojure structures would be needed is when we need to generate GeoJSON for another program that expects it (e.g., for data visualization). It'd be enlightening to hear more about your use cases. A few minor thoughts:
|
Beta Was this translation helpful? Give feedback.
-
Hi! I work with a lot of spatial data in tablecloth and frequently find myself wishing for a uniform and standardized approach for reading and writing GeoJSON files rather than reimplementing it in an ad-hoc way for each project.
I would be more than willing to contribute code for a PR, and am happy to sketch out my ideas further before I get started.
I ask here about this feature before diving in because I don't know whether it should be a part of tablecloth, an upstream contribution to tech.ml.dataset, or even part of a helper library like tcutils.
Any thoughts on where it makes the most sense for GeoJSON support to live, or any other feedback, are most welcome. Thanks for your time!
Beta Was this translation helpful? Give feedback.
All reactions