MySQL ERROR 3037: Invalid GIS data provided to function st_within - mysql

Following query:
SELECT st_contains(ST_GeomFromText('POLYGON((
9.2949170148074 3.5550157117451,
12.230624391667 3.5550157117451,
12.24455565975 4.9035765788215,
9.300807190941 4.8942904468525,
9.3019824958588 3.5550157117451,
9.2949170148074 3.5550157117451
))'),ST_GeomFromText("POINT( 6.31 8.92)"))
issues error Invalid GIS data provided to function st_within.
Although I don't see anything wrong with the query (last point is the same as first, points create ring, syntax is correct). When I remove the second to last point (9.3019824958588 3.5550157117451) then the query succeeds:
SELECT st_contains(ST_GeomFromText('POLYGON((
9.2949170148074 3.5550157117451,
12.230624391667 3.5550157117451,
12.24455565975 4.9035765788215,
9.300807190941 4.8942904468525,
9.2949170148074 3.5550157117451))'),ST_GeomFromText("POINT( 6.31 8.92)"))
Did I miss something?
Can I somehow further debug the message about Invalid GIS data to be more useful?
I'm using MySQL 5.7.31-0ubuntu0.18.04.1

I believe I found the answer: I tried ST_IsValid on both polygons, first one returned false (probably because it intersects itself), second one true. However, I tried several other self-intersecting polygons to feed the st_contains function without raising an error.
Then according to https://dev.mysql.com/doc/refman/5.7/en/geometry-well-formedness-validity.html
Spatial computations may detect some cases of invalid geometries and raise an error, but they may also return an undefined result without detecting the invalidity.
So whenever I got some result using self-intersecting polygons in the past, it was undefined and only this particular polygon in this question raised an error.
Conclusion is that if one uses spatial functions, one should check validity of geometry beforehand using ST_IsValid, because MySQL does not check it on inserts, nor updates - according to documentation:
It is permitted to insert, select, and update geometrically invalid geometries, but they must be syntactically well-formed. Due to the computational expense, MySQL does not check explicitly for geometric validity.
One point to add, this functionality has apparently changed between MySQL 5.6 and 5.7, in 5.6 the "faulty" polygon does not raise an error, whereas in 5.7 does.

Related

How to use RANSAC method to fit a line in Matlab

I am using RANSAC to fit a line to my data. The data is 30X2 double, I have used MatLab example to write the code given below, but I am getting an error in my problem. I don't understand the error and unable to resolve it.
The link to Matlab example is
https://se.mathworks.com/help/vision/ref/ransac.html
load linedata
data = [xm,ym];
N = length(xm); % number of data points
sampleSize = 2; % number of points to sample per trial
maxDistance = 2; % max allowable distance for inliers
fitLineFcn = polyfit(xm,ym,1); % fit function using polyfit
evalLineFcn =#(model) sum(ym - polyval(fitLineFcn, xm).^2,2); % distance evaluation function
[modelRANSAC, inlierIdx] = ransac(data,fitLineFcn,evalLineFcn,sampleSize,maxDistance);
The error is as follows
Error using ransac Expected fitFun to be one of these types:
function_handle
Instead its type was double.
Error in ransac>parseInputs (line 202) validateattributes(fitFun,
{'function_handle'}, {'scalar'}, mfilename, 'fitFun');
Error in ransac (line 148) [params, funcs] = parseInputs(data, fitFun,
distFun, sampleSize, ...
Lets read the error message and the documentation, as they tend to have all the information required to solve the issue!
Error using ransac Expected fitFun to be one of these types:
function_handle
Instead its type was double.
Hum, interesting. If you read the docs (which is always the first thing you should do) you see that fitFun is the second input. The error says its double, but it should be function_handle. This is easy to verify, indeed firLineFun is double!
But why? Well, lets read more documentation, right? polyfit says that it returns an array of the coefficient values, not a function_hanlde, so indeed everything the documentation says and the error says is clear about why you get the error.
Now, what do you want to do? It seems that you want to use polyfit as the function to fit with ransac. So we need to make it a function. According to the docs, fitFun has to be of the form fitFun(data), so we just do that, create a function_handle for this;
fitLineFcn=#(data)polyfit(data(:,1),data(:,2),1);
And magic! It works!
Lesson to learn: read the error text you provide, and the documentation1, all the information is there. In fact, I have never used ransac, its just reading the docs that led me to this answer.
1- In fact, programmers tend to reply with the now practically a meme: RTFM often, as it is always the first step on everything programming.

Working on migration of SPL 3.0 to 4.2 (TEDA)

I am working on migration of 3.0 code into new 4.2 framework. I am facing a few difficulties:
How to do CDR level deduplication in new 4.2 framework? (Note: Table deduplication is already done).
Where to implement PostDedupProcessor - context or chainsink custom? In either case, do I need to remove duplicate hashcodes from the list or just reject the tuples? Here I am also doing column updating for a few tuples.
My file is not moving into archive. The temporary output file is getting generated and that too empty and outside load directory. What could be the possible reasons? - I have thoroughly checked config parameters and after putting logs, it seems correct output is being sent from transformer custom, so I don't know where it is stuck. I had printed TableRowGenerator stream for logs(end of DataProcessor).
1. and 2.:
You need to select the type of deduplication. It is not a big difference if you choose "table-" or "cdr-level-deduplication".
The ite.businessLogic.transformation.outputType does affect this. There is one Dedup only. You can not have both.
Select recordStream for "cdr-level-deduplication", do the transformation to table row format (e.g. if you like to use the TableFileWriter) in xxx.chainsink.custom::PostContextDataProcessor.
In xxx.chainsink.custom::PostContextDataProcessor you need to add custom code for duplicate-handling: reject (discard) tuples or set special column values or write them to different target tables.
3.:
Possibly reasons could be:
Missing forwarding of window punctuations or statistic tuple
error in BloomFilter configuration, you would see it easily because PE is down and error log gives hints about wrong sha2 functions be used
To troubleshoot your ITE application, I recommend to enable the following debug sinks if checking the StreamsStudio live graph is not sufficient:
ite.businessLogic.transformation.debug=on
ite.businessLogic.group.debug=on
ite.businessLogic.sink.debug=on
Run a test with a single input file only and check the flow of your record and statistic tuples. "Debug sinks" write punctuations markers also to debug files.

MySQL: Spatial Query to find whether a latitude/longitude point is located within a given boundary

I'm working on google map search functionality. The vision of this is to find whether a (geolocation) point is located within a polygon or not as shown in the illustration below?
I'm using mysql 5.6.20 with Spatial extension, I know it has useful geometry functions built-in, so I will be allowed to query geocoded locations from a database directly.
My aim was to familiarize myself with geospatial functions, so I wrote up an experimental sql.
given a point geolocation: POINT(100.52438735961914 13.748889613522605)
and a polygon or boundary to be tested with was:
POLYGON(100.49503326416016 13.766897133254545,100.55940628051758 13.746555203977,100.56266784667969 13.72170897580617,100.48885345458984 13.739051587150175)
here is my sql example:
SELECT ST_Within(
ST_GEOMFROMTEXT('POINT(100.52438735961914 13.748889613522605)'),
ST_GEOMFROMTEXT('POLYGON(100.49503326416016 13.766897133254545,
100.55940628051758 13.746555203977,100.56266784667969 13.72170897580617,
100.48885345458984 13.739051587150175)'))
As geoFenceStatus
but after issuing the command, what I got in return seemed to be as follows:
geoFenceStatus
===============
null
I'm so unsure why it returned me 'null' value. since it was indicated in function documentation that this should return '1' in case a point resides within a given polygon
any advice would be appreciated, how to get my sql right.
The error message isn't very clear but your issue is that you have an invalid Polygon. There are two problems with it:
You have to repeat the first point at the end -- this is to differentiate it from a LINESTRING, essentially, ie, it is closed.
POLYGONS start with and end with double parenthesis, ie, POLYGON((x1 y1, x2 y2.......xn yn, x1 y1)). This is to allow for inner rings to be delineated with single parenthesis sets inside the polygon.
See the wikipedia WKT article for more information.
You should find that if you write you query as:
SELECT ST_Within(ST_GEOMFROMTEXT('POINT(100.52438735961914 13.748889613522605)'),
ST_GEOMFROMTEXT('POLYGON((100.49503326416016 13.766897133254545, 100.55940628051758 13.746555203977,100.56266784667969 13.72170897580617, 100.48885345458984 13.739051587150175,
100.49503326416016 13.766897133254545))'))
As geoFenceStatus
then is should work.

GeomFromText function documentation

I see that the following syntax is used in examples:
GeomFromText('Polygon((1 1, 2 2, 3 3))');
The double parenthesis caused a bit of a trouble so I decided to look it up in the official documentation. At my non-small surprise the search mysql polygon did not give me the documentation of this function. A search to mysql geomfromtext also did not give the definition of the function GeomFromText.
So I'm still looking for the official documentation of these functions.
I see that the MySQL Reference Manual for GeomFromText() doesn't even give a typical function definition either, but it does describe how to use it. GeomFromText() converts from "well-known text" (abbreviated as WKT) to MySQL's internal format. WKT is simply a textual representation of a geometry object, which can be a polygon as your example, or any of the other geometry types. A key point to understand is that Polygon(...) is the WKT format for a polygon; it isn't a MySQL function call, even though it sort of looks like one.
Polygons can contain holes. When defining a polygon, you may optionally supply one or more interior boundaries to define such holes. The WKT for polygons use inner parentheses to distinguish these boundaries from one other. Even if you don't want to define holes, the inner parentheses are still required. Wikipedia provides some simple examples of polygon WKTs together with pictures of the resulting polygons.

Catch Mathematica warnings/errors without displaying them

I have a problem involving NDSolve in Mathematica, which I run multiple times with different values of the parameters. For some of these values, the solution results in singularities and NDSolve warns with NDSolve::ndsz or other related warnings.
I would simply like to catch these warnings, suppress their display, and just keep track of the fact that a problem occurred for these particular values of the parameters. I thought of the following options (neither of which really do the trick):
I know I can determine whether a command has resulted in a warning or error by using Check. However, that will still display the warning. If I turn it off with Off the Check fails to report the warning too.
It is possible to stop NDSolve using the EventLocator method, so I could check for very large values of the function or its derivatives and stop evaluation in that case. However, in practice, this still produces warnings from time to time, presumably because the step size can sometimes be so large that the NDSolve warning triggers before my Event has taken place.
Any other suggestions?
If you wrap the Check with Quiet then I believe that everything should work as you want. For example, you can suppress the specific message Power::indet
In[1]:= Quiet[Check[0^0,err,Power::indet],Power::indet]
Out[1]= err
but other messages are still displayed
In[2]:= Quiet[Check[Sin[x,y],err,Power::indet],Power::indet]
During evaluation of In[2]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
Out[2]= Sin[x,y]
Using Quiet and Check together works:
Quiet[Check[Table[1/Sin[x], {x, 0, \[Pi], \[Pi]}], $Failed]]
Perhaps you wish to redirect messages? This is copied almost verbatim from that page.
stream = OpenWrite["msgtemp.txt"];
$Messages = {stream};
1/0
FilePrint["msgtemp.txt"]