sgsPy
structurally guided sampling
Loading...
Searching...
No Matches
existing.h
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Project: sgs
4 * Purpose: generate an access mask using vector and raster datasets
5 * Author: Joseph Meyer
6 * Date: October, 2025
7 *
8 ******************************************************************************/
9
14
15#pragma once
16
17#include "raster.h"
18#include "vector.h"
19#include "helper.h"
20
21#include <boost/unordered/unordered_flat_map.hpp>
22#include <gdal_priv.h>
23#include <ogrsf_frmts.h>
24#include <ogr_core.h>
25
26namespace sgs {
27namespace existing {
28
38struct Existing {
39 bool used;
40 boost::unordered::unordered_flat_map<int64_t, OGRPoint> samples;
41 double IGT[6];
42 int64_t width;
43
71 double *GT,
72 int64_t width,
73 OGRLayer *p_samples,
74 bool plot,
75 std::vector<double>& xCoords,
76 std::vector<double>& yCoords,
77 bool addAllPoints = true)
78 {
79 if (!p_vect) {
80 this->used = false;
81 return;
82 }
83
84 OGRFieldDefn existingField("existing", OFTInteger);
85 OGRErr err = p_samples->CreateField(&existingField);
86 if (err) {
87 throw std::runtime_error("cannot create 'existing' field in output layer.");
88 }
89
90 this->width = width;
91
92 std::vector<std::string> layerNames = p_vect->getLayerNames();
93 if (layerNames.size() > 1) {
94 throw std::runtime_error("the file containing existing sample points must have only a single layer.");
95 }
96
97 //check to ensure spatial reference system of raster and vector match
98 std::string rastProj = p_rast->getDataset()->GetProjectionRef();
99 OGRSpatialReference rastSRS;
100 rastSRS.importFromWkt(rastProj.c_str());
101 const OGRSpatialReference *p_sampSRS = p_samples->GetSpatialRef();
102 if (!rastSRS.IsSame(p_sampSRS)) {
103 throw std::runtime_error("existing sample vector and raster do not have the same spatial reference system.");
104 }
105
106 //invert geotransform so we can use IGT to convert from point to indexes
107 GDALInvGeoTransform(GT, this->IGT);
108
109 std::string layerName = layerNames[0];
110 OGRLayer *p_layer = p_vect->getLayer(layerName);
111 helper::Field fieldExistingTrue("existing", 1);
112
113 for (const auto& p_feature : *p_layer) {
114 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
115 if (!p_geometry) {
116 throw std::runtime_error(std::format("an invalid geometry was encountered in the {} layer.", layerName));
117 }
118 switch (wkbFlatten(p_geometry->getGeometryType())) {
119 case OGRwkbGeometryType::wkbPoint: {
120 OGRPoint *p_point = p_geometry->toPoint();
121 int64_t index = helper::point2index<int64_t>(p_point->getX(), p_point->getY(), IGT, width);
122 this->samples.emplace(index, *p_point);
123 if (addAllPoints) {
124 helper::addPoint(p_point, p_samples, &fieldExistingTrue);
125 if (plot) {
126 xCoords.push_back(p_point->getX());
127 yCoords.push_back(p_point->getY());
128 }
129 }
130 break;
131 }
132 case OGRwkbGeometryType::wkbMultiPoint: {
133 for (const auto& p_point : *p_geometry->toMultiPoint()) {
134 int64_t index = helper::point2index<int64_t>(p_point->getX(), p_point->getY(), IGT, width);
135 this->samples.emplace(index, *p_point);
136 if (addAllPoints) {
137 helper::addPoint(p_point, p_samples, &fieldExistingTrue);
138 if (plot) {
139 xCoords.push_back(p_point->getX());
140 yCoords.push_back(p_point->getY());
141 }
142 }
143 }
144 break;
145 }
146 default:
147 throw std::runtime_error("the file containing existing sample points must have only Point or MultiPoint geometries.");
148 }
149 }
150
151 this->used = true;
152 }
153
167 inline bool
168 containsIndex(int64_t x, int64_t y) {
169 int64_t index = y * this->width + x;
170 return this->samples.find(index) != this->samples.end();
171 }
172
181 inline OGRPoint
182 getPoint(int64_t x, int64_t y) {
183 int64_t index = y * this->width + x;
184 return this->samples.find(index)->second;
185 }
186
198 inline bool
199 containsCoordinates(double xCoord, double yCoord) {
200 int64_t index = helper::point2index<int64_t>(xCoord, yCoord, this->IGT, this->width);
201 return this->samples.find(index) != this->samples.end();
202 }
203
209 inline size_t
211 return this->samples.size();
212 }
213};
214
215} //namespace existing
216} //namespace sgs
Definition raster.h:57
GDALDataset * getDataset()
Definition raster.h:429
Definition vector.h:46
OGRLayer * getLayer(std::string layerName)
Definition vector.h:250
std::vector< std::string > getLayerNames()
Definition vector.h:198
T point2index(double xCoord, double yCoord, double *IGT, T width)
Definition helper.h:812
void addPoint(OGRPoint *p_point, OGRLayer *p_layer)
Definition helper.h:700
Definition existing.h:27
Definition pca.h:23
bool containsCoordinates(double xCoord, double yCoord)
Definition existing.h:199
int64_t width
Definition existing.h:42
bool used
Definition existing.h:39
OGRPoint getPoint(int64_t x, int64_t y)
Definition existing.h:182
size_t count()
Definition existing.h:210
double IGT[6]
Definition existing.h:41
bool containsIndex(int64_t x, int64_t y)
Definition existing.h:168
boost::unordered::unordered_flat_map< int64_t, OGRPoint > samples
Definition existing.h:40
Existing(vector::GDALVectorWrapper *p_vect, raster::GDALRasterWrapper *p_rast, double *GT, int64_t width, OGRLayer *p_samples, bool plot, std::vector< double > &xCoords, std::vector< double > &yCoords, bool addAllPoints=true)
Definition existing.h:68
Definition helper.h:46