I have the following code:
#%% Generate geoTiffs with index values based on one large geotiff with all individual bands
import rasterio
import os
from rasterio.plot import show
import geopandas as gpd
import numpy as np
from scipy.ndimage import gaussian\_filter
import folium
from folium import raster\_layers
from matplotlib.pyplot import imread
from satellite\_data\_helperfunctions import \*
from cloud\_handeling import \*
import scipy

from index\_calculation import \*
import shapely
### Testing ###
satelliteData = "sentinel2\_L2A" #"sentinel2\_L2A" "planetScope"
dir\_path = r'G:\\My Drive\\Bestanden\\SatelliteData\\testingData\\sentinel2\_L2A\_allRawBands\\'
tiff\_files = []
for dirpath, subdirs, files in os.walk(dir\_path):
 tiff\_files.extend(os.path.join(dirpath, x) for x in files if x.endswith("responses\_20220326\_sowingSugarbeet\_summerwhea\_clipped.tiff"))

geotiff = tiff\_files[0]

geotiff\_OutputLocation =dir\_path
png\_OutputLocation = dir\_path

fieldBoundary\_path = "testingData\\Sentinel2\_L2A\_allRawBands\\TestDataGeoJson\_winterSummerWheat.geojson"
fieldBoundary = 'testBoundary.geojson'
jsonGDF = gpd.read\_file(fieldBoundary)
datafile = rasterio.open(geotiff)
band\_dataMask = datafile.read(19) # Datamask
band\_dataMask[band\_dataMask== 0] = np.nan
outputFileName = 'test\_strange\_trueColoring\_5'
# check number of bands (planet == 17, sentinel == 19)
print(f"name: {datafile.name.split('/')[-4]}, bands: {datafile.count}")
print(f"crs = {datafile.crs}")
## CloudFiltering
cloud\_statistics\_scl, cloud\_mask\_scl = cloudProbability\_scl\_sentinel2\_L2A(datafile)
cloud\_statistics\_bratio, cloud\_mask\_bratio = cloudProbability\_bRatio(datafile, satelliteData)
# plt.imshow(cloud\_mask\_scl)

combined\_cloud\_mask, buffered\_combined\_cloud\_mask = combine\_scl\_bratio\_buffer(cloud\_mask\_scl, cloud\_mask\_bratio, datafile, satelliteData)

cloudMaskAsImage(buffered\_combined\_cloud\_mask, datafile, ("field\_3" + '\_cloud\_mask\_combined\_buffered'),
 dir\_path)
colorArray = getTrueColorImage(datafile, satelliteData, outputFileName, geotiff\_OutputLocation, png\_OutputLocation)
indexStatistics, ndvi, ndvi\_gaussianFiltered = calculateNDVI(datafile, buffered\_combined\_cloud\_mask, satelliteData, outputFileName, applyGaussianFilter=True)

plt.imshow(ndvi\_gaussianFiltered)

#%%

import jenkspy
from sklearn.tree import DecisionTreeClassifier

def zoning\_jenks\_breaks(dataLayer, dataMask, n\_classes = 5, breakType = "jenks\_natural\_breaks"):
 # Filter out np.nan values from the data
 filtered\_data = dataLayer[~np.isnan(dataLayer)]

 if breakType == "jenks\_natural\_breaks":
 # This method is a data exploration technique that identifies 
 # natural groupings of data based on the concept of maximizing the 
 # differences between groups and minimizing the differences within groups. 

 breaks = jenkspy.jenks\_breaks(filtered\_data.tolist(), n\_classes=n\_classes)

 elif breakType == "equal\_interval":
 # Equal Interval Method: This method splits the data into equal intervals 
 # based on the range of the data values. For example, if the data ranges from 0 to 100, 
 # and we want to split it into 5 classes, each class would have a range of 20.
 
 # Compute the range of the data
 data\_range = np.max(filtered\_data) - np.min(filtered\_data)

 # Compute the interval size
 interval\_size = data\_range / n\_classes

 # Compute the class limits
 breaks = [np.min(filtered\_data) + i\*interval\_size for i in range(n\_classes+1)]

 elif breakType == "quantile":
 # This method splits the data into quantiles, which are equal-sized groups based on 
 # the distribution of the data. For example, if the data is divided into 5 quantiles, 
 # each quantile would contain 20% of the data.
 
 # Compute the quantile limits
 breaks = [np.quantile(filtered\_data, i/n\_classes) for i in range(n\_classes+1)]

 else:
 raise NameError("type of breaking classes unknown. Please choose from 'jenks\_natural\_breaks', 'quantile' or 'equal\_interval' ")
 
 # Divide the data into classes using the breaks
 classes = np.digitize(dataLayer, breaks)

 # Replace values outside field boundary with np.nan
 classes = classes\*dataMask

 return classes, breaks

# Calculate classes raster file with breaks to be displayed in legend
classes\_layer, breaks = zoning\_jenks\_breaks(ndvi\_gaussianFiltered, band\_dataMask, n\_classes = 5, breakType = "jenks\_natural\_breaks")
indexArray = [classes\_layer]
# Important, first layer is always index, second layer is always cloudmask
# Store the geotiff image with right meta data from the origional geotiff
kwargs = datafile.meta
kwargs.update(dtype=rasterio.float32, count=len(indexArray))

#%% Save raster for checking
# Read each layer and write it to stack
with rasterio.open(f'rasterToCheck.tif', 'w', \*\*kwargs) as dst:
 for id, layer in enumerate(indexArray, start=1):
 dst.write\_band(id, layer.astype(rasterio.float32))
#%%
import rasterio
from rasterio.features import shapes
import geopandas as gpd
from shapely.geometry import shape
## Save as geotiff 

indexArray = [classes\_layer]
# Important, first layer is always index, second layer is always cloudmask
# Store the geotiff image with right meta data from the origional geotiff
kwargs = datafile.meta
kwargs.update(dtype=rasterio.float32, count=len(indexArray))

raster = classes\_layer.astype(int)
transform = datafile.transform
results = (
 {'properties': {'raster\_val': v}, 'geometry': s}
 for i, (s, v) in enumerate(shapes(raster, mask=None, transform=transform))
)

# Convert shapes to GeoDataFrame
geoms = list(results)
gdf\_rasterShape = gpd.GeoDataFrame.from\_features(geoms)
gdf\_rasterShape = gdf\_rasterShape.set\_crs(datafile.crs)

# Load initial field shape to gdf
gdf\_field\_boundary = gpd.read\_file(os.path.join(dirpath, "TestDataGeoJson\_winterSummerWheat.geojson"))


clipped\_gdf = gpd.clip(gdf\_rasterShape, gdf\_field\_boundary).set\_crs(datafile.crs)

# Write the GeoDataFrame to a shapefile file
gdf\_rasterShape.to\_file('smoothenfile\_gaussian1.shp')

color\_dict = {
 -2147483648.0: 'gray',
 1: 'blue',
 2: 'green',
 3: 'orange',
 4: 'red',
 5: 'green',
 6: 'purple'
}
clipped\_gdf['color'] = clipped\_gdf['raster\_val'].map(color\_dict)

Confirm you have read this code with "OK"
다음 코드가 있습니다:#모든 개별 밴드가 있는 하나의 큰 지오티프를 기반으로 인덱스 값이 있는 지오티프 생성하기rasterio 가져오기import osrasterio.plot에서 import show지오판다를 gpd로 가져 오기numpy를 np로 가져 오기scipy.ndimage에서 가우스\_필터 가져 오기import foliumfolium에서 래스터\_레이어를 가져옵니다.matplotlib.pyplot에서 imread를 가져옵니다.위성\_데이터\_헬퍼 함수에서 \*를 가져옵니다.cloud\_handling에서 import \*import scipyfrom index\_calculation import \*import shapely테스트 중 ### ###satelliteData = "sentinel2\_L2A" #"sentinel2\_L2A" "planetScope"dir\_path = r'G:\\My Drive\\Bestanden\\SatelliteData\\testingData\\sentinel2\_L2A\_allRawBands\\'tiff\_files = []경로, 하위 경로, os.walk(경로\_경로)의 파일에 대해: tiff\_files.extend(os.path.join(dirpath, x) for x in files if x.endswith("responses\_20220326\_sowingSugarbeet\_summerwhea\_clipped.tiff"))geotiff = tiff\_files[0]geotiff\_OutputLocation =dir\_pathpng\_OutputLocation = dir\_pathfieldBoundary\_path = "testingData\\Sentinel2\_L2A\_allRawBands\\TestDataGeoJson\_winterSummerWheat.geojson"fieldBoundary = 'testBoundary.geojson'jsonGDF = gpd.read\_file(fieldBoundary)데이터 파일 = rasterio.open(geotiff)band\_dataMask = datafile.read(19) # 데이터 마스크band\_dataMask[band\_dataMask== 0] = np.nan출력 파일 이름 = 'test\_strange\_trueColoring\_5'# 밴드 수 확인(행성 == 17, 센티넬 == 19)print(f"name: {datafile.name.split('/')[-4]}, bands: {datafile.count}")print(f"crs = {datafile.crs}")## 클라우드 필터링cloud\_statistics\_scl, cloud\_mask\_scl = cloudProbability\_scl\_sentinel2\_L2A(datafile)cloud\_statistics\_bratio, cloud\_mask\_bratio = cloudProbability\_bRatio(datafile, satelliteData)# plt.imshow(cloud\_mask\_scl)결합된\_cloud\_mask, 버퍼된\_combined\_cloud\_mask = 결합된\_scl\_브라티오\_버퍼(cloud\_mask\_scl, cloud\_mask\_브라티오, datafile, satelliteData)cloudMaskAsImage(buffered\_combined\_cloud\_mask, datafile, ("field\_3" + '\_cloud\_mask\_combined\_buffered'), dir\_path)colorArray = getTrueColorImage(datafile, satelliteData, outputFileName, geotiff\_OutputLocation, png\_OutputLocation)indexStatistics, ndvi, ndvi\_gaussianFiltered = calculateNDVI(datafile, buffered\_combined\_cloud\_mask, satelliteData, outputFileName, applyGaussianFilter=True)plt.imshow(ndvi\_gaussianFiltered)#%%import jenkspysklearn.tree에서 DecisionTreeClassifier를 가져옵니다.def zoning\_jenks\_breaks(dataLayer, dataMask, n\_classes = 5, breakType = "jenks\_natural\_breaks"): # 데이터에서 np.nan 값을 필터링합니다. filtered\_data = dataLayer[~np.isnan(dataLayer)]] if breakType == "jenks\_natural\_breaks": # 이 메서드는 데이터 탐색 기법으로, # 데이터의 자연스러운 그룹을 식별합니다.  # 데이터의 자연스러운 그룹화를 식별하는 데이터 탐색 기법입니다.  그룹 간의 차이를 최대화하고 그룹 내 차이를 최소화하는 개념에 기반하여 # 자연스러운 데이터 그룹을 식별하는 기법입니다.  breaks = jenkspy.jenks\_breaks(filtered\_data.tolist(), n\_classes=n\_classes) elif breakType == "equal\_interval": # 동일 간격 메서드: 이 메서드는 데이터를 동일한 간격으로 분할합니다.  # 데이터 값의 범위를 기준으로 데이터를 동일한 간격으로 분할합니다. 예를 들어, 데이터 범위가 0에서 100 사이이고,  # 5개의 클래스로 나누고 싶다면 각 클래스의 범위는 20이 됩니다.  # 데이터의 범위를 계산합니다. data\_range = np.max(filtered\_data) - np.min(filtered\_data) # 간격 크기 계산 interval\_size = 데이터\_범위 / n\_클래스 # 클래스 제한 계산 breaks = [np.min(filtered\_data) + i\*interval\_size for i in range(n\_classes+1)] elif breakType == "사분위수": # 이 메서드는 데이터의 분포에 따라 동일한 크기의 그룹인 사분위수로 데이터를 분할합니다.  # 데이터의 분포를 기준으로 동일한 크기의 그룹인 사분위수로 나눕니다. 예를 들어 데이터가 5 사분위수로 나뉘는 경우,  # 각 사분위수에는 데이터의 20%가 포함됩니다.  # 사분위수 한계를 계산합니다. breaks = [np.quantile(filtered\_data, i/n\_classes) for i in range(n\_classes+1)] else: raise NameError("깨는 클래스의 유형을 알 수 없습니다. 'jenks\_natural\_breaks', 'quantile' 또는 'equal\_interval' 중에서 선택해 주세요.")  # break를 사용하여 데이터를 클래스로 나눕니다. classes = np.digitize(dataLayer, breaks) # 필드 경계 밖의 값을 np.nan으로 바꾸기 classes = classes\*dataMask 클래스, 브레이크 반환# 범례에 표시할 브레이크가 있는 클래스 래스터 파일을 계산합니다.classes\_layer, breaks = zoning\_jenks\_breaks(ndvi\_gaussianFiltered, band\_dataMask, n\_classes = 5, breakType = "jenks\_natural\_breaks")indexArray = [classes\_layer]# 중요, 첫 번째 레이어는 항상 인덱스, 두 번째 레이어는 항상 클라우드 마스크입니다.# 원본 지오티프에서 올바른 메타 데이터와 함께 지오티프 이미지 저장kwargs = datafile.metakwargs.update(dtype=rasterio.float32, count=len(indexArray))#%% 확인을 위해 래스터 저장# 각 레이어를 읽고 스택에 쓰기rasterio.open(f'rasterToCheck.tif', 'w', \*\*kwargs)를 dst로 사용합니다: for id, layer in enumerate(indexArray, start=1): dst.write\_band(id, layer.astype(rasterio.float32))#%%rasterio 가져오기rasterio.features에서 모양 가져 오기지오판다를 gpd로 가져오기f