How to create geospatial schema.
Three geospatial data types, point,
linestring, and polygon, store data that can be searched with
geospatial shapes. After creating schema for these data types, geospatial queries can be constructed using
them. For most geospatial queries that look for geospatial points, points or
linestrings within circles or polygons, DSE Search indexes must also be
created.
The examples below load geospatial data with graph.addVertex(…)
commands, but the DSE Graph Loader can be used to load
geospatial data starting with DSE 5.0.9 and DSE 5.1.2.
Procedure
Point schema
-
Create schema for a point and add a vertex with a property value for a
point:
schema.propertyKey('name').Text().create()
schema.propertyKey('point').Point().withGeoBounds().create()
schema.vertexLabel('location').properties('name','point').create()
graph.addVertex(label, 'location', 'name', 'Paris', 'point', Geo.point(2.352222, 48.856614))
A vertex label is created for
location that has a
point property.
Note: For geospatial linestrings, as with geospatial
points, the
withGeoBounds()
method limit searches to a
default valid range of latitude in degrees from -90 to +90 (South Pole to
North Pole) and a valid range of longitude in degrees from -180 to +180
(east to west from the
Greenwich Meridian). The point is
specified using
Geo.point(longitude, latitude)
when adding
the point, using
WellKnownText (WKT) format. Note
that is specifies
longitude first, then
latitude.
Check that the point
exists:
g.V().has('location', 'name', 'Paris').valueMap()
==>{name=[Paris], point=[POINT (2.352222 48.856614)]}
Linestring schema
-
Create schema for a linestring and add a vertex with a property value
for a linestring:
schema.propertyKey('name').Text().create()
schema.propertyKey('line').Linestring().withGeoBounds().create()
schema.vertexLabel('lineLocation').properties('name','line').create()
graph.addVertex(label, 'lineLocation', 'name', 'ParisLondon', 'line', "LINESTRING(2.352222 48.856614, -0.127758 51.507351)")
A vertex label is created for
lineLocation that has a
LineString
property. The same
boundary
limits imposed on points are imposed on linestrings.
Check that the linestring
exists:
g.V().has('lineLocation','name','ParisLondon').valueMap()
==>{line=[LINESTRING (2.352222 48.856614, -0.127758 51.507351)], name=[ParisLondon]}
Polygon schema
-
Create schema for a polygon and add a vertex with a property value for a
polygon:
schema.propertyKey('name').Text().create()
schema.propertyKey('polygon').Polygon().withGeoBounds().create()
schema.vertexLabel('polyLocation').properties('name','polygon').create()
graph.addVertex(label, 'polyLocation','name', 'ParisLondonDublin', 'polygon',Geo.polygon(2.352222, 48.856614, -0.127758, 51.507351, -6.26031, 53.349805))
A vertex label is created for
polyLocation that has a
Polygon
property. The same
boundary
limits imposed on points are imposed on polygons.
Check that the polygon
exists:
g.V().has('polyLocation','name','ParisLondonDublin').valueMap()
==>{polygon=[POLYGON ((2.352222 48.856614, -0.127758 51.507351, -6.26031 53.349805, 2.352222 48.856614))], name=[ParisLondonDublin]}
DSE Search indexes
-
While DSE Graph natively supports geospatial searches, performing them without
a Search index does not scale as the number of vertices in the graph increases.
Doing such queries without a search index results in very inefficient query
performance because full scans are required. DSE Search indexes can index points
and linestrings, but not polygons.
//SEARCH INDEX ONLY WORKS FOR POINT AND LINESTRING
schema.vertexLabel('location').index('search').search().by('point').add()
schema.vertexLabel('lineLocation').index('search').search().by('line').add()
Without a search index, spatial queries always return exact results. DSE
Search indexes, however, can trade off performance for accuracy.
Note: A point of confusion can occur if the same
geospatial query is run with or without a DSE Search index. Without a
search index, geospatial queries always return exact results. DSE Search
indexes, however, trade off write performance and index size for query
accuracy with
two tunable parameters,
maxDistErr (default: 0.000009)
and
distErrPct (default: 0.025)
. Inconsistent results
in these two cases are due to the distance calculation algorithm
variation of the default values of these parameters. DSE Graph can pass
values for these two parameters when creating the search index. Change
maxDistErr
in
withError(maxDistErr,
distErrPct)
to
0.0
to force both
index-backed and non-index-backed queries to yield the same
value:
schema.vertexLabel('location').index('search').search().by('point').withError(0.000009,0.0).add()
What's next
Geospatial queries
can be created once schema exists.