@@ -135,6 +135,28 @@ static bool lookup(std::vector<BlockRead> &br, std::vector<RastInfo> &ri,
135135}
136136
137137
138+ // Like lookup(), but returns true whenever the cell falls inside the
139+ // raster's extent — even if the value is NaN. Needed for narm=false.
140+ static bool lookup_raw (std::vector<BlockRead> &br, std::vector<RastInfo> &ri,
141+ size_t i, double x, double y, double &val) {
142+ if (!br[i].active ) return false ;
143+ SpatExtent& ei = ri[i].ext ;
144+ if (x <= ei.xmin || x >= ei.xmax ||
145+ y <= ei.ymin || y >= ei.ymax ) return false ;
146+
147+ size_t ic = (size_t )((x - br[i].xmin ) / br[i].xres );
148+ size_t ir = (size_t )((br[i].ymax - y) / br[i].yres );
149+ if (ic >= br[i].ncol ) ic = br[i].ncol - 1 ;
150+ if (ir >= br[i].nrow ) ir = br[i].nrow - 1 ;
151+
152+ val = br[i].vals [ir * br[i].ncol + ic];
153+ return true ;
154+ }
155+
156+ // === main methods ===
157+
158+
159+
138160SpatRaster SpatRasterCollection::blend (SpatOptions &opt) {
139161
140162 size_t n = ds.size ();
@@ -351,6 +373,99 @@ SpatRaster SpatRasterCollection::mosaic(std::string fun, SpatOptions &opt) {
351373
352374
353375
376+ SpatRaster SpatRasterCollection::merge2 (bool first, bool narm, SpatOptions &opt) {
377+
378+ size_t n = ds.size ();
379+ SpatRaster out;
380+
381+ if (n == 0 ) {
382+ out.setError (" collection is empty" );
383+ return out;
384+ }
385+ if (n == 1 ) {
386+ if (opt.get_filename () != " " ) {
387+ out = ds[0 ].writeRaster (opt);
388+ } else {
389+ out = ds[0 ].deepCopy ();
390+ }
391+ return out;
392+ }
393+
394+ if (!setup_output (*this , out, opt)) return out;
395+
396+ double oxres = out.xres ();
397+ double oyres = out.yres ();
398+ SpatExtent oe = out.getExtent ();
399+ size_t onc = out.ncol ();
400+
401+ std::vector<RastInfo> ri = collect_info (*this );
402+
403+ if (!start_readers (*this , out)) return out;
404+
405+ opt.ncopies = std::max (opt.ncopies , n + 1 );
406+ if (!out.writeStart (opt, filenames ())) {
407+ stop_readers (*this );
408+ return out;
409+ }
410+
411+ // iteration order: first-wins scans 0..n-1, last-wins scans n-1..0
412+ std::vector<size_t > seq (n);
413+ if (first) {
414+ std::iota (seq.begin (), seq.end (), 0 );
415+ } else {
416+ std::iota (seq.rbegin (), seq.rend (), 0 );
417+ }
418+
419+ for (size_t b = 0 ; b < out.bs .n ; b++) {
420+
421+ size_t brow = out.bs .row [b];
422+ size_t bnrow = out.bs .nrows [b];
423+ size_t bncell = bnrow * onc;
424+
425+ double bymax = oe.ymax - brow * oyres;
426+ double bymin = oe.ymax - (brow + bnrow) * oyres;
427+
428+ std::vector<BlockRead> br (n);
429+ read_block (*this , ri, br, bymax, bymin, n);
430+
431+ std::vector<double > result (bncell, std::numeric_limits<double >::quiet_NaN ());
432+
433+ for (size_t r = 0 ; r < bnrow; r++) {
434+ double y = oe.ymax - (brow + r + 0.5 ) * oyres;
435+
436+ for (size_t c = 0 ; c < onc; c++) {
437+ double x = oe.xmin + (c + 0.5 ) * oxres;
438+
439+ for (size_t s = 0 ; s < n; s++) {
440+ size_t i = seq[s];
441+ double v;
442+ if (narm) {
443+ if (lookup (br, ri, i, x, y, v)) {
444+ result[r * onc + c] = v;
445+ break ;
446+ }
447+ } else {
448+ if (lookup_raw (br, ri, i, x, y, v)) {
449+ result[r * onc + c] = v;
450+ break ;
451+ }
452+ }
453+ }
454+ }
455+ }
456+
457+ if (!out.writeValues (result, brow, bnrow)) {
458+ stop_readers (*this );
459+ return out;
460+ }
461+ }
462+
463+ out.writeStop ();
464+ stop_readers (*this );
465+ return out;
466+ }
467+
468+
354469#include " recycle.h"
355470#include " string_utils.h"
356471
@@ -412,6 +527,9 @@ bool write_part(SpatRaster& out, SpatRaster r, const double& hxr, size_t& nl, bo
412527
413528SpatRaster SpatRasterCollection::merge (bool first, bool narm, int algo, std::string method, SpatOptions &opt) {
414529
530+ if ((algo == 1 ) && (method==" " )) {
531+ return (merge2 (first, narm, opt));
532+ }
415533
416534 SpatRaster out;
417535 size_t n = size ();
@@ -424,6 +542,7 @@ SpatRaster SpatRasterCollection::merge(bool first, bool narm, int algo, std::str
424542 return (out);
425543 }
426544
545+
427546 if (algo == 1 ) {
428547 SpatExtent e = ds[0 ].getExtent ();
429548 size_t nl = ds[0 ].nlyr ();
0 commit comments