上一节我们已能让Micaps支持新数据类型,但目前大量数据在数据库中保存,是否能让Micaps直接读取数据库中的数据显示呢?这一节我们将做一个Micaps直连数据库显示数据的插件。
Micaps实际上已经预留了数据库、XML数据读取接口,但它并没有实现。其实完全没必要将数据库与文件接口分开,主程序只用让插件绘图,其它的都让插件自己处理,不管数据是来自文件、数据库还是网络。
要实现这个功能,需解决如下问题:
与上节一样,增加一个显示绑定段,类名为:SxAwsDataBindings。
实现SxAwsDataBindings类,代码除了对文件名的判断不同,其它与上节都一样:
public bool CanCreateForFile(string filename)
{
//仅能打开名为"sxaws.udl"的文件
string fn = Path.GetFileName(filename).ToLower();
return fn == "sxaws.udl";
}
再实现数据读取,在CreateLayerForFile(OpenedFile file)中编写数据读取代码。与上节唯一不同的是,这里创建的是一个叫做SxAws的图层类。
public ILayer CreateLayerForFile(OpenedFile file)
{
//取得当前视图,转换为Micaps地图视图
var mainRenderView = WorkspaceSingleton.Workspace.ActiveViewContent as IMicapsMainView;
//如果当前视图是地图,则加载图层
if (mainRenderView != null)
{
//创建自动站数据库图层
SxAws Chart = new SxAws();
//用它创建Micaps图层绑定对象
MicapsDataLayerWrapper layer = new MicapsDataLayerWrapper(Chart);
//给图层的地图对象赋值
Chart.Map = mainRenderView.Map;
//加载数据
layer.Load(file, file.OpenRead());
file.CloseIfAllViewsClosed();
layer.LayerName = Chart.Description();
return layer;
}
return null;
}
SxAws类继承了C_ChartBase类,重写了 ReadFile(string filename)和Draw(GLGraphics g)虚函数,分别实现数据读取和绘图工作。与上节不同的是,读取数据库时,我们不是从sxaws.udl文件中读取数据,而是从sxaws.udl中读取数据库连接串,然后连接数据库读取数据。实际开发中,可根据需要修改读数据库和绘图代码,这里我读的陕西省的数据库的,把代码的直接贴上去是运行不了的。
public class SxAws : C_ChartBase
{
public override void Draw(GLGraphics g)
{
float x, y;
float ang;
foreach (DataRow row in _AwsData.Tables[0].Rows)
{
string t = row["dewtemp"].ToString();
float lat = float.Parse(row["latitude"].ToString());
float lon = float.Parse(row["longitude"].ToString());
Map.MemTY(lon, lat, out x, out y);
g.ShowNumber(t, x, y, 1, 1, Color.Red);
float dd = 9999;
float ff = 9999;
float.TryParse(row["WindDirect"].ToString(), out dd);
float.TryParse(row["WindVelocity"].ToString(),out ff);
if(dd!=9999&& ff !=9999)
{
ang = dd;//= ang - 270;
ang = ang + 180;
if (ang >= 360)
ang = ang - 360.0f;
ang = ang * 0.0174532925F;//转化为弧度
g.ShowWind(ff/10.0f, x, y, 0.8f, 0.8f, Color.Black, 360f - ang * 180.0f / (float)Math.PI, true);
}
}
}
private DataSet _AwsData = new DataSet();
public override string ReadFile(string filename)
{
string conString = @"Data Source=172.23.64.146;Persist Security Info=True;User ID=aws;;Initial Catalog=elementinfo";
SqlConnection connection = new SqlConnection(conString);
string sql = @"SELECT * FROM dbo.tabTimeData INNER JOIN dbo.tabStation ON dbo.tabTimeData.StationNum = dbo.tabStation.StationNum WHERE (ObservTimes = '2013010101')";
SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
_AwsData.Clear();
adapter.Fill(_AwsData);
connection.Close();
return "Success";
}
…………………
…………………
…………………
}
可惜的是,直接读取数据库时,Micaps的翻页功能无法使用。Micaps的图层类虽然预留了前一时次、后一时次的抽象方法,但却在翻页代码中却没有调用它,而是直接搜索文件来实现。我们调用数据库没有文件,就造成在插件代码中无法控制翻页。解决办法是我们重新编写翻页插件替换Micaps自带的翻页功能,翻页时,先调用每个图层的翻页方法,如果发生异常,再执行文件方式翻页(此方法并不安全,其它插件的翻页代码如果未抛出异常,那它的文件方式翻页功能将实效)。
下图即直接连接陕西省局自动站数据库绘图的效果: