C++写geohash

http://www.cnblogs.com/LBSer/p/3310455.html

http://www.sxrczx.com/pages/my.oschina.net/853294317/blog/296594.html

http://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=5300

受朋友委托写个查找附近人的算法,当然是不会写,不知道从何下手,于是学习了下geohash算法。看懂后开始一步步实现,当然还没有完全写完。不会之处在于:如何对已有的字符串进行前缀匹配的呢?怎么查找附近的人呢?

写了很多注释,怕自己以后看不懂。这也算是第一次体会到算法在工程中的作用。想起以前老师说算法在开发中没用!!表示汗颜、无语。

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string>
  4 #include<string.h>
  5 #include<map>
  6 #include <stdlib.h>
  7 #include <stdio.h>
  8 #include <winsock.h>
  9 #include <mysql.h>
 10 #include <cstring>
 11 using namespace std;
 12 map<string, string> base32;
 13
 14 //将纬度、经度二进制化
 15 //纬度范围(-90, 90)
 16 //经度范围(-180, 180)
 17 //传入w,返回二进制编码
 18 //max_step控制递归次数同时也是二进制编码长度
 19 //注意返回的是逆序的字符串 max_step必须是5的倍数
 20 string geohash_w_bin(double w,double left,double right,int step,int max_step)
 21 {
 22     if (step > max_step)
 23     {
 24         return "";
 25     }
 26     double mid = (left + right)*1.0 / 2;
 27
 28     if (w >= left && w <= mid) {
 29         return geohash_w_bin(w, left, mid,step+1,max_step)+"0";
 30     }
 31     if (w >= mid && w <= right) {
 32         return geohash_w_bin(w, mid, right,step+1,max_step)+"1";
 33     }
 34
 35 }
 36
 37 //合并经纬度
 38 //传入经度和纬度 返回合并的二进制编码
 39 string geohash_merge(string j, string w) {
 40     string s;
 41     for (int i = 0; i <j.size(); i++){
 42         s += j[i];
 43         s += w[i];
 44     }
 45     return s;
 46 }
 47
 48 //二进制编码base32化
 49 string geohash_base32(string s) {
 50     string temp;
 51     string ans;
 52     for (int i = 0; i < s.size(); i++) {
 53         temp += s[i];
 54         if ((i + 1) % 5 == 0) {
 55             ans+=base32[temp];
 56             temp = "";
 57         }
 58     }
 59
 60     return ans;
 61 }
 62
 63 //*****************
 64 //将经纬度转为base32 返回base32编码
 65 //w为纬度 j为经度
 66 //*****************
 67 string geohash(double j, double w) {
 68     string s_w="", s_j="";
 69     string s="", ss="";
 70
 71     s_w = geohash_w_bin(w, -90, 90, 1, 30);
 72     s_j = geohash_w_bin(j, -180, 180, 1, 30);
 73
 74     reverse(s_w.begin(), s_w.end());
 75     reverse(s_j.begin(), s_j.end());
 76
 77     s = geohash_merge(s_j, s_w);
 78     s= geohash_base32(s);
 79     return s;
 80 }
 81
 82 //有返回值的数据库写入
 83 MYSQL_RES * executeQuery(char *sql)
 84 {
 85     MYSQL* pConn = mysql_init(0);
 86     if (!mysql_real_connect(pConn, "localhost", "root", "root", "study1", 0, 0, 0))
 87     {
 88         goto error;
 89     }
 90     if (mysql_query(pConn, "set names gbk"))
 91     {
 92         goto error;
 93     }
 94     if (mysql_query(pConn, sql))
 95     {
 96         goto error;
 97     }
 98
 99         MYSQL_RES *result = mysql_store_result(pConn);
100         mysql_close(pConn);
101         return result;
102
103 error:
104         cout << "执行出错 " << mysql_error(pConn)<<endl;
105     //fprintf(cgiOut, "执行出错 %s", mysql_error(pConn));
106     //printf("执行出错 %s",mysql_error(pConn));
107 exit:
108     mysql_close(pConn);
109 }
110
111 //无返回值的数据库写入
112 void executeNonQuery(char * sql)
113 {
114     MYSQL* pConn = mysql_init(0);
115     if (!mysql_real_connect(pConn, "localhost", "root", "root", "study1", 0, 0, 0))
116     {
117         goto error;
118     }
119     if (mysql_query(pConn, "set names gbk"))
120     {
121         goto error;
122     }
123     if (mysql_query(pConn, sql))
124     {
125         goto error;
126     }
127     goto exit;
128 error:
129     cout << "执行出错 " << mysql_error(pConn) << endl;
130     /*cgiHeaderContentType("text/html;charset=gbk");
131     fprintf(cgiOut, "执行出错 %s", mysql_error(pConn));*/
132     //printf("执行出错 %s",mysql_error(pConn));
133 exit:
134     mysql_close(pConn);
135 }
136
137
138 //字符串截取函数
139 string jiequ(string s, int l, int r) {
140     string temp;
141     for (int i = 0; i < r; i++)
142     {
143         temp += s[i];
144     }
145     return temp;
146 }
147
148
149 //输入base32编码,结果打印在屏幕上
150 //查询编码前缀相同的
151 void geohash_search(string base32)
152 {
153     for (int i = base32.size()-3; i > 0; i--)
154     {
155         string temp_base32 = jiequ(base32, 0, i);
156         const char *temp_c_base32 = temp_base32.c_str();
157         char sql[1024]; char *c = "%";
158         int f = 0;
159
160         sprintf(sql, "select * from t_theatre where base32 like ‘%s%s‘", temp_c_base32,c);
161         MYSQL_RES *result = executeQuery(sql);
162         MYSQL_ROW row;
163
164         while (row = mysql_fetch_row(result))
165         {
166             char *base32 = row[1];
167             char *name = row[2];
168             cout << base32 << " " << name << endl;
169             //f = 1;
170         }
171
172         /*if (f) {
173             return;
174         }*/
175
176     }
177
178
179
180
181 }
182 int main()
183 {
184     base32["00000"] = "0";
185     base32["00001"] = "1";
186
187     base32["00010"] = "2";
188     base32["00011"] = "3";
189
190     base32["00100"] = "4";
191     base32["00101"] = "5";
192     base32["00110"] = "6";
193     base32["00111"] = "7";
194
195     base32["01000"] = "8";
196     base32["01001"] = "9";
197     base32["01010"] = "b";//10
198     base32["01011"] = "c";//11
199     base32["01100"] = "d";//12
200     base32["01101"] = "e";//13
201     base32["01110"] = "f";//14
202     base32["01111"] = "g";//15
203
204     base32["10000"] = "h";//16
205     base32["10001"] = "j";//17
206     base32["10010"] = "k";//18
207     base32["10011"] = "m";//19
208     base32["10100"] = "n";//20
209     base32["10101"] = "p";//21
210     base32["10110"] = "q";//22
211     base32["10111"] = "r";//23
212     base32["11000"] = "s";//24
213     base32["11001"] = "t";//25
214     base32["11010"] = "u";//26
215     base32["11011"] = "v";//27
216     base32["11100"] = "w";//28
217     base32["11101"] = "x";//29
218     base32["11110"] = "y";//30
219     base32["11111"] = "z";//31
220
221     geohash_search("wttf1y0ewmt3");
222
223     //select * from where like‘wttc%‘
224     //geohash_search("select * from t_theatre where base32 like ‘wttc%‘");
225
226
227
228     /*while (1) {
229         double w, j; char name[128], sql[1024];
230         cin >> j >> w>>name;
231
232         string base32=geohash(j,w);
233         const char *ch = base32.c_str();
234
235         sprintf(sql, "insert into t_theatre(base32,name) values(‘%s‘,‘%s‘)", ch,name);
236         executeNonQuery(sql);
237     }*/
238
239
240     ////insert into t_theatre(base32) values()
241     //char sql[] = "insert into t_theatre(base32) values(‘klkl‘)";
242     //executeNonQuery(sql);
243     //120.677252 31.316891
244     //cout << geohash(120.677252, 31.316891) << " 精品酒店" << endl;
245     //cout << geohash(120.674144, 31.316012) << " 星海实验中学" << endl;
246     //    cout<< geohash(120.648933, 31.374867) << " 相称去政府" <<endl;
247     //cout << geohash(120.683958, 31.391834) << " 我的位置" <<endl;
248
249     /*cout<<"111001001100011111101011100011000010110000010001010001000100";*/
250     ////double a = 90.0;
251     //string s=geohash_w_bin(104.031601, -180, 180, 1,30);
252     //reverse(s.begin(), s.end());
253     //cout << s<<endl;
254     ////cout << "101010111001001000100101101010";
255     ////cout << "110010011111101001100000000000";
256
257     getchar();
258     return 0;
259 }

最后希望自己踏实学习算法。一张纸叠n次可以比天高,而n张纸叠在一起就不一定了。

时间: 2024-10-13 03:08:48

C++写geohash的相关文章

GeoHash

GeoHash Geohash is a latitude/longitude geocode system invented by Gustavo Niemeyer when writing the web service at geohash.org, and put into the public domain. It is a hierarchical spatial data structure which subdivides space into buckets of grid s

GeoHash补充

最近在逛cocoa的时候发现有一些小细节可以优化的 - 我们在设定二分精度时可以设置精度为个体的影响范围为精度,这样我们在搜索的时候可以直接用"=="而非"like" - 我们可以不用进行base32编码,直接将其转化为unsinged long,可以大大减少计算,数据库使用字符串是因为很多数据库对字符串类型有很好的支持,c上面用字符串效率低得可以 - 之前那个写得仓促,有很多错误没整理,这次这个是完整版,当然,只是对我的游戏进行了优化,其他实现需要开发者动起手来

高效的多维空间点索引算法 — Geohash 和 Google S2

原文地址:https://www.jianshu.com/p/7332dcb978b2 引子 每天我们晚上加班回家,可能都会用到滴滴或者共享单车.打开 app 会看到如下的界面: app 界面上会显示出自己附近一个范围内可用的出租车或者共享单车.假设地图上会显示以自己为圆心,5公里为半径,这个范围内的车.如何实现呢?最直观的想法就是去数据库里面查表,计算并查询车距离用户小于等于5公里的,筛选出来,把数据返回给客户端. 这种做法比较笨,一般也不会这么做.为什么呢?因为这种做法需要对整个表里面的每一

Geohash 基本知识及 .NET 下计算相邻8个区域编码

目录 一.简介 二.计算方法 三.GeoHash的精度 四.查找相邻8个区域的Geohash编码(.NET) 最近项目中需要搜索周边的 POI 信息,查找的过程中了解到了 Geohash ,这这里记录下以便自己牢记也和大家分享下. 一.简介 GeoHash是一种地址编码方法.他能够把二维的空间经纬度数据编码成一个字符串.GeoHash具有以下特点: 1.GeoHash用一个字符串表示经度和纬度两个坐标.在数据库中可以实现在一列上应用索引 2.GeoHash表示的并不是一个点,而是一个区域: 3.

python3,从算法的视觉上去看待geohash源码

1.geohash有什么用途呢?这几天刚好有个测试任务是关于设备信息位置处理的,里面提及到geohash:抱着测试的警觉性,打算研读一下这个geohash到底是什么?Geohash 是一种地理编码系统,地球上的任何一个物体可以通过经纬度来定位其在地球位置,而作为程序猿通过经纬度两个信息很难(或者说很麻烦)在数据层面上进行检索和比对,这个时候geohash编码系统出现了,更可以说geohash是一种算法可以把经纬度坐标转换为短字符串.当所有的位置信息都可以通过一个字符串代替时,大大提高了地址检索和

Python:hashlib加密模块,flask模块写登录接口

hashlib模块 主要用于加密相关的操作,(比如说加密字符串)在python3的版本里,代替了md5和sha模块,主要提供 sha1, sha224, sha256, sha384, sha512 ,md5 这些加密方式 import  hashlib m = hashlib.md5()   #用md5加密的方式(md5加密后无法解密),创建一个md5的对象 m.update(b"Hello")  #b代表二进制字节bytes,把字符串hello转成字节,然后加密:用b给一个变量转换

三行写出莫比乌斯函数(HDU1695)

莫比乌斯函数是可以在三行内写出来的 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1000000; 5 int mu[maxn+10],T; 6 void Mobius(){ 7 for(int d=1,k;d<=maxn;++d) 8 for(mu[1]=1,k=d<<1;k<=maxn;mu[k]=mu[k]-mu[d],k+=d);

在windows 下使用eclipse进行编译和烧写

eclipse IDE是一款开源的前端编程软件,它提供了编写,编译和调试ESP-IDF项目的图形集成开发环境. 首先在https://www.obeo.fr/en/eclipse-download?INSTALLER-WIN64中选择需要的对应位数的eclipse. 然后在http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载eclipse运行所需的java环境. 在安装是选择 点

昨天没写今天补上

恩因为今天要考试所以昨天晚上在复习,没来得及写,现在补上. 昨天依旧是循环,被虐了整整一天! 到现在仍然不知道for里的循环体怎么写.... 感到人生无望...(不想说什么了粘题吧) p1032;#include〈iostream〉 using namespace std; int main () { long long a,b=0,c,d,sum=0; cin>>a; while (a>0) { d=a/10; sum++; for(int i=1;i<=sum;i++) { c