基于水平参考高程面计算挖填方比较简单,水平参考高程也就是某一个高程值,只需要计算同一位置上DEM高程到参考面高程即可,挖填方分析实际上就是计算DEM数据与参考面构成的封闭体体积。

DEM数据本身是由一系列等间距横向和纵向分布的高程点构成,其数据组成形式与一般图像类似,相当于每个图像坐标上由像素值变成高程值。一般tif格式DEM数据还附带一个tfw文件用以描述起始点坐标、横向和纵向间隔距离等信息,通过读取tfw文件可以更方便的计算DEM数据。

由于DEM数据为离散的高程数据,为了得到更精确的计算结果,需要对DEM数据进行内插,在DEM内部内插出更多的高程点形成更小的高程格网,以每个格网内高程点作为附近区域平均高程与参考面高程计算差值,并计算体积。当差值为正,此时需要将高出参考面部分挖去,差值即为需要挖掉的深度,通过差值与高程点所在格网面积计算的体积即为该格网处的挖方;当差值为负,此处高程低于参考面,需要进行填方计算,通过同样方式计算填方量。

整个实现过程主要分为三步:

第一步,读取DEM数据,获取每一个栅格的高程值,读取tfw文件,获取起始坐标和每一个栅格长度;

Tfw文件内容:

第二步,对DEM高程值进行内插计算,将每一个栅格分割为n*n的格网,通过双线性内插计算得到格网上每个点的高程值;

第三步,将每个格网上的高程值与参考面高程计算差值,通过单个格网面积计算得到挖填方结果。

具体实现:

public DigFillResultData analysisByElevation(File currentDEM,double referenceElevation,int interpolation) throws Exception{

		// 读取数据
		File currentDEMTfw = new File(currentDEM.toString().replace("tif", "tfw"));
		TfwInfo currentDEMInfo = new TfwReader().read(currentDEMTfw);
		DemData currentData = new DemReader().read(currentDEM);
		// 进行计算
		DigFillResultData result = computeByElevation( currentDEMInfo, currentData,referenceElevation, interpolation);
		return result;
	}
	
private DigFillResultData computeByElevation(TfwInfo currentDEMInfo,DemData currentData,double referenceElevation,int interpolation) {

		double maxDigDeep = 0.0;
		double maxFillDeep = 0.0;
		double digVolume = 0.0;
		double fillVolume = 0.0;
		int width = currentData.getWidth();
		int height = currentData.getHeight();
		DigFillResultData result = new DigFillResultData();
		for (int i = 0; i < height - 1; i++) {
			for (int j = 0; j < width - 1; j++) {
				double currentXCoordinate = currentDEMInfo.getxCoordinate() + j * currentDEMInfo.getxStep();
				double currentYCoordinate = currentDEMInfo.getyCoordinate() + i * currentDEMInfo.getyStep();

				double interXStep = currentDEMInfo.getxStep() / interpolation;
				double interYStep = currentDEMInfo.getyStep() / interpolation;
				for (int x = 0; x < interpolation; x++) {
					for (int y = 0; y < interpolation; y++) {
						double currentXInterCoord = currentXCoordinate + x * interXStep;
						double currentYInterCoord = currentYCoordinate + y * interYStep;

						double currentValue = new ElevationInterpolation().caculateElevation(currentXInterCoord,
								currentYInterCoord, currentData, currentDEMInfo);
						if (currentValue != -32767.0) {
							double difference = currentValue - referenceElevation;
							if (difference > 0) {
								if (difference > maxDigDeep) {
									maxDigDeep = difference;
								}
								digVolume += difference * interXStep * Math.abs(interYStep);
							}
							if (difference < 0) {
								if (Math.abs(difference) > maxFillDeep) {
									maxFillDeep = Math.abs(difference);
								}
								fillVolume += Math.abs(difference) * interXStep * Math.abs(interYStep);
							}
						}
					}
				}
			}
		}
		result.setDigVolume(format(digVolume));
		result.setFillVolume(format(fillVolume));
		result.setMaxDigDeep(format(maxDigDeep));
		result.setMaxFillDeep(format(maxFillDeep));
		return result;
	}

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐