python - 如果从 C# 控制台应用程序调用,则调用的 Arcpy 脚本不会完成
问题描述
早上好 StackOverflowers,
还有一个问题没有你的帮助我无法解决。我正在开发一个 C# 控制台应用程序 (.NET 5),它调用不同的 Python 脚本来执行 ArcGis 内容 (=> "arcpy"-Lib :)。打电话给他们的方案总是一样的,从来没有问题。在渗透测试过程中,我发现其中一个脚本存在问题:
以下脚本“搜索”要素类中的每一行,放大到它并将其导出为 .png 文件。
通过 cmd (Non Admin & Admin) 或 Python Gui (ArcGis Setup 可用) 执行此操作,它可以完美运行 (=> 创建 138 个图像),但如果我通过 C# App 执行它,它只会创建 36 个图像,之后进程继续运行但不创建图像。创建第 36 个图像后,CPU 使用率从 12% 下降到 0%。
第二个代码片段显示了被调用的方法,但也描述了调用我的 python 脚本的方案。我非常清楚这写得不好,我将在解决这个问题后做一些代码润色:)
我希望有人在那里提供小费。
非常感谢您提前。亲切的问候,简
import arcpy,os, logging
logging.basicConfig(filename='appPython.log', format='%(asctime)s - %(message)s', level=logging.INFO)
#Static Variables
mxdfileName = "D:\DigitalesFahrtenbuch_Datenpunkte\Templates\TemplateTelematik.mxd"
# Set the workspace for ListFeatureClasses
arcpy.env.workspace = str(sys.argv[1])
#arcpy.env.workspace = r"D:\DigitalesFahrtenbuch_Datenpunkte\DigFahrtenbuch_Datenpunkte.gdb"
featureclasses = arcpy.ListFeatureClasses()
try:
# Copy shapefiles to a file geodatabase
for fc in featureclasses:
featureName = os.path.splitext(fc)[0]
if "Dienstverrichtung_" in featureName and "_Projection" in featureName:
print(featureName)
#Global Variables
mxd = arcpy.mapping.MapDocument(mxdfileName)
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
#Create FeatureLayer
SelectionLayer = arcpy.management.MakeFeatureLayer(fc, "SelectionLayer").getOutput(0)
#Add Layer to mxd
arcpy.mapping.AddLayer(df, SelectionLayer, "TOP")
#Refresh TOC and DataFrames
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
#Refresh TOC and DataFrames
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
feature = arcpy.mapping.ListLayers(mxd, SelectionLayer, df)[0]
fields = ['OID@', 'SHAPE@', 'Name']
pngPath = r"D:\DigitalesFahrtenbuch_Datenpunkte\Images"
with arcpy.da.SearchCursor(feature, fields) as cursor:
for FID, Geometry, Name in cursor:
mxd.title = Name
print("{} in Bearbeitung.".format(mxd.title))
query = "ObjectID = {}".format(str(FID))
arcpy.management.SelectLayerByAttribute(feature, "NEW_SELECTION", query)
df.zoomToSelectedFeatures()
df.scale=2500
df.referenceScale = 3500
arcpy.RefreshActiveView()
png = "{}\\{}.png".format(pngPath, Name)
arcpy.mapping.ExportToPNG(mxd, png, df, df_export_width=2200, df_export_height=1300)
print("{} erfolgreich exportiert.".format(mxd.title))
print("Script beendet")
except Exception as e:
logging.error("Exception occurred", exc_info = True)
public static async Task<Tuple<string, bool>> ZoomToSelectedFeatures(string pPathToPythonExe, string pPathGeoDatabase)
{
Tuple<string, bool> resultTuple = null;
StringBuilder scriptMessageBuilder = new StringBuilder();
string scriptExceptions = string.Empty;
string scriptPrints = string.Empty;
string pythonPath = @"C:/Python27/ArcGIS10.8/python.exe";
try
{
await Task.Run(delegate
{
if (pPathToPythonExe != "")
{
pythonPath = pPathToPythonExe;
}
ProcessStartInfo start = new ProcessStartInfo();
//python interprater location
start.FileName = pythonPath;
//argument with file name and input parameters
start.Arguments =
$"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Python_Scripts\\Batch_ZoomToSelectedFeaturesAndExportPNG_2.py")}" +
$" {pPathGeoDatabase}";
start.UseShellExecute = false; // Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true; // Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
start.LoadUserProfile = true;
using (Process process = Process.Start(start))
{
process.WaitForExit();
using (StreamReader reader = process.StandardOutput)
{
scriptExceptions = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
scriptPrints = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
Debug.WriteLine("Batch_ZoomToSelectedFeaturesAndExportPNG_2.py meldet:");
Debug.WriteLine(scriptPrints);
Debug.WriteLine(scriptExceptions);
scriptMessageBuilder.AppendLine(scriptPrints);
scriptMessageBuilder.AppendLine(scriptExceptions);
}
}
resultTuple = new Tuple<string, bool>(scriptMessageBuilder.ToString(), true);
});
}
catch (Exception e)
{
Debug.WriteLine(e);
Debug.WriteLine(scriptExceptions);
resultTuple = new Tuple<string, bool>(scriptMessageBuilder.ToString(), false);
}
return resultTuple;
}
解决方案
我通过将输出从“打印消息”更改为“日志条目”来解决它。现在....老实说,我不知道为什么,该脚本正确地创建了所有图像。在编辑后的脚本下方。
无论如何,谢谢,祝你有美好的一天!
import arcpy,os,logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # process everything, even if everything isn't printed
fh = logging.FileHandler('D:\\appPython.log')
fh.setLevel(logging.DEBUG) # or any level you want
logger.addHandler(fh)
#Define Variables
#Static Variables
mxdfileName = "D:\DigitalesFahrtenbuch_Datenpunkte\Templates\TemplateTelematik.mxd"
# Set the workspace for ListFeatureClasses
arcpy.env.workspace = str(sys.argv[1])
#arcpy.env.workspace = r"D:\DigitalesFahrtenbuch_Datenpunkte\DigFahrtenbuch_Datenpunkte.gdb"
# Use the ListFeatureClasses function to return a list of
# shapefiles.
featureclasses = arcpy.ListFeatureClasses()
try:
# Copy shapefiles to a file geodatabase
for fc in featureclasses:
featureName = os.path.splitext(fc)[0]
if "Dienstverrichtung_" in featureName and "_Projection" in featureName:
logger.info(featureName)
#Global Variables
mxd = arcpy.mapping.MapDocument(mxdfileName)
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
#Create FeatureLayer
SelectionLayer = arcpy.management.MakeFeatureLayer(fc, "SelectionLayer").getOutput(0)
#Add Layer to mxd
arcpy.mapping.AddLayer(df, SelectionLayer, "TOP")
#Refresh TOC and DataFrames
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
#Refresh TOC and DataFrames
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
df = arcpy.mapping.ListDataFrames(mxd,"*")[0]
feature = arcpy.mapping.ListLayers(mxd, SelectionLayer, df)[0]
fields = ['OID@', 'SHAPE@', 'Name']
pngPath = r"D:\DigitalesFahrtenbuch_Datenpunkte\Images"
with arcpy.da.SearchCursor(feature, fields) as cursor:
for FID, Geometry, Name in cursor:
mxd.title = Name
#print("{} in Bearbeitung.".format(mxd.title))
logger.info("{} in Bearbeitung.".format(mxd.title))
query = "ObjectID = {}".format(str(FID))
arcpy.management.SelectLayerByAttribute(feature, "NEW_SELECTION", query)
df.zoomToSelectedFeatures()
df.scale=2500
df.referenceScale = 3500
arcpy.RefreshActiveView()
png = "{}\\{}.png".format(pngPath, Name)
arcpy.mapping.ExportToPNG(mxd, png, df, df_export_width=2200, df_export_height=1300)
logger.info("{} erfolgreich exportiert.".format(mxd.title))
#print("{} erfolgreich exportiert.".format(mxd.title))
logger.info("Script beendet")
except Exception as e:
logger.error(e)
推荐阅读
- html - 下拉式菜单; hover css 不适用于兄弟成员,但适用于后代成员
- html - Django 控制台消息:GET /%7B HTTP/1.1
- sql - 将一个表中的值分配给另一个表
- python - 如何通过多个页面申请循环并将每个页面添加到 csv 文件
- c# - 允许依赖于 AttributeUsage 的 Attribute 构造函数
- python - 如何在不更改尺寸的情况下减小 PNG 图像的文件大小?
- python - 将 np 矩阵及其索引转换为两个列表
- python - 如何将 static_test 运行到多个 python 文件?
- tensorflow - 如何在张量流模型内转换后打印特征值
- scala - 如何在scala中编程一个适合的圆