新项目需求:
结合百度地图,在地图中指定一个地点,获取此地点周围1km范围内所有数据库中存的单位的地点和信息标记在地图上。于是初写了一把oracle的存储过程,纯靠摸索写的。
后台需要的函数如下:
首先,计算圆弧函数
CREATE OR REPLACE FUNCTION RAD(d number) RETURN NUMBER
is
PI number :=3.141592625;
begin
return d* PI/180.0;
end ;
然后,计算距离函数
CREATE OR REPLACE FUNCTION GetDistance(lat1 number,
lng1 number,
lat2 number,
lng2 number) RETURN NUMBER is
earth_padius number := 6378.137;
radLat1 number := rad(lat1);
radLat2 number := rad(lat2);
a number := radLat1 - radLat2;
b number := rad(lng1) - rad(lng2);
s number := 0;
begin
s := 2 *
Asin(Sqrt(power(sin(a / 2), 2) +
cos(radLat1) * cos(radLat2) * power(sin(b / 2), 2)));
s := s * earth_padius;
s := Round(s * 10000) / 10000;
return s;
end;
接下来是我自己写的存储过程:
CREATE OR REPLACE PROCEDURE distance_maintunit(p_cur out sys_refcursor, center_lat in number , center_lng in number)
IS
v_muids VARCHAR(200);
v_distance NUMERIC(9,6);
BEGIN
FOR L_RECORD IN (select * from M_MAINTENACEUNIT)
LOOP
SELECT GetDistance(L_RECORD.Lat,L_RECORD.Longitude,center_lat,center_lng) INTO v_distance FROM dual;
IF (v_distance <=1)
THEN
v_muids:= v_muids || L_RECORD.muid || ',';
END IF;
END LOOP;
v_muids:= v_muids || '-1';
dbms_output.put_line(v_muids);
open p_cur for 'select * from m_maintenaceunit where muid in ('||v_muids||')';
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
dbms_output.put_line(SQLERRM);
END;
由于使用mybatis,所以service调用如下:
@Override
public List<MaintunitDto> getMaitunitByProcedures(Double lat, Double lng) {
Map<String ,Object> map=new HashMap<String, Object>();
map.put("lng", lng);
map.put("lat", lat);
try {
geoDao.getMaitunitByProcedures(map);
}catch(UncategorizedSQLException e) {
// System.out.println(e);
e.printStackTrace();
}
@SuppressWarnings("unchecked")
List<MaintunitDto> siteList=(List<MaintunitDto>)map.get("maintunits");
return siteList;
}
这里跟我之前转载的那篇关于oracle存储过程的文章有关联(如何调用一个返回集合的存储过程)
mapper.xml中的调用:
<select id="getMaitunitByProcedures" statementType="CALLABLE" parameterType="java.util.Map">
<![CDATA[
{call distance_maintunit(
#{maintunits,jdbcType=CURSOR,mode=OUT,resultMap=MAINTUNIT_MAP,javaType=ResultSet},
#{lat,jdbcType=DOUBLE,mode=IN},
#{lng,jdbcType=DOUBLE,mode=IN}
)}
]]>
</select>
<resultMap type="com.cseds.geo.dto.MaintunitDto" id="MAINTUNIT_MAP">
</resultMap>
dao中调用:
public List<MaintunitDto> getMaintUnitList(@Param("lng") Double lng, @Param("lat") Double lat);
由于第一次写oracle存储过程,代码只是实现了功能,有待改进。
参考:http://www.storyday.com/wp-content/uploads/2008/09/latlung_dis.html
http://blog.csdn.net/iw1210/article/details/9164573
http://www.cnblogs.com/microsoft-jiang/archive/2008/07/24/1250644.html