今天,日月教大家如何使用mysql根据经纬度实现距离排序搜索查询,话不多说,往下看。为了节省时间,我们在

中方式二的项目基础上修改。一、创建数据表,插入测试数据

根据上图,我们可以明显的看出,根据当前所在地按距离排序的话,应该是武汉-->黄冈-->咸宁-->九江  这样的顺序。二、创建mysql函数计算两个经纬度之间距离的 数据库函数

CREATE FUNCTION `lat_lng_distance` (lat1 FLOAT, lng1 FLOAT, lat2 FLOAT, lng2 FLOAT)RETURNS FLOATDETERMINISTICBEGIN    RETURN 6371 * 2 * ASIN(SQRT(        POWER(SIN((lat1 - abs(lat2)) * pi()/180 / 2),        2) + COS(lat1 * pi()/180 ) * COS(abs(lat2) *        pi()/180) * POWER(SIN((lng1 - lng2) *        pi()/180 / 2), 2) ));END

三、编写测试代码

SpringBootController.java

package com.chenqi.springboot.controller;import com.chenqi.springboot.entity.Store;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import com.chenqi.springboot.service.StoreService;import java.util.List;@RestControllerpublic class SpringBootController {    @Autowired    StoreService storeService;    @GetMapping("/getStores")    public List<Store> getStores(@RequestParam("longitude") String longitude,                                 @RequestParam("latitude") String latitude){        return storeService.getStores(longitude,latitude);    }}

StoreService.java

package com.chenqi.springboot.service;import com.chenqi.springboot.entity.Store;import java.util.List;public interface StoreService {    List<Store> getStores(String longitude, String latitude);}

StoreServiceImpl.java

package com.chenqi.springboot.service.impl;import com.chenqi.springboot.entity.Store;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.chenqi.springboot.dao.StoreMapper;import com.chenqi.springboot.service.StoreService;import java.util.HashMap;import java.util.List;import java.util.Map;@Servicepublic class StoreServiceImpl implements StoreService {    @Autowired    StoreMapper storeMapper;    @Override    public List<Store> getStores(String longitude, String latitude) {        //距离排序 范围500公里        Map<String,String> map = new HashMap<String,String>();        map = lonLatCalculation(Double.valueOf(longitude),Double.valueOf(latitude),);        map.put("longitude",longitude);        map.put("latitude",latitude);        return storeMapper.getStores(map);    }    /**     * @Author chenqi     * @Description 根据经纬度和半径 计算     * @Date 14:19 2019/1/2     * @Param [longitude 经度, latitude 纬度, raidus 搜索半径 m]     * @return java.util.Map<java.lang.String,java.lang.String>     **/    public static Map<String,String> lonLatCalculation(Double longitude, Double latitude, Integer raidus){        Map<String,String> map = new HashMap<String,String>();        // 赤道周长24901英里 1609是转换成米的系数        Double degree = (24901 * 1609) / 360.0;        double raidusMile = raidus;        Double dpmLat = 1 / degree;        Double radiusLat = dpmLat * raidusMile;        Double minLat = latitude - radiusLat;        Double maxLat = latitude + radiusLat;        Double mpdLng = degree * Math.cos(latitude * (Math.PI / 180));        Double dpmLng = 1 / mpdLng;        Double radiusLng = dpmLng * raidusMile;        Double minLng = longitude - radiusLng;        Double maxLng = longitude + radiusLng;        //return new double[] { minLat, minLng, maxLat, maxLng };        map.put("minLat",minLat.toString());        map.put("maxLat",maxLat.toString());        map.put("minLng",minLng.toString());        map.put("maxLng",maxLng.toString());        return map;    }}

StoreMapper.java

package com.chenqi.springboot.dao;import com.chenqi.springboot.entity.Store;import org.apache.ibatis.annotations.Mapper;import java.util.List;import java.util.Map;@Mapperpublic interface StoreMapper {    List<Store> getStores(Map<String,String> map);}

StoreMapper.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "-3-mapper.dtd" ><mapper namespace="com.chenqi.springboot.dao.StoreMapper" >      <select id="getStores" parameterType="java.util.Map" resultType="com.chenqi.springboot.entity.Store">        select s.store_id as storeId,        s.store_name as storeName,        s.longitude as longitude,        s.latitude as latitude        <if test="longitude != null and longitude != ''">            , ROUND(lat_lng_distance(#{latitude}, #{longitude}, latitude, longitude), 2) as distance        </if>        from store s where 1=1        <if test="longitude != null and longitude != ''">            and s.latitude &gt; #{minLat} and s.latitude &lt; #{maxLat}            and s.longitude &gt; #{minLng} and s.longitude &lt; #{maxLng}            order by distance asc        </if>    </select></mapper>

package com.chenqi.springboot.entity;import lombok.Data;import java.io.Serializable;/** * @author chenqi * @version V1.0 * @ClassName: Store * @Description: 店铺表 * @Date 2019/1/13 12:37 */@Datapublic class Store implements Serializable {    private static final long serialVersionUID = -82774092989L;    /** 店铺id */    private Long storeId;    /** 店铺名称 */    private String storeName;    /** 经度 */    private String longitude;    /** 纬度 */    private String latitude;    /** 距离 */    private String distance;}

四、启动项目,测试接口

浏览器或者postman请求:

http://localhost:8080/getStores?longitude=114.&latitude=30.594048

我们以武汉市政府的经纬度作为当前位置进行查询搜索。

可以看到,数据成功按照距离的远近进行排序返回了,distance是距离,单位km。至此,我们就简单的根据mysql函数实现了距离排序查询搜索的功能。