is_point_in_polygon_v2.md 2.9 KB

判断一个点是否在元空间的轮廓里

前置条件

元空间必须有轮廓, 且合法

处理逻辑

1. 元空间外轮廓数据格式由如下示例所示
2. 需要判断点在外轮廓内, 且不在任意1个被排除的轮廓内

元空间轮廓示例


[
    [
        {点坐标的XYZ信息},
        {点坐标的XYZ信息}...
    ], // 轮廓的外层轮廓
    [
        {点坐标的XYZ信息},
        {点坐标的XYZ信息}...
    ], // 轮廓的第n个需要被排除的轮廓, 可能有若干个
]

函数

版本1

输入为浮点型
CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v2"("x" float8, "y" float8, "json_poly" jsonb)
  RETURNS "pg_catalog"."bool" AS $BODY$
from matplotlib.path import Path
import json

def is_in_meta_polygon(point, single_poly, radius):
    poly_len = len(single_poly)
    poly = []
    for i in range(poly_len):
        pair = single_poly[i]
        poly.append((pair["X"], pair["Y"]))
    p = Path(poly)
    return p.contains_points([point], None, radius)

try:
    polygons = json.loads(json_poly)
    total_len = len(polygons)
    point_pair = (x, y)
    if total_len == 0:
        return False
    for i in range(total_len):
        polygon = polygons[i]
        if(i == 0):
            if not is_in_meta_polygon(point_pair, polygon, -0.001):
                return False
        else:
            if is_in_meta_polygon(point_pair, polygon, 0.001):
                return False
    return True
except Exception as e:
    return False
else:
    return True

$BODY$
  LANGUAGE plpython3u VOLATILE
  COST 100

版本2

输入为字符串类型
CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v2_str"("x" varchar, "y" varchar, "json_poly" jsonb)
  RETURNS "pg_catalog"."bool" AS $BODY$
from matplotlib.path import Path
import json

def is_in_meta_polygon(point, single_poly, radius):
    poly_len = len(single_poly)
    poly = []
    for i in range(poly_len):
        pair = single_poly[i]
        poly.append((pair["X"], pair["Y"]))
    p = Path(poly)
    return p.contains_points([point], None, radius)

try:
    polygons = json.loads(json_poly)
    total_len = len(polygons)
    point_pair = (float(x), float(y))
    if total_len == 0:
        return False
    for i in range(total_len):
        polygon = polygons[i]
        if(i == 0):
            if not is_in_meta_polygon(point_pair, polygon, -0.001):
                return False
        else:
            if is_in_meta_polygon(point_pair, polygon, 0.001):
                return False
    return True
except Exception as e:
    return False
else:
    return True

$BODY$
  LANGUAGE plpython3u VOLATILE
  COST 100

输入

1. 点的x坐标
2. 点的y坐标
3. 元空间的轮廓

返回结果

true    成功
false   失败