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

osm-p2p-server

v7.0.0

Published

Peer-to-peer OpenStreetMap API v0.6 Server

Downloads

132

Readme

osm-p2p-server

Build Status npm js-standard-style

Peer-to-peer OpenStreetMap API v0.6 Server

An implementation of the OpenStreetMap API v0.6 for osm-p2p-db, a peer-to-peer OSM database. It runs on node.js or, if you are creative, also in the browser. Data is stored in a LevelUP database. There is no need to set up a database, everything you need to get started is available as a single package that you can install from npm.

osm-p2p-server is tested and working with iD Editor - it appears as identical to the standard OSM API. It should theoretically work in the future with other editors such as JOSM but osm-p2p-server needs to use at least 64-bit ids to avoid collisions, and JOSM currently still uses 32-bit integers for some ids, such as changeset ids and version numbers.

osm-p2p-server is designed to run locally on each client. Synchronize data between clients by replicating the osm-p2p-db database. You can implement replication over wifi, bluetooth or via USB thumb drives (examples coming soon).

This module is for developers who want to build their own OSM tools. For users who want a one-click install of osm-p2p-server with iD Editor see Mapeo Desktop.

Table of Contents

Install

You will need to first install node.js

npm install osm-p2p-server

For the latest beta:

npm install osm-p2p-server@beta

Usage

usage: osm-p2p-server {OPTIONS}

-h --help     Show this message
-p --port     Listen on a port. Default: 5000
-d --datadir  Store data in this directory. Default: ./osm-p2p.db

Routes

osm-p2p-server currently implements the following routes from the OSM API v0.6:

  • [x] GET /api(/0.6)?/capabilities
  • [x] GET /api/0.6/map
  • [x] PUT /api/0.6/changeset/create
  • [x] POST /api/0.6/changeset/:id/upload
  • [x] PUT /api/0.6/changeset/:id/close
  • [x] GET /api/0.6/map
  • [x] GET /api/0.6/:type(nodes|ways|relations)?:ktype(nodes|ways|relations)=:ids
  • [x] GET /api/0.6/:type(node|way|relation)/:id
  • [x] GET /api/0.6/:type(node|way|relation)/:id/:version
  • [x] GET /api/0.6/:type(node|way|relation)/:id
  • [x] GET /api/0.6/:type(node|way|relation)/:id/history
  • [ ] GET /api/0.6/:type(way|relation)/:id/full

API

var osmrouter = require('osm-p2p-server')

var router = osmrouter(osm)

Create a new OpenStreetMap router given an osm-p2p-db handle osm.

var m = router.handle(req, res)

Match the req.method and req.url and dispatch m.fn(m, req, res) and return the match object if there is a match, or else null.

var m = router.match(method, url)

Return a match object m if method and url can be handled by the server. Used internally by router.handle(). The match object for router.match('GET', '/api/0.6/node/1234') would be:

{
  params: {
    type: 'node',
    id: '1234',
  },
  splats: [],
  route: '/:type(node|way|relation)/:id',
  fn: [Function],
  next: [Function]
}

API Example

var kosm = require('kappa-osm')
var kcore = require('kappa-core')
var level = require('level')
var raf = require('random-access-file')

var mkdirp = require('mkdirp')
mkdirp.sync('/tmp/osm-p2p/storage')

var osm = kosm({
  index: level('/tmp/osm-p2p/index'),
  core: kcore('/tmp/osm-p2p/core', { valueEncoding: 'json' }),
  storage: function (name, cb) { cb(null, raf('/tmp/osm-p2p/storage/'+name)) }
})

var router = require('osm-p2p-server')(osm)

var http = require('http')
var server = http.createServer(function (req, res) {
  if (!router.handle(req, res)) {
    res.statusCode = 404
    res.end('not found\n')
  }
})
server.listen(5000)

then you can try a few commands with curl to make sure it's working:

$ ID=$(echo '<osm><changeset></changeset></osm>' | curl -sSNT- -X PUT \
  -H content-type:text/xml http://localhost:5000/api/0.6/changeset/create)
$ echo $ID
13535672379618402612
$ echo '<osmChange version="1.0"><create><node id="-1"
  changeset="'$ID'" lon="-155.0" lat="19.5" />
</create></osmChange>' | curl -sSNT- -X POST \
  -H content-type:text/xml \
  http://localhost:5000/api/0.6/changeset/$ID/upload; echo
<?xml version="1.0" encoding="UTF-8"?><diffResult version="0.6" generator="obj2osm"><node old_id="-1" new_id="16799736668021112616" new_version="96c42510f431c1372d40880a42933eb38cb8d5c65be95b7ea0d1c3bcadab41bc@1"/></diffResult>

Use as Express middleware

var kosm = require('kappa-osm')
var kcore = require('kappa-core')
var level = require('level')
var raf = require('random-access-file')

var mkdirp = require('mkdirp')
mkdirp.sync('/tmp/osm-p2p/storage')

var osm = kosm({
  index: level('/tmp/osm-p2p/index'),
  core: kcore('/tmp/osm-p2p/core', { valueEncoding: 'json' }),
  storage: function (name, cb) { cb(null, raf('/tmp/osm-p2p/storage/'+name)) }
})

var express = require('express')
var router = require('osm-p2p-server')(osm)

var app = express()

app.use('/api/0.6', function (req, res, next) {
  if (!router.handle(req, res)) next()
})

app.use(function handleError (err, req, res, next) {
  if (!err) return
  if (!res.headersSent) {
    res.statusCode = err.status || err.statusCode || 500
    res.setHeader('content-type', 'text/plain')
    res.end(err.message + '\n')
  } else {
    next(err)
  }
})

app.listen(5000, function () {
  console.log('osm-p2p-server listening on port 5000!')
})

REST API

See the documentation for the OSM API v0.6 - osm-p2p-server replicates that API as faithfully as possible.

Differences to OSM API v0.6

The main differences to the OSM API v0.6 are related to the peer-to-peer architecture of osm-p2p-server. Ids are randomly generated, rather than sequential integers. Version ids are hashes rather than integers. For more details read osm-p2p-db Architecture.

  • If two users edit the same version of an entity (node|way|relation) then two versions will exist in the database. osm-p2p-server will not return 409: Conflict if you try to modify or delete an entity which is not the most recent version, it will create a fork instead. Forks can be created if two users edit the same entity whilst disconnected and then later replicate the database.

  • By default osm-p2p-server will only return the most recent 'fork', to maintain compatibility with tools that do not understand the concept of forked entities. To see all forks, append ?forks=true to the URL and if multiple forks exist the returned data will include multiple entities with the same id, but different version ids.

  • In changeset uploads (/changeset/:id/upload), the version property of each entity in the changeset can be a comma-separated list of version hashes of the documents that the update will replace. Use this to merge multiple forks into a single fork.

Contributing

If something does not work as it should, please open an Issue. Pull Requests are welcome, please follow JS Standard Style.

License

BSD (c) 2016 Digital Democracy