dynamodb_geo 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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