npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

geomodel

v0.2.2

Published

An implementation of the Geomodel/Geocell concept - http://code.google.com/apis/maps/articles/geospatial.html

Readme

geomodel.js

This library is an implementation of the Geomodel/Geocell concept:

http://code.google.com/apis/maps/articles/geospatial.html

It is a direct port of the Java and Python versions of the geomodel project:

  • http://code.google.com/p/javageomodel/
  • http://code.google.com/p/geomodel/

Most of the code for the core Geocell concept was ported from the Java version. The proximity_fetch implementation was ported from the Python version, with the "entity" store abstracted out to remove the coupling to Google App Engine. Also, this proximity_fetch does not directly support the execution of an additional query to filter the promixity results with, though this could be implemented in whatever entity finder function the user passes to it.

A geocell is a hexadecimal string that defines a two dimensional rectangular region inside the [-90,90] x [-180,180] latitude/longitude space. A geocell's 'resolution' is its length. For most practical purposes, at high resolutions, geocells can be treated as single points.

Much like geohashes (see http://en.wikipedia.org/wiki/Geohash), geocells are hierarchical, in that any prefix of a geocell is considered its ancestor, with geocell[:-1] being geocell's immediate parent cell.

To calculate the rectangle of a given geocell string, first divide the [-90,90] x [-180,180] latitude/longitude space evenly into a 4x4 grid like so:

NOTE: The point (0, 0) is at the intersection of grid cells 3, 6, 9 and c. And, for example, cell 7 should be the sub-rectangle from (-45, 90) to (0, 180).

Calculate the sub-rectangle for the first character of the geocell string and re-divide this sub-rectangle into another 4x4 grid. For example, if the geocell string is '78a', we will re-divide the sub-rectangle like so:

Continue to re-divide into sub-rectangles and 4x4 grids until the entire geocell string has been exhausted. The final sub-rectangle is the rectangular region for the geocell.

Requirements

The code relies heavily on lodash

While not absolutely dependent on this, it is helpful to have lo4gjs. If running on node.js, you should install it with npm.

So far I've only tested this on node.js. Theoretically, the code should work with any JS engine, including browsers.

Usage

Create a Geomodel instance, passing in a logger object and an options object:

var log4js = require('log4js-node');
var logger = log4js.getLogger('foo');  
var Geomodel = require('geomodel').create_geomodel({ logger, inspect: require('util').inspect });

geomodel.js defaults the inspect option to 'require('util').inspect' so you don't technically need to pass this if you are running on node.js.

If you don't have log4js and don't really care about logging, just create a Geomodel instance with no params:

var Geomodel = require('geomodel').create_geomodel();

Generate geocells for your entities based on their location, and save them to your data source such that you can query for them by geocell later:

my_obj.location = Geomodel.create_point(40.7407092, -73.9894039)
var geocells = Geomodel.generate_geocells(my_obj.location)
// then do some stuff to save my_obj to your data source, indexed by 
// the generated geocells somehow 

All geocelled objects must have an 'id' and a 'location' property. The location property must be an object with a 'lat' and 'lon' property (the create_point function creates such an object). These are used by proximity_fetch.

Call proximity_fetch to find entities near a point, passing in a finder function and success and error handlers:

var results = Geomodel.proximity_fetch(my_point, max_results, max_distance,
                function(geocells, finder_callback) {
                  // this function should query your data source for all 
                  // the entities in the specified geocells 
                  if (error) {
                    // if any errors occur pass an error object to the 
                    // callback like so:
                    finder_callback(some_error_object);
                  } else 
                    // otherwise, return the results in an array like so:
                    finder_callback(null, entity_results);
                }, 
                function(err, proximity_results) {
                  if (err) {
                    // handle errors from proximity_fetch here
                  } else {
                    // do what you want to do with the results here                        
                  }
                });

The results are returned as a list of "2-tuples" where the first element of the tuple is the object and the second is the distance from the query point, sorted by distance:

proximity_results.forEach(function(res) { puts(res[0].id + ' is ' + res[1] + ' meters away.') })

For a full working example of these steps check out the code in tests/test-proximity-fetch.js.

Aliases

To integrate more easily with your own data model, You can specify aliases for the location, lat and lon properties with the aliases option:

var Geomodel = require('geomodel').create_geomodel({
  aliases: {
    location: 'coordinates',
    lat: 'latitude',
    lon: 'longitude',
  }
});

location can be a path to a nested sub-object on your entities:

var Geomodel = require('geomodel').create_geomodel({
  aliases: {
    location: 'foo.bar.coordinates',
  }
});

Author

Daniel Kim
[email protected]
danieldkim on github

Contributors

Schwanksta Brian Chapman

License

The Java and python versions of this library were distributed under the Apache 2.0 License, and so is this.