This repository has been archived by the owner on Jan 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSurfaceGeneration.pyt
329 lines (281 loc) · 14.1 KB
/
SurfaceGeneration.pyt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
"""This script defines an ArcGIS Python Toolbox for generating FAA FAR 77
surfaces.
"""
import os, uuid, re
import arcpy
import arcpy.da as da
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Surface Generation"
self.alias = "far77"
# List of tool classes associated with this toolbox
self.tools = [LineToFar77]
class Far77Params(object):
"""A class used to define FAR 77 surface creation parameters based on
runway classification"""
def __init__(self, runway_type):
"""Creates a Far77Params instance
@param runway_type: A runway type
@type runway_type: str
@rtype: Far77Params
"""
self.primary_surface_length = 200
self.primary_surface_width = 0
self.approach_surface_extendedwidth = 0
self.first_section_length = 0
self.first_section_slope = 0
self.second_section_length = 0
self.second_section_slope = 0
self.horizontal_surface_height = 150
self.horizontal_surface_radius = 0
self.conical_surface_slope = 20
self.conical_surface_offset = 4000
self.transitional_surface_slope = 7
# The runway types listed in the documentation for FAA FAR 77 do not
# match what appears when you actually run the tool in ArcMap.
# These regular expressions should match either version.
if re.match("Visual\s*(?:Runway)?\s*Visual\sApproach", runway_type, re.I):
self.primary_surface_width = 500
self.approach_surface_extendedwidth = 1500
self.first_section_length = 5000
self.first_section_slope = 20
self.horizontal_surface_radius = 5000
elif re.match("Utility\s*(?:Runway)?\s*Visual Approach", runway_type, re.I):
self.primary_surface_width = 250
self.approach_surface_extendedwidth = 1250
self.first_section_length = 5000
self.first_section_slope = 20
self.horizontal_surface_radius = 5000
elif re.match("Utility\s*(?:Runway)?\s*Non[\s\-]*Precision Instrument Approach", runway_type, re.I):
self.primary_surface_width = 500
self.approach_surface_extendedwidth = 2000
self.first_section_length = 5000
self.first_section_slope = 20
self.horizontal_surface_radius = 5000
elif re.match("Precision Instrument\s*(?:Runway)?", runway_type, re.I):
self.primary_surface_width = 1000
self.approach_surface_extendedwidth = 16000
self.first_section_length = 10000
self.first_section_slope = 50
self.second_section_length = 40000
self.second_section_slope = 40
self.horizontal_surface_radius = 10000
elif re.match("Non Precision Instrument\s*(?:Runway)?\s*(?:(?:High)|(?:Greater)) Visibility", runway_type, re.I):
self.primary_surface_width = 500
self.approach_surface_extendedwidth = 3500
self.first_section_length = 10000
self.first_section_slope = 34
self.horizontal_surface_radius = 10000
elif re.match("Non Precision Instrument\s*(?:Runway)\s*Approach Low Visibility", runway_type, re.I):
self.primary_surface_width = 1000
self.approach_surface_extendedwidth = 4000
self.first_section_length = 10000
self.first_section_slope = 34
self.horizontal_surface_radius = 10000
class LineToFar77(object):
_RUNWAY_LINE_INDEX = 0
_RUNWAY_SPATIAL_REF_INDEX = 1
_ELEVATION_DATA = 2
_IS_PREPARED_HARD_SURFACE_INDEX = 3
_RUNWAY_TYPE_INDEX = 4
_OUTPUT_FEATURE_CLASS_INDEX = 5
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "LineToFar77"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
runwayLineParam = arcpy.Parameter(
name="runway_line",
displayName="Runway Line",
direction="Input",
datatype="String", #"Line",
parameterType="Required")
runwaySpatialRefParam = arcpy.Parameter(
name="runway_spatial_reference",
displayName="Runway Spatial Reference",
direction="Input",
datatype="Spatial Reference",
parameterType="Optional")
# Set the default value to web mercator auxiliary sphere.
runwaySpatialRefParam.value = arcpy.SpatialReference(3857).exportToString()
elevationParam = arcpy.Parameter(
name="elevation_layer",
displayName="Elevation Layer",
direction="Input",
datatype=["Raster Layer",
"LAS Dataset Layer",
"Terrain Layer",
"TIN Layer"],
parameterType="Required")
isPreparedHardSurfaceParam = arcpy.Parameter(
name="is_prepared_hard_surface",
displayName="Is prepared hard surface?",
direction="Input",
datatype="Boolean",
parameterType="Optional")
isPreparedHardSurfaceParam.value = False
runwayTypeParam = arcpy.Parameter(
name="runway_type",
displayName="Runway Type",
direction="Input",
datatype="String",
parameterType="Required"
)
runwayTypeParam.filter.type = "ValueList"
runwayTypeParam.filter.list = [
"Visual Runway Visual Approach",
"Utility Runway Visual Approach",
"Utility Runway Non Precision Instrument Approach",
"Precision Instrument Runway",
"Non Precision Instrument Runway High Visibility",
"Non Precision Instrument Runway Approach Low Visibility"]
outputFCParam = arcpy.Parameter(
name="output_feature_class",
displayName="Output Feature Class",
direction="Output",
datatype="Feature Class",
parameterType="Required")
outputFCParam.value = arcpy.CreateUniqueName("faafar77", arcpy.env.scratchGDB)
params = [runwayLineParam, runwaySpatialRefParam,
elevationParam, isPreparedHardSurfaceParam,
runwayTypeParam, outputFCParam]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True #arcpy.CheckExtension("3D") and arcpy.CheckExtension("Aeronautical")
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
outputFCParam = parameters[self._OUTPUT_FEATURE_CLASS_INDEX]
if not outputFCParam.altered:
outputFCParam.value = arcpy.CreateUniqueName("faafar77", arcpy.env.scratchGDB)
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""Creates FAA FAR 77 surfaces
@param parameters: The parameters for the tool.
@param messages: The messages for the tool.
"""
# Convert the runway centerline string into a polyline.
runway_centerline = parameters[self._RUNWAY_LINE_INDEX].valueAsText
# Split string into component number strings.
lineCoords = re.findall(r"[^\s;,]+", runway_centerline)
messages.addMessage(runway_centerline)
# Convert strings into floats.
runway_centerline = map(float, lineCoords)
sr = parameters[self._RUNWAY_SPATIAL_REF_INDEX].valueAsText
# Create a polyline from the numbers.
array = arcpy.Array([
arcpy.Point(
runway_centerline[0],
runway_centerline[1]
),arcpy.Point(
runway_centerline[2],
runway_centerline[3]
)])
runway_centerline = arcpy.Polyline(array, sr)
del array
# Create an array of features to pass in to the interpolate shape tool.
in_features = [runway_centerline]
del runway_centerline, lineCoords, sr
in_surface = parameters[self._ELEVATION_DATA].valueAsText
## production_workspace = parameters[self._PRODUCTION_DB_INDEX].valueAsText
isPreparedHardSurface = parameters[self._IS_PREPARED_HARD_SURFACE_INDEX].value
runway_type = parameters[self._RUNWAY_TYPE_INDEX].value
out_featureclass = parameters[self._OUTPUT_FEATURE_CLASS_INDEX].valueAsText
result = arcpy.management.GetCount(in_features)
messages.AddGPMessages()
inFeatureCount = result.getOutput(0)
messages.addMessage("in_features: %s" % inFeatureCount)
inFeatureCount = int(inFeatureCount)
if inFeatureCount <= 0:
# Use 010151: features found in <value>. Possible empty feature class. http://resources.arcgis.com/en/help/main/10.1/index.html#//00vq0000000m010151
# messages.addMessage("in_features contains no features. %s" % inFeatureCount)
messages.addIDMessage(1, 010151, "in_features")
return
clear_way_length = 0
if not isPreparedHardSurface:
clear_way_length = 200
use_predefined_database_specification = "CUSTOM_SPECIFICATION"
create_surface = "PRIMARY_SURFACE;APPROACH_SURFACE;HORIZONTAL_SURFACE;CONICAL_SURFACE;TRANSITIONAL_SURFACE"
# Set the other parameters appropriate for the runway type.
far77Params = Far77Params(runway_type)
primary_surface_length = far77Params.primary_surface_length
primary_surface_width = far77Params.primary_surface_width
approach_surface_extendedwidth = far77Params.approach_surface_extendedwidth
first_section_length = far77Params.first_section_length
first_section_slope = far77Params.first_section_slope
second_section_length = far77Params.second_section_length
second_section_slope = far77Params.second_section_slope
horizontal_surface_height = far77Params.horizontal_surface_height
horizontal_surface_radius = far77Params.horizontal_surface_radius
conical_surface_slope = far77Params.conical_surface_slope
conical_surface_offset = far77Params.conical_surface_offset
transitional_surface_slope = far77Params.transitional_surface_slope
messages.addMessage("Executing Interpolate Shape tool")
# Get the elevations of the runways. Output will be in a new feature class.
# Create the name for the output runways feature class with elevations.
in_features3D = arcpy.CreateUniqueName("runwayCenterlines", arcpy.env.scratchGDB)
# Create output feature class.
out_path, out_name = os.path.split(out_featureclass)
# Set the output coordinate system if it is not already set.
if not arcpy.env.outputCoordinateSystem:
arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(3857)
# Create the feature class for the FAA FAR 77 tool output.
arcpy.management.CreateFeatureclass(out_path, out_name,
geometry_type="POLYGON",
has_z="ENABLED")
messages.AddGPMessages()
# Create a 3D version of the input 2D features.
messages.addMessage("Getting elevation data for the input runways...")
arcpy.InterpolateShape_3d(in_surface, in_features, in_features3D)
messages.AddGPMessages()
# Add ZMax field
messages.addMessage("Determining max. elevation for each runway...")
arcpy.AddZInformation_3d(in_features3D, "Z_MAX")
messages.AddGPMessages()
# Get the elevation "Z_MAX" from first feature.
airportElevation = None
with da.SearchCursor(in_features3D, ["Z_MAX"]) as cursor:
for row in cursor:
airportElevation = row[0]
break
messages.addMessage("Executing the FAAFAR77 tool")
try:
# execute the FAA FAR 77 tool
arcpy.FAAFAR77_aeronautical(in_features3D,
out_featureclass,
clear_way_length,
runway_type,
airportElevation,
"CUSTOM_SPECIFICATION",
"FEET",
"SLOPE",
create_surface,
primary_surface_length,
primary_surface_width,
approach_surface_extendedwidth,
first_section_length,
first_section_slope,
second_section_length,
second_section_slope,
horizontal_surface_height,
horizontal_surface_radius,
conical_surface_slope,
conical_surface_offset,
transitional_surface_slope)
finally:
messages.AddGPMessages()
# Delete temporary feature classes.
if arcpy.Exists(in_features3D):
arcpy.management.Delete(in_features3D)
messages.AddGPMessages()
return