ToB企服应用市场:ToB评测及商务社交产业平台

标题: 第十届全国大学生GIS应用技能大赛试题及参考解题过程(A下午) [打印本页]

作者: 花瓣小跑    时间: 2022-8-31 19:46
标题: 第十届全国大学生GIS应用技能大赛试题及参考解题过程(A下午)
本次操作使用的ArcGIS版本为 10.8 。
第Ⅰ部分:试题

一、 案例背景

\(\quad\quad\)太阳能是一种可再生资源,是指太阳的热辐射能。太阳能资源丰富,既可免费使用,又无需运输,对环境无任何污染。太阳能的利用还不是很普及,太阳能的使用受到昼夜、季节、地理纬度和海拔高度等自然条件的限制以及晴、阴、云、雨等随机因素的影响。
\(\quad\quad\)某住宅小区希望在屋顶安装太阳能,供给家庭日常用电。你将为该小区评估是否适合安装太阳能电池板。
二、 数据说明(见 “上午A” 文件夹中的 “数据” 文件夹)

三、 分析要求(100分)

第Ⅱ部分:参考解题过程

一、 导入原始数据并配置地理处理空间

\(\quad\quad\)打开【地理处理】|【环境】,设置工作空间(我的数据文件夹就放在桌面上),并设置输出栅格像元大小与 DTM 一致。
[img=480px,440px]https://s1.ax1x.com/2022/07/23/jXwFqe.png[/img]图1 设置地理处理环境\(\quad\quad\)导入原始数据 “Building.shp” 、 “DTM.tif” 以及 “DSM.tif” 进入显示窗口中,操作前查看数据的坐标系是一个好习惯,发现三者的投影坐标系均一致,无需特别处理。
[img=800px,400px]https://s1.ax1x.com/2022/07/23/jXwEad.png[/img]图2 导入原始数据并查看坐标系二、根据建筑物修正DTM

三、计算每栋房屋的其它基础信息

\(\quad\quad\)首先对 Building 添加字段【max_tall】和【build_tall】,保留 2 位小数,并且将别名分别设置为【最大高度】和【建筑物高度】。
[img=480px,430px]https://s1.ax1x.com/2022/07/23/jXwQsS.png[/img]图13 添加【最大高度】和【建筑物高度】字段四、创建房屋屋顶区域 2021 年每月预计获得太阳辐射量栅格数据,在环境设置中,将 Building 作为掩膜

\(\quad\quad\)计算房屋屋顶区域 12 个月每一个月的太阳辐射量栅格数据主要使用【太阳辐射区域】工具,该工具位于【ArcToolBox】|【Spatial Analyst】|【太阳辐射】目录下,并且题目中对于参数已经做了限定,其余参数保持默认即可。尝试了几次该工具后我发现,其计算速度比较慢,如果手动计算 12 次要等很久,于是想到了使用 Arcpy 的 Python 模块来编写脚本。这样在 Python 代码运行的过程中可以继续使用 ArcMap 进行操作。
\(\quad\quad\)使用 ArcGIS 的 Python 脚本功能主要有 2 种方式:
\(\quad\quad\)这里我选择后者以方便调试。我打开了 Pycharm,新建 Python 项目,然后设置编译器的位置为 ArcGIS 安装位置处的 Python 2.7.18 环境,开发环境就这样搭建好啦。
\(\quad\quad\)那么接下来的问题是如何编写代码,由于 ArcMap 的【模型构建器】具有一键导出模型为 Python 脚本的功能,因此我先在 ArcToolBox 中拖动【太阳辐射区域】工具进入 【模型构建器】编辑界面,然后设置参数,然后一键生成代码,ArcMap 这个功能可以说是我的福音啊哈哈哈。
[img=480px,400px]https://s1.ax1x.com/2022/07/23/jXwNR0.png[/img]图20 添加【太阳辐射区域】进入模型构建器并设置掩膜\(\quad\quad\)上图中可以看出我事先设置模型属性中的掩膜为 Building.shp。太阳辐射区域的设置界面如下所示(以计算屋顶区域 2021 年 1 月份太阳辐射为例):
[img=480px,460px]https://s1.ax1x.com/2022/07/23/jXwdMT.png[/img]图21 太阳辐射区域设置界面\(\quad\quad\)设置完工具之后回到【模型构建器】的编辑界面,点击【导出至 Python 脚本】:
[img=480px,400px]https://s1.ax1x.com/2022/07/23/jXwwsU.png[/img]图22 导出模型到 Python 脚本\(\quad\quad\)当然,导出的脚本仍然有一些不完善的地方,例如需要针对每个月晴天天数对结果进行乘法修正,需要得到每个月太阳辐射的低值和高值。这时可以参照 ArcGIS 的帮助文档修改代码,帮助文档对 Python 脚本也是有详细介绍的:
[img=800px,400px]https://s1.ax1x.com/2022/07/23/jXwDZ4.png[/img]图23 ArcGIS 帮助文档界面\(\quad\quad\)最后,这是我的脚本的最终版本:
  1. # -*- coding:UTF-8 -*-
  2. # Name: AreaSolarRadiation_example02.py
  3. # Description: Derives incoming solar radiation from a raster surface.
  4. #              Outputs a global radiation raster and optional direct, diffuse and direct duration rasters
  5. #              for a specified time period. (April to July).
  6. #              
  7. # Requirements: Spatial Analyst Extension
  8. # Import system modules
  9. import arcpy
  10. from arcpy import env
  11. from arcpy.sa import *
  12. import numpy as np
  13. # Set environment settings
  14. env.workspace = "C:/Users/Fangh/Desktop/data"  # 工作空间,需更改
  15. # Check out the ArcGIS Spatial Analyst extension license
  16. arcpy.CheckOutExtension("Spatial")
  17. # Set Geoprocessing environments
  18. env.cellSizeProjectionMethod = "CONVERT_UNITS"
  19. env.cellSize = "DTM.tif"  # 像元大小与DTM.tif一致
  20. env.mask = "Building.shp"  # 设置屋顶区域Building.shp为掩膜
  21. # Set local variables
  22. inRaster = "C:/Users/Fangh/Desktop/data/DSM.tif"
  23. latitude = 41.77686382537  # 纬度
  24. skySize = 200  # 天空大小
  25. timeConfig = [TimeMultipleDays(2021, 1, 31),      # Jenuary
  26.               TimeMultipleDays(2021, 32, 59),     # February
  27.               TimeMultipleDays(2021, 60, 90),     # March
  28.               TimeMultipleDays(2021, 91, 120),    # April
  29.               TimeMultipleDays(2021, 121, 151),   # May
  30.               TimeMultipleDays(2021, 152, 181),   # June
  31.               TimeMultipleDays(2021, 182, 212),   # July
  32.               TimeMultipleDays(2021, 213, 243),   # August
  33.               TimeMultipleDays(2021, 244, 273),   # September
  34.               TimeMultipleDays(2021, 274, 304),   # October
  35.               TimeMultipleDays(2021, 305, 334),   # November
  36.               TimeMultipleDays(2021, 335, 365)]   # December
  37. dayInterval = 14  # 间隔天数
  38. hourInterval = 0.5  # 间隔小时数
  39. zFactor = 1  # 地形参数/Z因子
  40. calcDirections = 16  #  地形参数/计算方向
  41. zenithDivisions = 8  # 辐射参数/天顶分割
  42. azimuthDivisions = 8  # 辐射参数/方位角分割
  43. diffuseProp = 0.3  # 辐射参数/散射比例
  44. transmittivity = 0.5  # 辐射参数/透射率
  45. outDirectRad = ""  # 无需"输出直接辐射栅格数据"
  46. outDiffuseRad = ""  # 无需"输出散射辐射栅格数据"
  47. outDirectDur = ""  # 无需"直接辐射持续时间栅格数据"
  48. # Sunny days in every month
  49. SunnyDay = [25.0/31.0, 20.0/28.0, 24.0/31.0,
  50.             23.0/30.0, 20.0/31.0, 15.0/30.0,
  51.             22.0/31.0, 26.0/31.0, 27.0/30.0,
  52.             20.0/31.0, 25.0/30.0, 26.0/31.0]
  53. # statistic the maximum and minimum of every raster
  54. mni_max_value = np.zeros([2, 12])
  55. outputcsv = r"C:/Users/Fangh/Desktop/data/statics.csv"
  56. outputfile = open(outputcsv, 'w')
  57. for i in range(12):
  58.    # Execute AreaSolarRadiation
  59.    outGlobalRad = AreaSolarRadiation(inRaster, latitude, skySize, timeConfig[i],
  60.       dayInterval, hourInterval, "NOINTERVAL", zFactor, "FROM_DEM",
  61.       calcDirections, zenithDivisions, azimuthDivisions, "UNIFORM_SKY",
  62.       diffuseProp, transmittivity, outDirectRad, outDiffuseRad, outDirectDur)
  63.    # Consider the sunny day
  64.    outGlobalRad *= SunnyDay[i]
  65.    # Save the output
  66.    outGlobalRad.save("C:/Users/Fangh/Desktop/data/Rad_"+str(i+1)+".tif")
  67.    # Get the minimum and maximum
  68.    minimumvalueInfo = arcpy.GetRasterProperties_management(outGlobalRad, "MINIMUM")
  69.    mni_max_value[0, i] = minimumvalueInfo.getOutput(0)
  70.    maximumvalueInfo = arcpy.GetRasterProperties_management(outGlobalRad, "MAXIMUM")
  71.    mni_max_value[1, i] = maximumvalueInfo.getOutput(0)
  72. # Write the outputfile
  73. outputfile.write('Month'+','+'January'+','+'February'+','+'March'+','+'April'+','+'May'+','+'June'+','+'July'+','+'August'+','+'September'+','+'October'+','+'November'+','+'December'+'\n')
  74. outputfile.write('Minimum')
  75. for i in range(12):
  76.     outputfile.write(','+str(mni_max_value[0, i]))
  77. outputfile.write('\n')
  78. outputfile.write('Maximum')
  79. for i in range(12):
  80.     outputfile.write(','+str(mni_max_value[1, i]))
  81. outputfile.write('\n')
  82. outputfile.close()
  83. print("All Job Were Done!")
复制代码
\(\quad\quad\)这份代码在计算出 12 个月份的屋顶区域太阳辐射量栅格数据之后,生成了一份 statistic.csv 逗号分隔值文件(用 Excel 打开),与数据存放在相同文件夹之下。于是得到房屋屋顶区域 2021 年每月的太阳辐射量栅格数据以及每一个月的低值和高值如下表所示:
月份1月2月3月4月5月6月7月8月9月10月11月12月低值4.232212543495.310807704939.6210517883312.272103309612.55576801310.004987716714.289325714114.909709930412.18401050576.189159870154.795568466193.67597270012高值39828.097656348683.12585742.09375106786.398438108502.52343885074.40625123380.328125129046.210938107483.8437556247.48437544828.539062528945.9609375\(\quad\quad\)最后,手动拖入 12 份栅格数据进入 ArcMap 查看有无错误,并修改中文名称为 “太阳辐射 * 月”。结果如下:
[img=800px,400px]https://s1.ax1x.com/2022/07/23/jXwso9.png[/img]图24 2021 年每月房屋屋顶太阳辐射量栅格数据五、计算 8 月份可用房屋屋顶范围内的太阳辐射量,在环境设置中,将 Building 作为掩膜

\(\quad\quad\)这一要求可以使用 “与或非” 逻辑解决,借助【ArcToolBox】|【Spatial Analyst】|【地图代数】|【栅格计算器】工具,当坡度位于于 \([0, 15]\) 度时,可以在任意坡向方向安装太阳能电池板或者坡度位于 \((15, 30]\) 度之间时,且坡向位于 \((22.5, 337.5)\) 度之间或者坡度位于 \((30, 45]\) 度之间时,且坡向位于 \((67.5, 292.5)\) 度之间
[img=800px,400px]https://s1.ax1x.com/2022/07/23/jXwWQK.png[/img]图30 可用辐射 8 月栅格数据结果六、计算 8 月份每栋房屋可接收的太阳辐射量,在环境设置中,将 Building 作为掩膜

\(\quad\quad\)首先添加字段【可用面积】与【可用辐射量 8 月】如下所示,小数位数为 2 位,数据类型为双精度,精度为 12 位:
[img=480px,350px]https://s1.ax1x.com/2022/07/23/jXwfsO.png[/img]图31 添加【可用面积】与【可用辐射量 8 月】两个字段结尾:参赛收获及数据下载地址

\(\quad\quad\)这道题目做下来觉得操作量挺大的,耗时也比较长,例如使用 Arcpy 那一部分在我的电脑上运行了半个小时左右。在规定时间内完成全部题目很有难度。当然,如果操作者对 ArcGIS 分析流程更熟悉的话就容易很多,我还要继续加油。
\(\quad\quad\)数据下载地址(提取密码:wx7d)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4