Unable to create jts Polygon with sptaial.use.jts, malformed shape


(Dallas Phillips) #1

I am trying to use the extended spatial feature with Stardog. What I have done so far is make sure to turn on spatial indexing for the database. I next download the jts-core-1.14.0.jar, put this in the %STARDOG_HOME%/server/ext directory and set the spatial.use.jts to true in the stardog.properties file.

My first question is how can one be sure that the properties were loaded?

Next to test, I try to import a trig data.trig (1.0 KB) that has a geometry with a Point, and another with a Polygon. I get this exception when I try to import the file:

WARN 2018-12-04 11:58:39,709 [stardog-user-15] com.complexible.stardog.spatial.io.StatementSourceGeospatialSource:parse(95): Failed to parse unknown/malformed shape Polygon((-103.970560 37.494700, -103.970591 37.492456, -103.967732 37.494675, -103.967763 37.492422, -103.970560 37.494700)). Skipping this record

This would hint to me that the properties file was not read and the spatial.use.jts prop was not set. But I do not know a way to see the servers properties when it is started.


(stephen) #2

You specify %STARDOG_HOME%/server/ext. Unless %STARDOG_HOME% also happens to be where your Stardog installation lives, this will not be correct. Assuming that Stardog is instead installed in %STARDOG%, you would need to put the jar in %STARDOG%/server/ext

If you happen to have a %STARDOG_EXT% variable set, Stardog will look in that location instead.

As far as properties, the %STARDOG_HOME%/stardog.properties file is always loaded, and the db-level options specified in it are used at db create time. You may want to use the stardog-admin metadata get myDb -o spatial.use.jts -- command on your database to ensure that it is set to true at that level (and if it is not, metadata set will set it for you).

After all this and a server restart for good measure, you should see this shape parse properly.


(Dallas Phillips) #3

I might have been wrong in using %STARDOG_HOME% I am confident I have it in the right place because it is placed with another jar I created for user defined functions.

As for the command you shared, I get Invalid option as a response. Does this mean that it is not set?

And I also tried to just set the option but get Invalid option: spatial.use.jts. as a response.


(zachary.whitley) #4

Are you using a community, enterprise or 30-day eval license? The spatial features are only available with the enterprise or 30-day eval license.


(Dallas Phillips) #5

It is enterprise. I can use other spatial functionality fine but it is the jts stuff that I am needing to enable.


(stephen) #6

I misspoke; spatial.use.jts in indeed not a database-level setting. I get tripped up on that one. Only other thing I can think of is to ensure that your stardog.properties file is in $STARDOG_HOME (not the stardog install directory). If it is, could you share both the properties file and the output of stardog-admin metadata get myDb?


(Dallas Phillips) #7

stardog.properties.trig (16.1 KB)
meta.txt.trig (10.3 KB)

I uploaded them as trig but just remove the extension (to get around not being able load text or property files).


(stephen) #8

I apologize, we went right for the properties and settings and I failed to notice that the problem is actually with your data!

You are casting your Polygon as a <http://www.opengis.net/ont/sf#wktLiteral>, when you want to be casting to a geo:wktLiteral. If I change that, I am able to get the spatial index to parse your shape without any errors, and hopefully you can do the same!


(Dallas Phillips) #9

Unfortunately that did not work for me. Still get:

WARN 2018-12-06 13:07:26,615 [stardog-user-16] com.complexible.stardog.spatial.io.StatementSourceGeospatialSource:parse(95): Failed to parse unknown/malformed shape Polygon(-103.970560 37.494700, -103.970591 37.492456, -103.967732 37.494675, -103.967763 37.492422, -103.970560 37.494700). Skipping this record

This is the update trig I am importing into my database. I casted as geo:wktLiteral with no difference.
export.trig (996 Bytes)

It should also be noted for context that I am handling the import with Stardog Studio.


(stephen) #10

OK, after some more research, I think I've found the issue. Apparently (according to JTS anyway), Polygons cannot intersect themselves, as yours does (it appears to be 2 triangles that share a point).

The way we can model this with JTS, then, is to use a MultiPolygon and define the 2 triangles each as a Polygon within it. WIth all that said I was able to get your Geometry to load as geo:asWKT "MultiPolygon(((-103.970591 37.492456, -103.970560 37.494700, -103.968238 37.494500, -103.970591 37.492456)), ((-103.967732 37.494675, -103.967763 37.492422, -103.968238 37.494500, -103.967732 37.494675)))"^^geo:wktLiteral


(Dallas Phillips) #11

After doing some rearranging of the entries, I was able to import the data with no errors in the log. That problem is now solved, thank you. However, I am unable to get the geof:within(, ) to work with the point I ingest and the now-able-to-create polygon. Here is the query and corrected data:
export.trig (998 Bytes)

prefix geo:<http://www.opengis.net/ont/geosparql#>
prefix geof:<http://www.opengis.net/def/function/geosparql/>

select ?area where {
    graph ?ag {
        ?area a <tag:exp#Area> .
        ?area geo:hasGeometry ?ageo #Polygon
    }
    graph ?sg {
        ?sig a <tag:exp#Signal> .
        ?sig geo:hasGeometry ?sgeo #Point
    }
    filter(geof:within(?sgeo, ?ageo))
}

This will work when I replace ?ageo with the literal text of the corrected Polygon. In the Geospatial: A Primer, one of the accepted forms of the geof:within is <Geometry> geof:within <Geometry> so I would assume translates to the filter form used in the this query (of course I could be wrong). If I am wrong, then how would I be able to use both geometries in the query? I need to do it in this form for my scenario.


(stephen) #12

I thought I had tested all of the permutations out while writing the Geospatial: A Primer blog post, but apparently I missed this corner case where both objects were variables. Looking through our code I'm still not quite picking up on why this is returning no bindings.

However, I did find a workaround for you that should still be just as readable, as the geof:relate function seems to work just fine when given multiple variables, so you can replace your filter with filter(geof:relate(?sgeo, ?ageo, geo:within)) and it will return what you're looking for.

Thanks for bearing with me on these issues!


(Dallas Phillips) #13

Thank you for the persistent work Stephen. I just tested with the sample data and it did in fact work! Readability is good as it's easy to understand as you go through the sparql. I will now see how it works with our own data sets and see if any more snags occur! Thanks again!


(Dallas Phillips) #14

I think should be noted also what I have discovered with the polygon lat/lon pair sequence. The data am using has a southwest, northwest, northeast, and southeast points. Naturally that order could be considered a valid sequence for Polygon(LONG1 LAT1, LONG2 LAT2, ..., LONGN LATN, LONG1 LAT1). But rather, when switching values around to make it work, I needed to go in this order:
Polygon(NW, SE, NE, SW, NW)
Which when drawing out on paper at least, has an intersection where the original input:
Polygon(SW, NW, NE, SE, SW)
when drawn out has no intersection but the expected results are opposite when importing to Stardog.
Do you have any insight as the ordering or sequence of input points for a the Polygon?


(stephen) #15

Apologies for the delay on this... I actually seem to be having the opposite of what you are saying. I define two polygons using 4 somewhat arbitrary points, and the :SW_NW_NE_SE_SW polygon is the one that loads with no issues, while the other one (that on paper has an intersection) does not:

insert data {
    :SW_NW_NE_SE_SW a geo:Geometry ;
        geo:asWKT "Polygon(( -76.7278 39.96, -76.7205 40.063, -76.3055 40.0378, -76.7278 39.96, -76.7278 39.96 ))"^^geo:wktLiteral .

    :NW_SE_NE_SW_NW a geo:Geometry ;
        geo:asWKT "Polygon(( -76.7205 40.063, -76.0916 39.5477, -76.3055 40.0378, -76.7278 39.96, -76.7205 40.063 ))"^^geo:wktLiteral .
}

WARN  2018-12-17 09:12:08,534 [stardog-user-5] com.complexible.stardog.spatial.io.StatementSourceGeospatialSource:parse(97): Failed to parse unknown/malformed shape "Polygon(( -76.7205 40.063, -76.0916 39.5477, -76.3055 40.0378, -76.7278 39.96, -76.7205 40.063 ))"^^<http://www.opengis.net/ont/geosparql#wktLiteral>. Skipping this record

Could you share the 4 points you are using and I'll try to reproduce with those?