提示: 因为工程稍微有点大对我个人来说,所以可能在某些方面讲的不清楚或逻辑性不够强,如果有问题请@我。
原工程:https://github.com/LineChen/
六、用户位置管理
客户端的操作是摇一摇发送自己的位置吧并在地图上显示周围一公里用户的名称(客户端定位服务用的是百度地图),为了保持位置的时效性,
控制每五分钟发送一次用户的位置。服务器端要保存每个开启位置服务的用户的位置,考虑到用户量可能会很大,
不可能把所有的用户保存在一个哈希表中,所以分省份来分组保存,实际处理中可能需要分市来保存。
/**
* 用户位置类
*
* @author Administrator
*
*/
public class myLocationBean {
// 省份、经纬度
public String province;
public double longitude;
public double latitude;
@Override
public String toString() {
return "myLocationBean [province=" + province + ", longitude="
+ longitude + ", latitude=" + latitude + "]";
}
}
package com.managers;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.imomo_msg.myLocationBean;
/**
* 按省来管理用户位置
*
* @author Administrator
*
*/
public class ManageLocMap {
public static Map<String, ManageAProvinceLoc> map = new HashMap<String, ManageAProvinceLoc>();
/**
* 得到一个省的位置管理类
*
* @param province
* @return
*/
public static ManageAProvinceLoc getAProvinceLoc(String province) {
if (isContainsProvince(province)) {
// System.out.println("get省:" + province);
return (ManageAProvinceLoc) map.get(province);
}
return null;
}
/**
* 添加一个省位置管理类
*
* @param province
* @param AProvinceLoc
*/
public static void addAProvinceLoc(String province,
ManageAProvinceLoc AProvinceLoc) {
// System.out.println("添加省:--" + province);
map.put(province, AProvinceLoc);
}
/**
* 删除一个省的位置管理类
*
* @param province
*/
public static void deleteAProvinceLoc(String province) {
// System.out.println("删除省:--" + province);
map.remove(province);
}
/**
* 判断是否存在一个省位置管理类
*
* @param province
* @return
*/
public static boolean isContainsProvince(String province) {
return map.containsKey(province);
}
/**
* 用户下线,即时删掉位置信息
* @param userId
*/
public static void deleteOneUser(String userId){
Iterator<ManageAProvinceLoc> iterator = (Iterator<ManageAProvinceLoc>) map.values().iterator();
while(iterator.hasNext()){
ManageAProvinceLoc aProvinceLoc = iterator.next();
if(aProvinceLoc.isContainsId(userId)){
aProvinceLoc.deleteLocation(userId);
if(aProvinceLoc.getCount() == 0){
deleteAProvinceLoc(aProvinceLoc.province);
}
}
}
}
}
七、得到附近的人
当用户请求得到附近的人时,会发送自己的地理位置,然后服务器会根据省份得到该省开启服务的所有用户,进行距离计算,返回需要的用户信息。
根据经纬度计算距离:
package com.server_utils;
/**
* 根据一对经纬度得到两点距离
* @author Administrator
*
*/
public class DistanceUtil {
public static void main(String[] args) {
double dis = getDistance(120.133356, 36.013802, 120.133525, 36.013665);
System.out.println("两点距离 = " + dis);
}
/**
*
* @param long1
* 经度1
* @param lat1
* 纬度1
* @param long2
* 经度2
* @param lat2
* 纬度2
* @return 单位公里
*/
public static double getDistance(double long1, double lat1, double long2,
double lat2) {
double a, b, R;
R = 6378137; // 地球半径(米)
lat1 = lat1 * Math.PI / 180.0;
lat2 = lat2 * Math.PI / 180.0;
a = lat1 - lat2;
b = (long1 - long2) * Math.PI / 180.0;
double d;
double sa2, sb2;
sa2 = Math.sin(a / 2.0);
sb2 = Math.sin(b / 2.0);
d = 2
* R
* Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1)
* Math.cos(lat2) * sb2 * sb2));
return d/1000;
}
}
得到附近的人列表:
/**
* 得到指定距离内的陌生人相关信息
* @param isOnekm 是否是周围一公里
* @param userId
* @param range
* @return
*/
public List<StrangerBean> getDisStrangers(boolean isOnekm, String userId, int range) {
int NUM = 0;
int MAX = 100;
List<StrangerBean> list = new ArrayList<StrangerBean>();
////测试用....
//StrangerBean bean1 = new StrangerBean();
//bean1.strangerId = "9090";
//bean1.strangerName = "妖姬";
//bean1.Longitude = 120.143350;
//bean1.Latitude = 36.015562;
//bean1.strangerLoc = 1 + "公里以内";
//list.add(bean1);
//bean1 = new StrangerBean();
//bean1.strangerId = "9091";
//bean1.strangerName = "女神";
//bean1.Longitude = 120.133340;
//bean1.Latitude = 36.013557;
//bean1.strangerLoc = 1 + "公里以内";
//list.add(bean1);
myLocationBean loc1 = this.getLocation(userId);
Iterator<String> iter = locationMap.keySet().iterator();
while (iter.hasNext()) {
String strangerId = iter.next();
if (!strangerId.equals(userId)) {
myLocationBean loc2 = this.getLocation(strangerId);
double dist = DistanceUtil
.getDistance(loc1.longitude, loc1.latitude, loc2.longitude, loc2.latitude);
SqlModel model = new SqlModel();
if(isOnekm){
if(dist > 0 && dist <= 1){
StrangerBean bean = new StrangerBean();
bean.strangerId = strangerId;
bean.strangerName = model.getUserName(strangerId, false);
bean.Longitude = loc2.longitude;
bean.Latitude = loc2.latitude;
bean.strangerLoc = 1 + "公里以内";
list.add(bean);
NUM ++;
if(NUM == MAX){
break;
}
}
} else {
if(dist > range - 1 && dist <= range){
StrangerBean bean = new StrangerBean();
bean.strangerId = strangerId;
bean.strangerName = model.getUserName(strangerId, false);
bean.Longitude = loc2.longitude;
bean.Latitude = loc2.latitude;
bean.strangerLoc = range + "公里以内";
list.add(bean);
if(NUM == MAX){
break;
}
}
}
}
}
return list;
}
聊天服务器-解密陌生人(10)位置管理和获取周围一公里陌生人
原文地址:http://blog.csdn.net/u011102153/article/details/46670595