在GPS/GIS系统中经常会遇到坐标系问题,一般GPS模块输出的位置数据是参考84坐标的,而在系统应用的时候,特别在政府应用系统中的GIS电子地图常常采用地方坐标系。为了能够正确地在电子地图上显示移动终端的位置,需要将位置数据从84坐标转换到地方坐标。在实时环境下,如何自动完成转换,这里采用了SQL2000+存储过程+触发器+DLL调用的方法来实现。
1)背景
环境:windows2000+sp4
数据库:SQL2000
动态库制作:VB
结构:C/S
2)工作思路
采用TCP/IP将移动终端的位置数据传递到服务器,存入数据库的实时数据表a中;
在该实时数据表a上创建触发器(FOR INSERT),每当实时数据表a中记录插入的时候,触发器被激活,执行存储过程datatrans,该存储过程自动初始化COM实例,调用DLL中的转换方法,实现位置数据的坐标转换,将转换后的数据插入新的实时数据表b。
3)主要函数
SQL Server中的7个用于COM操作的扩展存储过程。
当需要操作一个COM对象时,首先通过调用sp_OACreate建立一个COM对象的实例,然后通过一系列的sp_OAGetProperty、sp_OASetProperty和sp_OAMethod调用完成需要完成的任务,在完成对COM对象的操作后,还需要调用sp_OADestroy释放该对象。每个调用返回一个整数类型的HRESULT,如果调用成功则该值为0。7个存储过程分别是:sp_OACreate 建立自动操作对象的一个实例
sp_OADestroy 释放一个对象的实例
sp_OAGetErrorInfo 从其他过程返回的HRESULT中获得错误描述信息
sp_OAGetProperty 把一个对象的属性存储在结果集或局部变量中
sp_OASetProperty 改变一个对象属性的值
sp_OAMethod 执行对象的方法,向方法传递参数,并得到返回值
sp_OAStop 关闭SQL Server的自动操作环境
4)代码
a)VB实现的DLL
打开VB6.0的IDE,按照ActivX DLL模版新建工程gpsSQLCOM,
CLASS的名称GPSFunction,工程名称gpsSQLCOM
实现转换
Public Function GetGpsDataSH(process_tmpGpsData As String) As String
‘输入process_tmpGpsData为84坐标数据
‘输出GetGpsDataSH=为地方坐标数据
END Fnction
编译输出DLL
b) 存储过程datatrans的实现
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[gps_datatrans]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[gps_datatrans]
GO
CREATE PROCEDURE gps_datatrans
@gpsvid varchar(25),
@gpsdata varchar(50)
AS
--定义用到的变量
declare @obj int,@re int
declare @VehileIDstring varchar(30)
declare @Mobilerestring varchar(30)
declare @Gpsadatastring varchar(30)
declare @sqlTable varchar(30)
declare @insertstring nvarchar(1000)
SET NOCOUNT ON
set @sqlTable='b'
--创建调用实例
exec @err=sp_OACreate 'gpsSQLCOM.GPSFunction', @obj out
if @err<>0 goto lberr --如果创建失败,则进行错误处理
--调用DLL中的位置转换函数
exec @err=sp_OAMethod @obj,'GetGpsDataSH',@Gpsadatastring out,@gpsdata
if @err<>0 goto lberr --如果调用错误,则进行错误处理
print '返回的结果是:' + @Gpsadatastring
--将结果存入数据表b,采用sp_executesql可以动态产成sql语句
set @insertstring=' INSERT INTO @sqlTabl (VEHICLEID,Time , DATA)
VALUES( @VehileIDstring,@Datetimestring,@Gpsadatastring )'
exec sp_executesql @insertstring,N'@VehileIDstring varchar(30),
@Gpsadatastring varchar(50) ,
@sqlTabl ',
@gpsvid,,@Gpsadatastring, @sqlTabl
--完成后释放实例
exec sp_OADestroy @obj
return
lberr:
--错误处理
c)触发器实现
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[gps_insert]') and OBJECTPROPERTY(id, N'IsTrigger') = 1)
drop trigger [dbo].[gps_insert]
GO
CREATE TRIGGER gps_Insert
ON [a]
FOR INSERT
AS
BEGIN
declare @gpsvid varchar(50)
declare @gpsdate varchar(50)
SET NOCOUNT ON
--获得新插入数据
select @gpsmobile =[feild1],
@gpsvid=[ feild2],
@gpsdata=[ feild3]
FROM a AS P INNER JOIN Inserted AS I
ON P. feild1 = I. feild1
--执行转换存储过程
exec gps_datatrans @gpsvid, @gpsdata
END
5)小节
采用这样的方式,以数据库为中心,转换灵活,只要制作不同的转换函数,就可以灵活实现多种坐标各式的转换,而通过触发器激活,不必使用专门的进程不停的来轮讯来发现新纪录,系统负担低。而且利于不同的前置系统接入也非常容易。