update
This commit is contained in:
+20
-1
@@ -1 +1,20 @@
|
||||
*.pdf
|
||||
*.pdf
|
||||
*.TIF
|
||||
*.TIF.aux.xml
|
||||
*.db
|
||||
*.xml
|
||||
*.jp2
|
||||
*.o
|
||||
a.out
|
||||
*.out
|
||||
data/
|
||||
data1/
|
||||
data2/
|
||||
data3/
|
||||
S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/
|
||||
S2A_MSIL2A_20241118T143741_N0511_R096_T18GXU_20241118T201252.SAFE/
|
||||
*.zip
|
||||
*.TIF
|
||||
*.tif
|
||||
*.png
|
||||
*.qgz
|
||||
Submodule 2024_Grundlagen_Betriebssysteme_Rechnernetze/uebung-3-pthreads added at 61606e3117
@@ -15,11 +15,14 @@ int main() {
|
||||
|
||||
printf("\nEingabe: %s", eingabe);
|
||||
|
||||
for (index = 0; eingabe[index] != '\0'; index++)
|
||||
if (eingabe[index] == 'a')
|
||||
for (index = 0; eingabe[index] != '\0'; index++)
|
||||
if (eingabe[index] == 'a')
|
||||
break;
|
||||
|
||||
if (eingabe[index] == '\0')
|
||||
printf("Der String enthält kein ’a’.");
|
||||
else
|
||||
printf("Das erste 'a' ist an Position %d.\n", index + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,17 +10,18 @@ int main() {
|
||||
|
||||
int num1, num2;
|
||||
num1 = 0;
|
||||
nun2 = 1;
|
||||
num2 = 1;
|
||||
|
||||
printf("Der Quotient der Variablen ist: ")
|
||||
printf("Der Quotient der Variablen ist: ");
|
||||
printf("%d\n", num1/num2);
|
||||
printf(\n); // Leerzeile
|
||||
printf("\n"); // Leerzeile
|
||||
|
||||
printf("Jetzt werden die Variablenwerte vertauscht.\n");
|
||||
|
||||
// Dies muss korrigiert werden. (logischer Fehler!!!)
|
||||
int temp = num1;
|
||||
num1 = num2;
|
||||
num2 = num1;
|
||||
num2 = temp;
|
||||
|
||||
printf("Der Quotient der Vaiablen ist nun: ");
|
||||
printf("%d\n", num1/num2);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main() {
|
||||
char statS[] = "Hallo, PdP!";
|
||||
|
||||
char *dynS = malloc( 50 * sizeof(char));
|
||||
if (dynS == NULL){
|
||||
printf("Speicher konnte nicht reserviert werden");
|
||||
return 1;
|
||||
}
|
||||
strcpy(dynS, "Hallo, PdP!");
|
||||
|
||||
printf("%s\n", statS);
|
||||
printf("%s\n", dynS);
|
||||
|
||||
statS[1] = 'e';
|
||||
dynS[1] = 'e';
|
||||
printf("%s\n", statS);
|
||||
printf("%s\n", dynS);
|
||||
|
||||
strcpy(statS, "neuer String");
|
||||
strcpy(dynS, "neuer String");
|
||||
|
||||
printf("%s\n", statS);
|
||||
printf("%s\n", dynS);
|
||||
|
||||
free(dynS);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX 40
|
||||
|
||||
int main(){
|
||||
|
||||
char s1 [MAX];
|
||||
char s2 [MAX];
|
||||
|
||||
printf("Bitte Vorname eingeben (max. %d Zeichen): ", MAX-1);
|
||||
fgets(s1, MAX, stdin);
|
||||
|
||||
size_t len = strlen(s1);
|
||||
if (len > 0 && s1[len - 1] == '\n') {
|
||||
s1[len - 1] = '\0';
|
||||
}
|
||||
|
||||
printf("Bitte Nachname eingeben (max. %d Zeichen): ", MAX-1);
|
||||
fgets(s2, MAX, stdin);
|
||||
|
||||
len = strlen(s2);
|
||||
if (len > 0 && s2[len - 1] == '\n') {
|
||||
s2[len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (strcmp(s1, s2) == 0) {
|
||||
printf("Vorname und Nachname sind gleich.\n");
|
||||
} else {
|
||||
printf("Vorname und Nachname sind nicht gleich.\n");
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
while(s2[index] != '\0'){
|
||||
if (s2[index] >= 'a' && s2[index] <= 'z'){
|
||||
s2[index] -= 'a'-'A';
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
printf("Einzeln: %s %s \n", s1,s2);
|
||||
|
||||
|
||||
char *name = malloc( 80 * sizeof(char));
|
||||
if (name==NULL){
|
||||
printf("Konnte nicht reserviert werden");
|
||||
return 1;
|
||||
}
|
||||
|
||||
strcpy(name, s1);
|
||||
strcat(name, " ");
|
||||
strcat(name, s2);
|
||||
|
||||
|
||||
printf("Zusammen: %s \n", name);
|
||||
printf("Laenge name: %zu\n", strlen(name));
|
||||
|
||||
free(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
double value;
|
||||
double cubic_value;
|
||||
char *endptr;
|
||||
|
||||
if (argc != 2){
|
||||
printf("Nur einen Parameter eingeben\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
value = strtod(argv[1], &endptr);
|
||||
|
||||
if (errno == ERANGE) {
|
||||
printf("Der Wert ist außerhalb des darstellbaren Bereichs.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (endptr == argv[1]) {
|
||||
printf("Keine gültige Zahl gefunden.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
cubic_value = value * value * value;
|
||||
|
||||
printf("Value: %f\n", value);
|
||||
printf("Cubic Value: %f\n", cubic_value);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* point_1.c
|
||||
*
|
||||
* Datentyp eines zweidimensionalen Punktes
|
||||
* verschiedene Methoden der Komponentenselektion
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct point {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
void move_point(struct point * ptr, float delta_a, float delta_b){
|
||||
if (ptr != NULL){
|
||||
ptr->x += delta_a;
|
||||
ptr->y += delta_b;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct point p1 = {3.0f,4.0f};
|
||||
struct point * ptr = &p1;
|
||||
struct point p2 = {0.0f,0.0f};
|
||||
|
||||
printf("\nx-Koordinate von p1: %f", ptr->x);
|
||||
printf("\ny-Koordinate von p1: %f", ptr->y);
|
||||
|
||||
p2 = p1;
|
||||
|
||||
printf("\nx-Koordinate von p2: %f", p2.x);
|
||||
printf("\ny-Koordinate von p2: %f", p2.y);
|
||||
|
||||
printf("\nAdresse von p1: %p", (void*)&p1);
|
||||
printf("\nAdresse von p2: %p", (void*)&p2);
|
||||
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
move_point(ptr, 4.0f , 5.0f);
|
||||
|
||||
printf("\nx-Koordinate von p1: %f", ptr->x);
|
||||
printf("\ny-Koordinate von p1: %f", ptr->y);
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -33,15 +33,16 @@ int main() {
|
||||
printf("\ny-Koordinate von p: %f", ptr->y);
|
||||
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
|
||||
printf("\n");
|
||||
printf("\nnach free():");
|
||||
// printf("\n");
|
||||
// printf("\nnach free():");
|
||||
|
||||
// Dangling Pointer!
|
||||
printf("\nx-Koordinate von p: %f", ptr->x);
|
||||
printf("\ny-Koordinate von p: %f", ptr->y);
|
||||
// // Dangling Pointer!
|
||||
// printf("\nx-Koordinate von p: %f", ptr->x);
|
||||
// printf("\ny-Koordinate von p: %f", ptr->y);
|
||||
|
||||
printf("\n\n");
|
||||
// printf("\n\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
// Structs
|
||||
|
||||
typedef struct point {
|
||||
float x;
|
||||
float y;
|
||||
} Point;
|
||||
|
||||
typedef struct Node {
|
||||
Point *pt;
|
||||
struct Node *next;
|
||||
} Node;
|
||||
|
||||
typedef struct Polygonenzug {
|
||||
Node *head;
|
||||
} Polygonenzug;
|
||||
|
||||
// Methods
|
||||
|
||||
Point *create_point(float a, float b){
|
||||
Point *pt = (Point *)malloc(sizeof(Point));
|
||||
if (pt == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed for Point.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pt->x=a;
|
||||
pt->y=b;
|
||||
return pt;
|
||||
}
|
||||
|
||||
Polygonenzug* create_list() {
|
||||
Polygonenzug* pzug = (Polygonenzug*)malloc(sizeof(Polygonenzug));
|
||||
if (pzug == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed for Polygonzug.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pzug->head = NULL;
|
||||
return pzug;
|
||||
}
|
||||
|
||||
void append(Polygonenzug *pzug, Point *pt){
|
||||
Node *new_node = (Node*)malloc(sizeof(Node));
|
||||
if (new_node == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed for new_node in append.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
new_node->pt = pt;
|
||||
new_node->next = NULL;
|
||||
|
||||
if (pzug->head == NULL){
|
||||
pzug->head = new_node;
|
||||
} else {
|
||||
Node * temp = pzug->head;
|
||||
while(temp->next != NULL){
|
||||
temp = temp->next;
|
||||
}
|
||||
temp->next = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
void shorten(Polygonenzug *pzug){
|
||||
|
||||
// Wenn Liste leer
|
||||
if (pzug->head == NULL){
|
||||
printf("The list is empty.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Wenn nur ein Knoten
|
||||
if (pzug->head->next == NULL){
|
||||
free(pzug->head->pt);
|
||||
pzug->head->pt = NULL;
|
||||
free(pzug->head);
|
||||
pzug->head = NULL;
|
||||
printf("Die Liste wurde geloescht.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Wenn mehrere Knoten
|
||||
Node * temp = pzug->head;
|
||||
while(temp->next && temp->next->next != NULL){
|
||||
temp = temp->next;
|
||||
}
|
||||
free(temp->next->pt);
|
||||
free(temp->next);
|
||||
temp->next = NULL;
|
||||
}
|
||||
|
||||
void insert(Polygonenzug *pzug, Point *pt, int index){
|
||||
|
||||
Node *new_node = (Node*)malloc(sizeof(Node));
|
||||
if (new_node == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed for new_node in insert.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
new_node->pt = pt;
|
||||
new_node->next = NULL;
|
||||
|
||||
// Wenn index 0
|
||||
if(index == 0){
|
||||
new_node->next = pzug->head;
|
||||
pzug->head = new_node;
|
||||
return;
|
||||
}
|
||||
|
||||
// Groesse der liste checken
|
||||
int i = 0;
|
||||
Node *temp = pzug->head;
|
||||
|
||||
if(temp == NULL){
|
||||
printf("Cannot insert at index %d in an empty list.\n", index);
|
||||
free(new_node);
|
||||
return;
|
||||
}
|
||||
|
||||
while(temp != NULL && i < index - 1){
|
||||
temp = temp->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Wenn index > 0
|
||||
if(temp != NULL){
|
||||
new_node->next = temp->next;
|
||||
temp->next = new_node;
|
||||
} else{
|
||||
printf("Index is outside the list bounds.\n");
|
||||
free(new_node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Polygonenzug *mirror(Polygonenzug *pzug){
|
||||
Polygonenzug *pzug2 = create_list();
|
||||
|
||||
Node *temp = pzug->head;
|
||||
while(temp != NULL){
|
||||
Node * new_node = (Node*)malloc(sizeof(Node));
|
||||
if (new_node == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed for new_node in mirror.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
Point *new_pt = create_point(temp->pt->x, temp->pt->y);
|
||||
new_node->pt = new_pt;
|
||||
new_node->next = pzug2->head;
|
||||
pzug2->head = new_node;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return pzug2;
|
||||
}
|
||||
|
||||
|
||||
void pretty_print(Polygonenzug *pzug){
|
||||
|
||||
Node *index = pzug->head;
|
||||
|
||||
while(index != NULL){
|
||||
printf("%f , %f\n", index->pt->x, index->pt->y);
|
||||
index = index->next;
|
||||
}
|
||||
}
|
||||
|
||||
void free_list(Polygonenzug *pzug){
|
||||
Node *current = pzug->head;
|
||||
while(current != NULL){
|
||||
Node *next_node = current->next;
|
||||
free(current->pt);
|
||||
free(current);
|
||||
current = next_node;
|
||||
}
|
||||
free(pzug);
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
Point *p1 = create_point(3.0f,4.0f);
|
||||
Point *p2 = create_point(5.0f,6.0f);
|
||||
Point *p3 = create_point(8.0f, 9.0f);
|
||||
|
||||
Polygonenzug *pzug = create_list();
|
||||
printf("Pzug after Append p1:\n");
|
||||
append(pzug, p1);
|
||||
pretty_print(pzug);
|
||||
|
||||
printf("Pzug after Append p2:\n");
|
||||
append(pzug, p2);
|
||||
pretty_print(pzug);
|
||||
|
||||
printf("Pzug after Insert p3:\n");
|
||||
insert(pzug, p3, 1);
|
||||
pretty_print(pzug);
|
||||
|
||||
Polygonenzug *pzug2 = mirror(pzug);
|
||||
|
||||
// Test shorten
|
||||
printf("Pzug after Shorten:\n");
|
||||
shorten(pzug);
|
||||
pretty_print(pzug);
|
||||
printf("Pzug after Shorten:\n");
|
||||
shorten(pzug);
|
||||
pretty_print(pzug);
|
||||
|
||||
// Test shorten liste loeschen
|
||||
printf("Pzug after Shorten:\n");
|
||||
shorten(pzug);
|
||||
pretty_print(pzug);
|
||||
|
||||
// Test shorten leer
|
||||
printf("Pzug after Shorten:\n");
|
||||
shorten(pzug);
|
||||
pretty_print(pzug);
|
||||
|
||||
// Test mirror
|
||||
printf("Pzug2:\n");
|
||||
pretty_print(pzug2);
|
||||
|
||||
free_list(pzug);
|
||||
free_list(pzug2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,19 +9,19 @@ int main() {
|
||||
|
||||
float n;
|
||||
int rvalue;
|
||||
int c;
|
||||
|
||||
printf("Geben Sie eine Zahl ein: ");
|
||||
rvalue = scanf("%f", &n);
|
||||
|
||||
// to be debugged: (Tip: Siehe VL4 F18)
|
||||
printf("Rueckgabewert von scanf: %d\n", rvalue);
|
||||
|
||||
if (rvalue == 0) {
|
||||
printf("Sie haben keine Zahl eingegeben.\n\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
while (1){
|
||||
stdout("Geben Sie eine Zahl ein: ");
|
||||
rvalue = scanf("%f", &n);
|
||||
stdout("Rueckgabewert von scanf: %d\n", rvalue);
|
||||
if (rvalue == 1){
|
||||
break;
|
||||
} else {
|
||||
while ((c = getchar()) != '\n' && c != EOF) {}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Die Zahl ist %f\n", n);
|
||||
stdout("Die Zahl ist %f\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "date.h"
|
||||
|
||||
void setDate(Date* date, int year){
|
||||
date->day = 1;
|
||||
date->month = 1;
|
||||
date->year = year;
|
||||
}
|
||||
|
||||
void prettyPrintDate(Date *date){
|
||||
printf("Day: %d Month: %d Year: %d \n", date->day,date->month,date->year);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef DATE_H
|
||||
#define DATE_H
|
||||
|
||||
typedef struct date{
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
} Date;
|
||||
|
||||
void setDate(Date *date, int year);
|
||||
|
||||
void prettyPrintDate(Date *date);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include "date.h"
|
||||
#include "highscore.h"
|
||||
|
||||
void setHighscore(Highscore *highscore, int score, int year){
|
||||
setDate(&highscore->date, year);
|
||||
highscore->score = score;
|
||||
}
|
||||
|
||||
void prettyPrintHighscore(Highscore *highscore){
|
||||
printf("The Highscore on the %d.%d.%d is %d \n", highscore->date.day,highscore->date.month,highscore->date.year,highscore->score);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef HIGHSCORE_H
|
||||
#define HIGHSCORE_H
|
||||
#include "date.h"
|
||||
|
||||
typedef struct highscore {
|
||||
Date date;
|
||||
int score;
|
||||
} Highscore;
|
||||
|
||||
void setHighscore(Highscore *highscore, int score, int year);
|
||||
|
||||
void prettyPrintHighscore(Highscore *highscore);
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int count = 1;
|
||||
|
||||
|
||||
void rec_out(int n);
|
||||
|
||||
void decr(int n)
|
||||
{
|
||||
rec_out(--n);
|
||||
@@ -9,7 +14,6 @@ void decr(int n)
|
||||
|
||||
void rec_out(int n)
|
||||
{
|
||||
int count = 1;
|
||||
printf("Die %d. Ausgabe.\n", count);
|
||||
count++;
|
||||
if (n > 1)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "date.h"
|
||||
#include "highscore.h"
|
||||
|
||||
int main(){
|
||||
|
||||
int year1 = 2024;
|
||||
int score1 = 10;
|
||||
|
||||
Highscore highscore;
|
||||
setHighscore(&highscore, score1, year1);
|
||||
prettyPrintHighscore(&highscore);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# Lab Assignment 2
|
||||
|
||||
Name: Joaquin Gottlebe
|
||||
Matrikelnummer: 829101
|
||||
|
||||
## Question 1
|
||||
|
||||

|
||||
|
||||
## Question 2
|
||||
|
||||

|
||||

|
||||
|
||||
The original Raster file included values from -125 C which are not realistic in germany. Also Maximum temperatures from 44 degrees are not common, but could be explainable through realy heat conductiv material on very small areas.
|
||||
|
||||
Between Water bodies and land bodies. and also the north and south of the area.
|
||||
|
||||
## Question 3
|
||||
|
||||

|
||||

|
||||
|
||||
The main differences of the map are the Bands and their display of it. For example the true color composite consists of band 2,3 and 4 in the order of RGB as 4,3,2. The false color composite consists of band 3,4 and 5 in the order ich which Vegetation is the most visible (5,4,3).
|
||||
|
||||
## Question 4
|
||||
|
||||

|
||||

|
||||
|
||||
I choose this study area because i was on this island Chiloe in Chile for a bit and noticed a lot of National parks and vegeation there and i wanted to know how this changed in these past years. These two images show difference in NDVI between 2013 and 2024 of the island Chiloe in Chile and surroundings. I chose NDVI as it shows the difference in vegetation very well.
|
||||
@@ -0,0 +1,23 @@
|
||||
.PHONY: all run_scripts
|
||||
|
||||
# Path to the Conda environment and scripts
|
||||
CONDA_ENV_NAME = gdal_env
|
||||
ACTIVATE_SCRIPT = ~/miniforge3/bin/activate
|
||||
SCRIPTS = top_of_atmosphere.py ndvi.py ndwi.py
|
||||
PANDOC=pandoc
|
||||
|
||||
all: run_scripts
|
||||
|
||||
run_scripts:
|
||||
@echo "Activating Conda environment and running scripts..."
|
||||
@source $(ACTIVATE_SCRIPT) && conda activate $(CONDA_ENV_NAME) && \
|
||||
python3 toa.py data/LC08_L1TP_193023_20170602_20170615_01_T1_MTL.txt toa data/LC08_L1TP_193023_20170602_20170615_01_T1_B2.TIF data/LC08_L1TP_193023_20170602_20170615_01_T1_B4.TIF data/LC08_L1TP_193023_20170602_20170615_01_T1_B3.TIF data/LC08_L1TP_193023_20170602_20170615_01_T1_B5.TIF && \
|
||||
python3 toa_radiance.py data/LC08_L1TP_193023_20170602_20170615_01_T1_MTL.txt toa_radiance data/LC08_L1TP_193023_20170602_20170615_01_T1_B10.TIF data/LC08_L1TP_193023_20170602_20170615_01_T1_B11.TIF && \
|
||||
python3 ndvi.py toa/LC08_L1TP_193023_20170602_20170615_01_T1_B4_toa.TIF toa/LC08_L1TP_193023_20170602_20170615_01_T1_B5_toa.TIF ndvi && \
|
||||
python3 ndwi.py toa/LC08_L1TP_193023_20170602_20170615_01_T1_B3_toa.TIF toa/LC08_L1TP_193023_20170602_20170615_01_T1_B5_toa.TIF ndwi && \
|
||||
python3 surface_temperature.py data/LC08_L1TP_193023_20170602_20170615_01_T1_MTL.txt toa_radiance/LC08_L1TP_193023_20170602_20170615_01_T1_B10_toa_radiance.TIF toa_radiance/LC08_L1TP_193023_20170602_20170615_01_T1_B11_toa_radiance.TIF surface_temperature && \
|
||||
python3 toa.py data2/LC08_L1TP_233089_20131224_20200912_02_T1_MTL.txt toa2 data2/LC08_L1TP_233089_20131224_20200912_02_T1_B2.TIF data2/LC08_L1TP_233089_20131224_20200912_02_T1_B4.TIF data2/LC08_L1TP_233089_20131224_20200912_02_T1_B3.TIF data2/LC08_L1TP_233089_20131224_20200912_02_T1_B5.TIF && \
|
||||
python3 toa.py data3/LC08_L1TP_233089_20240410_20240419_02_T1_MTL.txt toa3 data3/LC08_L1TP_233089_20240410_20240419_02_T1_B2.TIF data3/LC08_L1TP_233089_20240410_20240419_02_T1_B4.TIF data3/LC08_L1TP_233089_20240410_20240419_02_T1_B3.TIF data3/LC08_L1TP_233089_20240410_20240419_02_T1_B5.TIF && \
|
||||
python3 ndvi.py toa2/LC08_L1TP_233089_20131224_20200912_02_T1_B4_toa.TIF toa2/LC08_L1TP_233089_20131224_20200912_02_T1_B5_toa.TIF ndvi2 && \
|
||||
python3 ndvi.py toa3/LC08_L1TP_233089_20240410_20240419_02_T1_B4_toa.TIF toa3/LC08_L1TP_233089_20240410_20240419_02_T1_B5_toa.TIF ndvi3 && \
|
||||
$(PANDOC) Lab2.md -o rcm01_2425_lab2_gottlebe_829101.pdf
|
||||
@@ -0,0 +1,119 @@
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Loading B10 Layer
|
||||
path_st_b10 = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/false_color/false_color.tif"
|
||||
st_b10_layer = QgsRasterLayer(path_st_b10, "False Color Composite")
|
||||
if not st_b10_layer.isValid():
|
||||
print("st_b10 layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(st_b10_layer)
|
||||
print("st_b10 Layer loaded!")
|
||||
|
||||
# Styling Layer
|
||||
st_b10_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/false_color.qml'
|
||||
if not st_b10_layer.loadNamedStyle(st_b10_style_path):
|
||||
print("Failed to load st_b10 style!")
|
||||
else:
|
||||
print("st_b10 style loaded!")
|
||||
|
||||
# Load layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(20, 30, QgsUnitTypes.LayoutMillimeters)) # Added space between top and map
|
||||
map_item.attemptResize(QgsLayoutSize(200, 150, QgsUnitTypes.LayoutMillimeters)) # Reduced height for better spacing
|
||||
map_item.zoomToExtent(st_b10_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(100000) # Set interval for grid lines in map units
|
||||
grid.setIntervalY(100000)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0) # Set annotation precision for grid labels
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra) # Optional grid style
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText("False Color Composite - Lab 2")
|
||||
title_label.setFont(QFont("Arial", 16))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.attemptMove(QgsLayoutPoint(105, 10, QgsUnitTypes.LayoutMillimeters))
|
||||
title_label.adjustSizeToText()
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(245, 30, QgsUnitTypes.LayoutMillimeters)) # Adjusted for better alignment and spacing
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box') # Change to 'Single Box' or 'Double Box' for a proper scalebar
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m') # Add unit label to make it informative
|
||||
scalebar_item.setNumberOfSegments(4) # Specify the number of segments in the scalebar
|
||||
scalebar_item.setNumberOfSegmentsLeft(0) # Segments to the left of zero (if any)
|
||||
scalebar_item.setUnitsPerSegment(50000) # Set distance per segment in map units
|
||||
scalebar_item.setFont(QFont('Arial', 10)) # Set font size for better readability
|
||||
scalebar_item.setHeight(5) # Set the height of the scalebar
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(20, 190, QgsUnitTypes.LayoutMillimeters)) # Moved below the map for better organization
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath('/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg')
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(30, 40, QgsUnitTypes.LayoutMillimeters)) # Adjusted placement for better visibility
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(15, 15, QgsUnitTypes.LayoutMillimeters)) # Increased size for better visibility
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Author: Joaquin Gottlebe")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 100, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Date: 16.11.2025")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 110, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Coordinate System
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("CRS: EPSG 32633")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 120, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
|
||||
# Export
|
||||
export_path = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/maps/false_color.png"
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
export_result = exporter.exportToImage(export_path, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print("Failed to export map!")
|
||||
else:
|
||||
print("Map exported to:", export_path)
|
||||
@@ -0,0 +1,2 @@
|
||||
mktextfm ecrm1000
|
||||
mktextfm ecrm1000
|
||||
@@ -0,0 +1,73 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
def handle_nodata(array):
|
||||
clean_array = np.where((array < 0) | (array > 1), np.nan, array)
|
||||
return clean_array
|
||||
|
||||
def ndvi_calc(NIR,RED):
|
||||
ndvi_array = (NIR - RED) / (NIR + RED + 1e-10)
|
||||
return ndvi_array
|
||||
|
||||
def save_tif(array,data,output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
def get_output_path(output_dir,input_path):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
basename_no_ext = re.sub(r'_B[1-9]|_B10|_B11', '', basename_no_ext)
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_ndvi.TIF")
|
||||
return path
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label," Min:", np.nanmin(array), " Max:",np.nanmax(array))
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python3 script.py <red_band_path> <nir_band_path> <output_directory>")
|
||||
sys.exit(1)
|
||||
|
||||
red_path = sys.argv[1]
|
||||
nir_path = sys.argv[2]
|
||||
output_dir = sys.argv[3]
|
||||
|
||||
red_data, red_array = tif_to_array(red_path)
|
||||
nir_data, nir_array = tif_to_array(nir_path)
|
||||
red_array = handle_nodata(red_array)
|
||||
nir_array = handle_nodata(nir_array)
|
||||
|
||||
ndvi_array = ndvi_calc(nir_array, red_array)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
output_path = get_output_path(output_dir,red_path)
|
||||
|
||||
save_tif(ndvi_array, red_data, output_path)
|
||||
|
||||
print_min_max(red_array, "RED")
|
||||
print_min_max(nir_array, "NIR")
|
||||
print_min_max(ndvi_array, "NDVI")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,119 @@
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Loading NDVI Layer
|
||||
path_ndvi = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/ndvi3/LC08_L1TP_233089_20240410_20240419_02_T1_toa_ndvi.TIF"
|
||||
ndvi_layer = QgsRasterLayer(path_ndvi, "NDVI")
|
||||
if not ndvi_layer.isValid():
|
||||
print("NDVI layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(ndvi_layer)
|
||||
print("NDVI Layer loaded!")
|
||||
|
||||
# Styling NDVI Layer
|
||||
ndvi_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndvi.qml'
|
||||
if not ndvi_layer.loadNamedStyle(ndvi_style_path):
|
||||
print("Failed to load NDVI style!")
|
||||
else:
|
||||
print("NDVI style loaded!")
|
||||
|
||||
# Load layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(20, 30, QgsUnitTypes.LayoutMillimeters)) # Added space between top and map
|
||||
map_item.attemptResize(QgsLayoutSize(200, 150, QgsUnitTypes.LayoutMillimeters)) # Reduced height for better spacing
|
||||
map_item.zoomToExtent(ndvi_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(100000) # Set interval for grid lines in map units
|
||||
grid.setIntervalY(100000)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0) # Set annotation precision for grid labels
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra) # Optional grid style
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText("NDVI Chiloe 2024 - Lab 2")
|
||||
title_label.setFont(QFont("Arial", 16))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.attemptMove(QgsLayoutPoint(105, 10, QgsUnitTypes.LayoutMillimeters))
|
||||
title_label.adjustSizeToText()
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(245, 30, QgsUnitTypes.LayoutMillimeters)) # Adjusted for better alignment and spacing
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box') # Change to 'Single Box' or 'Double Box' for a proper scalebar
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m') # Add unit label to make it informative
|
||||
scalebar_item.setNumberOfSegments(4) # Specify the number of segments in the scalebar
|
||||
scalebar_item.setNumberOfSegmentsLeft(0) # Segments to the left of zero (if any)
|
||||
scalebar_item.setUnitsPerSegment(50000) # Set distance per segment in map units
|
||||
scalebar_item.setFont(QFont('Arial', 10)) # Set font size for better readability
|
||||
scalebar_item.setHeight(5) # Set the height of the scalebar
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(20, 190, QgsUnitTypes.LayoutMillimeters)) # Moved below the map for better organization
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath('/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg')
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(30, 40, QgsUnitTypes.LayoutMillimeters)) # Adjusted placement for better visibility
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(15, 15, QgsUnitTypes.LayoutMillimeters)) # Increased size for better visibility
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Author: Joaquin Gottlebe")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 100, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Date: 16.11.2025")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 110, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Coordinate System
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("CRS: EPSG 32633")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 120, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
|
||||
# Export
|
||||
export_path = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/maps/ndvi_chiloe_2024.png"
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
export_result = exporter.exportToImage(export_path, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print("Failed to export map!")
|
||||
else:
|
||||
print("Map exported to:", export_path)
|
||||
@@ -0,0 +1,139 @@
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Loading NDVI Layer
|
||||
path_ndvi = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/ndvi/LC08_L1TP_193023_20170602_20170615_01_T1_toa_ndvi.TIF"
|
||||
ndvi_layer = QgsRasterLayer(path_ndvi, "NDVI")
|
||||
if not ndvi_layer.isValid():
|
||||
print("NDVI layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(ndvi_layer)
|
||||
print("NDVI Layer loaded!")
|
||||
|
||||
# Loading Additional Layer
|
||||
path_overlay = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/ndwi/LC08_L1TP_193023_20170602_20170615_01_T1_toa_ndwi.TIF" # Replace with your actual layer path
|
||||
ndwi_layer = QgsRasterLayer(path_overlay, "NDWI")
|
||||
if not ndwi_layer.isValid():
|
||||
print("NDWI layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(ndwi_layer)
|
||||
print("NDWI Layer loaded!")
|
||||
|
||||
# Styling NDVI Layer
|
||||
ndvi_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndvi.qml'
|
||||
if not ndvi_layer.loadNamedStyle(ndvi_style_path):
|
||||
print("Failed to load NDVI style!")
|
||||
else:
|
||||
print("NDVI style loaded!")
|
||||
|
||||
ndwi_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndwi.qml'
|
||||
if not ndwi_layer.loadNamedStyle(ndwi_style_path):
|
||||
print("Failed to load NDWI style!")
|
||||
else:
|
||||
print("NDWI style loaded!")
|
||||
|
||||
# Reference system (optional, uncomment if needed)
|
||||
# crs = QgsCoordinateReferenceSystem("EPSG:4326")
|
||||
# crsSrc = QgsCoordinateReferenceSystem("EPSG:32633")
|
||||
# crsDest = QgsCoordinateReferenceSystem("EPSG:4326")
|
||||
|
||||
# Load layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(20, 30, QgsUnitTypes.LayoutMillimeters)) # Added space between top and map
|
||||
map_item.attemptResize(QgsLayoutSize(200, 150, QgsUnitTypes.LayoutMillimeters)) # Reduced height for better spacing
|
||||
map_item.zoomToExtent(ndvi_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(100000) # Set interval for grid lines in map units
|
||||
grid.setIntervalY(100000)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0) # Set annotation precision for grid labels
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra) # Optional grid style
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText("NDVI & NDWI - Lab 2")
|
||||
title_label.setFont(QFont("Arial", 16))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.attemptMove(QgsLayoutPoint(105, 10, QgsUnitTypes.LayoutMillimeters))
|
||||
title_label.adjustSizeToText()
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(245, 30, QgsUnitTypes.LayoutMillimeters)) # Adjusted for better alignment and spacing
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box') # Change to 'Single Box' or 'Double Box' for a proper scalebar
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m') # Add unit label to make it informative
|
||||
scalebar_item.setNumberOfSegments(4) # Specify the number of segments in the scalebar
|
||||
scalebar_item.setNumberOfSegmentsLeft(0) # Segments to the left of zero (if any)
|
||||
scalebar_item.setUnitsPerSegment(50000) # Set distance per segment in map units
|
||||
scalebar_item.setFont(QFont('Arial', 10)) # Set font size for better readability
|
||||
scalebar_item.setHeight(5) # Set the height of the scalebar
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(20, 190, QgsUnitTypes.LayoutMillimeters)) # Moved below the map for better organization
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath('/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg')
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(30, 40, QgsUnitTypes.LayoutMillimeters)) # Adjusted placement for better visibility
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(15, 15, QgsUnitTypes.LayoutMillimeters)) # Increased size for better visibility
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Author: Joaquin Gottlebe")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 100, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Date: 16.11.2025")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 110, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Coordinate System
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("CRS: EPSG 32633")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 120, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
|
||||
# Export
|
||||
export_path = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/maps/ndvi_ndwi.png"
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
export_result = exporter.exportToImage(export_path, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print("Failed to export map!")
|
||||
else:
|
||||
print("Map exported to:", export_path)
|
||||
@@ -0,0 +1,81 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
|
||||
def handle_nodata(array):
|
||||
clean_array = np.where((array < 0) | (array > 1), np.nan, array)
|
||||
return clean_array
|
||||
|
||||
|
||||
def ndwi_calc(GREEN, NIR):
|
||||
ndwi_array = (GREEN - NIR) / (GREEN + NIR + 1e-10)
|
||||
return ndwi_array
|
||||
|
||||
|
||||
def save_tif(array, data, output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
|
||||
def get_output_path(output_dir, input_path):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
basename_no_ext = re.sub(r'_B[1-9]|_B10|_B11', '', basename_no_ext)
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_ndwi.TIF")
|
||||
return path
|
||||
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label, " Min:", np.nanmin(array), " Max:", np.nanmax(array))
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python3 script.py <green_band_path> <nir_band_path> <output_directory>")
|
||||
sys.exit(1)
|
||||
|
||||
green_path = sys.argv[1]
|
||||
nir_path = sys.argv[2]
|
||||
output_dir = sys.argv[3]
|
||||
|
||||
green_data, green_array = tif_to_array(green_path)
|
||||
nir_data, nir_array = tif_to_array(nir_path)
|
||||
green_array = handle_nodata(green_array)
|
||||
nir_array = handle_nodata(nir_array)
|
||||
|
||||
ndwi_array = ndwi_calc(green_array, nir_array)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
output_path = get_output_path(output_dir, green_path)
|
||||
|
||||
save_tif(ndwi_array, green_data, output_path)
|
||||
|
||||
print_min_max(nir_array, "NIR")
|
||||
print_min_max(green_array, "GREEN")
|
||||
print_min_max(ndwi_array, "NDWI")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,81 @@
|
||||
import sys
|
||||
import os
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import math
|
||||
|
||||
def load_metadata(metadata_path):
|
||||
K_CONSTANTS = {}
|
||||
with open(metadata_path, "r") as file:
|
||||
metadata_lines = file.readlines()
|
||||
for line in metadata_lines:
|
||||
if "K1_CONSTANT_BAND_10" in line or "K2_CONSTANT_BAND_10" in line or \
|
||||
"K1_CONSTANT_BAND_11" in line or "K2_CONSTANT_BAND_11" in line:
|
||||
variable, value = line.split(" = ")
|
||||
K_CONSTANTS[variable.strip()] = float(value.strip())
|
||||
return K_CONSTANTS
|
||||
|
||||
def load_band(band_path):
|
||||
band_data = gdal.Open(band_path)
|
||||
band = band_data.GetRasterBand(1)
|
||||
band_array = band.ReadAsArray().astype(np.float32)
|
||||
no_data_value = band.GetNoDataValue()
|
||||
band_array = np.where(band_array == no_data_value, np.nan, band_array)
|
||||
return band_data, band_array
|
||||
|
||||
def calculate_surface_temperature(band_array, K1_CONSTANT, K2_CONSTANT):
|
||||
epsilon = 1e-10
|
||||
result_array = (K2_CONSTANT / np.log((K1_CONSTANT / (band_array + epsilon)) + 1)) - 273.15
|
||||
return result_array
|
||||
|
||||
def save_result(output_directory, band_path, result_array, band_data):
|
||||
if not os.path.exists(output_directory):
|
||||
os.makedirs(output_directory)
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = result_array.shape
|
||||
band_filename = os.path.basename(band_path)
|
||||
output_filename = os.path.splitext(band_filename)[0] + '_surfacetemp.TIF'
|
||||
output_path = os.path.join(output_directory, output_filename)
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(band_data.GetGeoTransform())
|
||||
out_data.SetProjection(band_data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(result_array)
|
||||
out_band.SetNoDataValue(0)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
def main():
|
||||
metadata_path = sys.argv[1]
|
||||
band_paths = {
|
||||
'BAND_10': sys.argv[2],
|
||||
'BAND_11': sys.argv[3]
|
||||
}
|
||||
output_directory = sys.argv[4]
|
||||
|
||||
# Load metadata
|
||||
K_CONSTANTS = load_metadata(metadata_path)
|
||||
print(K_CONSTANTS)
|
||||
|
||||
# Process each band
|
||||
for band_key, band_path in band_paths.items():
|
||||
# Load band
|
||||
band_data, band_array = load_band(band_path)
|
||||
|
||||
# Get K1 and K2 constants
|
||||
K1_CONSTANT = K_CONSTANTS[f'K1_CONSTANT_{band_key}']
|
||||
K2_CONSTANT = K_CONSTANTS[f'K2_CONSTANT_{band_key}']
|
||||
|
||||
# Calculate surface temperature
|
||||
result_array = calculate_surface_temperature(band_array, K1_CONSTANT, K2_CONSTANT)
|
||||
|
||||
# Save the result
|
||||
save_result(output_directory, band_path, result_array, band_data)
|
||||
|
||||
# Print min and max of the arrays
|
||||
print(f"{band_key} Min, Max:", np.nanmin(band_array), np.nanmax(band_array))
|
||||
print(f"{band_key} Surface Temp Min, Max:", np.nanmin(result_array), np.nanmax(result_array))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Loading B10 Layer
|
||||
path_st_b10 = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/surface_temperature/LC08_L1TP_193023_20170602_20170615_01_T1_B11_toa_radiance_surfacetemp.TIF"
|
||||
st_b10_layer = QgsRasterLayer(path_st_b10, "Surf. Temp. B11")
|
||||
if not st_b10_layer.isValid():
|
||||
print("st_b10 layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(st_b10_layer)
|
||||
print("st_b10 Layer loaded!")
|
||||
|
||||
# Styling Layer
|
||||
st_b10_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/surface_temperature.qml'
|
||||
if not st_b10_layer.loadNamedStyle(st_b10_style_path):
|
||||
print("Failed to load st_b10 style!")
|
||||
else:
|
||||
print("st_b10 style loaded!")
|
||||
|
||||
# Load layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(20, 30, QgsUnitTypes.LayoutMillimeters)) # Added space between top and map
|
||||
map_item.attemptResize(QgsLayoutSize(200, 150, QgsUnitTypes.LayoutMillimeters)) # Reduced height for better spacing
|
||||
map_item.zoomToExtent(st_b10_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(100000) # Set interval for grid lines in map units
|
||||
grid.setIntervalY(100000)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0) # Set annotation precision for grid labels
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra) # Optional grid style
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText("Surace Temperautre B11 - Lab 2")
|
||||
title_label.setFont(QFont("Arial", 16))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.attemptMove(QgsLayoutPoint(105, 10, QgsUnitTypes.LayoutMillimeters))
|
||||
title_label.adjustSizeToText()
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(245, 30, QgsUnitTypes.LayoutMillimeters)) # Adjusted for better alignment and spacing
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box') # Change to 'Single Box' or 'Double Box' for a proper scalebar
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m') # Add unit label to make it informative
|
||||
scalebar_item.setNumberOfSegments(4) # Specify the number of segments in the scalebar
|
||||
scalebar_item.setNumberOfSegmentsLeft(0) # Segments to the left of zero (if any)
|
||||
scalebar_item.setUnitsPerSegment(50000) # Set distance per segment in map units
|
||||
scalebar_item.setFont(QFont('Arial', 10)) # Set font size for better readability
|
||||
scalebar_item.setHeight(5) # Set the height of the scalebar
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(20, 190, QgsUnitTypes.LayoutMillimeters)) # Moved below the map for better organization
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath('/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg')
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(30, 40, QgsUnitTypes.LayoutMillimeters)) # Adjusted placement for better visibility
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(15, 15, QgsUnitTypes.LayoutMillimeters)) # Increased size for better visibility
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Author: Joaquin Gottlebe")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 100, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Date: 16.11.2025")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 110, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Coordinate System
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("CRS: EPSG 32633")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 120, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
|
||||
# Export
|
||||
export_path = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/maps/surface_temp_b11.png"
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
export_result = exporter.exportToImage(export_path, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print("Failed to export map!")
|
||||
else:
|
||||
print("Map exported to:", export_path)
|
||||
@@ -0,0 +1,122 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import math
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
def handle_nodata(array):
|
||||
# Replace only negative values with NaN
|
||||
clean_array = np.where(array < 0, np.nan, array)
|
||||
return clean_array
|
||||
|
||||
def reflectance_calc(array, reflectance_mult, reflectance_add, sun_elevation):
|
||||
# Debugging print statements
|
||||
print(f"Reflectance Mult: {reflectance_mult}, Reflectance Add: {reflectance_add}, Sun Elevation: {sun_elevation}")
|
||||
print(f"Array Sample Before: {array[:5, :5]}") # Print a small portion of the array for inspection
|
||||
|
||||
result = ((array * reflectance_mult) + reflectance_add) / math.sin(math.radians(sun_elevation))
|
||||
|
||||
# Debugging print statements
|
||||
print(f"Array Sample After: {result[:5, :5]}") # Print a small portion of the result for inspection
|
||||
return result
|
||||
|
||||
def save_tif(array, data, output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
def get_output_path(output_dir, input_path, suffix):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
# basename_no_ext = re.sub(r'_B[1-9]|_B10|_B11', '', basename_no_ext)
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_{suffix}.TIF")
|
||||
return path
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label, " Min:", np.nanmin(array), " Max:", np.nanmax(array))
|
||||
|
||||
def get_reflectance_params(band_number, metadata_lines):
|
||||
reflectance_mult = None
|
||||
reflectance_add = None
|
||||
for line in metadata_lines:
|
||||
if f"REFLECTANCE_MULT_BAND_{band_number}" in line:
|
||||
variable, value = line.split(" = ")
|
||||
reflectance_mult = float(value.strip())
|
||||
if f"REFLECTANCE_ADD_BAND_{band_number}" in line:
|
||||
variable, value = line.split(" = ")
|
||||
reflectance_add = float(value.strip())
|
||||
if reflectance_mult is None or reflectance_add is None:
|
||||
raise ValueError(f"Reflectance parameters not found for band {band_number} in metadata.")
|
||||
return reflectance_mult, reflectance_add
|
||||
|
||||
def process_bands(band_paths, metadata_path, output_dir):
|
||||
# Read metadata
|
||||
with open(metadata_path, "r") as file:
|
||||
metadata_lines = file.readlines()
|
||||
|
||||
# Extract sun elevation
|
||||
sun_elevation = None
|
||||
for line in metadata_lines:
|
||||
if "SUN_ELEVATION" in line:
|
||||
variable, value = line.split(" = ")
|
||||
sun_elevation = float(value.strip())
|
||||
break
|
||||
|
||||
if sun_elevation is None:
|
||||
raise ValueError("Sun elevation not found in metadata.")
|
||||
|
||||
# Debugging sun elevation value
|
||||
print(f"Sun Elevation: {sun_elevation}, Sun Elevation Radians: {math.radians(sun_elevation)}")
|
||||
|
||||
# Process each band
|
||||
for band_path in band_paths:
|
||||
band_number = int(re.search(r'_B(\d+)', band_path).group(1))
|
||||
data, array = tif_to_array(band_path)
|
||||
array = handle_nodata(array)
|
||||
|
||||
# Get reflectance parameters for the band
|
||||
reflectance_mult, reflectance_add = get_reflectance_params(band_number, metadata_lines)
|
||||
|
||||
# Calculate reflectance for the band
|
||||
reflectance = reflectance_calc(array, reflectance_mult, reflectance_add, sun_elevation)
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
# Save Top of Atmosphere (TOA) reflectance for the band
|
||||
output_path = get_output_path(output_dir, band_path, f"toa")
|
||||
save_tif(reflectance, data, output_path)
|
||||
|
||||
# Print min and max for the reflectance band
|
||||
print_min_max(reflectance, f"Band {band_number} Reflectance")
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: python3 script.py <metadata_path> <output_directory> <band_paths...>")
|
||||
sys.exit(1)
|
||||
|
||||
metadata_path = sys.argv[1]
|
||||
output_dir = sys.argv[2]
|
||||
band_paths = sys.argv[3:]
|
||||
|
||||
process_bands(band_paths, metadata_path, output_dir)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,107 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import math
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
def get_radiance_params(band_number, metadata_lines):
|
||||
radiance_mult = None
|
||||
radiance_add = None
|
||||
for line in metadata_lines:
|
||||
if f"RADIANCE_MULT_BAND_{band_number}" in line:
|
||||
_, value = line.split(" = ")
|
||||
radiance_mult = float(value.strip())
|
||||
if f"RADIANCE_ADD_BAND_{band_number}" in line:
|
||||
_, value = line.split(" = ")
|
||||
radiance_add = float(value.strip())
|
||||
if radiance_mult is None or radiance_add is None:
|
||||
raise ValueError(f"Radiance parameters not found for band {band_number} in metadata.")
|
||||
return radiance_mult, radiance_add
|
||||
|
||||
def save_tif(array, data, output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
def get_output_path(output_dir, input_path, suffix):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_{suffix}.TIF")
|
||||
return path
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label, " Min:", np.nanmin(array), " Max:", np.nanmax(array))
|
||||
|
||||
def process_bands(bands, metadata_path, output_dir):
|
||||
# Read metadata
|
||||
with open(metadata_path, "r") as file:
|
||||
metadata_lines = file.readlines()
|
||||
|
||||
# Extract sun elevation (optional for radiance, included for debugging)
|
||||
sun_elevation = None
|
||||
for line in metadata_lines:
|
||||
if "SUN_ELEVATION" in line:
|
||||
_, value = line.split(" = ")
|
||||
sun_elevation = float(value.strip())
|
||||
break
|
||||
|
||||
# Debugging sun elevation value
|
||||
if sun_elevation is not None:
|
||||
print(f"Sun Elevation: {sun_elevation}, Sun Elevation Radians: {math.radians(sun_elevation)}")
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
# Process each band
|
||||
for band_data in bands:
|
||||
band_number, band_path = band_data[0], band_data[1]
|
||||
|
||||
# Load the band data
|
||||
data, array = tif_to_array(band_path)
|
||||
|
||||
# Get radiance parameters for the band
|
||||
radiance_mult, radiance_add = get_radiance_params(band_number, metadata_lines)
|
||||
|
||||
# Calculate radiance
|
||||
radiance_array = (array * radiance_mult) + radiance_add
|
||||
|
||||
# Save the Top of Atmosphere (TOA) radiance
|
||||
output_path = get_output_path(output_dir, band_path, "toa_radiance")
|
||||
save_tif(radiance_array, data, output_path)
|
||||
|
||||
# Print min and max for the radiance band
|
||||
print_min_max(radiance_array, f"Band {band_number} Radiance")
|
||||
|
||||
def main():
|
||||
print(f"Number of arguments received: {len(sys.argv) - 1}")
|
||||
print("Arguments:", sys.argv)
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: python3 script.py <metadata_path> <output_directory> <band_paths...>")
|
||||
sys.exit(1)
|
||||
|
||||
metadata_path = sys.argv[1]
|
||||
output_dir = sys.argv[2]
|
||||
band_paths = sys.argv[3:]
|
||||
|
||||
bands = [(int(re.search(r'B(\d+)', path).group(1)), path) for path in band_paths]
|
||||
|
||||
process_bands(bands, metadata_path, output_dir)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,119 @@
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Loading B10 Layer
|
||||
path_st_b10 = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/true_color/true_color.tif"
|
||||
st_b10_layer = QgsRasterLayer(path_st_b10, "True Color Composite")
|
||||
if not st_b10_layer.isValid():
|
||||
print("st_b10 layer failed to load!")
|
||||
else:
|
||||
QgsProject.instance().addMapLayer(st_b10_layer)
|
||||
print("st_b10 Layer loaded!")
|
||||
|
||||
# Styling Layer
|
||||
st_b10_style_path = '/home/huaqo/dev/courses/2024_Remote_Sensing/styles/true_color.qml'
|
||||
if not st_b10_layer.loadNamedStyle(st_b10_style_path):
|
||||
print("Failed to load st_b10 style!")
|
||||
else:
|
||||
print("st_b10 style loaded!")
|
||||
|
||||
# Load layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(20, 30, QgsUnitTypes.LayoutMillimeters)) # Added space between top and map
|
||||
map_item.attemptResize(QgsLayoutSize(200, 150, QgsUnitTypes.LayoutMillimeters)) # Reduced height for better spacing
|
||||
map_item.zoomToExtent(st_b10_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(100000) # Set interval for grid lines in map units
|
||||
grid.setIntervalY(100000)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0) # Set annotation precision for grid labels
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra) # Optional grid style
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText("True Color Composite - Lab 2")
|
||||
title_label.setFont(QFont("Arial", 16))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.attemptMove(QgsLayoutPoint(105, 10, QgsUnitTypes.LayoutMillimeters))
|
||||
title_label.adjustSizeToText()
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(245, 30, QgsUnitTypes.LayoutMillimeters)) # Adjusted for better alignment and spacing
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box') # Change to 'Single Box' or 'Double Box' for a proper scalebar
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m') # Add unit label to make it informative
|
||||
scalebar_item.setNumberOfSegments(4) # Specify the number of segments in the scalebar
|
||||
scalebar_item.setNumberOfSegmentsLeft(0) # Segments to the left of zero (if any)
|
||||
scalebar_item.setUnitsPerSegment(50000) # Set distance per segment in map units
|
||||
scalebar_item.setFont(QFont('Arial', 10)) # Set font size for better readability
|
||||
scalebar_item.setHeight(5) # Set the height of the scalebar
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(20, 190, QgsUnitTypes.LayoutMillimeters)) # Moved below the map for better organization
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath('/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg')
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(30, 40, QgsUnitTypes.LayoutMillimeters)) # Adjusted placement for better visibility
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(15, 15, QgsUnitTypes.LayoutMillimeters)) # Increased size for better visibility
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Author: Joaquin Gottlebe")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 100, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Author
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("Date: 16.11.2025")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 110, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Coordinate System
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText("CRS: EPSG 32633")
|
||||
info_label.setFont(QFont("Arial", 12))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(245, 120, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
|
||||
# Export
|
||||
export_path = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab2/maps/true_color.png"
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
export_result = exporter.exportToImage(export_path, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print("Failed to export map!")
|
||||
else:
|
||||
print("Map exported to:", export_path)
|
||||
@@ -0,0 +1,27 @@
|
||||
# Lab 3
|
||||
|
||||
Name: Joaquin Gottlebe
|
||||
|
||||
Matrikelnummer: 829101
|
||||
|
||||
## Question 1
|
||||
|
||||

|
||||
|
||||
## Question 2
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Landsat 8 uses broader NIR and Green bands with a 30m resolution, while Sentinel-2 uses narrower bands with a 10m resolution. Differences in atmospheric correction methods and time of capture could also be factors.
|
||||
|
||||
## Question 3
|
||||
|
||||
For the third question i choose the Chacao Channel as it is also a very interesting region because of its national parks agriculture and abundance of waterbodies.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Here the symbology was reduced to 0-0.2 because the calculations resultet in a peak around this area and near to zero values till 1. Which doenst make much sense because the area has a lot of waterbodies. I couldnt find and error.
|
||||
@@ -0,0 +1,44 @@
|
||||
.PHONY: all preproc1 preproc2 proc proc2 maps export
|
||||
|
||||
ACTIVATE_SCRIPT = ~/miniforge3/bin/activate
|
||||
CONDA_ENV_NAME = gdal_env
|
||||
PANDOC=pandoc
|
||||
|
||||
all: preproc1 preproc2 proc proc2 maps export
|
||||
|
||||
preproc1:
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/GRANULE/L2A_T33UUU_A010072_20170527T102301/IMG_DATA/R10m/T33UUU_20170527T102031_B02_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff/B02.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/GRANULE/L2A_T33UUU_A010072_20170527T102301/IMG_DATA/R10m/T33UUU_20170527T102031_B03_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff/B03.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/GRANULE/L2A_T33UUU_A010072_20170527T102301/IMG_DATA/R10m/T33UUU_20170527T102031_B04_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff/B04.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/GRANULE/L2A_T33UUU_A010072_20170527T102301/IMG_DATA/R10m/T33UUU_20170527T102031_B08_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff/B08.tif
|
||||
|
||||
preproc2:
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20170527T102031_N9999_R065_T33UUU_20191015T100203.SAFE/GRANULE/L2A_T33UUU_A010072_20170527T102301/IMG_DATA/R10m/T33UUU_20170527T102031_B02_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff2/B02.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20241118T143741_N0511_R096_T18GXU_20241118T201252.SAFE/GRANULE/L2A_T18GXU_A049142_20241118T144600/IMG_DATA/R10m/T18GXU_20241118T143741_B03_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff2/B03.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20241118T143741_N0511_R096_T18GXU_20241118T201252.SAFE/GRANULE/L2A_T18GXU_A049142_20241118T144600/IMG_DATA/R10m/T18GXU_20241118T143741_B04_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff2/B04.tif && \
|
||||
gdal_translate -of GTiff /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/S2A_MSIL2A_20241118T143741_N0511_R096_T18GXU_20241118T201252.SAFE/GRANULE/L2A_T18GXU_A049142_20241118T144600/IMG_DATA/R10m/T18GXU_20241118T143741_B08_10m.jp2 /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/sen2tiff2/B08.tif
|
||||
proc:
|
||||
@source $(ACTIVATE_SCRIPT) && conda activate $(CONDA_ENV_NAME) && \
|
||||
python3 ndvi.py sen2tiff/B04.tif sen2tiff/B08.tif ndvi && \
|
||||
python3 ndwi.py sen2tiff/B03.tif sen2tiff/B08.tif ndwi && \
|
||||
python clip.py /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/l8_ndvi/l8_ndvi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndvi/B04_ndvi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/l8_ndvi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/sen_ndvi.TIF && \
|
||||
python diff.py /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/sen_ndvi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/l8_ndvi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/diff/aligned.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/diff/diff.TIF && \
|
||||
python clip.py /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/l8_ndwi/l8_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndwi/B03_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/l8_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/sen_ndwi.TIF && \
|
||||
python diff.py /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/sen_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/clip/l8_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/diff/aligned_ndwi.TIF /home/huaqo/dev/courses/2024_Remote_Sensing/lab3/diff/diff_ndwi.TIF && \
|
||||
python hist.py diff/diff_ndwi.TIF --output plots/diff_hist.png
|
||||
|
||||
proc2:
|
||||
@source $(ACTIVATE_SCRIPT) && conda activate $(CONDA_ENV_NAME) && \
|
||||
python3 ndvi.py sen2tiff2/B04.tif sen2tiff2/B08.tif ndvi2 && \
|
||||
python3 ndwi.py sen2tiff2/B03.tif sen2tiff2/B08.tif ndwi2
|
||||
|
||||
maps:
|
||||
python3 ndvi_map.py
|
||||
python3 ndvi_map2.py
|
||||
python3 ndwi_map.py
|
||||
python3 ndwi_map2.py
|
||||
python3 diff_map.py
|
||||
|
||||
export:
|
||||
|
||||
$(PANDOC) Lab3.md -o rcm01_2425_lab3_gottlebe_829101.pdf
|
||||
@@ -0,0 +1,62 @@
|
||||
import rasterio
|
||||
from rasterio.mask import mask
|
||||
from shapely.geometry import box
|
||||
import argparse
|
||||
|
||||
def get_common_extent(raster1_path, raster2_path):
|
||||
"""Calculate the common extent (intersection) of two rasters."""
|
||||
with rasterio.open(raster1_path) as src1, rasterio.open(raster2_path) as src2:
|
||||
bounds1 = src1.bounds
|
||||
bounds2 = src2.bounds
|
||||
|
||||
# Calculate the intersection of the extents
|
||||
common_bounds = box(
|
||||
max(bounds1.left, bounds2.left),
|
||||
max(bounds1.bottom, bounds2.bottom),
|
||||
min(bounds1.right, bounds2.right),
|
||||
min(bounds1.top, bounds2.top),
|
||||
)
|
||||
return common_bounds
|
||||
|
||||
def clip_raster_to_extent(raster_path, extent, output_path):
|
||||
"""Clip the raster to the provided extent and save it to a new file."""
|
||||
with rasterio.open(raster_path) as src:
|
||||
# Convert extent to GeoJSON-like dict for rasterio.mask
|
||||
geojson_extent = [extent.__geo_interface__]
|
||||
|
||||
# Clip the raster to the extent
|
||||
out_image, out_transform = mask(src, geojson_extent, crop=True)
|
||||
out_meta = src.meta.copy()
|
||||
|
||||
# Update metadata with new dimensions, transform, and bounds
|
||||
out_meta.update({
|
||||
"driver": "GTiff",
|
||||
"height": out_image.shape[1],
|
||||
"width": out_image.shape[2],
|
||||
"transform": out_transform
|
||||
})
|
||||
|
||||
# Save the clipped raster
|
||||
with rasterio.open(output_path, "w", **out_meta) as dest:
|
||||
dest.write(out_image)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Clip two rasters to their common extent.")
|
||||
parser.add_argument("raster1", help="Path to the first raster.")
|
||||
parser.add_argument("raster2", help="Path to the second raster.")
|
||||
parser.add_argument("output1", help="Path to save the clipped first raster.")
|
||||
parser.add_argument("output2", help="Path to save the clipped second raster.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Determine the common extent
|
||||
common_extent = get_common_extent(args.raster1, args.raster2)
|
||||
|
||||
# Clip both rasters to the common extent
|
||||
clip_raster_to_extent(args.raster1, common_extent, args.output1)
|
||||
clip_raster_to_extent(args.raster2, common_extent, args.output2)
|
||||
|
||||
print("Rasters clipped successfully!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,85 @@
|
||||
import rasterio
|
||||
from rasterio.warp import reproject, Resampling
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
def resample_raster_to_match(reference_path, target_path, output_path):
|
||||
"""Resample the target raster to match the resolution, extent, and CRS of the reference raster."""
|
||||
with rasterio.open(reference_path) as ref:
|
||||
ref_transform = ref.transform
|
||||
ref_crs = ref.crs
|
||||
ref_width = ref.width
|
||||
ref_height = ref.height
|
||||
ref_nodata = ref.nodata or -9999
|
||||
|
||||
with rasterio.open(target_path) as target:
|
||||
target_nodata = target.nodata or -9999
|
||||
profile = target.profile
|
||||
profile.update(
|
||||
transform=ref_transform,
|
||||
crs=ref_crs,
|
||||
width=ref_width,
|
||||
height=ref_height,
|
||||
nodata=ref_nodata
|
||||
)
|
||||
|
||||
# Resample target raster
|
||||
with rasterio.open(output_path, "w", **profile) as output:
|
||||
for i in range(1, target.count + 1):
|
||||
reproject(
|
||||
source=rasterio.band(target, i),
|
||||
destination=rasterio.band(output, i),
|
||||
src_transform=target.transform,
|
||||
src_crs=target.crs,
|
||||
dst_transform=ref_transform,
|
||||
dst_crs=ref_crs,
|
||||
resampling=Resampling.bilinear,
|
||||
)
|
||||
|
||||
def calculate_difference(raster1_path, raster2_resampled_path, output_path):
|
||||
"""Calculate the difference between two aligned rasters."""
|
||||
with rasterio.open(raster1_path) as src1:
|
||||
raster1 = src1.read(1)
|
||||
nodata1 = src1.nodata or -9999
|
||||
profile = src1.profile
|
||||
|
||||
with rasterio.open(raster2_resampled_path) as src2:
|
||||
raster2 = src2.read(1)
|
||||
nodata2 = src2.nodata or -9999
|
||||
|
||||
# Replace nodata values with NaN for calculation
|
||||
raster1 = np.where(raster1 == nodata1, np.nan, raster1)
|
||||
raster2 = np.where(raster2 == nodata2, np.nan, raster2)
|
||||
|
||||
# Compute difference
|
||||
difference = raster1 - raster2
|
||||
|
||||
# Replace NaN with nodata for saving
|
||||
difference[np.isnan(difference)] = -9999
|
||||
|
||||
# Update metadata to include nodata
|
||||
profile.update(nodata=-9999)
|
||||
|
||||
# Save the difference raster
|
||||
with rasterio.open(output_path, "w", **profile) as dst:
|
||||
dst.write(difference, 1)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Resample a raster and calculate the difference.")
|
||||
parser.add_argument("reference_raster", help="Path to the reference raster.")
|
||||
parser.add_argument("target_raster", help="Path to the target raster to be resampled.")
|
||||
parser.add_argument("aligned_raster", help="Path to save the resampled (aligned) raster.")
|
||||
parser.add_argument("difference_raster", help="Path to save the difference raster.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Resample raster 2 to match raster 1
|
||||
resample_raster_to_match(args.reference_raster, args.target_raster, args.aligned_raster)
|
||||
|
||||
# Calculate the difference
|
||||
calculate_difference(args.reference_raster, args.aligned_raster, args.difference_raster)
|
||||
|
||||
print("Aligned raster and difference raster created successfully!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,171 @@
|
||||
from qgis.core import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5 import *
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
QGIS_PREFIX_PATH = "/usr/share/qgis"
|
||||
LAYER_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/diff/diff_ndwi.TIF"
|
||||
STYLE_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/diff.qml"
|
||||
EXPORT_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/maps/diff_ndwi.png"
|
||||
NORTH_ARROW_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg"
|
||||
|
||||
map_pos_x = 20
|
||||
map_pos_y = 30
|
||||
map_size_x = 200
|
||||
map_size_y = 150
|
||||
|
||||
grid_interval_x = 100000
|
||||
grid_interval_y = 100000
|
||||
|
||||
LAYER_NAME = "DIFF"
|
||||
legend_pos_x = 245
|
||||
legend_pos_y = 30
|
||||
|
||||
scalebar_pos_x = 20
|
||||
scalebar_pos_y = 190
|
||||
|
||||
north_arrow_pos_x = 30
|
||||
north_arrow_pos_y = 40
|
||||
north_arrow_size_x = 15
|
||||
north_arrow_size_y = 15
|
||||
|
||||
title_text = "Difference NDWI Landsat 8 and Sentinel 2 - Lab 3"
|
||||
title_fontsize = 16
|
||||
title_height = 10
|
||||
|
||||
author_text = "Author: Joaquin Gottlebe"
|
||||
author_pos_y = 100
|
||||
|
||||
date_text = f"Date: {datetime.now().strftime('%d.%m.%Y')}"
|
||||
date_pos_y = 110
|
||||
|
||||
crs_text = "CRS: EPSG 32633"
|
||||
crs_pos_y = 120
|
||||
|
||||
fontfamily = "Arial"
|
||||
info_font_size = 12
|
||||
info_pos_x = legend_pos_x
|
||||
|
||||
# Initialize QGIS Application
|
||||
QgsApplication.setPrefixPath(QGIS_PREFIX_PATH, True)
|
||||
qgs = QgsApplication([], False)
|
||||
qgs.initQgis()
|
||||
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Load Layer
|
||||
raster_layer = QgsRasterLayer(LAYER_PATH, LAYER_NAME)
|
||||
if not raster_layer.isValid():
|
||||
raise Exception(f"{LAYER_NAME} layer failed to load!")
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
if not raster_layer.loadNamedStyle(STYLE_PATH):
|
||||
raise Exception(f"Style {STYLE_PATH} failed to load")
|
||||
|
||||
# Create Layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(map_pos_x,map_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.attemptResize(QgsLayoutSize(map_size_x, map_size_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.zoomToExtent(raster_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(grid_interval_x)
|
||||
grid.setIntervalY(grid_interval_y)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0)
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra)
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText(title_text)
|
||||
title_label.setFont(QFont(fontfamily, title_fontsize))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.adjustSizeToText()
|
||||
layout_width = layout.pageCollection().page(0).pageSize().width()
|
||||
title_width = title_label.rectWithFrame().width()
|
||||
center_x = (layout_width - title_width) / 2
|
||||
title_label.attemptMove(QgsLayoutPoint(center_x, title_height, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(legend_pos_x,legend_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box')
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m')
|
||||
scalebar_item.setNumberOfSegments(4)
|
||||
scalebar_item.setNumberOfSegmentsLeft(0)
|
||||
scalebar_item.setUnitsPerSegment(50000)
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(scalebar_pos_x,scalebar_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath(NORTH_ARROW_PATH)
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(north_arrow_pos_x,north_arrow_pos_y,QgsUnitTypes.LayoutMillimeters))
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(north_arrow_size_x,north_arrow_size_y,QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(author_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, author_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Date Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(date_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, date_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# CRS Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(crs_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, crs_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Export Map
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
if os.path.exists(EXPORT_PATH):
|
||||
os.remove(EXPORT_PATH)
|
||||
export_result = exporter.exportToImage(EXPORT_PATH, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print(f"Failed to export {LAYER_NAME} map!")
|
||||
else:
|
||||
print(f"Map exported to: {EXPORT_PATH}")
|
||||
|
||||
# Cleanup QGIS
|
||||
qgs.exitQgis()
|
||||
@@ -0,0 +1,46 @@
|
||||
import argparse
|
||||
import rasterio
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def plot_histogram(tiff_path, output_path=None):
|
||||
"""Plot a linear histogram for a given TIFF file and save it if an output path is provided."""
|
||||
try:
|
||||
with rasterio.open(tiff_path) as src:
|
||||
data = src.read(1) # Read the first band
|
||||
|
||||
# Mask nodata values
|
||||
if src.nodata is not None:
|
||||
data = np.ma.masked_equal(data, src.nodata)
|
||||
|
||||
# Flatten the array to 1D for histogram plotting
|
||||
data = data.compressed() if np.ma.isMaskedArray(data) else data.flatten()
|
||||
|
||||
# Plot the histogram
|
||||
plt.figure(figsize=(10, 6))
|
||||
plt.hist(data, bins=256, range=(np.min(data), np.max(data)), edgecolor='black', alpha=0.7)
|
||||
plt.title(f"Histogram of {tiff_path}")
|
||||
plt.xlabel("Pixel Value")
|
||||
plt.ylabel("Frequency")
|
||||
plt.grid(axis='y', alpha=0.75)
|
||||
|
||||
# Save the plot if an output path is specified
|
||||
if output_path:
|
||||
plt.savefig(output_path, dpi=300)
|
||||
print(f"Histogram saved to {output_path}")
|
||||
else:
|
||||
plt.show()
|
||||
except Exception as e:
|
||||
print(f"Error processing file {tiff_path}: {e}")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Plot a histogram for a TIFF file.")
|
||||
parser.add_argument("tiff_path", help="Path to the TIFF file.")
|
||||
parser.add_argument("--output", help="Path to save the histogram plot (optional).", default=None)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
plot_histogram(args.tiff_path, args.output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,77 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
def handle_nodata(array):
|
||||
# Normalize the reflectance values to [0, 1]
|
||||
normalized_array = array / 10000.0
|
||||
# Replace out-of-range values with NaN
|
||||
clean_array = np.where((normalized_array < 0) | (normalized_array > 1), np.nan, normalized_array)
|
||||
return clean_array
|
||||
|
||||
|
||||
def ndvi_calc(NIR,RED):
|
||||
ndvi_array = (NIR - RED) / (NIR + RED + 1e-10)
|
||||
return ndvi_array
|
||||
|
||||
def save_tif(array,data,output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
def get_output_path(output_dir,input_path):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
basename_no_ext = re.sub(r'_B[1-9]|_B10|_B11', '', basename_no_ext)
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_ndvi.TIF")
|
||||
return path
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label," Min:", np.nanmin(array), " Max:",np.nanmax(array))
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python3 script.py <red_band_path> <nir_band_path> <output_directory>")
|
||||
sys.exit(1)
|
||||
|
||||
red_path = sys.argv[1]
|
||||
nir_path = sys.argv[2]
|
||||
output_dir = sys.argv[3]
|
||||
|
||||
red_data, red_array = tif_to_array(red_path)
|
||||
nir_data, nir_array = tif_to_array(nir_path)
|
||||
red_array = handle_nodata(red_array)
|
||||
nir_array = handle_nodata(nir_array)
|
||||
|
||||
ndvi_array = ndvi_calc(nir_array, red_array)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
output_path = get_output_path(output_dir,red_path)
|
||||
|
||||
save_tif(ndvi_array, red_data, output_path)
|
||||
|
||||
print_min_max(red_array, "RED")
|
||||
print_min_max(nir_array, "NIR")
|
||||
print_min_max(ndvi_array, "NDVI")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,171 @@
|
||||
from qgis.core import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5 import *
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
QGIS_PREFIX_PATH = "/usr/share/qgis"
|
||||
LAYER_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndvi/B04_ndvi.TIF"
|
||||
STYLE_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndvi.qml"
|
||||
EXPORT_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/maps/ndvi.png"
|
||||
NORTH_ARROW_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg"
|
||||
|
||||
map_pos_x = 20
|
||||
map_pos_y = 30
|
||||
map_size_x = 200
|
||||
map_size_y = 150
|
||||
|
||||
grid_interval_x = 100000
|
||||
grid_interval_y = 100000
|
||||
|
||||
LAYER_NAME = "NDVI"
|
||||
legend_pos_x = 245
|
||||
legend_pos_y = 30
|
||||
|
||||
scalebar_pos_x = 20
|
||||
scalebar_pos_y = 190
|
||||
|
||||
north_arrow_pos_x = 30
|
||||
north_arrow_pos_y = 40
|
||||
north_arrow_size_x = 15
|
||||
north_arrow_size_y = 15
|
||||
|
||||
title_text = "NDVI - Lab 3"
|
||||
title_fontsize = 16
|
||||
title_height = 10
|
||||
|
||||
author_text = "Author: Joaquin Gottlebe"
|
||||
author_pos_y = 100
|
||||
|
||||
date_text = f"Date: {datetime.now().strftime('%d.%m.%Y')}"
|
||||
date_pos_y = 110
|
||||
|
||||
crs_text = "CRS: EPSG 32633"
|
||||
crs_pos_y = 120
|
||||
|
||||
fontfamily = "Arial"
|
||||
info_font_size = 12
|
||||
info_pos_x = legend_pos_x
|
||||
|
||||
# Initialize QGIS Application
|
||||
QgsApplication.setPrefixPath(QGIS_PREFIX_PATH, True)
|
||||
qgs = QgsApplication([], False)
|
||||
qgs.initQgis()
|
||||
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Load Layer
|
||||
raster_layer = QgsRasterLayer(LAYER_PATH, LAYER_NAME)
|
||||
if not raster_layer.isValid():
|
||||
raise Exception(f"{LAYER_NAME} layer failed to load!")
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
if not raster_layer.loadNamedStyle(STYLE_PATH):
|
||||
raise Exception(f"Style {STYLE_PATH} failed to load")
|
||||
|
||||
# Create Layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(map_pos_x,map_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.attemptResize(QgsLayoutSize(map_size_x, map_size_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.zoomToExtent(raster_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(grid_interval_x)
|
||||
grid.setIntervalY(grid_interval_y)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0)
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra)
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText(title_text)
|
||||
title_label.setFont(QFont(fontfamily, title_fontsize))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.adjustSizeToText()
|
||||
layout_width = layout.pageCollection().page(0).pageSize().width()
|
||||
title_width = title_label.rectWithFrame().width()
|
||||
center_x = (layout_width - title_width) / 2
|
||||
title_label.attemptMove(QgsLayoutPoint(center_x, title_height, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(legend_pos_x,legend_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box')
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m')
|
||||
scalebar_item.setNumberOfSegments(4)
|
||||
scalebar_item.setNumberOfSegmentsLeft(0)
|
||||
scalebar_item.setUnitsPerSegment(50000)
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(scalebar_pos_x,scalebar_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath(NORTH_ARROW_PATH)
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(north_arrow_pos_x,north_arrow_pos_y,QgsUnitTypes.LayoutMillimeters))
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(north_arrow_size_x,north_arrow_size_y,QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(author_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, author_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Date Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(date_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, date_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# CRS Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(crs_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, crs_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Export Map
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
if os.path.exists(EXPORT_PATH):
|
||||
os.remove(EXPORT_PATH)
|
||||
export_result = exporter.exportToImage(EXPORT_PATH, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print(f"Failed to export {LAYER_NAME} map!")
|
||||
else:
|
||||
print(f"Map exported to: {EXPORT_PATH}")
|
||||
|
||||
# Cleanup QGIS
|
||||
qgs.exitQgis()
|
||||
@@ -0,0 +1,171 @@
|
||||
from qgis.core import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5 import *
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
QGIS_PREFIX_PATH = "/usr/share/qgis"
|
||||
LAYER_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndvi2/B04_ndvi.TIF"
|
||||
STYLE_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndvi2.qml"
|
||||
EXPORT_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/maps/ndvi2.png"
|
||||
NORTH_ARROW_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg"
|
||||
|
||||
map_pos_x = 20
|
||||
map_pos_y = 30
|
||||
map_size_x = 200
|
||||
map_size_y = 150
|
||||
|
||||
grid_interval_x = 100000
|
||||
grid_interval_y = 100000
|
||||
|
||||
LAYER_NAME = "NDVI"
|
||||
legend_pos_x = 245
|
||||
legend_pos_y = 30
|
||||
|
||||
scalebar_pos_x = 20
|
||||
scalebar_pos_y = 190
|
||||
|
||||
north_arrow_pos_x = 30
|
||||
north_arrow_pos_y = 40
|
||||
north_arrow_size_x = 15
|
||||
north_arrow_size_y = 15
|
||||
|
||||
title_text = "Chacao Channel 18.11.24 NDVI - Lab 3"
|
||||
title_fontsize = 16
|
||||
title_height = 10
|
||||
|
||||
author_text = "Author: Joaquin Gottlebe"
|
||||
author_pos_y = 100
|
||||
|
||||
date_text = f"Date: {datetime.now().strftime('%d.%m.%Y')}"
|
||||
date_pos_y = 110
|
||||
|
||||
crs_text = "CRS: EPSG 32633"
|
||||
crs_pos_y = 120
|
||||
|
||||
fontfamily = "Arial"
|
||||
info_font_size = 12
|
||||
info_pos_x = legend_pos_x
|
||||
|
||||
# Initialize QGIS Application
|
||||
QgsApplication.setPrefixPath(QGIS_PREFIX_PATH, True)
|
||||
qgs = QgsApplication([], False)
|
||||
qgs.initQgis()
|
||||
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Load Layer
|
||||
raster_layer = QgsRasterLayer(LAYER_PATH, LAYER_NAME)
|
||||
if not raster_layer.isValid():
|
||||
raise Exception(f"{LAYER_NAME} layer failed to load!")
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
if not raster_layer.loadNamedStyle(STYLE_PATH):
|
||||
raise Exception(f"Style {STYLE_PATH} failed to load")
|
||||
|
||||
# Create Layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(map_pos_x,map_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.attemptResize(QgsLayoutSize(map_size_x, map_size_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.zoomToExtent(raster_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(grid_interval_x)
|
||||
grid.setIntervalY(grid_interval_y)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0)
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra)
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText(title_text)
|
||||
title_label.setFont(QFont(fontfamily, title_fontsize))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.adjustSizeToText()
|
||||
layout_width = layout.pageCollection().page(0).pageSize().width()
|
||||
title_width = title_label.rectWithFrame().width()
|
||||
center_x = (layout_width - title_width) / 2
|
||||
title_label.attemptMove(QgsLayoutPoint(center_x, title_height, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(legend_pos_x,legend_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box')
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m')
|
||||
scalebar_item.setNumberOfSegments(4)
|
||||
scalebar_item.setNumberOfSegmentsLeft(0)
|
||||
scalebar_item.setUnitsPerSegment(50000)
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(scalebar_pos_x,scalebar_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath(NORTH_ARROW_PATH)
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(north_arrow_pos_x,north_arrow_pos_y,QgsUnitTypes.LayoutMillimeters))
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(north_arrow_size_x,north_arrow_size_y,QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(author_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, author_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Date Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(date_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, date_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# CRS Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(crs_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, crs_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Export Map
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
if os.path.exists(EXPORT_PATH):
|
||||
os.remove(EXPORT_PATH)
|
||||
export_result = exporter.exportToImage(EXPORT_PATH, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print(f"Failed to export {LAYER_NAME} map!")
|
||||
else:
|
||||
print(f"Map exported to: {EXPORT_PATH}")
|
||||
|
||||
# Cleanup QGIS
|
||||
qgs.exitQgis()
|
||||
@@ -0,0 +1,84 @@
|
||||
from osgeo import gdal
|
||||
import numpy as np
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def tif_to_array(path):
|
||||
data = gdal.Open(path)
|
||||
if data is None:
|
||||
raise FileNotFoundError(f"Cannot open file: {path}")
|
||||
band = data.GetRasterBand(1)
|
||||
array = band.ReadAsArray().astype(np.float32)
|
||||
return data, array
|
||||
|
||||
|
||||
def handle_nodata(array):
|
||||
# Normalize the reflectance values to [0, 1]
|
||||
normalized_array = array / 10000.0
|
||||
# Replace out-of-range values with NaN
|
||||
clean_array = np.where((normalized_array < 0) | (normalized_array > 1), np.nan, normalized_array)
|
||||
return clean_array
|
||||
|
||||
|
||||
def ndwi_calc(GREEN, NIR):
|
||||
ndwi_array = (GREEN - NIR) / (GREEN + NIR + 1e-10)
|
||||
return ndwi_array
|
||||
|
||||
|
||||
def save_tif(array, data, output_path):
|
||||
driver = gdal.GetDriverByName('GTiff')
|
||||
rows, cols = array.shape
|
||||
out_data = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
|
||||
out_data.SetGeoTransform(data.GetGeoTransform())
|
||||
out_data.SetProjection(data.GetProjection())
|
||||
out_band = out_data.GetRasterBand(1)
|
||||
out_band.WriteArray(array)
|
||||
out_band.SetNoDataValue(-9999)
|
||||
out_band.FlushCache()
|
||||
out_data = None
|
||||
|
||||
|
||||
def get_output_path(output_dir, input_path):
|
||||
basename = os.path.basename(input_path)
|
||||
basename_no_ext = os.path.splitext(basename)[0]
|
||||
basename_no_ext = re.sub(r'_B[1-9]|_B10|_B11', '', basename_no_ext)
|
||||
path = os.path.join(output_dir, f"{basename_no_ext}_ndwi.TIF")
|
||||
return path
|
||||
|
||||
|
||||
def print_min_max(array, label):
|
||||
print(label, " Min:", np.nanmin(array), " Max:", np.nanmax(array))
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python3 script.py <green_band_path> <nir_band_path> <output_directory>")
|
||||
sys.exit(1)
|
||||
|
||||
green_path = sys.argv[1]
|
||||
nir_path = sys.argv[2]
|
||||
output_dir = sys.argv[3]
|
||||
|
||||
green_data, green_array = tif_to_array(green_path)
|
||||
nir_data, nir_array = tif_to_array(nir_path)
|
||||
green_array = handle_nodata(green_array)
|
||||
nir_array = handle_nodata(nir_array)
|
||||
|
||||
ndwi_array = ndwi_calc(green_array, nir_array)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
output_path = get_output_path(output_dir, green_path)
|
||||
|
||||
save_tif(ndwi_array, green_data, output_path)
|
||||
|
||||
print_min_max(nir_array, "NIR")
|
||||
print_min_max(green_array, "GREEN")
|
||||
print_min_max(ndwi_array, "NDWI")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,171 @@
|
||||
from qgis.core import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5 import *
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
QGIS_PREFIX_PATH = "/usr/share/qgis"
|
||||
LAYER_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndwi/B03_ndwi.TIF"
|
||||
STYLE_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndwi.qml"
|
||||
EXPORT_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/maps/ndwi.png"
|
||||
NORTH_ARROW_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg"
|
||||
|
||||
map_pos_x = 20
|
||||
map_pos_y = 30
|
||||
map_size_x = 200
|
||||
map_size_y = 150
|
||||
|
||||
grid_interval_x = 100000
|
||||
grid_interval_y = 100000
|
||||
|
||||
LAYER_NAME = "NDWI"
|
||||
legend_pos_x = 245
|
||||
legend_pos_y = 30
|
||||
|
||||
scalebar_pos_x = 20
|
||||
scalebar_pos_y = 190
|
||||
|
||||
north_arrow_pos_x = 30
|
||||
north_arrow_pos_y = 40
|
||||
north_arrow_size_x = 15
|
||||
north_arrow_size_y = 15
|
||||
|
||||
title_text = "NDWI - Lab 3"
|
||||
title_fontsize = 16
|
||||
title_height = 10
|
||||
|
||||
author_text = "Author: Joaquin Gottlebe"
|
||||
author_pos_y = 100
|
||||
|
||||
date_text = f"Date: {datetime.now().strftime('%d.%m.%Y')}"
|
||||
date_pos_y = 110
|
||||
|
||||
crs_text = "CRS: EPSG 32633"
|
||||
crs_pos_y = 120
|
||||
|
||||
info_font_size = 12
|
||||
info_pos_x = legend_pos_x
|
||||
fontfamily = "Arial"
|
||||
|
||||
# Initialize QGIS Application
|
||||
QgsApplication.setPrefixPath(QGIS_PREFIX_PATH, True)
|
||||
qgs = QgsApplication([], False)
|
||||
qgs.initQgis()
|
||||
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Load Layer
|
||||
raster_layer = QgsRasterLayer(LAYER_PATH, LAYER_NAME)
|
||||
if not raster_layer.isValid():
|
||||
raise Exception(f"{LAYER_NAME} layer failed to load!")
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
if not raster_layer.loadNamedStyle(STYLE_PATH):
|
||||
raise Exception(f"Style {STYLE_PATH} failed to load")
|
||||
|
||||
# Create Layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(map_pos_x,map_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.attemptResize(QgsLayoutSize(map_size_x, map_size_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.zoomToExtent(raster_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(grid_interval_x)
|
||||
grid.setIntervalY(grid_interval_y)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0)
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra)
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText(title_text)
|
||||
title_label.setFont(QFont(fontfamily, title_fontsize))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.adjustSizeToText()
|
||||
layout_width = layout.pageCollection().page(0).pageSize().width()
|
||||
title_width = title_label.rectWithFrame().width()
|
||||
center_x = (layout_width - title_width) / 2
|
||||
title_label.attemptMove(QgsLayoutPoint(center_x, title_height, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(legend_pos_x,legend_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box')
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m')
|
||||
scalebar_item.setNumberOfSegments(4)
|
||||
scalebar_item.setNumberOfSegmentsLeft(0)
|
||||
scalebar_item.setUnitsPerSegment(50000)
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(scalebar_pos_x,scalebar_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath(NORTH_ARROW_PATH)
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(north_arrow_pos_x,north_arrow_pos_y,QgsUnitTypes.LayoutMillimeters))
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(north_arrow_size_x,north_arrow_size_y,QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(author_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, author_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Date Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(date_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, date_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# CRS Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(crs_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, crs_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Export Map
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
if os.path.exists(EXPORT_PATH):
|
||||
os.remove(EXPORT_PATH)
|
||||
export_result = exporter.exportToImage(EXPORT_PATH, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print(f"Failed to export {LAYER_NAME} map!")
|
||||
else:
|
||||
print(f"Map exported to: {EXPORT_PATH}")
|
||||
|
||||
# Cleanup QGIS
|
||||
qgs.exitQgis()
|
||||
@@ -0,0 +1,171 @@
|
||||
from qgis.core import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5 import *
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
QGIS_PREFIX_PATH = "/usr/share/qgis"
|
||||
LAYER_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/ndwi2/B03_ndwi.TIF"
|
||||
STYLE_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/ndwi2.qml"
|
||||
EXPORT_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/lab3/maps/ndwi2.png"
|
||||
NORTH_ARROW_PATH = "/home/huaqo/dev/courses/2024_Remote_Sensing/styles/north_arrow.svg"
|
||||
|
||||
map_pos_x = 20
|
||||
map_pos_y = 30
|
||||
map_size_x = 200
|
||||
map_size_y = 150
|
||||
|
||||
grid_interval_x = 100000
|
||||
grid_interval_y = 100000
|
||||
|
||||
LAYER_NAME = "NDWI"
|
||||
legend_pos_x = 245
|
||||
legend_pos_y = 30
|
||||
|
||||
scalebar_pos_x = 20
|
||||
scalebar_pos_y = 190
|
||||
|
||||
north_arrow_pos_x = 30
|
||||
north_arrow_pos_y = 40
|
||||
north_arrow_size_x = 15
|
||||
north_arrow_size_y = 15
|
||||
|
||||
title_text = "Chacao Channel 18.11.24 NDWI - Lab 3"
|
||||
title_fontsize = 16
|
||||
title_height = 10
|
||||
|
||||
author_text = "Author: Joaquin Gottlebe"
|
||||
author_pos_y = 100
|
||||
|
||||
date_text = f"Date: {datetime.now().strftime('%d.%m.%Y')}"
|
||||
date_pos_y = 110
|
||||
|
||||
crs_text = "CRS: EPSG 32633"
|
||||
crs_pos_y = 120
|
||||
|
||||
info_font_size = 12
|
||||
info_pos_x = legend_pos_x
|
||||
fontfamily = "Arial"
|
||||
|
||||
# Initialize QGIS Application
|
||||
QgsApplication.setPrefixPath(QGIS_PREFIX_PATH, True)
|
||||
qgs = QgsApplication([], False)
|
||||
qgs.initQgis()
|
||||
|
||||
# Cleanup
|
||||
project = QgsProject.instance()
|
||||
layer_ids = list(project.mapLayers().keys())
|
||||
for layer_id in layer_ids:
|
||||
project.removeMapLayer(layer_id)
|
||||
|
||||
# Load Layer
|
||||
raster_layer = QgsRasterLayer(LAYER_PATH, LAYER_NAME)
|
||||
if not raster_layer.isValid():
|
||||
raise Exception(f"{LAYER_NAME} layer failed to load!")
|
||||
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
if not raster_layer.loadNamedStyle(STYLE_PATH):
|
||||
raise Exception(f"Style {STYLE_PATH} failed to load")
|
||||
|
||||
# Create Layout
|
||||
layout = QgsPrintLayout(project)
|
||||
layout.initializeDefaults()
|
||||
|
||||
# Map
|
||||
map_item = QgsLayoutItemMap(layout)
|
||||
map_item.attemptMove(QgsLayoutPoint(map_pos_x,map_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.attemptResize(QgsLayoutSize(map_size_x, map_size_y, QgsUnitTypes.LayoutMillimeters))
|
||||
map_item.zoomToExtent(raster_layer.extent())
|
||||
layout.addLayoutItem(map_item)
|
||||
|
||||
# Add Coordinate Grid
|
||||
grid = map_item.grid()
|
||||
grid.setEnabled(True)
|
||||
grid.setIntervalX(grid_interval_x)
|
||||
grid.setIntervalY(grid_interval_y)
|
||||
grid.setAnnotationEnabled(True)
|
||||
grid.setAnnotationPrecision(0)
|
||||
grid.setFrameStyle(QgsLayoutItemMapGrid.Zebra)
|
||||
|
||||
# Label
|
||||
title_label = QgsLayoutItemLabel(layout)
|
||||
title_label.setText(title_text)
|
||||
title_label.setFont(QFont(fontfamily, title_fontsize))
|
||||
title_label.setHAlign(Qt.AlignCenter)
|
||||
title_label.adjustSizeToText()
|
||||
layout_width = layout.pageCollection().page(0).pageSize().width()
|
||||
title_width = title_label.rectWithFrame().width()
|
||||
center_x = (layout_width - title_width) / 2
|
||||
title_label.attemptMove(QgsLayoutPoint(center_x, title_height, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(title_label)
|
||||
|
||||
# Legend
|
||||
legend_item = QgsLayoutItemLegend(layout)
|
||||
legend_item.setLinkedMap(map_item)
|
||||
legend_item.setTitle("Legend")
|
||||
legend_item.setFrameEnabled(True)
|
||||
legend_item.attemptMove(QgsLayoutPoint(legend_pos_x,legend_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(legend_item)
|
||||
|
||||
# Scalebar
|
||||
scalebar_item = QgsLayoutItemScaleBar(layout)
|
||||
scalebar_item.setStyle('Single Box')
|
||||
scalebar_item.setLinkedMap(map_item)
|
||||
scalebar_item.setUnitLabel('m')
|
||||
scalebar_item.setNumberOfSegments(4)
|
||||
scalebar_item.setNumberOfSegmentsLeft(0)
|
||||
scalebar_item.setUnitsPerSegment(50000)
|
||||
scalebar_item.applyDefaultSize()
|
||||
scalebar_item.attemptMove(QgsLayoutPoint(scalebar_pos_x,scalebar_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(scalebar_item)
|
||||
|
||||
# North Arrow
|
||||
north_arrow_item = QgsLayoutItemPicture(layout)
|
||||
north_arrow_item.setPicturePath(NORTH_ARROW_PATH)
|
||||
if not north_arrow_item.picturePath():
|
||||
print("North arrow image failed to load!")
|
||||
north_arrow_item.setReferencePoint(QgsLayoutItemPicture.UpperLeft)
|
||||
north_arrow_item.attemptMove(QgsLayoutPoint(north_arrow_pos_x,north_arrow_pos_y,QgsUnitTypes.LayoutMillimeters))
|
||||
north_arrow_item.attemptResize(QgsLayoutSize(north_arrow_size_x,north_arrow_size_y,QgsUnitTypes.LayoutMillimeters))
|
||||
layout.addLayoutItem(north_arrow_item)
|
||||
|
||||
# Author Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(author_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, author_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Date Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(date_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, date_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# CRS Info
|
||||
info_label = QgsLayoutItemLabel(layout)
|
||||
info_label.setText(crs_text)
|
||||
info_label.setFont(QFont(fontfamily, info_font_size))
|
||||
info_label.setHAlign(Qt.AlignLeft)
|
||||
info_label.attemptMove(QgsLayoutPoint(info_pos_x, crs_pos_y, QgsUnitTypes.LayoutMillimeters))
|
||||
info_label.adjustSizeToText()
|
||||
layout.addLayoutItem(info_label)
|
||||
|
||||
# Export Map
|
||||
exporter = QgsLayoutExporter(layout)
|
||||
if os.path.exists(EXPORT_PATH):
|
||||
os.remove(EXPORT_PATH)
|
||||
export_result = exporter.exportToImage(EXPORT_PATH, QgsLayoutExporter.ImageExportSettings())
|
||||
if export_result != QgsLayoutExporter.Success:
|
||||
print(f"Failed to export {LAYER_NAME} map!")
|
||||
else:
|
||||
print(f"Map exported to: {EXPORT_PATH}")
|
||||
|
||||
# Cleanup QGIS
|
||||
qgs.exitQgis()
|
||||
@@ -0,0 +1,223 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis minScale="1e+08" maxScale="0" styleCategories="AllStyleCategories" version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" autoRefreshMode="Disabled" autoRefreshTime="0">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal mode="0" enabled="0" fetchMode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" symbology="Line" zscale="1" zoffset="0">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol type="line" is_animated="0" clip_to_extent="1" force_rhr="0" name="" alpha="1" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer locked="0" pass="0" class="SimpleLine" id="{90717ec5-4c44-421e-8dcf-9d35d592e70c}" enabled="1">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="align_dash_pattern" value="0"/>
|
||||
<Option type="QString" name="capstyle" value="square"/>
|
||||
<Option type="QString" name="customdash" value="5;2"/>
|
||||
<Option type="QString" name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="customdash_unit" value="MM"/>
|
||||
<Option type="QString" name="dash_pattern_offset" value="0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_unit" value="MM"/>
|
||||
<Option type="QString" name="draw_inside_polygon" value="0"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="line_color" value="183,72,75,255"/>
|
||||
<Option type="QString" name="line_style" value="solid"/>
|
||||
<Option type="QString" name="line_width" value="0.6"/>
|
||||
<Option type="QString" name="line_width_unit" value="MM"/>
|
||||
<Option type="QString" name="offset" value="0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="ring_filter" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_end_unit" value="MM"/>
|
||||
<Option type="QString" name="trim_distance_start" value="0"/>
|
||||
<Option type="QString" name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_start_unit" value="MM"/>
|
||||
<Option type="QString" name="tweak_dash_pattern_on_corners" value="0"/>
|
||||
<Option type="QString" name="use_custom_dash" value="0"/>
|
||||
<Option type="QString" name="width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol type="fill" is_animated="0" clip_to_extent="1" force_rhr="0" name="" alpha="1" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer locked="0" pass="0" class="SimpleFill" id="{7e66c755-dd91-48e4-9d02-6cc4716ca573}" enabled="1">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="183,72,75,255"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="35,35,35,255"/>
|
||||
<Option type="QString" name="outline_style" value="no"/>
|
||||
<Option type="QString" name="outline_width" value="0.26"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="style" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option type="bool" name="WMSBackgroundLayer" value="false"/>
|
||||
<Option type="bool" name="WMSPublishDataSourceUrl" value="false"/>
|
||||
<Option type="int" name="embeddedWidgets/count" value="0"/>
|
||||
<Option type="QString" name="identify/format" value="Value"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" zoomedOutResamplingMethod="nearestNeighbour" enabled="false" zoomedInResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer opacity="1" alphaBand="-1" type="singlebandpseudocolor" band="1" classificationMin="-1" classificationMax="1" nodataColor="">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader clip="0" labelPrecision="4" minimumValue="-1" colorRampType="INTERPOLATED" maximumValue="1" classificationMode="1">
|
||||
<colorramp type="gradient" name="[source]">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="color1" value="0,0,4,255"/>
|
||||
<Option type="QString" name="color2" value="252,255,164,255"/>
|
||||
<Option type="QString" name="direction" value="ccw"/>
|
||||
<Option type="QString" name="discrete" value="0"/>
|
||||
<Option type="QString" name="rampType" value="gradient"/>
|
||||
<Option type="QString" name="spec" value="rgb"/>
|
||||
<Option type="QString" name="stops" value="0.0196078;2,2,12,255;rgb;ccw:0.0392157;5,4,23,255;rgb;ccw:0.0588235;10,7,34,255;rgb;ccw:0.0784314;16,9,45,255;rgb;ccw:0.0980392;22,11,57,255;rgb;ccw:0.117647;30,12,69,255;rgb;ccw:0.137255;38,12,81,255;rgb;ccw:0.156863;47,10,91,255;rgb;ccw:0.176471;56,9,98,255;rgb;ccw:0.196078;64,10,103,255;rgb;ccw:0.215686;73,11,106,255;rgb;ccw:0.235294;81,14,108,255;rgb;ccw:0.254902;89,16,110,255;rgb;ccw:0.27451;97,19,110,255;rgb;ccw:0.294118;105,22,110,255;rgb;ccw:0.313725;113,25,110,255;rgb;ccw:0.333333;120,28,109,255;rgb;ccw:0.352941;128,31,108,255;rgb;ccw:0.372549;136,34,106,255;rgb;ccw:0.392157;144,37,104,255;rgb;ccw:0.411765;152,39,102,255;rgb;ccw:0.431373;160,42,99,255;rgb;ccw:0.45098;168,46,95,255;rgb;ccw:0.470588;176,49,91,255;rgb;ccw:0.490196;183,53,87,255;rgb;ccw:0.509804;191,57,82,255;rgb;ccw:0.529412;198,61,77,255;rgb;ccw:0.54902;204,66,72,255;rgb;ccw:0.568627;211,71,67,255;rgb;ccw:0.588235;217,77,61,255;rgb;ccw:0.607843;223,83,55,255;rgb;ccw:0.627451;228,90,49,255;rgb;ccw:0.647059;233,97,43,255;rgb;ccw:0.666667;237,105,37,255;rgb;ccw:0.686275;241,113,31,255;rgb;ccw:0.705882;244,121,24,255;rgb;ccw:0.72549;247,130,18,255;rgb;ccw:0.745098;249,139,11,255;rgb;ccw:0.764706;250,148,7,255;rgb;ccw:0.784314;251,157,7,255;rgb;ccw:0.803922;252,166,12,255;rgb;ccw:0.823529;252,176,20,255;rgb;ccw:0.843137;251,186,31,255;rgb;ccw:0.862745;250,196,42,255;rgb;ccw:0.882353;248,205,55,255;rgb;ccw:0.901961;246,215,70,255;rgb;ccw:0.921569;244,225,86,255;rgb;ccw:0.941176;242,234,105,255;rgb;ccw:0.960784;242,242,125,255;rgb;ccw:0.980392;245,249,146,255;rgb;ccw"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item color="#000004" label="-1.0000" alpha="255" value="-1"/>
|
||||
<item color="#02020c" label="-0.9608" alpha="255" value="-0.9607844"/>
|
||||
<item color="#050417" label="-0.9216" alpha="255" value="-0.9215686"/>
|
||||
<item color="#0a0722" label="-0.8824" alpha="255" value="-0.882353"/>
|
||||
<item color="#10092d" label="-0.8431" alpha="255" value="-0.8431372"/>
|
||||
<item color="#160b39" label="-0.8039" alpha="255" value="-0.8039216"/>
|
||||
<item color="#1e0c45" label="-0.7647" alpha="255" value="-0.764706"/>
|
||||
<item color="#260c51" label="-0.7255" alpha="255" value="-0.72549"/>
|
||||
<item color="#2f0a5b" label="-0.6863" alpha="255" value="-0.686274"/>
|
||||
<item color="#380962" label="-0.6471" alpha="255" value="-0.647058"/>
|
||||
<item color="#400a67" label="-0.6078" alpha="255" value="-0.607844"/>
|
||||
<item color="#490b6a" label="-0.5686" alpha="255" value="-0.568628"/>
|
||||
<item color="#510e6c" label="-0.5294" alpha="255" value="-0.529412"/>
|
||||
<item color="#59106e" label="-0.4902" alpha="255" value="-0.490196"/>
|
||||
<item color="#61136e" label="-0.4510" alpha="255" value="-0.45098"/>
|
||||
<item color="#69166e" label="-0.4118" alpha="255" value="-0.411764"/>
|
||||
<item color="#71196e" label="-0.3726" alpha="255" value="-0.37255"/>
|
||||
<item color="#781c6d" label="-0.3333" alpha="255" value="-0.333334"/>
|
||||
<item color="#801f6c" label="-0.2941" alpha="255" value="-0.294118"/>
|
||||
<item color="#88226a" label="-0.2549" alpha="255" value="-0.254902"/>
|
||||
<item color="#902568" label="-0.2157" alpha="255" value="-0.215686"/>
|
||||
<item color="#982766" label="-0.1765" alpha="255" value="-0.17647"/>
|
||||
<item color="#a02a63" label="-0.1373" alpha="255" value="-0.137254"/>
|
||||
<item color="#a82e5f" label="-0.0980" alpha="255" value="-0.09804"/>
|
||||
<item color="#b0315b" label="-0.0588" alpha="255" value="-0.058824"/>
|
||||
<item color="#b73557" label="-0.0196" alpha="255" value="-0.019608"/>
|
||||
<item color="#bf3952" label="0.0196" alpha="255" value="0.0196080000000001"/>
|
||||
<item color="#c63d4d" label="0.0588" alpha="255" value="0.058824"/>
|
||||
<item color="#cc4248" label="0.0980" alpha="255" value="0.0980399999999999"/>
|
||||
<item color="#d34743" label="0.1373" alpha="255" value="0.137254"/>
|
||||
<item color="#d94d3d" label="0.1765" alpha="255" value="0.17647"/>
|
||||
<item color="#df5337" label="0.2157" alpha="255" value="0.215686"/>
|
||||
<item color="#e45a31" label="0.2549" alpha="255" value="0.254902"/>
|
||||
<item color="#e9612b" label="0.2941" alpha="255" value="0.294118"/>
|
||||
<item color="#ed6925" label="0.3333" alpha="255" value="0.333334"/>
|
||||
<item color="#f1711f" label="0.3725" alpha="255" value="0.37255"/>
|
||||
<item color="#f47918" label="0.4118" alpha="255" value="0.411764"/>
|
||||
<item color="#f78212" label="0.4510" alpha="255" value="0.45098"/>
|
||||
<item color="#f98b0b" label="0.4902" alpha="255" value="0.490196"/>
|
||||
<item color="#fa9407" label="0.5294" alpha="255" value="0.529412"/>
|
||||
<item color="#fb9d07" label="0.5686" alpha="255" value="0.568628"/>
|
||||
<item color="#fca60c" label="0.6078" alpha="255" value="0.607844"/>
|
||||
<item color="#fcb014" label="0.6471" alpha="255" value="0.647058"/>
|
||||
<item color="#fbba1f" label="0.6863" alpha="255" value="0.686274"/>
|
||||
<item color="#fac42a" label="0.7255" alpha="255" value="0.72549"/>
|
||||
<item color="#f8cd37" label="0.7647" alpha="255" value="0.764706"/>
|
||||
<item color="#f6d746" label="0.8039" alpha="255" value="0.803922"/>
|
||||
<item color="#f4e156" label="0.8431" alpha="255" value="0.843138"/>
|
||||
<item color="#f2ea69" label="0.8824" alpha="255" value="0.882352"/>
|
||||
<item color="#f2f27d" label="0.9216" alpha="255" value="0.921568"/>
|
||||
<item color="#f5f992" label="0.9608" alpha="255" value="0.960784"/>
|
||||
<item color="#fcffa4" label="1.0000" alpha="255" value="1"/>
|
||||
<rampLegendSettings maximumLabel="" useContinuousLegend="1" direction="0" orientation="2" minimumLabel="" suffix="" prefix="">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option type="invalid" name="decimal_separator"/>
|
||||
<Option type="int" name="decimals" value="6"/>
|
||||
<Option type="int" name="rounding_type" value="0"/>
|
||||
<Option type="bool" name="show_plus" value="false"/>
|
||||
<Option type="bool" name="show_thousand_separator" value="true"/>
|
||||
<Option type="bool" name="show_trailing_zeros" value="false"/>
|
||||
<Option type="invalid" name="thousand_separator"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation colorizeGreen="128" colorizeBlue="128" colorizeOn="0" grayscaleMode="0" colorizeRed="255" colorizeStrength="100" saturation="0" invertColors="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" minScale="1e+08" maxScale="0" autoRefreshMode="Disabled" autoRefreshTime="0">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal enabled="0" mode="0" fetchMode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" zoffset="0" zscale="1" symbology="Line">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="line" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleLine" locked="0" enabled="1" pass="0" id="{3d86879d-0528-4a95-93c6-173beb7dfe55}">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" value="0" type="QString"/>
|
||||
<Option name="capstyle" value="square" type="QString"/>
|
||||
<Option name="customdash" value="5;2" type="QString"/>
|
||||
<Option name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="customdash_unit" value="MM" type="QString"/>
|
||||
<Option name="dash_pattern_offset" value="0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_unit" value="MM" type="QString"/>
|
||||
<Option name="draw_inside_polygon" value="0" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="line_color" value="243,166,178,255" type="QString"/>
|
||||
<Option name="line_style" value="solid" type="QString"/>
|
||||
<Option name="line_width" value="0.6" type="QString"/>
|
||||
<Option name="line_width_unit" value="MM" type="QString"/>
|
||||
<Option name="offset" value="0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="ring_filter" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_end_unit" value="MM" type="QString"/>
|
||||
<Option name="trim_distance_start" value="0" type="QString"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_start_unit" value="MM" type="QString"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" value="0" type="QString"/>
|
||||
<Option name="use_custom_dash" value="0" type="QString"/>
|
||||
<Option name="width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="fill" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleFill" locked="0" enabled="1" pass="0" id="{6c6808b7-5fd3-4cca-9202-5fcfee4e7b68}">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="color" value="243,166,178,255" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="offset" value="0,0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="outline_color" value="35,35,35,255" type="QString"/>
|
||||
<Option name="outline_style" value="no" type="QString"/>
|
||||
<Option name="outline_width" value="0.26" type="QString"/>
|
||||
<Option name="outline_width_unit" value="MM" type="QString"/>
|
||||
<Option name="style" value="solid" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="WMSBackgroundLayer" value="false" type="bool"/>
|
||||
<Option name="WMSPublishDataSourceUrl" value="false" type="bool"/>
|
||||
<Option name="embeddedWidgets/count" value="0" type="int"/>
|
||||
<Option name="identify/format" value="Value" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" enabled="false" zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer nodataColor="" redBand="3" alphaBand="-1" blueBand="1" type="multibandcolor" opacity="1" greenBand="2">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>CumulativeCut</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<redContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.514984</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</redContrastEnhancement>
|
||||
<greenContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.168884</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</greenContrastEnhancement>
|
||||
<blueContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.149555</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</blueContrastEnhancement>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation invertColors="0" grayscaleMode="0" colorizeStrength="100" colorizeOn="0" colorizeRed="255" colorizeGreen="128" colorizeBlue="128" saturation="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis minScale="1e+08" maxScale="0" styleCategories="AllStyleCategories" version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" autoRefreshMode="Disabled" autoRefreshTime="0">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal mode="0" enabled="0" fetchMode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" symbology="Line" zscale="1" zoffset="0">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol type="line" is_animated="0" clip_to_extent="1" force_rhr="0" name="" alpha="1" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer locked="0" pass="0" class="SimpleLine" id="{aaa7f6dd-c35e-4d35-8e65-5347167a8568}" enabled="1">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="align_dash_pattern" value="0"/>
|
||||
<Option type="QString" name="capstyle" value="square"/>
|
||||
<Option type="QString" name="customdash" value="5;2"/>
|
||||
<Option type="QString" name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="customdash_unit" value="MM"/>
|
||||
<Option type="QString" name="dash_pattern_offset" value="0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="dash_pattern_offset_unit" value="MM"/>
|
||||
<Option type="QString" name="draw_inside_polygon" value="0"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="line_color" value="164,113,88,255"/>
|
||||
<Option type="QString" name="line_style" value="solid"/>
|
||||
<Option type="QString" name="line_width" value="0.6"/>
|
||||
<Option type="QString" name="line_width_unit" value="MM"/>
|
||||
<Option type="QString" name="offset" value="0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="ring_filter" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end" value="0"/>
|
||||
<Option type="QString" name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_end_unit" value="MM"/>
|
||||
<Option type="QString" name="trim_distance_start" value="0"/>
|
||||
<Option type="QString" name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="trim_distance_start_unit" value="MM"/>
|
||||
<Option type="QString" name="tweak_dash_pattern_on_corners" value="0"/>
|
||||
<Option type="QString" name="use_custom_dash" value="0"/>
|
||||
<Option type="QString" name="width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol type="fill" is_animated="0" clip_to_extent="1" force_rhr="0" name="" alpha="1" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer locked="0" pass="0" class="SimpleFill" id="{b695104e-c25e-4ec7-bd5b-303e06061048}" enabled="1">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="color" value="164,113,88,255"/>
|
||||
<Option type="QString" name="joinstyle" value="bevel"/>
|
||||
<Option type="QString" name="offset" value="0,0"/>
|
||||
<Option type="QString" name="offset_map_unit_scale" value="3x:0,0,0,0,0,0"/>
|
||||
<Option type="QString" name="offset_unit" value="MM"/>
|
||||
<Option type="QString" name="outline_color" value="35,35,35,255"/>
|
||||
<Option type="QString" name="outline_style" value="no"/>
|
||||
<Option type="QString" name="outline_width" value="0.26"/>
|
||||
<Option type="QString" name="outline_width_unit" value="MM"/>
|
||||
<Option type="QString" name="style" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option type="bool" name="WMSBackgroundLayer" value="false"/>
|
||||
<Option type="bool" name="WMSPublishDataSourceUrl" value="false"/>
|
||||
<Option type="int" name="embeddedWidgets/count" value="0"/>
|
||||
<Option type="QString" name="identify/format" value="Value"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="name" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option type="QString" name="type" value="collection"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" zoomedOutResamplingMethod="nearestNeighbour" enabled="false" zoomedInResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer opacity="1" alphaBand="-1" type="singlebandpseudocolor" band="1" classificationMin="0" classificationMax="1" nodataColor="">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader clip="0" labelPrecision="4" minimumValue="0" colorRampType="INTERPOLATED" maximumValue="1" classificationMode="1">
|
||||
<colorramp type="gradient" name="[source]">
|
||||
<Option type="Map">
|
||||
<Option type="QString" name="color1" value="215,25,28,255"/>
|
||||
<Option type="QString" name="color2" value="26,150,65,255"/>
|
||||
<Option type="QString" name="direction" value="ccw"/>
|
||||
<Option type="QString" name="discrete" value="0"/>
|
||||
<Option type="QString" name="rampType" value="gradient"/>
|
||||
<Option type="QString" name="spec" value="rgb"/>
|
||||
<Option type="QString" name="stops" value="0.25;253,174,97,255;rgb;ccw:0.5;255,255,192,255;rgb;ccw:0.75;166,217,106,255;rgb;ccw"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item color="#d7191c" label="0.0000" alpha="255" value="0"/>
|
||||
<item color="#fdae61" label="0.2500" alpha="255" value="0.25"/>
|
||||
<item color="#ffffc0" label="0.5000" alpha="255" value="0.5"/>
|
||||
<item color="#a6d96a" label="0.7500" alpha="255" value="0.75"/>
|
||||
<item color="#1a9641" label="1.0000" alpha="255" value="1"/>
|
||||
<rampLegendSettings maximumLabel="" useContinuousLegend="1" direction="0" orientation="2" minimumLabel="" suffix="" prefix="">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option type="invalid" name="decimal_separator"/>
|
||||
<Option type="int" name="decimals" value="6"/>
|
||||
<Option type="int" name="rounding_type" value="0"/>
|
||||
<Option type="bool" name="show_plus" value="false"/>
|
||||
<Option type="bool" name="show_thousand_separator" value="true"/>
|
||||
<Option type="bool" name="show_trailing_zeros" value="false"/>
|
||||
<Option type="invalid" name="thousand_separator"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation colorizeGreen="128" colorizeBlue="128" colorizeOn="0" grayscaleMode="0" colorizeRed="255" colorizeStrength="100" saturation="0" invertColors="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis minScale="1e+08" autoRefreshTime="0" maxScale="0" version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" autoRefreshMode="Disabled">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal fetchMode="0" enabled="0" mode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation symbology="Line" zscale="1" enabled="0" zoffset="0" band="1">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol force_rhr="0" name="" clip_to_extent="1" frame_rate="10" type="line" alpha="1" is_animated="0">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer id="{aaa7f6dd-c35e-4d35-8e65-5347167a8568}" enabled="1" class="SimpleLine" pass="0" locked="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" value="0" type="QString"/>
|
||||
<Option name="capstyle" value="square" type="QString"/>
|
||||
<Option name="customdash" value="5;2" type="QString"/>
|
||||
<Option name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="customdash_unit" value="MM" type="QString"/>
|
||||
<Option name="dash_pattern_offset" value="0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_unit" value="MM" type="QString"/>
|
||||
<Option name="draw_inside_polygon" value="0" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="line_color" value="164,113,88,255" type="QString"/>
|
||||
<Option name="line_style" value="solid" type="QString"/>
|
||||
<Option name="line_width" value="0.6" type="QString"/>
|
||||
<Option name="line_width_unit" value="MM" type="QString"/>
|
||||
<Option name="offset" value="0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="ring_filter" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_end_unit" value="MM" type="QString"/>
|
||||
<Option name="trim_distance_start" value="0" type="QString"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_start_unit" value="MM" type="QString"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" value="0" type="QString"/>
|
||||
<Option name="use_custom_dash" value="0" type="QString"/>
|
||||
<Option name="width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol force_rhr="0" name="" clip_to_extent="1" frame_rate="10" type="fill" alpha="1" is_animated="0">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer id="{b695104e-c25e-4ec7-bd5b-303e06061048}" enabled="1" class="SimpleFill" pass="0" locked="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="color" value="164,113,88,255" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="offset" value="0,0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="outline_color" value="35,35,35,255" type="QString"/>
|
||||
<Option name="outline_style" value="no" type="QString"/>
|
||||
<Option name="outline_width" value="0.26" type="QString"/>
|
||||
<Option name="outline_width_unit" value="MM" type="QString"/>
|
||||
<Option name="style" value="solid" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="WMSBackgroundLayer" value="false" type="bool"/>
|
||||
<Option name="WMSPublishDataSourceUrl" value="false" type="bool"/>
|
||||
<Option name="embeddedWidgets/count" value="0" type="int"/>
|
||||
<Option name="identify/format" value="Value" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" enabled="false" zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer opacity="1" classificationMin="0" classificationMax="0.7596869" nodataColor="" type="singlebandpseudocolor" alphaBand="-1" band="1">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader maximumValue="0.75968690000000005" labelPrecision="4" colorRampType="INTERPOLATED" minimumValue="0" clip="0" classificationMode="1">
|
||||
<colorramp name="[source]" type="gradient">
|
||||
<Option type="Map">
|
||||
<Option name="color1" value="215,25,28,255" type="QString"/>
|
||||
<Option name="color2" value="26,150,65,255" type="QString"/>
|
||||
<Option name="direction" value="ccw" type="QString"/>
|
||||
<Option name="discrete" value="0" type="QString"/>
|
||||
<Option name="rampType" value="gradient" type="QString"/>
|
||||
<Option name="spec" value="rgb" type="QString"/>
|
||||
<Option name="stops" value="0.25;253,174,97,255;rgb;ccw:0.5;255,255,192,255;rgb;ccw:0.75;166,217,106,255;rgb;ccw" type="QString"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item value="0" color="#d7191c" label="0.0000" alpha="255"/>
|
||||
<item value="0.189921721816063" color="#fdae61" label="0.1899" alpha="255"/>
|
||||
<item value="0.379843443632125" color="#ffffc0" label="0.3798" alpha="255"/>
|
||||
<item value="0.569765165448188" color="#a6d96a" label="0.5698" alpha="255"/>
|
||||
<item value="0.75968688726425" color="#1a9641" label="0.7597" alpha="255"/>
|
||||
<rampLegendSettings orientation="2" maximumLabel="" suffix="" prefix="" useContinuousLegend="1" minimumLabel="" direction="0">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option name="decimal_separator" type="invalid"/>
|
||||
<Option name="decimals" value="6" type="int"/>
|
||||
<Option name="rounding_type" value="0" type="int"/>
|
||||
<Option name="show_plus" value="false" type="bool"/>
|
||||
<Option name="show_thousand_separator" value="true" type="bool"/>
|
||||
<Option name="show_trailing_zeros" value="false" type="bool"/>
|
||||
<Option name="thousand_separator" type="invalid"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation invertColors="0" grayscaleMode="0" colorizeRed="255" colorizeOn="0" colorizeBlue="128" saturation="0" colorizeGreen="128" colorizeStrength="100"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis hasScaleBasedVisibilityFlag="0" minScale="1e+08" maxScale="0" autoRefreshMode="Disabled" autoRefreshTime="0" version="3.34.12-Prizren" styleCategories="AllStyleCategories">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal fetchMode="0" enabled="0" mode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" zscale="1" zoffset="0" symbology="Line">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol is_animated="0" name="" type="line" alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleLine" locked="0" pass="0" id="{99ba9813-b865-4da2-bbb6-acad204f8b25}">
|
||||
<Option type="Map">
|
||||
<Option value="0" name="align_dash_pattern" type="QString"/>
|
||||
<Option value="square" name="capstyle" type="QString"/>
|
||||
<Option value="5;2" name="customdash" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="customdash_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="customdash_unit" type="QString"/>
|
||||
<Option value="0" name="dash_pattern_offset" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="dash_pattern_offset_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="dash_pattern_offset_unit" type="QString"/>
|
||||
<Option value="0" name="draw_inside_polygon" type="QString"/>
|
||||
<Option value="bevel" name="joinstyle" type="QString"/>
|
||||
<Option value="243,166,178,255" name="line_color" type="QString"/>
|
||||
<Option value="solid" name="line_style" type="QString"/>
|
||||
<Option value="0.6" name="line_width" type="QString"/>
|
||||
<Option value="MM" name="line_width_unit" type="QString"/>
|
||||
<Option value="0" name="offset" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="offset_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="offset_unit" type="QString"/>
|
||||
<Option value="0" name="ring_filter" type="QString"/>
|
||||
<Option value="0" name="trim_distance_end" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="trim_distance_end_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="trim_distance_end_unit" type="QString"/>
|
||||
<Option value="0" name="trim_distance_start" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="trim_distance_start_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="trim_distance_start_unit" type="QString"/>
|
||||
<Option value="0" name="tweak_dash_pattern_on_corners" type="QString"/>
|
||||
<Option value="0" name="use_custom_dash" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="width_map_unit_scale" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol is_animated="0" name="" type="fill" alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer enabled="1" class="SimpleFill" locked="0" pass="0" id="{fd457c65-1070-4be2-a580-abb79399910b}">
|
||||
<Option type="Map">
|
||||
<Option value="3x:0,0,0,0,0,0" name="border_width_map_unit_scale" type="QString"/>
|
||||
<Option value="243,166,178,255" name="color" type="QString"/>
|
||||
<Option value="bevel" name="joinstyle" type="QString"/>
|
||||
<Option value="0,0" name="offset" type="QString"/>
|
||||
<Option value="3x:0,0,0,0,0,0" name="offset_map_unit_scale" type="QString"/>
|
||||
<Option value="MM" name="offset_unit" type="QString"/>
|
||||
<Option value="35,35,35,255" name="outline_color" type="QString"/>
|
||||
<Option value="no" name="outline_style" type="QString"/>
|
||||
<Option value="0.26" name="outline_width" type="QString"/>
|
||||
<Option value="MM" name="outline_width_unit" type="QString"/>
|
||||
<Option value="solid" name="style" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option value="false" name="WMSBackgroundLayer" type="bool"/>
|
||||
<Option value="false" name="WMSPublishDataSourceUrl" type="bool"/>
|
||||
<Option value="0" name="embeddedWidgets/count" type="int"/>
|
||||
<Option value="Value" name="identify/format" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option value="" name="name" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option value="collection" name="type" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling enabled="false" zoomedOutResamplingMethod="nearestNeighbour" zoomedInResamplingMethod="nearestNeighbour" maxOversampling="2"/>
|
||||
</provider>
|
||||
<rasterrenderer band="1" alphaBand="-1" classificationMin="0.3" classificationMax="1" opacity="1" nodataColor="" type="singlebandpseudocolor">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader minimumValue="0.29999999999999999" labelPrecision="4" colorRampType="DISCRETE" classificationMode="2" maximumValue="1" clip="0">
|
||||
<colorramp name="[source]" type="gradient">
|
||||
<Option type="Map">
|
||||
<Option value="215,25,28,0" name="color1" type="QString"/>
|
||||
<Option value="29,10,150,255" name="color2" type="QString"/>
|
||||
<Option value="ccw" name="direction" type="QString"/>
|
||||
<Option value="0" name="discrete" type="QString"/>
|
||||
<Option value="gradient" name="rampType" type="QString"/>
|
||||
<Option value="rgb" name="spec" type="QString"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item value="0.3" color="#d7191c" label="<= 0.3000" alpha="0"/>
|
||||
<item value="1" color="#1d0a96" label="0.3000 - 1.0000" alpha="255"/>
|
||||
<rampLegendSettings maximumLabel="" suffix="" orientation="2" prefix="" useContinuousLegend="1" minimumLabel="" direction="0">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option name="decimal_separator" type="invalid"/>
|
||||
<Option value="6" name="decimals" type="int"/>
|
||||
<Option value="0" name="rounding_type" type="int"/>
|
||||
<Option value="false" name="show_plus" type="bool"/>
|
||||
<Option value="true" name="show_thousand_separator" type="bool"/>
|
||||
<Option value="false" name="show_trailing_zeros" type="bool"/>
|
||||
<Option name="thousand_separator" type="invalid"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation colorizeGreen="128" colorizeRed="255" colorizeBlue="128" colorizeOn="0" grayscaleMode="0" colorizeStrength="100" saturation="0" invertColors="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,180 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis minScale="1e+08" autoRefreshTime="0" maxScale="0" version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" autoRefreshMode="Disabled">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal fetchMode="0" enabled="0" mode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation symbology="Line" zscale="1" enabled="0" zoffset="0" band="1">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol force_rhr="0" name="" clip_to_extent="1" frame_rate="10" type="line" alpha="1" is_animated="0">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer id="{f0727dba-6c15-410e-a4de-645ce35a3a77}" enabled="1" class="SimpleLine" pass="0" locked="0">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" value="0" type="QString"/>
|
||||
<Option name="capstyle" value="square" type="QString"/>
|
||||
<Option name="customdash" value="5;2" type="QString"/>
|
||||
<Option name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="customdash_unit" value="MM" type="QString"/>
|
||||
<Option name="dash_pattern_offset" value="0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_unit" value="MM" type="QString"/>
|
||||
<Option name="draw_inside_polygon" value="0" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="line_color" value="231,113,72,255" type="QString"/>
|
||||
<Option name="line_style" value="solid" type="QString"/>
|
||||
<Option name="line_width" value="0.6" type="QString"/>
|
||||
<Option name="line_width_unit" value="MM" type="QString"/>
|
||||
<Option name="offset" value="0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="ring_filter" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_end_unit" value="MM" type="QString"/>
|
||||
<Option name="trim_distance_start" value="0" type="QString"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_start_unit" value="MM" type="QString"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" value="0" type="QString"/>
|
||||
<Option name="use_custom_dash" value="0" type="QString"/>
|
||||
<Option name="width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol force_rhr="0" name="" clip_to_extent="1" frame_rate="10" type="fill" alpha="1" is_animated="0">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer id="{9c243aaf-373e-405c-9930-44db50dc2819}" enabled="1" class="SimpleFill" pass="0" locked="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="color" value="231,113,72,255" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="offset" value="0,0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="outline_color" value="35,35,35,255" type="QString"/>
|
||||
<Option name="outline_style" value="no" type="QString"/>
|
||||
<Option name="outline_width" value="0.26" type="QString"/>
|
||||
<Option name="outline_width_unit" value="MM" type="QString"/>
|
||||
<Option name="style" value="solid" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="WMSBackgroundLayer" value="false" type="bool"/>
|
||||
<Option name="WMSPublishDataSourceUrl" value="false" type="bool"/>
|
||||
<Option name="embeddedWidgets/count" value="0" type="int"/>
|
||||
<Option name="identify/format" value="Value" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" enabled="false" zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer opacity="1" classificationMin="0" classificationMax="0.2" nodataColor="" type="singlebandpseudocolor" alphaBand="-1" band="1">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader maximumValue="0.20000000000000001" labelPrecision="4" colorRampType="INTERPOLATED" minimumValue="0" clip="0" classificationMode="1">
|
||||
<colorramp name="[source]" type="gradient">
|
||||
<Option type="Map">
|
||||
<Option name="color1" value="247,251,255,255" type="QString"/>
|
||||
<Option name="color2" value="8,48,107,255" type="QString"/>
|
||||
<Option name="direction" value="ccw" type="QString"/>
|
||||
<Option name="discrete" value="0" type="QString"/>
|
||||
<Option name="rampType" value="gradient" type="QString"/>
|
||||
<Option name="spec" value="rgb" type="QString"/>
|
||||
<Option name="stops" value="0.13;222,235,247,255;rgb;ccw:0.26;198,219,239,255;rgb;ccw:0.39;158,202,225,255;rgb;ccw:0.52;107,174,214,255;rgb;ccw:0.65;66,146,198,255;rgb;ccw:0.78;33,113,181,255;rgb;ccw:0.9;8,81,156,255;rgb;ccw" type="QString"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item value="0" color="#f7fbff" label="0.0000" alpha="255"/>
|
||||
<item value="0.026" color="#deebf7" label="0.0260" alpha="255"/>
|
||||
<item value="0.052" color="#c6dbef" label="0.0520" alpha="255"/>
|
||||
<item value="0.078" color="#9ecae1" label="0.0780" alpha="255"/>
|
||||
<item value="0.104" color="#6baed6" label="0.1040" alpha="255"/>
|
||||
<item value="0.13" color="#4292c6" label="0.1300" alpha="255"/>
|
||||
<item value="0.156" color="#2171b5" label="0.1560" alpha="255"/>
|
||||
<item value="0.18" color="#08519c" label="0.1800" alpha="255"/>
|
||||
<item value="0.2" color="#08306b" label="0.2000" alpha="255"/>
|
||||
<rampLegendSettings orientation="2" maximumLabel="" suffix="" prefix="" useContinuousLegend="1" minimumLabel="" direction="0">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option name="decimal_separator" type="invalid"/>
|
||||
<Option name="decimals" value="6" type="int"/>
|
||||
<Option name="rounding_type" value="0" type="int"/>
|
||||
<Option name="show_plus" value="false" type="bool"/>
|
||||
<Option name="show_thousand_separator" value="true" type="bool"/>
|
||||
<Option name="show_trailing_zeros" value="false" type="bool"/>
|
||||
<Option name="thousand_separator" type="invalid"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation invertColors="0" grayscaleMode="0" colorizeRed="255" colorizeOn="0" colorizeBlue="128" saturation="0" colorizeGreen="128" colorizeStrength="100"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="348" width="226">
|
||||
<path d="M5.53,240.17l108.38-113.54,106.91,112.07-106.91-229.3z" stroke="#000" stroke-width="6" fill="none"/>
|
||||
<path d="m113.91,9.2162,0,117.41,106.36,111.33z"/>
|
||||
<path d="m145.05,321.47-10.375,0-44.125-74.375,0.125,5.625c0.12498,2.1251,0.18748,3.9167,0.1875,5.375v63.375h-8.625v-85.312h13.375l41.25,69.562-0.125-5.9375c-0.0834-2.3333-0.12506-4.3958-0.125-6.1875v-57.438h8.4375z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 455 B |
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" minScale="1e+08" maxScale="0" autoRefreshMode="Disabled" autoRefreshTime="0">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal enabled="0" mode="0" fetchMode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" zoffset="0" zscale="1" symbology="Line">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="line" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleLine" locked="0" enabled="1" pass="0" id="{cb94a686-abc6-45a2-b47c-962b72fe165b}">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" value="0" type="QString"/>
|
||||
<Option name="capstyle" value="square" type="QString"/>
|
||||
<Option name="customdash" value="5;2" type="QString"/>
|
||||
<Option name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="customdash_unit" value="MM" type="QString"/>
|
||||
<Option name="dash_pattern_offset" value="0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_unit" value="MM" type="QString"/>
|
||||
<Option name="draw_inside_polygon" value="0" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="line_color" value="190,178,151,255" type="QString"/>
|
||||
<Option name="line_style" value="solid" type="QString"/>
|
||||
<Option name="line_width" value="0.6" type="QString"/>
|
||||
<Option name="line_width_unit" value="MM" type="QString"/>
|
||||
<Option name="offset" value="0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="ring_filter" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_end_unit" value="MM" type="QString"/>
|
||||
<Option name="trim_distance_start" value="0" type="QString"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_start_unit" value="MM" type="QString"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" value="0" type="QString"/>
|
||||
<Option name="use_custom_dash" value="0" type="QString"/>
|
||||
<Option name="width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="fill" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleFill" locked="0" enabled="1" pass="0" id="{b9a48ebb-e4c4-4d4e-bda2-50e4d13036b9}">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="color" value="190,178,151,255" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="offset" value="0,0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="outline_color" value="35,35,35,255" type="QString"/>
|
||||
<Option name="outline_style" value="no" type="QString"/>
|
||||
<Option name="outline_width" value="0.26" type="QString"/>
|
||||
<Option name="outline_width_unit" value="MM" type="QString"/>
|
||||
<Option name="style" value="solid" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="WMSBackgroundLayer" value="false" type="bool"/>
|
||||
<Option name="WMSPublishDataSourceUrl" value="false" type="bool"/>
|
||||
<Option name="embeddedWidgets/count" value="0" type="int"/>
|
||||
<Option name="identify/format" value="Value" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" enabled="false" zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer nodataColor="" band="1" alphaBand="-1" classificationMin="0" classificationMax="44.2479858" type="singlebandpseudocolor" opacity="1">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>None</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<rastershader>
|
||||
<colorrampshader classificationMode="1" maximumValue="44.247985800000002" colorRampType="INTERPOLATED" labelPrecision="4" minimumValue="0" clip="0">
|
||||
<colorramp name="[source]" type="gradient">
|
||||
<Option type="Map">
|
||||
<Option name="color1" value="5,113,176,0" type="QString"/>
|
||||
<Option name="color2" value="202,0,32,255" type="QString"/>
|
||||
<Option name="direction" value="ccw" type="QString"/>
|
||||
<Option name="discrete" value="0" type="QString"/>
|
||||
<Option name="rampType" value="gradient" type="QString"/>
|
||||
<Option name="spec" value="rgb" type="QString"/>
|
||||
<Option name="stops" value="0.25;146,197,222,255;rgb;ccw:0.5;247,247,247,255;rgb;ccw:0.75;244,165,130,255;rgb;ccw" type="QString"/>
|
||||
</Option>
|
||||
</colorramp>
|
||||
<item label="0.0000" alpha="0" value="0" color="#0571b0"/>
|
||||
<item label="11.0620" alpha="255" value="11.06199645" color="#92c5de"/>
|
||||
<item label="22.1240" alpha="255" value="22.1239929" color="#f7f7f7"/>
|
||||
<item label="33.1860" alpha="255" value="33.18598935" color="#f4a582"/>
|
||||
<item label="44.2480" alpha="255" value="44.2479858" color="#ca0020"/>
|
||||
<rampLegendSettings minimumLabel="" useContinuousLegend="1" maximumLabel="" direction="0" suffix="" orientation="2" prefix="">
|
||||
<numericFormat id="basic">
|
||||
<Option type="Map">
|
||||
<Option name="decimal_separator" type="invalid"/>
|
||||
<Option name="decimals" value="6" type="int"/>
|
||||
<Option name="rounding_type" value="0" type="int"/>
|
||||
<Option name="show_plus" value="false" type="bool"/>
|
||||
<Option name="show_thousand_separator" value="true" type="bool"/>
|
||||
<Option name="show_trailing_zeros" value="false" type="bool"/>
|
||||
<Option name="thousand_separator" type="invalid"/>
|
||||
</Option>
|
||||
</numericFormat>
|
||||
</rampLegendSettings>
|
||||
</colorrampshader>
|
||||
</rastershader>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation invertColors="0" grayscaleMode="0" colorizeStrength="100" colorizeOn="0" colorizeRed="255" colorizeGreen="128" colorizeBlue="128" saturation="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis version="3.34.12-Prizren" hasScaleBasedVisibilityFlag="0" styleCategories="AllStyleCategories" minScale="1e+08" maxScale="0" autoRefreshMode="Disabled" autoRefreshTime="0">
|
||||
<flags>
|
||||
<Identifiable>1</Identifiable>
|
||||
<Removable>1</Removable>
|
||||
<Searchable>1</Searchable>
|
||||
<Private>0</Private>
|
||||
</flags>
|
||||
<temporal enabled="0" mode="0" fetchMode="0">
|
||||
<fixedRange>
|
||||
<start></start>
|
||||
<end></end>
|
||||
</fixedRange>
|
||||
</temporal>
|
||||
<elevation band="1" enabled="0" zoffset="0" zscale="1" symbology="Line">
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
<profileLineSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="line" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleLine" locked="0" enabled="1" pass="0" id="{42348ace-1922-48ab-bbe5-7063be49abaf}">
|
||||
<Option type="Map">
|
||||
<Option name="align_dash_pattern" value="0" type="QString"/>
|
||||
<Option name="capstyle" value="square" type="QString"/>
|
||||
<Option name="customdash" value="5;2" type="QString"/>
|
||||
<Option name="customdash_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="customdash_unit" value="MM" type="QString"/>
|
||||
<Option name="dash_pattern_offset" value="0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="dash_pattern_offset_unit" value="MM" type="QString"/>
|
||||
<Option name="draw_inside_polygon" value="0" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="line_color" value="152,125,183,255" type="QString"/>
|
||||
<Option name="line_style" value="solid" type="QString"/>
|
||||
<Option name="line_width" value="0.6" type="QString"/>
|
||||
<Option name="line_width_unit" value="MM" type="QString"/>
|
||||
<Option name="offset" value="0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="ring_filter" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end" value="0" type="QString"/>
|
||||
<Option name="trim_distance_end_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_end_unit" value="MM" type="QString"/>
|
||||
<Option name="trim_distance_start" value="0" type="QString"/>
|
||||
<Option name="trim_distance_start_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="trim_distance_start_unit" value="MM" type="QString"/>
|
||||
<Option name="tweak_dash_pattern_on_corners" value="0" type="QString"/>
|
||||
<Option name="use_custom_dash" value="0" type="QString"/>
|
||||
<Option name="width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileLineSymbol>
|
||||
<profileFillSymbol>
|
||||
<symbol name="" is_animated="0" alpha="1" clip_to_extent="1" force_rhr="0" type="fill" frame_rate="10">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleFill" locked="0" enabled="1" pass="0" id="{3c87b40f-2c76-4731-b363-09dce0e2f69b}">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="color" value="152,125,183,255" type="QString"/>
|
||||
<Option name="joinstyle" value="bevel" type="QString"/>
|
||||
<Option name="offset" value="0,0" type="QString"/>
|
||||
<Option name="offset_map_unit_scale" value="3x:0,0,0,0,0,0" type="QString"/>
|
||||
<Option name="offset_unit" value="MM" type="QString"/>
|
||||
<Option name="outline_color" value="35,35,35,255" type="QString"/>
|
||||
<Option name="outline_style" value="no" type="QString"/>
|
||||
<Option name="outline_width" value="0.26" type="QString"/>
|
||||
<Option name="outline_width_unit" value="MM" type="QString"/>
|
||||
<Option name="style" value="solid" type="QString"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</profileFillSymbol>
|
||||
</elevation>
|
||||
<customproperties>
|
||||
<Option type="Map">
|
||||
<Option name="WMSBackgroundLayer" value="false" type="bool"/>
|
||||
<Option name="WMSPublishDataSourceUrl" value="false" type="bool"/>
|
||||
<Option name="embeddedWidgets/count" value="0" type="int"/>
|
||||
<Option name="identify/format" value="Value" type="QString"/>
|
||||
</Option>
|
||||
</customproperties>
|
||||
<mapTip enabled="1"></mapTip>
|
||||
<pipe-data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</pipe-data-defined-properties>
|
||||
<pipe>
|
||||
<provider>
|
||||
<resampling maxOversampling="2" enabled="false" zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour"/>
|
||||
</provider>
|
||||
<rasterrenderer nodataColor="" redBand="3" alphaBand="-1" blueBand="1" type="multibandcolor" opacity="1" greenBand="2">
|
||||
<rasterTransparency/>
|
||||
<minMaxOrigin>
|
||||
<limits>CumulativeCut</limits>
|
||||
<extent>WholeRaster</extent>
|
||||
<statAccuracy>Estimated</statAccuracy>
|
||||
<cumulativeCutLower>0.02</cumulativeCutLower>
|
||||
<cumulativeCutUpper>0.98</cumulativeCutUpper>
|
||||
<stdDevFactor>2</stdDevFactor>
|
||||
</minMaxOrigin>
|
||||
<redContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.168884</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</redContrastEnhancement>
|
||||
<greenContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.149555</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</greenContrastEnhancement>
|
||||
<blueContrastEnhancement>
|
||||
<minValue>-0.119304</minValue>
|
||||
<maxValue>0.143137</maxValue>
|
||||
<algorithm>StretchToMinimumMaximum</algorithm>
|
||||
</blueContrastEnhancement>
|
||||
</rasterrenderer>
|
||||
<brightnesscontrast gamma="1" contrast="0" brightness="0"/>
|
||||
<huesaturation invertColors="0" grayscaleMode="0" colorizeStrength="100" colorizeOn="0" colorizeRed="255" colorizeGreen="128" colorizeBlue="128" saturation="0"/>
|
||||
<rasterresampler maxOversampling="2"/>
|
||||
<resamplingStage>resamplingFilter</resamplingStage>
|
||||
</pipe>
|
||||
<blendMode>0</blendMode>
|
||||
</qgis>
|
||||
Reference in New Issue
Block a user