import win32com.client
import pythoncom
from tkinter import filedialog, messagebox
import math
import operator
import numpy
from os import system
def list_change(old_list, step=4, stop=None):
new_list = [old_list[x:x + step][:stop] for x in range(0, len(old_list), step)]
return new_list
def azimuth(x1, y1, x2, y2):
angle = 0
dx = x2 - x1
dy = y2 - y1
if dx == 0 and dy > 0:
angle = 0
if dx == 0 and dy < 0:
angle = 180
if dy == 0 and dx > 0:
angle = 90
if dy == 0 and dx < 0:
angle = 270
if dx > 0 and dy > 0:
angle = math.atan(dx / dy) * 180 / math.pi
elif dx < 0 and dy > 0:
angle = 360 + math.atan(dx / dy) * 180 / math.pi
elif dx < 0 and dy < 0:
angle = 180 + math.atan(dx / dy) * 180 / math.pi
elif dx > 0 and dy < 0:
angle = 180 + math.atan(dx / dy) * 180 / math.pi
return math.radians(angle)
def calculationAngle(list1):
angleList = []
for zuobiao in list1:
weizhi = list1.index(zuobiao)
if weizhi != len(list1) - 1:
xiaYiGeZuoBiao = list1[weizhi + 1]
angle = azimuth(zuobiao[0], zuobiao[1], xiaYiGeZuoBiao[0], xiaYiGeZuoBiao[1])
angleList.append([zuobiao, xiaYiGeZuoBiao, angle])
return angleList
def vtpnt(x, y, z=0):
"""坐标点转化为浮点数"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
def vtobj(obj):
"""转化为对象数组"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)
def vtFloat(list):
"""列表转化为浮点数"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)
def vtInt(list):
"""列表转化为整数"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)
def vtVariant(list):
"""列表转化为变体"""
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)
def distance(point1, point2):
d = math.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)
return d
def pointInLine(point1, point2, pointQ):
x1, y1 = point1
x2, y2 = point2
xQ, yQ = pointQ
maxX = max(x1, x2)
maxY = max(y1, y2)
minX = min(x1, x2)
minY = min(y1, y2)
if (abs(((xQ - x1) * (y2 - y1) - (x2 - x1) * (yQ - y1))) < 0.00001) and (xQ >= minX and xQ <= maxX) and (
yQ >= minY and yQ <= maxY):
return True
else:
return False
def rrd(point, f):
if type(point) == str:
return point
if f == 0:
point = str(int(point))
elif f > 0:
SP = str(numpy.around(point, f))
sy = SP.split(".")
n = len(sy[1])
if n < f:
sj = f - n
point = sy[0] + "." + sy[1] + "0" * sj
else:
point = SP
elif f < 0:
messagebox.showinfo("tip", "取位不可为负数!")
return point
def kilometerPile(pile):
s = divmod(pile, 1000)
Pile = "K" + rrd(s[0], 0) + "+" + rrd(s[1], 3)
return Pile
acad = win32com.client.Dispatch("AutoCAD.Application")
doc = acad.ActiveDocument
doc.Utility.Prompt("\n醉后不知天在水\n满船清梦压星河\n")
mp = doc.ModelSpace
messagebox.showinfo('提示', "请在屏幕拾取图元,以Enter键结束")
try:
doc.SelectionSets.Item("SS1").Delete()
except:
messagebox.showinfo('警告', "Delete selection failed")
slt = doc.SelectionSets.Add("SS1")
slt.SelectOnScreen()
def obLine(list1):
x1, y1 = list1[0]
point_1 = vtpnt(x1, y1)
x2, y2 = list1[1]
point_2 = vtpnt(x2, y2)
lineObj = mp.AddLine(point_1, point_2)
return lineObj
zdmCoordinates = []
hdmCoordinates = []
gcdBlock = []
for Select in slt:
if Select.ObjectName == "AcDbBlockReference":
if Select.Layer == "GCD":
gcdBlock.append(Select)
if Select.ObjectName == "AcDbPolyline":
if Select.Layer == "zdm":
oldZdm = Select.Coordinates
newZdm = list_change(oldZdm, 2)
zdmCoordinates = calculationAngle(newZdm)
if Select.Layer == "hdm":
oldHdm = Select.Coordinates
newHdm = list_change(oldHdm, 2)
hdmCoordAngels = calculationAngle(newHdm)
hdmCoordinates += hdmCoordAngels
hdmToZdmIntersectCoord = []
dZdm = 0
rawData = dict()
for zdmLineCoordinates in zdmCoordinates:
dZdm += distance(zdmLineCoordinates[0], zdmLineCoordinates[1])
line1 = obLine(zdmLineCoordinates)
for hdmLineCoordinates in hdmCoordinates:
line2 = obLine(hdmLineCoordinates)
i = line1.IntersectWith(line2, 0)
if i != ():
d = distance(zdmLineCoordinates[1], i)
inPointDist = dZdm - d
gcdToHdmIntersectCoord = dict()
for gcd in gcdBlock:
gcdCoord = gcd.InsertionPoint
rawData.update({gcdCoord: ""})
startGcdInsHdmLine = pointInLine(hdmLineCoordinates[0], i[:-1], gcdCoord[:-1])
if startGcdInsHdmLine:
gcdInLineDist = distance(gcdCoord, i)
gcdToHdmIntersectCoord.update({gcdCoord: -gcdInLineDist})
endGcdInsHdmLine = pointInLine(i[:-1], hdmLineCoordinates[1], gcdCoord[:-1])
if endGcdInsHdmLine:
gcdInLineDist = distance(gcdCoord, i)
gcdToHdmIntersectCoord.update({gcdCoord: gcdInLineDist})
hdmToZdmIntersectCoord.append([inPointDist, i, hdmLineCoordinates, gcdToHdmIntersectCoord])
hdmToZdmIntersectCoord.sort(key=operator.itemgetter(0))
n = 0
gcdCount = 0
with open("横断面.txt", "w") as f:
for result in hdmToZdmIntersectCoord:
gcdCoordDist = sorted(result[3].items(), key=lambda x: x[1], reverse=False)
begin = ",".join(["BEGIN", rrd(result[0], 3) + ":" + str(n) + "\n"])
f.writelines(begin)
for val in gcdCoordDist:
del rawData[val[0]]
writeGcdLine = ",".join([rrd(val[1], 3), rrd(val[0][-1], 3) + "\n"])
f.writelines(writeGcdLine)
n += 1
f.close()
if len(rawData) != 0:
with open("错误高程点.txt", "w") as log:
diffentF = ["X", "\t", "Y", "\t", "Z" + "\n"]
log.writelines(diffentF)
for diffent in rawData.items():
diffentT = "\t".join([rrd(x, 3) for x in diffent[0]])
log.writelines(diffentT)
log.write("\n")
log.close()
messagebox.showinfo("tip", "部分高程未被提取,请检查错误数据!")
system("start 错误高程点.txt")
else:
messagebox.showinfo("tip", "提取完成!")
system("start 横断面.txt")
|