近期公司接的公租房项目,在小程序模块中有用到离我最近的房源列表的功能,经过项目实践相关实现过程如下:
功能演示
PC后台配置小区位置:
单击地图描点后打开如下图所示的描点对话框,描点选择后单击确定按钮返回经纬度信息:
小程序中获取位置后调用接口显示距离:
代码实现:
管理后台描点Vue组件核心代码
<template>
<el-dialog width="95%" class="hkt-dlg-darkblue resource-modal" top="5vh" :title="title" :visible.sync="isShow" destroy-on-close :close-on-click-modal="false">
<div class="map-container" ref="mapContainer"></div>
<div slot="footer" class="dialog-footer dialog-footer-wrap text-center">
<el-button @click="isShow = false">取 消</el-button>
<el-button type="primary" :disabled="!latitude" @click="pickedHandler">{{'确 定'}}</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'PickerQMapPositionModal',
props: {
show: {
type: Boolean,
default: false
},
title: {
type: String,
default: '地图描点'
},
dialogProps: {
type: Object,
reuired: true
}
},
data () {
return {
latitude: '',
longitude: ''
}
},
computed: {
isShow: {
get () {
return this.show
},
set (val) {
this.$emit('update:show', val)
}
}
},
mounted () {
this.init()
},
methods: {
init () {
this.initMap()
},
async initMap () {
// if (!window.TMap) {
// }
await this.$hktUtils.loadJS('https://map.qq.com/api/gljs?v=1.exp&key=VQ6BZ-ZFSW6-H36SN-E7TZL-QZ6U6-O3F24')
var center = new TMap.LatLng(28.239377,112.866161)
//定义map变量,调用 TMap.Map() 构造函数创建地图
var map = new TMap.Map(this.$refs.mapContainer, {
center: center,//设置地图中心点坐标
zoom: 15, //设置地图缩放级别
// pitch: 43.5, //设置俯仰角
// rotation: 45 //设置地图旋转角度
});
//初始化marker图层
var markerLayer = new TMap.MultiMarker({
id: 'marker-layer',
map: map
});
map.on("click", (evt) => {
if(markerLayer.geometries && markerLayer.geometries.length > 0) {
markerLayer.remove(markerLayer.geometries[0].id)
}
markerLayer.add({
position: evt.latLng
});
console.log('evt.latLng', evt.latLng, evt)
this.latitude = evt.latLng.lat.toFixed(7)
this.longitude = evt.latLng.lng.toFixed(7)
})
},
pickedHandler () {
this.$emit('callback', {
latitude: this.latitude,
longitude: this.longitude
})
this.isShow = false
}
}
}
</script>
<style lang="scss" scoped>
.map-container {
width:100%;
height:70vh;
}
</style>
Java端计算距离核心代码
package com.hkt.jianfa.rental.housing.manager.wx.util;
/**
* 根据经纬度计算距离的工具类
*
* @author 朱治龙(i@zhuzhilong.cn)
* @since 2021-06-29 16:22:18
*/
public class DistanceUtil {
//地球平均半径
private static final double EARTH_RADIUS = 6378137;
//把经纬度转为度(°)
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 根据两点间经纬度坐标(double值),计算两点间距离,单位为米
*
* @param lng1 第1个坐标的经度值
* @param lat1 第1个坐标的纬度值
* @param lng2 第2个坐标的经度值
* @param lat2 第2个坐标的纬度值
* @return
*/
public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(
Math.sqrt(
Math.pow(Math.sin(a / 2), 2)
+ Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
)
);
s = s * EARTH_RADIUS;
s = Math.round(s * 10000) / 10000;
return s;
}
/**
* 传入逗号分隔的两个经纬度的值计算巨鹿
*
* @param position1 第一个经纬度
* @param position2 第二个经纬度
* @return
*/
public static double getDistance(String position1, String position2) {
if (position1.contains(",") && position2.contains(",")) {
String[] point1 = position1.split(",");
String[] point2 = position2.split(",");
return getDistance(Double.parseDouble(point1[1]), Double.parseDouble(point1[0]), Double.parseDouble(point2[1]), Double.parseDouble(point2[0]));
}
return 0;
}
/**
* 将距离数值转换为前端显示所需的字符串信息
*
* @param distance
* @return
*/
public static String decodeDistance(double distance) {
if (distance < 1000) {
return "<1km";
} else if (distance / 1000 > 100) {
return ">100km";
} else {
return new Double(distance / 1000).intValue() + "km";
}
}
}
业务逻辑类中调用DistanceUtil方法计算距离:
小程序中获取位置后,将经纬度信息传给后端计算距离及排序
核心代码如下:
uni.getLocation({
type: 'gcj02',
success: (res) => {
this.searchForm.sort = 'distance'
this.searchForm.location = res.latitude + ',' + res.longitude
this.getProjects()
},
fail: (err) => {
this.getProjects()
}
})
评论 (0)