A javascript implementation of the Geo::DNA perl module, which is a perl port of the python "geoprint" library.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


    GeoDNA - Encode latitude and longitude in a useful string format
    There's an interactive demo of this at

     <script type="text/javascript" src="geodna.js"></script>

     var geo = GeoDNA.encode( -41.288889, 174.777222, { precision: 22 } );
     console.log( geo );
     > etctttagatagtgacagtcta

     var coords = GeoDNA.decode( geo );
     console.log( coords[0], coords[1] );
     > -41.288889, 174.777222


    * Simple API
        Generally you just convert coordinates back and forth with simple
        function calls.

    * Fast
        It's just basic space partitioning, really.

    This is a javascript version of the Python "geoprint" system that we developed
    a few years back at Action Without Borders.

    Its purpose is to encode a latitude/longitude pair in a string format
    that can be used in text databases to locate items by proximity. For
    example, if Wellington, New Zealand has the GeoDNA(10) value of


    (which it does), then you can chop characters off the end of that to
    expand the area around Wellington. You can easily tell if items are
    close together because (for the most part) their GeoDNA will have the
    same prefix. For example, Palmerston North, New Zealand, has a
    GeoDNA(10) code of


    which has the same initial 7 characters.

    The original implementation of this in Python was by Michel Pelletier.

    This uses a concept that is very similar to Gustavo Niemeyer's geohash
    system ( http://geohash.org ), but encodes the latitude and longitude in
    a way that is more conducive to stem-based searching (which is probably
    the most common use of these hashing systems).


      var code = GeoDNA.encode( latitude, longitude, options );

    Returns a GeoDNA code (which is a string) for latitude, longitude.
    Possible options are:

    radians : true/false
        A true value means the latitude and longitude are in radians.

    precision : Integer (defaults to 22)
        number of characters in the GeoDNA code. Note that any more than
        22 chars and you're kinda splitting hairs.

     var coords = GeoDNA.decode( code, options )

    Returns the latitude and longitude encoded within a GeoDNA code.

    radians : true/false
        If true, the values returned will be in radians.

     var neighbours = GeoDNA.neighbours( code );

    Returns an array of the 8 GeoDNA codes representing boxes of equal
    size around the one represented by code. This is very useful for
    proximity searching, because you can generate these GeoDNA codes, and
    then using only textual searching (eg. a SQL "LIKE" operator), you can
    locate any items within any of those boxes.

    The precision (ie. string length) of the GeoDNA codes will be the same
    as code.

     var neighbours = GeoDNA.neighboursWithinRadius( code, radius, options );

    Returns a raw list of GeoDNA codes of a certain size contained within the
    radius (specified in kilometres) about the point represented by a

    The size of the returned codes will either be specified in options, or
    will be the default (11).

    precision: N
        If this is present, the returned GeoDNA codes will have this size.

     var neighbours = GeoDNA.reduce( neighbours )

    Given an array of GeoDNA codes of arbitrary size (eg. as returned by
    the "neighboursWithinRadius" function), this will return the minimal set
    of GeoDNA codes (of any sizes) that exactly cover the same area.  This is
    important because it can massively reduce the number of comparisons you
    have to do in order to perform stem-matching, *and* more crucially, if
    you *don't* reduce the list, you *can't* perform stem matching.

     var coords = GeoDNA.boundingBox( code );

    This returns an array containing two arrays:

     [ [ minimum latitude,  maximum latitude  ],
       [ minimum longitude, maximum longitude ],

    * Add conveniences to help you with prefix-based searching
        At present you have to understand how this geometry works fairly
        well in order to get the most out of this module.

    * Bulletproofing
        It's not particularly well-tested. And there is the boundary-problem
        in that two very close-by locations can have radically different
        GeoDNA codes if they are on different sides of a partition. This
        is not a problem if you use the neighbouring GeoDNA codes of your
        reference point to do proximity searching, but if you don't know how
        to do that, it will make life hard for you.

    Please report bugs relevant to `GeoDNA' to <info[at]kyledawkins.com>.

    The github repository is at

    Some other stuff.

    Kyle Dawkins, <info[at]kyledawkins.com>

    Copyright 2012 by Kyle Dawkins