GeoHash补充

最近在逛cocoa的时候发现有一些小细节可以优化的

- 我们在设定二分精度时可以设置精度为个体的影响范围为精度,这样我们在搜索的时候可以直接用“==”而非“like”

- 我们可以不用进行base32编码,直接将其转化为unsinged long,可以大大减少计算,数据库使用字符串是因为很多数据库对字符串类型有很好的支持,c上面用字符串效率低得可以

- 之前那个写得仓促,有很多错误没整理,这次这个是完整版,当然,只是对我的游戏进行了优化,其他实现需要开发者动起手来

#pragma once

#include"BaseEntity.h"
#include"cocos2d.h"
#include<algorithm>
#include<bitset>

using namespace std;

class GeoHash
{
public:
    static char base32_encode[32];

#define precision 10
#define binaryLength 20

#define world_size Vec2(1000,1000)//wathc out!if x!=y,there will be problems in combining binary code 

protected://dividision
    static void halfDivision(double, double, double,string&);//half division,declare the left part as ‘0‘ there
    static bool between(double value,double min,double max)
    {
        return value > min&&value < max;
    }
protected://convert to base32 code
    static string base32Encoding(string);

public:
    static string getIndex(Vec2);//get GeoHash code
    static unsigned long getUlIndex(Vec2);
    static std::vector<BaseEntity*> getNeighbors(Vec2, std::vector<BaseEntity*>);
};

char GeoHash::base32_encode[] = {
    ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘,
    ‘8‘, ‘9‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘,
    ‘h‘, ‘j‘, ‘k‘, ‘m‘, ‘n‘, ‘p‘, ‘q‘, ‘r‘,
    ‘s‘, ‘t‘, ‘u‘, ‘v‘, ‘w‘, ‘x‘, ‘y‘, ‘z‘
};

string GeoHash::base32Encoding(string bitStr)
{
    string outPutStr;
    int count = 0;
    while (bitStr.length>count * 5)
    {
        string eachStr;
        for (int i = 0; i < 5; i++)
        {
            eachStr.push_back(bitStr.at(count + i));
        }
        int refer = 0;
        for (int j = 0; j < 5; j++)
        {
            refer = refer * 2 + (eachStr[j] - ‘0‘);
        }
        outPutStr.push_back(base32_encode[refer]);
    }

    if (bitStr.length > count * 5)//push ‘0‘ to fill the rest
    {
        int addTo5 = (count + 1) * 5 - bitStr.length;
        string eachStr;
        for (int i = 0; i < addTo5; i++)
        {
            eachStr.push_back(‘0‘);
        }
        int refer = 0;
        for (int j = 0; j < 5; j++)
        {
            refer = refer * 2 + (bitStr[j] - ‘0‘);
        }
        outPutStr.push_back(base32_encode[refer]);
    }
    return outPutStr;
}

string GeoHash::getIndex(Vec2 po)
{
    string bitX;
    halfDivision(world_size.x, world_size.y, po.x, bitX);

    string bitY;
    halfDivision(world_size.x, world_size.y, po.y, bitY);

    //将xy轴组合,偶数位放y,奇数位放x
    string totalBit;
    for (int i = 0; i < bitX.size(); i++)
    {
        totalBit.push_back(bitY.at(i));
        totalBit.push_back(bitX.at(i));
    }

    return base32Encoding(totalBit);
}
unsigned long GeoHash::getUlIndex(Vec2 po)
{
    string bitX;
    halfDivision(world_size.x, world_size.y, po.x, bitX);

    string bitY;
    halfDivision(world_size.x, world_size.y, po.y, bitY);

    //将xy轴组合,偶数位放y,奇数位放x
    string totalBit;
    for (int i = 0; i < bitX.size(); i++)
    {
        totalBit.push_back(bitY.at(i));
        totalBit.push_back(bitX.at(i));
    }

    bitset<binaryLength> binaryIndex(totalBit);
    return binaryIndex.to_ulong();
}

void GeoHash::halfDivision(double min, double max, double value,string& bit)
{
    if (max - min < precision)
    {
        return;
    }
    if (between(value, min, (min + max) / 2))
    {
        bit += "0";
        halfDivision(value, min, (min + max) / 2, bit);
    }
    else
    {
        bit += "1";
        halfDivision(value, (min + max) / 2, max, bit);
    }
}

std::vector<BaseEntity*> GeoHash::getNeighbors(Vec2 centre, vector<BaseEntity*> preSelectedEntities)
{
    vector<BaseEntity*> temp;
    for_each(preSelectedEntities.cbegin(), preSelectedEntities.cend(), [&temp,centre](BaseEntity* entity){
        if (entity->getGeoHashIndex() == getUlIndex(centre))
        {
            temp.push_back(entity);
        }
    });

    return temp;
}
时间: 2024-10-24 15:44:30

GeoHash补充的相关文章

GeoHash解析及java实现

GeoHash解析请参考这里: http://www.open-open.com/lib/view/open1417940079964.html java实现GeoHash,代码已注释. import java.util.BitSet; import java.util.HashMap; /** * 地理知识补充: Latitude(纬度)[-90, 90],Longitude(经度)[-180, 180] * * @author FengKang 2014-10-03 * */ public

查找最近距离geohash算法(增加周边邻近编号)

接着上一篇文章:查找附近网点geohash算法及实现 (Java版本) http://blog.csdn.net/sunrise_2013/article/details/42024813 参考文档: http://www.slideshare.net/sandeepbhaskar2/geohash  介绍geohash原理及例子 http://geohash.gofreerange.com/    演示实例 http://geohash.gofreerange.com/    周边8格子实例

031医疗项目-模块三:药品供应商目录模块——sql补充知识

这个补充知识有一个点很有必要,视屏上的老师提出一点: 内链接关联查询: 如果表A和表B有一个外键关联 ,可以通过外键进行内链接查询 select dictinfo.*, dicttype.typename from dictinfo, dicttype where dictinfo.typecode = dicttype.typecode --不通过外键,通过groupid查询用户类型的代码结果集,只能查询出一条记录,可以使用内链接 select sysuser.*, dictinfo.info

WebView使用详解(三)——WebChromeClient与LoadData补充

前言: 我不会忘了我 忘了我曾说过一定会得到的梦想 --<老大>小柯 相关文章 1.<WebView使用详解(一)--Native与JS相互调用(附JadX反编译)> 2.<WebView使用详解(二)--WebViewClient与常用事件监听> 一.WebChromeClient 1.概述 (1). 与WebViewClient的区别 很多同学一看到这里有Chrome,立马就会想到google 的Chrome浏览器:这里并不是指Chrome浏览器的意思,而是泛指浏览

Nancy之基于Self Hosting的补充小Demo

前面把Hosting Nancy with ASP.NET.Self Hosting Nancy和Hosting Nancy with OWIN 以demo的形式简单描述了一下. 这篇是为Self Hosting Nancy.和Owin 下面的Self Hosting作个补充. 首先是Self Hosting Nancy的补充: 这里主要是介绍一下Topshelf 官网:http://topshelf-project.com/ GitHub地址:https://github.com/Topshe

故障定位之查找附近点GeoHash研讨

随着移动终端的普及,很多应用都基于LBS功能,附近的某某(餐馆.银行.妹纸等等). 基础数据中,一般保存了目标位置的经纬度:利用用户提供的经纬度,进行对比,从而获得是否在附近. 目标:查找附近的XXX,由近到远返回结果,且结果中有与目标点的距离. 针对查找附近的XXX,提出两个方案,如下: 一.方案A:=================================================================================================

UGC补充

成功案例 WIKI:最大也是最小的百科全书 WIKI指的是一种网上共同协作的超文本系统,可由多人共同对网站内容进行维护和更新,是典型的靠UGC运作的系统.其中,WIKI利用UGC概念,使网站的内容制作和编辑成本最小化,但是能够实现领域知识的积累和最大化. 用户可以通过网页浏览器对WIKI文本进行浏览.创建.更改,与其他超文本系统相比,WIKI有使用方便及开放的特点,所以WIKI系统可以帮助用户在一个社群内共同收集.创作某领域的知识,发布所有领域用户都关心和感兴趣的话题.WIKI使用了UGC概念,

jstl标签 core fmt fn函数使用参考(为第一篇的补充,更为实用)

JSTL标签 参考手册 前言 ========================================================================= JSTL标签库,是日常开发经常使用的,也是众多标签中性能最好的.把常用的内容,放在这里备份一份,随用随查.尽量做到不用查,就可以随手就可以写出来.这算是Java程序员的基本功吧,一定要扎实. JSTL全名为JavaServer Pages Standard Tag Library,目前最新的版本为1.1版.JSTL是由J

使用NHibernate(10) -- 补充(inverse &amp;&amp; cascade)

1,inverse属性的作用: 只有集合标记(set/map/list/array/bag)才有invers属性: 以set为例,set的inverse属性决定是否把对set的改动反应到数据库中去,inverse=false(反应),inverse=true(不反应):默认值是false; one-to-many 和many-to-many都适用: inverse等于false时,对于one-to-many,如果删除"一"方,NH会先执行Update语句来把"多"方