以下是之前同事整理的一个查询坐标距离的一个例子,记录下以免以后要用。
CREATE OR REPLACE VIEW V_HJYJ_FXKZ_FXYXXS
AS
--风险源部分信息,用于计算该风险源与其周边敏感源的距离
SELECT FXY.XH XH, --风险源序号
FXY.FXYMC MC, --风险源名称
FXY.ADDRESS DZ, --风险源地址
TO_NUMBER(FXY.JD) X, --经度,即X坐标
TO_NUMBER(FXY.WD) Y, --纬度,即Y坐标
0 Z, --高度,即Z坐标
FXY.SHENG, --行政区划:省
FXY.SHI, --行政区划:市
FXY.QX, --行政区划:区县
FXY.ORGID
FROM T_HJYJ_FXY_JBXX FXY
WHERE FXY.SFYX = 'YES'
AND FXY.JD IS NOT NULL
AND FXY.WD IS NOT NULL
AND FXY.JD != 'NaN'
AND FXY.WD != 'NaN'
AND TO_NUMBER(FXY.JD) <= 180
AND TO_NUMBER(FXY.WD) <= 90
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE VIEW V_HJYJ_FXKZ_MGYXXS
AS
--查询敏感源等信息(可能会存在多个种类的风险源,如果有请使用UNION ALL),用于提供对风险源名录的智能分析
SELECT FJMSQXX.XH, --序号
FJMSQXX.FJMSQMC MC, --名称
FJMSQXX.ADDRRESS DZ, --地址
TO_NUMBER(FJMSQXX.JD) X, --经度,即X坐标
TO_NUMBER(FJMSQXX.WD) Y, --纬度,即Y坐标
0 Z, --高度,即Z坐标
10000 YJJL, --预警距离(单位:米),表示如果风险源到该敏感目标的距离小于该距离(不同敏感源要求的安全范围也不一样),则需要列出来给客户参考,是否纳入风险源名录
'FJMSQ' LX --表示数据业务类型,这里指的是风景名胜区的信息
FROM T_HJYJ_MGY_FJMSQXX FJMSQXX
WHERE FJMSQXX.JD IS NOT NULL
AND FJMSQXX.WD IS NOT NULL
AND FJMSQXX.JD != 'NaN'
AND FJMSQXX.WD != 'NaN'
AND TO_NUMBER(FJMSQXX.JD) <= 180
AND TO_NUMBER(FJMSQXX.WD) <= 90
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
create table T_HJYJ_FXY_MLTJ
(
XH NVARCHAR2(50) not null,
FXYXH NVARCHAR2(50),
FXYMC NVARCHAR2(100),
FXYDZ NVARCHAR2(100),
SHENG NVARCHAR2(50),
SHI NVARCHAR2(50),
QX NVARCHAR2(50),
MGYXH NVARCHAR2(50),
MGYMC NVARCHAR2(100),
MGYDZ NVARCHAR2(50),
MGYLX NVARCHAR2(50),
SJJL INTEGER,
ITEM1 NVARCHAR2(50),
ITEM2 NVARCHAR2(50),
ITEM3 NVARCHAR2(50),
ITEM4 NVARCHAR2(50),
ITEM5 NVARCHAR2(50),
BZ NVARCHAR2(1000),
ORGID NVARCHAR2(50),
CJR NVARCHAR2(50),
CJSJ DATE,
XGR NVARCHAR2(50),
XGSJ DATE,
constraint PK_T_HJYJ_FXY_MLTJ primary key (XH)
);
comment on table T_HJYJ_FXY_MLTJ is
'存储计算获得的推荐风险源名录名单,如风险源与敏感源之间的距离小于一定值时,需要提供给用户参考是否纳入风险源名录';
comment on column T_HJYJ_FXY_MLTJ.XH is
'序号';
comment on column T_HJYJ_FXY_MLTJ.FXYXH is
'风险源序号(与风险源基本信息T_HJYJ_FXY_JBXX主键XH关联)';
comment on column T_HJYJ_FXY_MLTJ.FXYMC is
'风险源名称';
comment on column T_HJYJ_FXY_MLTJ.FXYDZ is
'风险源地址';
comment on column T_HJYJ_FXY_MLTJ.SHENG is
'省(风险源)';
comment on column T_HJYJ_FXY_MLTJ.SHI is
'市(风险源)';
comment on column T_HJYJ_FXY_MLTJ.QX is
'区/县(风险源)';
comment on column T_HJYJ_FXY_MLTJ.MGYXH is
'敏感源序号';
comment on column T_HJYJ_FXY_MLTJ.MGYMC is
'敏感源名称';
comment on column T_HJYJ_FXY_MLTJ.MGYDZ is
'敏感源地址';
comment on column T_HJYJ_FXY_MLTJ.MGYLX is
'敏感源类型';
comment on column T_HJYJ_FXY_MLTJ.SJJL is
'实际距离';
comment on column T_HJYJ_FXY_MLTJ.ITEM1 is
'预留字段1';
comment on column T_HJYJ_FXY_MLTJ.ITEM2 is
'预留字段2';
comment on column T_HJYJ_FXY_MLTJ.ITEM3 is
'预留字段3';
comment on column T_HJYJ_FXY_MLTJ.ITEM4 is
'预留字段4';
comment on column T_HJYJ_FXY_MLTJ.ITEM5 is
'预留字段5';
comment on column T_HJYJ_FXY_MLTJ.BZ is
'备注';
comment on column T_HJYJ_FXY_MLTJ.ORGID is
'组织机构';
comment on column T_HJYJ_FXY_MLTJ.CJR is
'创建人';
comment on column T_HJYJ_FXY_MLTJ.CJSJ is
'创建时间';
comment on column T_HJYJ_FXY_MLTJ.XGR is
'修改人';
comment on column T_HJYJ_FXY_MLTJ.XGSJ is
'修改时间';
----------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION GetDistance (
--该函数用于计算两个坐标点之间的距离
--与Google Earth手工测算结果比较,偏差率为0.4%
x_start NUMBER, --起始坐标经度
y_start NUMBER, --起始坐标纬度
z_start NUMBER, --起始坐标高度,如果两个坐标的高度都是0,则表示两个坐标点之间的平面距离
x_end NUMBER, --终止坐标经度
y_end NUMBER, --终止坐标纬度
z_end NUMBER, --终止坐标高度,如果两个坐标的高度都是0,则表示两个坐标点之间的平面距离
c nvarchar2 --指定返回测算结果的单位,如果是为米,则参数值为unit=M,如果是千米,则参数值为unit=KM
) RETURN FLOAT IS JL FLOAT := 0 ; --返回两个点之间的距离,单位为:米
BEGIN
SELECT
sdo_geom.sdo_distance (
mdsys.sdo_geometry (
2001, --表示存储的坐标代表的几何类型,如点、线、面,这里2001代表点类型
8307, --代表WGS84坐标系
mdsys.sdo_point_type (x_start, y_start, z_start),
NULL, --如果几何类型为点类型的话,这里对应的值为NULL;
NULL --如果几何类型为点类型的话,这里对应的值为NULL;
),
mdsys.sdo_geometry (
2001, --表示存储的坐标代表的几何类型,如点、线、面,这里2001代表点类型
8307, --代表WGS84坐标系
mdsys.sdo_point_type (x_end, y_end, z_end),
NULL, --如果几何类型为点类型的话,这里对应的值为NULL;
NULL --如果几何类型为点类型的话,这里对应的值为NULL;
),
0.005, --0.005为oracle计算时候的误差精度,这里指5毫米
c
) INTO JL FROM dual ;
RETURN JL ;
END ;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE Pro_Calculate_FxymlTj
AS
--计算风险源与敏感源之间小于某个距离时,需要列出来供用户参考,是否需要将该风险源列入风险源名录内管理
cur_mgy V_HJYJ_FXKZ_MGYXXS%rowtype;
cur_fxy V_HJYJ_FXKZ_FXYXXS%rowtype;
cursor cur_mgys is SELECT XH,MC,DZ,X,Y,Z,YJJL,LX FROM V_HJYJ_FXKZ_MGYXXS;
cursor cur_fxys is SELECT XH,MC,DZ,X,Y,Z,SHENG,SHI,QX,ORGID FROM V_HJYJ_FXKZ_FXYXXS;
count_jl FLOAT; --计算获得的距离
begin
for cur_mgy in cur_mgys loop
begin
for cur_fxy in cur_fxys loop
begin
count_jl := Round(GetDistance(cur_mgy.X, cur_mgy.Y,cur_mgy.Z,cur_fxy.X, cur_fxy.Y,cur_fxy.Z,'unit=M')); --计算风险源与敏感源之间的距离
if count_jl <= cur_mgy.YJJL then --如果风险源与敏感源之间的距离小于预警距离时,将风险源保存起来,供用户参考是否需要加入到今年的风险源名录中进行管理
INSERT INTO T_HJYJ_FXY_MLTJ (XH, FXYXH, FXYMC, FXYDZ, SHENG, SHI, QX, MGYXH, MGYMC, MGYDZ, MGYLX, SJJL, ORGID, CJR, CJSJ, XGR, XGSJ)
VALUES (sys_guid(), cur_fxy.XH, cur_fxy.MC, cur_fxy.DZ, cur_fxy.SHENG, cur_fxy.SHI, cur_fxy.QX, cur_mgy.XH, cur_mgy.MC, cur_mgy.DZ, cur_mgy.LX, count_jl, cur_fxy.ORGID, 'SYSTEM', SYSDATE, 'SYSTEM', SYSDATE);
end if;
end;
end loop;
end;
end loop;
commit;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.put_line(SYSDATE||' 操作数据时出现异常!');
end;