Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 623bc9c7dd | |||
| 174de1034b | |||
| d1a4534653 | |||
| 57fbdede1b | |||
| c60dea728f | |||
| d96c0c9d69 | |||
| 0d48844822 | |||
| c80b43eeac | |||
| ca71aff891 | |||
| 94eca6bb29 | |||
| c40aafef03 | |||
| 0e8d85d972 | |||
| 208f1fab6e | |||
| b0fba1a5ff | |||
| bb25aa12cc | |||
| 2ffe74357e | |||
| e684d9c5c1 | |||
| bc678f3e6b | |||
| 94ebec25f2 | |||
| 3199ff242a | |||
| 06ef6bee92 | |||
| ad40578284 | |||
| 120cd84b66 | |||
| d2834725a2 | |||
| 3712787689 | |||
| 3783bdf678 | |||
| 2854ad170d | |||
| 3a32ccd90a | |||
| df7294eb1a | |||
| 95ed7cfc08 | |||
| 6c2baeb7d5 | |||
| fb67ca6498 | |||
| 62b07c52e3 | |||
| 44626c7e34 | |||
| 95bfb52281 | |||
| 47d9aa99f3 | |||
| ea2c49104c | |||
| f31982c50a | |||
| 23bc443245 |
@@ -0,0 +1,7 @@
|
|||||||
|
ThuanHoa/ThuanHoa_VH.tif
|
||||||
|
ThuanHoa/ThuanHoa_VV.tif
|
||||||
|
model_train/model.joblib
|
||||||
|
model_train/model_new.joblib
|
||||||
|
backup_model_train/model.joblib
|
||||||
|
backup_model_train/model_new.joblib
|
||||||
|
dataset_cache/sentinel2_timeseries_40scenes.nc
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:c65f38d91762e7167ef17d7cbdaf71547a323a9d485833e7acf62550674ea840
|
|
||||||
size 863658
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:dd3fecbef4c80ff1bd20922e6b2250d94ac05e55c3a2efbff4da20fcea3d739f
|
||||||
|
size 39812
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:350b680a5454d4d080d8d943d723ea01668c9c19219cb8feb396c54462ee89c3
|
||||||
|
size 857629
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:89c347e98288e77ddb7579d4cfa2b49924a993f7173a2d12155ef7a1893082b1
|
||||||
|
size 163627
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:2ba3e38fac960f3049906d20a4d2255789415028b47a25c62fe4505bebccdddf
|
|
||||||
size 3375914
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:54efd837e5dcbfbd4bd8c2cfc44ff1b5eecbf03de302d41fab0ed47257bfa62c
|
||||||
|
size 4828615
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:5ae460f1a110627f8037f7daad1e781dd3128586d0dd6094ddf70f13354ee92c
|
|
||||||
size 1671089
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:72d0f97e1e623ab49fe749054c8b2c3901ff0807b52667289108bbd0b8220e2a
|
||||||
|
size 2240648
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
UTF-8
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
PROJCS["VN-2000_TM-3_105-30",GEOGCS["GCS_VN_2000",DATUM["D_Vietnam_2000",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",105.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis version="3.34.9-Prizren">
|
||||||
|
<identifier></identifier>
|
||||||
|
<parentidentifier></parentidentifier>
|
||||||
|
<language></language>
|
||||||
|
<type></type>
|
||||||
|
<title></title>
|
||||||
|
<abstract></abstract>
|
||||||
|
<contact>
|
||||||
|
<name></name>
|
||||||
|
<organization></organization>
|
||||||
|
<position></position>
|
||||||
|
<voice></voice>
|
||||||
|
<fax></fax>
|
||||||
|
<email></email>
|
||||||
|
<role></role>
|
||||||
|
</contact>
|
||||||
|
<links/>
|
||||||
|
<dates/>
|
||||||
|
<fees></fees>
|
||||||
|
<encoding></encoding>
|
||||||
|
<crs>
|
||||||
|
<spatialrefsys nativeFormat="Wkt">
|
||||||
|
<wkt></wkt>
|
||||||
|
<proj4></proj4>
|
||||||
|
<srsid>0</srsid>
|
||||||
|
<srid>0</srid>
|
||||||
|
<authid></authid>
|
||||||
|
<description></description>
|
||||||
|
<projectionacronym></projectionacronym>
|
||||||
|
<ellipsoidacronym></ellipsoidacronym>
|
||||||
|
<geographicflag>false</geographicflag>
|
||||||
|
</spatialrefsys>
|
||||||
|
</crs>
|
||||||
|
<extent>
|
||||||
|
<spatial minz="0" maxy="-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368" maxz="0" maxx="-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368" crs="" miny="179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368" dimensions="2" minx="179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"/>
|
||||||
|
<temporal>
|
||||||
|
<period>
|
||||||
|
<start></start>
|
||||||
|
<end></end>
|
||||||
|
</period>
|
||||||
|
</temporal>
|
||||||
|
</extent>
|
||||||
|
</qgis>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
UTF-8
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
PROJCS["VN-2000_TM-3_105-30",GEOGCS["GCS_VN_2000",DATUM["D_Vietnam_2000",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",105.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
|
||||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis version="3.34.9-Prizren">
|
||||||
|
<identifier></identifier>
|
||||||
|
<parentidentifier></parentidentifier>
|
||||||
|
<language></language>
|
||||||
|
<type></type>
|
||||||
|
<title></title>
|
||||||
|
<abstract></abstract>
|
||||||
|
<links/>
|
||||||
|
<dates/>
|
||||||
|
<fees></fees>
|
||||||
|
<encoding></encoding>
|
||||||
|
<crs>
|
||||||
|
<spatialrefsys nativeFormat="Wkt">
|
||||||
|
<wkt></wkt>
|
||||||
|
<proj4></proj4>
|
||||||
|
<srsid>0</srsid>
|
||||||
|
<srid>0</srid>
|
||||||
|
<authid></authid>
|
||||||
|
<description></description>
|
||||||
|
<projectionacronym></projectionacronym>
|
||||||
|
<ellipsoidacronym></ellipsoidacronym>
|
||||||
|
<geographicflag>false</geographicflag>
|
||||||
|
</spatialrefsys>
|
||||||
|
</crs>
|
||||||
|
<extent/>
|
||||||
|
</qgis>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
UTF-8
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
PROJCS["WGS_1984_UTM_Zone_48N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",105.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis version="3.30.0-'s-Hertogenbosch">
|
||||||
|
<identifier></identifier>
|
||||||
|
<parentidentifier></parentidentifier>
|
||||||
|
<language></language>
|
||||||
|
<type>dataset</type>
|
||||||
|
<title></title>
|
||||||
|
<abstract></abstract>
|
||||||
|
<contact>
|
||||||
|
<name></name>
|
||||||
|
<organization></organization>
|
||||||
|
<position></position>
|
||||||
|
<voice></voice>
|
||||||
|
<fax></fax>
|
||||||
|
<email></email>
|
||||||
|
<role></role>
|
||||||
|
</contact>
|
||||||
|
<links/>
|
||||||
|
<dates/>
|
||||||
|
<fees></fees>
|
||||||
|
<encoding></encoding>
|
||||||
|
<crs>
|
||||||
|
<spatialrefsys nativeFormat="Wkt">
|
||||||
|
<wkt>PROJCRS["WGS 84 / UTM zone 48N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 48N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",105,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Engineering survey, topographic mapping."],AREA["Between 102°E and 108°E, northern hemisphere between equator and 84°N, onshore and offshore. Cambodia. China. Indonesia. Laos. Malaysia - West Malaysia. Mongolia. Russian Federation. Singapore. Thailand. Vietnam."],BBOX[0,102,84,108]],ID["EPSG",32648]]</wkt>
|
||||||
|
<proj4>+proj=utm +zone=48 +datum=WGS84 +units=m +no_defs</proj4>
|
||||||
|
<srsid>3132</srsid>
|
||||||
|
<srid>32648</srid>
|
||||||
|
<authid>EPSG:32648</authid>
|
||||||
|
<description>WGS 84 / UTM zone 48N</description>
|
||||||
|
<projectionacronym>utm</projectionacronym>
|
||||||
|
<ellipsoidacronym>EPSG:7030</ellipsoidacronym>
|
||||||
|
<geographicflag>false</geographicflag>
|
||||||
|
</spatialrefsys>
|
||||||
|
</crs>
|
||||||
|
<extent>
|
||||||
|
<spatial miny="0" minz="0" maxz="0" crs="EPSG:32648" minx="0" maxy="0" dimensions="2" maxx="0"/>
|
||||||
|
<temporal>
|
||||||
|
<period>
|
||||||
|
<start></start>
|
||||||
|
<end></end>
|
||||||
|
</period>
|
||||||
|
</temporal>
|
||||||
|
</extent>
|
||||||
|
</qgis>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
UTF-8
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
PROJCS["WGS_1984_UTM_Zone_48N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",105.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis version="3.30.0-'s-Hertogenbosch">
|
||||||
|
<identifier></identifier>
|
||||||
|
<parentidentifier></parentidentifier>
|
||||||
|
<language></language>
|
||||||
|
<type>dataset</type>
|
||||||
|
<title></title>
|
||||||
|
<abstract></abstract>
|
||||||
|
<contact>
|
||||||
|
<name></name>
|
||||||
|
<organization></organization>
|
||||||
|
<position></position>
|
||||||
|
<voice></voice>
|
||||||
|
<fax></fax>
|
||||||
|
<email></email>
|
||||||
|
<role></role>
|
||||||
|
</contact>
|
||||||
|
<links/>
|
||||||
|
<dates/>
|
||||||
|
<fees></fees>
|
||||||
|
<encoding></encoding>
|
||||||
|
<crs>
|
||||||
|
<spatialrefsys nativeFormat="Wkt">
|
||||||
|
<wkt>PROJCRS["WGS 84 / UTM zone 48N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 48N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",105,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Engineering survey, topographic mapping."],AREA["Between 102°E and 108°E, northern hemisphere between equator and 84°N, onshore and offshore. Cambodia. China. Indonesia. Laos. Malaysia - West Malaysia. Mongolia. Russian Federation. Singapore. Thailand. Vietnam."],BBOX[0,102,84,108]],ID["EPSG",32648]]</wkt>
|
||||||
|
<proj4>+proj=utm +zone=48 +datum=WGS84 +units=m +no_defs</proj4>
|
||||||
|
<srsid>3132</srsid>
|
||||||
|
<srid>32648</srid>
|
||||||
|
<authid>EPSG:32648</authid>
|
||||||
|
<description>WGS 84 / UTM zone 48N</description>
|
||||||
|
<projectionacronym>utm</projectionacronym>
|
||||||
|
<ellipsoidacronym>EPSG:7030</ellipsoidacronym>
|
||||||
|
<geographicflag>false</geographicflag>
|
||||||
|
</spatialrefsys>
|
||||||
|
</crs>
|
||||||
|
<extent>
|
||||||
|
<spatial miny="0" minz="0" maxz="0" crs="EPSG:32648" minx="0" maxy="0" dimensions="2" maxx="0"/>
|
||||||
|
<temporal>
|
||||||
|
<period>
|
||||||
|
<start></start>
|
||||||
|
<end></end>
|
||||||
|
</period>
|
||||||
|
</temporal>
|
||||||
|
</extent>
|
||||||
|
</qgis>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d9702f45dddb21e62fa5f65fce514f1e6dd2632556758fe75cf50f227e0e9fcf
|
oid sha256:520c3480efaafdf844c3bba3dd165a8e44f3318ab21209539c78201f18fd6312
|
||||||
size 3066028
|
size 3066028
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2c842ea560305344c483d4b9dbbf117526655cc684e29d8135610f4e9e4b3969
|
oid sha256:7d3bff20682fc510a9c41b5aa2b42e3ebef8098ed81e27b4436f9ae86f47b9a6
|
||||||
size 3066028
|
size 3066028
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:86d72d0e70f63442e5e1979fdd48844890821b8d28e2ffa794bf5b5aafcf63a4
|
oid sha256:322f48d2d54ee921facfc3c0c44b320a86a90694e1779b683824264f9affa3fc
|
||||||
size 3066028
|
size 3066028
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+788
@@ -0,0 +1,788 @@
|
|||||||
|
"""
|
||||||
|
API Server for Land Classification Model Training
|
||||||
|
Cho phép chọn dữ liệu và cấu hình training qua giao diện web
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI, BackgroundTasks, HTTPException
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.responses import HTMLResponse, FileResponse
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Optional, List
|
||||||
|
import uvicorn
|
||||||
|
import joblib
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
app = FastAPI(title="Land Classification Training API", version="1.0.0")
|
||||||
|
|
||||||
|
# Enable CORS
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Global training status
|
||||||
|
training_status = {
|
||||||
|
"is_training": False,
|
||||||
|
"progress": "",
|
||||||
|
"error": None,
|
||||||
|
"result": None,
|
||||||
|
"start_time": None,
|
||||||
|
"end_time": None,
|
||||||
|
"cancel_requested": False
|
||||||
|
}
|
||||||
|
|
||||||
|
# Global prediction status
|
||||||
|
prediction_status = {
|
||||||
|
"is_predicting": False,
|
||||||
|
"progress": "",
|
||||||
|
"error": None,
|
||||||
|
"result": None,
|
||||||
|
"output_file": None,
|
||||||
|
"start_time": None,
|
||||||
|
"end_time": None
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TrainingConfig(BaseModel):
|
||||||
|
"""Cấu hình training"""
|
||||||
|
# Khu vực (bbox)
|
||||||
|
min_lon: float = 105.6
|
||||||
|
min_lat: float = 9.3
|
||||||
|
max_lon: float = 106.2
|
||||||
|
max_lat: float = 9.8
|
||||||
|
|
||||||
|
# Thời gian
|
||||||
|
start_date: str = "2023-03-01"
|
||||||
|
end_date: str = "2023-05-31"
|
||||||
|
|
||||||
|
# Dữ liệu
|
||||||
|
max_scenes: int = 12
|
||||||
|
cloud_cover: int = 30
|
||||||
|
resolution: int = 20 # 10m hoặc 20m
|
||||||
|
|
||||||
|
# Model parameters
|
||||||
|
model_type: str = "xgboost" # xgboost, random_forest, decision_tree, svm, cnn
|
||||||
|
n_estimators: int = 100
|
||||||
|
max_depth: int = 20
|
||||||
|
learning_rate: float = 0.1
|
||||||
|
use_gpu: bool = True
|
||||||
|
|
||||||
|
# Cache
|
||||||
|
use_cache: bool = True # Cache dataset để test nhanh hơn
|
||||||
|
|
||||||
|
# Training data
|
||||||
|
training_shapefile: str = "train/ST_training data_updated_1130points_new.shp"
|
||||||
|
|
||||||
|
|
||||||
|
class PredictionConfig(BaseModel):
|
||||||
|
"""Cấu hình dự đoán"""
|
||||||
|
# Model to use
|
||||||
|
model_filename: str
|
||||||
|
|
||||||
|
# Khu vực (bbox)
|
||||||
|
min_lon: float = 105.6
|
||||||
|
min_lat: float = 9.3
|
||||||
|
max_lon: float = 106.2
|
||||||
|
max_lat: float = 9.8
|
||||||
|
|
||||||
|
# Thời gian
|
||||||
|
start_date: str = "2023-03-01"
|
||||||
|
end_date: str = "2023-05-31"
|
||||||
|
|
||||||
|
# Dữ liệu
|
||||||
|
max_scenes: int = 12
|
||||||
|
cloud_cover: int = 30
|
||||||
|
resolution: int = 20
|
||||||
|
|
||||||
|
|
||||||
|
class TrainingStatus(BaseModel):
|
||||||
|
"""Trạng thái training"""
|
||||||
|
is_training: bool
|
||||||
|
progress: str
|
||||||
|
error: Optional[str]
|
||||||
|
result: Optional[dict]
|
||||||
|
start_time: Optional[str]
|
||||||
|
end_time: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def root():
|
||||||
|
"""Serve giao diện web"""
|
||||||
|
html_file = Path(__file__).parent / "training_interface.html"
|
||||||
|
if html_file.exists():
|
||||||
|
return FileResponse(html_file)
|
||||||
|
else:
|
||||||
|
return HTMLResponse("""
|
||||||
|
<html>
|
||||||
|
<head><title>Training Interface</title></head>
|
||||||
|
<body>
|
||||||
|
<h1>Land Classification Training API</h1>
|
||||||
|
<p>API Documentation: <a href="/docs">/docs</a></p>
|
||||||
|
<p>Training Interface: Tạo file training_interface.html</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/config/presets")
|
||||||
|
async def get_presets():
|
||||||
|
"""Lấy các preset cấu hình sẵn"""
|
||||||
|
return {
|
||||||
|
"presets": [
|
||||||
|
{
|
||||||
|
"name": "PC - Nhỏ (3 tháng, 20m, 12 scenes)",
|
||||||
|
"config": {
|
||||||
|
"min_lon": 105.6, "min_lat": 9.3, "max_lon": 106.2, "max_lat": 9.8,
|
||||||
|
"start_date": "2023-03-01", "end_date": "2023-05-31",
|
||||||
|
"max_scenes": 12, "cloud_cover": 30, "resolution": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Server - Trung bình (6 tháng, 10m, 30 scenes)",
|
||||||
|
"config": {
|
||||||
|
"min_lon": 105.5, "min_lat": 9.2, "max_lon": 106.4, "max_lat": 10.0,
|
||||||
|
"start_date": "2023-01-01", "end_date": "2023-06-30",
|
||||||
|
"max_scenes": 30, "cloud_cover": 30, "resolution": 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Full - Lớn (1 năm, 10m, 60 scenes)",
|
||||||
|
"config": {
|
||||||
|
"min_lon": 105.5, "min_lat": 9.2, "max_lon": 106.4, "max_lat": 10.0,
|
||||||
|
"start_date": "2022-09-01", "end_date": "2023-10-01",
|
||||||
|
"max_scenes": 60, "cloud_cover": 50, "resolution": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/training/status", response_model=TrainingStatus)
|
||||||
|
async def get_training_status():
|
||||||
|
"""Kiểm tra trạng thái training"""
|
||||||
|
return training_status
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/training/start")
|
||||||
|
async def start_training(config: TrainingConfig, background_tasks: BackgroundTasks):
|
||||||
|
"""Bắt đầu training với config đã chọn"""
|
||||||
|
global training_status
|
||||||
|
|
||||||
|
if training_status["is_training"]:
|
||||||
|
raise HTTPException(status_code=400, detail="Training đang chạy, vui lòng đợi")
|
||||||
|
|
||||||
|
# Reset status
|
||||||
|
training_status = {
|
||||||
|
"is_training": True,
|
||||||
|
"progress": "Đang khởi tạo...",
|
||||||
|
"error": None,
|
||||||
|
"result": None,
|
||||||
|
"start_time": datetime.now().isoformat(),
|
||||||
|
"end_time": None
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run training in background
|
||||||
|
background_tasks.add_task(run_training, config)
|
||||||
|
|
||||||
|
return {"message": "Training đã bắt đầu", "status": training_status}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/training/stop")
|
||||||
|
async def stop_training():
|
||||||
|
"""Dừng training (nếu đang chạy)"""
|
||||||
|
global training_status
|
||||||
|
|
||||||
|
if not training_status["is_training"]:
|
||||||
|
return {"message": "Không có training nào đang chạy"}
|
||||||
|
|
||||||
|
# Set cancel flag - the training will check this and stop
|
||||||
|
training_status["cancel_requested"] = True
|
||||||
|
training_status["progress"] = "Đang hủy training..."
|
||||||
|
|
||||||
|
return {"message": "Đang dừng training..."}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/cache/clear")
|
||||||
|
async def clear_cache():
|
||||||
|
"""Xóa cache dataset"""
|
||||||
|
import shutil
|
||||||
|
cache_dir = Path("dataset_cache")
|
||||||
|
|
||||||
|
if not cache_dir.exists():
|
||||||
|
return {"message": "Không có cache để xóa", "deleted": 0}
|
||||||
|
|
||||||
|
# Count files
|
||||||
|
cache_files = list(cache_dir.glob("*.joblib"))
|
||||||
|
count = len(cache_files)
|
||||||
|
|
||||||
|
# Delete all cache files
|
||||||
|
for cache_file in cache_files:
|
||||||
|
try:
|
||||||
|
cache_file.unlink()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {"message": f"Đã xóa {count} file cache", "deleted": count}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/cache/info")
|
||||||
|
async def get_cache_info():
|
||||||
|
"""Lấy thông tin về cache với metadata đầy đủ"""
|
||||||
|
cache_dir = Path("dataset_cache")
|
||||||
|
|
||||||
|
if not cache_dir.exists():
|
||||||
|
return {"exists": False, "files": [], "total_size_mb": 0}
|
||||||
|
|
||||||
|
cache_files = []
|
||||||
|
total_size = 0
|
||||||
|
|
||||||
|
for cache_file in cache_dir.glob("*.joblib"):
|
||||||
|
size = cache_file.stat().st_size
|
||||||
|
total_size += size
|
||||||
|
|
||||||
|
# Try to load metadata from cache
|
||||||
|
metadata = {}
|
||||||
|
try:
|
||||||
|
cached_data = joblib.load(cache_file)
|
||||||
|
if isinstance(cached_data, dict):
|
||||||
|
metadata = {
|
||||||
|
"bbox": cached_data.get("bbox", []),
|
||||||
|
"time_range": cached_data.get("time_range", ""),
|
||||||
|
"resolution": cached_data.get("resolution", 20),
|
||||||
|
"n_samples": len(cached_data.get("features", [])),
|
||||||
|
"created": cached_data.get("timestamp", "")
|
||||||
|
}
|
||||||
|
# Parse time_range to get start/end dates
|
||||||
|
if metadata["time_range"]:
|
||||||
|
time_parts = metadata["time_range"].split("/")
|
||||||
|
if len(time_parts) == 2:
|
||||||
|
metadata["start_date"] = time_parts[0]
|
||||||
|
metadata["end_date"] = time_parts[1]
|
||||||
|
# Parse bbox to get min/max lon/lat
|
||||||
|
if metadata["bbox"] and len(metadata["bbox"]) == 4:
|
||||||
|
metadata["min_lon"] = metadata["bbox"][0]
|
||||||
|
metadata["min_lat"] = metadata["bbox"][1]
|
||||||
|
metadata["max_lon"] = metadata["bbox"][2]
|
||||||
|
metadata["max_lat"] = metadata["bbox"][3]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading cache metadata: {e}")
|
||||||
|
|
||||||
|
cache_files.append({
|
||||||
|
"filename": cache_file.name,
|
||||||
|
"size_mb": round(size / 1024 / 1024, 2),
|
||||||
|
"modified": datetime.fromtimestamp(cache_file.stat().st_mtime).isoformat(),
|
||||||
|
"metadata": metadata
|
||||||
|
})
|
||||||
|
|
||||||
|
# Sort by modified time (newest first)
|
||||||
|
cache_files.sort(key=lambda x: x["modified"], reverse=True)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"exists": True,
|
||||||
|
"files": cache_files,
|
||||||
|
"count": len(cache_files),
|
||||||
|
"total_size_mb": round(total_size / 1024 / 1024, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/models/list")
|
||||||
|
async def list_models():
|
||||||
|
"""Liệt kê các model đã train"""
|
||||||
|
model_dir = Path("model_train")
|
||||||
|
if not model_dir.exists():
|
||||||
|
return {"models": []}
|
||||||
|
|
||||||
|
models = []
|
||||||
|
for model_file in model_dir.glob("*.joblib"):
|
||||||
|
info_file = model_file.with_suffix('.json')
|
||||||
|
info = {}
|
||||||
|
if info_file.exists():
|
||||||
|
with open(info_file) as f:
|
||||||
|
info = json.load(f)
|
||||||
|
|
||||||
|
models.append({
|
||||||
|
"filename": model_file.name,
|
||||||
|
"created": datetime.fromtimestamp(model_file.stat().st_mtime).isoformat(),
|
||||||
|
"size_mb": round(model_file.stat().st_size / 1024 / 1024, 2),
|
||||||
|
"info": info
|
||||||
|
})
|
||||||
|
|
||||||
|
# Sort by creation time (newest first)
|
||||||
|
models.sort(key=lambda x: x["created"], reverse=True)
|
||||||
|
return {"models": models}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/prediction/start")
|
||||||
|
async def start_prediction(config: PredictionConfig, background_tasks: BackgroundTasks):
|
||||||
|
"""Bắt đầu dự đoán"""
|
||||||
|
global prediction_status
|
||||||
|
|
||||||
|
if prediction_status["is_predicting"]:
|
||||||
|
raise HTTPException(status_code=400, detail="Đang có dự đoán khác đang chạy")
|
||||||
|
|
||||||
|
# Reset status
|
||||||
|
prediction_status = {
|
||||||
|
"is_predicting": True,
|
||||||
|
"progress": "Đang khởi động...",
|
||||||
|
"error": None,
|
||||||
|
"result": None,
|
||||||
|
"output_file": None,
|
||||||
|
"start_time": datetime.now().isoformat(),
|
||||||
|
"end_time": None
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run prediction in background
|
||||||
|
background_tasks.add_task(run_prediction, config)
|
||||||
|
|
||||||
|
return {"message": "Đã bắt đầu dự đoán", "status": prediction_status}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/prediction/status")
|
||||||
|
async def get_prediction_status():
|
||||||
|
"""Kiểm tra trạng thái dự đoán"""
|
||||||
|
return prediction_status
|
||||||
|
|
||||||
|
|
||||||
|
async def run_training(config: TrainingConfig):
|
||||||
|
"""Chạy training process"""
|
||||||
|
global training_status
|
||||||
|
|
||||||
|
try:
|
||||||
|
training_status["cancel_requested"] = False
|
||||||
|
training_status["progress"] = "Đang import thư viện..."
|
||||||
|
|
||||||
|
# Import training module
|
||||||
|
from train_module import train_model
|
||||||
|
|
||||||
|
training_status["progress"] = "Đang load dữ liệu Sentinel-2..."
|
||||||
|
|
||||||
|
# Function to check if training should be cancelled
|
||||||
|
def should_cancel():
|
||||||
|
return training_status.get("cancel_requested", False)
|
||||||
|
|
||||||
|
# Run training
|
||||||
|
result = train_model(
|
||||||
|
bbox=[config.min_lon, config.min_lat, config.max_lon, config.max_lat],
|
||||||
|
time_range=f"{config.start_date}/{config.end_date}",
|
||||||
|
max_scenes=config.max_scenes,
|
||||||
|
cloud_cover=config.cloud_cover,
|
||||||
|
resolution=config.resolution,
|
||||||
|
training_shapefile=config.training_shapefile,
|
||||||
|
model_type=config.model_type,
|
||||||
|
n_estimators=config.n_estimators,
|
||||||
|
max_depth=config.max_depth,
|
||||||
|
learning_rate=config.learning_rate,
|
||||||
|
use_gpu=config.use_gpu,
|
||||||
|
use_cache=config.use_cache,
|
||||||
|
status_callback=lambda msg: update_progress(msg),
|
||||||
|
cancel_check=should_cancel
|
||||||
|
)
|
||||||
|
|
||||||
|
if training_status.get("cancel_requested", False):
|
||||||
|
training_status["is_training"] = False
|
||||||
|
training_status["progress"] = "Đã hủy training"
|
||||||
|
training_status["error"] = "Training cancelled by user"
|
||||||
|
else:
|
||||||
|
training_status["is_training"] = False
|
||||||
|
training_status["progress"] = "Hoàn thành!"
|
||||||
|
training_status["result"] = result
|
||||||
|
training_status["end_time"] = datetime.now().isoformat()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
training_status["is_training"] = False
|
||||||
|
training_status["error"] = str(e)
|
||||||
|
training_status["progress"] = f"Lỗi: {str(e)}"
|
||||||
|
training_status["end_time"] = datetime.now().isoformat()
|
||||||
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
def update_progress(message: str):
|
||||||
|
"""Cập nhật progress message"""
|
||||||
|
global training_status
|
||||||
|
training_status["progress"] = message
|
||||||
|
print(f"[PROGRESS] {message}")
|
||||||
|
|
||||||
|
|
||||||
|
def update_prediction_progress(message: str):
|
||||||
|
"""Cập nhật prediction progress message"""
|
||||||
|
global prediction_status
|
||||||
|
prediction_status["progress"] = message
|
||||||
|
print(f"[PREDICTION PROGRESS] {message}")
|
||||||
|
|
||||||
|
|
||||||
|
async def run_prediction(config: PredictionConfig):
|
||||||
|
"""Chạy prediction process - Áp dụng phương pháp từ 02.predict_ODC.ipynb"""
|
||||||
|
global prediction_status
|
||||||
|
|
||||||
|
try:
|
||||||
|
prediction_status["progress"] = "Đang import thư viện..."
|
||||||
|
|
||||||
|
# Import required libraries
|
||||||
|
import xarray as xr
|
||||||
|
import numpy as np
|
||||||
|
from datetime import datetime as dt
|
||||||
|
import rioxarray
|
||||||
|
import dask.array as da
|
||||||
|
|
||||||
|
prediction_status["progress"] = "Đang load model..."
|
||||||
|
|
||||||
|
# Load model
|
||||||
|
model_path = Path("model_train") / config.model_filename
|
||||||
|
if not model_path.exists():
|
||||||
|
raise FileNotFoundError(f"Model không tồn tại: {config.model_filename}")
|
||||||
|
|
||||||
|
model_data = joblib.load(model_path)
|
||||||
|
|
||||||
|
# Extract model from dict (models are saved as {'model': xgb_model, 'label_encoder': encoder})
|
||||||
|
if isinstance(model_data, dict):
|
||||||
|
model = model_data.get('model')
|
||||||
|
label_encoder = model_data.get('label_encoder')
|
||||||
|
else:
|
||||||
|
model = model_data
|
||||||
|
label_encoder = None
|
||||||
|
|
||||||
|
# Check if it's a CNN model (PyTorch)
|
||||||
|
is_cnn_model = hasattr(model, '__class__') and 'CNN' in model.__class__.__name__
|
||||||
|
if is_cnn_model:
|
||||||
|
prediction_status["progress"] = "Phát hiện PyTorch CNN model..."
|
||||||
|
# Import PyTorch if needed
|
||||||
|
try:
|
||||||
|
import torch
|
||||||
|
except ImportError:
|
||||||
|
raise ImportError("PyTorch is required for CNN prediction. Install: pip install torch")
|
||||||
|
|
||||||
|
prediction_status["progress"] = "Đang kết nối Microsoft Planetary Computer..."
|
||||||
|
|
||||||
|
# Import and use Microsoft Planetary Computer STAC API
|
||||||
|
import pystac_client
|
||||||
|
import planetary_computer
|
||||||
|
from odc.stac import load
|
||||||
|
|
||||||
|
catalog = pystac_client.Client.open(
|
||||||
|
"https://planetarycomputer.microsoft.com/api/stac/v1",
|
||||||
|
modifier=planetary_computer.sign_inplace,
|
||||||
|
)
|
||||||
|
|
||||||
|
bbox = [config.min_lon, config.min_lat, config.max_lon, config.max_lat]
|
||||||
|
time_range = f"{config.start_date}/{config.end_date}"
|
||||||
|
|
||||||
|
# ============ BƯỚC 1: TẢI DỮ LIỆU SENTINEL-2 ============
|
||||||
|
prediction_status["progress"] = "Đang tải dữ liệu Sentinel-2..."
|
||||||
|
|
||||||
|
# Search Sentinel-2 data
|
||||||
|
s2_search = catalog.search(
|
||||||
|
collections=["sentinel-2-l2a"],
|
||||||
|
bbox=bbox,
|
||||||
|
datetime=time_range,
|
||||||
|
query={"eo:cloud_cover": {"lt": config.cloud_cover}}
|
||||||
|
)
|
||||||
|
|
||||||
|
s2_items = list(s2_search.items())
|
||||||
|
if not s2_items:
|
||||||
|
raise ValueError("Không tìm thấy dữ liệu Sentinel-2 cho khu vực và thời gian này")
|
||||||
|
|
||||||
|
s2_items = s2_items[:config.max_scenes]
|
||||||
|
prediction_status["progress"] = f"Đang xử lý {len(s2_items)} scenes Sentinel-2..."
|
||||||
|
|
||||||
|
# Load Sentinel-2 data
|
||||||
|
s2_data = load(
|
||||||
|
s2_items,
|
||||||
|
bbox=bbox,
|
||||||
|
chunks={"time": 1, "x": 2048, "y": 2048},
|
||||||
|
groupby="solar_day",
|
||||||
|
resolution=config.resolution
|
||||||
|
)
|
||||||
|
|
||||||
|
# ============ BƯỚC 2: TÍNH NDVI VÀ XỬ LÝ MÂY ============
|
||||||
|
prediction_status["progress"] = "Đang tính toán NDVI và xử lý mây..."
|
||||||
|
|
||||||
|
# Calculate NDVI using Sentinel-2 band names (B08 = NIR, B04 = Red)
|
||||||
|
nir = s2_data["B08"].astype('float32')
|
||||||
|
red = s2_data["B04"].astype('float32')
|
||||||
|
ndvi = (nir - red) / (nir + red + 1e-8)
|
||||||
|
|
||||||
|
# Mask clouds using SCL band if available
|
||||||
|
if "SCL" in s2_data:
|
||||||
|
scl = s2_data["SCL"]
|
||||||
|
# SCL values: 4=vegetation, 5=bare soil, 6=water - these are clear
|
||||||
|
# 3=cloud shadow, 8=cloud medium, 9=cloud high, 10=cirrus - mask these
|
||||||
|
cloud_mask = (scl == 3) | (scl == 8) | (scl == 9) | (scl == 10)
|
||||||
|
ndvi = ndvi.where(~cloud_mask)
|
||||||
|
|
||||||
|
# ============ BƯỚC 3: ĐIỀN GIÁ TRỊ NAN (FILL NAN) ============
|
||||||
|
prediction_status["progress"] = "Đang điền giá trị bị che mây..."
|
||||||
|
|
||||||
|
# Fill NaN using forward fill and backward fill
|
||||||
|
ndvi_filled = ndvi.ffill(dim='time').bfill(dim='time')
|
||||||
|
|
||||||
|
# Resample to monthly average
|
||||||
|
prediction_status["progress"] = "Đang tính trung bình NDVI theo tháng..."
|
||||||
|
ndvi_monthly = ndvi_filled.resample(time="1ME").mean()
|
||||||
|
|
||||||
|
# Compute NDVI (convert from dask to numpy)
|
||||||
|
ndvi_monthly = ndvi_monthly.compute()
|
||||||
|
|
||||||
|
# ============ BƯỚC 4: TẢI DỮ LIỆU SENTINEL-1 (VH, VV) ============
|
||||||
|
prediction_status["progress"] = "Đang tải dữ liệu Sentinel-1 (Radar)..."
|
||||||
|
|
||||||
|
# Search Sentinel-1 data
|
||||||
|
s1_search = catalog.search(
|
||||||
|
collections=["sentinel-1-rtc"],
|
||||||
|
bbox=bbox,
|
||||||
|
datetime=time_range,
|
||||||
|
)
|
||||||
|
|
||||||
|
s1_items = list(s1_search.items())
|
||||||
|
|
||||||
|
if s1_items:
|
||||||
|
s1_items = s1_items[:config.max_scenes]
|
||||||
|
prediction_status["progress"] = f"Đang xử lý {len(s1_items)} scenes Sentinel-1..."
|
||||||
|
|
||||||
|
# Load Sentinel-1 data (without like= to avoid conflict with bbox/resolution)
|
||||||
|
s1_data = load(
|
||||||
|
s1_items,
|
||||||
|
bbox=bbox,
|
||||||
|
chunks={"time": 1, "x": 2048, "y": 2048},
|
||||||
|
groupby="sat:absolute_orbit",
|
||||||
|
resolution=config.resolution
|
||||||
|
)
|
||||||
|
|
||||||
|
# Extract VH and VV bands
|
||||||
|
if "vh" in s1_data and "vv" in s1_data:
|
||||||
|
vh = s1_data["vh"].astype('float32')
|
||||||
|
vv = s1_data["vv"].astype('float32')
|
||||||
|
|
||||||
|
# Resample to monthly average
|
||||||
|
prediction_status["progress"] = "Đang tính trung bình VH/VV theo tháng..."
|
||||||
|
vh_monthly = vh.resample(time="1ME").mean().compute()
|
||||||
|
vv_monthly = vv.resample(time="1ME").mean().compute()
|
||||||
|
|
||||||
|
use_radar = True
|
||||||
|
else:
|
||||||
|
prediction_status["progress"] = "Không tìm thấy bands VH/VV, tiếp tục với NDVI..."
|
||||||
|
use_radar = False
|
||||||
|
else:
|
||||||
|
prediction_status["progress"] = "Không có dữ liệu Sentinel-1, tiếp tục với NDVI..."
|
||||||
|
use_radar = False
|
||||||
|
|
||||||
|
# ============ BƯỚC 5: CHUẨN BỊ FEATURES CHO DỰ ĐOÁN ============
|
||||||
|
prediction_status["progress"] = "Đang chuẩn bị features cho dự đoán..."
|
||||||
|
|
||||||
|
# Get shape information
|
||||||
|
n_times_ndvi = len(ndvi_monthly.time)
|
||||||
|
y_size = len(ndvi_monthly.y)
|
||||||
|
x_size = len(ndvi_monthly.x)
|
||||||
|
n_pixels = y_size * x_size
|
||||||
|
|
||||||
|
# Prepare NDVI features (flatten each time step)
|
||||||
|
ndvi_features = []
|
||||||
|
for t in range(n_times_ndvi):
|
||||||
|
ndvi_t = ndvi_monthly.isel(time=t).values.flatten()
|
||||||
|
ndvi_features.append(ndvi_t)
|
||||||
|
|
||||||
|
# Stack NDVI features
|
||||||
|
features = np.column_stack(ndvi_features)
|
||||||
|
|
||||||
|
# Add radar features if available
|
||||||
|
if use_radar:
|
||||||
|
n_times_vh = len(vh_monthly.time)
|
||||||
|
n_times_vv = len(vv_monthly.time)
|
||||||
|
|
||||||
|
# Add VH features
|
||||||
|
for t in range(min(n_times_vh, n_times_ndvi)):
|
||||||
|
vh_t = vh_monthly.isel(time=t).values.flatten()
|
||||||
|
# Resize if needed
|
||||||
|
if len(vh_t) != n_pixels:
|
||||||
|
vh_t = np.resize(vh_t, n_pixels)
|
||||||
|
features = np.column_stack([features, vh_t])
|
||||||
|
|
||||||
|
# Add VV features
|
||||||
|
for t in range(min(n_times_vv, n_times_ndvi)):
|
||||||
|
vv_t = vv_monthly.isel(time=t).values.flatten()
|
||||||
|
# Resize if needed
|
||||||
|
if len(vv_t) != n_pixels:
|
||||||
|
vv_t = np.resize(vv_t, n_pixels)
|
||||||
|
features = np.column_stack([features, vv_t])
|
||||||
|
|
||||||
|
# Handle NaN values in features✓ CNN PyTorch: Mạnh nhất với ảnh vệ tinh, tự học features, tương thích GPU tốt, cần pip install torch
|
||||||
|
features = np.nan_to_num(features, nan=0.0)
|
||||||
|
|
||||||
|
# ============ BƯỚC 6: DỰ ĐOÁN ============
|
||||||
|
# Check model's expected feature count and adjust
|
||||||
|
try:
|
||||||
|
# Get expected number of features from model
|
||||||
|
if is_cnn_model:
|
||||||
|
# For PyTorch CNN, get n_features from model
|
||||||
|
expected_features = model.n_features
|
||||||
|
elif hasattr(model, 'n_features_in_'):
|
||||||
|
expected_features = model.n_features_in_
|
||||||
|
elif hasattr(model, 'feature_names_in_'):
|
||||||
|
expected_features = len(model.feature_names_in_)
|
||||||
|
else:
|
||||||
|
# Try to get from booster for XGBoost
|
||||||
|
try:
|
||||||
|
expected_features = model.get_booster().num_features()
|
||||||
|
except:
|
||||||
|
expected_features = features.shape[1]
|
||||||
|
|
||||||
|
prediction_status["progress"] = f"Model cần {expected_features} features, đang có {features.shape[1]} features..."
|
||||||
|
|
||||||
|
# Adjust features to match model
|
||||||
|
if features.shape[1] > expected_features:
|
||||||
|
# Trim to expected number (use only first N features - NDVI only)
|
||||||
|
prediction_status["progress"] = f"Cắt bớt features từ {features.shape[1]} xuống {expected_features}..."
|
||||||
|
features = features[:, :expected_features]
|
||||||
|
elif features.shape[1] < expected_features:
|
||||||
|
# Pad with zeros or repeat last features
|
||||||
|
prediction_status["progress"] = f"Thêm features từ {features.shape[1]} lên {expected_features}..."
|
||||||
|
n_missing = expected_features - features.shape[1]
|
||||||
|
# Repeat last feature column to fill
|
||||||
|
padding = np.tile(features[:, -1:], (1, n_missing))
|
||||||
|
features = np.column_stack([features, padding])
|
||||||
|
except Exception as e:
|
||||||
|
prediction_status["progress"] = f"Không thể xác định số features của model, tiếp tục với {features.shape[1]} features..."
|
||||||
|
|
||||||
|
prediction_status["progress"] = f"Đang dự đoán với {features.shape[1]} features..."
|
||||||
|
|
||||||
|
# Make prediction
|
||||||
|
if is_cnn_model:
|
||||||
|
# PyTorch CNN prediction
|
||||||
|
predictions = model.predict(features)
|
||||||
|
else:
|
||||||
|
predictions = model.predict(features)
|
||||||
|
|
||||||
|
# Decode labels if label_encoder exists
|
||||||
|
if label_encoder is not None:
|
||||||
|
try:
|
||||||
|
predictions = label_encoder.inverse_transform(predictions)
|
||||||
|
except:
|
||||||
|
pass # Keep numeric predictions if inverse_transform fails
|
||||||
|
|
||||||
|
# Reshape to original shape
|
||||||
|
pred_shape = (y_size, x_size)
|
||||||
|
predictions_2d = predictions.reshape(pred_shape)
|
||||||
|
|
||||||
|
# ============ BƯỚC 7: TẠO OUTPUT VÀ LƯU KẾT QUẢ ============
|
||||||
|
prediction_status["progress"] = "Đang tạo bản đồ phân loại..."
|
||||||
|
|
||||||
|
# Create output xarray
|
||||||
|
prediction_da = xr.DataArray(
|
||||||
|
predictions_2d,
|
||||||
|
coords={
|
||||||
|
"y": ndvi_monthly.y,
|
||||||
|
"x": ndvi_monthly.x
|
||||||
|
},
|
||||||
|
dims=["y", "x"],
|
||||||
|
name="classification"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save output
|
||||||
|
output_dir = Path("predictions")
|
||||||
|
output_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
timestamp = dt.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
output_file = output_dir / f"prediction_{timestamp}.tif"
|
||||||
|
|
||||||
|
prediction_status["progress"] = "Đang lưu kết quả GeoTIFF..."
|
||||||
|
|
||||||
|
# Set CRS and save as GeoTIFF
|
||||||
|
if hasattr(s2_data, 'rio') and s2_data.rio.crs is not None:
|
||||||
|
prediction_da.rio.write_crs(s2_data.rio.crs, inplace=True)
|
||||||
|
else:
|
||||||
|
prediction_da.rio.write_crs("EPSG:4326", inplace=True)
|
||||||
|
|
||||||
|
prediction_da.rio.to_raster(str(output_file), driver="GTiff")
|
||||||
|
|
||||||
|
# Get unique classes for result
|
||||||
|
unique_classes = np.unique(predictions_2d)
|
||||||
|
unique_classes = unique_classes[~np.isnan(unique_classes)].tolist()
|
||||||
|
|
||||||
|
prediction_status["is_predicting"] = False
|
||||||
|
prediction_status["progress"] = "Hoàn thành!"
|
||||||
|
prediction_status["output_file"] = str(output_file)
|
||||||
|
prediction_status["result"] = {
|
||||||
|
"output_file": str(output_file),
|
||||||
|
"shape": list(pred_shape),
|
||||||
|
"unique_classes": unique_classes,
|
||||||
|
"bbox": bbox,
|
||||||
|
"time_range": time_range,
|
||||||
|
"n_features": features.shape[1],
|
||||||
|
"n_times_ndvi": n_times_ndvi,
|
||||||
|
"used_radar": use_radar,
|
||||||
|
"model_used": config.model_filename
|
||||||
|
}
|
||||||
|
prediction_status["end_time"] = dt.now().isoformat()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
prediction_status["is_predicting"] = False
|
||||||
|
prediction_status["error"] = str(e)
|
||||||
|
prediction_status["progress"] = f"Lỗi: {str(e)}"
|
||||||
|
prediction_status["end_time"] = dt.now().isoformat()
|
||||||
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/predictions/list")
|
||||||
|
async def list_predictions():
|
||||||
|
"""Lấy danh sách các file prediction đã tạo"""
|
||||||
|
predictions_dir = Path("predictions")
|
||||||
|
predictions_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
predictions = []
|
||||||
|
for pred_file in predictions_dir.glob("*.tif"):
|
||||||
|
predictions.append({
|
||||||
|
"filename": pred_file.name,
|
||||||
|
"created": datetime.fromtimestamp(pred_file.stat().st_mtime).isoformat(),
|
||||||
|
"size_mb": round(pred_file.stat().st_size / 1024 / 1024, 2),
|
||||||
|
"download_url": f"/api/predictions/download/{pred_file.name}"
|
||||||
|
})
|
||||||
|
|
||||||
|
# Sort by creation time (newest first)
|
||||||
|
predictions.sort(key=lambda x: x["created"], reverse=True)
|
||||||
|
return {"predictions": predictions}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/predictions/download/{filename}")
|
||||||
|
async def download_prediction(filename: str):
|
||||||
|
"""Download file prediction GeoTIFF"""
|
||||||
|
predictions_dir = Path("predictions")
|
||||||
|
file_path = predictions_dir / filename
|
||||||
|
|
||||||
|
# Security check: ensure filename doesn't contain path traversal
|
||||||
|
if ".." in filename or "/" in filename or "\\" in filename:
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid filename")
|
||||||
|
|
||||||
|
if not file_path.exists():
|
||||||
|
raise HTTPException(status_code=404, detail=f"File không tồn tại: {filename}")
|
||||||
|
|
||||||
|
return FileResponse(
|
||||||
|
path=str(file_path),
|
||||||
|
filename=filename,
|
||||||
|
media_type="image/tiff",
|
||||||
|
headers={
|
||||||
|
"Content-Disposition": f"attachment; filename={filename}"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=" * 70)
|
||||||
|
print("🚀 LAND CLASSIFICATION TRAINING API SERVER")
|
||||||
|
print("=" * 70)
|
||||||
|
print("\n📍 Endpoints:")
|
||||||
|
print(" - Web Interface: http://localhost:8000")
|
||||||
|
print(" - API Docs: http://localhost:8000/docs")
|
||||||
|
print(" - Start Training: POST http://localhost:8000/api/training/start")
|
||||||
|
print(" - Check Status: GET http://localhost:8000/api/training/status")
|
||||||
|
print("\n" + "=" * 70)
|
||||||
|
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:37686f6bbdd4590ce2dc5474eef8268f680498c2b78881a486625e264d2a1015
|
||||||
|
size 841901
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:78d28d677d39cc67e607bb418948b9e3e921351762d63b4737036fc02d1d361a
|
||||||
|
size 3375913
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:892cabc8da5cfcc0f9295ddb3ad32fda077027efa53e7b48e2f81965ad6ca202
|
||||||
|
size 3361173
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:fbab8f823ca6965dcbe43d9ce914f8912e3976833de1b205032eec48bfa83970
|
||||||
|
size 1670930
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7c33115ec7d6896758abf1eb8d07eba94ae15444c63f318e8adbd5d032df9a4f
|
||||||
|
size 1671094
|
||||||
@@ -85,7 +85,7 @@ def load_data(dc, date_range, longtitude_range, latitude_range):
|
|||||||
}
|
}
|
||||||
native_crs = notebook_utils.mostcommon_crs(dc, query)
|
native_crs = notebook_utils.mostcommon_crs(dc, query)
|
||||||
print(f'Most common native CRS: {native_crs}')
|
print(f'Most common native CRS: {native_crs}')
|
||||||
measurements = ['blue', 'green', 'red', 'nir', 'scl']
|
measurements = [ 'red', 'nir', 'scl']
|
||||||
|
|
||||||
load_params = {
|
load_params = {
|
||||||
'measurements': measurements, # Selected measurement or alias names
|
'measurements': measurements, # Selected measurement or alias names
|
||||||
@@ -317,4 +317,38 @@ def save_result(result, HT_MAP):
|
|||||||
# cbar.ax.set_yticklabels(labels)
|
# cbar.ax.set_yticklabels(labels)
|
||||||
# plt.title(f'{HT_MAP[k]["name"]}')
|
# plt.title(f'{HT_MAP[k]["name"]}')
|
||||||
# plt.axis('off')
|
# plt.axis('off')
|
||||||
# plt.show()
|
# plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def accuracy_test(test, data_array):
|
||||||
|
# cấu hình nhãn dữ liệu
|
||||||
|
label_mapping = {
|
||||||
|
"Lua tom": "0",
|
||||||
|
"Lua": "1",
|
||||||
|
"CHN": "2",
|
||||||
|
"CLN": "3",
|
||||||
|
"TS": "4",
|
||||||
|
"Song": "5",
|
||||||
|
"Dat xay dung": "6",
|
||||||
|
"Rung": "7"
|
||||||
|
}
|
||||||
|
|
||||||
|
chk = []
|
||||||
|
pred = []
|
||||||
|
dd = []
|
||||||
|
for idx, point in test.iterrows():
|
||||||
|
label = point.LULC
|
||||||
|
predict = data_array.sel(x=point.geometry.x, y=point.geometry.y, method='nearest').values
|
||||||
|
pred.append(label_mapping[label])
|
||||||
|
dd.append(str(predict))
|
||||||
|
chk.append(predict == int(label_mapping[label]))
|
||||||
|
test["code"] = pred
|
||||||
|
test["dd"] = dd
|
||||||
|
test["check"] = chk
|
||||||
|
path = "ThuanHoa/TestAccuracy"
|
||||||
|
if not os.path.exists(path):
|
||||||
|
os.mkdir(path)
|
||||||
|
test.to_file(f"{path}/result.shp")
|
||||||
|
|
||||||
|
percentage_true = np.mean(chk) * 100
|
||||||
|
print(f"độ chính xác: {percentage_true:.2f}%")
|
||||||
+1
Submodule backup_code_training/CSIROBoeingPhase5-Vietnam added at 8f0cb55cba
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:e71c696efbcb9e766eb1a666cc85b4f604992a65efc7258a46a46c7f81c596db
|
||||||
|
size 3536032
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:520c3480efaafdf844c3bba3dd165a8e44f3318ab21209539c78201f18fd6312
|
||||||
|
size 3066028
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7d3bff20682fc510a9c41b5aa2b42e3ebef8098ed81e27b4436f9ae86f47b9a6
|
||||||
|
size 3066028
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:322f48d2d54ee921facfc3c0c44b320a86a90694e1779b683824264f9affa3fc
|
||||||
|
size 3066028
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a446d333bf7f6d0cb7df014f12b0da3f7298f85bdfb4de06893173e90fbd5ccb
|
||||||
|
size 14112695
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:3eec576dffe1cc1393fdb584fb99d28db62abdd0977d41030aee5c4fa5377180
|
||||||
|
size 11474743
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:cc125de4c172c98d9e50123bfcc2f8dd856e4ccd6bb04edd639badf090af2eef
|
||||||
|
size 5077735
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:8004f197bab9800b257d62064bf1220b908f2b17eadce826b87f0284241a1842
|
||||||
|
size 1420071
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:4e989c28641beb9af91d2b12a9a0b957b2b8c6510f437a68b69271ea136cce65
|
||||||
|
size 1604860
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7115a28f7fb41599b59f9337d7457ed4578ba989878a4ccd907c60e69be2311a
|
||||||
|
size 973302
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:da63ad454fd0e6de316e17df9345abe1b193998d1eb97c545b6a87a66058e884
|
||||||
|
size 766972
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:cfb8412f0ee12abb7f1bb067522b3b800102ffdfa18b84027603c5d1870c968e
|
||||||
|
size 518845
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7318566231680cb0c97883b7a5e4177aa1bfeec462a0f52ed34aa103ddec210b
|
||||||
|
size 20903
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9cabf5e0241dcc3a73133ac8ae11171f34042c491f895b268c016407619bdfe1
|
||||||
|
size 20903
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,164 @@
|
|||||||
|
# 🌾 Giải Thích Quy Trình Phân Loại Đất Trồng Cây
|
||||||
|
|
||||||
|
File notebook `02.predict_ODC.ipynb` sử dụng **Machine Learning** kết hợp với **dữ liệu vệ tinh** để phân loại các loại đất/cây trồng. Dưới đây là quy trình chi tiết:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 1: Thu thập dữ liệu vệ tinh** (Cell 3-4)
|
||||||
|
|
||||||
|
```python
|
||||||
|
date_range = ('2022-09-01', '2023-10-01')
|
||||||
|
longtitude_range = (105.86575, 105.94120)
|
||||||
|
latitude_range = (9.65070, 9.69850)
|
||||||
|
data = load_data(dc, date_range, longtitude_range, latitude_range)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Lấy ảnh **Sentinel-2** (ảnh quang học) từ kho dữ liệu trong khoảng thời gian và vị trí cụ thể
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 2: Xử lý mây** (Cell 5)
|
||||||
|
|
||||||
|
```python
|
||||||
|
result = mask_clean(data)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Loại bỏ các pixel bị mây che phủ để đảm bảo dữ liệu chính xác
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 3: Tính chỉ số NDVI** (Cell 6-10)
|
||||||
|
|
||||||
|
```python
|
||||||
|
ndvi = calculate_indices(result, index='NDVI', satellite_mission='s2')
|
||||||
|
fill_nan_ndvi = fill_nan(ndvi, time_split)
|
||||||
|
average_ndvi = fill_nan_ndvi.resample(time='1M').mean()
|
||||||
|
```
|
||||||
|
|
||||||
|
- **NDVI** (Normalized Difference Vegetation Index) = (NIR - Red) / (NIR + Red)
|
||||||
|
- Giá trị từ **-1 đến 1**: cao = thực vật xanh tốt, thấp = đất trống/nước
|
||||||
|
- Điền giá trị nan (mây) và tính trung bình theo tháng
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 4: Lấy dữ liệu Radar Sentinel-1** (Cell 11)
|
||||||
|
|
||||||
|
```python
|
||||||
|
dsvh, dsvv = load_data_sen1(dc, date_range, coordinates)
|
||||||
|
average_vv = calculate_average(dsvv, time_pattern='1M')
|
||||||
|
average_vh = calculate_average(dsvh, time_pattern='1M')
|
||||||
|
```
|
||||||
|
|
||||||
|
- **VH, VV**: Dữ liệu radar (xuyên mây), cho biết cấu trúc bề mặt
|
||||||
|
- Giúp phân biệt lúa ngập nước, cây trồng cạn, mặt nước...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 5: Dự đoán bằng Model ML** (Cell 12) ⭐ **QUAN TRỌNG NHẤT**
|
||||||
|
|
||||||
|
```python
|
||||||
|
loaded_model = joblib.load("model_train/model_odc.joblib")
|
||||||
|
data_array = predict(loaded_model, data.rio.crs, average_ndvi, average_vh, average_vv)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Model đã được train trước** với dữ liệu mẫu (training data) gồm:
|
||||||
|
- **Đầu vào (Features)**: NDVI theo tháng + VH + VV (chuỗi thời gian)
|
||||||
|
- **Đầu ra (Labels)**: Loại đất đã được gắn nhãn thủ công
|
||||||
|
|
||||||
|
### Cách model phân loại:
|
||||||
|
|
||||||
|
| Đặc điểm | Loại đất |
|
||||||
|
|----------|----------|
|
||||||
|
| NDVI cao đều, VV thấp | Rừng |
|
||||||
|
| NDVI biến đổi theo mùa vụ, VH cao (nước) | Lúa |
|
||||||
|
| NDVI thấp, VV rất thấp | Sông/nước |
|
||||||
|
| NDVI trung bình ổn định | Cây lâu năm (CLN) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 6: Hiển thị kết quả** (Cell 13-15)
|
||||||
|
|
||||||
|
```python
|
||||||
|
colors = ["#abcee9", "#ffef44", "#c4ff9e", "#ffd6a8", "#93ddda", "#1aeef7", "#ffa7f2", "#33ee33"]
|
||||||
|
labels = ["Lúa tôm", "Lúa", "CHN", "CLN", "TS", "Sông", "Đất xây dựng", "Rừng"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8 lớp phân loại:
|
||||||
|
|
||||||
|
| Mã | Tên | Màu | Ý nghĩa |
|
||||||
|
|----|-----|-----|---------|
|
||||||
|
| 0 | Lúa tôm | 🔵 Xanh nhạt | Luân canh lúa-tôm |
|
||||||
|
| 1 | Lúa | 🟡 Vàng | Đất trồng lúa |
|
||||||
|
| 2 | CHN | 🟢 Xanh lá nhạt | Cây hàng năm |
|
||||||
|
| 3 | CLN | 🟠 Cam nhạt | Cây lâu năm (cây ăn trái) |
|
||||||
|
| 4 | TS | 🩵 Xanh ngọc | Thủy sản |
|
||||||
|
| 5 | Sông | 🔷 Cyan | Mặt nước sông |
|
||||||
|
| 6 | Đất XD | 💗 Hồng | Đất xây dựng |
|
||||||
|
| 7 | Rừng | 💚 Xanh đậm | Rừng |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## **Bước 7: Lưu kết quả** (Cell 16)
|
||||||
|
|
||||||
|
```python
|
||||||
|
region_result.rio.to_raster("KetQuaPhanLoaiDatODC.tif")
|
||||||
|
```
|
||||||
|
|
||||||
|
- Xuất file GeoTIFF chứa mã phân loại (0-7) cho từng pixel
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 **Tóm tắt quy trình:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Ảnh vệ tinh (Sentinel-1 + Sentinel-2)
|
||||||
|
↓
|
||||||
|
Xử lý (loại mây, tính NDVI, VH, VV)
|
||||||
|
↓
|
||||||
|
Kết hợp features theo thời gian (13 tháng)
|
||||||
|
↓
|
||||||
|
Model ML (Random Forest/XGBoost) dự đoán
|
||||||
|
↓
|
||||||
|
Bản đồ phân loại 8 lớp đất
|
||||||
|
↓
|
||||||
|
File .tif (mỗi pixel = 1 mã loại đất)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Cấu trúc dữ liệu đầu vào cho Model
|
||||||
|
|
||||||
|
### Features (Đặc trưng):
|
||||||
|
- **NDVI theo 13 tháng**: 13 bands
|
||||||
|
- **VH (radar) theo 13 tháng**: 13 bands
|
||||||
|
- **VV (radar) theo 13 tháng**: 13 bands
|
||||||
|
- **Tổng cộng**: ~39 features cho mỗi pixel
|
||||||
|
|
||||||
|
### Labels (Nhãn):
|
||||||
|
- Được lấy từ shapefile training: `train/ST_training data_updated_1130points_new.shp`
|
||||||
|
- 1130 điểm mẫu đã được gắn nhãn thủ công bởi chuyên gia
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Các thư viện sử dụng
|
||||||
|
|
||||||
|
| Thư viện | Mục đích |
|
||||||
|
|----------|----------|
|
||||||
|
| `datacube` | Truy vấn dữ liệu vệ tinh |
|
||||||
|
| `xarray` | Xử lý dữ liệu đa chiều |
|
||||||
|
| `rioxarray` | Đọc/ghi GeoTIFF |
|
||||||
|
| `joblib` | Load/save model ML |
|
||||||
|
| `sklearn` / `xgboost` | Training model |
|
||||||
|
| `matplotlib` / `hvplot` | Trực quan hóa |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Ghi chú
|
||||||
|
|
||||||
|
- **Độ phân giải**: 10-20m (tùy cấu hình)
|
||||||
|
- **Thời gian xử lý**: Phụ thuộc vào kích thước vùng và số scenes
|
||||||
|
- **Yêu cầu**: Cần kết nối internet để tải dữ liệu vệ tinh từ Planetary Computer hoặc ODC
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Tài liệu được tạo ngày 14/12/2025*
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:ae2f82f6c837396729cc63efa41ee3048d9a7de3197e28318dc846be830239b9
|
||||||
|
size 41536
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-14T18:04:27.406540",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 0.515686274509804,
|
||||||
|
"test_accuracy": 0.5,
|
||||||
|
"model_type": "cnn",
|
||||||
|
"device": "cpu",
|
||||||
|
"n_estimators": 50,
|
||||||
|
"max_depth": null,
|
||||||
|
"learning_rate": null,
|
||||||
|
"cnn_epochs": 25,
|
||||||
|
"n_features": 3,
|
||||||
|
"n_classes": 7,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:abc03d62c7f620b88150a6481143026d516fd3a34bd5ab67c734adac4a8900f9
|
||||||
|
size 41536
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-14T18:17:48.399298",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 0.4803921568627451,
|
||||||
|
"test_accuracy": 0.484375,
|
||||||
|
"model_type": "cnn",
|
||||||
|
"device": "cpu",
|
||||||
|
"n_estimators": 50,
|
||||||
|
"max_depth": null,
|
||||||
|
"learning_rate": null,
|
||||||
|
"cnn_epochs": 25,
|
||||||
|
"n_features": 3,
|
||||||
|
"n_classes": 7,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-25",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:21f906aa2a61d2e793a3463df95fe3e364134934af326771efae90d80caca419
|
||||||
|
size 41536
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-14T18:23:10.713912",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 0.46862745098039216,
|
||||||
|
"test_accuracy": 0.4609375,
|
||||||
|
"model_type": "cnn",
|
||||||
|
"device": "cpu",
|
||||||
|
"n_estimators": 50,
|
||||||
|
"max_depth": null,
|
||||||
|
"learning_rate": null,
|
||||||
|
"cnn_epochs": 25,
|
||||||
|
"n_features": 3,
|
||||||
|
"n_classes": 7,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:3eec576dffe1cc1393fdb584fb99d28db62abdd0977d41030aee5c4fa5377180
|
||||||
|
size 11474743
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:0fe99f96ad3d3ba7aaacc0e742572a8f5b22947a328c74b245e0aa5f2913c757
|
||||||
|
size 1347520
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-12T12:57:54.509336",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 1.0,
|
||||||
|
"test_accuracy": 0.578125,
|
||||||
|
"model_type": "XGBClassifier",
|
||||||
|
"device": "cuda:0",
|
||||||
|
"gpu_device": "RTX 4060",
|
||||||
|
"tree_method": "hist",
|
||||||
|
"n_estimators": 100,
|
||||||
|
"max_depth": 20,
|
||||||
|
"learning_rate": 0.1
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b717f564f9413a6e5c9cd3f7011cbc18be02479691d01c554986defb400f0490
|
||||||
|
size 1347520
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-12T22:15:25.794614",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 1.0,
|
||||||
|
"test_accuracy": 0.578125,
|
||||||
|
"model_type": "XGBClassifier",
|
||||||
|
"device": "cuda:0",
|
||||||
|
"tree_method": "hist",
|
||||||
|
"n_estimators": 100,
|
||||||
|
"max_depth": 20,
|
||||||
|
"learning_rate": 0.1,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b9c6cabb59d9cdbba22a438ae935911f1711d7434dcf3728db4e518ec1b90190
|
||||||
|
size 556184
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-12T22:33:42.950629",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 904,
|
||||||
|
"testing_samples": 226,
|
||||||
|
"train_accuracy": 0.19911504424778761,
|
||||||
|
"test_accuracy": 0.19911504424778761,
|
||||||
|
"model_type": "XGBClassifier",
|
||||||
|
"device": "cuda:0",
|
||||||
|
"tree_method": "hist",
|
||||||
|
"n_estimators": 100,
|
||||||
|
"max_depth": 20,
|
||||||
|
"learning_rate": 0.1,
|
||||||
|
"bbox": [
|
||||||
|
104.89032,
|
||||||
|
10.944563,
|
||||||
|
104.972717,
|
||||||
|
11.016689
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b717f564f9413a6e5c9cd3f7011cbc18be02479691d01c554986defb400f0490
|
||||||
|
size 1347520
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-14T13:40:03.325930",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 510,
|
||||||
|
"testing_samples": 128,
|
||||||
|
"train_accuracy": 1.0,
|
||||||
|
"test_accuracy": 0.578125,
|
||||||
|
"model_type": "XGBClassifier",
|
||||||
|
"device": "cuda:0",
|
||||||
|
"tree_method": "hist",
|
||||||
|
"n_estimators": 100,
|
||||||
|
"max_depth": 20,
|
||||||
|
"learning_rate": 0.1,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-05-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a44efc173619782c8add224e9024f33ef0150ab192b5435d009cb119c379f03c
|
||||||
|
size 2088632
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2025-12-14T16:52:19.862770",
|
||||||
|
"data_source": "Microsoft Planetary Computer STAC",
|
||||||
|
"collections": [
|
||||||
|
"sentinel-2-l2a",
|
||||||
|
"sentinel-1-rtc"
|
||||||
|
],
|
||||||
|
"features": [
|
||||||
|
"NDVI_mean",
|
||||||
|
"VH_dB_mean",
|
||||||
|
"VV_dB_mean"
|
||||||
|
],
|
||||||
|
"training_samples": 859,
|
||||||
|
"testing_samples": 215,
|
||||||
|
"train_accuracy": 0.9976717112922002,
|
||||||
|
"test_accuracy": 0.6837209302325581,
|
||||||
|
"model_type": "XGBClassifier",
|
||||||
|
"device": "cuda:0",
|
||||||
|
"tree_method": "hist",
|
||||||
|
"n_estimators": 100,
|
||||||
|
"max_depth": 20,
|
||||||
|
"learning_rate": 0.1,
|
||||||
|
"bbox": [
|
||||||
|
105.6,
|
||||||
|
9.3,
|
||||||
|
106.2,
|
||||||
|
9.8
|
||||||
|
],
|
||||||
|
"time_range": "2023-03-01/2023-12-31",
|
||||||
|
"resolution": 20
|
||||||
|
}
|
||||||
@@ -0,0 +1,479 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
# Common imports and settings
|
||||||
|
import os, sys
|
||||||
|
os.environ['USE_PYGEOS'] = '0'
|
||||||
|
from IPython.display import Markdown
|
||||||
|
import pandas as pd
|
||||||
|
pd.set_option("display.max_rows", None)
|
||||||
|
import xarray as xr
|
||||||
|
|
||||||
|
# Datacube
|
||||||
|
import datacube
|
||||||
|
from datacube.utils.rio import configure_s3_access
|
||||||
|
from datacube.utils import masking
|
||||||
|
from datacube.utils.cog import write_cog
|
||||||
|
# https://github.com/GeoscienceAustralia/dea-notebooks/tree/develop/Tools
|
||||||
|
from dea_tools.plotting import display_map, rgb
|
||||||
|
from dea_tools.datahandling import mostcommon_crs
|
||||||
|
|
||||||
|
# EASI defaults
|
||||||
|
easinotebooksrepo = '/home/jovyan/easi-notebooks'
|
||||||
|
if easinotebooksrepo not in sys.path: sys.path.append(easinotebooksrepo)
|
||||||
|
from easi_tools import EasiDefaults, xarray_object_size, notebook_utils, unset_cachingproxy
|
||||||
|
from easi_tools.load_s2l2a import load_s2l2a_with_offset
|
||||||
|
from dask.distributed import progress
|
||||||
|
|
||||||
|
# Data tools
|
||||||
|
import numpy as np
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Datacube
|
||||||
|
from datacube.utils import masking # https://github.com/opendatacube/datacube-core/blob/develop/datacube/utils/masking.py
|
||||||
|
from odc.algo import enum_to_bool # https://github.com/opendatacube/odc-algo/blob/main/odc/algo/_masking.py
|
||||||
|
from odc.algo import xr_reproject # https://github.com/opendatacube/odc-algo/blob/main/odc/algo/_warp.py
|
||||||
|
from datacube.utils.geometry import GeoBox, box # https://github.com/opendatacube/datacube-core/blob/develop/datacube/utils/geometry/_base.py
|
||||||
|
|
||||||
|
# Holoviews, Datashader and Bokeh
|
||||||
|
import hvplot.pandas
|
||||||
|
import hvplot.xarray
|
||||||
|
import holoviews as hv
|
||||||
|
import panel as pn
|
||||||
|
import colorcet as cc
|
||||||
|
import cartopy.crs as ccrs
|
||||||
|
from datashader import reductions
|
||||||
|
from holoviews import opts
|
||||||
|
from utils import load_data_geo
|
||||||
|
import rasterio
|
||||||
|
import rioxarray
|
||||||
|
# import geoviews as gv
|
||||||
|
# from holoviews.operation.datashader import rasterize
|
||||||
|
hv.extension('bokeh', logo=False)
|
||||||
|
|
||||||
|
from deafrica_tools.bandindices import calculate_indices
|
||||||
|
from sklearn.ensemble import RandomForestClassifier
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
from sklearn.metrics import accuracy_score, classification_report
|
||||||
|
from sklearn.preprocessing import LabelEncoder
|
||||||
|
|
||||||
|
from sklearn.pipeline import Pipeline
|
||||||
|
from sklearn.ensemble import RandomForestClassifier
|
||||||
|
from sklearn.impute import SimpleImputer
|
||||||
|
from sklearn.preprocessing import StandardScaler
|
||||||
|
from sklearn.model_selection import GridSearchCV
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
from sklearn.metrics import accuracy_score
|
||||||
|
from shapely.geometry import Point, Polygon
|
||||||
|
import geopandas as gpd
|
||||||
|
from pyproj import CRS
|
||||||
|
from matplotlib.colors import ListedColormap
|
||||||
|
from holoviews import opts
|
||||||
|
from datashader import reductions
|
||||||
|
from bokeh.models.tickers import FixedTicker
|
||||||
|
from rioxarray.merge import merge_arrays
|
||||||
|
|
||||||
|
from sklearn.preprocessing import PolynomialFeatures
|
||||||
|
from sklearn.linear_model import LinearRegression
|
||||||
|
from sklearn.ensemble import RandomForestRegressor
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
from sklearn.metrics import mean_squared_error, r2_score
|
||||||
|
|
||||||
|
import joblib
|
||||||
|
|
||||||
|
|
||||||
|
def load_data(dc, date_range, longtitude_range, latitude_range):
|
||||||
|
product = 's2_l2a'
|
||||||
|
query = {
|
||||||
|
'product': product, # Product name
|
||||||
|
'x': longtitude_range, # "x" axis bounds
|
||||||
|
'y': latitude_range, # "y" axis bounds
|
||||||
|
'time': date_range, # Any parsable date strings
|
||||||
|
}
|
||||||
|
native_crs = notebook_utils.mostcommon_crs(dc, query)
|
||||||
|
print(f'Most common native CRS: {native_crs}')
|
||||||
|
measurements = ['red', 'nir', 'scl']
|
||||||
|
|
||||||
|
load_params = {
|
||||||
|
'measurements': measurements, # Selected measurement or alias names
|
||||||
|
'output_crs': native_crs, # Target EPSG code
|
||||||
|
'resolution': (-10, 10), # Target resolution
|
||||||
|
'group_by': 'solar_day', # Scene grouping
|
||||||
|
'dask_chunks': {'x': 2048, 'y': 2048}, # Dask chunks
|
||||||
|
}
|
||||||
|
data = load_s2l2a_with_offset(
|
||||||
|
dc,
|
||||||
|
query | load_params # Combine the two dicts that contain our search and load parameters
|
||||||
|
)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def mask_clean(data):
|
||||||
|
flag_name = 'scl'
|
||||||
|
flag_desc = masking.describe_variable_flags(data[flag_name]) # Pandas dataframe
|
||||||
|
display(flag_desc)
|
||||||
|
display(flag_desc.loc['qa'].values[1])
|
||||||
|
# Create a "data quality" Mask layer
|
||||||
|
flags_def = flag_desc.loc['qa'].values[1]
|
||||||
|
good_pixel_flags = [flags_def[str(i)] for i in [2, 4, 5, 6]] # To pass strings to enum_to_bool()
|
||||||
|
|
||||||
|
# enum_to_bool calculates the pixel-wise "or" of each set of pixels given by good_pixel_flags
|
||||||
|
# 1 = good data
|
||||||
|
# 0 = "bad" data
|
||||||
|
good_pixel_mask = enum_to_bool(data[flag_name], good_pixel_flags)
|
||||||
|
data_layer_names = [x for x in data.data_vars if x != 'scl']
|
||||||
|
# Apply good pixel mask to blue, green, red and nir.
|
||||||
|
result = data[data_layer_names].where(good_pixel_mask).persist()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def fill_nan(ndvi, time_split):
|
||||||
|
rs = []
|
||||||
|
for times in time_split:
|
||||||
|
tmp = ndvi.sel(time=times)
|
||||||
|
fill_ds = tmp.sel(time=times).bfill(dim='time')
|
||||||
|
fill_ds = fill_ds.sel(time=times).ffill(dim='time')
|
||||||
|
rs.append(fill_ds)
|
||||||
|
merged_ndvi = xr.concat([i for i in rs], dim="time")
|
||||||
|
fill_m = merged_ndvi.bfill(dim="time")
|
||||||
|
fill_m = fill_m.ffill(dim="time")
|
||||||
|
return fill_m
|
||||||
|
|
||||||
|
|
||||||
|
def load_train_data(train_path):
|
||||||
|
train = load_data_geo(train_path)
|
||||||
|
return train
|
||||||
|
|
||||||
|
|
||||||
|
def load_sen1(name_vh, name_vv):
|
||||||
|
dsvv = rioxarray.open_rasterio(name_vv)
|
||||||
|
dsvh = rioxarray.open_rasterio(name_vh)
|
||||||
|
return dsvh, dsvv
|
||||||
|
|
||||||
|
|
||||||
|
def get_data_sen1_and_sen2(train, average_ndvi, dsvh, dsvv):
|
||||||
|
loaded_datasets = {}
|
||||||
|
for idx, point in train.iterrows():
|
||||||
|
key = f"point_{idx + 1}"
|
||||||
|
try:
|
||||||
|
ndvi_data = average_ndvi.sel(x=point.geometry.x, y=point.geometry.y, method='nearest').values
|
||||||
|
vh_data = dsvh.sel(x=point.geometry.x, y=point.geometry.y, method='nearest').values
|
||||||
|
vv_data = dsvv.sel(x=point.geometry.x, y=point.geometry.y, method='nearest').values
|
||||||
|
loaded_datasets[key] = {
|
||||||
|
"data": np.concatenate((ndvi_data, vh_data, vv_data)),
|
||||||
|
"label": point.HT_code
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
# loaded_datasets[key] = None
|
||||||
|
print(e)
|
||||||
|
return loaded_datasets
|
||||||
|
|
||||||
|
|
||||||
|
def split_train_data(train, label_mapping, datasets):
|
||||||
|
label_encoder = LabelEncoder()
|
||||||
|
|
||||||
|
# Fit and transform the labels
|
||||||
|
labels = train.Hientrang.values
|
||||||
|
numeric_labels = label_encoder.fit_transform([label_mapping[label] for label in labels])
|
||||||
|
X = []
|
||||||
|
x_new = []
|
||||||
|
lb_new = []
|
||||||
|
for k, v in datasets.items():
|
||||||
|
X.append(v)
|
||||||
|
for i in range(len(X)):
|
||||||
|
if X[i] is not None:
|
||||||
|
x_new.append(X[i]["data"])
|
||||||
|
lb_new.append(numeric_labels[i])
|
||||||
|
X_train, X_temp, y_train, y_temp= train_test_split(x_new, lb_new, test_size=0.4, random_state=42)
|
||||||
|
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
|
||||||
|
return X_train, X_val, X_test, y_train, y_val, y_test
|
||||||
|
|
||||||
|
|
||||||
|
def train_with_rf(X_train, X_val, y_train, y_val):
|
||||||
|
# Takes 1-2 minutes to complete
|
||||||
|
|
||||||
|
# Tạo RandomForestClassifier mặc định để sử dụng làm mô hình ban đầu trong pipeline
|
||||||
|
base_model = RandomForestClassifier(random_state=42, n_jobs=-1)
|
||||||
|
|
||||||
|
# Tạo pipeline
|
||||||
|
pipeline = Pipeline([
|
||||||
|
# ('imputer', SimpleImputer(strategy='mean')),
|
||||||
|
('scaler', StandardScaler()),
|
||||||
|
('classifier', base_model),
|
||||||
|
])
|
||||||
|
# Thiết lập các tham số bạn muốn tối ưu hóa
|
||||||
|
param_grid = {
|
||||||
|
'classifier__n_estimators': [100, 300, 500, 700, 1000],
|
||||||
|
'classifier__max_depth': [6, 8, 10, 15, 20],
|
||||||
|
'classifier__criterion': ['gini', 'entropy'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sử dụng GridSearchCV để tìm bộ tham số tốt nhất
|
||||||
|
grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
|
||||||
|
grid_search.fit(X_train, y_train)
|
||||||
|
|
||||||
|
# In ra bộ tham số tốt nhất
|
||||||
|
best_params = grid_search.best_params_
|
||||||
|
print("Best Parameters:", best_params)
|
||||||
|
|
||||||
|
# Dự đoán trên tập kiểm tra
|
||||||
|
y_pred = grid_search.predict(X_val)
|
||||||
|
|
||||||
|
# Đánh giá kết quả
|
||||||
|
accuracy = accuracy_score(y_val, y_pred)
|
||||||
|
print(f"Accuracy: {round(accuracy, 2)*100} %")
|
||||||
|
return grid_search
|
||||||
|
|
||||||
|
|
||||||
|
def save_model(name_file, grid_search):
|
||||||
|
dir_save_model = "model_train"
|
||||||
|
if not os.path.exists(dir_save_model):
|
||||||
|
os.mkdir(dir_save_model)
|
||||||
|
joblib.dump(grid_search, os.path.join(dir_save_model, name_file))
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
|
||||||
|
def predict(model, data_crs, ndvi, vh, vv):
|
||||||
|
data_predict = []
|
||||||
|
for i in range(ndvi.shape[1]):
|
||||||
|
ndvi_tmp = ndvi.isel(y=i).values
|
||||||
|
vh_data = vh.sel(y=ndvi.y.values[i], method='nearest').values
|
||||||
|
vv_data = vv.sel(y=ndvi.y.values[i], method='nearest').values
|
||||||
|
all_tmp = np.concatenate((ndvi_tmp, vh_data, vv_data), axis=0)
|
||||||
|
data_predict.extend(all_tmp.T)
|
||||||
|
y_pred = model.predict(data_predict)
|
||||||
|
final_label = y_pred.reshape(ndvi.y.shape[0], ndvi.x.shape[0])
|
||||||
|
|
||||||
|
final_xarray_save = xr.DataArray(final_label, dims=("y", "x"))
|
||||||
|
final_xarray_save = final_xarray_save.rio.write_crs(data_crs)
|
||||||
|
|
||||||
|
x_values = ndvi.x.values
|
||||||
|
y_values = ndvi.y.values
|
||||||
|
|
||||||
|
data_array = xr.DataArray(final_xarray_save,
|
||||||
|
coords={'x': x_values, 'y': y_values},
|
||||||
|
dims=['y', 'x'])
|
||||||
|
data_array = data_array.rio.write_crs(ndvi.rio.crs)
|
||||||
|
return data_array
|
||||||
|
|
||||||
|
|
||||||
|
def cut_according_shp(thuanhoa_path, average_ndvi, data_array):
|
||||||
|
gdf = gpd.read_file(thuanhoa_path)
|
||||||
|
gdf = gdf.to_crs(average_ndvi.rio.crs)
|
||||||
|
polygon_coords = list(gdf.geometry.values[0].exterior.coords)
|
||||||
|
polygon_coordinates = [(x, y) for x, y in polygon_coords]
|
||||||
|
|
||||||
|
geometries = [
|
||||||
|
{
|
||||||
|
'type': 'Polygon',
|
||||||
|
'coordinates': [polygon_coordinates]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
region_result = data_array.rio.clip(geometries, data_array.rio.crs, drop=False)
|
||||||
|
region_result = region_result.where(region_result >= 0, float('nan'))
|
||||||
|
return region_result
|
||||||
|
|
||||||
|
|
||||||
|
def compare(KD_path, KetQuaPhanLoaiDat, CODE_MAP, HT_MAP):
|
||||||
|
gdf = gpd.read_file(KD_path, crs="EPSG:9209")
|
||||||
|
polygon = gdf.geometry.values
|
||||||
|
label = gdf.tenchu.values
|
||||||
|
ouput_image = rioxarray.open_rasterio(KetQuaPhanLoaiDat)
|
||||||
|
code_tq = HT_MAP["TQ"]["data"][0]
|
||||||
|
code_pnn = HT_MAP["PNN"]["data"][0]
|
||||||
|
result = {}
|
||||||
|
for key, values in HT_MAP.items():
|
||||||
|
print(f"process {key}")
|
||||||
|
array_list = []
|
||||||
|
for i in range(len(polygon)):
|
||||||
|
po = polygon[i]
|
||||||
|
lb = label[i]
|
||||||
|
code_lb = CODE_MAP.get(lb, code_tq)
|
||||||
|
try:
|
||||||
|
qr = ouput_image.rio.clip([po], "EPSG:9209")
|
||||||
|
if code_lb in values["data"]:
|
||||||
|
if code_lb == code_pnn:
|
||||||
|
qr = qr.where((qr != float(code_pnn)), np.nan)
|
||||||
|
# qr = qr.where((qr != 3.0), np.nan)
|
||||||
|
elif code_lb == code_tq:
|
||||||
|
qr = qr.where((qr != float(code_pnn)), np.nan)
|
||||||
|
qr = qr.where((qr != 3.0), np.nan)
|
||||||
|
else:
|
||||||
|
qr = qr.where(qr != float(code_lb), np.nan)
|
||||||
|
else:
|
||||||
|
qr.values[:, :, :] = np.nan
|
||||||
|
array_list.append(qr)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
result.update({key: array_list})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def save_result(result, HT_MAP):
|
||||||
|
# cmap = ListedColormap(colors)
|
||||||
|
save_path = "ThuanHoa/KetQua"
|
||||||
|
if not os.path.exists(save_path):
|
||||||
|
os.mkdir(save_path)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
rs = merge_arrays(v, nodata = np.nan)
|
||||||
|
rs.rio.to_raster(f"{save_path}/{k}.tif")
|
||||||
|
print(f"save {save_path}/{k}.tif")
|
||||||
|
# img = rs.plot(cmap=cmap, add_colorbar=False)
|
||||||
|
# cbar = plt.colorbar(img)
|
||||||
|
# cbar.ax.set_yticklabels(labels)
|
||||||
|
# plt.title(f'{HT_MAP[k]["name"]}')
|
||||||
|
# plt.axis('off')
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
def load_data_sen1(dc, date_range, coordinates):
|
||||||
|
longtitude_range, latitude_range = coordinates
|
||||||
|
data_sen1 = dc.load(
|
||||||
|
product="sentinel1_grd_gamma0_10m",
|
||||||
|
x=longtitude_range,
|
||||||
|
y=latitude_range,
|
||||||
|
time=date_range,
|
||||||
|
measurements=["vv", "vh"],
|
||||||
|
output_crs="EPSG:32648",
|
||||||
|
resolution=(-10,10),
|
||||||
|
dask_chunks={"x":2048, "y":2048},
|
||||||
|
skip_broken_datasets=True,
|
||||||
|
group_by='solar_day'
|
||||||
|
)
|
||||||
|
|
||||||
|
notebook_utils.heading(notebook_utils.xarray_object_size(data_sen1))
|
||||||
|
display(data_sen1)
|
||||||
|
dsvh = data_sen1.vh
|
||||||
|
dsvv = data_sen1.vv
|
||||||
|
|
||||||
|
return dsvh, dsvv
|
||||||
|
|
||||||
|
def calculate_average(data, time_pattern='1M'):
|
||||||
|
return data.resample(time=time_pattern).mean().persist()
|
||||||
|
|
||||||
|
|
||||||
|
def load_data_sen2(dc, date_range, coordinates):
|
||||||
|
longtitude_range, latitude_range = coordinates
|
||||||
|
product = 's2_l2a'
|
||||||
|
query = {
|
||||||
|
'product': product, # Product name
|
||||||
|
'x': longtitude_range, # "x" axis bounds
|
||||||
|
'y': latitude_range, # "y" axis bounds
|
||||||
|
'time': date_range, # Any parsable date strings
|
||||||
|
}
|
||||||
|
native_crs = notebook_utils.mostcommon_crs(dc, query)
|
||||||
|
print(f'Most common native CRS: {native_crs}')
|
||||||
|
|
||||||
|
# measurements = ['red','green', 'blue', 'nir', 'scl']
|
||||||
|
measurements = ['red', 'nir', 'scl']
|
||||||
|
|
||||||
|
load_params = {
|
||||||
|
'measurements': measurements, # Selected measurement or alias names
|
||||||
|
'output_crs': native_crs, # Target EPSG code
|
||||||
|
'resolution': (-10, 10), # Target resolution
|
||||||
|
'group_by': 'solar_day', # Scene grouping
|
||||||
|
'dask_chunks': {'x': 2048, 'y': 2048}, # Dask chunks
|
||||||
|
}
|
||||||
|
data = load_s2l2a_with_offset(
|
||||||
|
dc,
|
||||||
|
query | load_params # Combine the two dicts that contain our search and load parameters
|
||||||
|
)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def mask_cloud(data):
|
||||||
|
flag_name = 'scl'
|
||||||
|
flag_desc = masking.describe_variable_flags(data[flag_name]) # Pandas dataframe
|
||||||
|
display(flag_desc.loc['qa'].values[1])
|
||||||
|
# Create a "data quality" Mask layer
|
||||||
|
flags_def = flag_desc.loc['qa'].values[1]
|
||||||
|
good_pixel_flags = [flags_def[str(i)] for i in [2, 4, 5, 6]] # To pass strings to enum_to_bool()
|
||||||
|
|
||||||
|
# enum_to_bool calculates the pixel-wise "or" of each set of pixels given by good_pixel_flags
|
||||||
|
# 1 = good data
|
||||||
|
# 0 = "bad" data
|
||||||
|
good_pixel_mask = enum_to_bool(data[flag_name], good_pixel_flags)
|
||||||
|
data_layer_names = [x for x in data.data_vars if x != 'scl']
|
||||||
|
# Apply good pixel mask to blue, green, red and nir.
|
||||||
|
result = data[data_layer_names].where(good_pixel_mask).persist()
|
||||||
|
return result
|
||||||
|
|
||||||
|
def find_best_model(dataset):
|
||||||
|
X_train, X_val, y_train, y_val = dataset
|
||||||
|
# Tạo RandomForestClassifier mặc định để sử dụng làm mô hình ban đầu trong pipeline
|
||||||
|
base_model = RandomForestClassifier(random_state=42, n_jobs=-1)
|
||||||
|
|
||||||
|
# Tạo pipeline
|
||||||
|
pipeline = Pipeline([
|
||||||
|
# ('imputer', SimpleImputer(strategy='mean')),
|
||||||
|
('scaler', StandardScaler()),
|
||||||
|
('classifier', base_model),
|
||||||
|
])
|
||||||
|
# Thiết lập các tham số bạn muốn tối ưu hóa
|
||||||
|
param_grid = {
|
||||||
|
'classifier__n_estimators': [100, 300, 500, 700, 1000],
|
||||||
|
'classifier__max_depth': [6, 8, 10, 15, 20],
|
||||||
|
'classifier__criterion': ['gini', 'entropy'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sử dụng GridSearchCV để tìm bộ tham số tốt nhất
|
||||||
|
grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
|
||||||
|
grid_search.fit(X_train, y_train)
|
||||||
|
|
||||||
|
# In ra bộ tham số tốt nhất
|
||||||
|
best_params = grid_search.best_params_
|
||||||
|
print("Best Parameters:", best_params)
|
||||||
|
|
||||||
|
# Dự đoán trên tập kiểm tra
|
||||||
|
y_pred = grid_search.predict(X_val)
|
||||||
|
|
||||||
|
# Đánh giá kết quả
|
||||||
|
accuracy = accuracy_score(y_val, y_pred)
|
||||||
|
print(f"Accuracy: {round(accuracy, 2)*100} %")
|
||||||
|
return grid_search
|
||||||
|
|
||||||
|
def save_result_new(result, save_path, HT_MAP):
|
||||||
|
# cmap = ListedColormap(colors)
|
||||||
|
if not os.path.exists(save_path):
|
||||||
|
os.mkdir(save_path)
|
||||||
|
|
||||||
|
for k, v in result.items():
|
||||||
|
rs = merge_arrays(v, nodata = np.nan)
|
||||||
|
rs.rio.to_raster(f"{save_path}/{k}.tif")
|
||||||
|
print(f"save {save_path}/{k}.tif")
|
||||||
|
# img = rs.plot(cmap=cmap, add_colorbar=False)
|
||||||
|
# cbar = plt.colorbar(img)
|
||||||
|
# cbar.ax.set_yticklabels(labels)
|
||||||
|
# plt.title(f'{HT_MAP[k]["name"]}')
|
||||||
|
# plt.axis('off')
|
||||||
|
# plt.show()
|
||||||
|
def accuracy_test(test, data_array):
|
||||||
|
# cấu hình nhãn dữ liệu
|
||||||
|
label_mapping = {
|
||||||
|
"Lua tom": "0",
|
||||||
|
"Lua": "1",
|
||||||
|
"CHN": "2",
|
||||||
|
"CLN": "3",
|
||||||
|
"TS": "4",
|
||||||
|
"Song": "5",
|
||||||
|
"Dat xay dung": "6",
|
||||||
|
"Rung": "7"
|
||||||
|
}
|
||||||
|
|
||||||
|
chk = []
|
||||||
|
pred = []
|
||||||
|
dd = []
|
||||||
|
for idx, point in test.iterrows():
|
||||||
|
label = point.LULC
|
||||||
|
predict = data_array.sel(x=point.geometry.x, y=point.geometry.y, method='nearest').values
|
||||||
|
pred.append(label_mapping[label])
|
||||||
|
dd.append(str(predict))
|
||||||
|
chk.append(predict == int(label_mapping[label]))
|
||||||
|
test["code"] = pred
|
||||||
|
test["dd"] = dd
|
||||||
|
test["check"] = chk
|
||||||
|
path = "ThuanHoa/TestAccuracy"
|
||||||
|
if not os.path.exists(path):
|
||||||
|
os.mkdir(path)
|
||||||
|
test.to_file(f"{path}/result.shp")
|
||||||
|
|
||||||
|
percentage_true = np.mean(chk) * 100
|
||||||
|
print(f"độ chính xác: {percentage_true:.2f}%")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:eb89e36fa4f4c740d5a079baf53b02bec2ef1120ac770bed6b6be4aa9fc99a1b
|
||||||
|
size 208470
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:179d3a61420c1552e9653de5c7657665c9880ad29d751e56bae646fb3b634687
|
||||||
|
size 73272920
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:179d3a61420c1552e9653de5c7657665c9880ad29d751e56bae646fb3b634687
|
||||||
|
size 73272920
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:179d3a61420c1552e9653de5c7657665c9880ad29d751e56bae646fb3b634687
|
||||||
|
size 73272920
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d8fb13c2e466b9811104cbd7747ea6ca8c14ddb44802d934aadfe52a4b5dd916
|
||||||
|
size 73272920
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a2fe092e1fd96e56da519acffe5ca5c9a8246e796bc5700cffb9694dc99f3aec
|
||||||
|
size 73272920
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:809b41520bb499e1032042e806ffb9f3c798609a88edc771efb75e39dd80f20d
|
||||||
|
size 1335865
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6c282f1a104a47a2837f1882da8011293051f507b0bb1d7e6ab27ba68b24dc19
|
||||||
|
size 787409
|
||||||
+309
@@ -0,0 +1,309 @@
|
|||||||
|
affine @ file:///home/conda/feedstock_root/build_artifacts/affine_1733762038348/work
|
||||||
|
aiobotocore==2.25.0
|
||||||
|
aiohappyeyeballs==2.6.1
|
||||||
|
aiohttp==3.12.15
|
||||||
|
aioitertools==0.12.0
|
||||||
|
aiosignal==1.4.0
|
||||||
|
alembic==1.16.5
|
||||||
|
annotated-doc==0.0.4
|
||||||
|
annotated-types==0.7.0
|
||||||
|
antimeridian @ file:///home/conda/feedstock_root/build_artifacts/antimeridian_1753706324394/work
|
||||||
|
anyio @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_anyio_1758634638/work
|
||||||
|
argon2-cffi @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi_1749017159514/work
|
||||||
|
argon2-cffi-bindings @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi-bindings_1649500328244/work
|
||||||
|
arrow @ file:///home/conda/feedstock_root/build_artifacts/arrow_1733584251875/work
|
||||||
|
asciitree==0.3.3
|
||||||
|
asttokens @ file:///home/conda/feedstock_root/build_artifacts/asttokens_1733250440834/work
|
||||||
|
async-lru @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_async-lru_1742153708/work
|
||||||
|
async-timeout==3.0.1
|
||||||
|
attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1741918516150/work
|
||||||
|
babel @ file:///home/conda/feedstock_root/build_artifacts/babel_1738490167835/work
|
||||||
|
beautifulsoup4 @ file:///home/conda/feedstock_root/build_artifacts/beautifulsoup4_1759146011391/work
|
||||||
|
bleach @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_bleach_1737382993/work
|
||||||
|
blinker==1.9.0
|
||||||
|
bokeh==3.7.3
|
||||||
|
boto3==1.40.18
|
||||||
|
botocore==1.40.49
|
||||||
|
Bottleneck @ file:///croot/bottleneck_1731058641041/work
|
||||||
|
branca @ file:///croot/branca_1675157607453/work
|
||||||
|
Brotli @ file:///croot/brotli-split_1736182456865/work
|
||||||
|
brotlicffi @ file:///croot/brotlicffi_1736182461069/work
|
||||||
|
cached-property @ file:///home/conda/feedstock_root/build_artifacts/cached_property_1615209429212/work
|
||||||
|
cachetools==6.2.0
|
||||||
|
Cartopy==0.25.0
|
||||||
|
certifi @ file:///home/conda/feedstock_root/build_artifacts/certifi_1759648874697/work/certifi
|
||||||
|
cffi @ file:///croot/cffi_1736182485317/work
|
||||||
|
cftime @ file:///home/conda/feedstock_root/build_artifacts/cftime_1649636873066/work
|
||||||
|
chardet @ file:///home/conda/feedstock_root/build_artifacts/chardet_1649184137891/work
|
||||||
|
charset-normalizer @ file:///croot/charset-normalizer_1721748349566/work
|
||||||
|
ciso8601==2.3.3
|
||||||
|
click @ file:///home/conda/feedstock_root/build_artifacts/click_1747811314515/work
|
||||||
|
click-plugins @ file:///home/conda/feedstock_root/build_artifacts/click-plugins_1750848229740/work
|
||||||
|
cligj @ file:///home/conda/feedstock_root/build_artifacts/cligj_1733749956636/work
|
||||||
|
cloudpickle @ file:///home/conda/feedstock_root/build_artifacts/cloudpickle_1736947526808/work
|
||||||
|
colorama==0.4.6
|
||||||
|
colorcet==3.1.0
|
||||||
|
comm @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_comm_1753453984/work
|
||||||
|
contourpy @ file:///croot/contourpy_1732540045555/work
|
||||||
|
cycler @ file:///tmp/build/80754af9/cycler_1637851556182/work
|
||||||
|
cytoolz==0.11.2
|
||||||
|
dask @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_dask-core_1760473436/work
|
||||||
|
dask-gateway @ file:///Users/runner/miniforge3/conda-bld/bld/rattler-build_dask-gateway_1744370153/work/dask-gateway
|
||||||
|
dask-glm @ file:///home/conda/feedstock_root/build_artifacts/dask-glm_1701346265909/work
|
||||||
|
dask-image==2024.5.3
|
||||||
|
dask-ml @ file:///home/conda/feedstock_root/build_artifacts/dask-ml_1679705292494/work
|
||||||
|
datacube==1.8.15
|
||||||
|
datacube_ows==1.9.4
|
||||||
|
datashader==0.18.2
|
||||||
|
dea-tools==0.3.0
|
||||||
|
debugpy @ file:///home/task_175706711740264/conda-bld/debugpy_1757067131873/work
|
||||||
|
decorator @ file:///home/conda/feedstock_root/build_artifacts/decorator_1740384970518/work
|
||||||
|
deepdiff==8.6.1
|
||||||
|
defusedxml @ file:///home/conda/feedstock_root/build_artifacts/defusedxml_1615232257335/work
|
||||||
|
deprecat @ file:///home/conda/feedstock_root/build_artifacts/deprecat_1734684036993/work
|
||||||
|
distributed @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_distributed_1760476147/work
|
||||||
|
eo-tides==0.8.2
|
||||||
|
exceptiongroup @ file:///home/conda/feedstock_root/build_artifacts/exceptiongroup_1746947292760/work
|
||||||
|
executing @ file:///home/conda/feedstock_root/build_artifacts/executing_1756729339227/work
|
||||||
|
fastapi==0.124.3
|
||||||
|
fasteners @ file:///home/conda/feedstock_root/build_artifacts/fasteners_1734943108928/work
|
||||||
|
fastjsonschema @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_python-fastjsonschema_1755304154/work/dist
|
||||||
|
filelock==3.19.1
|
||||||
|
fiona==1.10.1
|
||||||
|
Flask==3.1.2
|
||||||
|
flask-babel==4.0.0
|
||||||
|
flatbuffers==25.2.10
|
||||||
|
folium==0.20.0
|
||||||
|
fonttools @ file:///croot/fonttools_1737039080035/work
|
||||||
|
fqdn @ file:///home/conda/feedstock_root/build_artifacts/fqdn_1733327382592/work/dist
|
||||||
|
frozenlist==1.7.0
|
||||||
|
fsspec @ file:///home/conda/feedstock_root/build_artifacts/fsspec_1756908513222/work
|
||||||
|
GDAL @ file:///croot/gdal-split_1734448174900/work/build/swig/python
|
||||||
|
GeoAlchemy2 @ file:///home/conda/feedstock_root/build_artifacts/geoalchemy2_1753372953474/work
|
||||||
|
geographiclib==2.1
|
||||||
|
geojson==3.2.0
|
||||||
|
geomad==1.0.0
|
||||||
|
geopandas @ file:///croot/geopandas-split_1755761494241/work
|
||||||
|
geopy==2.4.1
|
||||||
|
greenlet @ file:///home/conda/feedstock_root/build_artifacts/greenlet_1648882383677/work
|
||||||
|
h11 @ file:///home/conda/feedstock_root/build_artifacts/h11_1745526374115/work
|
||||||
|
h2 @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_h2_1756364871/work
|
||||||
|
h3==4.3.1
|
||||||
|
hdstats==0.2.1
|
||||||
|
holoviews==1.21.0
|
||||||
|
hpack @ file:///home/conda/feedstock_root/build_artifacts/hpack_1737618293087/work
|
||||||
|
httpcore @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_httpcore_1745602916/work
|
||||||
|
httpx @ file:///home/conda/feedstock_root/build_artifacts/httpx_1733663348460/work
|
||||||
|
hvplot==0.12.1
|
||||||
|
hyperframe @ file:///home/conda/feedstock_root/build_artifacts/hyperframe_1737618333194/work
|
||||||
|
idna==3.10
|
||||||
|
imagecodecs==2025.3.30
|
||||||
|
imageio==2.37.0
|
||||||
|
importlib_metadata @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_importlib-metadata_1747934053/work
|
||||||
|
ipykernel @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_ipykernel_1760459840/work
|
||||||
|
ipyleaflet==0.20.0
|
||||||
|
ipython @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_ipython_1748711175/work
|
||||||
|
ipywidgets==8.1.7
|
||||||
|
iso8601==2.1.0
|
||||||
|
isoduration @ file:///home/conda/feedstock_root/build_artifacts/isoduration_1733493628631/work/dist
|
||||||
|
itsdangerous==2.2.0
|
||||||
|
jedi @ file:///home/conda/feedstock_root/build_artifacts/jedi_1733300866624/work
|
||||||
|
Jinja2 @ file:///croot/jinja2_1741710844255/work
|
||||||
|
jmespath @ file:///home/conda/feedstock_root/build_artifacts/jmespath_1733229141657/work
|
||||||
|
joblib @ file:///home/conda/feedstock_root/build_artifacts/joblib_1756321760188/work
|
||||||
|
json5 @ file:///home/conda/feedstock_root/build_artifacts/json5_1755034879854/work
|
||||||
|
jsonpointer @ file:///home/conda/feedstock_root/build_artifacts/jsonpointer_1756754132747/work
|
||||||
|
jsonschema @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jsonschema_1755595646/work
|
||||||
|
jsonschema-specifications==2025.4.1
|
||||||
|
jupyter-events @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_events_1738765986/work
|
||||||
|
jupyter-leaflet==0.20.0
|
||||||
|
jupyter-lsp @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter-lsp_1756388269/work/jupyter-lsp
|
||||||
|
jupyter-ui-poll==1.0.0
|
||||||
|
jupyter_client @ file:///home/conda/feedstock_root/build_artifacts/jupyter_client_1733440914442/work
|
||||||
|
jupyter_core @ file:///home/conda/feedstock_root/build_artifacts/jupyter_core_1748333051527/work
|
||||||
|
jupyter_server @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_jupyter_server_1755870522/work
|
||||||
|
jupyter_server_terminals @ file:///home/conda/feedstock_root/build_artifacts/jupyter_server_terminals_1733427956852/work
|
||||||
|
jupyterlab @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_1758913905644/work
|
||||||
|
jupyterlab_pygments @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_pygments_1733328101776/work
|
||||||
|
jupyterlab_server @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_server_1733599573484/work
|
||||||
|
jupyterlab_widgets==3.0.15
|
||||||
|
kiwisolver @ file:///croot/kiwisolver_1737039087198/work
|
||||||
|
lark==1.2.2
|
||||||
|
lark-parser==0.12.0
|
||||||
|
lazy_loader==0.4
|
||||||
|
linkify-it-py==2.0.3
|
||||||
|
llvmlite @ file:///croot/llvmlite_1741209858218/work
|
||||||
|
locket @ file:///home/conda/feedstock_root/build_artifacts/locket_1650660393415/work
|
||||||
|
lxml==5.4.0
|
||||||
|
lz4 @ file:///croot/lz4_1736366683208/work
|
||||||
|
Mako @ file:///home/conda/feedstock_root/build_artifacts/mako_1744317760971/work
|
||||||
|
mapclassify @ file:///croot/mapclassify_1675157730177/work
|
||||||
|
Markdown==3.9
|
||||||
|
markdown-it-py==4.0.0
|
||||||
|
MarkupSafe @ file:///croot/markupsafe_1738584038848/work
|
||||||
|
matplotlib==3.10.5
|
||||||
|
matplotlib-inline @ file:///home/conda/feedstock_root/build_artifacts/matplotlib-inline_1733416936468/work
|
||||||
|
mdit-py-plugins==0.5.0
|
||||||
|
mdurl==0.1.2
|
||||||
|
mistune @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_mistune_1756495311/work
|
||||||
|
mpmath==1.3.0
|
||||||
|
msgpack @ file:///home/conda/feedstock_root/build_artifacts/msgpack-python_1648745999384/work
|
||||||
|
multidict @ file:///home/conda/feedstock_root/build_artifacts/multidict_1648882415384/work
|
||||||
|
multipledispatch @ file:///home/conda/feedstock_root/build_artifacts/multipledispatch_1721907546485/work
|
||||||
|
narwhals==2.3.0
|
||||||
|
nbclient @ file:///home/conda/feedstock_root/build_artifacts/nbclient_1734628800805/work
|
||||||
|
nbconvert @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_nbconvert-core_1738067871/work
|
||||||
|
nbformat @ file:///home/conda/feedstock_root/build_artifacts/nbformat_1733402752141/work
|
||||||
|
nest_asyncio @ file:///home/conda/feedstock_root/build_artifacts/nest-asyncio_1733325553580/work
|
||||||
|
netCDF4 @ file:///croot/netcdf4_1743512888672/work
|
||||||
|
networkx @ file:///croot/networkx_1737039604450/work
|
||||||
|
notebook @ file:///home/conda/feedstock_root/build_artifacts/notebook_1759152069573/work
|
||||||
|
notebook_shim @ file:///home/conda/feedstock_root/build_artifacts/notebook-shim_1733408315203/work
|
||||||
|
numba @ file:///croot/numba_1750798165355/work
|
||||||
|
numcodecs @ file:///croot/numcodecs_1707513121886/work
|
||||||
|
numexpr @ file:///croot/numexpr_1755766469354/work
|
||||||
|
numpy @ file:///croot/numpy_and_numpy_base_1755590845055/work/dist/numpy-1.26.4-cp310-cp310-linux_x86_64.whl#sha256=1096d33ad9a9757a1b4b46634d809e894263fc8b78780bff36801684b6e8cc88
|
||||||
|
nvidia-cublas-cu12==12.8.4.1
|
||||||
|
nvidia-cuda-cupti-cu12==12.8.90
|
||||||
|
nvidia-cuda-nvrtc-cu12==12.8.93
|
||||||
|
nvidia-cuda-runtime-cu12==12.8.90
|
||||||
|
nvidia-cudnn-cu12==9.10.2.21
|
||||||
|
nvidia-cufft-cu12==11.3.3.83
|
||||||
|
nvidia-cufile-cu12==1.13.1.3
|
||||||
|
nvidia-curand-cu12==10.3.9.90
|
||||||
|
nvidia-cusolver-cu12==11.7.3.90
|
||||||
|
nvidia-cusparse-cu12==12.5.8.93
|
||||||
|
nvidia-cusparselt-cu12==0.7.1
|
||||||
|
nvidia-nccl-cu12==2.27.3
|
||||||
|
nvidia-nvjitlink-cu12==12.8.93
|
||||||
|
nvidia-nvtx-cu12==12.8.90
|
||||||
|
odc-algo==0.2.3
|
||||||
|
odc-geo==0.4.10
|
||||||
|
odc-io==0.2.2
|
||||||
|
odc-loader @ file:///home/conda/feedstock_root/build_artifacts/odc-loader_1743656085024/work
|
||||||
|
odc-stac @ file:///home/conda/feedstock_root/build_artifacts/odc-stac_1746136311934/work
|
||||||
|
odc-ui==0.2.1
|
||||||
|
orderly-set==5.5.0
|
||||||
|
overrides @ file:///home/conda/feedstock_root/build_artifacts/overrides_1734587627321/work
|
||||||
|
OWSLib==0.34.1
|
||||||
|
packaging @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_packaging_1745345660/work
|
||||||
|
pandas @ file:///home/task_175982153789305/conda-bld/pandas_1759822248912/work/dist/pandas-2.3.3-cp310-cp310-linux_x86_64.whl#sha256=0de7c83109c411cc2a74419a396c92f65e3d1e457fb4d835e5f100cfb04393a7
|
||||||
|
pandocfilters @ file:///home/conda/feedstock_root/build_artifacts/pandocfilters_1631603243851/work
|
||||||
|
panel==1.7.5
|
||||||
|
param==2.2.1
|
||||||
|
parso @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_parso_1755974222/work
|
||||||
|
partd @ file:///home/conda/feedstock_root/build_artifacts/partd_1715026491486/work
|
||||||
|
pexpect @ file:///home/conda/feedstock_root/build_artifacts/pexpect_1733301927746/work
|
||||||
|
pickleshare @ file:///home/conda/feedstock_root/build_artifacts/pickleshare_1733327343728/work
|
||||||
|
pillow @ file:///croot/pillow_1738010226202/work
|
||||||
|
PIMS==0.7
|
||||||
|
planetary-computer==1.0.0
|
||||||
|
platformdirs @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_platformdirs_1756227402/work
|
||||||
|
prometheus_client==0.22.1
|
||||||
|
prometheus_flask_exporter==0.23.2
|
||||||
|
prompt_toolkit @ file:///home/conda/feedstock_root/build_artifacts/prompt-toolkit_1756321756983/work
|
||||||
|
propcache==0.3.2
|
||||||
|
psutil @ file:///home/conda/feedstock_root/build_artifacts/psutil_1653089181607/work
|
||||||
|
psycopg2 @ file:///croot/psycopg2_1744919787325/work
|
||||||
|
ptyprocess @ file:///home/conda/feedstock_root/build_artifacts/ptyprocess_1733302279685/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl#sha256=92c32ff62b5fd8cf325bec5ab90d7be3d2a8ca8c8a3813ff487a8d2002630d1f
|
||||||
|
pure_eval @ file:///home/conda/feedstock_root/build_artifacts/pure_eval_1733569405015/work
|
||||||
|
pyarrow @ file:///home/task_175983338836370/conda-bld/pyarrow_1759833584228/work/python
|
||||||
|
pycparser @ file:///tmp/build/80754af9/pycparser_1636541352034/work
|
||||||
|
pyct==0.5.0
|
||||||
|
pydantic==2.11.7
|
||||||
|
pydantic_core==2.33.2
|
||||||
|
Pygments @ file:///home/conda/feedstock_root/build_artifacts/pygments_1750615794071/work
|
||||||
|
pyogrio @ file:///croot/pyogrio_1741107161422/work
|
||||||
|
pyows==0.3.1
|
||||||
|
pyparsing @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_pyparsing_1753873557/work
|
||||||
|
pyproj @ file:///croot/pyproj_1739284761968/work
|
||||||
|
PyQt6==6.7.1
|
||||||
|
PyQt6_sip @ file:///croot/pyqt-split_1753427276959/work/pyqt_sip
|
||||||
|
pyshp==2.3.1
|
||||||
|
PySocks @ file:///home/builder/ci_310/pysocks_1640793678128/work
|
||||||
|
pystac @ file:///home/conda/feedstock_root/build_artifacts/pystac_1758218055393/work
|
||||||
|
pystac-client==0.9.0
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-dotenv==1.1.1
|
||||||
|
python-json-logger @ file:///home/conda/feedstock_root/build_artifacts/python-json-logger_1677079630776/work
|
||||||
|
python-slugify==8.0.4
|
||||||
|
pyTMD==2.2.8
|
||||||
|
pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1742920838005/work
|
||||||
|
pyviz_comms==3.0.6
|
||||||
|
PyYAML==6.0.2
|
||||||
|
pyzmq @ file:///croot/pyzmq_1734687138743/work
|
||||||
|
rasterio @ file:///croot/rasterio_1740069178893/work
|
||||||
|
rasterstats==0.20.0
|
||||||
|
referencing==0.36.2
|
||||||
|
regex==2025.9.1
|
||||||
|
requests @ file:///croot/requests_1756709366904/work
|
||||||
|
rfc3339_validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3339-validator_1733599910982/work
|
||||||
|
rfc3986-validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3986-validator_1598024191506/work
|
||||||
|
rfc3987==1.3.8
|
||||||
|
rfc3987-syntax @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_rfc3987-syntax_1752876729/work
|
||||||
|
rioxarray @ file:///home/conda/feedstock_root/build_artifacts/rioxarray_1737140588464/work
|
||||||
|
rpds-py @ file:///croot/rpds-py_1736541261634/work
|
||||||
|
ruamel.yaml @ file:///home/conda/feedstock_root/build_artifacts/ruamel.yaml_1649033201098/work
|
||||||
|
ruamel.yaml.clib==0.2.12
|
||||||
|
s3fs==2025.9.0
|
||||||
|
s3transfer==0.13.1
|
||||||
|
scikit-image==0.25.2
|
||||||
|
scikit-learn==1.7.1
|
||||||
|
scipy @ file:///croot/scipy_1747238027288/work/dist/scipy-1.15.3-cp310-cp310-linux_x86_64.whl#sha256=2a791554880ad4f358fcc4cd2a982ffe1e9d472e9241011216b2be797457f1f9
|
||||||
|
seaborn==0.13.2
|
||||||
|
Send2Trash @ file:///home/conda/feedstock_root/build_artifacts/send2trash_1733322040660/work
|
||||||
|
setuptools-scm==9.2.0
|
||||||
|
shapely @ file:///croot/shapely_1754380812723/work
|
||||||
|
simplejson==3.20.1
|
||||||
|
sip @ file:///croot/sip_1738856193618/work
|
||||||
|
six==1.17.0
|
||||||
|
slicerator==1.1.0
|
||||||
|
sniffio @ file:///home/conda/feedstock_root/build_artifacts/sniffio_1733244044561/work
|
||||||
|
snuggs @ file:///home/conda/feedstock_root/build_artifacts/snuggs_1733818638588/work
|
||||||
|
sortedcontainers @ file:///home/conda/feedstock_root/build_artifacts/sortedcontainers_1738440353519/work
|
||||||
|
soupsieve @ file:///home/conda/feedstock_root/build_artifacts/soupsieve_1756330469801/work
|
||||||
|
sparse @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_sparse_1747799051/work
|
||||||
|
SQLAlchemy==1.4.54
|
||||||
|
stack_data @ file:///home/conda/feedstock_root/build_artifacts/stack_data_1733569443808/work
|
||||||
|
starlette==0.50.0
|
||||||
|
sympy==1.14.0
|
||||||
|
tblib @ file:///home/conda/feedstock_root/build_artifacts/tblib_1743515515538/work
|
||||||
|
terminado @ file:///home/conda/feedstock_root/build_artifacts/terminado_1710262609923/work
|
||||||
|
text-unidecode==1.3
|
||||||
|
threadpoolctl @ file:///home/conda/feedstock_root/build_artifacts/threadpoolctl_1741878222898/work
|
||||||
|
tifffile==2025.5.10
|
||||||
|
timescale==0.0.9
|
||||||
|
timezonefinder==8.0.0
|
||||||
|
tinycss2 @ file:///home/conda/feedstock_root/build_artifacts/tinycss2_1729802851396/work
|
||||||
|
tomli @ file:///croot/tomli_1753774587605/work
|
||||||
|
toolz @ file:///home/conda/feedstock_root/build_artifacts/toolz_1733736030883/work
|
||||||
|
torch==2.8.0
|
||||||
|
tornado @ file:///croot/tornado_1748956929273/work
|
||||||
|
tqdm==4.67.1
|
||||||
|
traitlets @ file:///home/conda/feedstock_root/build_artifacts/traitlets_1733367359838/work
|
||||||
|
traittypes==0.2.1
|
||||||
|
triton==3.4.0
|
||||||
|
types-python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/types-python-dateutil_1759899809376/work
|
||||||
|
typing-inspection==0.4.1
|
||||||
|
typing_extensions @ file:///home/conda/feedstock_root/build_artifacts/bld/rattler-build_typing_extensions_1756220668/work
|
||||||
|
typing_utils @ file:///home/conda/feedstock_root/build_artifacts/typing_utils_1733331286120/work
|
||||||
|
tzdata @ file:///croot/python-tzdata_1746123641790/work
|
||||||
|
uc-micro-py==1.0.3
|
||||||
|
unicodedata2 @ file:///croot/unicodedata2_1736541023050/work
|
||||||
|
uri-template @ file:///home/conda/feedstock_root/build_artifacts/uri-template_1733323593477/work/dist
|
||||||
|
urllib3 @ file:///croot/urllib3_1750775463400/work
|
||||||
|
uvicorn==0.38.0
|
||||||
|
wcwidth @ file:///home/conda/feedstock_root/build_artifacts/wcwidth_1733231326287/work
|
||||||
|
webcolors @ file:///home/conda/feedstock_root/build_artifacts/webcolors_1733359735138/work
|
||||||
|
webencodings @ file:///home/conda/feedstock_root/build_artifacts/webencodings_1733236011802/work
|
||||||
|
websocket-client @ file:///home/conda/feedstock_root/build_artifacts/websocket-client_1759928050786/work
|
||||||
|
Werkzeug==3.1.3
|
||||||
|
widgetsnbextension==4.0.14
|
||||||
|
wrapt @ file:///home/conda/feedstock_root/build_artifacts/wrapt_1651495243689/work
|
||||||
|
xarray @ file:///home/conda/feedstock_root/build_artifacts/xarray_1749743207754/work
|
||||||
|
xgboost==3.1.2
|
||||||
|
xyzservices @ file:///croot/xyzservices_1675159059961/work
|
||||||
|
yarl==1.20.1
|
||||||
|
zarr @ file:///home/conda/feedstock_root/build_artifacts/zarr_1733237197728/work
|
||||||
|
zict @ file:///home/conda/feedstock_root/build_artifacts/zict_1733261551178/work
|
||||||
|
zipp @ file:///home/conda/feedstock_root/build_artifacts/zipp_1749421620841/work
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
pydantic
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uvicorn api_server:app --reload --host 0.0.0.0 --port 8000
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:c8fa50e2debed3c65b599f956095550a72844082245ae2500d1ab196ae23641e
|
||||||
|
size 393276
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
PROJCS["WGS_1984_UTM_Zone_48N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",105],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
|
||||||
@@ -0,0 +1,835 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis simplifyLocal="1" labelsEnabled="0" simplifyMaxScale="1" symbologyReferenceScale="-1" simplifyDrawingHints="0" readOnly="0" version="3.30.0-'s-Hertogenbosch" styleCategories="AllStyleCategories" minScale="100000000" hasScaleBasedVisibilityFlag="0" simplifyAlgorithm="0" simplifyDrawingTol="1" maxScale="0">
|
||||||
|
<flags>
|
||||||
|
<Identifiable>1</Identifiable>
|
||||||
|
<Removable>1</Removable>
|
||||||
|
<Searchable>1</Searchable>
|
||||||
|
<Private>0</Private>
|
||||||
|
</flags>
|
||||||
|
<temporal durationUnit="min" startField="" startExpression="" enabled="0" mode="0" endField="" limitMode="0" endExpression="" durationField="" fixedDuration="0" accumulate="0">
|
||||||
|
<fixedRange>
|
||||||
|
<start></start>
|
||||||
|
<end></end>
|
||||||
|
</fixedRange>
|
||||||
|
</temporal>
|
||||||
|
<elevation zoffset="0" clamping="Terrain" zscale="1" type="IndividualFeatures" extrusionEnabled="0" showMarkerSymbolInSurfacePlots="0" respectLayerSymbol="1" extrusion="0" symbology="Line" binding="Centroid">
|
||||||
|
<data-defined-properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data-defined-properties>
|
||||||
|
<profileLineSymbol>
|
||||||
|
<symbol alpha="1" name="" type="line" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleLine" locked="0" pass="0" enabled="1" id="{4823d26e-1862-4571-b95a-700950c67ef2}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||||
|
<Option name="capstyle" type="QString" value="square"/>
|
||||||
|
<Option name="customdash" type="QString" value="5;2"/>
|
||||||
|
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||||
|
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="line_color" type="QString" value="213,180,60,255"/>
|
||||||
|
<Option name="line_style" type="QString" value="solid"/>
|
||||||
|
<Option name="line_width" type="QString" value="0.6"/>
|
||||||
|
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="offset" type="QString" value="0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="ring_filter" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||||
|
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||||
|
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileLineSymbol>
|
||||||
|
<profileFillSymbol>
|
||||||
|
<symbol alpha="1" name="" type="fill" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleFill" locked="0" pass="0" enabled="1" id="{e14e2a41-3f73-4ada-ae93-be42049e0fc8}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="color" type="QString" value="213,180,60,255"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="152,129,43,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0.2"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="style" type="QString" value="solid"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileFillSymbol>
|
||||||
|
<profileMarkerSymbol>
|
||||||
|
<symbol alpha="1" name="" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{dac44936-adba-4f10-96ad-7fd6e313a662}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="213,180,60,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="diamond"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="152,129,43,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0.2"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="3"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileMarkerSymbol>
|
||||||
|
</elevation>
|
||||||
|
<renderer-v2 symbollevels="0" type="categorizedSymbol" referencescale="-1" forceraster="0" attr="HT_code" enableorderby="0">
|
||||||
|
<categories>
|
||||||
|
<category type="long" label="1 - Lua tom" symbol="0" render="true" value="1"/>
|
||||||
|
<category type="long" label="2 - Lua 2 vu" symbol="1" render="true" value="2"/>
|
||||||
|
<category type="long" label="3 - Lua 3 vu" symbol="2" render="true" value="3"/>
|
||||||
|
<category type="long" label="4 - Cay hang nam" symbol="3" render="true" value="4"/>
|
||||||
|
<category type="long" label="5 - Cay lau nam" symbol="4" render="true" value="5"/>
|
||||||
|
<category type="long" label="6 - TS" symbol="5" render="true" value="6"/>
|
||||||
|
<category type="long" label="7 - Song rach" symbol="6" render="true" value="7"/>
|
||||||
|
<category type="long" label="8 - Dat xay dung" symbol="7" render="true" value="8"/>
|
||||||
|
<category type="long" label="9 - Rung" symbol="8" render="true" value="9"/>
|
||||||
|
<category type="string" label="" symbol="9" render="true" value=""/>
|
||||||
|
</categories>
|
||||||
|
<symbols>
|
||||||
|
<symbol alpha="1" name="0" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="108,101,225,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="1" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="100,233,133,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="2" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="214,61,87,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="3" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="18,125,213,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="4" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="199,140,233,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="5" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="237,104,206,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="6" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="225,231,108,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="7" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="84,213,14,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="8" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="50,208,184,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" name="9" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="213,44,75,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</symbols>
|
||||||
|
<source-symbol>
|
||||||
|
<symbol alpha="1" name="0" type="marker" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" locked="0" pass="0" enabled="1" id="{0eba47fb-4130-4afe-b08f-be065656540b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="69,237,206,255"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</source-symbol>
|
||||||
|
<rotation/>
|
||||||
|
<sizescale/>
|
||||||
|
</renderer-v2>
|
||||||
|
<customproperties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="dualview/previewExpressions" type="List">
|
||||||
|
<Option type="QString" value=""No""/>
|
||||||
|
</Option>
|
||||||
|
<Option name="embeddedWidgets/count" type="int" value="0"/>
|
||||||
|
<Option name="variableNames"/>
|
||||||
|
<Option name="variableValues"/>
|
||||||
|
</Option>
|
||||||
|
</customproperties>
|
||||||
|
<blendMode>0</blendMode>
|
||||||
|
<featureBlendMode>0</featureBlendMode>
|
||||||
|
<layerOpacity>1</layerOpacity>
|
||||||
|
<SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram">
|
||||||
|
<DiagramCategory lineSizeScale="3x:0,0,0,0,0,0" penAlpha="255" minScaleDenominator="0" scaleBasedVisibility="0" spacing="5" lineSizeType="MM" scaleDependency="Area" opacity="1" backgroundColor="#ffffff" height="15" diagramOrientation="Up" barWidth="5" width="15" maxScaleDenominator="1e+08" sizeScale="3x:0,0,0,0,0,0" labelPlacementMethod="XHeight" backgroundAlpha="255" rotationOffset="270" enabled="0" penColor="#000000" minimumSize="0" sizeType="MM" direction="0" spacingUnitScale="3x:0,0,0,0,0,0" spacingUnit="MM" showAxis="1" penWidth="0">
|
||||||
|
<fontProperties description="MS Shell Dlg 2,8.25,-1,5,50,0,0,0,0,0" strikethrough="0" italic="0" underline="0" style="" bold="0"/>
|
||||||
|
<attribute color="#000000" label="" colorOpacity="1" field=""/>
|
||||||
|
<axisSymbol>
|
||||||
|
<symbol alpha="1" name="" type="line" is_animated="0" force_rhr="0" frame_rate="10" clip_to_extent="1">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleLine" locked="0" pass="0" enabled="1" id="{2b5bc07c-e6a7-41b4-bf16-35cf42f3de0b}">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||||
|
<Option name="capstyle" type="QString" value="square"/>
|
||||||
|
<Option name="customdash" type="QString" value="5;2"/>
|
||||||
|
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||||
|
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="line_color" type="QString" value="35,35,35,255"/>
|
||||||
|
<Option name="line_style" type="QString" value="solid"/>
|
||||||
|
<Option name="line_width" type="QString" value="0.26"/>
|
||||||
|
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="offset" type="QString" value="0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="ring_filter" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||||
|
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||||
|
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</axisSymbol>
|
||||||
|
</DiagramCategory>
|
||||||
|
</SingleCategoryDiagramRenderer>
|
||||||
|
<DiagramLayerSettings priority="0" placement="0" linePlacementFlags="18" showAll="1" zIndex="0" obstacle="0" dist="0">
|
||||||
|
<properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</properties>
|
||||||
|
</DiagramLayerSettings>
|
||||||
|
<geometryOptions removeDuplicateNodes="0" geometryPrecision="0">
|
||||||
|
<activeChecks/>
|
||||||
|
<checkConfiguration/>
|
||||||
|
</geometryOptions>
|
||||||
|
<legend type="default-vector" showLabelLegend="0"/>
|
||||||
|
<referencedLayers/>
|
||||||
|
<fieldConfiguration>
|
||||||
|
<field name="No" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field name="X" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field name="Y" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field name="LU2022" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field name="Hientrang" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field name="HT_code" configurationFlags="None">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
</fieldConfiguration>
|
||||||
|
<aliases>
|
||||||
|
<alias index="0" name="" field="No"/>
|
||||||
|
<alias index="1" name="" field="X"/>
|
||||||
|
<alias index="2" name="" field="Y"/>
|
||||||
|
<alias index="3" name="" field="LU2022"/>
|
||||||
|
<alias index="4" name="" field="Hientrang"/>
|
||||||
|
<alias index="5" name="" field="HT_code"/>
|
||||||
|
</aliases>
|
||||||
|
<splitPolicies>
|
||||||
|
<policy field="No" policy="Duplicate"/>
|
||||||
|
<policy field="X" policy="Duplicate"/>
|
||||||
|
<policy field="Y" policy="Duplicate"/>
|
||||||
|
<policy field="LU2022" policy="Duplicate"/>
|
||||||
|
<policy field="Hientrang" policy="Duplicate"/>
|
||||||
|
<policy field="HT_code" policy="Duplicate"/>
|
||||||
|
</splitPolicies>
|
||||||
|
<defaults>
|
||||||
|
<default applyOnUpdate="0" expression="" field="No"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="X"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="Y"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="LU2022"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="Hientrang"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="HT_code"/>
|
||||||
|
</defaults>
|
||||||
|
<constraints>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="No" unique_strength="0" notnull_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="X" unique_strength="0" notnull_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="Y" unique_strength="0" notnull_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="LU2022" unique_strength="0" notnull_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="Hientrang" unique_strength="0" notnull_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="HT_code" unique_strength="0" notnull_strength="0"/>
|
||||||
|
</constraints>
|
||||||
|
<constraintExpressions>
|
||||||
|
<constraint exp="" desc="" field="No"/>
|
||||||
|
<constraint exp="" desc="" field="X"/>
|
||||||
|
<constraint exp="" desc="" field="Y"/>
|
||||||
|
<constraint exp="" desc="" field="LU2022"/>
|
||||||
|
<constraint exp="" desc="" field="Hientrang"/>
|
||||||
|
<constraint exp="" desc="" field="HT_code"/>
|
||||||
|
</constraintExpressions>
|
||||||
|
<expressionfields/>
|
||||||
|
<attributeactions>
|
||||||
|
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
|
||||||
|
</attributeactions>
|
||||||
|
<attributetableconfig sortOrder="0" actionWidgetStyle="dropDown" sortExpression=""HT_code"">
|
||||||
|
<columns>
|
||||||
|
<column width="-1" name="No" type="field" hidden="0"/>
|
||||||
|
<column width="-1" name="X" type="field" hidden="0"/>
|
||||||
|
<column width="-1" name="Y" type="field" hidden="0"/>
|
||||||
|
<column width="138" name="LU2022" type="field" hidden="0"/>
|
||||||
|
<column width="-1" name="Hientrang" type="field" hidden="0"/>
|
||||||
|
<column width="-1" name="HT_code" type="field" hidden="0"/>
|
||||||
|
<column width="-1" type="actions" hidden="1"/>
|
||||||
|
</columns>
|
||||||
|
</attributetableconfig>
|
||||||
|
<conditionalstyles>
|
||||||
|
<rowstyles/>
|
||||||
|
<fieldstyles/>
|
||||||
|
</conditionalstyles>
|
||||||
|
<storedexpressions/>
|
||||||
|
<editform tolerant="1"></editform>
|
||||||
|
<editforminit/>
|
||||||
|
<editforminitcodesource>0</editforminitcodesource>
|
||||||
|
<editforminitfilepath></editforminitfilepath>
|
||||||
|
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
QGIS forms can have a Python function that is called when the form is
|
||||||
|
opened.
|
||||||
|
|
||||||
|
Use this function to add extra logic to your forms.
|
||||||
|
|
||||||
|
Enter the name of the function in the "Python Init function"
|
||||||
|
field.
|
||||||
|
An example follows:
|
||||||
|
"""
|
||||||
|
from qgis.PyQt.QtWidgets import QWidget
|
||||||
|
|
||||||
|
def my_form_open(dialog, layer, feature):
|
||||||
|
geom = feature.geometry()
|
||||||
|
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||||
|
]]></editforminitcode>
|
||||||
|
<featformsuppress>0</featformsuppress>
|
||||||
|
<editorlayout>generatedlayout</editorlayout>
|
||||||
|
<editable>
|
||||||
|
<field name="HT_code" editable="1"/>
|
||||||
|
<field name="Hientrang" editable="1"/>
|
||||||
|
<field name="LU2022" editable="1"/>
|
||||||
|
<field name="No" editable="1"/>
|
||||||
|
<field name="X" editable="1"/>
|
||||||
|
<field name="Y" editable="1"/>
|
||||||
|
</editable>
|
||||||
|
<labelOnTop>
|
||||||
|
<field name="HT_code" labelOnTop="0"/>
|
||||||
|
<field name="Hientrang" labelOnTop="0"/>
|
||||||
|
<field name="LU2022" labelOnTop="0"/>
|
||||||
|
<field name="No" labelOnTop="0"/>
|
||||||
|
<field name="X" labelOnTop="0"/>
|
||||||
|
<field name="Y" labelOnTop="0"/>
|
||||||
|
</labelOnTop>
|
||||||
|
<reuseLastValue>
|
||||||
|
<field reuseLastValue="0" name="HT_code"/>
|
||||||
|
<field reuseLastValue="0" name="Hientrang"/>
|
||||||
|
<field reuseLastValue="0" name="LU2022"/>
|
||||||
|
<field reuseLastValue="0" name="No"/>
|
||||||
|
<field reuseLastValue="0" name="X"/>
|
||||||
|
<field reuseLastValue="0" name="Y"/>
|
||||||
|
</reuseLastValue>
|
||||||
|
<dataDefinedFieldProperties/>
|
||||||
|
<widgets/>
|
||||||
|
<previewExpression>"No"</previewExpression>
|
||||||
|
<mapTip></mapTip>
|
||||||
|
<layerGeometryType>0</layerGeometryType>
|
||||||
|
</qgis>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user