Skip to content

POI example notebook

Gezim Sejdiu edited this page Mar 26, 2018 · 2 revisions

By this example, we show how different layers of SANSA can be used for a specific use case. We perform some inference over given dataset and show the class distribution of it. Afterwards we rank resources and bind them to a map (using their lat and lan geo-coordinates)

Point of Interest Example

1. Load Data
import net.sansa_stack.rdf.spark.io._
import org.apache.jena.riot.Lang

val input = "hdfs://namenode:8020/data/GermanyPopulatedPlaces.nt"
val lang = Lang.NTRIPLES
val graph = spark.rdf(lang)(input)
2. Compute statistics (i.e. Property Distribution)
import net.sansa_stack.rdf.spark.stats._

val propertyDist = PropertyUsage(graph, spark).PostProc()
                   .map(f => f._1.getLocalName+ "\t" + f._2)

println("%table Property Distribution\tFrequency\n " + propertyDist.mkString("\n"))
3. Infer new Knowledge
import net.sansa_stack.inference.spark.forwardchaining.triples.ForwardRuleReasonerRDFS
import net.sansa_stack.inference.spark.data.loader.RDFGraphLoader
import java.net.{ URI => JavaURI }

val RDFGraph = RDFGraphLoader.loadFromDisk(spark, JavaURI.create(input), 4)
val reasoner = new ForwardRuleReasonerRDFS(spark.sparkContext)
val inferredGraph = reasoner.apply(RDFGraph)
inferredGraph.cache()
3.1 Compute statistics (i.e Class Distribution to the original graph)
val rdf_stats_class_dist = Used_Classes(graph, spark).PostProc()
                           .map(f => f._1.toString.substring(f._1.toString.lastIndexOf("/") + 1)+ "\t" + f._2)
println("%table Class Distribution\tFrequency\n " + rdf_stats_class_dist.mkString("\n"))
3.2 Compute statistics (i.e size of the inferred graph)
val O_graph = "original graph" + "\t" + graph.count 
val I_Graph = "\n inferred graph" + "\t" + inferredGraph.size

println("%table graph\t size\n " + O_graph.union(I_Graph))
4. Compute resource ranking and get top 50 POIs.
import org.apache.spark.graphx.Graph
import net.sansa_stack.rdf.spark.model.graph._

val graph_rep =graph.asGraph()
   // Create a subgraph based on the vertices connected by geoproperty.
 val geoSubgraph =
    graph_rep.subgraph(t => t.attr =="http://www.w3.org/2006/vcard/ns#geo")

val pagerank = geoSubgraph.pageRank(0.00001).vertices
val report = pagerank.join(geoSubgraph.vertices)
     .map({ case (k, (r, v)) => (r, v, k) })
     .sortBy(50 - _._1)

case class POI(geoloc:Long, rank:Double, lat: String, lon: String)
 val POIs = report.filter(f=>f._2.isLiteral()&& f._2.getLiteralLexicalForm().startsWith("geo:")).map { f =>
    val geoloc = f._3
    val rank = f._1
    val geo = f._2.getLiteralLexicalForm.split("[:,]+")
    val lat = geo(1)
    val lon = geo(2)

    POI(geoloc, rank, lat, lon)

  }.take(50)

z.angularBind("pois", POIs) // this is what sends the data to the map

val reportPOI = POIs.map(f => f.geoloc + "\t" + f.lat+", " + f.lon + "\t" + f.rank)
println("%table geoloc \t geocord \t rank \n " + reportPOI.mkString("\n"))
5. Show POI on the map
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.css" />
<div id="map" style="height: 800px; width: 100%"></div>

<script type="text/javascript">
function initMap() {
    var map = L.map('map').setView([30.00, -30.00], 3);

    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
        maxZoom: 12,
        minZoom: 3
    }).addTo(map);

    var geoMarkers = L.layerGroup().addTo(map);

    var el = angular.element($('#map').parent('.ng-scope'));
    angular.element(el).ready(function() {
        window.locationWatcher = el.scope().compiledScope.$watch('pois', function(newValue, oldValue) {
            // geoMarkers.clearLayers(); -- if you want to only show new data clear the layer first
            angular.forEach(newValue, function(poi) {
                var marker = L.marker([ poi.lat, poi.lon ])
                  .bindPopup(poi.geoloc + ": " + poi.rank)
                  .addTo(geoMarkers);
            });
        })
    });
}

if (window.locationWatcher) {
    // clear existing watcher otherwise we'll have duplicates
    window.locationWatcher();
}

// ensure we only load the script once, seems to cause issues otherwise
if (window.L) {
    initMap();
} else {
    console.log('Loading Leaflet library');
    var sc = document.createElement('script');
    sc.type = 'text/javascript';
    sc.src = 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.5/leaflet.js';
    sc.onload = initMap;
    sc.onerror = function(err) { alert(err); }
    document.getElementsByTagName('head')[0].appendChild(sc);
}
</script>