l1aF2027 commited on
Commit
35bb22e
·
1 Parent(s): 8efcc29
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerfile +19 -0
  2. .gitignore +35 -0
  3. README.md +96 -11
  4. app.py +95 -0
  5. prepare_solid_data.py +113 -0
  6. requirements.txt +8 -0
  7. retrieval_app.py +128 -0
  8. solid_data.py +240 -0
  9. solid_data/GloAspectClE_5min/GloAspectClE_5min.npz +3 -0
  10. solid_data/GloAspectClE_5min/heatmap.png +0 -0
  11. solid_data/GloAspectClE_5min/metadata.json +1 -0
  12. solid_data/GloAspectClN_5min/GloAspectClN_5min.npz +3 -0
  13. solid_data/GloAspectClN_5min/heatmap.png +0 -0
  14. solid_data/GloAspectClN_5min/metadata.json +1 -0
  15. solid_data/GloAspectClS_5min/GloAspectClS_5min.npz +3 -0
  16. solid_data/GloAspectClS_5min/heatmap.png +0 -0
  17. solid_data/GloAspectClS_5min/metadata.json +1 -0
  18. solid_data/GloAspectClU_5min/GloAspectClU_5min.npz +3 -0
  19. solid_data/GloAspectClU_5min/heatmap.png +0 -0
  20. solid_data/GloAspectClU_5min/metadata.json +1 -0
  21. solid_data/GloAspectClW_5min/GloAspectClW_5min.npz +3 -0
  22. solid_data/GloAspectClW_5min/heatmap.png +0 -0
  23. solid_data/GloAspectClW_5min/metadata.json +1 -0
  24. solid_data/GloElev_5min/GloElev_5min.npz +3 -0
  25. solid_data/GloElev_5min/heatmap.png +0 -0
  26. solid_data/GloElev_5min/metadata.json +1 -0
  27. solid_data/GloLand_5min/GloLand_5min.npz +3 -0
  28. solid_data/GloLand_5min/heatmap.png +0 -0
  29. solid_data/GloLand_5min/metadata.json +1 -0
  30. solid_data/GloSlopesCl1_5min/GloSlopesCl1_5min.npz +3 -0
  31. solid_data/GloSlopesCl1_5min/heatmap.png +0 -0
  32. solid_data/GloSlopesCl1_5min/metadata.json +1 -0
  33. solid_data/GloSlopesCl2_5min/GloSlopesCl2_5min.npz +3 -0
  34. solid_data/GloSlopesCl2_5min/heatmap.png +0 -0
  35. solid_data/GloSlopesCl2_5min/metadata.json +1 -0
  36. solid_data/GloSlopesCl3_5min/GloSlopesCl3_5min.npz +3 -0
  37. solid_data/GloSlopesCl3_5min/heatmap.png +0 -0
  38. solid_data/GloSlopesCl3_5min/metadata.json +1 -0
  39. solid_data/GloSlopesCl4_5min/GloSlopesCl4_5min.npz +3 -0
  40. solid_data/GloSlopesCl4_5min/heatmap.png +0 -0
  41. solid_data/GloSlopesCl4_5min/metadata.json +1 -0
  42. solid_data/GloSlopesCl5_5min/GloSlopesCl5_5min.npz +3 -0
  43. solid_data/GloSlopesCl5_5min/heatmap.png +0 -0
  44. solid_data/GloSlopesCl5_5min/metadata.json +1 -0
  45. solid_data/GloSlopesCl6_5min/GloSlopesCl6_5min.npz +3 -0
  46. solid_data/GloSlopesCl6_5min/heatmap.png +0 -0
  47. solid_data/GloSlopesCl6_5min/metadata.json +1 -0
  48. solid_data/GloSlopesCl7_5min/GloSlopesCl7_5min.npz +3 -0
  49. solid_data/GloSlopesCl7_5min/heatmap.png +0 -0
  50. solid_data/GloSlopesCl7_5min/metadata.json +1 -0
.dockerfile ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Cài đặt các gói phụ thuộc
6
+ COPY requirements.txt .
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ # Sao chép mã nguồn vào container
10
+ COPY . .
11
+
12
+ # Cài đặt biến môi trường
13
+ ENV SOLID_DATA_PATH="/app/solid_data"
14
+
15
+ # Mở cổng cho ứng dụng
16
+ EXPOSE 7860
17
+
18
+ # Khởi chạy ứng dụng
19
+ CMD ["python", "app.py"]
.gitignore ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+
11
+ # Virtual environments
12
+ venv/
13
+ env/
14
+ ENV/
15
+
16
+ # IDE specific files
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+
22
+ # Local development settings
23
+ .env
24
+ .env.local
25
+
26
+ # Logs
27
+ logs/
28
+ *.log
29
+
30
+ # Data files (uncomment if you don't want to commit data files)
31
+ # solid_data/
32
+ # *.npz
33
+
34
+ # Jupyter notebook checkpoints
35
+ .ipynb_checkpoints/
README.md CHANGED
@@ -1,11 +1,96 @@
1
- ---
2
- title: Soil Data
3
- emoji: 🔥
4
- colorFrom: green
5
- colorTo: indigo
6
- sdk: docker
7
- pinned: false
8
- license: unknown
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Solid Data API
2
+
3
+ API để tra cứu dữ liệu dựa trên tọa độ latitude và longitude.
4
+
5
+ ## Giới thiệu
6
+
7
+ API này cho phép người dùng truy vấn dữ liệu từ các tệp SolidData dựa trên tọa độ vị trí (latitude và longitude). API sẽ trả về chuỗi giá trị từ tất cả các lớp dữ liệu tại vị trí đó.
8
+
9
+ ## Cài đặt
10
+
11
+ ### Yêu cầu
12
+
13
+ - Python 3.8 trở lên
14
+ - Các thư viện được liệt kê trong `requirements.txt`
15
+
16
+ ### Cách cài đặt
17
+
18
+ 1. Clone repository
19
+ ```bash
20
+ git clone https://huggingface.co/spaces/l1aF2027/Solid-Data
21
+ cd Solid-Data
22
+ ```
23
+
24
+ 2. Cài đặt các thư viện phụ thuộc
25
+ ```bash
26
+ pip install -r requirements.txt
27
+ ```
28
+
29
+ 3. Đặt dữ liệu SolidData vào thư mục `solid_data/`
30
+
31
+ 4. Chạy ứng dụng
32
+ ```bash
33
+ python app.py
34
+ ```
35
+
36
+ ## Cách sử dụng API
37
+
38
+ ### Endpoint
39
+
40
+ - `POST /get_data`: Trả về giá trị dữ liệu tại tọa độ được chỉ định
41
+
42
+ ### Cấu trúc request
43
+
44
+ ```json
45
+ {
46
+ "latitude": 10.123,
47
+ "longitude": 106.456
48
+ }
49
+ ```
50
+
51
+ ### Cấu trúc response
52
+
53
+ ```json
54
+ {
55
+ "values": "[0.0, 1.0, 0.0, 0.0, ...]",
56
+ "status": "success"
57
+ }
58
+ ```
59
+
60
+ ### Ví dụ sử dụng với curl
61
+
62
+ ```bash
63
+ curl -X 'POST' \
64
+ 'https://[your-username]-solid-data-api.hf.space/get_data' \
65
+ -H 'accept: application/json' \
66
+ -H 'Content-Type: application/json' \
67
+ -d '{"latitude": 10.123, "longitude": 106.456}'
68
+ ```
69
+
70
+ ### Endpoints khác
71
+
72
+ - `GET /health`: Kiểm tra trạng thái hoạt động của API
73
+ - `GET /data_info`: Lấy thông tin về các tệp dữ liệu đã được tải
74
+
75
+ ## Triển khai trên Hugging Face Spaces
76
+
77
+ API này được thiết kế để dễ dàng triển khai trên Hugging Face Spaces. Các tệp cấu hình cần thiết đã được bao gồm:
78
+ - `Dockerfile`: Cấu hình Docker để xây dựng container
79
+ - `requirements.txt`: Danh sách các thư viện Python cần thiết
80
+
81
+ ## Cấu trúc thư mục
82
+
83
+ ```
84
+ .
85
+ ├── app.py # Mã nguồn chính của API
86
+ ├── retrieval_app.py # Module để tải và truy xuất dữ liệu
87
+ ├── solid_data/ # Thư mục chứa dữ liệu (các tệp .npz)
88
+ ├── requirements.txt # Danh sách các thư viện cần thiết
89
+ ├── Dockerfile # Cấu hình Docker để triển khai
90
+ └── README.md # Tệp hướng dẫn này
91
+ ```
92
+
93
+ ## Lưu ý
94
+
95
+ - Đảm bảo rằng tệp `solid_data.py` chứa lớp `SolidData` đã được đặt trong thư mục làm việc
96
+ - Thư mục `solid_data/` phải chứa các tệp .npz có cấu trúc phù hợp
app.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ import uvicorn
3
+ from pydantic import BaseModel
4
+ from typing import List, Optional
5
+ import numpy as np
6
+ import os
7
+ from tqdm.auto import tqdm
8
+ import pandas as pd
9
+ from solid_data import SolidData
10
+ from retrieval_app import RetrievalSolidData
11
+
12
+ # Khởi tạo FastAPI app
13
+ app = FastAPI(
14
+ title="Solid Data API",
15
+ description="API để tra cứu dữ liệu dựa trên tọa độ latitude và longitude",
16
+ version="1.0.0"
17
+ )
18
+
19
+ # Model dữ liệu đầu vào
20
+ class CoordinateRequest(BaseModel):
21
+ latitude: float
22
+ longitude: float
23
+
24
+ # Model dữ liệu đầu ra
25
+ class DataResponse(BaseModel):
26
+ values: str
27
+ status: str = "success"
28
+
29
+ # Biến global để lưu đối tượng RetrievalSolidData
30
+ solid_data_app = None
31
+
32
+ # Hàm khởi tạo dữ liệu - sẽ được gọi khi server khởi động
33
+ @app.on_event("startup")
34
+ async def startup_event():
35
+ global solid_data_app
36
+ solid_data_path = os.environ.get("SOLID_DATA_PATH", "./solid_data")
37
+ print(f"Khởi tạo dữ liệu từ thư mục: {solid_data_path}")
38
+ solid_data_app = RetrievalSolidData(solid_data_path)
39
+ print("Khởi tạo dữ liệu hoàn tất")
40
+
41
+ # API endpoint để lấy dữ liệu dựa trên tọa độ
42
+ @app.post("/get_data", response_model=DataResponse)
43
+ async def get_data(request: CoordinateRequest):
44
+ global solid_data_app
45
+
46
+ if solid_data_app is None:
47
+ raise HTTPException(status_code=500, detail="Hệ thống dữ liệu chưa được khởi tạo")
48
+
49
+ try:
50
+ # Lấy dữ liệu từ RetrievalSolidData
51
+ df_data = solid_data_app.get_data(request.longitude, request.latitude)
52
+
53
+ # Sắp xếp dữ liệu theo thứ tự như yêu cầu
54
+ new_order = ['Elevation', 'SlopesCl1', 'SlopesCl2', 'SlopesCl3', 'SlopesCl4', 'SlopesCl5', 'SlopesCl6',
55
+ 'SlopesCl7', 'SlopesCl8', 'AspectClN', 'AspectClE', 'AspectClS', 'AspectClW', 'AspectClU',
56
+ 'WAT', 'NVG', 'URB', 'GRS', 'FOR', 'CULTRF', 'CULTIR', 'CULT', 'sq1', 'sq2', 'sq3', 'sq4',
57
+ 'sq5', 'sq6', 'sq7', 'LandMask']
58
+
59
+ df_data['name'] = pd.Categorical(df_data['name'], categories=new_order, ordered=True)
60
+ df_data = df_data.sort_values('name').reset_index(drop=True)
61
+
62
+ # Chuyển cột value thành một chuỗi dạng [x1, x2, ...]
63
+ values_list = df_data['value'].tolist()
64
+ values_str = str(values_list).replace("'", "")
65
+
66
+ return DataResponse(values=values_str)
67
+
68
+ except ValueError as e:
69
+ raise HTTPException(status_code=400, detail=f"Lỗi dữ liệu: {str(e)}")
70
+ except Exception as e:
71
+ raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")
72
+
73
+ # API endpoint để kiểm tra trạng thái
74
+ @app.get("/health")
75
+ async def health_check():
76
+ return {"status": "ok"}
77
+
78
+ # API endpoint để lấy thông tin về dữ liệu
79
+ @app.get("/data_info")
80
+ async def get_data_info():
81
+ global solid_data_app
82
+
83
+ if solid_data_app is None:
84
+ raise HTTPException(status_code=500, detail="Hệ thống dữ liệu chưa được khởi tạo")
85
+
86
+ try:
87
+ info_df = solid_data_app.get_data_info()
88
+ return {"data_info": info_df.to_dict(orient="records")}
89
+ except Exception as e:
90
+ raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")
91
+
92
+ # Chạy ứng dụng nếu file này được thực thi trực tiếp
93
+ if __name__ == "__main__":
94
+ port = int(os.environ.get("PORT", 7860)) # Hugging Face Spaces sử dụng cổng 7860
95
+ uvicorn.run("app:app", host="0.0.0.0", port=port, reload=True)
prepare_solid_data.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ from solid_data import SolidData
4
+
5
+ class ProcessingSolidData:
6
+ def __init__(self, input_root="data", output_root="solid_data", data_info=None):
7
+ """
8
+ Khởi tạo đối tượng GenSolidData với thông tin thư mục và ánh xạ.
9
+ - input_root: Thư mục chứa các tệp ASC (ví dụ: 'data').
10
+ - output_root: Thư mục lưu kết quả (ví dụ: 'solid_data').
11
+ - data_info: Dictionary chứa filename, name và dtype dữ liệu.
12
+ """
13
+ self.input_root = input_root
14
+ self.output_root = output_root
15
+ # Kiểm tra nếu data_info không được cung cấp, tạo dictionary trống
16
+ self.data_info = data_info if data_info else {}
17
+
18
+ def load_data_info(self, filename="data_info.json"):
19
+ """
20
+ Đọc file JSON và trả về dictionary ánh xạ từ filename sang name và dtype.
21
+ - filename: Đường dẫn đến file JSON chứa bộ ánh xạ.
22
+ """
23
+ with open(filename, "r") as f:
24
+ self.data_info = json.load(f)
25
+ return self.data_info
26
+
27
+ def process_asc_files(self):
28
+ """
29
+ Duyệt qua tất cả tệp .asc trong input_root, đọc và lưu vào output_root với cấu trúc tương ứng.
30
+ """
31
+ # Duyệt qua tất cả thư mục và tệp trong input_root
32
+ for root, dirs, files in os.walk(self.input_root):
33
+ for file in files:
34
+ if file.endswith(".asc"): # Chỉ xử lý tệp .asc
35
+ # Đường dẫn đầy đủ của tệp .asc
36
+ asc_path = os.path.join(root, file)
37
+
38
+ # Tên tệp không có đuôi (sẽ dùng làm name và tên thư mục lưu)
39
+ file_name = os.path.splitext(file)[0]
40
+
41
+ # Ánh xạ file_name sang name và dtype nếu có trong dictionary
42
+ data_info = self.data_info.get(file_name, {"name": file_name, "dtype": "float", "description": "Unknown"})
43
+ name = data_info["name"]
44
+ dtype = data_info["dtype"]
45
+ description = data_info["description"]
46
+
47
+ # Đường dẫn tương đối từ input_root
48
+ relative_path = os.path.relpath(root, self.input_root)
49
+ if relative_path == ".":
50
+ output_dir = os.path.join(self.output_root, file_name)
51
+ else:
52
+ output_dir = os.path.join(self.output_root, relative_path, file_name)
53
+
54
+ print(f"Đang xử lý: {asc_path} -> {output_dir}")
55
+
56
+ try:
57
+ # Đọc tệp .asc và tạo SolidData với name từ ánh xạ
58
+ data = SolidData.read_asc(asc_path, name=name, dtype=dtype, description=description)
59
+
60
+ try:
61
+ data.plot(os.path.join(output_dir, "heatmap.png"))
62
+ except Exception as e:
63
+ print(f"Lỗi khi xử lý {asc_path}: {str(e)}")
64
+
65
+ # Lưu ma trận và metadata vào output_dir
66
+ data.save_dok_matrix(output_dir)
67
+
68
+ print(f"Đã lưu thành công: {output_dir}")
69
+ except Exception as e:
70
+ print(f"Lỗi khi xử lý {asc_path}: {str(e)}")
71
+
72
+
73
+ def generate_data_info_json(self, output_file="data_info.json"):
74
+ """
75
+ Tạo file JSON ánh xạ filename sang name và dtype cho tất cả các tệp .asc trong thư mục input_root.
76
+ - output_file: Đường dẫn đến file JSON sẽ được tạo.
77
+ """
78
+ data_info = {}
79
+
80
+ # Duyệt qua tất cả tệp .asc trong input_root
81
+ for root, dirs, files in os.walk(self.input_root):
82
+ for file in files:
83
+ if file.endswith(".asc"): # Chỉ xử lý tệp .asc
84
+ file_name = os.path.splitext(file)[0]
85
+ # Mặc định name và dtype
86
+ name = file_name # Dùng file_name làm name mặc định
87
+ dtype = "float" # Kiểu dữ liệu mặc định
88
+
89
+ # Thêm vào dictionary
90
+ data_info[file_name] = {"name": name, "dtype": dtype, "description": "Unknown"}
91
+
92
+ # Lưu dictionary vào file JSON
93
+ with open(output_file, "w") as f:
94
+ json.dump(data_info, f, indent=4)
95
+
96
+ print(f"File JSON đã được tạo: {output_file}")
97
+
98
+
99
+ if __name__ == "__main__":
100
+ # Khởi tạo đối tượng GenSolidData
101
+ input_dir = "./data"
102
+ output_dir = "./solid_data"
103
+
104
+ gen_solid_data = ProcessingSolidData(input_root=input_dir, output_root=output_dir)
105
+
106
+ # Tạo file JSON chứa ánh xạ từ filename sang name và dtype
107
+ # gen_solid_data.generate_data_info_json("data_info.json")
108
+
109
+ # Đọc bộ ánh xạ từ file JSON
110
+ gen_solid_data.load_data_info("data_info.json")
111
+
112
+ # Gọi phương thức để xử lý các tệp ASC
113
+ gen_solid_data.process_asc_files()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.103.1
2
+ uvicorn==0.23.2
3
+ pydantic==2.3.0
4
+ numpy==1.24.3
5
+ pandas==2.0.3
6
+ scipy==1.10.1
7
+ tqdm==4.66.1
8
+ python-multipart==0.0.6
retrieval_app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from tqdm.auto import tqdm
3
+ import pandas as pd
4
+ from solid_data import SolidData
5
+
6
+ class RetrievalSolidData:
7
+ def __init__(self, directory):
8
+ """
9
+ Khởi tạo đối tượng với thư mục chứa các tệp dữ liệu Solid.
10
+ - directory: Thư mục chứa dữ liệu Solid.
11
+ """
12
+ self.directory = directory
13
+ self.solid_data_dict = self.load_solid_data_from_directory()
14
+
15
+ def load_solid_data_from_directory(self):
16
+ """
17
+ Duyệt qua thư mục, tìm các tệp .npz và sử dụng hàm load_dok_matrix
18
+ để tải và lưu các đối tượng SolidData vào một dictionary.
19
+ - Trả về: Dictionary với tên dữ liệu là key và đối tượng SolidData là value.
20
+ """
21
+ solid_data_dict = {}
22
+
23
+ # Tạo danh sách tất cả file .npz cần xử lý
24
+ npz_files = []
25
+ for root, dirs, files in os.walk(self.directory):
26
+ for file in files:
27
+ if file.endswith(".npz"):
28
+ npz_files.append((root, file))
29
+
30
+ # Dùng tqdm để hiển thị tiến trình
31
+ for root, file in tqdm(npz_files, desc="Đang tải dữ liệu", unit="file"):
32
+ file_name = os.path.splitext(file)[0]
33
+ try:
34
+ print(f"Đang lấy dữ liệu từ {root}")
35
+ solid_data_dict[file_name] = SolidData.load_dok_matrix(root)
36
+ except Exception as e:
37
+ print(f"\nKhông thể tải dữ liệu từ {file}: {str(e)}")
38
+
39
+ return solid_data_dict
40
+
41
+ def get_data(self, lon, lat):
42
+ """
43
+ Duyệt qua tất cả các SolidData trong dictionary và trả về giá trị tại vị trí lon, lat.
44
+ - lon, lat: Tọa độ lon và lat cần tra cứu.
45
+ - Trả về: Dictionary chứa tên dữ liệu là key và giá trị tại (lon, lat) là value.
46
+ """
47
+ result_dict = {'name': [], 'value': []}
48
+ for file_name, solid_data in self.solid_data_dict.items():
49
+ try:
50
+ name = solid_data.name
51
+ value = solid_data[lon, lat]
52
+ result_dict['name'].append(name)
53
+ result_dict['value'].append(value)
54
+ except ValueError as e:
55
+ result_dict['name'].append(name)
56
+ result_dict['value'].append(f"Lỗi: {e}")
57
+
58
+ # Chuyển kết quả sang DataFrame
59
+ df = pd.DataFrame(result_dict)
60
+ return df
61
+
62
+ def get_data_info(self):
63
+ """
64
+ Chuyển thông tin từ solid_data_dict thành DataFrame
65
+
66
+ Returns:
67
+ pd.DataFrame: DataFrame chứa các thuộc tính của các đối tượng SolidData
68
+ """
69
+ data = []
70
+
71
+ for file_name, solid_data in self.solid_data_dict.items():
72
+ data.append({
73
+ 'file_name': file_name,
74
+ 'name': solid_data.name,
75
+ 'rows': solid_data.rows,
76
+ 'columns': solid_data.cols,
77
+ 'x_corner': solid_data.x_corner,
78
+ 'y_corner': solid_data.y_corner,
79
+ 'cell_size': solid_data.cellsize,
80
+ 'description': getattr(solid_data, 'description', 'Unknown') # Thêm trường description nếu có
81
+ })
82
+
83
+ # Tạo DataFrame từ danh sách dữ liệu
84
+ df = pd.DataFrame(data)
85
+
86
+ # Sắp xếp các cột (tuỳ chọn)
87
+ columns_order = ['name', 'rows', 'columns', 'x_corner', 'y_corner', 'cell_size', 'description']
88
+ df = df[columns_order]
89
+
90
+ return df
91
+
92
+ if __name__ == "__main__":
93
+ solid_data_path = "./solid_data"
94
+ app = RetrievalSolidData(solid_data_path)
95
+
96
+ while True:
97
+ print("\n" + "="*50)
98
+ print("NHẬP TỌA ĐỘ ĐỂ TRA CỨU DỮ LIỆU")
99
+ print("="*50)
100
+
101
+ try:
102
+ # Nhập tọa độ từ người dùng
103
+ lat = float(input("Nhập vĩ độ (latitude): "))
104
+ lon = float(input("Nhập kinh độ (longitude): "))
105
+
106
+ # Lấy dữ liệu
107
+ df_data = app.get_data(lon, lat)
108
+ new_order = ['Elevation', 'SlopesCl1', 'SlopesCl2', 'SlopesCl3', 'SlopesCl4', 'SlopesCl5', 'SlopesCl6', 'SlopesCl7', 'SlopesCl8', 'AspectClN', 'AspectClE', 'AspectClS', 'AspectClW', 'AspectClU', 'WAT', 'NVG', 'URB', 'GRS', 'FOR', 'CULTRF', 'CULTIR', 'CULT', 'sq1', 'sq2', 'sq3', 'sq4', 'sq5', 'sq6', 'sq7', 'LandMask']
109
+ df_data['name'] = pd.Categorical(df_data['name'], categories=new_order, ordered=True)
110
+
111
+ # Sắp xếp theo cột 'name'
112
+ df_data = df_data.sort_values('name').reset_index(drop=True)
113
+
114
+ # Hiển thị kết quả
115
+ print("\nKẾT QUẢ TRA CỨU:")
116
+ print("="*50)
117
+ print(f"Tọa độ: Lat={lat}, Lon={lon}")
118
+ print("\nGiá trị tại tọa độ:")
119
+ print(df_data)
120
+ print(df_data['value'])
121
+ except ValueError:
122
+ print("Lỗi: Vui lòng nhập số hợp lệ cho tọa độ!")
123
+ except KeyboardInterrupt:
124
+ print("\nKết thúc chương trình...")
125
+ break
126
+ except Exception as e:
127
+ print(f"Lỗi: {str(e)}")
128
+
solid_data.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.sparse import dok_matrix, save_npz, load_npz
3
+ from tqdm.auto import tqdm
4
+ import json
5
+ import os
6
+
7
+ class LonLatMapper:
8
+ def __init__(self, x_corner, y_corner, cellsize, rows, cols):
9
+ """
10
+ Khởi tạo bộ ánh xạ lon-lat sang x-y và ngược lại.
11
+ - x_corner: Tọa độ x (kinh độ) của góc dưới-trái ô đầu tiên.
12
+ - y_corner: Tọa độ y (vĩ độ) của góc dưới-trái ô đầu tiên.
13
+ - cellsize: Kích thước ô lưới (độ hoặc mét).
14
+ - rows: Số hàng của lưới.
15
+ - cols: Số cột của lưới.
16
+ """
17
+ self.x_corner = x_corner
18
+ self.y_corner = y_corner
19
+ self.cellsize = cellsize
20
+ self.rows = rows
21
+ self.cols = cols
22
+
23
+ def lonlat2xy(self, lon, lat):
24
+ """
25
+ Ánh xạ (lon, lat) sang chỉ số ô lưới (x, y).
26
+ - lon: Kinh độ (hoặc tọa độ x trong hệ chiếu).
27
+ - lat: Vĩ độ (hoặc tọa độ y trong hệ chiếu).
28
+ - Trả về: (x, y) - chỉ số cột và hàng.
29
+ """
30
+ x = int(round((lon - self.x_corner) / self.cellsize))
31
+ y = abs(int(round((lat + self.y_corner) / self.cellsize)))
32
+
33
+ # Kiểm tra giới hạn
34
+ if not (0 <= x < self.cols and 0 <= y < self.rows):
35
+ raise ValueError(f"Chỉ số (x={x}, y={y}) ngoài phạm vi lưới ({self.cols}x{self.rows})")
36
+
37
+ return x, y
38
+
39
+ def xy2lonlat(self, x, y):
40
+ """
41
+ Ánh xạ chỉ số ô lưới (x, y) sang (lon, lat).
42
+ - x: Chỉ số cột.
43
+ - y: Chỉ số hàng.
44
+ - Trả về: (lon, lat) - kinh độ và vĩ độ.
45
+ """
46
+ # Kiểm tra giới hạn
47
+ if not (0 <= x < self.cols and 0 <= y < self.rows):
48
+ raise ValueError(f"Chỉ số (x={x}, y={y}) ngoài phạm vi lưới ({self.cols}x{self.rows})")
49
+
50
+ lon = self.x_corner + x * self.cellsize
51
+ lat = abs(self.y_corner) - y * self.cellsize
52
+ return lon, lat
53
+
54
+ def lonlat2xy_batch(self, lons, lats):
55
+ """
56
+ Ánh xạ hàng loạt (lon, lat) sang (x, y).
57
+ - lons, lats: Mảng hoặc danh sách kinh độ và vĩ độ.
58
+ - Trả về: Danh sách (x, y).
59
+ """
60
+ lons = np.asarray(lons)
61
+ lats = np.asarray(lats)
62
+ x = np.round((lons - self.x_corner) / self.cellsize).astype(int)
63
+ y = np.abs(np.round((lats + self.y_corner) / self.cellsize)).astype(int)
64
+
65
+ # Kiểm tra giới hạn
66
+ valid = (x >= 0) & (x < self.cols) & (y >= 0) & (y < self.rows)
67
+ if not valid.all():
68
+ raise ValueError("Một số tọa độ ngoài phạm vi lưới")
69
+
70
+ return list(zip(x, y))
71
+
72
+ def xy2lonlat_batch(self, xs, ys):
73
+ """
74
+ Ánh xạ hàng loạt (x, y) sang (lon, lat).
75
+ - xs, ys: Mảng hoặc danh sách chỉ số cột và hàng.
76
+ - Trả về: Danh sách (lon, lat).
77
+ """
78
+ xs = np.asarray(xs)
79
+ ys = np.asarray(ys)
80
+
81
+ # Kiểm tra giới hạn
82
+ valid = (xs >= 0) & (xs < self.cols) & (ys >= 0) & (ys < self.rows)
83
+ if not valid.all():
84
+ raise ValueError("Một số chỉ số ngoài phạm vi lưới")
85
+
86
+ lons = self.x_corner + xs * self.cellsize
87
+ lats = abs(self.y_corner) - ys * self.cellsize
88
+ return list(zip(lons, lats))
89
+
90
+
91
+ class SolidData():
92
+ def __init__(self, M, rows, cols, x_corner, y_corner, cellsize, name, description="Unknown"):
93
+ self.M, self.rows, self.cols, self.x_corner, self.y_corner, self.cellsize = M, rows, cols, x_corner, y_corner, cellsize
94
+ self.name = name
95
+ self.description = description
96
+ self.mapper = LonLatMapper(self.x_corner, self.y_corner, self.cellsize, self.rows, self.cols)
97
+
98
+ def __getitem__(self, key):
99
+ """
100
+ Truy cập ma trận thưa hoặc metadata qua toán tử [].
101
+ - key là tuple (i,j): Trả về giá trị M[i,j] (hoặc 0 nếu không tồn tại). i, j là lon, lat
102
+ """
103
+ if isinstance(key, tuple):
104
+ if self.M is None:
105
+ raise ValueError("Ma trận chưa được tải. Gọi load_data() trước.")
106
+ x, y = self.mapper.lonlat2xy(key[0], key[1])
107
+ return self.M[y, x] # Trả về giá trị tại (i,j), 0 nếu không có
108
+ else:
109
+ raise TypeError("Khóa phải là tuple (lon, lat)")
110
+
111
+ @staticmethod
112
+ def read_asc(file_path, name, dtype='int', description="Unknown"):
113
+ # Đọc metadata từ header
114
+ with open(file_path, "r") as file:
115
+ cols = int(file.readline().split()[1])
116
+ rows = int(file.readline().split()[1])
117
+ x_corner = float(file.readline().split()[1])
118
+ y_corner = float(file.readline().split()[1])
119
+ cellsize = float(file.readline().split()[1])
120
+ nodata_val = float(file.readline().split()[1]) # Giả sử nodata là số
121
+
122
+ # Đọc dữ liệu dưới dạng mảng NumPy (bỏ qua 6 dòng header)
123
+ data = np.loadtxt(file_path, skiprows=6, dtype=np.float64)
124
+
125
+ # Xử lý giá trị nodata và chuyển đổi sang ma trận thưa
126
+ mask = (data != nodata_val)
127
+ if dtype == 'int':
128
+ data = data.astype(np.int64)
129
+ elif dtype == 'float':
130
+ data = data.astype(np.float64)
131
+
132
+ # Tạo ma trận thưa (dok_matrix hoặc lil_matrix)
133
+ M = dok_matrix((rows, cols), dtype=data.dtype)
134
+ rows_idx, cols_idx = np.where(mask)
135
+ M[rows_idx, cols_idx] = data[rows_idx, cols_idx]
136
+
137
+ return SolidData(M, rows, cols, x_corner, y_corner, cellsize, name, description)
138
+
139
+ def save_dok_matrix(self, output_dir):
140
+ """
141
+ Lưu ma trận dok_matrix và metadata vào thư mục output_dir.
142
+ - output_dir: Thư mục lưu tệp.
143
+ - Tệp ma trận: <tên thư mục>.npz.
144
+ - Tệp metadata: metadata.json.
145
+ """
146
+ print("Bắt đầu lưu dữ liệu: ")
147
+ # Lấy tên thư mục từ output_dir
148
+ folder_name = os.path.basename(os.path.normpath(output_dir))
149
+
150
+ # Tạo thư mục nếu chưa tồn tại
151
+ os.makedirs(output_dir, exist_ok=True)
152
+
153
+ # Đường dẫn tệp
154
+ matrix_path = os.path.join(output_dir, f"{folder_name}.npz")
155
+ metadata_path = os.path.join(output_dir, "metadata.json")
156
+
157
+ # Chuyển dok_matrix sang csr_matrix để lưu
158
+ M_csr = self.M.tocsr()
159
+ save_npz(matrix_path, M_csr)
160
+
161
+ # Lưu metadata
162
+ metadata = {
163
+ 'name' : self.name,
164
+ 'rows' : self.rows,
165
+ 'cols' : self.cols,
166
+ 'x_corner': self.x_corner,
167
+ 'y_corner': self.y_corner,
168
+ 'cellsize': self.cellsize,
169
+ 'description' : self.description
170
+ }
171
+ with open(metadata_path, 'w') as f:
172
+ json.dump(metadata, f)
173
+
174
+ @staticmethod
175
+ def load_dok_matrix(input_dir):
176
+ """
177
+ Đọc ma trận dok_matrix và metadata từ thư mục input_dir.
178
+ - input_dir: Thư mục chứa tệp <tên thư mục>.npz và metadata.json.
179
+ - Trả về: (M, x_corner, y_corner, cellsize)
180
+ """
181
+ # Lấy tên thư mục từ input_dir
182
+ folder_name = os.path.basename(os.path.normpath(input_dir))
183
+
184
+ # Đường dẫn tệp
185
+ matrix_path = os.path.join(input_dir, f"{folder_name}.npz")
186
+ metadata_path = os.path.join(input_dir, "metadata.json")
187
+
188
+ # Đọc ma trận
189
+ M_csr = load_npz(matrix_path)
190
+ M = M_csr.todok() # Chuyển lại dok_matrix
191
+
192
+ # Đọc metadata
193
+ with open(metadata_path, 'r') as f:
194
+ metadata = json.load(f)
195
+
196
+ rows = metadata['rows']
197
+ cols = metadata['cols']
198
+ x_corner = metadata['x_corner']
199
+ y_corner = metadata['y_corner']
200
+ cellsize = metadata['cellsize']
201
+ description = metadata['description']
202
+ name = metadata['name']
203
+ data = SolidData(M, rows, cols, x_corner, y_corner, cellsize, name, description)
204
+ return data
205
+
206
+ def sparse2dict(self):
207
+ sparse_dict = {
208
+ 'lon': [],
209
+ 'lat': [],
210
+ self.name: [],
211
+ }
212
+
213
+ llmapper = LonLatMapper(self.x_corner, self.y_corner, self.cellsize, self.rows, self.cols)
214
+ for i in tqdm(self.M.items()):
215
+ y, x = i[0]
216
+ lon, lat = llmapper.xy2lonlat(x, y)
217
+ sparse_dict['lon'].append(lon)
218
+ sparse_dict['lat'].append(lat)
219
+ sparse_dict[self.name].append(i[1])
220
+ return sparse_dict
221
+
222
+ def plot(self, output_file=None):
223
+ import matplotlib.pyplot as plt
224
+ import vaex
225
+
226
+ data_dict = self.sparse2dict()
227
+ df = vaex.from_dict(data_dict)
228
+ df.viz.heatmap(df.lon, df.lat, what=vaex.stat.mean(getattr(df, self.name)))
229
+ if output_file:
230
+ print("Bắt đầu lưu biểu đồ")
231
+ folder_name = os.path.dirname(output_file)
232
+ # Tạo thư mục nếu chưa tồn tại
233
+ os.makedirs(folder_name, exist_ok=True)
234
+ plt.savefig(output_file) # Lưu hình thành tệp
235
+ else:
236
+ print("Bắt đầu plot biểu đồ:")
237
+ plt.show()
238
+ plt.close()
239
+
240
+
solid_data/GloAspectClE_5min/GloAspectClE_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c9267959d510d1c7333fb86e5a5316af45e4b680b360d088067be59ecdf73626
3
+ size 3923278
solid_data/GloAspectClE_5min/heatmap.png ADDED
solid_data/GloAspectClE_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "AspectClE", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Aspect class for East-facing slopes, representing the direction of the slope gradient in the Eastward direction."}
solid_data/GloAspectClN_5min/GloAspectClN_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9d9d1ac7af0e133533656365849f3f2264a05da4030001fba19db59fe7743494
3
+ size 3892827
solid_data/GloAspectClN_5min/heatmap.png ADDED
solid_data/GloAspectClN_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "AspectClN", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Aspect class for North-facing slopes, representing the direction of the slope gradient towards the north."}
solid_data/GloAspectClS_5min/GloAspectClS_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:882415f2db533c7723bd146dbb0f3255ccb88205460894c2aa7a7e1a9f74143a
3
+ size 3890603
solid_data/GloAspectClS_5min/heatmap.png ADDED
solid_data/GloAspectClS_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "AspectClS", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Aspect class for South-facing slopes, representing the direction of the slope gradient towards the south."}
solid_data/GloAspectClU_5min/GloAspectClU_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:15ed47a363aee7a166f180c8255c4d561415beced7fa655392c9f674e70cba95
3
+ size 4319324
solid_data/GloAspectClU_5min/heatmap.png ADDED
solid_data/GloAspectClU_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "AspectClU", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Aspect class for undefined slope aspects where the slope gradient is either undefined or less than a certain threshold."}
solid_data/GloAspectClW_5min/GloAspectClW_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a114071a642a3c9246dcd83a4bdf4ee6ce68db6e4cdf964c63e5719991bd8eb1
3
+ size 3926473
solid_data/GloAspectClW_5min/heatmap.png ADDED
solid_data/GloAspectClW_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "AspectClW", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Aspect class for West-facing slopes, representing the direction of the slope gradient towards the west."}
solid_data/GloElev_5min/GloElev_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3522a95065d3c14222e0b50e1c184bd4a673f549d0a257486dfdcd2760f38b3c
3
+ size 4328335
solid_data/GloElev_5min/heatmap.png ADDED
solid_data/GloElev_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "Elevation", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Median elevation data for each grid cell, measured in meters above sea level."}
solid_data/GloLand_5min/GloLand_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64c27c031dc15e6a3b0860bbd59e77b48298682d0d0c54625837346c326cdd6e
3
+ size 407106
solid_data/GloLand_5min/heatmap.png ADDED
solid_data/GloLand_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "LandMask", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Land mask indicating the fraction of 3 arc-second grid cells that fall into a 5-minute"}
solid_data/GloSlopesCl1_5min/GloSlopesCl1_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb0b1699145748c061e0ffd8d07ba33ef8755374844d3db8be05797108672999
3
+ size 3591579
solid_data/GloSlopesCl1_5min/heatmap.png ADDED
solid_data/GloSlopesCl1_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl1", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 0% and 0.5%."}
solid_data/GloSlopesCl2_5min/GloSlopesCl2_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9339c9b3ac6145f057d78f8b4e4e1446b4ffeeac255604090a1aeb2e5fc8c567
3
+ size 4184117
solid_data/GloSlopesCl2_5min/heatmap.png ADDED
solid_data/GloSlopesCl2_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl2", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 0.5% and 2%."}
solid_data/GloSlopesCl3_5min/GloSlopesCl3_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:472747752d1f2025cbabe1229c814d522db3bfc1973608531d6eceb6838ff23b
3
+ size 4158399
solid_data/GloSlopesCl3_5min/heatmap.png ADDED
solid_data/GloSlopesCl3_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl3", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 2% and 5%."}
solid_data/GloSlopesCl4_5min/GloSlopesCl4_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e1770f8040047f64557c373e12a8557797d131d8c283e2af03d97d6fb5300f1
3
+ size 3776388
solid_data/GloSlopesCl4_5min/heatmap.png ADDED
solid_data/GloSlopesCl4_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl4", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 5% and 10%."}
solid_data/GloSlopesCl5_5min/GloSlopesCl5_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:308a95ee1fa2254e45293acde29af429170e311793498aa0a9714090f0fcae65
3
+ size 3069507
solid_data/GloSlopesCl5_5min/heatmap.png ADDED
solid_data/GloSlopesCl5_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl5", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 10% and 15%."}
solid_data/GloSlopesCl6_5min/GloSlopesCl6_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ae609a37a1ef48772cc1bdf50adfbdf61f2bb1089162ea747b968ea8255afb8a
3
+ size 2762316
solid_data/GloSlopesCl6_5min/heatmap.png ADDED
solid_data/GloSlopesCl6_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl6", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 15% and 30%."}
solid_data/GloSlopesCl7_5min/GloSlopesCl7_5min.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:33d4c1fb0000dac64a753eac2be9183e315f1db31afda7924a7276c39892bfa3
3
+ size 1890531
solid_data/GloSlopesCl7_5min/heatmap.png ADDED
solid_data/GloSlopesCl7_5min/metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"name": "SlopesCl7", "rows": 2160, "cols": 4320, "x_corner": -180.0, "y_corner": -90.0, "cellsize": 0.0833333333333333, "description": "Percentage of grid cells with slope between 30% and 45%."}