drought/disaster/krigring/interpolation.py

70 lines
2.5 KiB
Python

import numpy as np
import pykrige.kriging_tools as kt
from pykrige import OrdinaryKriging
import rasterio as rio
class KrigingData(object):
def __init__(self, path, save_dir):
self.data = KrigingData.read_data(path)
self.save_dir = save_dir
self.get_conf()
@staticmethod
def read_data(path):
data = []
with open(path, 'r') as file:
lines = file.readlines()[1:]
for line in lines:
arr = line.split(' ')
data.append(
[int(arr[0]), float(arr[1]), float(arr[2]), float(arr[5]), float(arr[6]), int(arr[3]), int(arr[4])])
return np.array(data)
def get_minmax(self):
delta = 0.1
miny = self.data[:, 1].min() - delta
minx = self.data[:, 2].min() - delta
maxy = self.data[:, 1].max() + delta
maxx = self.data[:, 2].max() + delta
return (minx, miny, maxx, maxy)
def get_conf(self):
(minx, miny, maxx, maxy) = self.get_minmax()
res = 0.003
self.gridx = np.arange(minx, maxx, res)
self.gridy = np.arange(miny, maxy, res)
self.height = len(self.gridx)
self.width = len(self.gridy)
from rasterio.transform import from_origin
self.transform = from_origin(miny - res / 2, maxx + res / 2, res, res)
def write_tif(self, path, kriging_data):
out_meta = {"driver": "GTiff",
"height": self.height,
"width": self.width,
"transform": self.transform}
with rio.open(path, "w", count=1, dtype='float64', crs='+proj=latlong', **out_meta) as dest:
# kriging_data.reshape(self.height, self.width)
dest.write_band(1, kriging_data)
def kriging(self, value_name):
if value_name == 'rain':
value_index = 3
else:
value_index = 4
OK = OrdinaryKriging(self.data[:, 2], self.data[:, 1], self.data[:, value_index], variogram_model='spherical',
verbose=False,
enable_plotting=False)
z, ss = OK.execute('grid', self.gridx, self.gridy)
name = str(int(self.data[0, 5])) + '-' + str(int(self.data[0, 6])) + '-' + value_name + '.tif'
path = self.save_dir + '//' + name
self.write_tif(path, z)
if __name__ == '__main__':
kd = KrigingData("D:/work/3.scala-gis/geotrellis-through/geotrellis/bj_197901.txt", "D://")
kd.kriging('rain')
kd.kriging('temp')