manticoresoftware / manticoresearch

Easy to use open source fast database for search | Good alternative to Elasticsearch now | Drop-in replacement for E in the ELK soon
https://manticoresearch.com
GNU General Public License v3.0
8.99k stars 500 forks source link

Polygon data type supoort #1410

Open cevin opened 1 year ago

cevin commented 1 year ago

A point takes intersections with multiple polygons

id restarant_name delivery_range
1 Pizza ( (1,1), (2,2), (3,3) )

select contains(delivery_range, point(1,1)) from table

sanikolaev commented 1 year ago

Have you considered the geo-spatial functions https://manual.manticoresearch.com/Functions/Geo_spatial_functions#Geo-spatial-functions ? If so, can you please elaborate more on the issue with them as it's not quite clear what you suggest.

cevin commented 1 year ago
5,15,25,35,45,5
4,14,24,34,44,5
3,13,23,33,43,5
2,12,22,32,42,5
1,11,21,31,41,5

Geographic location-based spatial extent intersection search.

For example, multiple polygons with ranges of

Then contains(polygon_column, point(1,3)) should return 1 , 2 and 3, contains(polygon_column, point(2,5)) should return 1.

The contains method of manticoresearch only accepts a single polygon .

So, Hopefully there can be a data type poylgon similar to MySQL or PostgreSQL.

sanikolaev commented 1 year ago

Thanks for the explanation.

tomatolog commented 1 year ago

could you put all your geo data into JSON field then address it like JSON.field argument of the POLY2D function?

select contains(POLY2D(delivery_range[0],delivery_range[1],delivery_range[2],delivery_range[3],delivery_range[4],delivery_range[5]), point_attr1,point_attr2) from table
select contains(POLY2D( delivery_range[0].x, delivery_range[0].y, delivery_range[1].x, delivery_range[1].y, delivery_range[2].x, delivery_range[2].y), point_attr1,point_attr2) from table

or you do not now the amount of polygons points upfront?

or in case of multiple polygons in the attribute you could address them all with the same function and get the result

select contains(POLY2D( delivery_range[0].x, delivery_range[0].y), point_attr1,point_attr2) as cnd1,  contains(POLY2D( delivery_range[1].x, delivery_range[1].y), point_attr1,point_attr2) as cnd2, contains(POLY2D(delivery_range[2].x, delivery_range[2].y), point_attr1,point_attr2) as cnd3 from table
tomatolog commented 1 year ago

we also has [INDEXOF](https://manual.manticoresearch.com/Functions/Arrays_and_conditions_functions#INDEXOF()) function that could iterate JSON array and returns the index of the first element that matched

select INDEXOF( contains(POLY2D( range.x, range.y), point_attr1,point_attr2) for range in j.delivery_ranges) as val from table
cevin commented 1 year ago

@tomatolog

It's a dynamic range, Set by the "merchant" itself, not necessarily a fixed number of points.

like:

image image

Get all the "ranges" including the point.

image

This may indicate the scope of business accepted by a post office, the scope of takeout delivery for a restaurant, or the scope of business borne by an errand business.

Like PostgreSQL:

CREATE TABLE areas (
    id SERIAL PRIMARY KEY,
    shape POLYGON
);
INSERT INTO areas (shape) VALUES
    ('((0,0),(0,10),(10,10),(10,0),(0,0))'),
    ('((5,5),(5,15),(15,15),(15,5),(5,5))');

postgres=# select *,point(0,0) <@ shape as "include?" from areas;
 id |                shape                | include?
----+-------------------------------------+----------
  1 | ((0,0),(0,10),(10,10),(10,0),(0,0)) | t
  2 | ((5,5),(5,15),(15,15),(15,5),(5,5)) | f
(2 rows)

postgres=# select *,point(5,8) <@ shape as "include?" from areas;
 id |                shape                | include?
----+-------------------------------------+----------
  1 | ((0,0),(0,10),(10,10),(10,0),(0,0)) | t
  2 | ((5,5),(5,15),(15,15),(15,5),(5,5)) | t
(2 rows)