from pyautocad import Autocad, APoint, aDouble import shapefile from shapefile import Reader def takeSec(elem): return elem[1] def fill3(str1): if len(str1) == 5: str2 = str1 elif len(str1) == 4: str2 = '0' + str1 elif len(str1) == 3: str2 = '00' + str1 else: str2 = '000' + str1 return str2 def start(): dmdpath = r'D:\4work_now\20241017dm\20241129\hltdm3\dmd.shp' dmxpath = r'D:\4work_now\20241017dm\20241129\hltdm3\dmx.shp' mbpath = r'D:\4work_now\20241017dm\20241129\hltdm3\mb.dwg' #要手动建 outpath = r'D:\4work_now\20241017dm\20241129\hltdm3\HLT.dwg' txtpath = r'D:\4work_now\20241017dm\20241129\hltdm3\log.txt' #读取shapefile #线用来索引 max1 = 0 dmxdict = dict() with Reader(dmdpath) as dmd: dmdrec = dmd.records() with Reader(dmxpath) as dmx: dmxrec = dmx.records() for dmxr in dmxrec: knum = dmxr.KZ kzh = dmxr.ZH try: zzh = kzh.split('.',-1)[0] except: zzh = kzh if knum > max1: max1 = knum list1 = [] #记录要删除的index,统一删 index1 = [] id = 0 for dmdr in dmdrec: dzh = dmdr.ZH if dzh == kzh: lista = [] #这里就计算累距 lj1 = dmdr.LJ * dmdr.SFR lista.append(dmdr.height) lista.append(lj1) lista.append(dmdr.SFL) list1.append(lista) index1.append(id) id = id + 1 # #因为会有区别,所以要用个值 # zz = 0 # for ind in index1: # num0 = ind - zz # dmdrec.pop(num0) # zz = zz + 1 dmxdict[zzh] = list1 kk = max1 #链接cad acad = Autocad(create_if_not_exists=True) acad.Application.Documents.Open(outpath) target_doc = acad.ActiveDocument if kk > 20: #要那个大框的 num1 = kk // 20 nn = 0 while nn <= num1: yy = 0 if nn == num1: max2 = kk num2 = kk % 20 min2 = max2 - num2 numa1 = (nn*4200) + 10 numa2 = ((nn+1) * 4200) + 120 numa3 = (num2 * 200) + 270 jx1 = [numa1,-10,0] jx2 = [numa2,-10,0] jx3 = [numa2,numa3,0] jx4 = [numa1,numa3,0] line1 = jx1 + jx2 + jx3 + jx4 + jx1 pnts1 = aDouble(line1) plineObj1 = acad.model.AddPolyLine(pnts1) #文字 stra1 = 'K' + str(min2) +'+000 - K' + str(max2) + '+950' numa5 = (numa1 + numa2) / 2 numa6 = (num2 * 200) + 210 p1 = APoint(numa5,numa6) text1 = acad.model.AddText(stra1,p1,30) text1.Color = 1 else: max2 = 19 + (nn * 20) min2 = nn * 20 numa1 = (nn*4200) + 10 numa2 = ((nn+1) * 4200) +120 numa3 = 4070 jx1 = [numa1,-10,0] jx2 = [numa2,-10,0] jx3 = [numa2,numa3,0] jx4 = [numa1,numa3,0] line1 = jx1 + jx2 + jx3 + jx4 + jx1 pnts1 = aDouble(line1) plineObj1 = acad.model.AddPolyLine(pnts1) #文字 stra1 = 'K' + str(min2) +'+000 - K' + str(max2) + '+950' numa5 = (numa1 + numa2) / 2 numa6 = 4010 p1 = APoint(numa5,numa6) text1 = acad.model.AddText(stra1,p1,30) text1.Color = 1 mm = max2 x0 = (nn * 4220) + 300 while mm >= min2: xx = x0 jj = 0 jj1 = 0 while jj < 1000: zhA = 'K' + str(mm) + '+' + str(str(jj).zfill(3)) key1 = dmxdict.get(zhA, 'none') if key1 == 'none': # pass xx = xx + 210 else: if len(key1) == 0: dmxdict.pop(zhA,'nonevalue') xx = xx + 210 else: list2 = key1 list2.sort(key=takeSec) slj = 0 list3 = [] for li4 in list2: if li4[1] == list2[0][1]: slj = li4[1] xs = 1 listb1 = [] listb1.append(li4[0]) listb1.append(li4[1]) listb1.append(xs) listb1.append(li4[2]) list3.append(listb1) else: listb1 = [] #区分下正负交替的部分 if slj < 0 and li4[1] >=0: dis = 5 slj = li4[1] else: dis = abs(abs(slj) - abs(li4[1])) if dis >= 3: xs = 1 slj = li4[1] else: xs = -1 listb1.append(li4[0]) listb1.append(li4[1]) listb1.append(xs) listb1.append(li4[2]) list3.append(listb1) #只对模板进行开关 acad.Application.Documents.Open(mbpath) doc = acad.ActiveDocument #先写,再移动 text1 = list(acad.iter_objects("Text")) #防止重复 k1 = 1 k2 = 1 minnum = 0 pd1 = -1 if abs(list3[0][1])>=28.7 or abs(list3[len(list3)-1][1])>=28.7: pd1 = 1 for t2 in text1: if 'K' in t2.TextString: #最下面那个桩号 t2.TextString = zhA if '+' in t2.TextString and 'K' not in t2.TextString: if k1 == -1: pass else: for li1 in list3: if li1[2] == -1: pass else: #找到相对位置进行位移并赋值 if li1[1] == list3[0][1]: if pd1 ==1: #就以那个为起点 num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 t2.TextString = str2 else: # jl1 = abs(abs(li1[1]) - 28.7) # center = APoint(0,0,0) # pt = APoint(jl1,0,0) # t2.move(center,pt) num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 t2.TextString = str2 minnum = abs(li1[1]) else: #复制 copy = t2.Copy() #移动 jl1 = minnum + li1[1] center = APoint(0,0,0) pt = APoint(jl1,0,0) copy.move(center,pt) #重新赋值 if li1[1] < 0: num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 else: try: num4 = str(format(li1[1], '.1f')).replace('-','') except: num4 = str(format(li1[1], '.1f')) str5 = fill3(num4) str2 = '0+' + str5 copy.TextString = str2 k1 = -1 if '.' in t2.TextString and '+' not in t2.TextString: if k2 == -1: pass else: for li1 in list3: if li1[2] == -1: pass else: #找到相对位置进行位移并赋值 if li1[1] == list3[0][1]: if pd1 == 1: #就以那个为起点 str2 = str(format(li1[0], '.1f')) t2.TextString = str2 else: # jl1 = abs(abs(li1[1]) - 28.7) # center = APoint(0,0,0) # pt = APoint(jl1,0,0) # t2.move(center,pt) str2 = str(format(li1[0], '.1f')) t2.TextString = str2 else: #复制 copy = t2.Copy() #移动 jl1 = minnum + li1[1] center = APoint(0,0,0) pt = APoint(jl1,0,0) copy.move(center,pt) #重新赋值 str2 = str(format(li1[0], '.1f')) copy.TextString = str2 k2 = -1 print('B') #设置一条二位多段线line line1 = [] road = -1 mn = 0 for li3 in list3: hh = li3[0] #----------------------------------------------------------------------------------------------------------------------- gc = abs(410 - hh) #----------------------------------------------------------------------------------------------------------------------- # gc = abs(670 - hh) lj4 = minnum + li3[1] lj5 = 0 # if pd1 == 1: # zbx = 91.6 + lj4 # else: # lj5 = abs(abs(li3[1]) - 28.7) # zbx = 91.6 + lj4+lj5 zbx = 91.6 + lj4 zby = gc + 56.7 pt1 = [zbx,zby,0] line1 = line1 + pt1 if li3[2] ==-1: #那个竖线 ptA = APoint(zbx,zby) ptB = APoint(zbx,57) # ptB = APoint(zbx,(yy+25+37)) lnobj2 = acad.model.AddLine(ptA,ptB) #这个要调一下 lnobj2.Color = 3 else: #那个竖线 ptA = APoint(zbx,zby) ptB = APoint(zbx,22) # ptB = APoint(zbx,(yy+27)) lnobj2 = acad.model.AddLine(ptA,ptB) #这个要调一下 lnobj2.Color = 3 #单独看下需要写出路的部分 try: if li3[3] == 1 and list3[mn+1][3] == 1 and abs(list3[mn+1][0] -li3[0]) <1: if road == -1: # str6 = '水泥路' # text3 = acad.model.AddText(str6,ptA,1) # text3.Color = 1 text3 = list(acad.iter_objects("Text")) for t3 in text3: if '路' in t3.TextString: center = APoint(0,0) numb1 = 91.5+lj4 # if pd1 == 1: # numb1 = 91.5+lj4 # else: # numb1 = 91.5 + lj4+lj5 numb2 = 58+gc pt3 = APoint(numb1,numb2) t3.move(center,pt3) road = 1 except: pass mn = mn + 1 if road == -1: #删除标注 text3 = list(acad.iter_objects("Text")) for t3 in text3: if '路' in t3.TextString: t3.Delete() #把线绘制出来 pnts = aDouble(line1) try: plineObj = acad.model.AddPolyLine(pnts) except: with open(txtpath,'a+')as line1: line1.write(zhA) line1.flush() print('C') handle_string = 'select' text1 = list(acad.iter_objects(["Text", "Line","Circle"])) for t1 in text1: handle_string += ' (handent "'+t1.Handle+'")' #命令 handle_string += '\n\n' doc.SendCommand(handle_string) #移动的距离 str1 = 'move\n0,0,0\n' + str(xx) + ','+ str(yy) + ',0\n' #移动 # doc.SendCommand('move\n-80,-140,0\n760,-140,0\n') doc.SendCommand(str1) #再次选择 doc.SendCommand(handle_string) doc.SendCommand('copybase\n0,0,0\n') # target_doc.SendCommand('PASTEORIG\n') target_doc.SendCommand('PASTEORIG\n') #过程的不保存(删除所有要素) doc.Close(False) print(zhA + 'Finish') xx = xx + 210 dmxdict.pop(zhA,'nonevalue') jj = jj + 50 mm = mm - 1 yy =yy + 200 nn = nn + 1 else: yy = 0 while kk >= 0: xx = 0 jj = 0 while jj < 1000: zhA = 'K' + str(kk) + '+' + str(str(jj).zfill(3)) key1 = dmxdict.get(zhA, 'none') if key1 == 'none': # xx = xx + 210 pass else: if len(key1) == 0: dmxdict.pop(zhA,'nonevalue') xx = xx + 210 else: list2 = key1 list2.sort(key=takeSec) slj = 0 list3 = [] for li4 in list2: if li4[1] == list2[0][1]: slj = li4[1] xs = 1 listb1 = [] listb1.append(li4[0]) listb1.append(li4[1]) listb1.append(xs) listb1.append(li4[2]) list3.append(listb1) else: listb1 = [] #区分下正负交替的部分 if slj < 0 and li4[1] >=0: dis = 5 slj = li4[1] else: dis = abs(abs(slj) - abs(li4[1])) if dis >= 3: xs = 1 slj = li4[1] else: xs = -1 listb1.append(li4[0]) listb1.append(li4[1]) listb1.append(xs) listb1.append(li4[2]) list3.append(listb1) #只对模板进行开关 acad.Application.Documents.Open(mbpath) doc = acad.ActiveDocument #先写,再移动 text1 = list(acad.iter_objects("Text")) #防止重复 k1 = 1 k2 = 1 minnum = 0 pd1 = -1 if abs(list3[0][1])>=28.7 or abs(list3[len(list3)-1][1])>=28.7: pd1 = 1 for t2 in text1: if 'K' in t2.TextString: #最下面那个桩号 t2.TextString = zhA if '+' in t2.TextString and 'K' not in t2.TextString: if k1 == -1: pass else: for li1 in list3: if li1[2] == -1: pass else: #找到相对位置进行位移并赋值 if li1[1] == list3[0][1]: if pd1 ==1: #就以那个为起点 num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 t2.TextString = str2 else: jl1 = abs(abs(li1[1]) - 28.7) center = APoint(0,0,0) pt = APoint(jl1,0,0) t2.move(center,pt) num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 t2.TextString = str2 minnum = abs(li1[1]) else: #复制 copy = t2.Copy() #移动 jl1 = minnum + li1[1] center = APoint(0,0,0) pt = APoint(jl1,0,0) copy.move(center,pt) #重新赋值 if li1[1] < 0: num4 = str(format(li1[1], '.1f')).replace('-','') str5 = fill3(num4) str2 = '-0+' + str5 else: try: num4 = str(format(li1[1], '.1f')).replace('-','') except: num4 = str(format(li1[1], '.1f')) str5 = fill3(num4) str2 = '0+' + str5 copy.TextString = str2 k1 = -1 if '.' in t2.TextString and '+' not in t2.TextString: if k2 == -1: pass else: for li1 in list3: if li1[2] == -1: pass else: #找到相对位置进行位移并赋值 if li1[1] == list3[0][1]: if pd1 == 1: #就以那个为起点 str2 = str(format(li1[0], '.1f')) t2.TextString = str2 else: jl1 = abs(abs(li1[1]) - 28.7) center = APoint(0,0,0) pt = APoint(jl1,0,0) t2.move(center,pt) str2 = str(format(li1[0], '.1f')) t2.TextString = str2 else: #复制 copy = t2.Copy() #移动 jl1 = minnum + li1[1] center = APoint(0,0,0) pt = APoint(jl1,0,0) copy.move(center,pt) #重新赋值 str2 = str(format(li1[0], '.1f')) copy.TextString = str2 k2 = -1 print('B') #设置一条二位多段线line line1 = [] road = -1 mn = 0 for li3 in list3: hh = li3[0] #----------------------------------------------------------------------------------------------------------------------- gc = abs(420- hh) #----------------------------------------------------------------------------------------------------------------------- # gc = abs(670 - hh) lj4 = minnum + li3[1] zbx = 91.6 + lj4 zby = gc + 56.7 pt1 = [zbx,zby,0] line1 = line1 + pt1 if li3[2] ==-1: #那个竖线 ptA = APoint(zbx,zby) ptB = APoint(zbx,56.7) # ptB = APoint(zbx,(yy+25+37)) lnobj2 = acad.model.AddLine(ptA,ptB) #这个要调一下 lnobj2.Color = 3 else: #那个竖线 ptA = APoint(zbx,zby) ptB = APoint(zbx,22) # ptB = APoint(zbx,(yy+27)) lnobj2 = acad.model.AddLine(ptA,ptB) #这个要调一下 lnobj2.Color = 3 #单独看下需要写出路的部分 try: if li3[3] == 1 and list3[mn+1][3] == 1 and abs(list3[mn+1][0] -li3[0]) <1: if road == -1: # str6 = '水泥路' # text3 = acad.model.AddText(str6,ptA,1) # text3.Color = 1 text3 = list(acad.iter_objects("Text")) for t3 in text3: if '路' in t3.TextString: center = APoint(0,0) numb1 = 91.5+lj4 numb2 = 58+gc pt3 = APoint(numb1,numb2) t3.move(center,pt3) gc1 = hh road = 1 except: pass mn = mn + 1 if road == -1: #删除标注 text3 = list(acad.iter_objects("Text")) for t3 in text3: if '路' in t3.TextString: t3.Delete() #把线绘制出来 pnts = aDouble(line1) try: plineObj = acad.model.AddPolyLine(pnts) except: with open(txtpath,'a+')as line1: line1.write(zhA) line1.flush() print('C') handle_string = 'select' text1 = list(acad.iter_objects(["Text", "Line","Circle"])) for t1 in text1: handle_string += ' (handent "'+t1.Handle+'")' #命令 handle_string += '\n\n' doc.SendCommand(handle_string) #移动的距离 str1 = 'move\n0,0,0\n' + str(xx) + ','+ str(yy) + ',0\n' #移动 # doc.SendCommand('move\n-80,-140,0\n760,-140,0\n') doc.SendCommand(str1) #再次选择 doc.SendCommand(handle_string) doc.SendCommand('copybase\n0,0,0\n') # target_doc.SendCommand('PASTEORIG\n') target_doc.SendCommand('PASTEORIG\n') #过程的不保存(删除所有要素) doc.Close(False) print(zhA + 'Finish') xx = xx + 210 dmxdict.pop(zhA,'nonevalue') jj = jj + 10 kk = kk - 1 yy =yy + 200 target_doc.Close() if __name__ == '__main__': start()