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 🙏

© 2024 – Pkg Stats / Ryan Hefner

p2p-db-osm

v3.1.2

Published

API for p2p-db adding OpenStreetMap data types and querying.

Downloads

24

Readme

p2p-db-osm

Pluggable API for p2p-db adding OpenStreetMap data types and querying.

Usage

var P2P = require('p2p-db')
var osm = require('p2p-db-osm')
var hyperdb = require('hyperdb')
var ram = require('random-access-memory')
var memdb = require('memdb')
var Geo = require('grid-point-store')

// Create p2p-db and p2p-db-osm dependencies
var hyperdb = P2P.provide('hyperdb', hyperdb(ram, { valueEncoding: 'json' }))
var leveldb = P2P.provide('leveldb', memdb())
var pointstore = P2P.provide('pointstore', Geo(memdb()))

// Create the p2p-db
var db = P2P([hyperdb, leveldb, pointstore, osm])

var node = {
  type: 'node',
  lat: '-12.7',
  lon: '1.3',
  tags: { feature: 'water fountain' },
  changeset: 'abcdef'
}

db.osm.create(node, function (err, node) {
  console.log('created node with id', node.id)
  db.osm.get(node.id, function (err, elms) {
    console.log('got elements at', node.id)
    console.log(elms)
  })
})

outputs

created node with id 78d06921416fe95b
got elements at 78d06921416fe95b
[ { type: 'node',
    lat: '-12.7',
    lon: '1.3',
    tags: { feature: 'water fountain' },
    changeset: 'abcdef',
    timestamp: '2017-12-16T00:15:55.238Z',
    id: '78d06921416fe95b',
    version: 'eAXxidJuq9PoqiDsyrLKfR4jME9hgYnGSozS7BKXUqbDH' } ]

API

var osm = require('p2p-db-osm')

Returns a depj dependency object, which is no more than

module.exports = {
  gives: 'osm',
  needs: ['hyperdb', 'leveldb', 'pointstore'],
  create: function (api) {
    return new Osm(api)
  }
}

This is passed as a dependency directly into the p2p-db constructor. See p2p-db for more details on how this works.

You create a new p2p-db with p2p-db-osm like so:

var P2P = require('p2p-db')

var db = P2P([
  P2P.provide('hyperdb', hyperdb),
  P2P.provide('leveldb', leveldb),
  P2P.provide('pointstore', pointstore),
  require('p2p-db-osm')
])

Where hyperdb is a hyperdb instance, leveldb is a levelup instance, and pointstore is a grid-point-store instance. The order they are given doesn't matter -- depj sorts it out.

If you just want to use p2p-db-osm and don't care about p2p-db, that's fine too! You can get around the dependency management business and make a plain osmdb like so:

var osm = require('p2p-db-osm')

var osmdb = osm.create({
  hyperdb: hyperdb,
  leveldb: leveldb,
  pointstore: pointstore
})

osmdb.create({type: 'node', ...})  // etc

db.osm.create(element, cb)

Create the new OSM element element and add it to the database. The resulting element, populated with the id and version fields, is returned by the callback cb.

db.osm.get(id, cb)

Fetch all of the newest OSM elements with the ID id. In the case that multiple peers modified an element prior to sync'ing with each other, there may be multiple latest elements ("heads") for the ID.

db.osm.put(id, element, cb)

Update an existing element with ID id to be the OSM element element. The new element should have all fields that the OSM element would have. The type of the element cannot be changed.

If the value of ID currently returns two or more elements, this new value will replace them all.

cb is called with the new element, including id and version properties.

db.osm.batch(ops, cb)

Create and update many elements atomically. ops is an array of objects describing the elements to be added or updated.

{
  type: 'put',
  id: 'id',
  value: { /* element */ }
}

If no id field is set, the element is created, otherwise it is updated with the element value.

Currently, doing a batch insert skips many validation checks in order to be as fast as possible.

TODO: accept opts.validate or opts.strict

var rs = db.osm.query(bbox[, cb])

Retrieves all nodes, ways, and relations touching the bounding box bbox.

bbox is expected to be of the format [[minLat, maxLat], [minLon, maxLon]]. Latitude runs between (-85, 85), and longitude between (-180, 180).

A callback parameter cb is optional. If given, it will be called as cb(err, elements). If not provided or set to null, a Readable stream will be returned that can be read from as elements are emitted. The distinction between the two is that the callback will buffer all results before they are returned, but the stream will emit results as they arrive, resulting in much less buffering. This can make a large impact on memory use for queries on large datasets.

The following algorithm is used to determine what OSM elements are returned:

  1. All nodes that are inside a given bounding box and any relations that reference them.
  2. All ways that reference at least one node that is inside a given bounding box, any relations that reference them (the ways), and any nodes outside the bounding box that the ways may reference.
  3. All relations that reference one of the nodes, ways or relations included due to the above rules. (This does not apply recursively; meaning that elements referenced by a relation are not returned by virtue of being in that relation.)

db.osm.getChanges(id, cb)

Fetch a list of all OSM elements belonging to the changeset id. cb is called with an array of objects of the form:

{
  id: '...',
  version: '...'
}

TODO: optionally return a readable stream

Deletions

To delete an element, OSM specifies to set the visible property to false. This can be done using the db.osm.put API above.

Architecture

TODO: talk about forking data & forking architecture

Install

With npm installed, run

$ npm install p2p-db-osm

License

ISC