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 OrientDB - Codemotion Spain

486 views

Published on

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

Published in: Technology
  • Be the first to comment

Geospatial Graphs made easy with OrientDB - Codemotion Spain

  1. 1. GeoSpatial Graphs made easy with Luigi Dell’Aquila MADRID · NOV 18-19 · 2016
  2. 2. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Luigi Dell’Aquila Core Developer and Director of Consulting OrientDB LTD Twitter: @ldellaquila http://www.orientdb.com
  3. 3. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Our goal
  4. 4. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Summary •What is OrientDB •OrientDB GeoSpatial API •Importing Geo data (Java and/or 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 Madrid - Nov 18-19 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 Madrid - Nov 18-19 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 Madrid - Nov 18-19 2016 OrientDB GeoSpatial Classes •OPoint •OLine •OPolygon •OMultiPoint •OMultiline •OMultiPlygon
  8. 8. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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 Madrid - Nov 18-19 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 Madrid - Nov 18-19 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 Madrid - Nov 18-19 2016 Now let’s import data! Let’s do it in Java you can download some Geo files from http://www.mapcruzin.com/free-spain-maps.htm and convert them to WKT using QGis (www.qgis.org)
  12. 12. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Maven Dependencies <dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-csv</artifactId>
 <version>1.2</version>
 </dependency>
 
 <dependency>
 <groupId>com.orientechnologies</groupId>
 <artifactId>orientdb-graphdb</artifactId>
 <version>2.2.13</version>
 </dependency>
  13. 13. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Read from CSV Reader reader = new FileReader("/path/to/poi_file.csv");
 CSVParser parser = CSVFormat.DEFAULT.parse(reader);
 Iterator<CSVRecord> iterator = parser.iterator();
 iterator.next(); //discard the header 
 
 while(iterator.hasNext()){ //read each row
 importRecord(iterator.next()); 
 } 

  14. 14. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 OrientDB connection Reader reader = new FileReader("/path/to/poi_file.csv");
 CSVParser parser = CSVFormat.DEFAULT.parse(reader);
 Iterator<CSVRecord> iterator = parser.iterator();
 iterator.next(); //discard the header 
 OrientGraph graph = new OrientGraph("remote:localhost/testdb", "admin", "admin");
 while(iterator.hasNext()){ //read each row
 importRecord(iterator.next(), graph);
 } 
 graph.shutdown();
  15. 15. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 importRecord() void importRecord(CSVRecord record, OrientGraph graph) {
 String wkt = record.get(0);
 String name = record.get(2);
 String type = record.get(3);
 
 graph.command(new OCommandSQL(
 "insert into Natural " +
 "set name = ?, type = ?, " +
 "location = ST_GeomFromText(?)"))
 .execute(name, type, wkt);
 }
  16. 16. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Querying geo data We are here: (40.399640, -3.8375544) (lat, lon)
  17. 17. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Front-End!
  18. 18. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Clone the scaffolding > git clone https://github.com/luigidellaquila/geospatial-demo > cd geospatial-demo > npm install (it’s a clone of https://github.com/angular/quickstart) > npm start
  19. 19. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Clone the scaffolding > git clone https://github.com/luigidellaquila/geospatial-demo > 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
  20. 20. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 We need Google Maps <script src=“https://maps.googleapis.com/maps/api/js?key=API_KEY"
 async defer></script>
  21. 21. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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>
  22. 22. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Draw the map drawMap(){
 var controller = this;
 let mapProp = {
 center: new google.maps.LatLng(40.399640, -3.8375544),
 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();
 });
 });
 }
  23. 23. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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 */ } );
 }

  24. 24. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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 */ } );}

  25. 25. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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 */ } );
 }

  26. 26. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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) });
 }

  27. 27. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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);
 }
  28. 28. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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);
 });
 }
  29. 29. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 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);
 }
  30. 30. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Query the Geospatial Graph (DEMO)
  31. 31. Luigi Dell’Aquila @ldellaquila Madrid - Nov 18-19 2016 Thank you!

×