48 OGRMultiPolygon *buffInnerPolygons =
new OGRMultiPolygon;
49 OGRMultiPolygon *buffOuterPolygons =
new OGRMultiPolygon;
50 OGRGeometry *p_polygonMask;
53 for (
const auto& p_feature : *p_access->
getLayer(layerName.c_str())) {
54 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
55 OGRwkbGeometryType type = wkbFlatten(p_geometry->getGeometryType());
58 case OGRwkbGeometryType::wkbLineString: {
59 OGRGeometry *p_outer = p_geometry->Buffer(buffOuter);
60 buffOuterPolygons->addGeometry(p_outer);
61 OGRGeometryFactory::destroyGeometry(p_outer);
64 OGRGeometry *p_inner = p_geometry->Buffer(buffInner);
65 buffInnerPolygons->addGeometry(p_inner);
66 OGRGeometryFactory::destroyGeometry(p_inner);
70 case OGRwkbGeometryType::wkbMultiLineString: {
71 for (
const auto& p_lineString : *p_geometry->toMultiLineString()) {
72 OGRGeometry *p_outer = p_geometry->Buffer(buffOuter);
73 buffOuterPolygons->addGeometry(p_outer);
74 OGRGeometryFactory::destroyGeometry(p_outer);
76 OGRGeometry *p_inner = p_geometry->Buffer(buffInner);
77 buffInnerPolygons->addGeometry(p_inner);
78 OGRGeometryFactory::destroyGeometry(p_inner);
84 throw std::runtime_error(
"access polygon geometry type must be LineString or MultiLineString");
91 p_polygonMask = buffOuterPolygons->UnionCascaded();
94 OGRGeometry *buffOuterUnion = buffOuterPolygons->UnionCascaded();
95 OGRGeometry *buffInnerUnion = buffInnerPolygons->UnionCascaded();
96 p_polygonMask = buffOuterUnion->Difference(buffInnerUnion);
97 OGRGeometryFactory::destroyGeometry(buffOuterUnion);
98 OGRGeometryFactory::destroyGeometry(buffInnerUnion);
100 delete buffOuterPolygons;
101 delete buffInnerPolygons;
103 return p_polygonMask;
251 std::string location,
254 std::string layerName,
259 std::string filename)
266 GDALInvGeoTransform(GT, IGT);
269 double xMin, xMax, yMin, yMax;
276 double xDiff = xMax - xMin;
277 double yDiff = yMax - yMin;
278 double rngMax = yDiff * xDiff;
279 std::mt19937::result_type seed = time(
nullptr);
280 auto rng = std::bind(
281 std::uniform_real_distribution<double>(0, rngMax),
286 double rotation = rng() / (rngMax / 180);
289 std::string gridFunction;
290 if (shape ==
"square") {
291 gridFunction =
"ST_SquareGrid";
294 gridFunction =
"ST_HexagonalGrid";
298 std::string extentPolygon =
"'POLYGON (( "
299 + std::to_string(xMin) +
" " + std::to_string(yMin) +
", "
300 + std::to_string(xMin) +
" " + std::to_string(yMax) +
", "
301 + std::to_string(xMax) +
" " + std::to_string(yMax) +
", "
302 + std::to_string(xMax) +
" " + std::to_string(yMin) +
", "
303 + std::to_string(xMin) +
" " + std::to_string(yMin) +
" ))'";
305 std::string queryString =
"SELECT RotateCoords("
310 +
"), " + std::to_string(-rotation) +
"), "
311 + std::to_string(cellSize) +
"), "
312 + std::to_string(rotation) +
")";
315 OGRLayer *p_grid = p_raster->
getDataset()->ExecuteSQL(queryString.c_str(),
nullptr,
"SQLITE");
318 GDALDriver *p_driver = GetGDALDriverManager()->GetDriverByName(
"MEM");
320 throw std::runtime_error(
"unable to create output sample dataset driver.");
322 GDALDataset *p_sampleDataset = p_driver->Create(
"", 0, 0, 0, GDT_Unknown,
nullptr);
323 if (!p_sampleDataset) {
324 throw std::runtime_error(
"unable to create output dataset with driver.");
328 OGRLayer *p_sampleLayer = p_sampleDataset->CreateLayer(
"samples", p_wrapper->
getSRS(), wkbPoint,
nullptr);
329 if (!p_sampleLayer) {
330 throw std::runtime_error(
"unable to create output dataset layer.");
334 OGRGeometry *
access =
nullptr;
341 buffOuter = buffOuter - pixelSize / 50;
342 buffInner = buffInner == 0 ? 0 : buffInner + pixelSize / 50;
348 std::vector<double> xCoords, yCoords;
355 std::vector<std::vector<std::vector<double>>> grid;
358 for (
const auto& p_feature : *p_grid) {
359 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
360 for (
const auto& p_polygon : *p_geometry->toMultiPolygon()) {
363 OGRPoint secondPoint;
364 if (location ==
"centers") {
365 p_polygon->Centroid(&point);
367 double x = point.getX();
368 double y = point.getY();
379 xCoords.push_back(x);
380 yCoords.push_back(y);
384 else if (location ==
"corners") {
385 (*p_polygon->begin())->getPoint(0, &point);
386 (*p_polygon->begin())->getPoint(1, &secondPoint);
388 double x = point.getX();
389 double y = point.getY();
400 xCoords.push_back(x);
401 yCoords.push_back(y);
405 x = secondPoint.getX();
406 y = secondPoint.getY();
417 xCoords.push_back(x);
418 yCoords.push_back(y);
424 OGREnvelope envelope;
425 p_polygon->getEnvelope(&envelope);
426 double xMinEnv = envelope.MinX;
427 double xMaxEnv = envelope.MaxX;
428 double xDiffEnv = xMaxEnv - xMinEnv;
429 double yMinEnv = envelope.MinY;
430 double yMaxEnv = envelope.MaxY;
431 double yDiffEnv = yMaxEnv - yMinEnv;
436 while (tries < 10 && !found) {
437 point.setX(xMinEnv + rng() / (rngMax / xDiffEnv));
438 point.setY(yMinEnv + rng() / (rngMax / yDiffEnv));
439 while (!p_polygon->Contains(&point)) {
440 point.setX(xMinEnv + rng() / (rngMax / xDiffEnv));
441 point.setY(yMinEnv + rng() / (rngMax / yDiffEnv));
444 double x = point.getX();
445 double y = point.getY();
457 xCoords.push_back(x);
458 yCoords.push_back(y);
469 grid.back().push_back({});
470 grid.back().push_back({});
471 for (
const auto& p_linearRing : *p_polygon) {
472 for (
const auto& p_point : *p_linearRing) {
473 grid.back()[0].push_back(p_point.getX());
474 grid.back()[1].push_back(p_point.getY());
481 if (filename !=
"") {
483 p_wrapper->
write(filename);
485 catch (
const std::exception& e) {
486 std::cout <<
"Exception thrown trying to write file: " << e.what() << std::endl;
491 p_raster->
getDataset()->ReleaseResultSet(p_grid);
493 OGRGeometryFactory::destroyGeometry(
access);
496 return {p_wrapper, {xCoords, yCoords}, grid};