新项目需求:
结合百度地图,在地图中指定一个地点,获取此地点周围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; /*dbms_output.put_line(‘distance:‘ || v_distance);*/ 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
本文出自 “java程序猿的博客” 博客,请务必保留此出处http://chengxuyuan.blog.51cto.com/5789198/1787169
oracle存储过程---获取数据库中到指定经纬度距离的坐标
原文地址:http://chengxuyuan.blog.51cto.com/5789198/1787169