dynamodb_geo 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 34aa9b9ef408a4556afbc74c173c40ccb5932fc0a47d29a3e519c0cb803fe043
4
+ data.tar.gz: f7dd0b6c92a94e7da2c14417ee67296af8f04f86b768bfb2c8acd32572bdd8e9
5
+ SHA512:
6
+ metadata.gz: 9d3d2f46f82c2e9ece62dc006dbda654753d01fb7d82d06d803448171a9852cef5933ce814ce20057017ed9fcb318b9f6ff37dbe79cb7f5167c82aea65f3258c
7
+ data.tar.gz: 8df26e8041dfbb59020496faf2ae5014fae971b9b7d0f84274ff4eeb58c0c70487623a7a44343a4443647d08cfe72acc48c8115004c287853c2896dc46e91b9a
@@ -0,0 +1,55 @@
1
+ # DynamoDB_Geo
2
+
3
+
4
+ # Geohashing
5
+ Includes a Geohash implimentation written in C
6
+ <https://github.com/simplegeo/libgeohash>
7
+
8
+
9
+ ### Methods
10
+ Encoding a Geohash
11
+
12
+ Description: Takes in a latitude, longitude, and precision, and returns a geohash as a string
13
+ Input: latitude => Number
14
+ longitude => Number
15
+ precision => Number
16
+ Output: Geohash => String
17
+
18
+ Geohash.encode(lat, long, precision) => String
19
+
20
+
21
+ Decoding a Geohash
22
+
23
+ Description: Takes in a hash, and returns a Geocoord
24
+ Input: Geohash => String
25
+ Output: Geocoord => Object
26
+
27
+ Geohash.decode(hash) => Geocoord
28
+
29
+ Viewing all my neighbours
30
+
31
+ Description: Takes in a Geohash and shows the surrounding 8 neighbours
32
+
33
+ Physical representation:
34
+ NW N NE 7 0 1
35
+ W X E => 6 X 2
36
+ SW S SE 5 4 3
37
+
38
+ Flat representation:
39
+ N NE E SE S SW W NW
40
+ 0 1 2 3 4 5 6 7
41
+ Input: Geohash => String
42
+ Output: Array[Geocoord]
43
+
44
+ Geohash.neighbours(hash) => Array[Geohash]
45
+
46
+ Get width and height about a specific precision
47
+
48
+ Description: Takes in a precision value, returns the height and width of the box
49
+ Input: precision => Number
50
+ Output: Dimension => Object
51
+
52
+ Geohash.dimensions(precision) => Dimension
53
+
54
+ #### Geocoord(Object) => attr_accessor: :latitude, :longitude, :north, :south, :east, :west, :dimension
55
+ #### Dimension(Object) => attr_accessor: :length, :width
@@ -0,0 +1,266 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ # V=0 quiet, V=1 verbose. other values don't work.
5
+ V = 0
6
+ Q1 = $(V:1=)
7
+ Q = $(Q1:0=@)
8
+ ECHO1 = $(V:1=@ :)
9
+ ECHO = $(ECHO1:0=@ echo)
10
+ NULLCMD = :
11
+
12
+ #### Start of system configuration section. ####
13
+
14
+ srcdir = .
15
+ topdir = /home/justin/.rvm/rubies/ruby-2.7.0/include/ruby-2.7.0
16
+ hdrdir = $(topdir)
17
+ arch_hdrdir = /home/justin/.rvm/rubies/ruby-2.7.0/include/ruby-2.7.0/x86_64-linux
18
+ PATH_SEPARATOR = :
19
+ VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
20
+ prefix = $(DESTDIR)/home/justin/.rvm/rubies/ruby-2.7.0
21
+ rubysitearchprefix = $(rubylibprefix)/$(sitearch)
22
+ rubyarchprefix = $(rubylibprefix)/$(arch)
23
+ rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
24
+ exec_prefix = $(prefix)
25
+ vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
26
+ sitearchhdrdir = $(sitehdrdir)/$(sitearch)
27
+ rubyarchhdrdir = $(rubyhdrdir)/$(arch)
28
+ vendorhdrdir = $(rubyhdrdir)/vendor_ruby
29
+ sitehdrdir = $(rubyhdrdir)/site_ruby
30
+ rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
31
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
32
+ vendorlibdir = $(vendordir)/$(ruby_version)
33
+ vendordir = $(rubylibprefix)/vendor_ruby
34
+ sitearchdir = $(sitelibdir)/$(sitearch)
35
+ sitelibdir = $(sitedir)/$(ruby_version)
36
+ sitedir = $(rubylibprefix)/site_ruby
37
+ rubyarchdir = $(rubylibdir)/$(arch)
38
+ rubylibdir = $(rubylibprefix)/$(ruby_version)
39
+ sitearchincludedir = $(includedir)/$(sitearch)
40
+ archincludedir = $(includedir)/$(arch)
41
+ sitearchlibdir = $(libdir)/$(sitearch)
42
+ archlibdir = $(libdir)/$(arch)
43
+ ridir = $(datarootdir)/$(RI_BASE_NAME)
44
+ mandir = $(datarootdir)/man
45
+ localedir = $(datarootdir)/locale
46
+ libdir = $(exec_prefix)/lib
47
+ psdir = $(docdir)
48
+ pdfdir = $(docdir)
49
+ dvidir = $(docdir)
50
+ htmldir = $(docdir)
51
+ infodir = $(datarootdir)/info
52
+ docdir = $(datarootdir)/doc/$(PACKAGE)
53
+ oldincludedir = $(DESTDIR)/usr/include
54
+ includedir = $(prefix)/include
55
+ runstatedir = $(localstatedir)/run
56
+ localstatedir = $(prefix)/var
57
+ sharedstatedir = $(prefix)/com
58
+ sysconfdir = $(prefix)/etc
59
+ datadir = $(datarootdir)
60
+ datarootdir = $(prefix)/share
61
+ libexecdir = $(exec_prefix)/libexec
62
+ sbindir = $(exec_prefix)/sbin
63
+ bindir = $(exec_prefix)/bin
64
+ archdir = $(rubyarchdir)
65
+
66
+
67
+ CC_WRAPPER =
68
+ CC = gcc
69
+ CXX = g++
70
+ LIBRUBY = $(LIBRUBY_SO)
71
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
72
+ LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)
73
+ LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS)
74
+ empty =
75
+ OUTFLAG = -o $(empty)
76
+ COUTFLAG = -o $(empty)
77
+ CSRCFLAG = $(empty)
78
+
79
+ RUBY_EXTCONF_H = extconf.h
80
+ cflags = $(optflags) $(debugflags) $(warnflags)
81
+ cxxflags =
82
+ optflags = -O3
83
+ debugflags = -ggdb3
84
+ warnflags = -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable
85
+ cppflags =
86
+ CCDLFLAGS = -fPIC
87
+ CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG)
88
+ INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
89
+ DEFS =
90
+ CPPFLAGS = -DRUBY_EXTCONF_H=\"$(RUBY_EXTCONF_H)\" $(DEFS) $(cppflags)
91
+ CXXFLAGS = $(CCDLFLAGS) -g -O2 $(ARCH_FLAG)
92
+ ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic
93
+ dldflags = -Wl,--compress-debug-sections=zlib
94
+ ARCH_FLAG =
95
+ DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
96
+ LDSHARED = $(CC) -shared
97
+ LDSHAREDXX = $(CXX) -shared
98
+ AR = ar
99
+ EXEEXT =
100
+
101
+ RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
102
+ RUBY_SO_NAME = ruby
103
+ RUBYW_INSTALL_NAME =
104
+ RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
105
+ RUBYW_BASE_NAME = rubyw
106
+ RUBY_BASE_NAME = ruby
107
+
108
+ arch = x86_64-linux
109
+ sitearch = $(arch)
110
+ ruby_version = 2.7.0
111
+ ruby = $(bindir)/$(RUBY_BASE_NAME)
112
+ RUBY = $(ruby)
113
+ ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h $(RUBY_EXTCONF_H)
114
+
115
+ RM = rm -f
116
+ RM_RF = $(RUBY) -run -e rm -- -rf
117
+ RMDIRS = rmdir --ignore-fail-on-non-empty -p
118
+ MAKEDIRS = /usr/bin/mkdir -p
119
+ INSTALL = /usr/bin/install -c
120
+ INSTALL_PROG = $(INSTALL) -m 0755
121
+ INSTALL_DATA = $(INSTALL) -m 644
122
+ COPY = cp
123
+ TOUCH = exit >
124
+
125
+ #### End of system configuration section. ####
126
+
127
+ preload =
128
+ libpath = . $(libdir)
129
+ LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir)
130
+ DEFFILE =
131
+
132
+ CLEANFILES = mkmf.log
133
+ DISTCLEANFILES =
134
+ DISTCLEANDIRS =
135
+
136
+ extout =
137
+ extout_prefix =
138
+ target_prefix = /dynamodb-geo
139
+ LOCAL_LIBS =
140
+ LIBS = $(LIBRUBYARG_SHARED) -lm -lc
141
+ ORIG_SRCS = geohash.c geohash_wrapper.c
142
+ SRCS = $(ORIG_SRCS)
143
+ OBJS = geohash.o geohash_wrapper.o
144
+ HDRS = $(srcdir)/extconf.h $(srcdir)/geohash.h
145
+ LOCAL_HDRS =
146
+ TARGET = dynamodb-geo
147
+ TARGET_NAME = dynamodb
148
+ TARGET_ENTRY = Init_$(TARGET_NAME)
149
+ DLLIB = $(TARGET).so
150
+ EXTSTATIC =
151
+ STATIC_LIB =
152
+
153
+ TIMESTAMP_DIR = .
154
+ BINDIR = $(bindir)
155
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
156
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
157
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
158
+ HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
159
+ ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
160
+ TARGET_SO_DIR =
161
+ TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
162
+ CLEANLIBS = $(TARGET_SO)
163
+ CLEANOBJS = *.o *.bak
164
+
165
+ all: $(DLLIB)
166
+ static: $(STATIC_LIB)
167
+ .PHONY: all install static install-so install-rb
168
+ .PHONY: clean clean-so clean-static clean-rb
169
+
170
+ clean-static::
171
+ clean-rb-default::
172
+ clean-rb::
173
+ clean-so::
174
+ clean: clean-so clean-static clean-rb-default clean-rb
175
+ -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
176
+
177
+ distclean-rb-default::
178
+ distclean-rb::
179
+ distclean-so::
180
+ distclean-static::
181
+ distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
182
+ -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
183
+ -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
184
+ -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
185
+
186
+ realclean: distclean
187
+ install: install-so install-rb
188
+
189
+ install-so: $(DLLIB) $(TIMESTAMP_DIR)/.sitearchdir.-.dynamodb-geo.time
190
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
191
+ clean-static::
192
+ -$(Q)$(RM) $(STATIC_LIB)
193
+ install-rb: pre-install-rb do-install-rb install-rb-default
194
+ install-rb-default: pre-install-rb-default do-install-rb-default
195
+ pre-install-rb: Makefile
196
+ pre-install-rb-default: Makefile
197
+ do-install-rb:
198
+ do-install-rb-default:
199
+ pre-install-rb-default:
200
+ @$(NULLCMD)
201
+ $(TIMESTAMP_DIR)/.sitearchdir.-.dynamodb-geo.time:
202
+ $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
203
+ $(Q) $(TOUCH) $@
204
+
205
+ site-install: site-install-so site-install-rb
206
+ site-install-so: install-so
207
+ site-install-rb: install-rb
208
+
209
+ .SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
210
+
211
+ .cc.o:
212
+ $(ECHO) compiling $(<)
213
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
214
+
215
+ .cc.S:
216
+ $(ECHO) translating $(<)
217
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
218
+
219
+ .mm.o:
220
+ $(ECHO) compiling $(<)
221
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
222
+
223
+ .mm.S:
224
+ $(ECHO) translating $(<)
225
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
226
+
227
+ .cxx.o:
228
+ $(ECHO) compiling $(<)
229
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
230
+
231
+ .cxx.S:
232
+ $(ECHO) translating $(<)
233
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
234
+
235
+ .cpp.o:
236
+ $(ECHO) compiling $(<)
237
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
238
+
239
+ .cpp.S:
240
+ $(ECHO) translating $(<)
241
+ $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
242
+
243
+ .c.o:
244
+ $(ECHO) compiling $(<)
245
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
246
+
247
+ .c.S:
248
+ $(ECHO) translating $(<)
249
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
250
+
251
+ .m.o:
252
+ $(ECHO) compiling $(<)
253
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
254
+
255
+ .m.S:
256
+ $(ECHO) translating $(<)
257
+ $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
258
+
259
+ $(TARGET_SO): $(OBJS) Makefile
260
+ $(ECHO) linking shared-object dynamodb-geo/$(DLLIB)
261
+ -$(Q)$(RM) $(@)
262
+ $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
263
+
264
+
265
+
266
+ $(OBJS): $(HDRS) $(ruby_headers)
@@ -0,0 +1,3 @@
1
+ #ifndef EXTCONF_H
2
+ #define EXTCONF_H
3
+ #endif
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ create_header
3
+ create_makefile('geohash_wrapper/geohash_wrapper')
@@ -0,0 +1,293 @@
1
+ /*
2
+ * geohash.c
3
+ * libgeohash
4
+ *
5
+ * Created by Derek Smith on 10/6/09.
6
+ * Copyright (c) 2010, SimpleGeo
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are met:
11
+
12
+ * Redistributions of source code must retain the above copyright notice, this list
13
+ * of conditions and the following disclaimer. Redistributions in binary form must
14
+ * reproduce the above copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided with the distribution.
16
+ * Neither the name of the SimpleGeo nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without specific prior
18
+ * written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23
+ * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include "geohash.h"
32
+
33
+ #include <stdlib.h>
34
+ #include <string.h>
35
+ #include <stdio.h>
36
+
37
+ #define MAX_LAT 90.0
38
+ #define MIN_LAT -90.0
39
+
40
+ #define MAX_LONG 180.0
41
+ #define MIN_LONG -180.0
42
+
43
+ #define NORTH 0
44
+ #define EAST 1
45
+ #define SOUTH 2
46
+ #define WEST 3
47
+
48
+ #define LENGTH_OF_DEGREE 111100 // meters
49
+
50
+ typedef struct IntervalStruct {
51
+
52
+ double high;
53
+ double low;
54
+
55
+ } Interval;
56
+
57
+
58
+ /* Normal 32 characer map used for geohashing */
59
+ static char char_map[32] = "0123456789bcdefghjkmnpqrstuvwxyz";
60
+
61
+ /*
62
+ * The follow character maps were created by Dave Troy and used in his Javascript Geohashing
63
+ * library. http://github.com/davetroy/geohash-js
64
+ */
65
+ static char *even_neighbors[] = {"p0r21436x8zb9dcf5h7kjnmqesgutwvy",
66
+ "bc01fg45238967deuvhjyznpkmstqrwx",
67
+ "14365h7k9dcfesgujnmqp0r2twvyx8zb",
68
+ "238967debc01fg45kmstqrwxuvhjyznp"
69
+ };
70
+
71
+ static char *odd_neighbors[] = {"bc01fg45238967deuvhjyznpkmstqrwx",
72
+ "p0r21436x8zb9dcf5h7kjnmqesgutwvy",
73
+ "238967debc01fg45kmstqrwxuvhjyznp",
74
+ "14365h7k9dcfesgujnmqp0r2twvyx8zb"
75
+ };
76
+
77
+ static char *even_borders[] = {"prxz", "bcfguvyz", "028b", "0145hjnp"};
78
+ static char *odd_borders[] = {"bcfguvyz", "prxz", "0145hjnp", "028b"};
79
+
80
+ unsigned int index_for_char(char c, char *string) {
81
+
82
+ int index = -1;
83
+ int string_amount = strlen(string);
84
+ int i;
85
+ for(i = 0; i < string_amount; i++) {
86
+
87
+ if(c == string[i]) {
88
+
89
+ index = i;
90
+ break;
91
+ }
92
+
93
+ }
94
+
95
+ return index;
96
+ }
97
+
98
+ char* get_neighbor(char *hash, int direction) {
99
+
100
+ int hash_length = strlen(hash);
101
+
102
+ char last_char = hash[hash_length - 1];
103
+
104
+ int is_odd = hash_length % 2;
105
+ char **border = is_odd ? odd_borders : even_borders;
106
+ char **neighbor = is_odd ? odd_neighbors : even_neighbors;
107
+
108
+ char *base = malloc(sizeof(char) * 1);
109
+ base[0] = '\0';
110
+ strncat(base, hash, hash_length - 1);
111
+
112
+ if(index_for_char(last_char, border[direction]) != -1)
113
+ base = get_neighbor(base, direction);
114
+
115
+ int neighbor_index = index_for_char(last_char, neighbor[direction]);
116
+ last_char = char_map[neighbor_index];
117
+
118
+ char *last_hash = malloc(sizeof(char) * 2);
119
+ last_hash[0] = last_char;
120
+ last_hash[1] = '\0';
121
+ strcat(base, last_hash);
122
+ free(last_hash);
123
+
124
+ return base;
125
+ }
126
+
127
+ char* geohash_encode(double lat, double lng, int precision) {
128
+
129
+ if(precision < 1 || precision > 12)
130
+ precision = 6;
131
+
132
+ char* hash = NULL;
133
+
134
+ if(lat <= 90.0 && lat >= -90.0 && lng <= 180.0 && lng >= -180.0) {
135
+
136
+ hash = (char*)malloc(sizeof(char) * (precision + 1));
137
+ hash[precision] = '\0';
138
+
139
+ precision *= 5.0;
140
+
141
+ Interval lat_interval = {MAX_LAT, MIN_LAT};
142
+ Interval lng_interval = {MAX_LONG, MIN_LONG};
143
+
144
+ Interval *interval;
145
+ double coord, mid;
146
+ int is_even = 1;
147
+ unsigned int hashChar = 0;
148
+ int i;
149
+ for(i = 1; i <= precision; i++) {
150
+
151
+ if(is_even) {
152
+
153
+ interval = &lng_interval;
154
+ coord = lng;
155
+
156
+ } else {
157
+
158
+ interval = &lat_interval;
159
+ coord = lat;
160
+ }
161
+
162
+ mid = (interval->low + interval->high) / 2.0;
163
+ hashChar = hashChar << 1;
164
+
165
+ if(coord > mid) {
166
+
167
+ interval->low = mid;
168
+ hashChar |= 0x01;
169
+
170
+ } else
171
+ interval->high = mid;
172
+
173
+ if(!(i % 5)) {
174
+
175
+ hash[(i - 1) / 5] = char_map[hashChar];
176
+ hashChar = 0;
177
+
178
+ }
179
+
180
+ is_even = !is_even;
181
+ }
182
+
183
+
184
+ }
185
+
186
+ return hash;
187
+ }
188
+
189
+ GeoCoord geohash_decode(char *hash) {
190
+
191
+ GeoCoord coordinate = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
192
+
193
+ if(hash) {
194
+
195
+ int char_amount = strlen(hash);
196
+
197
+ if(char_amount) {
198
+
199
+ unsigned int char_mapIndex;
200
+ Interval lat_interval = {MAX_LAT, MIN_LAT};
201
+ Interval lng_interval = {MAX_LONG, MIN_LONG};
202
+ Interval *interval;
203
+
204
+ int is_even = 1;
205
+ double delta;
206
+ int i, j;
207
+ for(i = 0; i < char_amount; i++) {
208
+
209
+ char_mapIndex = index_for_char(hash[i], (char*)char_map);
210
+
211
+ if(char_mapIndex < 0)
212
+ break;
213
+
214
+ // Interpret the last 5 bits of the integer
215
+ for(j = 0; j < 5; j++) {
216
+
217
+ interval = is_even ? &lng_interval : &lat_interval;
218
+
219
+ delta = (interval->high - interval->low) / 2.0;
220
+
221
+ if((char_mapIndex << j) & 0x0010)
222
+ interval->low += delta;
223
+ else
224
+ interval->high -= delta;
225
+
226
+ is_even = !is_even;
227
+ }
228
+
229
+ }
230
+
231
+ coordinate.latitude = lat_interval.high - ((lat_interval.high - lat_interval.low) / 2.0);
232
+ coordinate.longitude = lng_interval.high - ((lng_interval.high - lng_interval.low) / 2.0);
233
+
234
+ coordinate.north = lat_interval.high;
235
+ coordinate.east = lng_interval.high;
236
+ coordinate.south = lat_interval.low;
237
+ coordinate.west = lng_interval.low;
238
+ }
239
+ }
240
+
241
+ return coordinate;
242
+ }
243
+
244
+
245
+ char** geohash_neighbors(char *hash) {
246
+
247
+ char** neighbors = NULL;
248
+
249
+ if(hash) {
250
+
251
+ // N, NE, E, SE, S, SW, W, NW
252
+ neighbors = (char**)malloc(sizeof(char*) * 8);
253
+
254
+ neighbors[0] = get_neighbor(hash, NORTH);
255
+ neighbors[1] = get_neighbor(neighbors[0], EAST);
256
+ neighbors[2] = get_neighbor(hash, EAST);
257
+ neighbors[3] = get_neighbor(neighbors[2], SOUTH);
258
+ neighbors[4] = get_neighbor(hash, SOUTH);
259
+ neighbors[5] = get_neighbor(neighbors[4], WEST);
260
+ neighbors[6] = get_neighbor(hash, WEST);
261
+ neighbors[7] = get_neighbor(neighbors[6], NORTH);
262
+
263
+ }
264
+
265
+ return neighbors;
266
+ }
267
+
268
+ GeoBoxDimension geohash_dimensions_for_precision(int precision) {
269
+
270
+ GeoBoxDimension dimensions = {0.0, 0.0};
271
+
272
+ if(precision > 0) {
273
+
274
+ int lat_times_to_cut = precision * 5 / 2;
275
+ int lng_times_to_cut = precision * 5 / 2 + (precision % 2 ? 1 : 0);
276
+
277
+ double width = 360.0;
278
+ double height = 180.0;
279
+
280
+ int i;
281
+ for(i = 0; i < lat_times_to_cut; i++)
282
+ height /= 2.0;
283
+
284
+ for(i = 0; i < lng_times_to_cut; i++)
285
+ width /= 2.0;
286
+
287
+ dimensions.width = width;
288
+ dimensions.height = height;
289
+
290
+ }
291
+
292
+ return dimensions;
293
+ }
@@ -0,0 +1,77 @@
1
+ /*
2
+ * geohash.h
3
+ * libgeohash
4
+ *
5
+ * Created by Derek Smith on 10/6/09.
6
+ * Copyright (c) 2010, SimpleGeo
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are met:
11
+
12
+ * Redistributions of source code must retain the above copyright notice, this list
13
+ * of conditions and the following disclaimer. Redistributions in binary form must
14
+ * reproduce the above copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided with the distribution.
16
+ * Neither the name of the SimpleGeo nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without specific prior
18
+ * written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23
+ * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ // Metric in meters
32
+ typedef struct GeoBoxDimensionStruct {
33
+
34
+ double height;
35
+ double width;
36
+
37
+ } GeoBoxDimension;
38
+
39
+ typedef struct GeoCoordStruct {
40
+
41
+ double latitude;
42
+ double longitude;
43
+
44
+ double north;
45
+ double east;
46
+ double south;
47
+ double west;
48
+
49
+ GeoBoxDimension dimension;
50
+
51
+ } GeoCoord;
52
+
53
+ /*
54
+ * Creates a the hash at the specified precision. If precision is set to 0.
55
+ * or less than it defaults to 12.
56
+ */
57
+ extern char* geohash_encode(double lat, double lng, int precision);
58
+
59
+ /*
60
+ * Returns the latitude and longitude used to create the hash along with
61
+ * the bounding box for the encoded coordinate.
62
+ */
63
+ extern GeoCoord geohash_decode(char* hash);
64
+
65
+ /*
66
+ * Return an array of geohashes that represent the neighbors of the passed
67
+ * in value. The neighbors are indexed as followed:
68
+ *
69
+ * N, NE, E, SE, S, SW, W, NW
70
+ * 0, 1, 2, 3, 4, 5, 6, 7
71
+ */
72
+ extern char** geohash_neighbors(char* hash);
73
+
74
+ /*
75
+ * Returns the width and height of a precision value.
76
+ */
77
+ extern GeoBoxDimension geohash_dimensions_for_precision(int precision);
@@ -0,0 +1,70 @@
1
+ #include "ruby.h"
2
+ #include "extconf.h"
3
+ #include "geohash.h"
4
+ #include <stdio.h>
5
+
6
+ void Init_geohash_wrapper();
7
+ VALUE wrap_geohash_encode(VALUE self, VALUE lat, VALUE lng, VALUE precision);
8
+ VALUE wrap_geohash_decode(VALUE self, VALUE hash);
9
+ VALUE wrap_geohash_neighbors(VALUE self, VALUE hash);
10
+ VALUE wrap_geohash_dimensions_for_precision(VALUE self, VALUE precision);
11
+
12
+
13
+ void Init_geohash_wrapper()
14
+ {
15
+ VALUE Geohash;
16
+ Geohash = rb_define_class("Geohash", rb_cObject);
17
+
18
+ rb_define_singleton_method(Geohash, "encode", wrap_geohash_encode, 3);
19
+ rb_define_singleton_method(Geohash, "wrap_decode", wrap_geohash_decode, 1);
20
+ rb_define_singleton_method(Geohash, "neighbours", wrap_geohash_neighbors, 1);
21
+ rb_define_singleton_method(Geohash, "dimensions_for_precision", wrap_geohash_dimensions_for_precision, 1);
22
+ }
23
+
24
+ VALUE wrap_geohash_encode(VALUE self, VALUE lat, VALUE lng, VALUE precision) {
25
+ return rb_str_new_cstr(geohash_encode(NUM2DBL(lat), NUM2DBL(lng), NUM2INT(precision)));
26
+ }
27
+
28
+ VALUE wrap_geohash_decode(VALUE self, VALUE hash) {
29
+ GeoCoord decode;
30
+ VALUE r_hash = rb_hash_new();
31
+ VALUE r_dimension = rb_hash_new();
32
+
33
+ decode = geohash_decode(StringValueCStr(hash));
34
+
35
+ rb_hash_aset(r_dimension, rb_str_new2("height"), DBL2NUM(decode.dimension.height));
36
+ rb_hash_aset(r_dimension, rb_str_new2("width"), DBL2NUM(decode.dimension.width));
37
+
38
+ rb_hash_aset(r_hash, rb_str_new2("latitude"), DBL2NUM(decode.latitude));
39
+ rb_hash_aset(r_hash, rb_str_new2("longitude"), DBL2NUM(decode.longitude));
40
+ rb_hash_aset(r_hash, rb_str_new2("north"), DBL2NUM(decode.north));
41
+ rb_hash_aset(r_hash, rb_str_new2("south"), DBL2NUM(decode.south));
42
+ rb_hash_aset(r_hash, rb_str_new2("east"), DBL2NUM(decode.east));
43
+ rb_hash_aset(r_hash, rb_str_new2("west"), DBL2NUM(decode.west));
44
+ rb_hash_aset(r_hash, rb_str_new2("dimension"), r_dimension);
45
+
46
+ return r_hash;
47
+ }
48
+
49
+ VALUE wrap_geohash_neighbors(VALUE self, VALUE hash) {
50
+ char** hashed_neighbours = geohash_neighbors(StringValueCStr(hash));
51
+ VALUE neighbours = rb_ary_new2(8);
52
+ int i;
53
+
54
+ for (i = 0; i <= 7; i++) {
55
+ rb_ary_store(neighbours, i, rb_str_new_cstr(hashed_neighbours[i]));
56
+ }
57
+ return neighbours;
58
+ }
59
+
60
+ VALUE wrap_geohash_dimensions_for_precision(VALUE self, VALUE precision) {
61
+ GeoBoxDimension dimension;
62
+ VALUE r_hash = rb_hash_new();
63
+
64
+ dimension = geohash_dimensions_for_precision(NUM2INT(precision));
65
+
66
+ rb_hash_aset(r_hash, rb_str_new2("height"), DBL2NUM(dimension.height));
67
+ rb_hash_aset(r_hash, rb_str_new2("width"), DBL2NUM(dimension.width));
68
+
69
+ return r_hash;
70
+ }
@@ -0,0 +1 @@
1
+ require 'geohash'
@@ -0,0 +1,5 @@
1
+ module DynamodbGeo
2
+ module Version
3
+ STRING = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ require 'geohash/geohash_wrapper'
2
+
3
+ class Geohash
4
+ class << self
5
+ def decode(hash)
6
+ Geocoord.new(wrap_decode(hash)).freeze
7
+ end
8
+
9
+ def dimensions(precision)
10
+ Dimension.new(dimensions_for_precision(precision)).freeze
11
+ end
12
+ end
13
+ end
14
+
15
+ class Geocoord
16
+ attr_accessor :latitude, :longitude, :north, :south, :east, :west, :dimension
17
+ def initialize(geocoord)
18
+ @latitude = geocoord['latitude']
19
+ @longitude = geocoord['longitude']
20
+ @north = geocoord['north']
21
+ @south = geocoord['south']
22
+ @east = geocoord['east']
23
+ @west = geocoord['west']
24
+ @dimension = Dimension.new(geocoord['dimension'])
25
+ end
26
+ end
27
+
28
+ class Dimension
29
+ attr_accessor :length, :width
30
+
31
+ def initialize(geobox)
32
+ length = geobox['length']
33
+ width = geobox['width']
34
+ end
35
+ end
@@ -0,0 +1 @@
1
+ require 'spec_helper'
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ # Quick note, I'm not actually testing if the Geohash is accurate or not.
4
+ # I'm assuming the C Lib I imported is doing that for me properly.
5
+ describe Geohash do
6
+ describe '.encode' do
7
+ it 'encodes' do
8
+ encode = Geohash.encode(1,1,1)
9
+ expect(encode).to be_a String
10
+ end
11
+ end
12
+
13
+ describe '.decode' do
14
+ it 'decodes' do
15
+ decode = Geohash.decode('s')
16
+ expect(decode).to be_a Geocoord
17
+ end
18
+ end
19
+
20
+ describe '.neighbours' do
21
+ it 'finds my neighbours' do
22
+ neighbours = Geohash.neighbours('s')
23
+ expect(neighbours.sample).to be_a String
24
+ expect(neighbours.length).to be 8
25
+ end
26
+ end
27
+
28
+ describe '.precision' do
29
+ it 'calculates the dimensions for precision' do
30
+ dimensions = Geohash.dimensions(1)
31
+ expect(dimensions).to be_a Dimension
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'geohash'
5
+ require 'byebug'
6
+
7
+ RSpec.configure do |config|
8
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dynamodb_geo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Justin Ahn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-sdk-dynamodb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: aws-sdk-dynamodbstreams
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
83
+ description: A port of dynamodb_geo to Ruby. Includes a geohash module.
84
+ email: justin@soonahn.ca
85
+ executables: []
86
+ extensions:
87
+ - ext/geohash_wrapper/extconf.rb
88
+ extra_rdoc_files:
89
+ - README.md
90
+ files:
91
+ - README.md
92
+ - ext/geohash_wrapper/Makefile
93
+ - ext/geohash_wrapper/extconf.h
94
+ - ext/geohash_wrapper/extconf.rb
95
+ - ext/geohash_wrapper/geohash.c
96
+ - ext/geohash_wrapper/geohash.h
97
+ - ext/geohash_wrapper/geohash_wrapper.c
98
+ - lib/dynamodb_geo.rb
99
+ - lib/dynamodb_geo/version.rb
100
+ - lib/geohash.rb
101
+ - lib/geohash/geohash_wrapper.so
102
+ - spec/dynamodb_geo.rb
103
+ - spec/geohash_spec.rb
104
+ - spec/spec_helper.rb
105
+ homepage:
106
+ licenses:
107
+ - Beerware
108
+ metadata:
109
+ source_code_uri: https://github.com/JA-Soonahn/dynamodb_geo
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubygems_version: 3.1.2
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: dynamodb_geo-0.0.1
129
+ test_files:
130
+ - spec/dynamodb_geo.rb
131
+ - spec/geohash_spec.rb
132
+ - spec/spec_helper.rb