layer shifting added
netzel

netzel commited on 2024-03-19 18:06:41
Showing 2 changed files, with 117 additions and 5 deletions.

... ...
@@ -1 +1 @@
1
-683
1
+737
... ...
@@ -30,6 +30,7 @@ typedef struct {
30 30
   GDALRasterBandH band_h;
31 31
   int is_no_data;
32 32
   double no_data;
33
+  int shift_cols, shift_rows;
33 34
   double *buffer;
34 35
   double *iobuffer;
35 36
 } layer;
... ...
@@ -312,6 +313,34 @@ int get_band_number(const char *data) {
312 313
 	return result;
313 314
 }
314 315
 
316
+int get_shift_cols(const char *data) {
317
+    int l = (int)strlen(data)+2;
318
+    char *s = (char *)malloc(l);
319
+    strcpy(s,data);
320
+    char **toks = str_tokens(s,':');
321
+    char *tok = toks[2];
322
+    int result = 0;
323
+    if(tok!=NULL && *tok!='\0') 
324
+      result = atoi(tok);
325
+    free(s);
326
+    free(toks);
327
+    return result;
328
+}
329
+
330
+int get_shift_rows(const char *data) {
331
+    int l = (int)strlen(data)+2;
332
+    char *s = (char *)malloc(l);
333
+    strcpy(s,data);
334
+    char **toks = str_tokens(s,':');
335
+    char *tok = toks[3];
336
+    int result = 0;
337
+    if(tok!=NULL && *tok!='\0') 
338
+      result = atoi(tok);
339
+    free(s);
340
+    free(toks);
341
+    return result;
342
+}
343
+
315 344
 
316 345
 layer *open_inputs(struct arg_str *input) {
317 346
   int i;
... ...
@@ -339,6 +368,8 @@ layer *open_inputs(struct arg_str *input) {
339 368
 
340 369
       fname = get_file_name(input->sval[i]);
341 370
       band = get_band_number(input->sval[i]);
371
+      layers[i].shift_cols = get_shift_cols(input->sval[i]);
372
+      layers[i].shift_rows = get_shift_rows(input->sval[i]);
342 373
 
343 374
       layers[i].dataset_h = GDALOpenShared(fname,GA_ReadOnly);
344 375
       if(!(layers[i].dataset_h)) {
... ...
@@ -360,7 +391,7 @@ layer *open_inputs(struct arg_str *input) {
360 391
       layers[i].buffer = (double *)malloc(cols*sizeof(double));
361 392
       layers[i].iobuffer = (double *)malloc(cols*sizeof(double));
362 393
 
363
-      fprintf(stderr,"Input layer %s, band: %d", fname, band);
394
+      fprintf(stderr,"Input layer %s, band: %d, shift: %d,%d", fname, band, layers[i].shift_cols, layers[i].shift_rows);
364 395
       if(layers[i].is_no_data==1)
365 396
         fprintf(stderr,", no_data: %lf",layers[i].no_data);
366 397
       fprintf(stderr,"\n");
... ...
@@ -489,19 +520,62 @@ void close_outputs(layer **layers) {
489 520
   free(*layers);
490 521
   *layers = NULL;
491 522
 }
523
+/*
524
+void read_buffers(int ninputs, layer *layers, int row) {
525
+  int i;
526
+  CPLErr res;
527
+  for(i=0; i<ninputs; i++) {
528
+
529
+    res=GDALRasterIO(layers[i].band_h, GF_Read, 0, row, cols, 1,
530
+                       layers[i].buffer, cols, 1, GDT_Float64, 0, 0);
531
+    if(res>2) {
532
+      show_message(stderr, "Error in data reading!");
533
+      exit(1);
534
+    }
535
+  }
536
+}*/
492 537
 
493 538
 void read_buffers(int ninputs, layer *layers, int row) {
494 539
   int i;
495 540
   CPLErr res;
496 541
   for(i=0; i<ninputs; i++) {
497 542
 
543
+    double d = 0.0;
544
+    double *p;
545
+    row -= layers[i].shift_rows;
546
+    if(row<0 || row>=rows) {
547
+      if(layers[i].is_no_data) d = layers[i].no_data;
548
+      p = layers[i].buffer;
549
+      for(i=0; i<cols; i++)
550
+        *(p++) = d;
551
+    } else {
552
+      if(layers[i].shift_cols==0)
498 553
         res=GDALRasterIO(layers[i].band_h, GF_Read, 0, row, cols, 1,
499 554
                          layers[i].buffer, cols, 1, GDT_Float64, 0, 0);
555
+      else if(layers[i].shift_cols<0) {
556
+        res=GDALRasterIO(layers[i].band_h, GF_Read,0, row, cols+layers[i].shift_cols, 1,
557
+                         layers[i].buffer-layers[i].shift_cols, cols + layers[i].shift_cols, 1, 
558
+                         GDT_Float64, 0, 0);
559
+        if(layers[i].is_no_data) d = layers[i].no_data;
560
+        p = layers[i].buffer;
561
+        for(i=0; i<-layers[i].shift_cols; i++)
562
+          *(p++) = d;
563
+      } else { // >0
564
+        res=GDALRasterIO(layers[i].band_h, GF_Read, layers[i].shift_cols, row, cols-layers[i].shift_cols, 1,
565
+                         layers[i].buffer, cols - layers[i].shift_cols, 1, GDT_Float64, 0, 0);
566
+        if(layers[i].is_no_data) d = layers[i].no_data;
567
+        p = layers[i].buffer + (cols - layers[i].shift_cols);
568
+        for(i=0; i<layers[i].shift_cols; i++)
569
+          *(p++) = d;
570
+      }
571
+    }
500 572
     if(res>2) {
501 573
       show_message(stderr, "Error in data reading!");
502 574
       exit(1);
503 575
     }
576
+    printf("layer[%d], row%d; ",i,row);
504 577
   }
578
+  printf("\n");
505 579
 }
506 580
 
507 581
 void write_buffers(int noutputs, layer *layers, int row) {
... ...
@@ -518,8 +592,7 @@ void write_buffers(int noutputs, layer *layers, int row) {
518 592
     }
519 593
   }
520 594
 }
521
-
522
-
595
+/*
523 596
 void read_iobuffer(layer *l, int cols, int row) {
524 597
   CPLErr res;
525 598
   res=GDALRasterIO(l->band_h, GF_Read, 0, row, cols, 1,
... ...
@@ -528,6 +601,45 @@ void read_iobuffer(layer *l, int cols, int row) {
528 601
     show_message(stderr, "Error in data reading!");
529 602
     exit(1);
530 603
   }
604
+}*/
605
+
606
+void read_iobuffer(layer *l, int cols, int row) {
607
+
608
+    int i;
609
+    CPLErr res = 0;
610
+    double d = 0.0;
611
+    double *p;
612
+    row += l->shift_rows;
613
+    if(row<0 || row>=rows) {
614
+      if(l->is_no_data) d = l->no_data;
615
+      p = l->iobuffer;
616
+      for(i=0; i<cols; i++)
617
+        *(p++) = d;
618
+    } else {
619
+      if(l->shift_cols==0)
620
+        res=GDALRasterIO(l->band_h, GF_Read, 0, row, cols, 1,
621
+                         l->iobuffer, cols, 1, GDT_Float64, 0, 0);
622
+      else if(l->shift_cols<0) {
623
+        res=GDALRasterIO(l->band_h, GF_Read,0, row, cols+l->shift_cols, 1,
624
+                         l->iobuffer-l->shift_cols, cols + l->shift_cols, 1, 
625
+                         GDT_Float64, 0, 0);
626
+        if(l->is_no_data) d = l->no_data;
627
+        p = l->iobuffer;
628
+        for(i=0; i<-l->shift_cols; i++)
629
+          *(p++) = d;
630
+      } else { // >0
631
+        res=GDALRasterIO(l->band_h, GF_Read, l->shift_cols, row, cols-l->shift_cols, 1,
632
+                         l->iobuffer, cols - l->shift_cols, 1, GDT_Float64, 0, 0);
633
+        if(l->is_no_data) d = l->no_data;
634
+        p = l->iobuffer + (cols - l->shift_cols);
635
+        for(i=0; i<l->shift_cols; i++)
636
+          *(p++) = d;
637
+      }
638
+    }
639
+    if(res>2) {
640
+      show_message(stderr, "Error in data reading!");
641
+      exit(1);
642
+    }
531 643
 }
532 644
 
533 645
 void write_iobuffer(layer *l, int cols, int row) {
... ...
@@ -787,7 +899,7 @@ int main(int argc,char **argv) {
787 899
     struct arg_lit  *overwrite = arg_lit0("f", "force", "force to overwrite output file");
788 900
     struct arg_lit  *nan = arg_lit0(NULL, "use-nan", "force to treat NAN as a value (default: no-data)");
789 901
     struct arg_int  *threads = arg_int0("t", "threads", "<n>","number of threads");
790
-    struct arg_str  *input = arg_strn("i", "input", "file.tif[:band]",1,MAX_INPUTS,"input layer(s) (GeoTIFF)");
902
+    struct arg_str  *input = arg_strn("i", "input", "file.tif[[[:band]:shit_x]:shif_y]",1,MAX_INPUTS,"input layer(s) (GeoTIFF or any other GDAL raster format), optionally followed by the band number, horizontal shift by the specified number of cells (a negative value means a rightward shift), vertical shift by the specified number of cells (a negative value means a downward shift)");
791 903
     struct arg_str  *output = arg_strn("o", "output", "file.tif[:type[:no_data:[compression]]]",0,MAX_OUTPUTS,"output layer(s): file name, data type (Byte, Int16, UInt16, Int32, UInt32, Float32, default Float64), no_data value (default 0.0), compress (NONE, DEFLATE, DEFLATE2, DEFLATE3, LZW, LZW2, LZW3). (GeoTIFF)");
792 904
     struct arg_int  *mem = arg_int0("m", "memory", "<n>","number of memory cells to store temporary data");
793 905
     struct arg_str  *memstore = arg_str0("s", "memory-store", "<file name>","file to store memory cells (TXT)");
794 906