Skip to content

Commit

Permalink
fixes #1675
Browse files Browse the repository at this point in the history
  • Loading branch information
rhijmans committed Dec 14, 2024
1 parent 27ba82d commit 680de31
Showing 1 changed file with 82 additions and 13 deletions.
95 changes: 82 additions & 13 deletions src/patches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,87 @@

#include "spatRaster.h"

void patch_search(const std::vector<double> &m, std::vector<double> &patches, const int &i, const long &ncol, const int &patch, const size_t &dirs) {
void patch_search_wrap(const std::vector<double> &m, std::vector<double> &patches, const int &i, const long &ncol, const int &patch, const size_t &dirs) {
// DFS

std::vector<long> directions;
std::vector<long> directions, dirfirst, dirlast;
if (dirs==4) {
directions = {-ncol, ncol, -1, 1};
dirfirst = {-ncol, ncol, ncol-1, 1};
dirlast = {-ncol, ncol, -1, 1-ncol};
} else {
directions = {-ncol, ncol, -1, 1, -ncol-1, -ncol+1, ncol-1, ncol+1};
dirfirst = {-ncol, ncol, ncol-1, 1, -1, -ncol+1, ncol+ncol-1, ncol+1};
dirlast = {-ncol, ncol, -1, 1-ncol, -ncol-1, -ncol-ncol+1, ncol-1, 1};
}

size_t ncell = m.size();
patches[i] = patch;
for (size_t d=0; d<dirs; d++) {
size_t j = i + directions[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search(m, patches, j, ncol, patch, dirs);
}
}
if ((i % ncol) == 0) { //firstcol
for (size_t d=0; d<dirfirst.size(); d++) {
size_t j = i + dirfirst[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search_wrap(m, patches, j, ncol, patch, dirs);
}
}
} else if (((i+1) % ncol) == 0) { // lastcol
for (size_t d=0; d<dirlast.size(); d++) {
size_t j = i + dirlast[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search_wrap(m, patches, j, ncol, patch, dirs);
}
}
} else {
for (size_t d=0; d<dirs; d++) {
size_t j = i + directions[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search_wrap(m, patches, j, ncol, patch, dirs);
}
}
}
}


void patch_search(const std::vector<double> &m, std::vector<double> &patches, const int &i, const long &ncol, const int &patch, const size_t &dirs) {
// DFS

std::vector<long> directions, dirfirst, dirlast;
if (dirs==4) {
directions = {-ncol, ncol, -1, 1};
dirfirst = {-ncol, ncol, 1};
dirlast = {-ncol, ncol, -1};
} else {
directions = {-ncol, ncol, -1, 1, -ncol-1, -ncol+1, ncol-1, ncol+1};
dirfirst = {-ncol, ncol, 1, -ncol+1, ncol+1};
dirlast = {-ncol, ncol, -1, -ncol-1, ncol-1};
}

size_t ncell = m.size();
patches[i] = patch;
if ((i % ncol) == 0) { //firstcol
for (size_t d=0; d<dirfirst.size(); d++) {
size_t j = i + dirfirst[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search(m, patches, j, ncol, patch, dirs);
}
}
} else if (((i+1) % ncol) == 0) { // lastcol
for (size_t d=0; d<dirlast.size(); d++) {
size_t j = i + dirlast[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search(m, patches, j, ncol, patch, dirs);
}
}
} else {
for (size_t d=0; d<dirs; d++) {
size_t j = i + directions[d];
if (j >= 0 && j < ncell && (!std::isnan(m[j])) && std::isnan(patches[j]) && m[j] == m[i]) {
patch_search(m, patches, j, ncol, patch, dirs);
}
}
}
}

SpatRaster SpatRaster::patches(size_t dirs, SpatOptions &opt) {

SpatRaster out = geometry(1, false);
Expand Down Expand Up @@ -101,13 +161,22 @@ SpatRaster SpatRaster::patches(size_t dirs, SpatOptions &opt) {
if (!out.writeBlock(patches, i)) return out;
}
*/

std::vector<double> patches(nrow() * nc, NAN);
readValues(v, 0, nrow(), 0, nc);
for (size_t j=0; j<v.size(); j++) {
if ((!std::isnan(v[j])) && std::isnan(patches[j])) {
patch_search(v, patches, j, nc, patch, dirs);
patch++;

if (is_global_lonlat()) {
for (size_t j=0; j<v.size(); j++) {
if ((!std::isnan(v[j])) && std::isnan(patches[j])) {
patch_search_wrap(v, patches, j, nc, patch, dirs);
patch++;
}
}
} else {
for (size_t j=0; j<v.size(); j++) {
if ((!std::isnan(v[j])) && std::isnan(patches[j])) {
patch_search(v, patches, j, nc, patch, dirs);
patch++;
}
}
}
if (!out.writeValues(patches, 0, nrow())) return out;
Expand Down

0 comments on commit 680de31

Please sign in to comment.