附件地点搜索(非geohash)

geohash用一个字符串表示经度和纬度两个坐标。它的缺点是:位于格子边界两侧的两点,虽然十分接近,但编码会完全不同。

我想出了另一种方法,本方法是得到一个点邻近区域内的点集合:

思路:第一步(生成):将一个长方形区域分成许多正方形格子,区域内的点都属于某个格子,有点的格子新建一个list,将格子中的点放进去。

            第二步(查找):进来一个坐标,先计算它属于哪个格子,将周围9个格子(包括所在格子)中的list合并起来,就是邻近点集合。

package custom;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class SuperMap
{
	static Map<Double,ArrayList<Integer>> map=new HashMap<Double, ArrayList<Integer>>();     //格子中的list
	static int cnt=0;              //点编号
        static final  ArrayList<Integer> nullList = new ArrayList<Integer>(); 
 	static final double begin_lon=119;
	static final double begin_lat=27;
	static final double end_lon=122;
	static final double end_lat=29;     /*长方形区域*/
	static final double dist=0.007;  //邻近区域半径
	static int lat_Num=(int)((end_lat-begin_lat)/dist+1);
	//邻近区域周围格子
    static int[][] offset={
    	{0,0},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}
    };
    
	/**
	 * 将所有点放到格子中
	 * @param lon  经度
	 * @param lat   纬度
	 */
	public static void addToMap(double lon,double lat)
	{
		double idx=getCellNo(lon,lat);
		if(!map.containsKey(idx))     //有点的格子才新建list
		{
			map.put(idx, new ArrayList<Integer>());
		}
		map.get(idx).add(cnt);
		cnt++; 
	}
	
	/**
	 * 得到周围格子中的点编号
	 * @param lon 经度
	 * @param lat  纬度
	 * @return 邻近表
	 */
	public static List<Integer> NearTable(double lon,double lat)
	{
		ArrayList<Integer> res=new ArrayList<Integer>();
		for(int i=0;i<9;i++)
		{
			res.addAll(getList(lon+offset[i][0]*dist,lat+offset[i][1]*dist));
		}
		return res;
	}
	
	/**
	 * 得到某个格子的点编号
	 * @param d 经度
	 * @param e
	 * @return
	 */
	private static ArrayList<Integer> getList(double lon, double lat)
	{
		double idx=getCellNo(lon, lat);
		if(map.containsKey(idx))    //格子中有没有list
		{
			return map.get(idx);
		}
		return   nullList;//格子没有点,返回空list
	}

	/**
	 * 得到隐式二维数组格子编号
	 * 将纬度变成小数
	 * @param lon
	 * @param lat
	 * @return
	 */
	private static double getCellNo(double lon, double lat)
	{
		int i=(int)((lon-begin_lon)/dist);
		int j=(int)((lat-begin_lat)/dist);
		return (double)j/lat_Num+i;
	}
	
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值