geoshape distance between points in gremlin-python

348 views
Skip to first unread message

John B

unread,
Sep 4, 2018, 11:00:46 AM9/4/18
to Gremlin-users
I have saved latitude-longitude data in Janusgraph with Cassandra backend. Data were input via a graphson file.  The goal is to use these values to calculate the distance between selected points. But I'm struggling to understand how to call the distance function via gremlin-python. Actually, I use python goblin.

The schema contains:

point = mgmt.makePropertyKey('point').dataType(org.janusgraph.core.attribute.Geoshape.class).cardinality(org.janusgraph.core.Cardinality.SINGLE).make()


The graphson file contains vertex properties that have this form:

            vp = {
               
"id": {
                   
"@type": "g:Int64",
                   
"@value": 10
                   
},
               
"value": {
                   
"@type": "janusgraph:Geoshape",
                   
"@value": {"type": "Point", "coordinates": [{"@value": -90.2, "@type": "g:Double"}, {"@value": 30.3, "@type": "g:Double"}]}
                   
},
               
"properties": {}

               
}


I can successfully read the data into Janusgraph/Cassandra. But I don't understand how to construct a query to calculate and return the distance between two vertices, say, with IDs 10 and 20, or even more simply, between vertex ID 10 and itself. For example, the following does not work:

    results = await (session.g.V(10)
       
.properties('point')
       
.as_("a")
       
.distance(__.select('a'))
       
.toList()
       
)

It fails with the message: TypeError: 'AsyncGraphTraversal' object is not callable

The javadocs for Janusgraph indicate that the distance function is: 

public double distance(Geoshape.Point other)

where other is a second point. Most of the Geoshape examples I can find on the web look something like this:

g.E().has("place", geoWithin(Geoshape.circle(37.97, 23.72, 50)))

But that is not my use case. I have geo data saved, and I wish to select points, calculate distances between them, and return the results. Any suggestions would be appreciated.





Jason Plurad

unread,
Sep 4, 2018, 11:37:36 AM9/4/18
to Gremlin-users
Geoshape is a JanusGraph-specific datatype so the TinkerPop gremlin-python GLV isn't able to handle it.
We've started work on a JanusGraph Python GLV. If you're interested and inclined, you can help give it a review.
https://github.com/JanusGraph/janusgraph-python/pull/4

John B

unread,
Sep 4, 2018, 2:47:46 PM9/4/18
to Gremlin-users
Thanks Jason. I don't see how janusgraph-python can be used to calculate distance between two points, which was my question. Your code includes methods like getLatitude(), but not distance(). Is the Janusgraph distance(self, other) function internal only, such that it cannot be called? Or is there some way to call it that is not yet implemented in janusgraph-python?  If so, what would that look like?

I understand I could use janusgraph-python to call getCoordinates() and calculate the distance myself, external to Janusgraph. O I could use your code to search for a point within the radius of a circle, using geoContains. I was thinking that using Janusgraph to calculate a bunch of distances would be faster than pulling the geolocations into python and then calculating distances there.

John B

unread,
Sep 9, 2018, 6:51:55 PM9/9/18
to Gremlin-users
I have now tried janusgraph-python, and it seems to work well on my small test. Thanks to those who put this together. My question remains, however. Is there some way to call Geoshape.Point.distance(self, other), to have Janusgraph calculate and return the distance between two points? If so, can someone suggest the traversal that would accomplish this task?
John

Florian Hockmann

unread,
Sep 11, 2018, 9:17:07 AM9/11/18
to Gremlin-users
Currently, that would only be possible with a lambda which allows you to execute arbitrary code on the server as part of your traversal. However, it would also be possible to add a similar functionality to the Python Point class in the future. I think we should first try to keep the language drivers relatively simple so that they basically only enable writing traversals that use JanusGraph specific types and predicates. At a later point, we can then better decide whether we want to add more complexity to them or not.
Reply all
Reply to author
Forward
0 new messages