An article from Anders.
Geodata in javascript
GeoJSON is the standard way of storing geodata in JSON, javascripts native data format. The wikipedia article has very clear and telling examples. If you have never heard of GeoJSON, read it. The aim of this article is to show you how to convert your geodata to GeoJSON and some basics in querying the data.
Convert to GeoJSON
Shapefiles
If your geodata comes in files, probably they are shapefiles. There are a number of /javascript, we will use shapefile by Mike Bostock the creator of D3js, a library we will use later for visualising our data.
Create a folder for the project, open it, initialise NPM, download the library and create a folder to put the data:
$ mkdir 1.1_shapefiles$ cd 1.1_shapefiles$ npm init$ npm install shapefile --save$ mkdir dataInside the /data folder create two other called /shp and /geojson.
$ cd data$ mkdir shp$ mkdir geojsonPut your shapefiles in /shp. For this example I took one from Natural Earth.
Go back to the ‘1.1_shapefiles’ folder, create a file called convertShp.js and open it in a text editor.
Require shapefile, the library we downloaded with npm, and write the paths to our data folders:
var shp = require('shapefile')var shpPath = 'data/shp/'var geojsonPath = 'data/geojson/'See if it works by converting the file and logging the result to the console:
shp.read(shpPath + 'ne_110m_admin_0_countries', function(err,json) { console.log(json)})Go back to the terminal and run the script:
$ node convertShpYou should see your GeoJSON data in the console. Now we will save it to a file. There is a library that does that very easily, jsonfile. Download it with npm:
$ npm install jsonfile --saveOpen convertShp.js again and require jsonfile.
var jf = require('jsonfile')Modify the previous script by passing the output of shp.read() to jf. Give the file a name. Ask the script to log ‘done’ in the console when it is.
shp.read(shpPath + 'ne_110m_admin_0_countries', function(err,json) { jf.writeFile(geojsonPath + 'countries.json', json, function() { console.log('done') })})Run the script with the command line:
$ node convertShpYou now have a countries.geojson file in /data/geojson.
The code is here
PostGIS
If you have geodata in a database it probably is a PostgreSQL db with the postGIS plugin. If it is not …change database server
That was a joke about famous proprietary GIS software. Not a statement in the debate about NoSQL databases vs postGIS. NoSQL databases such as MongoDB already store data as JSON and are outside of the scope of this article.
Recent versions of postGIS have a ST_AsGeoJSON function that enables you to convert geometries.
Try it:
SELECT id, ST_AsGeoJSON(geom) as geometry FROM tableYou will get something like:
id;geometry1;{type:'Point',coordinates:[0,0]}2;{type:'Point',coordinates:[1,1]}There are many npm libraries that access PostgreSQL databases, such as pg. The problem is that the output is not exactly GeoJSON. If we use our previous query, we get a JSON array like this:
[ { id: 1, geometry: { type:'Point', coordinates:[0,0] } }, { id: 2, geometry: { type:'Point', coordinates:[1,1] } }]Whereas GeoJSON would look like this:
{ type: 'FeatureCollection', features: [ { type: 'Feature', properties: { id: 1 }, geometry: { type: 'Point', coordinates: [0,0] } }, { type: 'Feature', properties: { id: 2 }, geometry: { type: 'Point', coordinates: [1,1] } } ]}The geometries are right we just need to create the type and properties of every feature and put them in a feature collection. It is easy enough but, unsurprisingly, there are libraries that do that. We will be lazy and take postgeo.
Create a new folder /1.2_postgis, initialise npm and download postgeo.
$ mkdir 1.2_postgis$ cd 1.2_postgis$ npm init$ npm install postgeo --saveCreate a file fromPostGis.js, open it, require postgeo, connect to the db and write your query:
var postgeo = require('postgeo')var connectionString = 'postgres://user@host
ort/database';postgeo.connect(connectionString)postgeo.query("SELECT id, ST_AsGeoJSON(geom) AS geometry FROM table", "geojson", function(data) { console.log(data);})Change the connectionString with your credentials and run the script:
$ node fromPostgis.jsYou have your GeoJSON in the console. If you want to save it to a file, use jsonfile as we did with the shapefiles.
The code is here
OpenStreetMap data
OSM, is the wikipedia of geodata: a very useful resource for any mapping project. The data comes in .osm files a form of .xml file. There are a lot of ways to get OSM data, see the wiki. To convert it to GeoJSON, you can use osmtogeojson which works as a command line tool.
Install the package globally:
$ sudo npm install osmtogeojson -gNavigate to the folder where you have your file.osm and convert it with the following command:
$ osmtogeojson file.osm > file.geojson This could take some time if the .osm file is big. I would not try on planet.osm (the whole OSM dataset ~600GB) but it works fine for smaller sets.
The GeoJSON file created this way includes all types of data (points, lines, polygons…) in one file, just like in the original .osm file. This is a good starting point for some basics in querying GeoJSON files.
Query GeoJSON
Loop
The main approach to working with GeoJSON data is to loop through the features. The classical method of looping through an array in javascript looks like this:
for(i=0;i
Geodata in javascript
GeoJSON is the standard way of storing geodata in JSON, javascripts native data format. The wikipedia article has very clear and telling examples. If you have never heard of GeoJSON, read it. The aim of this article is to show you how to convert your geodata to GeoJSON and some basics in querying the data.
Convert to GeoJSON
Shapefiles
If your geodata comes in files, probably they are shapefiles. There are a number of /javascript, we will use shapefile by Mike Bostock the creator of D3js, a library we will use later for visualising our data.
Create a folder for the project, open it, initialise NPM, download the library and create a folder to put the data:
$ mkdir 1.1_shapefiles$ cd 1.1_shapefiles$ npm init$ npm install shapefile --save$ mkdir dataInside the /data folder create two other called /shp and /geojson.
$ cd data$ mkdir shp$ mkdir geojsonPut your shapefiles in /shp. For this example I took one from Natural Earth.
Go back to the ‘1.1_shapefiles’ folder, create a file called convertShp.js and open it in a text editor.
Require shapefile, the library we downloaded with npm, and write the paths to our data folders:
var shp = require('shapefile')var shpPath = 'data/shp/'var geojsonPath = 'data/geojson/'See if it works by converting the file and logging the result to the console:
shp.read(shpPath + 'ne_110m_admin_0_countries', function(err,json) { console.log(json)})Go back to the terminal and run the script:
$ node convertShpYou should see your GeoJSON data in the console. Now we will save it to a file. There is a library that does that very easily, jsonfile. Download it with npm:
$ npm install jsonfile --saveOpen convertShp.js again and require jsonfile.
var jf = require('jsonfile')Modify the previous script by passing the output of shp.read() to jf. Give the file a name. Ask the script to log ‘done’ in the console when it is.
shp.read(shpPath + 'ne_110m_admin_0_countries', function(err,json) { jf.writeFile(geojsonPath + 'countries.json', json, function() { console.log('done') })})Run the script with the command line:
$ node convertShpYou now have a countries.geojson file in /data/geojson.
The code is here
PostGIS
If you have geodata in a database it probably is a PostgreSQL db with the postGIS plugin. If it is not …change database server
That was a joke about famous proprietary GIS software. Not a statement in the debate about NoSQL databases vs postGIS. NoSQL databases such as MongoDB already store data as JSON and are outside of the scope of this article.
Recent versions of postGIS have a ST_AsGeoJSON function that enables you to convert geometries.
Try it:
SELECT id, ST_AsGeoJSON(geom) as geometry FROM tableYou will get something like:
id;geometry1;{type:'Point',coordinates:[0,0]}2;{type:'Point',coordinates:[1,1]}There are many npm libraries that access PostgreSQL databases, such as pg. The problem is that the output is not exactly GeoJSON. If we use our previous query, we get a JSON array like this:
[ { id: 1, geometry: { type:'Point', coordinates:[0,0] } }, { id: 2, geometry: { type:'Point', coordinates:[1,1] } }]Whereas GeoJSON would look like this:
{ type: 'FeatureCollection', features: [ { type: 'Feature', properties: { id: 1 }, geometry: { type: 'Point', coordinates: [0,0] } }, { type: 'Feature', properties: { id: 2 }, geometry: { type: 'Point', coordinates: [1,1] } } ]}The geometries are right we just need to create the type and properties of every feature and put them in a feature collection. It is easy enough but, unsurprisingly, there are libraries that do that. We will be lazy and take postgeo.
Create a new folder /1.2_postgis, initialise npm and download postgeo.
$ mkdir 1.2_postgis$ cd 1.2_postgis$ npm init$ npm install postgeo --saveCreate a file fromPostGis.js, open it, require postgeo, connect to the db and write your query:
var postgeo = require('postgeo')var connectionString = 'postgres://user@host
$ node fromPostgis.jsYou have your GeoJSON in the console. If you want to save it to a file, use jsonfile as we did with the shapefiles.
The code is here
OpenStreetMap data
OSM, is the wikipedia of geodata: a very useful resource for any mapping project. The data comes in .osm files a form of .xml file. There are a lot of ways to get OSM data, see the wiki. To convert it to GeoJSON, you can use osmtogeojson which works as a command line tool.
Install the package globally:
$ sudo npm install osmtogeojson -gNavigate to the folder where you have your file.osm and convert it with the following command:
$ osmtogeojson file.osm > file.geojson This could take some time if the .osm file is big. I would not try on planet.osm (the whole OSM dataset ~600GB) but it works fine for smaller sets.
The GeoJSON file created this way includes all types of data (points, lines, polygons…) in one file, just like in the original .osm file. This is a good starting point for some basics in querying GeoJSON files.
Query GeoJSON
Loop
The main approach to working with GeoJSON data is to loop through the features. The classical method of looping through an array in javascript looks like this:
for(i=0;i