Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
GeoSpatial Graphs
made easy with
Luigi Dell’Aquila
Prague, 20-21 October 2016
Luigi Dell’Aquila
Core Developer and Director of Consulting
OrientDB LTD
Twitter: @ldellaquila
http://www.orientdb.com
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Our goal
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Summary
•What is OrientDB
•OrientDB GeoSpatial API
•Importing Ge...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
What is OrientDB
•Multi-Model Database (Document, Graph and more...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Install
•http://www.orientdb.com/download/
•http://central.maven...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
OrientDB GeoSpatial Classes
•OPoint
•OLine
•OPolygon
•OMultiPoin...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
OrientDB GeoSpatial Functions
•ST_GeomFromText(text)
•ST_Equals(...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Our Data Model
CREATE CLASS POI EXTENDS V
CREATE PROPERTY POI.lo...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Our Data Source (WKT)
WKT,osm_id,name,type
"POINT (14.4641804 50...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Now let’s import data!
> npm init
> npm install orientjs
> npm i...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Dependencies
var fs = require("fs")

var ODatabase = require("or...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Read from CSV
var stream = fs.createReadStream("data/poland-poi....
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
DB connection
var db = new ODatabase({

host: "localhost",

port...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Insert
var insertElement = function(data){

db.insert().into(cla...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Is it done?
Not yet :-(
Node.js… asynchronous… promises…
Final v...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Querying geo data
We are here:
(50.10902, 14.5831653)
(lat, lon)
Front-End!
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Clone the scaffolding
> git clone https://github.com/luigidellaq...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Clone the scaffolding
> git clone https://github.com/luigidellaq...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
We need Google Maps
<script src=“https://maps.googleapis.com/map...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Let’s display a map (app.html)
<div class=“container">

<div cla...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Draw the map
drawMap(){

var controller = this;

let mapProp = {...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Create a Person
createPerson(): void{

var location = {

// the ...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Create a Person
createPerson(): void{

var location = {

"@class...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Create a Person
createPerson(): void{

var location = {

"@class...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Create a Person
createPerson(): void{

var location = {

"@class...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Add Person Vertex to Orient via REST API
command(statement: stri...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Add Person to the Map
addPersonToMap(personData:any){

let locat...
Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016
Add an edge between people
(FriendOf)
createEdge(from:any, to:an...
Query the
Geospatial Graph
(DEMO)
Thank you!
Upcoming SlideShare
Loading in …5
×

GeeCON Prague 2016 - Geospatial Graphs made easy with OrientDB

819 views

Published on

How to configure OrientDB to manage geospatial data, implement a Node.js importer and an Angular2+GoogleMaps frontend

Published in: Technology
  • Be the first to comment

GeeCON Prague 2016 - Geospatial Graphs made easy with OrientDB

  1. 1. GeoSpatial Graphs made easy with Luigi Dell’Aquila Prague, 20-21 October 2016
  2. 2. Luigi Dell’Aquila Core Developer and Director of Consulting OrientDB LTD Twitter: @ldellaquila http://www.orientdb.com
  3. 3. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Our goal
  4. 4. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Summary •What is OrientDB •OrientDB GeoSpatial API •Importing Geo data (Node.js) •Querying Geo data (OrientDB Studio) •Displaying Geo data (Angular2, Google Maps) •Adding Relationships - graph data •Graph + Spatial queries
  5. 5. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 What is OrientDB •Multi-Model Database (Document, Graph and more) •Tables Classes •Extended SQL •JOIN Physical Pointers •Schema, No-Schema, Hybrid •HTTP + Binary protocols •Stand-alone or Embedded •Distributed Multi-Master •Apache 2 license
  6. 6. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Install •http://www.orientdb.com/download/ •http://central.maven.org/maven2/com/ orientechnologies/orientdb-spatial/VERSION/ orientdb-spatial-VERSION-dist.jar > cd orientdb-community/bin/ > ./server.sh
  7. 7. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 OrientDB GeoSpatial Classes •OPoint •OLine •OPolygon •OMultiPoint •OMultiline •OMultiPlygon
  8. 8. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 OrientDB GeoSpatial Functions •ST_GeomFromText(text) •ST_Equals(geom, geom) •ST_Contains(geom, geom) •ST_Disjoint(geom, geom) •ST_Intersects(geom, geom) •ST_Distance_Sphere(geom, geom) •and more…
  9. 9. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Our Data Model CREATE CLASS POI EXTENDS V CREATE PROPERTY POI.location EMBEDDED OPoint CREATE INDEX POI.location on POI(location) SPATIAL ENGINE LUCENE CREATE CLASS Natural EXTENDS V CREATE PROPERTY Natural.location EMBEDDED OPolygon CREATE INDEX Natural.location on Natural(location) SPATIAL ENGINE LUCENE CREATE CLASS Person EXTENDS V CREATE PROPERTY Person.location EMBEDDED OPoint CREATE CLASS FriendOf EXTENDS E
  10. 10. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Our Data Source (WKT) WKT,osm_id,name,type "POINT (14.4641804 50.0972109)",24569342,"Invalidovna, Metro B",station "POINT (14.4739792 50.1036789)",24569358,"Palmovka, Metro B",station "POINT (14.4921863 50.1062907)",24569412,"Českomoravská, Metro B",station
  11. 11. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Now let’s import data! > npm init > npm install orientjs > npm install fast-csv > touch index.js import files http://www.mapcruzin.com/free-czech-republic-maps.htm (convert to WKT using QGis)
  12. 12. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Dependencies var fs = require("fs")
 var ODatabase = require("orientjs").ODatabase
 var csv = require("fast-csv")
  13. 13. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Read from CSV var stream = fs.createReadStream("data/poland-poi.csv");
 
 var csvStream = csv.parse({headers: true})
 .on("data", function(data){
 console.log(data)
 })
 .on("end", function(){
 console.log("Done!")
 });
 
 stream.pipe(csvStream); 

  14. 14. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 DB connection var db = new ODatabase({
 host: "localhost",
 port: 2424,
 username: "admin",
 password: "admin",
 name: "geo"
 }) db.open().then(function(){
 } 

  15. 15. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Insert var insertElement = function(data){
 db.insert().into(className).set(
 {
 name: data.name,
 type: data.type,
 location: db.rawExpression("ST_GeomFromText('"+data.WKT+"')")
 }
 ).one().then(function(){})
 } 

  16. 16. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Is it done? Not yet :-( Node.js… asynchronous… promises… Final version: https://github.com/luigidellaquila/wkt-to-orient
  17. 17. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Querying geo data We are here: (50.10902, 14.5831653) (lat, lon)
  18. 18. Front-End!
  19. 19. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Clone the scaffolding > git clone https://github.com/luigidellaquila/geospatial-demo > git checkout warsaw_demo_step0 > cd geospatial-demo > npm install (it’s a clone of https://github.com/angular/quickstart) > npm start
  20. 20. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Clone the scaffolding > git clone https://github.com/luigidellaquila/geospatial-demo > git checkout warsaw_demo_step0 > cd geospatial-demo > npm install (it’s a clone of https://github.com/angular/quickstart) > npm start > cd <orientdb-home>/www > ln -s <quickstart-path> > tsc -w
  21. 21. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 We need Google Maps <script src=“https://maps.googleapis.com/maps/api/js?key=API_KEY"
 async defer></script>
  22. 22. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Let’s display a map (app.html) <div class=“container">
 <div class="row">
 <div class="col-md-12" id="map" style=“height:600px"></div>
 </div>
 </div>
  23. 23. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Draw the map drawMap(){
 var controller = this;
 let mapProp = {
 center: new google.maps.LatLng(52.231807953759706, 21.013154983520508),
 zoom: 16,
 mapTypeId: google.maps.MapTypeId.ROADMAP
 };
 
 controller.map = new google.maps.Map(document.getElementById("map"), mapProp);
 controller.map.addListener("click", function(point: any){
 controller.zone.run(()=> {
 controller.lat = point.latLng.lat();
 controller.lon = point.latLng.lng();
 });
 });
 }
  24. 24. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Create a Person createPerson(): void{
 var location = {
 // the location object
 }
 
 var queryString = ””; // OrientDB statement
 
 this.orient.command( queryString, (result) => { /* Success callback */ }, (error) => { /* Error callback */ } );
 }

  25. 25. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Create a Person createPerson(): void{
 var location = {
 "@class": "OPoint",
 coordinates: [this.lon, this.lat]
 }
 
 var queryString = ””; // OrientDB statement
 
 this.orient.command( queryString, (result) => { /* Success callback */ }, (error) => { /* Error callback */ } );}

  26. 26. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Create a Person createPerson(): void{
 var location = {
 "@class": "OPoint",
 coordinates: [this.lon, this.lat]
 }
 
 var queryString = `insert into Person 
 set name = '${this.personName}', 
 location = ${JSON.stringify(location)}`;
 
 this.orient.command( queryString, (result) => { /* Success callback */ }, (error) => { /* Error callback */ } );
 }

  27. 27. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Create a Person createPerson(): void{
 var location = {
 "@class": "OPoint",
 coordinates: [this.lon, this.lat]
 }
 
 var queryString = `insert into Person 
 set name = '${this.personName}', 
 location = ${JSON.stringify(location)}`;
 
 this.orient.command( queryString, (res) => {
 let body = res.json();
 let person = body.result[0];
 this.addPersonToMap(person)
 }, (e) => { console.log(e) });
 }

  28. 28. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Add Person Vertex to Orient via REST API command(statement: string, success: (data: any) => void, error: (err: any) => void): void{
 var url = this.url + "sql/-/-1" 
 var headers = new Headers();
 headers.append("Authorization", "Basic " + btoa(this.username+":"+this.password));
 
 this.http.post( // HTTP POST
 url, // the URL
 JSON.stringify({
 "command": statement // the SQL command
 }),
 {headers: headers} // the authentication data
 ).toPromise()
 .then(success)
 .catch(error);
 }
  29. 29. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Add Person to the Map addPersonToMap(personData:any){
 let location = personData.location;
 let coordinates = location.coordinates;
 let controller = this;
 let marker = new google.maps.Marker({
 position: {lat:coordinates[1], lng:coordinates[0]},
 map: this.map,
 title: personData.name,
 rid: personData["@rid"]
 });
 google.maps.event.addListener(marker, 'click', function() {
 controller.onMarkerClick(marker);
 });
 }
  30. 30. Luigi Dell’Aquila @ldellaquila Prague, 20-21 October 2016 Add an edge between people (FriendOf) createEdge(from:any, to:any): void{
 this.orient.command(
 `create edge FriendOf from ${from.rid} to ${to.rid}`,
 (x)=>{console.log(x)},
 (x)=>{console.log(x)}
 )
 this.addEdgeBetweenMarkersToMap(from, to);
 }
  31. 31. Query the Geospatial Graph (DEMO)
  32. 32. Thank you!

×