OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GDALTableFunctions.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  */
4 
5 #pragma once
6 
7 #ifndef __CUDACC__
8 
11 
12 #include <algorithm>
13 #include <array>
14 
15 #include "GDALTableFunctions.hpp"
17 
18 #include "Geospatial/Compression.h"
19 #include "Geospatial/GDAL.h"
20 #include "Shared/scope.h"
21 
22 #include "cpl_conv.h"
23 #include "cpl_string.h"
24 #include "gdal.h"
25 #include "gdal_alg.h"
26 #include "gdal_version.h"
27 #include "ogr_api.h"
28 #include "ogr_srs_api.h"
29 
30 #include "ogrsf_frmts.h"
31 
32 namespace GDALTableFunctions {
33 
34 //
35 // general implementation
36 //
37 
38 template <typename TV, typename TG>
40  const int32_t raster_width,
41  const int32_t raster_height,
42  const double affine_transform[6],
43  const TV* values,
44  const TV contour_interval,
45  const TV contour_offset,
46  Column<TG>& contour_features,
47  Column<TV>& contour_values) {
48  // supported types
49  static_assert(std::is_same_v<float, TV> || std::is_same_v<double, TV>);
50  static_assert(std::is_same_v<GeoLineString, TG> || std::is_same_v<GeoPolygon, TG>);
51 
52  // value type
53  std::string value_type_str;
54  int pixel_offset{};
55  double null_value;
56  if constexpr (std::is_same_v<float, TV>) {
57  value_type_str = "Float32";
58  pixel_offset = sizeof(float);
59  null_value = static_cast<double>(std::numeric_limits<float>::min());
60  } else if constexpr (std::is_same_v<double, TV>) {
61  value_type_str = "Float64";
62  pixel_offset = sizeof(double);
63  null_value = std::numeric_limits<double>::min();
64  }
65  CHECK(value_type_str.length());
66 
67  auto const num_values = raster_width * raster_height;
68  VLOG(2) << "tf_raster_contour: Final raster data has " << num_values << " values, min "
69  << *std::min_element(values, values + num_values) << ", max "
70  << *std::max_element(values, values + num_values);
71 
72  // geo type
73  constexpr bool is_polygons = std::is_same_v<GeoPolygon, TG>;
74 
75  // construct in-memory-raster string
76  std::stringstream mem_ss;
77  mem_ss << "MEM:::DATAPOINTER=" << std::hex << values << std::dec
78  << ",PIXELS=" << raster_width << ",LINES=" << raster_height
79  << ",BANDS=1,DATATYPE=" << value_type_str << ",PIXELOFFSET=" << pixel_offset
80  << ",GEOTRANSFORM=" << affine_transform[0] << "/" << affine_transform[1] << "/"
81  << affine_transform[2] << "/" << affine_transform[3] << "/"
82  << affine_transform[4] << "/" << affine_transform[5];
83  std::string mem_str = mem_ss.str();
84 
85  // lazy init GDAL
87 
88  // things to clean up
89  char** options = nullptr;
90  GDALDatasetH raster_ds = nullptr;
91  GDALDataset* vector_ds = nullptr;
92 
93  // auto clean-up on any exit
94  ScopeGuard cleanup = [options, raster_ds, vector_ds]() {
95  if (options) {
96  CSLDestroy(options);
97  }
98  if (raster_ds) {
99  GDALClose(raster_ds);
100  }
101  if (vector_ds) {
102  GDALClose(vector_ds);
103  }
104  };
105 
106  // input dataset
107  raster_ds = GDALOpen(mem_str.c_str(), GA_ReadOnly);
108  CHECK(raster_ds);
109 
110  // input band
111  auto raster_band = GDALGetRasterBand(raster_ds, 1);
112  CHECK(raster_band);
113 
114  // output driver
115  auto* memory_driver = GetGDALDriverManager()->GetDriverByName("Memory");
116  CHECK(memory_driver);
117 
118  // output dataset
119  vector_ds = memory_driver->Create("contours", 0, 0, 0, GDT_Unknown, NULL);
120  CHECK(vector_ds);
121 
122  // output spatial reference
123  OGRSpatialReference spatial_reference;
124  spatial_reference.importFromEPSG(4326);
125  spatial_reference.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
126 
127  // output layer
128  auto* vector_layer =
129  vector_ds->CreateLayer("lines", &spatial_reference, wkbLineString, NULL);
130  CHECK(vector_layer);
131 
132  // contour values fields
133  int contour_min_field_index{-1};
134  int contour_max_field_index{-1};
135  int contour_val_field_index{-1};
136  if (is_polygons) {
137  OGRFieldDefn contour_min_field_defn("contour_min", OFTReal);
138  vector_layer->CreateField(&contour_min_field_defn);
139  contour_min_field_index = vector_layer->FindFieldIndex("contour_min", TRUE);
140  CHECK_GE(contour_min_field_index, 0);
141  OGRFieldDefn contour_max_field_defn("contour_max", OFTReal);
142  vector_layer->CreateField(&contour_max_field_defn);
143  contour_max_field_index = vector_layer->FindFieldIndex("contour_max", TRUE);
144  CHECK_GE(contour_max_field_index, 0);
145  } else {
146  OGRFieldDefn contour_val_field_defn("contour_val", OFTReal);
147  vector_layer->CreateField(&contour_val_field_defn);
148  contour_val_field_index = vector_layer->FindFieldIndex("contour_val", TRUE);
149  CHECK_GE(contour_val_field_index, 0);
150  }
151 
152  // options
153  if constexpr (is_polygons) {
154  options = CSLAppendPrintf(options, "ELEV_FIELD_MIN=%d", contour_min_field_index);
155  options = CSLAppendPrintf(options, "ELEV_FIELD_MAX=%d", contour_max_field_index);
156  } else {
157  options = CSLAppendPrintf(options, "ELEV_FIELD=%d", contour_val_field_index);
158  }
159  options =
160  CSLAppendPrintf(options, "LEVEL_INTERVAL=%f", static_cast<float>(contour_interval));
161  options = CSLAppendPrintf(options, "LEVEL_BASE=%f", static_cast<float>(contour_offset));
162  options = CSLAppendPrintf(options, "NODATA=%.19g", null_value);
163  if constexpr (is_polygons) {
164  options = CSLAppendPrintf(options, "POLYGONIZE=YES");
165  }
166 
167  // generate contour
168  auto result =
169  GDALContourGenerateEx(raster_band, vector_layer, options, nullptr, nullptr);
170  if (result != CE_None) {
171  return mgr.ERROR_MESSAGE("Contour generation failed");
172  }
173 
174  // reset the output dataset
175  vector_ds->ResetReading();
176 
177  // get feature count
178  auto const num_features = static_cast<int32_t>(vector_layer->GetFeatureCount());
179 
180  VLOG(1) << "tf_raster_contour: GDAL generated " << num_features << " features";
181 
182  // did we get any features?
183  if (num_features == 0) {
186  mgr.set_output_row_size(0);
187  return 0;
188  }
189 
190  // first pass, accumulate total sizes
191 
192  int64_t total_num_points{};
193  int32_t num_output_features{};
194 
195  vector_layer->ResetReading();
196 
197  // iterate features
198  for (int32_t i = 0; i < num_features; i++) {
199  // get feature
200  Geospatial::GDAL::FeatureUqPtr feature(vector_layer->GetNextFeature());
201 
202  // get geometry
203  auto const* geometry = feature->GetGeometryRef();
204  CHECK(geometry);
205 
206  // get geometry type
207  auto const geometry_wkb_type = wkbFlatten(geometry->getGeometryType());
208 
209  if constexpr (is_polygons) {
210  // check type
211  if (geometry_wkb_type != wkbMultiPolygon) {
212  return mgr.ERROR_MESSAGE("Geometry WKB type is not MultiPolygon");
213  }
214 
215  // it's a polygon
216  auto const* multipolygon_geometry = dynamic_cast<const OGRMultiPolygon*>(geometry);
217  CHECK(multipolygon_geometry);
218 
219  // count the points from all rings of all polygons
220  auto const num_geometries = multipolygon_geometry->getNumGeometries();
221  for (auto p = 0; p < num_geometries; p++) {
222  // get this polygon
223  auto const* polygon_geometry =
224  dynamic_cast<const OGRPolygon*>(multipolygon_geometry->getGeometryRef(p));
225  CHECK(polygon_geometry);
226 
227  // count points in exterior ring
228  auto const* exterior_ring = polygon_geometry->getExteriorRing();
229  CHECK(exterior_ring);
230  total_num_points += exterior_ring->getNumPoints();
231 
232  // count points in interior rings
233  for (auto r = 0; r < polygon_geometry->getNumInteriorRings(); r++) {
234  auto const* interior_ring = polygon_geometry->getInteriorRing(r);
235  CHECK(interior_ring);
236  total_num_points += interior_ring->getNumPoints();
237  }
238 
239  // each polygon is an output feature
240  num_output_features++;
241  }
242  } else {
243  // check type
244  if (geometry_wkb_type != wkbLineString) {
245  return mgr.ERROR_MESSAGE("Geometry WKB type is not Linestring");
246  }
247 
248  // it's a linestring
249  auto const* linestring_geometry = dynamic_cast<const OGRLineString*>(geometry);
250  CHECK(linestring_geometry);
251 
252  // accumulate these points
253  total_num_points += linestring_geometry->getNumPoints();
254 
255  // one output feature
256  num_output_features++;
257  }
258  }
259 
260  VLOG(1) << "tf_raster_contour: Total points " << total_num_points;
261 
262  // size outputs
263  mgr.set_output_array_values_total_number(0, total_num_points * 2);
264  mgr.set_output_array_values_total_number(1, num_output_features);
265  mgr.set_output_row_size(num_output_features);
266 
267  // second pass, build output features
268 
269  int64_t output_feature_index{};
270 
271  vector_layer->ResetReading();
272 
273  // iterate features
274  for (int32_t i = 0; i < num_features; i++) {
275  // get feature
276  Geospatial::GDAL::FeatureUqPtr feature(vector_layer->GetNextFeature());
277 
278  // get geometry
279  auto const* geometry = feature->GetGeometryRef();
280  CHECK(geometry);
281 
282  if constexpr (is_polygons) {
283  // it's a polygon
284  auto const* multipolygon_geometry = dynamic_cast<const OGRMultiPolygon*>(geometry);
285  CHECK(multipolygon_geometry);
286 
287  // process each polygon as an output feature
288  auto const num_geometries = multipolygon_geometry->getNumGeometries();
289  for (auto p = 0; p < num_geometries; p++) {
290  // get this polygon
291  auto const* polygon_geometry =
292  dynamic_cast<const OGRPolygon*>(multipolygon_geometry->getGeometryRef(p));
293  CHECK(polygon_geometry);
294 
295  // gather the points from all rings
296  std::vector<std::vector<double>> coords;
297  {
298  std::vector<double> ring_coords;
299  auto const* exterior_ring = polygon_geometry->getExteriorRing();
300  CHECK(exterior_ring);
301  for (int j = 0; j < exterior_ring->getNumPoints(); j++) {
302  OGRPoint point;
303  exterior_ring->getPoint(j, &point);
304  ring_coords.push_back(point.getX());
305  ring_coords.push_back(point.getY());
306  }
307  coords.push_back(ring_coords);
308  }
309  for (auto r = 0; r < polygon_geometry->getNumInteriorRings(); r++) {
310  auto const* interior_ring = polygon_geometry->getInteriorRing(r);
311  CHECK(interior_ring);
312  std::vector<double> ring_coords;
313  for (int j = 0; j < interior_ring->getNumPoints(); j++) {
314  OGRPoint point;
315  interior_ring->getPoint(j, &point);
316  ring_coords.push_back(point.getX());
317  ring_coords.push_back(point.getY());
318  }
319  coords.push_back(ring_coords);
320  }
321 
322  // set output contour polygon
323  auto status = contour_features[output_feature_index].fromCoords(coords);
324  if (status != FlatBufferManager::Status::Success) {
325  return mgr.ERROR_MESSAGE("fromCoords failed: " + ::toString(status));
326  }
327 
328  // set output contour value
329  // min value may be zero; if so, replace with (max - interval)
330  // that will still be valid in the cases of max == interval or offset != 0
331  auto const contour_min =
332  static_cast<TV>(feature->GetFieldAsDouble(contour_min_field_index));
333  auto const contour_max =
334  static_cast<TV>(feature->GetFieldAsDouble(contour_max_field_index));
335  contour_values[output_feature_index] = (contour_min == static_cast<TV>(0))
336  ? (contour_max - contour_interval)
337  : contour_min;
338 
339  // done
340  output_feature_index++;
341  }
342  } else {
343  // it's a linestring
344  auto const* linestring_geometry = dynamic_cast<const OGRLineString*>(geometry);
345  CHECK(linestring_geometry);
346 
347  // unpack linestring
348  std::vector<double> coords;
349  for (int j = 0; j < linestring_geometry->getNumPoints(); j++) {
350  OGRPoint point;
351  linestring_geometry->getPoint(j, &point);
352  coords.push_back(point.getX());
353  coords.push_back(point.getY());
354  }
355 
356  // set output contour linestring
357  contour_features[output_feature_index].fromCoords(coords);
358 
359  // set output contour value
360  contour_values[output_feature_index] =
361  static_cast<TV>(feature->GetFieldAsDouble(contour_val_field_index));
362 
363  // done
364  output_feature_index++;
365  }
366  }
367 
368  VLOG(1) << "tf_raster_contour: Output " << num_features << " features";
369 
370  // done
371  return num_output_features;
372 }
373 
374 //
375 // rasterize implementation
376 //
377 
378 template <typename TLL, typename TV, typename TG>
380  const Column<TLL>& lon,
381  const Column<TLL>& lat,
382  const Column<TV>& values,
383  const TextEncodingNone& agg_type,
384  const float bin_dim_meters,
385  const int32_t neighborhood_fill_radius,
386  const bool fill_only_nulls,
387  const TextEncodingNone& fill_agg_type,
388  const bool flip_latitude,
389  const TV contour_interval,
390  const TV contour_offset,
391  Column<TG>& contour_features,
392  Column<TV>& contour_values) {
393  // enforce parser validation
394  CHECK_GT(bin_dim_meters, 0.0f);
395  CHECK_GE(neighborhood_fill_radius, 0);
396  CHECK_GT(contour_interval, static_cast<TV>(0));
397 
398  // validate the rest
399  auto const raster_agg_type = get_raster_agg_type(agg_type, false);
400  if (raster_agg_type == RasterAggType::INVALID) {
401  auto const error_msg = "Invalid Raster Aggregate Type: " + agg_type.getString();
402  return mgr.ERROR_MESSAGE(error_msg);
403  }
404  auto const raster_fill_agg_type = get_raster_agg_type(fill_agg_type, true);
405  if (raster_fill_agg_type == RasterAggType::INVALID) {
406  auto const error_msg =
407  "Invalid Raster Fill Aggregate Type: " + fill_agg_type.getString();
408  return mgr.ERROR_MESSAGE(error_msg);
409  }
410 
411  VLOG(2) << "tf_raster_contour: Input raster data has " << values.size()
412  << " values, min "
413  << *std::min_element(values.getPtr(), values.getPtr() + values.size())
414  << ", max "
415  << *std::max_element(values.getPtr(), values.getPtr() + values.size());
416 
417  std::unique_ptr<GeoRaster<TLL, TV>> geo_raster;
418  try {
419  geo_raster = std::make_unique<GeoRaster<TLL, TV>>(
420  lon, lat, values, raster_agg_type, bin_dim_meters, true, true);
421  CHECK(geo_raster);
422  } catch (std::runtime_error& e) {
423  // the only exception this variant of GeoRaster constructor will throw
424  // is when num_x_bins_ < 1 || num_y_bins_ < 1, which is handled below
425  geo_raster = nullptr;
426  }
427 
428  // GeoRaster constructor can still return zero size if no input
429  if (!geo_raster || geo_raster->num_x_bins_ < 1 || geo_raster->num_y_bins_ < 1) {
430  VLOG(1) << "tf_raster_contour: No input raster data. Cannot compute contours.";
433  mgr.set_output_row_size(0);
434  return 0;
435  }
436 
437  if (neighborhood_fill_radius > 0) {
438  geo_raster->fill_bins_from_neighbors(
439  neighborhood_fill_radius, fill_only_nulls, raster_fill_agg_type);
440  }
441 
442  auto const raster_width = static_cast<int32_t>(geo_raster->num_x_bins_);
443  auto const raster_height = static_cast<int32_t>(geo_raster->num_y_bins_);
444  auto const lon_min = static_cast<double>(geo_raster->x_min_);
445  auto const lat_min = static_cast<double>(geo_raster->y_min_);
446  auto const lon_bin_scale = static_cast<double>(geo_raster->x_scale_input_to_bin_);
447  auto const lat_bin_scale = static_cast<double>(geo_raster->y_scale_input_to_bin_);
448 
449  // this should never happen, but make it an exception anyway
450  if (lon_bin_scale <= 0.0 || lat_bin_scale <= 0.0) {
451  return mgr.ERROR_MESSAGE("Invalid input raster scale. Cannot compute contours.");
452  }
453 
454  // build affine transform matrix
455  std::array<double, 6> affine_transform;
456  affine_transform[0] = lon_min;
457  affine_transform[1] = 1.0 / lon_bin_scale;
458  affine_transform[2] = 0.0;
459  affine_transform[4] = 0.0;
460  if (flip_latitude) {
461  affine_transform[3] = lat_min + (double(raster_height) / lat_bin_scale);
462  affine_transform[5] = -1.0 / lat_bin_scale;
463  } else {
464  affine_transform[3] = lat_min;
465  affine_transform[5] = 1.0 / lat_bin_scale;
466  }
467 
468  // do it
469  return tf_raster_contour_impl<TV, TG>(mgr,
470  raster_width,
471  raster_height,
472  affine_transform.data(),
473  geo_raster->z_.data(),
474  contour_interval,
475  contour_offset,
476  contour_features,
477  contour_values);
478 }
479 
480 //
481 // direct implementation
482 //
483 
484 template <typename TLL, typename TV, typename TG>
486  const Column<TLL>& lon,
487  const Column<TLL>& lat,
488  const Column<TV>& values,
489  const int32_t raster_width,
490  const int32_t raster_height,
491  const bool flip_latitude,
492  const TV contour_interval,
493  const TV contour_offset,
494  Column<TG>& contour_features,
495  Column<TV>& contour_values) {
496  // enforce parser validation
497  CHECK_GE(raster_width, 1u);
498  CHECK_GE(raster_height, 1u);
499  CHECK_GT(contour_interval, static_cast<TV>(0));
500 
501  // expected pixel counts
502  auto const num_pixels =
503  static_cast<int64_t>(raster_width) * static_cast<int64_t>(raster_height);
504  if (lon.size() != num_pixels || lat.size() != num_pixels ||
505  values.size() != num_pixels) {
506  return mgr.ERROR_MESSAGE("Raster lon/lat/values size mismatch");
507  }
508 
509  // find lon/lat range
510  double lon_min = double(*std::min_element(lon.getPtr(), lon.getPtr() + num_pixels));
511  double lon_max = double(*std::max_element(lon.getPtr(), lon.getPtr() + num_pixels));
512  double lat_min = double(*std::min_element(lat.getPtr(), lat.getPtr() + num_pixels));
513  double lat_max = double(*std::max_element(lat.getPtr(), lat.getPtr() + num_pixels));
514 
515  // build affine transform matrix
516  // @TODO(se) verify the -1s
517  std::array<double, 6> affine_transform;
518  affine_transform[0] = lon_min;
519  affine_transform[1] = (lon_max - lon_min) / double(raster_width - 1);
520  affine_transform[2] = 0.0;
521  affine_transform[4] = 0.0;
522  if (flip_latitude) {
523  affine_transform[3] = lat_max;
524  affine_transform[5] = (lat_min - lat_max) / double(raster_height - 1);
525  } else {
526  affine_transform[3] = lat_min;
527  affine_transform[5] = (lat_max - lat_min) / double(raster_height - 1);
528  }
529 
530  // do it
531  return tf_raster_contour_impl<TV, TG>(mgr,
532  raster_width,
533  raster_height,
534  affine_transform.data(),
535  values.getPtr(),
536  contour_interval,
537  contour_offset,
538  contour_features,
539  contour_values);
540 }
541 
542 } // namespace GDALTableFunctions
543 
544 //
545 // public TFs
546 //
547 
548 // clang-format off
549 /*
550  UDTF: tf_raster_contour_lines__cpu_template(TableFunctionManager mgr,
551  Cursor<Column<TLL> lon, Column<TLL> lat, Column<TV> values> raster,
552  TextEncodingNone agg_type, float bin_dim_meters | require="bin_dim_meters > 0.0",
553  int32_t neighborhood_fill_radius | require="neighborhood_fill_radius >= 0",
554  bool fill_only_nulls, TextEncodingNone fill_agg_type, bool flip_latitude, TV contour_interval | require="contour_interval > 0.0",
555  TV contour_offset) -> Column<GeoLineString> contour_lines, Column<TV> contour_values,
556  TLL=[double], TV=[double]
557  */
558 // clang-format on
559 
560 template <typename TLL, typename TV>
561 TEMPLATE_NOINLINE int32_t
563  const Column<TLL>& lon,
564  const Column<TLL>& lat,
565  const Column<TV>& values,
566  const TextEncodingNone& agg_type,
567  const float bin_dim_meters,
568  const int32_t neighborhood_fill_radius,
569  const bool fill_only_nulls,
570  const TextEncodingNone& fill_agg_type,
571  const bool flip_latitude,
572  const TV contour_interval,
573  const TV contour_offset,
574  Column<GeoLineString>& contour_lines,
575  Column<TV>& contour_values) {
576  return GDALTableFunctions::tf_raster_contour_rasterize_impl<TLL, TV, GeoLineString>(
577  mgr,
578  lon,
579  lat,
580  values,
581  agg_type,
582  bin_dim_meters,
583  neighborhood_fill_radius,
584  fill_only_nulls,
585  fill_agg_type,
586  flip_latitude,
587  contour_interval,
588  contour_offset,
589  contour_lines,
590  contour_values);
591 }
592 
593 // clang-format off
594 /*
595  UDTF: tf_raster_contour_lines__cpu_template(TableFunctionManager mgr,
596  Cursor<Column<TLL> lon, Column<TLL> lat, Column<TV> values> raster,
597  int32_t raster_width | require="raster_width > 0", int32_t raster_height | require="raster_height > 0",
598  bool flip_latitude, TV contour_interval | require="contour_interval > 0.0",
599  TV contour_offset) -> Column<GeoLineString> contour_lines, Column<TV> contour_values,
600  TLL=[double], TV=[double]
601  */
602 // clang-format on
603 
604 template <typename TLL, typename TV>
605 TEMPLATE_NOINLINE int32_t
607  const Column<TLL>& lon,
608  const Column<TLL>& lat,
609  const Column<TV>& values,
610  const int32_t raster_width,
611  const int32_t raster_height,
612  const bool flip_latitude,
613  const TV contour_interval,
614  const TV contour_offset,
615  Column<GeoLineString>& contour_lines,
616  Column<TV>& contour_values) {
617  return GDALTableFunctions::tf_raster_contour_direct_impl<TLL, TV, GeoLineString>(
618  mgr,
619  lon,
620  lat,
621  values,
622  raster_width,
623  raster_height,
624  flip_latitude,
625  contour_interval,
626  contour_offset,
627  contour_lines,
628  contour_values);
629 }
630 
631 // clang-format off
632 /*
633  UDTF: tf_raster_contour_polygons__cpu_template(TableFunctionManager mgr,
634  Cursor<Column<TLL> lon, Column<TLL> lat, Column<TV> values> raster,
635  TextEncodingNone agg_type, float bin_dim_meters | require="bin_dim_meters > 0.0",
636  int32_t neighborhood_fill_radius | require="neighborhood_fill_radius >= 0", bool fill_only_nulls, TextEncodingNone fill_agg_type,
637  bool flip_latitude, TV contour_interval | require="contour_interval > 0.0",
638  TV contour_offset) -> Column<GeoPolygon> contour_polygons, Column<TV> contour_values,
639  TLL=[double], TV=[double]
640  */
641 // clang-format on
642 
643 template <typename TLL, typename TV>
644 TEMPLATE_NOINLINE int32_t
646  const Column<TLL>& lon,
647  const Column<TLL>& lat,
648  const Column<TV>& values,
649  const TextEncodingNone& agg_type,
650  const float bin_dim_meters,
651  const int32_t neighborhood_fill_radius,
652  const bool fill_only_nulls,
653  const TextEncodingNone& fill_agg_type,
654  const bool flip_latitude,
655  const TV contour_interval,
656  const TV contour_offset,
657  Column<GeoPolygon>& contour_polygons,
658  Column<TV>& contour_values) {
659  return GDALTableFunctions::tf_raster_contour_rasterize_impl<TLL, TV, GeoPolygon>(
660  mgr,
661  lon,
662  lat,
663  values,
664  agg_type,
665  bin_dim_meters,
666  neighborhood_fill_radius,
667  fill_only_nulls,
668  fill_agg_type,
669  flip_latitude,
670  contour_interval,
671  contour_offset,
672  contour_polygons,
673  contour_values);
674 }
675 
676 // clang-format off
677 /*
678  UDTF: tf_raster_contour_polygons__cpu_template(TableFunctionManager mgr,
679  Cursor<Column<TLL> lon, Column<TLL> lat, Column<TV> values> raster,
680  int32_t raster_width | require="raster_width > 0", int32_t raster_height | require="raster_height > 0",
681  bool flip_latitude, TV contour_interval | require="contour_interval > 0.0",
682  TV contour_offset) -> Column<GeoPolygon> contour_polygons, Column<TV> contour_values,
683  TLL=[double], TV=[double]
684  */
685 // clang-format on
686 
687 template <typename TLL, typename TV>
688 TEMPLATE_NOINLINE int32_t
690  const Column<TLL>& lon,
691  const Column<TLL>& lat,
692  const Column<TV>& values,
693  const int32_t raster_width,
694  const int32_t raster_height,
695  const bool flip_latitude,
696  const TV contour_interval,
697  const TV contour_offset,
698  Column<GeoPolygon>& contour_polygons,
699  Column<TV>& contour_values) {
700  return GDALTableFunctions::tf_raster_contour_direct_impl<TLL, TV, GeoPolygon>(
701  mgr,
702  lon,
703  lat,
704  values,
705  raster_width,
706  raster_height,
707  flip_latitude,
708  contour_interval,
709  contour_offset,
710  contour_polygons,
711  contour_values);
712 }
713 
714 #endif // __CUDACC__
void set_output_row_size(int64_t num_rows)
Definition: heavydbTypes.h:373
TEMPLATE_NOINLINE int32_t tf_raster_contour_polygons__cpu_template(TableFunctionManager &mgr, const Column< TLL > &lon, const Column< TLL > &lat, const Column< TV > &values, const TextEncodingNone &agg_type, const float bin_dim_meters, const int32_t neighborhood_fill_radius, const bool fill_only_nulls, const TextEncodingNone &fill_agg_type, const bool flip_latitude, const TV contour_interval, const TV contour_offset, Column< GeoPolygon > &contour_polygons, Column< TV > &contour_values)
void set_output_array_values_total_number(int32_t index, int64_t output_array_values_total_number)
Definition: heavydbTypes.h:361
std::string getString() const
Definition: heavydbTypes.h:641
DEVICE int64_t size() const
#define CHECK_GE(x, y)
Definition: Logger.h:306
static void init()
Definition: GDAL.cpp:67
DEVICE T * getPtr() const
std::string toString(const QueryDescriptionType &type)
Definition: Types.h:64
#define CHECK_GT(x, y)
Definition: Logger.h:305
RasterAggType get_raster_agg_type(const std::string &agg_type_str, const bool is_fill_agg)
std::unique_ptr< OGRFeature, FeatureDeleter > FeatureUqPtr
Definition: GDAL.h:53
int32_t tf_raster_contour_rasterize_impl(TableFunctionManager &mgr, const Column< TLL > &lon, const Column< TLL > &lat, const Column< TV > &values, const TextEncodingNone &agg_type, const float bin_dim_meters, const int32_t neighborhood_fill_radius, const bool fill_only_nulls, const TextEncodingNone &fill_agg_type, const bool flip_latitude, const TV contour_interval, const TV contour_offset, Column< TG > &contour_features, Column< TV > &contour_values)
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
#define CHECK(condition)
Definition: Logger.h:291
TEMPLATE_NOINLINE int32_t tf_raster_contour_lines__cpu_template(TableFunctionManager &mgr, const Column< TLL > &lon, const Column< TLL > &lat, const Column< TV > &values, const TextEncodingNone &agg_type, const float bin_dim_meters, const int32_t neighborhood_fill_radius, const bool fill_only_nulls, const TextEncodingNone &fill_agg_type, const bool flip_latitude, const TV contour_interval, const TV contour_offset, Column< GeoLineString > &contour_lines, Column< TV > &contour_values)
int32_t tf_raster_contour_impl(TableFunctionManager &mgr, const int32_t raster_width, const int32_t raster_height, const double affine_transform[6], const TV *values, const TV contour_interval, const TV contour_offset, Column< TG > &contour_features, Column< TV > &contour_values)
int32_t tf_raster_contour_direct_impl(TableFunctionManager &mgr, const Column< TLL > &lon, const Column< TLL > &lat, const Column< TV > &values, const int32_t raster_width, const int32_t raster_height, const bool flip_latitude, const TV contour_interval, const TV contour_offset, Column< TG > &contour_features, Column< TV > &contour_values)
#define VLOG(n)
Definition: Logger.h:388
#define TEMPLATE_NOINLINE
Definition: heavydbTypes.h:60