GPU加速的R3算法(可视域计算)

目标是做一个arcgis的插件,但是似乎arcgis和pycuda不兼容= =。。。。搞半天都没弄好,只能把读数据、处理数据和显示数据分成三个部分来做

数据读取

import arcpy
import numpy
from arcpy.sa import *
import pycuda.autoinit
import pycuda.driver as cuda
import numpy as np
import math
import sys
from timeit import default_timer as timer
import pycuda.gpuarray as gpuarray
from pycuda.compiler import SourceModule
reload(sys)
sys.setdefaultencoding('utf8')


# get raster layer
Input_rasterLyr = arcpy.GetParameterAsText(0)
arcpy.AddMessage(Input_rasterLyr)
# turn layer to raster
InputRatser = Raster(Input_rasterLyr)
# turn Raster To NumPyArray
myArray = arcpy.RasterToNumPyArray(InputRatser)
# get width and height of myArray
desc = arcpy.Describe(InputRatser)
raster_width = desc.width
raster_height = desc.height
extent = desc.Extent
#get point
Input_point_x = arcpy.GetParameter(1)
Input_point_y = arcpy.GetParameter(2)
x_co = float(Input_point_x)
#x_co = 129.390076
y_co = float(Input_point_y)        
#y_co = 47.360901          
rows = raster_height
columns = raster_width
der_x = extent.XMax - extent.XMin
der_y = extent.YMax - extent.YMin

column = int((x_co - extent.XMin) / der_x * columns)
row = int((extent.YMax - y_co) / der_y * rows)
lower_left = arcpy.Point(X=extent.XMin, Y=extent.YMin)


numpy.save("D:\\DEM_save.npy", myArray)
arcpy.AddMessage("OKOKOK")
#arcpy.AddMessage(y_co)
arcpy.AddMessage("raster_height = ")
arcpy.AddMessage(raster_height)
arcpy.AddMessage("raster_width = ")
arcpy.AddMessage(raster_width)
arcpy.AddMessage("row(x) = ")
arcpy.AddMessage(row)
arcpy.AddMessage("column(y) = ")
arcpy.AddMessage(column)

显示的行和列输到数据处理的文件中(没错每个图还需要改一下)

数据处理文件

import pycuda.autoinit
import pycuda.driver as cuda
import numpy as np
import math
from timeit import default_timer as timer
import pycuda.gpuarray as gpuarray
from pycuda.compiler import SourceModule

mod = SourceModule("""
#include <stdio.h>
#include <cmath>
using namespace std;
__global__ void func(int R_array[457][449], float my_array[457][449], int width, int height, int x, int y, float H_xy, size_t N)
{
	const int idx = blockIdx.x * blockDim.x + threadIdx.x;
	const int idy = blockIdx.y * blockDim.y + threadIdx.y;
    	if (idx > width || idy > height) {
		return;
	}
	if(my_array[idx][idy] > 1000 || my_array[idx][idy] < 0){
		my_array[idx][idy] = 0;
		R_array[idx][idy] = 2;
		return;
	}
	if(my_array[idx][idy] == 0){
		R_array[idx][idy] = 2;
		return;
	}
    int add_x, add_y, i,j;
	float k, v;
	bool flag = true;
	if (idy >= y) {
		add_y = 1;
	}
	else {
		add_y = -1;
	}
	if (idx >= x) {
		add_x = 1;
	}
	else{
		add_x = -1;
	}
	float x_chaju = (idx - x) * add_x;
	float y_chaju = (idy - y) * add_y;
	double threshold = sqrt(x_chaju * x_chaju + y_chaju * y_chaju * 1.0);
	if (idx == x || idy == y ) {	
		j = x + add_x;
		i = y + add_y;
		float Height = my_array[idx][idy] - H_xy;
		for (; ;i += add_y) {
			if (add_y > 0 && i > idy)break;
			if (add_y < 0 && i < idy)break;
			float h_cha = my_array[x][i];
			float h_view = Height * (i - y) * add_y/ y_chaju + H_xy;
			if (h_cha > h_view) {
				R_array[idx][idy] = 0;
				flag = false;
				break;
			}
			if (!flag) break;
		}
		for (; ; j += add_x) {
				if (add_x > 0 && j > idx)break;
				if (add_x < 0 && j < idx)break;
				float h_cha = my_array[j][y];
				float h_view = Height * (j - x) * add_x / x_chaju + H_xy;
				if (h_cha > h_view) {
					R_array[idx][idy] = 0;
					flag = false;
					break;
				}
			}
		
	}
	else {
		i = x + add_x;
		j = y + add_y;
		if (idx != x && idy != y) {
			k = (idy - y) * 1.0/ (idx - x);
			v = idy - k * idx;
			float Height = my_array[idx][idy] - H_xy;
			for (; ;i += add_x) {
				if (add_x > 0 && i > idx)break;
				if (add_x < 0 && i < idx)break;
				float y_0 = k * i + v;
				//if (y_0 > height || y_0 < 0) break;
				float h_cha;
				if ( y_0 - int(y_0) < 0.01 ) {
					h_cha = my_array[i][int(y_0)];
				}
				else {
					int y_1 = (int)(y_0);
					float h1 = my_array[i][y_1];
					int y_2 = (int)(y_0)+1;
					float h2 = my_array[i][y_2];
					h_cha = (y_2 - y_0) * (h2 - h1) + h1;
				}
				float h_view = Height * (i - x) * add_x / x_chaju + H_xy;
				if (h_cha > h_view) {
					R_array[idx][idy] = 0;
					flag = false;
					break;
				}
			}
			
			if (flag) {
				for (; ;j += add_y) {
					if (add_y > 0 && j > idy)break;
					if (add_y < 0 && j < idy)break;
					float x_0 = (j - v) / k;
					float h_cha;
					if (x_0 - (int)(x_0) < 0.01) {
							h_cha = my_array[(int)(x_0)][j];
					}
					else {
							int x_1 = (int)(x_0);
							int x_2 = (int)(x_0)+1;
							//if (x_0 > width || x_0 < 0) break;
							float h1 = my_array[x_1][j];
							float h2 = my_array[x_2][j];
							h_cha = (x_0 - x_1) * (h2 - h1) + h1;
					}
					
					float h_view = Height * (j - y) * add_y / y_chaju + H_xy;
					if (h_cha > h_view) {
						R_array[idx][idy] = 0;
						flag = false;
						break;
					}
				}
			}
			if (flag) R_array[idx][idy] = 1;
		}
	}
	if (flag) R_array[idx][idy] = 1;
	
}
""")
func = mod.get_function("func")
myArray = np.load("D:\\DEM_save.npy")
myArray = myArray.astype(np.float32)
Width = np.int32(myArray.shape[1])
Height = np.int32(myArray.shape[0])
X_set = np.int32(271)
Y_set = np.int32(315)
raster_width = Width
raster_height = Height
N = raster_width
x = np.int32(X_set)
y = np.int32(Y_set)
H_xy = myArray[int(round(x))][int(round(y))]
ResultArray = np.int32((np.zeros_like(myArray)))
a_gpu = cuda.mem_alloc(myArray.nbytes)
r_gpu = cuda.mem_alloc(ResultArray.nbytes)


cuda.memcpy_htod(a_gpu, myArray)
cuda.memcpy_htod(r_gpu, ResultArray)
np.set_printoptions(threshold = 'nan')
nTheads = 20
nBlocks = int( ( N + nTheads) / nTheads )
func(r_gpu, a_gpu, raster_width, raster_height, x, y, H_xy, N,
    block=( nTheads, nTheads, 1 ), grid=( nBlocks, nBlocks ) )
r_doubled = np.empty_like(ResultArray)
cuda.memcpy_dtoh(ResultArray, r_gpu)
cuda.memcpy_dtoh(myArray, a_gpu)
np.save("D:\\ResultArray.npy",ResultArray)
数据显示

为了和原DEM在一起显示,还要使用DEM图层的参数

import arcpy
import numpy
from arcpy.sa import *

myarray = numpy.load("D:/ResultArray.npy")
arcpy.AddMessage("Load done")

Input_rasterLyr = arcpy.GetParameterAsText(0)
raster = Raster(Input_rasterLyr)
describe = arcpy.Describe(raster)
cell_size_x = describe.meanCellWidth
cell_size_y = describe.meanCellHeight
spatialReference = describe.spatialReference
extent = describe.Extent
lower_left = arcpy.Point(X=extent.XMin, Y=extent.YMin)
#my_raster = arcpy.NumPyArrayToRaster(myarray)
result = arcpy.NumPyArrayToRaster(myarray, lower_left_corner=lower_left, x_cell_size=cell_size_x,y_cell_size=cell_size_y)
arcpy.DefineProjection_management(result, spatialReference)
result.save("D:/15ArcGIS功能扩展/try/result.gdb/RasterNo4")





猜你喜欢

转载自blog.csdn.net/weiwanshu/article/details/78964335