引入
在使用全站仪时,每次的测量的坐标均可保存在储存中,便于后期内业导入Cass中成图。导出的.dat数据的格式如下(随手编造的数据)
其中每一行为一个点的数据,用英文逗号隔开,分别表示代号,(空值),X坐标,Y坐标,Z坐标
,代号根据自己设定。在这个数据中,我使用FW1表示房屋1;FW2表示房屋2;前加下划线的数据表示线状数据,这里DL表示道路;空代号表示仅仅是测的一个高程点
Cass
将数据导入Cass,展点和点号,看到如下结果
根据相同代码连接起来,得到测量的两个房子和一条道路
再生成个DTM搞个等高线,等高距0.5m,看看地形如何
最后就是各种修图之类的杂七杂八工作了。和这里没啥关系了
Grasshopper
在最近自己看Rhino、Grasshopper的时候,想到能不能配合上脚本电池从原始全站仪数据快速的得到地形、建筑等多种信息呢。答案肯定是可以,就是自己水平还没那么高,先简单记录下今天的成果
- 为脚本电池设计了三个输入参数和三个输出结果,如下
- CassData:用于接收.dat文件的路径
- BuildMax:随机建筑高度的最大值
- BuildMin:随机建筑高度的最小值
- LinearFeatures:线状地物
- SidesOfBuilding:建筑物的侧面(加盖的代码还没参悟怎么写,后期用Grasshopper来加)
- GCPs:高程点(3D Delaunay Mesh和嵌面的代码也没搞出来,先搞出点,后面再拟合面)
-
接下来写了写了脚本后,连好电池,额外使用一个加盖和生成地形,如下(脚本在最后)
就能得到结果了,先看生成的地物,绿色表示选择电池输出的结果。这是线状地物
这是建筑物
这是地形(旋了一下不然看不出来起伏)
大概测的结果已经能看到了,接下来水平有限只能统统烘焙到Rhino处理一波,打开渲染模式(设置是不会设置的,切换就完事)
就这样,比起Cass的平面建筑和等高线还是直观的多,手工操作的地方也并不多。不过麻烦点的就是外业测量的时候建筑闭合的顺序要注意,还有编代号的要有统一 -
由于没有都写在脚本,也可以用Cluster打个包。加入Cluster Input和Cluster Output,替换确定的输入输出
然后直接全部选起来,Cluster。还可以改个参数名,设置个图标啥的。右键菜单Properties可以设置。通过File菜单的Create User Object可以变为自己的工具,以后用起来方便,美滋滋
-
脚本思路就是根据下换线和空值区分建筑、线状地物和普通高程点。对建筑的点按顺序进行封闭,拉出随机高度;对线状地物的点按顺序连接(不封闭);导出所有点的Point3d格式的List,用于生产地形。所有的脚本代码如下
private void RunScript(string CassData, int BuildMax, int BuildMin, ref object LinearFeatures, ref object SidesOfBuilding, ref object GCPs)
{
List<Point3d> gcds = new List<Point3d>();
List<Curve> budbs = new List<Curve>();
List<Curve> builds = new List<Curve>();
ReadCassData(CassData, ref gcds, ref budbs, ref builds);
GCPs = gcds;
LinearFeatures = budbs;
SidesOfBuilding = ExBuilds(builds, BuildMax, BuildMin);
}
// <Custom additional code>
public int ReadCassData(string path, ref List<Point3d> gcds, ref List<Curve> budbs, ref List<Curve> builds)
{
int cNum = 0;
string[] qPoints = File.ReadAllLines(path); // 读取文件
List<string> budtp = new List<string>(); // 存储标志
Dictionary<string,List<Point3d>> budtp2 = new Dictionary<string,List<Point3d>>(); // 分组创建曲线点
// 每行遍历查找标志的数目
foreach (var pi in qPoints)
{
string[] p = pi.Split(','); // 分割数据
if (!budtp.Contains(p[0]) && p[0] != string.Empty) // 判断标志是否存在,若不存在存储标志
{
budtp.Add(p[0]);
}
}
// 标志键对应
foreach (var item in budtp)
{
budtp2.Add(item, new List<Point3d>());
}
// 搜索高程和分组存点
foreach (var pi in qPoints)
{
// 保存高程点
string[] p = pi.Split(',');
double px = Convert.ToDouble(p[2]);
double py = Convert.ToDouble(p[3]);
double pz = Convert.ToDouble(p[4]);
Point3d gcd = new Point3d(px, py, pz);
Point3d pmd = new Point3d(px, py, 0);
gcds.Add(gcd);
// 分点
if (budtp2.ContainsKey(p[0]))
{
budtp2[p[0]].Add(pmd);
}
}
// 创建曲线
foreach (var item in budtp2.Keys)
{
if (item[0] != '_')
{
budtp2[item].Add(budtp2[item][0]); // 用于封闭
var c = new PolylineCurve(budtp2[item]);
builds.Add(c);
}
else
{
var c = new PolylineCurve(budtp2[item]);
budbs.Add(c);
}
}
return cNum;
}
public List<Surface> ExBuilds(List<Curve> builds, int Rmax, int Rmin)
{
List<Surface> result = new List<Surface>();
Random r = new Random();
foreach (var item in builds)
{
Vector3d dir = new Vector3d(0, 0, 1) * r.Next(Rmin, Rmax); // 随机Z方向
var nSrf = Surface.CreateExtrusion(item, dir); // 拉伸
result.Add(nSrf);
}
return result;
}
// </Custom additional code>
说真的资料真的好少,不知道多久才能写出一节更比六节强的电池。。。