python基于北京公交线txt数据画cad

运用python基于北京公交线网txt数据绘制cad

文章前半部分为学习过程,后半部分为在cad中对北京市两千多条公交线路(单向)的绘制,先上效果图2790个图层的北京公交线网

导入pyautocad

pip install pyautocad

读取cad文件

from pyautocad import Autocad,APoint
import math

acad = Autocad(create_if_not_exists=True)  #必须把cad文件打开

在cad控制台上打字

acad.prompt('hello world')
print(acad.doc.Name)  #输出文件名

读取图层信息

layers_nums=acad.ActiveDocument.Layers.count  #图层总数
print(layers_nums)
layers_names=[acad.ActiveDocument.Layers.Item(i).Name for i in range(layers_nums)]  #图层名称
print(layers_names)

读取多段线顶点坐标

items=[]
for item in acad.iter_objects("PolyLine"):
    print(item.Coordinates)
    items.append(item.Coordinates)
print(len(items))

新建图层置为当前

layerobj=acad.ActiveDocument.Layers.Add('HIT_Layer')
acad.ActiveDocument.ActiveLayer=layerobj

cad上画图

#设置颜色
ClrNum=1
layerobj.color=ClrNum
# ClrNum为颜色索引号,其取值范围为[0,256];标准颜色的颜色索引号指定如下::1 红、2 黄、3 绿、4 青、5 蓝、6 洋红、7/黑; 0 ByBlock、256 ByLayer;

 #画线l
p1=APoint(0,0)   #所有点必须这样表示
p2=APoint(100,100)
acad.model.AddLine(p1,p2)

#画多段线pl
lon=[[55,66,77],[1,3,44],[755,74,1,20]]
lat=[[55,66,77],[1,3,44],[755,74,1,20]]
pnts=[]
for i in range(len(lon[2])):
    pnts.append(APoint(lon[2][i],lat[2][i]))
pnts = np.array([j for i in pnts for j in i], dtype=np.float)
pnts = Autocad.aDouble(pnts)
pline_obj = acad.model.AddPolyLine(pnts)

#画图形
for i in range(5):   
    text = acad.model.AddText('Hi %s!' % i, p1, 2.5)
    acad.model.AddLine(p1, p2)
    acad.model.AddCircle(p1, 10)
    p1.y += 10
dp = APoint(10, 0)

保存

acad.ActiveDocument.Application.preferences.OpenSave.AutoSaveInterval = 0.51

完整代码

from pyautocad import Autocad,APoint
import math

acad = Autocad(create_if_not_exists=True)       #必须把cad文件打开
# acad.ActiveDocument.Application.Documents.Open("2.dwg")

#在cad控制台上打字
acad.prompt('hello world')
print(acad.doc.Name)  #输出文件名

# # 使用SummaryInfo对象访问图纸的属性(只适用于Windows),也可以使用SummaryInfo访问自动定义属性
# for doc in acad.app.Documents:
#     print(doc.Name)  # 文件名
#     print(doc.SummaryInfo.Author)
#     print(doc.SummaryInfo.Comments)
#     print(doc.SummaryInfo.HyperlinkBase)
#     print(doc.SummaryInfo.Keywords)
#     print(doc.SummaryInfo.LastSavedBy)
#     print(doc.SummaryInfo.RevisionNumber)
#     print(doc.SummaryInfo.Subject)
#     print(doc.SummaryInfo.Title)

# 读取图层信息
layers_nums=acad.ActiveDocument.Layers.count  #图层总数
print(layers_nums)
layers_names=[acad.ActiveDocument.Layers.Item(i).Name for i in range(layers_nums)]  #图层名称
print(layers_names)
print(acad.ActiveDocument.Layers.Item(0))


# 读取多段线顶点坐标
items=[]
for item in acad.iter_objects("PolyLine"):
    print(item.Coordinates)
    items.append(item.Coordinates)
print(len(items))


#新建图层置为当前
layerobj=acad.ActiveDocument.Layers.Add('HIT_Layer')
acad.ActiveDocument.ActiveLayer=layerobj
#设置颜色
ClrNum=1
layerobj.color=ClrNum
# ClrNum为颜色索引号,其取值范围为[0,256];
 # 标准颜色的颜色索引号指定如下::1 红、2 黄、3 绿、4 青、5 蓝、6 洋红、7/黑;
 # 0 ByBlock、256 ByLayer;


#画线
p1=APoint(0,0)   #所有点必须这样表示
p2=APoint(100,100)
acad.model.AddLine(p1,p2)


#画多段线
lon=[[55,66,77],[1,3,44],[755,74,1,20]]
lat=[[55,66,77],[1,3,44],[755,74,1,20]]
pnts=[]
for i in range(len(lon[2])):
    pnts.append(APoint(lon[2][i],lat[2][i]))
pnts = np.array([j for i in pnts for j in i], dtype=np.float)
pnts = Autocad.aDouble(pnts)

          # 将各点坐标顺序变换为行数据;
          # 添加样条曲线时参数仅支持1行多列的1维数组,即将各点x,y,z坐标顺序排列构成的数组。
          # 如报错可尝试增加该行代码 pnts = aDouble(pnts)
pline_obj = acad.model.AddPolyLine(pnts)


for i in range(5):   #画图形
    text = acad.model.AddText('Hi %s!' % i, p1, 2.5)
    acad.model.AddLine(p1, p2)
    acad.model.AddCircle(p1, 10)
    p1.y += 10
dp = APoint(10, 0)

# 更改标注的位置
for text in acad.iter_objects('Text'):
    print('text: %s at: %s' % (text.TextString, text.InsertionPoint))
    text.InsertionPoint = APoint(text.InsertionPoint) + dp

for obj in acad.iter_objects(['Circle', 'Line']):
    print(obj.ObjectName)

# text = acad.model.AddText("{0}".format(text), p1, 15)             #添加文本,文本字符串,点的位置下显示文本,字体大小
# text.move(p1, p2)                                                 #文本從p1點移動到p2點
# acad.model.AddCircle(p1, 10)                                      #画圆,圆心,半径
# acad.model.AddArc(p1, 500, math.radians(90), math.radians(270))   #画圆弧,圆心,半径,开始弧度,结束弧度

# 保存cad图到指定位置,第一個參數一定是保存的絕對路徑!!,64是保存的一種格式,筆者從1100都試了一遍,
# 有一些是可以生成图的,都是CAD可以打開的文件類型格式。其實跟着筆者寫64就好!
# acad.doc.SaveAs("D:\\pycharm\\mycode\\this_pc_new\\dwg_read\\test.dwg", 64)
# acad.doc.SaveAs("{0}".format("D:\\pycharm\\mycode\\this_pc_new\\dwg_read\\test.dwg"), 64)
acad.ActiveDocument.Application.preferences.OpenSave.AutoSaveInterval = 0.51  #自动保存

将txt线条打印到cad中

遇到一个需求,统计北京市的所有公交线并置于cad中,目前有txt的文件,大概55.4m,这里放个字段的截图。
北京公交部分线路信息
数据很大,不可能人工画,根据线路代码进行绘制,读取到一个新的线路代码就新建一个cad图层,直接上代码

from pyautocad import Autocad,APoint
import math
from tqdm import tqdm
from numba import jit
import numpy as np

#读取公交线路信息
s = []
code=[]
lon=[]
lat=[]
f= open('bus.txt','r')
for lines in f:
    ls = lines.strip('\n').replace(' ','').replace('、','/').replace('?','').split('/')
    for i in ls:
        s.append(i)
f.close()
del s[0]
for i in s:
    b = i.split(',', 2)
    if b[0] not in code:
        code.append(b[0])
        lon.append([])
        lat.append([])
    lon[-1].append(b[1])
    lat[-1].append(b[2])


# 高德火星坐标系转化为WGS84地理坐标系
def gcj2wgs(jingdu,weidu):
    lon = float(jingdu)
    lat = float(weidu)
    a = 6378245.0  # 克拉索夫斯基椭球参数长半轴a
    ee = 0.00669342162296594323  # 克拉索夫斯基椭球参数第一偏心率平方
    PI = 3.14159265358979324  # 圆周率
    # 以下为转换公式
    x = lon - 105.0
    y = lat - 35.0
    # 经度
    dLon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x))
    dLon += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0
    dLon += (20.0 * math.sin(x * PI) + 40.0 * math.sin(x / 3.0 * PI)) * 2.0 / 3.0
    dLon += (150.0 * math.sin(x / 12.0 * PI) + 300.0 * math.sin(x / 30.0 * PI)) * 2.0 / 3.0
    # 纬度
    dLat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))
    dLat += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0
    dLat += (20.0 * math.sin(y * PI) + 40.0 * math.sin(y / 3.0 * PI)) * 2.0 / 3.0
    dLat += (160.0 * math.sin(y / 12.0 * PI) + 320 * math.sin(y * PI / 30.0)) * 2.0 / 3.0
    #转换
    radLat = lat / 180.0 * PI
    magic = math.sin(radLat)
    magic = 1 - ee * magic * magic
    sqrtMagic = math.sqrt(magic)
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI)
    dLon = (dLon * 180.0) / (a / sqrtMagic * math.cos(radLat) * PI)
    wgsLon = lon - dLon
    wgsLat = lat - dLat
    return wgsLon, wgsLat


# 度数坐标系转换成小数坐标系
def deg2flo(jingdu,weidu):
    lon=str(jingdu)
    lat=str(weidu)
    flon=float(lon[:3])+float(lon[3:])/60
    flat = float(lat[:2]) + float(lat[2:])/60
    return flon,flat


# WGS84国际坐标系转GCJ02(火星坐标系)
def wgs2gcj(jingdu, weidu):
    lon = float(jingdu)
    lat = float(weidu)
    a = 6378245.0  # 克拉索夫斯基椭球参数长半轴a
    ee = 0.00669342162296594323  # 克拉索夫斯基椭球参数第一偏心率平方
    PI = 3.14159265358979324  # 圆周率
    # 以下为转换公式
    x = lon - 105.0
    y = lat - 35.0
    # 经度
    dLon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x))
    dLon += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0
    dLon += (20.0 * math.sin(x * PI) + 40.0 * math.sin(x / 3.0 * PI)) * 2.0 / 3.0
    dLon += (150.0 * math.sin(x / 12.0 * PI) + 300.0 * math.sin(x / 30.0 * PI)) * 2.0 / 3.0
    # 纬度
    dLat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))
    dLat += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0
    dLat += (20.0 * math.sin(y * PI) + 40.0 * math.sin(y / 3.0 * PI)) * 2.0 / 3.0
    dLat += (160.0 * math.sin(y / 12.0 * PI) + 320 * math.sin(y * PI / 30.0)) * 2.0 / 3.0
    # 转换
    radLat = lat / 180.0 * PI
    magic = math.sin(radLat)
    magic = 1 - ee * magic * magic
    sqrtMagic = math.sqrt(magic)
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI)
    dLon = (dLon * 180.0) / (a / sqrtMagic * math.cos(radLat) * PI)
    wgsLon = lon + dLon
    wgsLat = lat + dLat
    return wgsLon, wgsLat



#画线
acad = Autocad(create_if_not_exists=True)       #必须把cad文件打开
acad.ActiveDocument.Application.Documents.Open("aa.dwg")
for i in tqdm(range(len(code))):     #公交线数量
    layerobj = acad.ActiveDocument.Layers.Add(str(code[i]))  # 新建图层置为当前   PolyLine
    acad.ActiveDocument.ActiveLayer = layerobj
    pnts = []      #多段线坐标转换
    for j in range(len(lon[i])):
        [wgsLon,wgsLat]=wgs2gcj(lon[i][j],lat[i][j])  #坐标转换
        pnts.append(APoint(float(wgsLon)/5.8705*499.29, float(wgsLat)/6.3795*702.64))
        # pnts.append(APoint(float(wgsLon), float(wgsLat)))
    pnts = np.array([m for n in pnts for m in n], dtype=np.float)
    pnts = Autocad.aDouble(pnts)
    pline_obj = acad.model.AddPolyLine(pnts)

acad.ActiveDocument.Application.preferences.OpenSave.AutoSaveInterval = 0.51  #自动保存
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值