先简单说一说skyline软件的系统,skyline软件主要有TerraBuilder,TerraExplorer以及TerraGate。TerraBuilder主要是采用图像,dem等生成地形,制作成三维地球或三维平面;TerraExplorer的功能是编辑和浏览(关键部分);TerraGate主要是网络功能。换句话说,Terrabuilder是数据制作源,TerraExplorer是数据可视化窗口。想了解更多http://help.skylineglobe.cn/forum.php?mod=forumdisplay&fid=36
(一)二次开发准备
打开vs2010,在工具栏处右键,添加选项卡,建立skyline控件组,在建好的组内,右键选择项
添加skyline有关的com组件
添加完成后,将会得到如下控件:
TE3DWindow是三维浏览窗口,TEInformationWindow是树信息目录窗口,TENavigationMap是鹰眼窗口。
(二)管线生成
//接口的使用
TECoClass = new TerraExplorerClass();
mTerraExplorer = (ITerraExplorer5)TECoClass;
mPlane = (IPlane5)TECoClass;
mNavigation = (ITENavigationMap5)TECoClass;
mRender = (IRender5)TECoClass;
mMenue = (IMenu)TECoClass;
mObjectManager = (IObjectManager5)TECoClass;
mInformationTee = (IInformationTree5)TECoClass;
//加载三维球
mTerraExplorer.LoadEx(@"C:\globe.fly", "", "", 0);//或者mpt文件,可以使用Terrabuilder生成。
管线绘制的代码生成主要有两种方式:
1.单管段
int iGround = mInformationTee.CreateGroup("管线", 0);
double x1 = 0, y1 = 0, z1 = 0, x2, y2, z2;
double pipeLength;
double fillOpacity = 0.7;
double pipeRadius = 2;
object oYaw, oPitch;
double finYaw;
while (sdr.Read())
{
x1 = Convert.ToDouble(sdr["x1"].ToString());
y1 = Convert.ToDouble(sdr["y1"].ToString());
z1 = Convert.ToDouble(sdr["z1"].ToString());
x2 = Convert.ToDouble(sdr["x2"].ToString());
y2 = Convert.ToDouble(sdr["y2"].ToString());
z2 = Convert.ToDouble(sdr["z2"].ToString());
pipeLength = mCoordSys.GetDistanceEx(x1, y1, z1, x2, y2, z2);
mCoordSys.GetAimingAngles(x1, y1, z1, x2, y2, z2, out oYaw, out oPitch);
if ((double)oYaw < 180)
{
finYaw = (double)oYaw + 180;
}
else
{
finYaw = (double)oYaw - 180;
}
//这里是创建3Dobject的代码,创建圆柱体,可以进行贴图,输入一端的坐标,管径,管长度,圆柱形状逼近多边形的边数等
mTerra3DRegbase = mObjectManager.CreateCylinder(x1, y1, z1, pipeRadius, pipeLength, segmentNum, lineColor, fillOpacity, fillColor, HeightStyleCode.HSC_TERRAIN_ABSOLUTE, iGround, "");
mTerra3DRegbase.SetPosition(x1, y1, z1, finYaw, 90 - (double)oPitch, 0.0, 7);
}
2.以图层方式添加,优势在于成组进行图层管理,图层的显示类型有很多种类,比如每个点位显示球形,圆柱形,3D模型等等,图层的属性中可以进行一定的更改。
//创建图层组
int iGround = mInformationTee.CreateGroup("管线layer", 0); ;
double x1 = 0, y1 = 0, z1 = 0;
double x2 = 0, y2 = 0, z2 = 0;
double pipeLength;
double pipeRadius = 2;
List Aname = new List();
IPosition6 currCoord, nextCoord;
SGWorld sgworld = new SGWorld();
//创建featurelayer
ILayer6 CylindresLayer = sgworld.Creator.CreateNewFeatureLayer("第一管线段", LayerGeometryType.LGT_POINT, "FileName=pipes" + DateTime.Now.Day + ".shp;TEPlugName=OGR;", iGround);
//sdsdsd.Streaming = false;
//编辑layer属性,类似于在shp文件中设置字段属性,每一个点可以取得不同的值,再将其赋值给图层的属性中
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Yaw", AttributeTypeCode.AT_DOUBLE, 0);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Pitch", AttributeTypeCode.AT_DOUBLE, 0);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Roll", AttributeTypeCode.AT_DOUBLE, 0);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Texture", AttributeTypeCode.AT_TEXT, 1024);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Rotate", AttributeTypeCode.AT_DOUBLE, 100);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("RadiusX", AttributeTypeCode.AT_DOUBLE, 0);
CylindresLayer.DataSourceInfo.Attributes.CreateAttribute("Height", AttributeTypeCode.AT_DOUBLE, 0);
CylindresLayer.Visibility.MaxVisibilityDistance = 5000;
//编辑属性对应,如上图
CylindresLayer.FeatureGroups.Point.DisplayAs = ObjectTypeCode.OT_CYLINDER;
CylindresLayer.FeatureGroups.Point.SetProperty("Number of sides", 16);
CylindresLayer.FeatureGroups.Point.SetProperty("Line Opacity", 0);
CylindresLayer.FeatureGroups.Point.SetProperty("Fill Opacity", 100);
CylindresLayer.FeatureGroups.Point.SetProperty("Yaw", "[Yaw]");
CylindresLayer.FeatureGroups.Point.SetProperty("Roll", "[Roll]");
CylindresLayer.FeatureGroups.Point.SetProperty("Pitch", "[Pitch]");
CylindresLayer.FeatureGroups.Point.SetProperty("Texture File", "[Texture]");
CylindresLayer.FeatureGroups.Point.SetProperty("Rotate", "[Rotate]");
CylindresLayer.FeatureGroups.Point.SetProperty("Radius X", "[RadiusX]");
CylindresLayer.FeatureGroups.Point.SetProperty("Height", "[Height]");
//创建管段端外围
ILayer6 SpheresLayer = sgworld.Creator.CreateNewFeatureLayer("管段连接", LayerGeometryType.LGT_POINT, "FileName=connectors" + DateTime.Now.Day + ".shp;TEPlugName=OGR;", iGround);
//SpheresLayer.Streaming = false;
SpheresLayer.Refresh();
SpheresLayer.DataSourceInfo.Attributes.CreateAttribute("Yaw", AttributeTypeCode.AT_DOUBLE, 0);
SpheresLayer.DataSourceInfo.Attributes.CreateAttribute("Pitch", AttributeTypeCode.AT_DOUBLE, 0);
SpheresLayer.DataSourceInfo.Attributes.CreateAttribute("Roll", AttributeTypeCode.AT_DOUBLE, 0);
SpheresLayer.FeatureGroups.Point.DisplayAs = ObjectTypeCode.OT_SPHERE;
SpheresLayer.FeatureGroups.Point.SetProperty("Yaw", "[Yaw]");
SpheresLayer.FeatureGroups.Point.SetProperty("Roll", "[Roll]");
SpheresLayer.FeatureGroups.Point.SetProperty("Pitch", "[Pitch]");
SpheresLayer.FeatureGroups.Point.SetProperty("Segment density", 16);
SpheresLayer.FeatureGroups.Point.SetProperty("Line Opacity", 0);
SpheresLayer.FeatureGroups.Point.SetProperty("Fill Opacity", 100);
SpheresLayer.FeatureGroups.Point.SetProperty("Radius", pipeRadius);
SpheresLayer.FeatureGroups.Point.SetProperty("Texture File", Application.StartupPath+@"\pipeTextureCyan2.bmp");
SpheresLayer.Visibility.MaxVisibilityDistance = 5000;
while (sdr.Read())
{
x1 = Convert.ToDouble(sdr["x1"].ToString());
y1 = Convert.ToDouble(sdr["y1"].ToString());
z1 = Convert.ToDouble(sdr["z1"].ToString());
x2 = Convert.ToDouble(sdr["x2"].ToString());
y2 = Convert.ToDouble(sdr["y2"].ToString());
z2 = Convert.ToDouble(sdr["z2"].ToString());
//创建点位
currCoord = sgworld.Creator.CreatePosition(x1, y1, z1);
nextCoord = sgworld.Creator.CreatePosition(x2, y2, z2);
currCoord = currCoord.AimTo(nextCoord);
currCoord.ChangeAltitudeType(AltitudeTypeCode.ATC_TERRAIN_RELATIVE); // Relative to terrain
pipeLength = currCoord.DistanceTo(nextCoord);
//管段绘制
var pitch = -90 + currCoord.Pitch;
CylindresLayer.FeatureGroups.Point.CreateFeature(new double[] { currCoord.X, currCoord.Y, currCoord.Altitude }, currCoord.Yaw + ";" + pitch + ";" + currCoord.Roll + ";" + texture + ";" + FixTextureAngle(pitch, 16) + ";" + pipeRadius + ";" + pipeLength);
//管端外围
var radius1 = pipeRadius * 1.1;
CylindresLayer.FeatureGroups.Point.CreateFeature(new double[] { currCoord.X, currCoord.Y, currCoord.Altitude }, currCoord.Yaw + ";" + pitch + ";" + currCoord.Roll + ";" + Application.StartupPath+@"\pipeTextureCyan.bmp" + ";" + FixTextureAngle(pitch, 16) + ";" + radius1 + ";" + radius1);
CylindresLayer.FeatureGroups.Point.CreateFeature(new double[] { nextCoord.X, nextCoord.Y, nextCoord.Altitude }, (180 + currCoord.Yaw) + ";" + pitch + ";" + currCoord.Roll + ";" + Application.StartupPath+@"\pipeTextureCyan.bmp" + ";" + FixTextureAngle(pitch, 16) + ";" + radius1 + ";" + radius1);
//绘制连接弯管(球代替),判断有连接则放置
string a1 = sdr["A1"].ToString();
string a2 = sdr["A2"].ToString();
if (Aname.Contains(a1))
{
currCoord.Altitude -= pipeRadius;
SpheresLayer.FeatureGroups.Point.CreateFeature(new double[] { currCoord.X, currCoord.Y, currCoord.Altitude }, currCoord.Yaw + ";" + currCoord.Pitch + ";" + currCoord.Roll);
Aname.Remove(a1);
}
else
{
Aname.Add(a1);
}
if (Aname.Contains(a2))
{
nextCoord.Altitude -= pipeRadius;
SpheresLayer.FeatureGroups.Point.CreateFeature(new double[] { nextCoord.X, nextCoord.Y, nextCoord.Altitude }, nextCoord.Yaw + ";" + nextCoord.Pitch + ";" + nextCoord.Roll);
Aname.Remove(a2);
}
else
{
Aname.Add(a2);
}
}
CylindresLayer.Save();
SpheresLayer.Save();
类似的,加载三维模型:
需要注意的是,在加载mpt之后,以图层方式加载管线显示不出来,只有在fly文件基础上才能看到。完整的程序可以在本人的CSDN中下载:http://download.csdn.net/detail/a1002308667/9487840