Skip to content

Commit a07dd8b

Browse files
committed
dtype-next based geotiff processing - a draft
1 parent f457303 commit a07dd8b

File tree

1 file changed

+43
-43
lines changed

1 file changed

+43
-43
lines changed

src/gis/geotiff.clj

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
[tech.v3.tensor.dimensions :as dims]
1717
[tech.v3.libs.buffered-image :as bufimg]
1818
[tablecloth.api :as tc]
19-
[clojure.java.io :as io]))
19+
[clojure.java.io :as io]
20+
[tech.v3.dataset.tensor :as ds-tensor]))
2021
;; # Cloud Optimized GeoTIFFs in JVM Clojure
2122
;; ## Motivation
2223
;; This document shows several different methods for handling COGs in JVM Clojure without
@@ -80,6 +81,8 @@
8081
{:images images
8182
:reader-format (.getFormatName reader)}))))
8283

84+
(require '[tech.v3.datatype :as dtype])
85+
8386
(defn get-pixel [^BufferedImage image x y]
8487
(let [raster (.getRaster image)
8588
;; Handle images with an arbitrary number of bands.
@@ -135,17 +138,19 @@
135138
;; For our purposes we can just add the tablecloth dependency and that will transitively
136139
;; bring along the rest of the stack.
137140

138-
(require '[tablecloth.api :as tc])
139-
140-
(repeatedly 5 #(double-array 2 3))
141-
141+
(require '[tablecloth.api :as tc]
142+
'[tech.v3.tensor :as tensor]
143+
'[tech.v3.dataset.tensor :as ds-tensor])
142144

143145

144146
(defn buffered-image->dataset [^BufferedImage img]
145147
(let [width (.getWidth img)
146148
height (.getHeight img)
147149
num-bands (.getNumBands (.getRaster img))
148-
150+
151+
;; The following will be easier after dtype-next's
152+
;; [#133](https://github.com/cnuernber/dtype-next/issues/133)
153+
;; is resolved.
149154
tensor (-> img
150155
dtype/->array-buffer
151156
;; height x width x bands
@@ -162,13 +167,22 @@
162167
(fn [y x] y)))
163168

164169
;; Build dataset
165-
ds-map (into {:x xs :y ys}
166-
(for [i (range num-bands)]
167-
[(keyword (str "band-" i))
168-
(dtype/as-reader
169-
(tensor i))]))]
170-
(tc/dataset ds-map)))
171-
170+
ds-map (into {:x xs :y ys}
171+
(for [i (range num-bands)]
172+
[(keyword (str "band-" i))
173+
(dtype/as-reader
174+
(tensor i))]))]
175+
(-> tensor
176+
(tensor/reshape [(* height width)
177+
num-bands])
178+
ds-tensor/tensor->dataset
179+
(tc/add-columns {:x xs
180+
:y ys})
181+
(tc/select-columns (concat [:x :y]
182+
(range num-bands)))
183+
(tc/rename-columns (into {}
184+
(for [i (range num-bands)]
185+
[i (keyword (str "band-" i))]))))))
172186

173187
(defonce ds (-> example-geotiff-medium
174188
:images
@@ -200,7 +214,6 @@
200214
(defonce ds-with-approx-dvi (add-dvi ds))
201215

202216
(require '[tech.v3.dataset :as ds]
203-
'[tech.v3.datatype :as dtype]
204217
'[tech.v3.datatype.statistics :as dstats])
205218
(import '[java.awt Color])
206219

@@ -223,35 +236,22 @@
223236
(add-approx-dvi-display ds-with-approx-dvi))
224237

225238
(defn dataset->image
226-
[dataset {:keys [r g b]}]
227-
(let [xs (ds/column dataset :x)
228-
ys (ds/column dataset :y)
229-
rs (ds/column dataset r)
230-
gs (ds/column dataset g)
231-
bs (ds/column dataset b)
232-
233-
max-x (-> xs last int)
234-
min-x (-> xs first int)
235-
max-y (-> ys last int)
236-
min-y (-> ys first int)
237-
238-
width (inc (- max-x min-x))
239-
height (inc (- max-y min-y))
240-
241-
;; Create the image
242-
img (BufferedImage. width height BufferedImage/TYPE_INT_RGB)]
243-
244-
;; Set pixels
245-
(dotimes [i (ds/row-count dataset)]
246-
(let [x (- (int (dtype/get-value xs i)) min-x)
247-
y (- (int (dtype/get-value ys i)) min-y)
248-
r (int (dtype/get-value rs i))
249-
g (int (dtype/get-value gs i))
250-
b (int (dtype/get-value bs i))
251-
color (Color. r g b)]
252-
(.setRGB img x y (.getRGB color))))
253-
254-
img))
239+
[dataset {:as columns-mapping
240+
:keys [r g b]}]
241+
(let [height (->> dataset
242+
:y
243+
((juxt dstats/max dstats/min))
244+
(apply -))
245+
width (->> dataset
246+
:x
247+
((juxt dstats/max dstats/min))
248+
(apply -))]
249+
(-> columns-mapping
250+
(update-vals dataset)
251+
tc/dataset
252+
ds-tensor/dataset->tensor
253+
(tensor/reshape [height width 3])
254+
bufimg/tensor->image)))
255255

256256
(dataset->image ds-with-dvi-display
257257
{:r :dvi-display

0 commit comments

Comments
 (0)