OmniSciDB  04ee39c94c
ResultSetGeoSerialization.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
24 #ifndef QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
25 #define QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
26 
27 #include <Shared/geo_compression.h>
28 #include <Shared/geo_types.h>
29 #include <Shared/sqltypes.h>
30 #include "ResultSet.h"
31 #include "TargetValue.h"
32 
33 using VarlenDatumPtr = std::unique_ptr<VarlenDatum>;
34 
35 template <SQLTypes GEO_SOURCE_TYPE>
37  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for target value serializer.");
38 };
39 
40 template <SQLTypes GEO_SOURCE_TYPE>
42  static_assert(IS_GEO(GEO_SOURCE_TYPE), "Invalid geo type for wkt serializer.");
43 };
44 
45 template <SQLTypes GEO_SOURCE_TYPE>
47  static_assert(IS_GEO(GEO_SOURCE_TYPE),
48  "Invalid geo type for target value ptr serializer.");
49 };
50 
51 template <ResultSet::GeoReturnType GEO_RETURN_TYPE, SQLTypes GEO_SOURCE_TYPE>
53  static_assert(GEO_RETURN_TYPE == ResultSet::GeoReturnType::GeoTargetValue ||
54  GEO_RETURN_TYPE == ResultSet::GeoReturnType::WktString ||
56  "ResultSet: Unrecognized Geo Return Type encountered.");
57 };
58 
59 template <SQLTypes GEO_SOURCE_TYPE>
60 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValue, GEO_SOURCE_TYPE> {
62 };
63 
64 template <SQLTypes GEO_SOURCE_TYPE>
65 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::WktString, GEO_SOURCE_TYPE> {
67 };
68 
69 template <SQLTypes GEO_SOURCE_TYPE>
70 struct GeoReturnTypeTraits<ResultSet::GeoReturnType::GeoTargetValuePtr, GEO_SOURCE_TYPE> {
72 };
73 
74 namespace {
75 
76 template <typename T>
77 void unpack_geo_vector(std::vector<T>& output, const int8_t* input_ptr, const size_t sz) {
78  auto elems = reinterpret_cast<const T*>(input_ptr);
79  CHECK(elems);
80  CHECK_EQ(size_t(0), sz % sizeof(T));
81  const size_t num_elems = sz / sizeof(T);
82  output.resize(num_elems);
83  for (size_t i = 0; i < num_elems; i++) {
84  output[i] = elems[i];
85  }
86 }
87 
88 template <typename T>
89 void decompress_geo_coords_geoint32(std::vector<T>& dec,
90  const int8_t* enc,
91  const size_t sz) {
92  const auto compressed_coords = reinterpret_cast<const int32_t*>(enc);
93  const auto num_coords = sz / sizeof(int32_t);
94  dec.resize(num_coords);
95  for (size_t i = 0; i < num_coords; i += 2) {
96  dec[i] = Geo_namespace::decompress_longitude_coord_geoint32(compressed_coords[i]);
97  dec[i + 1] =
99  }
100 }
101 
102 template <typename T>
103 std::shared_ptr<std::vector<T>> decompress_coords(const SQLTypeInfo& geo_ti,
104  const int8_t* coords,
105  const size_t coords_sz);
106 
107 template <>
108 std::shared_ptr<std::vector<double>> decompress_coords<double>(const SQLTypeInfo& geo_ti,
109  const int8_t* coords,
110  const size_t coords_sz) {
111  auto decompressed_coords_ptr = std::make_shared<std::vector<double>>();
112  if (geo_ti.get_compression() == kENCODING_GEOINT) {
113  if (geo_ti.get_comp_param() == 32) {
114  decompress_geo_coords_geoint32(*decompressed_coords_ptr, coords, coords_sz);
115  }
116  } else {
117  CHECK_EQ(geo_ti.get_compression(), kENCODING_NONE);
118  unpack_geo_vector(*decompressed_coords_ptr, coords, coords_sz);
119  }
120  return decompressed_coords_ptr;
121 }
122 
123 } // namespace
124 
125 // Point
126 template <>
128  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
129  std::array<VarlenDatumPtr, 1>& vals) {
130  if (vals[0]->is_null) {
131  return GeoPointTargetValue(std::vector<double>{});
132  }
133  return GeoPointTargetValue(
134  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length));
135  }
136 };
137 
138 template <>
140  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
141  std::array<VarlenDatumPtr, 1>& vals) {
143  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length));
144  return NullableString(point.getWktString());
145  }
146 };
147 
148 template <>
150  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
151  std::array<VarlenDatumPtr, 1>& vals) {
152  return GeoPointTargetValuePtr({std::move(vals[0])});
153  }
154 };
155 
156 // LineString
157 template <>
159  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
160  std::array<VarlenDatumPtr, 1>& vals) {
161  if (vals[0]->is_null) {
162  return GeoLineStringTargetValue(std::vector<double>{});
163  }
165  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length));
166  }
167 };
168 
169 template <>
171  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
172  std::array<VarlenDatumPtr, 1>& vals) {
173  Geo_namespace::GeoLineString linestring(
174  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length));
175  return NullableString(linestring.getWktString());
176  }
177 };
178 
179 template <>
181  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
182  std::array<VarlenDatumPtr, 1>& vals) {
183  return GeoLineStringTargetValuePtr({std::move(vals[0])});
184  }
185 };
186 
187 // Polygon
188 template <>
190  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
191  std::array<VarlenDatumPtr, 2>& vals) {
192  std::vector<int32_t> ring_sizes_vec;
193  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
194  return GeoPolyTargetValue(
195  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length),
196  ring_sizes_vec);
197  }
198 };
199 
200 template <>
202  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
203  std::array<VarlenDatumPtr, 2>& vals) {
204  std::vector<int32_t> ring_sizes_vec;
205  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
207  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length),
208  ring_sizes_vec);
209  return NullableString(poly.getWktString());
210  };
211 };
212 
213 template <>
215  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
216  std::array<VarlenDatumPtr, 2>& vals) {
217  return GeoPolyTargetValuePtr({std::move(vals[0]), std::move(vals[1])});
218  }
219 };
220 
221 // MultiPolygon
222 template <>
224  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
225  std::array<VarlenDatumPtr, 3>& vals) {
226  std::vector<int32_t> ring_sizes_vec;
227  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
228  std::vector<int32_t> poly_rings_vec;
229  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
231  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length),
232  ring_sizes_vec,
233  poly_rings_vec);
234  }
235 };
236 
237 template <>
239  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
240  std::array<VarlenDatumPtr, 3>& vals) {
241  std::vector<int32_t> ring_sizes_vec;
242  unpack_geo_vector(ring_sizes_vec, vals[1]->pointer, vals[1]->length);
243  std::vector<int32_t> poly_rings_vec;
244  unpack_geo_vector(poly_rings_vec, vals[2]->pointer, vals[2]->length);
246  *decompress_coords<double>(geo_ti, vals[0]->pointer, vals[0]->length),
247  ring_sizes_vec,
248  poly_rings_vec);
249  return NullableString(mpoly.getWktString());
250  }
251 };
252 
253 template <>
255  static inline TargetValue serialize(const SQLTypeInfo& geo_ti,
256  std::array<VarlenDatumPtr, 3>& vals) {
258  {std::move(vals[0]), std::move(vals[1]), std::move(vals[2])});
259  }
260 };
261 
262 #endif // QUERYENGINE_RESULTSET_GEOSERIALIZATION_H
#define CHECK_EQ(x, y)
Definition: Logger.h:195
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
void unpack_geo_vector(std::vector< T > &output, const int8_t *input_ptr, const size_t sz)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
int64_t const int32_t sz
boost::variant< GeoPointTargetValue, GeoLineStringTargetValue, GeoPolyTargetValue, GeoMultiPolyTargetValue > GeoTargetValue
Definition: TargetValue.h:161
Constants for Builtin SQL Types supported by MapD.
Compression / decompression routines for geospatial coordinates.
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::shared_ptr< std::vector< double > > decompress_coords< double >(const SQLTypeInfo &geo_ti, const int8_t *coords, const size_t coords_sz)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
DEVICE double decompress_lattitude_coord_geoint32(const int32_t compressed)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 3 > &vals)
bool is_null(const T &v, const SQLTypeInfo &t)
std::shared_ptr< std::vector< T > > decompress_coords(const SQLTypeInfo &geo_ti, const int8_t *coords, const size_t coords_sz)
boost::variant< std::string, void * > NullableString
Definition: TargetValue.h:155
std::string getWktString() const
Definition: geo_types.cpp:157
void decompress_geo_coords_geoint32(std::vector< T > &dec, const int8_t *enc, const size_t sz)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
#define CHECK(condition)
Definition: Logger.h:187
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 2 > &vals)
Basic constructors and methods of the row set interface.
boost::variant< ScalarTargetValue, ArrayTargetValue, GeoTargetValue, GeoTargetValuePtr > TargetValue
Definition: TargetValue.h:167
DEVICE double decompress_longitude_coord_geoint32(const int32_t compressed)
static TargetValue serialize(const SQLTypeInfo &geo_ti, std::array< VarlenDatumPtr, 1 > &vals)
std::unique_ptr< VarlenDatum > VarlenDatumPtr
#define IS_GEO(T)
Definition: sqltypes.h:164
boost::variant< GeoPointTargetValuePtr, GeoLineStringTargetValuePtr, GeoPolyTargetValuePtr, GeoMultiPolyTargetValuePtr > GeoTargetValuePtr
Definition: TargetValue.h:165