Reputation: 833
I am trying to write a query against a MarkLogic set of documents that contain geospatial information. Searching for the documents containing points was relatively easy, but I have some documents that define polygons.
<gml:Polygon gml:id="test" srsName="EPSG:4326">
<gml:exterior>
<gml:LinearRing>
<gml:pos>0 5</gml:pos>
<gml:pos>5 10</gml:pos>
<gml:pos>10 5</gml:pos>
<gml:pos>5 0</gml:pos>
<gml:pos>0 5</gml:pos>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
My problem is that I cannot find a cts: or gml: type of query that will allow a user to define a polygon to search for a polygon. I can compare polygons using (http://docs.marklogic.com/6.0/cts:polygon-intersects) type of functions, but that doesn't seem to allow me to query for polygons, just compare shape objects.
Any suggestion on how to do this (or confirmation that I cannot do this) would be greatly appreciated.
Upvotes: 2
Views: 175
Reputation: 1
You're close, but there are still cases where your search polygon can overlap the region in the database without covering one of the region's perimiter points.
MarkLogic Professional Services has a library that does the standard geo operations (intersects, disjoint, contains, within, overlaps, etc) over stored polygons, linestrings, boxes, circles, etc. It works by using a pre-filter step that involves a combination of forward and reverse queries based on cts:bounding-boxes and additional decorating points, leveraging the MarkLogic geo indexes. It then has a secondary step that performs fine-grained exact filter on the polygons/regions that survive the first filter, so you wind up with an exact set of matching regions.
It’s not publicly available, but you can contact your MarkLogic account manager if you want to bring in Professional Services to get access to the library.
Upvotes: 0
Reputation: 833
After a lot of trial and error trying to create a query that worked as expected, I created a solution that worked for my situation. I had documents in MarkLogic that had a mix of gml:Point
and gml:Polygon
information. The problem I had was trying to get a query that covered both situations when the user enters any WKT query.
An example gml:Point
would be:
<gml:Point srsDimension="2" srsName="http://somesite.com">
<gml:pos>1 1</gml:pos>
</gml:Point>
Or it could be like the gml:Polygon
described in the original question.
My mindset was that I needed to query the gml:Polygon
, but in fact, I needed to query the gml:LinearRing
using an cts:element-child-geospatial-query query.
My final query looked like (supports both gml and gml32):
cts:or-query((
cts:element-child-geospatial-query(
xs:QName("gml:Point"),
xs:QName("gml:pos"),
$parsedGeometry
),
cts:element-child-geospatial-query(
xs:QName("gml32:Point"),
xs:QName("gml32:pos"),
$parsedGeometry
),
cts:element-child-geospatial-query(
xs:QName("gml:LinearRing"),
xs:QName("gml:pos"),
$parsedGeometry
),
cts:element-child-geospatial-query(
xs:QName("gml32:LinearRing"),
xs:QName("gml32:pos"),
$parsedGeometry
)
))
Then adding the proper geospatial element child indexes would make the query return what I expect and give sub 0.2 second responses.
Upvotes: 0
Reputation: 7842
Create a cts:polygon
and use it with cts:element-geospatial-query
. The $regions
parameter takes cts:region*
, and cts:polygon
is a subtype of cts:region
. Once you have a cts:element-geospatial-query
you can compose it with other cts:query
items and use it with cts:search
or search:resolve
.
cts:element-geospatial-query(
xs:QName("gml:Polygon"),
cts:polygon(10.0, 35.0, 20.0, 40.0))
Upvotes: 2