基于SuperMap iObjects.NET 7C 中扩展图层实现航线一键查询系统

作者:小卒

该系统实现的源工程参见技术资源中心下面的示例代码。
首先小编在这里要告诉读者你,看这篇文章前要有C#基础并且能够使用SuperMap iObjects.NET 7C打开地图,添加绘制图层。好了,相必你来这里搜索到了这篇文章,你的编程能力和对SuperMap iObjects.NET 7C的了解已经超乎我的想象,废话不多说,进入正题。
你平常在SuperMap桌面或者组件中看到的地图都是将数据导入到数据源中成为数据集,然后将数据集以一定的风格展现在图层中。但是,往往你已经有了自己的数据,但是数据格式又不是SuperMap的数据格式(无法导入为数据集) ,并且你想不通过数据转换的方法,将这些数据显示到SuperMap的地图中。看到这里你心里应该已经在窃喜了,因为本文的重量级选手即将登台,那就是扩展图层,扩展图层的功能是可以创建你自己的图层类型,由你决定图层在地图上的绘制情况。所以你就可以通过扩展图层功能,自定义绘制这些数据到地图上,形成自己的数据图层。
我根据文章主题,来带你慢慢揭开扩展图层的面纱,假如你正好有这样一份数据(txt格式),如下所示(只提供部分数据)。

<CityList>
<Airlines cityFrom="呼和浩特" cityTo="石家庄">
<Airline>
<AirlineCode>JD5339</AirlineCode>
<Company>首都航空</Company>
<StartTime>12:40</StartTime>
<ArriveTime>13:30</ArriveTime>
<Mode>319</Mode>
</Airline>
<Airline>
<AirlineCode>GS7493</AirlineCode>
<Company>天津航空</Company>
<StartTime>16:25</StartTime>
<ArriveTime>17:15</ArriveTime>
<Mode>E90</Mode>
</Airline>
<Airline>
<AirlineCode>9C8990</AirlineCode>
<Company>春秋航空</Company>
<StartTime>18:00</StartTime>
<ArriveTime>19:00</ArriveTime>
<Mode>320</Mode>
</Airline>
</Airlines>

最后你通过扩展图层实现的结果,就是如图所示的效果:
基于SuperMap iObjects.NET 7C 中扩展图层实现航线一键查询系统_第1张图片

                                图一、扩展图层效果图

那么哪一部分是通过图层绘制展现的,跟原图一对比,一目了然了吧。
基于SuperMap iObjects.NET 7C 中扩展图层实现航线一键查询系统_第2张图片

                                图二、原底图

你的图层要显示到SuperMap地图窗口中,就必须继承LayerExtensionBase类,LayerExtensionBase类继承自Layer类。如何实现自己的图层类型呢?你必须实现LayerExtensionBase类中的一系列接口,才能将你的数据绘制到SuperMap地图上,下面通过示例代码为你讲解自定义图层的关键要点。

// 1. 自定义图层类型必须继承LayerExtensionBase类。
publicclassBruTileLayer : LayerExtensionBase
{
 privateconstInt32LayerExtensionType = 1001;
// 2. 实现 LayerExtensionBase.ExtensionType 接口。
//定义您的图层类型,该属性值可以为任意一个整数。
publicoverrideintExtensionType
{
 get{returnLayerExtensionType; }
}
//3.这个事件处理函数您要注意了,其作用特别重要。他是系统用来识别用户创建的所有继承于LayerExtensionBase的自定义类型的图层;您需要在这个事件中显示的告诉系统创建哪种类型的自定义图层。
staticvoidLayerExtensionBase_LayerExtensionBaseCreated(object sender, LayerExtensionBaseCreatedEventArgs e)
{
 if (e.ExtensionType == LayerExtensionType)
{
 e.LayerExtension = newBruTileLayer(e.Handle);
}
}
staticBruTileLayer()
{
 LayerExtensionBase.LayerExtensionBaseCreated +=    LayerExtensionBase_LayerExtensionBaseCreated;
}
//4. 该接口处将实现您的图层数据如何在SuperMap地图上进行绘制。
//该接口中的参数为MapPainter类型,该类型中的MapPainter.Graphics可以绘制自定义对象。
publicoverridevoidOnDraw(MapPainter painter)
{
 //自定义绘制实现代码
}
//5. 该构造函数用于用户代码中显示创建一个新的BruTileLayer使用。
publicBruTileLayer()
: this(IntPtr.Zero){}
//6.打开了保持有该类型图层的地图时,SuperMap内部需要在LayerExtensionBaseCreated事件中通过此构造函数才能正确构造此对象
publicBruTileLayer(IntPtr handle)
:base(handle)
{
 // 实现代码
}
//7. 实现将图层信息输出为 XML 字符串保存。
publicoverridestringToXML(WorkspaceVersion version)
{
 // 实现代码
}
//8. 与ToXML方法配合使用,实现通过XML字符串构建图层对象。
publicoverridevoidFromXML(string xml)
{
 // 实现代码
}
}

有了上面的你自定义的图层类型,那么,就可以通过–方法:Layers.Add (Layer),将你自定义的图层对象添加到地图的图层集合中,在地图中显示您的图层数据。
上面的代码关键点中就是在第4步,实现你的图层数据如何在SuperMap地图上进行绘制,是通过Graphics 类 (System.Drawing)进行绘制的。

方法 名称 说明
TranslateTransform(Single, Single)) 通过使此 Graphics 的变换矩阵左乘指定的平移来更改坐标系统的原点。
RotateTransform(Single) 将指定旋转应用于此 Graphics 的变换矩阵。
ResetTransform() 将此 Graphics 的世界变换矩阵重置为单位矩阵。
DrawImage(Image, Rectangle) 在指定位置并且按指定大小绘制指定的 Image。
DrawString(String, Font, Brush, Single, Single) 在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。

1.飞机的绘制
首先从你现有的xml文档中,通过XmlNode 类中的相关接口,读取xml文档中的信息,具体的实现代码见源工程。其中可以读取到从A地出发飞往B地的航班以及每趟航班的起飞时间(LaunchTime)和降落时间(LaunchTime),A地到B地的距离(s)可以通过geoline.Length来获得,从而就可以知道飞机飞行的速度v=s/(LaunchTime- LaunchTime)。接下来我们看看你现在的时间(timenow)是不是在起飞时间和降落时间之间,如果在这之间,就说明飞机是飞行的,代码如下:

public FightStatus GetStatus(DateTime timeNow)
        {
            FightStatus status = FightStatus.Unknown;
            //还没开始飞行
            if (DateTime.Compare(timeNow, this.LaunchTime) <= 0)
            {
                return FightStatus.Launch;
            }
            //正在飞行
            if ((DateTime.Compare(timeNow, this.LaunchTime) > 0) && (DateTime.Compare(timeNow, this.LandingTime) <= 0))
            {
                return FightStatus.OnAir;
            }
            //已经降落
            if (DateTime.Compare(timeNow, this.LandingTime) > 0)
            {
                status = FightStatus.Landed;
            }
            return status;
        }

那么在这一时刻飞行了多远的距离(l),就可以通过速度v*(timenow- LaunchTime)获得,从而通过GeoLine.FindPointOnLineByDistance 方法来找到该时刻飞机所在的位置点。

public Point2D GetPointByTime(DateTime timeNow)
        {
            //起始、降落时间差
            TimeSpan CS0000 = (TimeSpan) (this.LandingTime - this.LaunchTime);
            double totalMinutes = CS0000.TotalMinutes;
            //飞行速度
            double speed = this.LineLength / totalMinutes;
            //此刻起始的时间差
            TimeSpan CS0001 = (TimeSpan) (timeNow - this.LaunchTime);
            //此刻飞行的距离
            double flyLength = CS0001.TotalMinutes * speed;
            //在线上以指定的距离找点
            return this.Line.FindPointOnLineByDistance(flyLength);
        }

最后通过计算方位角(Azimuth)确定飞机的方向,此刻你就可以在OnDraw方法中实现绘制了。

2.飞机线路的绘制

//如果选中的航线中的线对象不为空,就绘制显示该航线对象
if (this.m_selected.Line != null)
{
   GeoStyle style = new GeoStyle();
   style.LineSymbolID = 8;
   style.LineColor = Color.DarkGreen;
   style.LineWidth = 0.4;
   this.m_selected.Line.Style = style;
   //绘制单个Geometry对象
   mappainter.DrawGeometry(this.m_selected.Line);
 }

3.气泡及文字说明的绘制
这一部分的绘制主要是通过Graphics 类 (System.Drawing)中的相关接口进行绘制的,具体的代码部分,请查看源工程。

好了,文章就写到这里,相必你已经清楚了整个系统实现的流程了,也了解了扩展图层的一些功能,赶紧拿一份自己的数据动手实践一下吧。

你可能感兴趣的:(编程,技术,地图,supermap,扩展图层)