• Keine Ergebnisse gefunden

Conclusion and outlook

A.1 Python source code

A.1.7 APOLLO configuration process

4 """ The process is part of the explosive ordnance disposal workflow 5 and returns APOLLO configuration data for SIRIUS interface.

6 """

7 8 # libs

9 importlogging 10 importtempfile 11 importjson

12 frompywpsimportProcess, LiteralInput, ComplexInput, ComplexOutput, Format 13 frompywps.app.CommonimportMetadata

14 frompywps.validator.modeimportMODE 15 frompywps.validatorimportcomplexvalidator

16 frompywps.validator.allowed_valueimportRANGECLOSURETYPE, ALLOWEDVALUETYPE 17 frompywps.inout.literaltypesimportAllowedValue

18 fromeasydictimportEasyDict 19 fromosgeoimportogr 20 fromlibimportgeolib 21

22 # authorship information 23 __author__ ="Gunnar Ströer"

24 __copyright__ ="Copyright 2019, integration of wps in local sdi"

25 __version__ ="1.0"

26 __maintainer__ ="Gunnar Ströer"

27 __email__ ="gunnar.stroeer@yahoo.de"

34 # process returns APOLLO configuration data for SIRIUS interface 35 classApolloConf(Process):

36 # static class variables

37 epsg = 25832 # local spatial reference code 38 epsg2 = 4326 # spatial reference code for WGS84

39 srv_url ='https://www.cadfem.de/apollo/' # url provided by the SIRIUS project team 40

48 # validation mode unable to use due incompatibilities between mimetype library and QGIS wps client

49 mode=MODE.NONE

55 abstract='Precision used by APOLLO simulation. Supported values are: 0.5, 1.0, 2.5, 5.0, 10.0',

56 data_type='float',

57 allowed_values=(0.5, 1.0, 2.5, 5.0, 10.0)

58 )

69 'Exact TNT Blast Power [kg]',

70 data_type='integer',

71 # spacing unable to use due incompatibilities between QGIS wps client 72 # allowed_values=(range(50, 2000+1, 50)),

73 allowed_values=[AllowedValue(minval=1, maxval=5000, # spacing=50,

74 allowed_type=ALLOWEDVALUETYPE.RANGE,

75 range_closure=RANGECLOSURETYPE.OPEN)]

76 )

77

78 in_heading = LiteralInput(

79 'in_heading',

80 'Bomb Azimuth Angle [deg]',

81 data_type='float',

88 'Bomb Tilt Angle [deg]',

89 data_type='float',

97 abstract='Type of the bomb after classification. Supported values are: N/A, GP100, GP250',

98 data_type='string',

106 abstract='Position of detonator after classification. Supported values are: N/A, Front, Rear, Top, Bottom',

107 data_type='string',

108 allowed_values=('N/A','Front','Rear','Top','Bottom'),

109 min_occurs=0

115 abstract='Description of the bomb find location. Supported values are: Surface, Cavern',

116 data_type='string',

131 'Hidden Objects [gml:id1 gml:id2]',

132 abstract='List of 3D city model objects that will be ignored by the simulation. '

133 'Supported values are GML identificationstrings.',

134 data_type='string',

145

146 inputs = [in_geom, in_precision, in_height, in_tnt, in_heading, in_pitch, 147 in_type, in_detonator, in_site_desc, in_site_rad, in_hidden]

148

156 abstract='The process returns APOLLO configuration data for SIRIUS interface.', 157 metadata=[Metadata('The process is part of the explosive ordnance disposal workflow '

158 'and returns APOLLO configuration data for SIRIUS interface.',

159 'http://geodev:8080/geonetwork/srv/ger/catalog.search?service=CSW&version=2.0.2'

168 # handler method obtains request object and response object 169 # @staticmethod # only for static methods, no 'self' applicable 170 def_handler(self, request, response):

171 # obtain input with identifier as file name 172 in_file = request.inputs['in_geom'][0].file 173

174 # possible request attributes: 'abstract', 'as_reference', 'base64', 'clone', 'crs', 'crss', 'data', 175 # 'describe_xml', 'dimensions', 'execute_xml', 'file', 'get_base64', 'get_data', 'get_file',

176 # 'get_memory_object', 'get_stream', 'get_workdir', 'identifier', 'json', 'll', 'max_occurs', 'memory_object', 177 # 'metadata', 'min_occurs', 'set_base64', 'set_data', 'set_file', 'set_memory_object', 'set_stream', 178 # 'set_workdir', 'source', 'source_type', 'stream', 'title', 'ur', 'valid_mode', 'validator', 'workdir' 179

180 # default parameter values

181 bomb_type, detonator, site_desc, hidden ='','','',''

182 precision, height, tnt, heading, pitch, site_rad = 0., 0., 0, 0., 0., 2.

183

184 # check and obtain input with identifier as data directly 185 if'in_precision'inrequest.inputs:

186 precision = request.inputs['in_precision'][0].data 187 if'in_height'inrequest.inputs:

188 height = request.inputs['in_height'][0].data 189 if'in_tnt'inrequest.inputs:

190 tnt = request.inputs['in_tnt'][0].data 191 if'in_heading'inrequest.inputs:

192 heading = request.inputs['in_heading'][0].data 193 if'in_pitch'inrequest.inputs:

194 pitch = request.inputs['in_pitch'][0].data 195 if'in_type'inrequest.inputs:

196 bomb_type = request.inputs['in_type'][0].data 197 if'in_detonator'inrequest.inputs:

198 detonator = request.inputs['in_detonator'][0].data 199 if'in_site_desc'inrequest.inputs:

200 site_desc = request.inputs['in_site_desc'][0].data 201 if'in_site_rad'inrequest.inputs:

202 site_rad = request.inputs['in_site_rad'][0].data 203 if'in_hidden'inrequest.inputs:

204 hidden = (request.inputs['in_hidden'][0].data).split() 205

206 # open file and layer 207 in_src = ogr.Open(in_file) 208 in_lyr = in_src.GetLayer() 209

210 # only one single input feature and valid tnt blast power 211 ifin_lyr.GetFeatureCount() == 1andtnt > 0:

212 # conservative calculation for float glass

213 dist_threshold = geolib.damage_dist_threshold(tnt, 0) 214

215 LOGGER.debug('Threshold:'+str(dist_threshold)) 216

217 # get the feature geometry 218 in_feat = in_lyr.GetNextFeature() 219 in_geom = in_feat.GetGeometryRef() 220

221 # get SRID of geometry and make sure location is a point

222 epsg0 =int(in_geom.GetSpatialReference().GetAttrValue('AUTHORITY', 1)) 223 x0, y0 = in_geom.Centroid().GetX(), in_geom.Centroid().GetY() 224

225 # harmonization of spatial reference

226 ifepsg0 != self.epsg:

227 # transform position to local spatial reference 228 x2, y2 = geolib.geo_transform(x0, y0, epsg0, self.epsg)

229 else:

230 x2, y2 = x0, y0

231

232 # calculate bounding box

233 bbx1 = x2 - dist_threshold

234 bby1 = y2 - dist_threshold

235 bbx2 = x2 + dist_threshold

236 bby2 = y2 + dist_threshold

237

238 # transform position to WGS84

239 x_wgs, y_wgs = geolib.geo_transform(x2, y2, self.epsg, self.epsg2) 240

241 LOGGER.debug('Coordinates in '+str(self.epsg) +':'+str(x2) +'/'+str(y2)) 242 LOGGER.debug('Coordinates in '+str(self.epsg2) +':'+str(x_wgs) +'/'+str(y_wgs)) 243

244 # create location geometry

245 location = ogr.Geometry(ogr.wkbPoint)

246 location.AddPoint(x2, y2)

247

248 LOGGER.debug('Location as WKT:'+ location.ExportToWkt()) 249

250 # create output data

251 conf_data = EasyDict({'bomb': {'tnt': tnt,'type': bomb_type,'detonator': detonator},

252 'domain': {'name':'Ultimo','zroi': 100,'droi': dist_threshold},

253 'mode': {'name':'Ultimo','t': 50,'precision': precision},

254 'site': {'type': site_desc,'radius': site_rad},

255 'geometry': {'crs': self.epsg2,'position': [x_wgs, y_wgs],'depth': (-1) * height},

256 'crs': self.epsg,

257 'position': [x2, y2],

258 'height': height,

259 'heading': heading,

260 'pitch': pitch,

261 'extent': [bbx1, bby1, bbx2, bby2],

262 'hiddenObjects': hidden,

263 'service': {'url': self.srv_url,'resultFile':'effects_'+str(self.uuid) +'.zip'}

264 })

265

266 conf_json = json.dumps(conf_data) 267

268 # create file, w: write in text mode

269 conf_path = tempfile.mkstemp(prefix='conf_', suffix='.json')[1]

270 withopen(conf_path,'w') as fp:

271 fp.write(conf_json)

272 fp.close()

273

274 # set output format and file name

275 response.outputs['out_conf'].output_format = Format(mime_type='application/json', extension='.json',

276 validate=complexvalidator.validategeojson,

277 encoding='UTF-8', schema='json')

278 response.outputs['out_conf'].file= conf_path

279 else:

280 # remove output from response

281 delresponse.outputs['out_conf']

282

283 LOGGER.debug('Only one single input feature allowed. '+ 284 str(in_lyr.GetFeatureCount()) +' detected!') 285

286 # free and reassign

287 in_src = None

288 in_lyr = None

289

290 # possible response attributes: 'abstract', 'as_reference', 'base64', 'crs', 'crss', 'data', 'describe_xml', 291 # 'dimensions', 'execute_xml', 'file', 'get_base64', 'get_data', 'get_file', 'get_memory_object', 'get_stream', 292 # 'get_workdir', 'identifier', 'json', 'll', 'max_occurs', 'memory_object', 'metadata', 'min_occurs', 293 # 'set_base64', 'set_data', 'set_file', 'set_memory_object', 'set_stream', 'set_workdir', 'source', 294 # 'source_type', 'stream', 'title', 'ur', 'valid_mode', 'validator', 'workdir'

295

296 returnresponse

Listing A.7: APOLLO configuration process