Wednesday, August 31, 2016

PHP / Mongo geoJSON Loop is not valid

Leave a Comment

I'm passing in some coordinates to mongo to do a geo search. It works fine if the coordinates don't intersect (for instance a figure eight). But when two lines intersect it gives the loop is not valid. Is there any way to find the intersection and split all these loops up?

Note there could be many.

EDIT: I added the sample query and error. Note that I understand why it's happening, I'm just wondering if there is some known way to split those loops up into separate polygon's (some algorithm or within Mongo).

Query:

db.items.find({     "address.location": {         "$geoWithin": {             "$geometry": {                 "type": "Polygon",                 "coordinates": [[                     [-97.209091, 49.905691],                     [-97.206345, 49.918072],                     [-97.178879, 49.919399],                     [-97.165146, 49.907903],                     [-97.164459, 49.892865],                     [-97.180939, 49.889326],                     [-97.197418, 49.895077],                     [-97.200165, 49.902596],                     [-97.203598, 49.919399],                     [-97.216644, 49.928682],                     [-97.244797, 49.927356],                     [-97.255096, 49.913209],                     [-97.209091, 49.905691]                 ]]             }         }     } }); 

Error:

Error: error: {     "waitedMS" : NumberLong(0),     "ok" : 0,     "errmsg" : "Loop is not valid: [             [ -97.209091, 49.905691 ]             [ -97.206345, 49.918072 ],             [ -97.17887899999999, 49.919399 ],             [ -97.16514599999999, 49.907903 ],             [ -97.16445899999999, 49.892865 ],             [ -97.180939, 49.889326 ],             [ -97.197418, 49.895077 ],             [ -97.200165, 49.902596 ],             [ -97.203598, 49.919399 ],             [ -97.216644, 49.928682 ],             [ -97.24479700000001, 49.927356 ],             [ -97.25509599999999, 49.913209 ],             [ -97.209091, 49.905691 ]         ]         Edges 1 and 7 cross.         Edge locations in degrees: [-97.2063450, 49.9180720]-[-97.1788790, 49.9193990]         and [-97.2001650, 49.9025960]-[-97.2035980, 49.9193990]     ",     "code" : 2 } 

2 Answers

Answers 1

It is because your coordinates are identical that creates an anomaly in the polygon shape: [-97.1788790, 49.9193990] and [-97.2035980, 49.9193990]. In your code remove or change any of the duplicate coordinate,

"coordinates": [[     [-97.209091, 49.905691],     [-97.206345, 49.918072],     [-97.178879, 49.919399], // this line     [-97.165146, 49.907903],     [-97.164459, 49.892865],     [-97.180939, 49.889326],     [-97.197418, 49.895077],     [-97.200165, 49.902596],     [-97.203598, 49.919399], // and this one     [-97.216644, 49.928682],     [-97.244797, 49.927356],     [-97.255096, 49.913209],     [-97.209091, 49.905691] ]] 

Answers 2

As I mentioned in comments the better tool to query spatial data would be to use PostGIS.

For example PostGIS have the ST_validReason() to find the problem with polygon and a st_makevalid to fix but if this is not an option then I would create a service available to your PHP script with shapely python library https://github.com/Toblerity/Shapely

http://toblerity.org/shapely/manual.html

The first premise of Shapely is that Python programmers should be able to perform PostGIS type geometry operations outside of an RDBMS

Certainly shapely is a popular tool, and you should get future help with in on StackOverflow or gis.stackexchange.com from more experienced users

I think the problem you are trying to solve is not as trivial as it sounds.

So I would perform following steps:

1 Find how to do it with shapely

similar questions: Splitting self-intersecting polygon only returned one polygon in shapely in Python

2 create a simple php service which will pass query details to python script

3 Shapely will not prevent the creation of invalid polygon, but exceptions will be raised when they are operated on. So basically on such exception, I would call the script from step 1.

If this is just for one of query, I would just use QGIS software ( import points as CSV, create a new shapefile layer ( of type polygon ), and use Numerical vertex edit plugin )

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment