Geoprocessing with Node.js

Carol B. Hansen

@CarolBirgitta

Work at Mapbox

Geoprocessing?

Why Node?

Mapnik? GDAL?

Examples...?

NOTE:

Native C++

Mapnik GDAL

Javascript

node-mapnik

node-gdal

Geoprocessing?
Manipulating spatial data

Rasterio

python

numpy

GDAL

GDAL/OGR

C++ library

bash

python

GDAL?

Open source C++ library for reading and writing Raster and Vector data

Supports a ton...

a slew...

a gaggle...

a lot...

of formats

over 200

Raster

GeoTIFF

MrSID

JPEG2000...

Vector

KML

GPX

Shape

PostGIS...

A key library for a lot of things geo
Mapnik ?
Open source C++ toolkit used for processing and rendering a virtual map
Why Node?
client-side
server-side
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
    
    console.log(results);  // 'Finished!'      
  
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
      
    console.log(results);  // 'Finished!' 
    
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
    
    console.log(results);  // 'Finished!'      
  
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
      
    console.log(results);  // 'Finished!' 
    
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
      
    console.log(results);  // 'Finished!' 
    
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
      
    console.log(results);  // 'Finished!' 
    
  });
function myProcess(dataset, callback) {
    
    // do stuff
    
    return callback('Finished!');
  
  }
myProcess(dataset, function(results) {
      
    console.log(results);  // 'Finished!' 
    
  });

Open source

github.com/mapbox/mapnik-omnivore

github.com/mapbox/tilelive-omnivore

github.com/mapbox/tilelive.js

github.com/mapbox/mapbox-file-sniff

github.com/mapbox/shapefile-fairy

...

mapnik-omnivore
  mapnik_omnivore.digest(filepath, function(err, metadata) {
     
     // metadata is JSON
  
  });
 metadata: 
{ filesize: 428328,   // size of file in bytes
  projection: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over',
  filename: 'world_merc',
  center: [ 0, 12.048603815490733 ],
  extent: [ -180, -59.47306100000001, 180, 83.57026863098147 ],
  json: { 
    vector_layers: [ { 
      id: 'world_merc',
      description: '',
      minzoom: 0,
      maxzoom: 22,
      fields: { 
        FIPS: 'String',
        ISO2: 'String',
        ISO3: 'String',
        UN: 'Number',
        NAME: 'String',
        AREA: 'Number',
        POP2005: 'Number',
        REGION: 'Number',
        SUBREGION: 'Number',
        LON: 'Number',
        LAT: 'Number' } 
    } ] 
  },
  minzoom: 0,    // calculates the optimal minimum and
  maxzoom: 5,   // maximum zoom levels for the file
  layers: [ 'world_merc' ],
  dstype: 'shape',
  filetype: '.shp' }
  
tilelive-omnivore
getTile()
    var uri = 'omnivore://' + filepath;
    new Omnivore(uri, function(err, src) {
      src.getTile(z, x, y, function(err, data, headers) {

        // data is Vector Tile

        src.close(function(err) {
          callback();
        });
      });
    });
  
GDAL
var ds = gdal.open(filepath);
Mapnik
    var options = {
      file: filepath,
      type: 'shape'  // format
    };

    var ds = mapnik.Datasource(options);
  
Datasource --> ds

layers: ds.layers

fields: ds.layers.get(i).fields

features: ds.layers.get(i).features

projection: ds.layers.get(i).srs

extent: ds.layers.get(i).getExtent()

bands: ds.bands

pixels: ds.bands.get(i).pixels

noData: value ds.bands.get(i).noDataValue

dimensions: ds.rasterSize

other awesome stuff ds...

Thank you!

Carol B. Hansen

@CarolBirgitta