码迷,mamicode.com
首页 > 其他好文 > 详细

GeoHash补充

时间:2016-05-12 21:29:14      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

最近在逛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;
}

GeoHash补充

标签:

原文地址:http://blog.csdn.net/qq_22984991/article/details/51353811

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!