Geo-Hash-XS

 view release on metacpan or  search on metacpan

xs/geohash.xs  view on Meta::CPAN

            (*neighbors)[m++] = adjacent(xhash, xhashlen, ADJ_BOTTOM);
        }
        for ( j = 0; j < 2 * i; j ++ ) {
            xhash = (*neighbors)[m - 1];
            xhashlen = strlen( xhash );
            (*neighbors)[m++] = adjacent(xhash, xhashlen, ADJ_LEFT);
        }
        for ( j = 0; j < 2 * i; j ++ ) {
            xhash = (*neighbors)[m - 1];
            xhashlen = strlen( xhash );
            (*neighbors)[m++] = adjacent(xhash, xhashlen, ADJ_TOP);
        }
        i++;
        xhash = (*neighbors)[m - 1];
        xhashlen = strlen( xhash );
    }
        Safefree(tmp);
    }
}

MODULE = Geo::Hash::XS PACKAGE = Geo::Hash::XS

PROTOTYPES: DISABLE

SV *
encode(self, lat, lon, p = 0)
        SV *self;
        SV *lat;
        SV *lon;
        IV p;
    PREINIT:
        char *encoded;
    CODE:
        if (! looks_like_number(lat) || ! looks_like_number(lon) ) {
            croak("encode() only works on degrees, not dms values");
        }  

        if (p <= 0) {
            p = precision(lat, lon);
        }
        PERL_UNUSED_VAR(self);

        Newxz(encoded, p + 1, char);
        encode(encoded, p, SvNV(lat), SvNV(lon));

        RETVAL = newSV(0);
        sv_setpv( RETVAL, encoded );
        Safefree( encoded );
    OUTPUT:
        RETVAL

void
decode_to_interval(self, hash)
        SV *self;
        char *hash;
    PREINIT:
        NV lat_min = 0, lat_max = 0, lon_min = 0, lon_max = 0;
        STRLEN len = strlen(hash);
        AV *lat_range = (AV *)sv_2mortal((SV *)newAV());
        AV *lon_range = (AV *)sv_2mortal((SV *)newAV());
    PPCODE:
        PERL_UNUSED_VAR(self);
        decode_to_interval(hash, len, &lat_min, &lat_max, &lon_min, &lon_max);

        av_push(lat_range, newSVnv(lat_max));
        av_push(lat_range, newSVnv(lat_min));
        av_push(lon_range, newSVnv(lon_max));
        av_push(lon_range, newSVnv(lon_min));

        XPUSHs(sv_2mortal(newRV_inc((SV *)lat_range)));
        XPUSHs(sv_2mortal(newRV_inc((SV *)lon_range)));

void
decode(self, hash)
        SV *self;
        char *hash;
    PREINIT:
        NV lat = 0, lon = 0;
        STRLEN len = strlen(hash);
    PPCODE:
        PERL_UNUSED_VAR(self);
        decode(hash, len, &lat, &lon);
        mXPUSHn(lat);
        mXPUSHn(lon);

IV
precision(self, lat, lon)
        SV *self
        SV *lat
        SV *lon;
    CODE:
        PERL_UNUSED_VAR(self);
        RETVAL = precision(lat, lon);
    OUTPUT:
        RETVAL

SV *
adjacent(self, hash, direction)
        SV *self;
        char *hash;
        int direction;
    PREINIT:
        char *adj;
    CODE:
        PERL_UNUSED_VAR(self);
        adj = adjacent(hash, strlen(hash), direction);

        RETVAL = newSV(0);
        sv_setpv(RETVAL, adj);
        Safefree(adj);
    OUTPUT:
        RETVAL

void
neighbors(self, hash, around = 1, offset = 0)
        SV *self;
        char *hash;
        int around;
        int offset;
    PREINIT:
        int i;
        int nsize;
        char **list;
    PPCODE:
        PERL_UNUSED_VAR(self);
        neighbors(hash, strlen(hash), around, offset, &list, &nsize);

        for( i = 0; i < nsize; i++ ) {
            mXPUSHp( list[i], strlen(list[i]) );
        }
        for( i = 0; i < nsize; i++ ) {
            Safefree(list[i]);
        }
        Safefree(list);

IV
_constant()
    ALIAS:
        ADJ_TOP = ADJ_TOP
        ADJ_RIGHT = ADJ_RIGHT
        ADJ_LEFT = ADJ_LEFT
        ADJ_BOTTOM = ADJ_BOTTOM
    CODE:
        RETVAL = ix;
    OUTPUT:
        RETVAL



( run in 0.762 second using v1.01-cache-2.11-cpan-5511b514fd6 )