def execute(request): """Clips selected search results using the clip geometry. :param request: json as a dict. """ clipped = 0 errors = 0 skipped = 0 global result_count parameters = request["params"] # Retrieve the clip features. clip_features = task_utils.get_parameter_value(parameters, "clip_features", "value") # Retrieve the coordinate system code. out_coordinate_system = int(task_utils.get_parameter_value(parameters, "output_projection", "code")) # Retrieve the output format, create mxd and output file name parameter values. out_format = task_utils.get_parameter_value(parameters, "output_format", "value") create_mxd = task_utils.get_parameter_value(parameters, "create_mxd", "value") output_file_name = task_utils.get_parameter_value(parameters, "output_file_name", "value") if not output_file_name: output_file_name = "clip_results" # Create the temporary workspace if clip_feature_class: out_workspace = os.path.join(request["folder"], "temp") if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Set the output coordinate system. if not out_coordinate_system == 0: # Same as Input out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr # Set the output workspace. status_writer.send_status(_("Setting the output workspace...")) if not out_format == "SHP": out_workspace = arcpy.CreateFileGDB_management(out_workspace, "output.gdb").getOutput(0) arcpy.env.workspace = out_workspace # Query the index for results in groups of 25. headers = {"x-access-token": task_utils.get_security_token(request["owner"])} result_count, response_index = task_utils.get_result_count(parameters) query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl # Get the Clip features by id. id = clip_features["id"] clip_query = "{0}{1}{2}".format( sys.argv[2].split("=")[1], "/select?&wt=json", "&fl=id,path:[absolute],[lyrFile],[geo]&q=id:{0}".format(id) ) clip_result = requests.get(clip_query, headers=headers) clipper = clip_result.json()["response"]["docs"][0] if "path" in clipper: clip_features = clipper["path"] elif "[lyrFile]" in clipper: clip_features = clipper["[lyrFile]"] elif "[geo]" in clipper: clip_features = arcpy.AsShape(clipper["[geo]"]).projectAs(arcpy.SpatialReference(4326)) else: bbox = clipper["bbox"].split() extent = arcpy.Extent(*bbox) pt_array = arcpy.Array([extent.lowerLeft, extent.upperLeft, extent.upperRight, extent.lowerRight]) clip_features = arcpy.Polygon(pt_array, 4326) query = "{0}{1}{2}".format(sys.argv[2].split("=")[1], "/select?&wt=json", fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, "") query += fq elif "ids" in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]["ids"]), task_utils.CHUNK_SIZE, "") else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, "") status_writer.send_percent(0.0, _("Starting to process..."), "clip_data") for group in groups: if fq: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers ) elif "ids" in parameters[response_index]: results = requests.get(query + "{0}&ids={1}".format(fl, ",".join(group)), headers=headers) else: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers ) # docs = eval(results.read().replace('false', 'False').replace('true', 'True').replace('null', 'None'))['response']['docs'] docs = results.json()["response"]["docs"] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]["response"]["docs"]) input_rows = collections.defaultdict(list) for doc in docs: if "path" not in doc: input_rows[doc["name"]].append(doc) if input_rows: result = clip_data(input_rows, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if input_items: result = clip_data(input_items, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _("No items to process. Check if items exist.")) return if arcpy.env.workspace.endswith(".gdb"): out_workspace = os.path.dirname(arcpy.env.workspace) if clipped > 0: try: if out_format == "MPK": mxd_template = os.path.join( os.path.dirname(os.path.dirname(__file__)), "supportfiles", "MapTemplate.mxd" ) mxd = task_utils.create_mxd(out_workspace, mxd_template, "output") status_writer.send_status(_("Packaging results...")) task_utils.create_mpk(out_workspace, mxd, files_to_package) shutil.move( os.path.join(out_workspace, "output.mpk"), os.path.join(os.path.dirname(out_workspace), "{0}.mpk".format(output_file_name)), ) elif out_format == "LPK": status_writer.send_status(_("Packaging results...")) task_utils.create_lpk(out_workspace, output_file_name, files_to_package) elif out_format == "KML": task_utils.convert_to_kml(os.path.join(out_workspace, "output.gdb")) arcpy.env.workspace = "" arcpy.RefreshCatalog(os.path.join(out_workspace, "output.gdb")) try: arcpy.Delete_management(os.path.join(out_workspace, "output.gdb")) except arcpy.ExecuteError: pass zip_file = task_utils.zip_data(out_workspace, "{0}.zip".format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) else: if create_mxd: mxd_template = os.path.join( os.path.dirname(os.path.dirname(__file__)), "supportfiles", "MapTemplate.mxd" ) task_utils.create_mxd(out_workspace, mxd_template, "output") zip_file = task_utils.zip_data(out_workspace, "{0}.zip".format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) except arcpy.ExecuteError as ee: status_writer.send_state(status.STAT_FAILED, _(ee)) sys.exit(1) else: status_writer.send_state(status.STAT_FAILED, _("No output created. Zero inputs were clipped.")) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state(status.STAT_WARNING, _("{0} results could not be processed").format(errors + skipped)) task_utils.report( os.path.join(request["folder"], "__report.json"), clipped, skipped, errors, errors_reasons, skipped_reasons )
def execute(request): """Clips selected search results using the clip geometry. :param request: json as a dict. """ clipped = 0 errors = 0 skipped = 0 global result_count parameters = request['params'] # Retrieve clip geometry. try: clip_area = task_utils.get_parameter_value(parameters, 'clip_geometry', 'wkt') if not clip_area: clip_area = 'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))' except KeyError: clip_area = 'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))' # Retrieve the coordinate system code. out_coordinate_system = int(task_utils.get_parameter_value(parameters, 'output_projection', 'code')) # Retrieve the output format, create mxd parameter and output file name values. out_format = task_utils.get_parameter_value(parameters, 'output_format', 'value') create_mxd = task_utils.get_parameter_value(parameters, 'create_mxd', 'value') output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'clip_results' # Create the temporary workspace if clip_feature_class: out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Set the output coordinate system. if not out_coordinate_system == 0: # Same as Input out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr # Create the clip polygon geometry object in WGS84 projection. gcs_sr = task_utils.get_spatial_reference(4326) gcs_clip_poly = task_utils.from_wkt(clip_area, gcs_sr) if not gcs_clip_poly.area > 0: gcs_clip_poly = task_utils.from_wkt('POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))', gcs_sr) # Set the output workspace. status_writer.send_status(_('Setting the output workspace...')) if not out_format == 'SHP': out_workspace = arcpy.CreateFileGDB_management(out_workspace, 'output.gdb').getOutput(0) arcpy.env.workspace = out_workspace # Query the index for results in groups of 25. headers = {'x-access-token': task_utils.get_security_token(request['owner'])} result_count, response_index = task_utils.get_result_count(parameters) query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') # Begin processing status_writer.send_percent(0.0, _('Starting to process...'), 'clip_data') for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) # docs = eval(results.read().replace('false', 'False').replace('true', 'True').replace('null', 'None'))['response']['docs'] docs = results.json()['response']['docs'] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) input_rows = collections.defaultdict(list) for doc in docs: if 'path' not in doc: input_rows[doc['name']].append(doc) if input_rows: result = clip_data(input_rows, out_workspace, out_coordinate_system, gcs_sr, gcs_clip_poly, out_format) clipped += result[0] errors += result[1] skipped += result[2] if input_items: result = clip_data(input_items, out_workspace, out_coordinate_system, gcs_sr, gcs_clip_poly, out_format) clipped += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _('No items to process. Check if items exist.')) return if arcpy.env.workspace.endswith('.gdb'): out_workspace = os.path.dirname(arcpy.env.workspace) if clipped > 0: try: if out_format == 'MPK': mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') mxd = task_utils.create_mxd(out_workspace, mxd_template, 'output') status_writer.send_status(_("Packaging results...")) task_utils.create_mpk(out_workspace, mxd, files_to_package) shutil.move(os.path.join(out_workspace, 'output.mpk'), os.path.join(os.path.dirname(out_workspace), '{0}.mpk'.format(output_file_name))) elif out_format == 'LPK': status_writer.send_status(_("Packaging results...")) task_utils.create_lpk(out_workspace,output_file_name, files_to_package) elif out_format == 'KML': task_utils.convert_to_kml(os.path.join(out_workspace, "output.gdb")) arcpy.env.workspace = '' try: arcpy.Delete_management(os.path.join(out_workspace, "output.gdb")) except arcpy.ExecuteError: pass zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) else: if create_mxd: mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') task_utils.create_mxd(out_workspace, mxd_template, 'output') zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) except arcpy.ExecuteError as ee: status_writer.send_state(status.STAT_FAILED, _(ee)) sys.exit(1) else: status_writer.send_state(status.STAT_FAILED, _('No output created. Zero inputs were clipped.')) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(errors + skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), clipped, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Exports search results a CSV, shapefile or XML document. :param request: json as a dict. """ chunk_size = task_utils.CHUNK_SIZE file_name = task_utils.get_parameter_value(request['params'], 'file_name', 'value') fields = task_utils.get_parameter_value(request['params'], 'fields', 'value') out_format = task_utils.get_parameter_value(request['params'], 'output_format', 'value') if not 'path' in fields and 'path:[absolute]' in fields: fields.append('path') if 'geo' in fields: i_geo = fields.index('geo') fields.remove('geo') fields.insert(i_geo, '[geo]') # Create the temporary workspace. task_folder = os.path.join(request['folder'], 'temp') if not os.path.exists(task_folder): os.makedirs(task_folder) headers = {'x-access-token': task_utils.get_security_token(request['owner'])} num_results, response_index = task_utils.get_result_count(request['params']) query = '{0}/select?&wt=json&fl={1}'.format(sys.argv[2].split('=')[1], ','.join(fields)) if 'query' in request['params'][response_index]: # Voyager Search Traditional UI for p in request['params']: if 'query' in p: request_qry = p['query'] break if 'voyager.list' in request_qry: query += '&voyager.list={0}'.format(request_qry['voyager.list']) # Replace spaces with %20 & remove \\ to avoid HTTP Error 400. if 'fq' in request_qry: try: query += '&fq={0}'.format(request_qry['fq'].replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['fq']: query += '&fq={0}'.format(qry).replace("\\", "").replace(' ', '%20') if 'q' in request_qry: try: query += '&q={0}'.format(request_qry['q'].replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['q']: query += '&q={0}'.format(qry).replace("\\", "").replace(' ', '%20') if 'place' in request_qry: try: query += '&place={0}'.format(request_qry['place'].replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['place']: query += '&place={0}'.format(qry).replace("\\", "").replace(' ', '%20') if 'place.op' in request_qry: query += '&place.op={0}'.format(request_qry['place.op']) query += '&rows={0}&start={1}' exported_cnt = 0. for i in xrange(0, num_results, chunk_size): req = urllib2.Request(query.replace('{0}', str(chunk_size)).replace('{1}', str(i)), headers=headers) for n in urllib2.urlopen(req): jobs = eval(n.replace('null', '"null"'))['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) exported_cnt += chunk_size if exported_cnt > num_results: status_writer.send_percent(100, 'exported: 100%', 'export_results') else: percent_done = exported_cnt / num_results status_writer.send_percent(percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') else: # Voyager Search Portal/Cart UI ids = [] for p in request['params']: if 'ids' in p: ids = p['ids'] break groups = task_utils.grouper(list(ids), chunk_size, '') i = 0 for group in groups: i += len([v for v in group if not v == '']) req = urllib2.Request(query + '&ids={0}'.format(','.join(group)), headers=headers) results = urllib2.urlopen(req) jobs = eval(results.read())['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) percent_done = float(i) / num_results status_writer.send_percent(percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') # Zip up outputs. if exported_count == 0: task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) else: task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) zip_file = task_utils.zip_data(task_folder, 'output.zip') shutil.move(zip_file, os.path.join(os.path.dirname(task_folder), os.path.basename(zip_file)))
def execute(request): """Converts each input dataset to kml (.kmz). :param request: json as a dict. """ converted = 0 skipped = 0 errors = 0 global result_count parameters = request['params'] out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Get the boundary box extent for input to KML tools. extent = '' try: try: ext = task_utils.get_parameter_value(parameters, 'processing_extent', 'wkt') if ext: sr = task_utils.get_spatial_reference("4326") extent = task_utils.from_wkt(ext, sr) except KeyError: ext = task_utils.get_parameter_value(parameters, 'processing_extent', 'feature') if ext: extent = arcpy.Describe(ext).extent except KeyError: pass # Get the output file name. output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'kml_results' result_count, response_index = task_utils.get_result_count(parameters) # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') # Begin processing status_writer.send_percent(0.0, _('Starting to process...'), 'convert_to_kml') headers = { 'x-access-token': task_utils.get_security_token(request['owner']) } for group in groups: if fq: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) docs = results.json()['response']['docs'] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items( parameters[response_index]['response']['docs']) input_rows = collections.defaultdict(list) for doc in docs: if 'path' not in doc: input_rows[doc['name']].append(doc) if input_rows: result = convert_to_kml(input_rows, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if input_items: result = convert_to_kml(input_items, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state( status.STAT_FAILED, _('No items to process. Check if items exist.')) return # Zip up kmz files if more than one. if converted > 1: status_writer.send_status("Converted: {}".format(converted)) zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move( zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) shutil.copy2( os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', '_thumb.png'), request['folder']) elif converted == 1: try: kml_file = glob.glob(os.path.join(out_workspace, '*.kmz'))[0] tmp_lyr = arcpy.KMLToLayer_conversion(kml_file, out_workspace, 'kml_layer') task_utils.make_thumbnail( tmp_lyr.getOutput(0), os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: pass shutil.move( kml_file, os.path.join(request['folder'], os.path.basename(kml_file))) # Update state if necessary. if skipped > 0 or errors > 0: status_writer.send_state( status.STAT_WARNING, _('{0} results could not be processed').format(errors + skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), converted, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Clips selected search results using the clip geometry. :param request: json as a dict. """ clipped = 0 errors = 0 skipped = 0 global result_count parameters = request['params'] # Retrieve the clip features. clip_features = task_utils.get_parameter_value(parameters, 'clip_features', 'value') # Retrieve the coordinate system code. out_coordinate_system = int(task_utils.get_parameter_value(parameters, 'output_projection', 'code')) # Retrieve the output format, create mxd and output file name parameter values. out_format = task_utils.get_parameter_value(parameters, 'output_format', 'value') create_mxd = task_utils.get_parameter_value(parameters, 'create_mxd', 'value') output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'clip_results' # Create the temporary workspace if clip_feature_class: out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Set the output coordinate system. if not out_coordinate_system == 0: # Same as Input out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr # Set the output workspace. status_writer.send_status(_('Setting the output workspace...')) if not out_format == 'SHP': out_workspace = arcpy.CreateFileGDB_management(out_workspace, 'output.gdb').getOutput(0) arcpy.env.workspace = out_workspace # Query the index for results in groups of 25. headers = {'x-access-token': task_utils.get_security_token(request['owner'])} result_count, response_index = task_utils.get_result_count(parameters) query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl # Get the Clip features by id. id = clip_features['id'] clip_query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', "&fl=id,path,fullpath:[absolute],absolute_path:[absolute],[lyrFile],[geo]&q=id:{0}".format(id)) clip_result = requests.get(clip_query, verify=verify_ssl, headers=headers) clipper = clip_result.json()['response']['docs'][0] if 'absolute_path' in clipper and not clipper['absolute_path'].startswith('s3'): clip_features = clipper['absolute_path'] elif '[lyrFile]' in clipper: clip_features = clipper['[lyrFile]'] elif '[geo]' in clipper: clip_features = arcpy.AsShape(clipper['[geo]']).projectAs(arcpy.SpatialReference(4326)) elif 'absolute_path' in clipper and clipper['absolute_path'].startswith('s3'): base_name = os.path.basename(clipper['path']) temp_folder = tempfile.mkdtemp() if '[downloadURL]' in clipper: download = os.path.join(temp_folder, os.path.basename(clipper['[downloadURL]'])) response = requests.get(clipper['[downloadURL]'], verify=verify_ssl) with open(download, 'wb') as fp: fp.write(response.content) if download.endswith('.zip'): zip = zipfile.ZipFile(download) zip.extractall(temp_folder) clip_features = os.path.join(temp_folder, base_name) else: clip_features = download else: bbox = clipper['bbox'].split() extent = arcpy.Extent(*bbox) pt_array = arcpy.Array([extent.lowerLeft, extent.upperLeft, extent.upperRight, extent.lowerRight]) clip_features = arcpy.Polygon(pt_array, 4326) query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') status_writer.send_percent(0.0, _('Starting to process...'), 'clip_data') for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), verify=verify_ssl, headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), verify=verify_ssl, headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), verify=verify_ssl, headers=headers) docs = results.json()['response']['docs'] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) input_rows = collections.defaultdict(list) for doc in docs: if 'path' not in doc: input_rows[doc['name']].append(doc) if input_rows: result = clip_data(input_rows, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if input_items: result = clip_data(input_items, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _('No items to process. Check if items exist.')) return if arcpy.env.workspace.endswith('.gdb'): out_workspace = os.path.dirname(arcpy.env.workspace) if clipped > 0: try: if out_format == 'MPK': mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') mxd = task_utils.create_mxd(out_workspace, mxd_template, 'output') status_writer.send_status(_("Packaging results...")) task_utils.create_mpk(out_workspace, mxd, files_to_package) shutil.move(os.path.join(out_workspace, 'output.mpk'), os.path.join(os.path.dirname(out_workspace), '{0}.mpk'.format(output_file_name))) elif out_format == 'LPK': status_writer.send_status(_("Packaging results...")) task_utils.create_lpk(out_workspace, output_file_name, files_to_package) elif out_format == 'KML': task_utils.convert_to_kml(os.path.join(out_workspace, "output.gdb")) arcpy.env.workspace = '' arcpy.RefreshCatalog(os.path.join(out_workspace, "output.gdb")) try: arcpy.Delete_management(os.path.join(out_workspace, "output.gdb")) except arcpy.ExecuteError: pass zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) else: if create_mxd: mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') task_utils.create_mxd(out_workspace, mxd_template, 'output') zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) except arcpy.ExecuteError as ee: status_writer.send_state(status.STAT_FAILED, _(ee)) sys.exit(1) else: status_writer.send_state(status.STAT_FAILED, _('No output created. Zero inputs were clipped.')) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(errors + skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), clipped, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Mosaics input raster datasets into a new raster dataset. :param request: json as a dict. """ parameters = request['params'] out_coordinate_system = task_utils.get_parameter_value(parameters, 'output_projection', 'code') # Advanced options output_raster_format = task_utils.get_parameter_value(parameters, 'raster_format', 'value') compression_method = task_utils.get_parameter_value(parameters, 'compression_method', 'value') compression_quality = task_utils.get_parameter_value(parameters, 'compression_quality', 'value') output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'output' arcpy.env.compression = '{0} {1}'.format(compression_method, compression_quality) clip_area = None if not output_raster_format == 'MosaicDataset': # Get the clip region as an extent object. try: clip_area_wkt = task_utils.get_parameter_value(parameters, 'processing_extent', 'wkt') if not clip_area_wkt: clip_area_wkt = 'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))' if not out_coordinate_system == '0': clip_area = task_utils.get_clip_region(clip_area_wkt, out_coordinate_system) else: clip_area = task_utils.get_clip_region(clip_area_wkt) except KeyError: pass status_writer.send_status(_('Setting the output workspace...')) out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) if output_raster_format == 'FileGDB' or output_raster_format == 'MosaicDataset': out_workspace = arcpy.CreateFileGDB_management(out_workspace, 'output.gdb').getOutput(0) arcpy.env.workspace = out_workspace status_writer.send_status(_('Starting to process...')) num_results, response_index = task_utils.get_result_count(parameters) raster_items = None if num_results > task_utils.CHUNK_SIZE: # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, num_results), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, num_results), task_utils.CHUNK_SIZE, '') headers = {'x-access-token': task_utils.get_security_token(request['owner'])} for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) input_items = task_utils.get_input_items(results.json()['response']['docs']) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) raster_items, pixels, bands, skipped = get_items(input_items) else: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) raster_items, pixels, bands, skipped = get_items(input_items) if not raster_items: if skipped == 0: status_writer.send_state(status.STAT_FAILED, _('Invalid input types')) skipped_reasons['All Items'] = _('Invalid input types') task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), num_results, skipped_details=skipped_reasons) return else: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), skipped, skipped_details=skipped_reasons) return # Get most common pixel type. pixel_type = pixel_types[max(set(pixels), key=pixels.count)] if output_raster_format in ('FileGDB', 'GRID', 'MosaicDataset'): output_name = arcpy.ValidateTableName('mosaic', out_workspace) else: output_name = '{0}.{1}'.format(arcpy.ValidateTableName('mosaic', out_workspace)[:9], output_raster_format.lower()) status_writer.send_status(output_name) if output_raster_format == 'MosaicDataset': try: status_writer.send_status(_('Generating {0}. Large input {1} will take longer to process.'.format('Mosaic', 'rasters'))) if out_coordinate_system == '0': out_coordinate_system = raster_items[0] else: out_coordinate_system = None mosaic_ds = arcpy.CreateMosaicDataset_management(out_workspace, output_name, out_coordinate_system, max(bands), pixel_type) arcpy.AddRastersToMosaicDataset_management(mosaic_ds, 'Raster Dataset', raster_items) arcpy.MakeMosaicLayer_management(mosaic_ds, 'mosaic_layer') layer_object = arcpy.mapping.Layer('mosaic_layer') task_utils.make_thumbnail(layer_object, os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: status_writer.send_state(status.STAT_FAILED, arcpy.GetMessages(2)) return else: try: if len(bands) > 1: status_writer.send_state(status.STAT_FAILED, _('Input rasters must have the same number of bands')) return status_writer.send_status(_('Generating {0}. Large input {1} will take longer to process.'.format('Mosaic', 'rasters'))) if out_coordinate_system == '0': out_coordinate_system = None if clip_area: ext = '{0} {1} {2} {3}'.format(clip_area.XMin, clip_area.YMin, clip_area.XMax, clip_area.YMax) tmp_mosaic = arcpy.MosaicToNewRaster_management( raster_items, out_workspace, 'tm', out_coordinate_system, pixel_type, number_of_bands=bands.keys()[0] ) status_writer.send_status(_('Clipping...')) out_mosaic = arcpy.Clip_management(tmp_mosaic, ext, output_name) arcpy.Delete_management(tmp_mosaic) else: out_mosaic = arcpy.MosaicToNewRaster_management(raster_items, out_workspace, output_name, out_coordinate_system, pixel_type, number_of_bands=bands.keys()[0]) arcpy.MakeRasterLayer_management(out_mosaic, 'mosaic_layer') layer_object = arcpy.mapping.Layer('mosaic_layer') task_utils.make_thumbnail(layer_object, os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: status_writer.send_state(status.STAT_FAILED, arcpy.GetMessages(2)) return if arcpy.env.workspace.endswith('.gdb'): out_workspace = os.path.dirname(arcpy.env.workspace) zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) # Update state if necessary. if skipped > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), skipped, skipped_details=skipped_reasons)
def execute(request): """Copies files to a target folder. :param request: json as a dict. """ extracted = 0 skipped = 0 errors = 0 global result_count parameters = request['params'] output_type = task_utils.get_parameter_value(parameters, 'output_format', 'value') task_folder = os.path.join(request['folder'], 'temp') if not os.path.exists(task_folder): os.makedirs(task_folder) if output_type == 'FGDB': arcpy.CreateFileGDB_management(task_folder, 'output.gdb') result_count, response_index = task_utils.get_result_count(parameters) # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) # query = '{0}{1}{2}'.format("http://localhost:8888/solr/v0", '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') headers = { 'x-access-token': task_utils.get_security_token(request['owner']) } status_writer.send_percent(0.0, _('Starting to process...'), 'locate_xt_arcgis_tool') for group in groups: if fq: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) docs = results.json()['response']['docs'] if not docs: docs = parameters[response_index]['response']['docs'] input_items = task_utils.get_input_items(docs) if input_items: result = extract(input_items, output_type, task_folder) extracted += result[0] errors += result[1] skipped += result[2] else: status_writer.send_state( status.STAT_FAILED, _('No items to process. Check if items exist.')) return # Zip up outputs. zip_file = task_utils.zip_data(task_folder, 'output.zip') shutil.move( zip_file, os.path.join(os.path.dirname(task_folder), os.path.basename(zip_file))) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state( status.STAT_WARNING, _('{0} results could not be processed').format(skipped + errors)) task_utils.report(os.path.join(request['folder'], '__report.json'), extracted, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Copies files to a target folder. :param request: json as a dict. """ extracted = 0 skipped = 0 errors = 0 global result_count parameters = request['params'] output_type = task_utils.get_parameter_value(parameters, 'output_format', 'value') task_folder = os.path.join(request['folder'], 'temp') if not os.path.exists(task_folder): os.makedirs(task_folder) if output_type == 'FGDB': arcpy.CreateFileGDB_management(task_folder, 'output.gdb') result_count, response_index = task_utils.get_result_count(parameters) # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) # query = '{0}{1}{2}'.format("http://localhost:8888/solr/v0", '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') headers = {'x-access-token': task_utils.get_security_token(request['owner'])} status_writer.send_percent(0.0, _('Starting to process...'), 'locate_xt_arcgis_tool') for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) docs = results.json()['response']['docs'] if not docs: docs = parameters[response_index]['response']['docs'] input_items = task_utils.get_input_items(docs) if input_items: result = extract(input_items, output_type, task_folder) extracted += result[0] errors += result[1] skipped += result[2] else: status_writer.send_state(status.STAT_FAILED, _('No items to process. Check if items exist.')) return # Zip up outputs. zip_file = task_utils.zip_data(task_folder, 'output.zip') shutil.move(zip_file, os.path.join(os.path.dirname(task_folder), os.path.basename(zip_file))) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(skipped + errors)) task_utils.report(os.path.join(request['folder'], '__report.json'), extracted, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Exports search results a CSV, shapefile or XML document. :param request: json as a dict. """ # Get SSL trust setting. verify_ssl = task_utils.get_ssl_mode() chunk_size = task_utils.CHUNK_SIZE file_name = task_utils.get_parameter_value(request['params'], 'file_name', 'value') fields = task_utils.get_parameter_value(request['params'], 'fields', 'value') out_format = task_utils.get_parameter_value(request['params'], 'output_format', 'value') if not 'path' in fields and 'path:[absolute]' in fields: fields.append('path') if 'geo' in fields: i_geo = fields.index('geo') fields.remove('geo') fields.insert(i_geo, '[geo]') # Create the temporary workspace. task_folder = os.path.join(request['folder'], 'temp') if not os.path.exists(task_folder): os.makedirs(task_folder) headers = { 'x-access-token': task_utils.get_security_token(request['owner']) } num_results, response_index = task_utils.get_result_count( request['params']) if len(sys.argv) == 2: query = '{0}/solr/v0/select?&wt=json&fl={1}'.format( 'http://localhost:8888', ','.join(fields)) else: query = '{0}/select?&wt=json&fl={1}'.format(sys.argv[2].split('=')[1], ','.join(fields)) if 'query' in request['params'][response_index]: # Voyager Search Traditional UI for p in request['params']: if 'query' in p: request_qry = p['query'] break if 'voyager.list' in request_qry: query += '&voyager.list={0}'.format(request_qry['voyager.list']) # Replace spaces with %20 & remove \\ to avoid HTTP Error 400. if 'fq' in request_qry: try: if isinstance(request_qry['fq'], list): for fq in request_qry['fq']: try: query += '&fq={0}'.format(str(fq)) except UnicodeEncodeError: query += '&fq={0}'.format(str(fq.encode('utf-8'))) else: query += '&fq={0}'.format(request_qry['fq']) if '{!expand}' in query: query = query.replace('{!expand}', '') if '{!tag' in query: tag = re.findall('{!(.*?)}', query) if tag: tag_str = "{!" + tag[0] + "}" query = query.replace(tag_str, '') query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['fq']: query += '&fq={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'q' in request_qry: try: query += '&q={0}'.format(request_qry['q'].replace("\\", "")) query = query.replace(' ', '%20') except UnicodeEncodeError: query += '&q={0}'.format( request_qry['q'].encode('utf-8').replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['q']: query += '&q={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'place' in request_qry: try: query += '&place={0}'.format(request_qry['place'].replace( "\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['place']: query += '&place={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'place.op' in request_qry: query += '&place.op={0}'.format(request_qry['place.op']) query += '&rows={0}&start={1}' exported_cnt = 0. for i in range(0, num_results, chunk_size): url = query.replace('{0}', str(chunk_size)).replace('{1}', str(i)) res = requests.get(url, verify=verify_ssl, headers=headers) jobs = res.json()['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) exported_cnt += chunk_size if exported_cnt > num_results: status_writer.send_percent(100, 'exported: 100%', 'export_results') else: percent_done = exported_cnt / num_results status_writer.send_percent( percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') else: # Voyager Search Portal/Cart UI ids = [] for p in request['params']: if 'ids' in p: ids = p['ids'] break groups = task_utils.grouper(list(ids), chunk_size, '') i = 0 for group in groups: i += len([v for v in group if not v == '']) results = requests.get(query + '&ids={0}'.format(','.join(group)), verify=verify_ssl, headers=headers) jobs = eval(results.text)['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) percent_done = float(i) / num_results status_writer.send_percent( percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') # Zip up outputs. if exported_count == 0: status_writer.send_state(status.STAT_FAILED) task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) else: task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) zip_file = task_utils.zip_data(task_folder, '{0}.zip'.format(file_name)) shutil.move( zip_file, os.path.join(os.path.dirname(task_folder), os.path.basename(zip_file)))
def execute(request): """Converts each input dataset to kml (.kmz). :param request: json as a dict. """ converted = 0 skipped = 0 errors = 0 global result_count parameters = request["params"] out_workspace = os.path.join(request["folder"], "temp") if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Get the boundary box extent for input to KML tools. extent = "" try: try: ext = task_utils.get_parameter_value(parameters, "processing_extent", "wkt") if ext: sr = task_utils.get_spatial_reference("4326") extent = task_utils.from_wkt(ext, sr) except KeyError: ext = task_utils.get_parameter_value(parameters, "processing_extent", "feature") if ext: extent = arcpy.Describe(ext).extent except KeyError: pass # Get the output file name. output_file_name = task_utils.get_parameter_value(parameters, "output_file_name", "value") if not output_file_name: output_file_name = "kml_results" result_count, response_index = task_utils.get_result_count(parameters) # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = "{0}{1}{2}".format(sys.argv[2].split("=")[1], "/select?&wt=json", fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, "") query += fq elif "ids" in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]["ids"]), task_utils.CHUNK_SIZE, "") else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, "") # Begin processing status_writer.send_percent(0.0, _("Starting to process..."), "convert_to_kml") headers = {"x-access-token": task_utils.get_security_token(request["owner"])} for group in groups: if fq: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers ) elif "ids" in parameters[response_index]: results = requests.get(query + "{0}&ids={1}".format(fl, ",".join(group)), headers=headers) else: results = requests.get( query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers ) docs = results.json()["response"]["docs"] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]["response"]["docs"]) input_rows = collections.defaultdict(list) for doc in docs: if "path" not in doc: input_rows[doc["name"]].append(doc) if input_rows: result = convert_to_kml(input_rows, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if input_items: result = convert_to_kml(input_items, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _("No items to process. Check if items exist.")) return # Zip up kmz files if more than one. if converted > 1: status_writer.send_status("Converted: {}".format(converted)) zip_file = task_utils.zip_data(out_workspace, "{0}.zip".format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) shutil.copy2( os.path.join(os.path.dirname(os.path.dirname(__file__)), "supportfiles", "_thumb.png"), request["folder"] ) elif converted == 1: try: kml_file = glob.glob(os.path.join(out_workspace, "*.kmz"))[0] tmp_lyr = arcpy.KMLToLayer_conversion(kml_file, out_workspace, "kml_layer") task_utils.make_thumbnail(tmp_lyr.getOutput(0), os.path.join(request["folder"], "_thumb.png")) except arcpy.ExecuteError: pass shutil.move(kml_file, os.path.join(request["folder"], os.path.basename(kml_file))) # Update state if necessary. if skipped > 0 or errors > 0: status_writer.send_state(status.STAT_WARNING, _("{0} results could not be processed").format(errors + skipped)) task_utils.report( os.path.join(request["folder"], "__report.json"), converted, skipped, errors, errors_reasons, skipped_reasons )
def execute(request): """Mosaics input raster datasets into a new raster dataset. :param request: json as a dict. """ parameters = request['params'] out_coordinate_system = task_utils.get_parameter_value( parameters, 'output_projection', 'code') # Advanced options output_raster_format = task_utils.get_parameter_value( parameters, 'raster_format', 'value') compression_method = task_utils.get_parameter_value( parameters, 'compression_method', 'value') compression_quality = task_utils.get_parameter_value( parameters, 'compression_quality', 'value') output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'output' arcpy.env.compression = '{0} {1}'.format(compression_method, compression_quality) clip_area = None if not output_raster_format == 'MosaicDataset': # Get the clip region as an extent object. try: clip_area_wkt = task_utils.get_parameter_value( parameters, 'processing_extent', 'wkt') if not clip_area_wkt: clip_area_wkt = 'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))' if not out_coordinate_system == '0': clip_area = task_utils.get_clip_region(clip_area_wkt, out_coordinate_system) else: clip_area = task_utils.get_clip_region(clip_area_wkt) except KeyError: pass status_writer.send_status(_('Setting the output workspace...')) out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) if output_raster_format == 'FileGDB' or output_raster_format == 'MosaicDataset': out_workspace = arcpy.CreateFileGDB_management( out_workspace, 'output.gdb').getOutput(0) arcpy.env.workspace = out_workspace status_writer.send_status(_('Starting to process...')) num_results, response_index = task_utils.get_result_count(parameters) raster_items = None if num_results > task_utils.CHUNK_SIZE: # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, num_results), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper( list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, num_results), task_utils.CHUNK_SIZE, '') headers = { 'x-access-token': task_utils.get_security_token(request['owner']) } for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format( task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get( query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format( task_utils.CHUNK_SIZE, group[0]), headers=headers) input_items = task_utils.get_input_items( results.json()['response']['docs']) if not input_items: input_items = task_utils.get_input_items( parameters[response_index]['response']['docs']) raster_items, pixels, bands, skipped = get_items(input_items) else: input_items = task_utils.get_input_items( parameters[response_index]['response']['docs']) raster_items, pixels, bands, skipped = get_items(input_items) if not raster_items: if skipped == 0: status_writer.send_state(status.STAT_FAILED, _('Invalid input types')) skipped_reasons['All Items'] = _('Invalid input types') task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), num_results, skipped_details=skipped_reasons) return else: status_writer.send_state( status.STAT_WARNING, _('{0} results could not be processed').format(skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), skipped, skipped_details=skipped_reasons) return # Get most common pixel type. pixel_type = pixel_types[max(set(pixels), key=pixels.count)] if output_raster_format in ('FileGDB', 'GRID', 'MosaicDataset'): output_name = arcpy.ValidateTableName('mosaic', out_workspace) else: output_name = '{0}.{1}'.format( arcpy.ValidateTableName('mosaic', out_workspace)[:9], output_raster_format.lower()) status_writer.send_status(output_name) if output_raster_format == 'MosaicDataset': try: status_writer.send_status( _('Generating {0}. Large input {1} will take longer to process.' .format('Mosaic', 'rasters'))) if out_coordinate_system == '0': out_coordinate_system = raster_items[0] else: out_coordinate_system = None mosaic_ds = arcpy.CreateMosaicDataset_management( out_workspace, output_name, out_coordinate_system, max(bands), pixel_type) arcpy.AddRastersToMosaicDataset_management(mosaic_ds, 'Raster Dataset', raster_items) arcpy.MakeMosaicLayer_management(mosaic_ds, 'mosaic_layer') layer_object = arcpy.mapping.Layer('mosaic_layer') task_utils.make_thumbnail( layer_object, os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: status_writer.send_state(status.STAT_FAILED, arcpy.GetMessages(2)) return else: try: if len(bands) > 1: status_writer.send_state( status.STAT_FAILED, _('Input rasters must have the same number of bands')) return status_writer.send_status( _('Generating {0}. Large input {1} will take longer to process.' .format('Mosaic', 'rasters'))) if out_coordinate_system == '0': out_coordinate_system = None if clip_area: ext = '{0} {1} {2} {3}'.format(clip_area.XMin, clip_area.YMin, clip_area.XMax, clip_area.YMax) tmp_mosaic = arcpy.MosaicToNewRaster_management( raster_items, out_workspace, 'tm', out_coordinate_system, pixel_type, number_of_bands=bands.keys()[0]) status_writer.send_status(_('Clipping...')) out_mosaic = arcpy.Clip_management(tmp_mosaic, ext, output_name) arcpy.Delete_management(tmp_mosaic) else: out_mosaic = arcpy.MosaicToNewRaster_management( raster_items, out_workspace, output_name, out_coordinate_system, pixel_type, number_of_bands=bands.keys()[0]) arcpy.MakeRasterLayer_management(out_mosaic, 'mosaic_layer') layer_object = arcpy.mapping.Layer('mosaic_layer') task_utils.make_thumbnail( layer_object, os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: status_writer.send_state(status.STAT_FAILED, arcpy.GetMessages(2)) return if arcpy.env.workspace.endswith('.gdb'): out_workspace = os.path.dirname(arcpy.env.workspace) zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move( zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) # Update state if necessary. if skipped > 0: status_writer.send_state( status.STAT_WARNING, _('{0} results could not be processed').format(skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), len(raster_items), skipped, skipped_details=skipped_reasons)
def execute(request): """Clips selected search results using the clip geometry. :param request: json as a dict. """ clipped = 0 errors = 0 skipped = 0 global result_count parameters = request['params'] # Retrieve the clip features. clip_features = task_utils.get_parameter_value(parameters, 'clip_features', 'value') # Retrieve the coordinate system code. out_coordinate_system = int(task_utils.get_parameter_value(parameters, 'output_projection', 'code')) # Retrieve the output format, create mxd and output file name parameter values. out_format = task_utils.get_parameter_value(parameters, 'output_format', 'value') create_mxd = task_utils.get_parameter_value(parameters, 'create_mxd', 'value') output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'clip_results' # Create the temporary workspace if clip_feature_class: out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Set the output coordinate system. if not out_coordinate_system == 0: # Same as Input out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr # Set the output workspace. status_writer.send_status(_('Setting the output workspace...')) if not out_format == 'SHP': out_workspace = arcpy.CreateFileGDB_management(out_workspace, 'output.gdb').getOutput(0) arcpy.env.workspace = out_workspace # Query the index for results in groups of 25. headers = {'x-access-token': task_utils.get_security_token(request['owner'])} result_count, response_index = task_utils.get_result_count(parameters) query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl # Get the Clip features by id. id = clip_features['id'] clip_query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', "&fl=id,path,fullpath:[absolute],absolute_path:[absolute],[lyrFile],[geo]&q=id:{0}".format(id)) clip_result = requests.get(clip_query, headers=headers) clipper = clip_result.json()['response']['docs'][0] if 'absolute_path' in clipper and not clipper['absolute_path'].startswith('s3'): clip_features = clipper['absolute_path'] elif '[lyrFile]' in clipper: clip_features = clipper['[lyrFile]'] elif '[geo]' in clipper: clip_features = arcpy.AsShape(clipper['[geo]']).projectAs(arcpy.SpatialReference(4326)) elif 'absolute_path' in clipper and clipper['absolute_path'].startswith('s3'): base_name = os.path.basename(clipper['path']) temp_folder = tempfile.mkdtemp() if '[downloadURL]' in clipper: download = os.path.join(temp_folder, os.path.basename(clipper['[downloadURL]'])) response = requests.get(clipper['[downloadURL]']) with open(download, 'wb') as fp: fp.write(response.content) if download.endswith('.zip'): zip = zipfile.ZipFile(download) zip.extractall(temp_folder) clip_features = os.path.join(temp_folder, base_name) else: clip_features = download else: bbox = clipper['bbox'].split() extent = arcpy.Extent(*bbox) pt_array = arcpy.Array([extent.lowerLeft, extent.upperLeft, extent.upperRight, extent.lowerRight]) clip_features = arcpy.Polygon(pt_array, 4326) query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') status_writer.send_percent(0.0, _('Starting to process...'), 'clip_data') for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) docs = results.json()['response']['docs'] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) input_rows = collections.defaultdict(list) for doc in docs: if 'path' not in doc: input_rows[doc['name']].append(doc) if input_rows: result = clip_data(input_rows, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if input_items: result = clip_data(input_items, out_workspace, clip_features, out_format) clipped += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _('No items to process. Check if items exist.')) return if arcpy.env.workspace.endswith('.gdb'): out_workspace = os.path.dirname(arcpy.env.workspace) if clipped > 0: try: if out_format == 'MPK': mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') mxd = task_utils.create_mxd(out_workspace, mxd_template, 'output') status_writer.send_status(_("Packaging results...")) task_utils.create_mpk(out_workspace, mxd, files_to_package) shutil.move(os.path.join(out_workspace, 'output.mpk'), os.path.join(os.path.dirname(out_workspace), '{0}.mpk'.format(output_file_name))) elif out_format == 'LPK': status_writer.send_status(_("Packaging results...")) task_utils.create_lpk(out_workspace, output_file_name, files_to_package) elif out_format == 'KML': task_utils.convert_to_kml(os.path.join(out_workspace, "output.gdb")) arcpy.env.workspace = '' arcpy.RefreshCatalog(os.path.join(out_workspace, "output.gdb")) try: arcpy.Delete_management(os.path.join(out_workspace, "output.gdb")) except arcpy.ExecuteError: pass zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) else: if create_mxd: mxd_template = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', 'MapTemplate.mxd') task_utils.create_mxd(out_workspace, mxd_template, 'output') zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) except arcpy.ExecuteError as ee: status_writer.send_state(status.STAT_FAILED, _(ee)) sys.exit(1) else: status_writer.send_state(status.STAT_FAILED, _('No output created. Zero inputs were clipped.')) # Update state if necessary. if errors > 0 or skipped > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(errors + skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), clipped, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Converts each input dataset to kml (.kmz). :param request: json as a dict. """ converted = 0 skipped = 0 errors = 0 global result_count parameters = request['params'] out_workspace = os.path.join(request['folder'], 'temp') if not os.path.exists(out_workspace): os.makedirs(out_workspace) # Get the boundary box extent for input to KML tools. extent = '' try: try: ext = task_utils.get_parameter_value(parameters, 'processing_extent', 'wkt') if ext: sr = task_utils.get_spatial_reference("4326") extent = task_utils.from_wkt(ext, sr) except KeyError: ext = task_utils.get_parameter_value(parameters, 'processing_extent', 'feature') if ext: extent = arcpy.Describe(ext).extent except KeyError: pass # Get the output file name. output_file_name = task_utils.get_parameter_value(parameters, 'output_file_name', 'value') if not output_file_name: output_file_name = 'kml_results' result_count, response_index = task_utils.get_result_count(parameters) # Query the index for results in groups of 25. query_index = task_utils.QueryIndex(parameters[response_index]) fl = query_index.fl query = '{0}{1}{2}'.format(sys.argv[2].split('=')[1], '/select?&wt=json', fl) fq = query_index.get_fq() if fq: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') query += fq elif 'ids' in parameters[response_index]: groups = task_utils.grouper(list(parameters[response_index]['ids']), task_utils.CHUNK_SIZE, '') else: groups = task_utils.grouper(range(0, result_count), task_utils.CHUNK_SIZE, '') # Begin processing status_writer.send_percent(0.0, _('Starting to process...'), 'convert_to_kml') headers = {'x-access-token': task_utils.get_security_token(request['owner'])} for group in groups: if fq: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) elif 'ids' in parameters[response_index]: results = requests.get(query + '{0}&ids={1}'.format(fl, ','.join(group)), headers=headers) else: results = requests.get(query + "&rows={0}&start={1}".format(task_utils.CHUNK_SIZE, group[0]), headers=headers) docs = results.json()['response']['docs'] input_items = task_utils.get_input_items(docs) if not input_items: input_items = task_utils.get_input_items(parameters[response_index]['response']['docs']) input_rows = collections.defaultdict(list) for doc in docs: if 'path' not in doc: input_rows[doc['name']].append(doc) if input_rows: result = convert_to_kml(input_rows, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if input_items: result = convert_to_kml(input_items, out_workspace, extent) converted += result[0] errors += result[1] skipped += result[2] if not input_items and not input_rows: status_writer.send_state(status.STAT_FAILED, _('No items to process. Check if items exist.')) return # Zip up kmz files if more than one. if converted > 1: status_writer.send_status("Converted: {}".format(converted)) zip_file = task_utils.zip_data(out_workspace, '{0}.zip'.format(output_file_name)) shutil.move(zip_file, os.path.join(os.path.dirname(out_workspace), os.path.basename(zip_file))) shutil.copy2(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'supportfiles', '_thumb.png'), request['folder']) elif converted == 1: try: kml_file = glob.glob(os.path.join(out_workspace, '*.kmz'))[0] tmp_lyr = arcpy.KMLToLayer_conversion(kml_file, out_workspace, 'kml_layer') task_utils.make_thumbnail(tmp_lyr.getOutput(0), os.path.join(request['folder'], '_thumb.png')) except arcpy.ExecuteError: pass shutil.move(kml_file, os.path.join(request['folder'], os.path.basename(kml_file))) # Update state if necessary. if skipped > 0 or errors > 0: status_writer.send_state(status.STAT_WARNING, _('{0} results could not be processed').format(errors + skipped)) task_utils.report(os.path.join(request['folder'], '__report.json'), converted, skipped, errors, errors_reasons, skipped_reasons)
def execute(request): """Exports search results a CSV, shapefile or XML document. :param request: json as a dict. """ chunk_size = task_utils.CHUNK_SIZE file_name = task_utils.get_parameter_value(request['params'], 'file_name', 'value') fields = task_utils.get_parameter_value(request['params'], 'fields', 'value') out_format = task_utils.get_parameter_value(request['params'], 'output_format', 'value') if not 'path' in fields and 'path:[absolute]' in fields: fields.append('path') if 'geo' in fields: i_geo = fields.index('geo') fields.remove('geo') fields.insert(i_geo, '[geo]') # Create the temporary workspace. task_folder = os.path.join(request['folder'], 'temp') if not os.path.exists(task_folder): os.makedirs(task_folder) headers = { 'x-access-token': task_utils.get_security_token(request['owner']) } num_results, response_index = task_utils.get_result_count( request['params']) query = '{0}/select?&wt=json&fl={1}'.format(sys.argv[2].split('=')[1], ','.join(fields)) if 'query' in request['params'][response_index]: # Voyager Search Traditional UI for p in request['params']: if 'query' in p: request_qry = p['query'] break if 'voyager.list' in request_qry: query += '&voyager.list={0}'.format(request_qry['voyager.list']) # Replace spaces with %20 & remove \\ to avoid HTTP Error 400. if 'fq' in request_qry: try: query += '&fq={0}'.format(request_qry['fq'].replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['fq']: query += '&fq={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'q' in request_qry: try: query += '&q={0}'.format(request_qry['q'].replace("\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['q']: query += '&q={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'place' in request_qry: try: query += '&place={0}'.format(request_qry['place'].replace( "\\", "")) query = query.replace(' ', '%20') except AttributeError: for qry in request_qry['place']: query += '&place={0}'.format(qry).replace("\\", "").replace( ' ', '%20') if 'place.op' in request_qry: query += '&place.op={0}'.format(request_qry['place.op']) query += '&rows={0}&start={1}' exported_cnt = 0. for i in xrange(0, num_results, chunk_size): req = urllib2.Request(query.replace('{0}', str(chunk_size)).replace( '{1}', str(i)), headers=headers) for n in urllib2.urlopen(req): jobs = eval(n.replace('null', '"null"'))['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) exported_cnt += chunk_size if exported_cnt > num_results: status_writer.send_percent(100, 'exported: 100%', 'export_results') else: percent_done = exported_cnt / num_results status_writer.send_percent( percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') else: # Voyager Search Portal/Cart UI ids = [] for p in request['params']: if 'ids' in p: ids = p['ids'] break groups = task_utils.grouper(list(ids), chunk_size, '') i = 0 for group in groups: i += len([v for v in group if not v == '']) req = urllib2.Request(query + '&ids={0}'.format(','.join(group)), headers=headers) results = urllib2.urlopen(req) jobs = eval(results.read())['response']['docs'] if out_format == 'CSV': export_to_csv(jobs, file_name, task_folder, fields) elif out_format == 'XML': export_to_xml(jobs, file_name, task_folder) elif out_format == 'SHP': export_to_shp(jobs, file_name, task_folder) percent_done = float(i) / num_results status_writer.send_percent( percent_done, '{0}: {1:.0f}%'.format("exported", percent_done * 100), 'export_results') # Zip up outputs. if exported_count == 0: task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) else: task_utils.report(os.path.join(request['folder'], '__report.json'), exported_count, 0, errors_count, errors_reasons) zip_file = task_utils.zip_data(task_folder, 'output.zip') shutil.move( zip_file, os.path.join(os.path.dirname(task_folder), os.path.basename(zip_file)))