# 判断一个点是否在元空间的轮廓里
## 前置条件
    
    元空间必须有轮廓, 且合法
    
## 处理逻辑

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

## 元空间轮廓示例
```

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

```


# 函数
## 版本1

<details>
<summary>输入为浮点型</summary>

```
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
```
</details>

## 版本2
<details>
<summary>输入为字符串类型</summary>

```
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
```
</details>

## 输入
    1. 点的x坐标
    2. 点的y坐标
    3. 元空间的轮廓
## 返回结果
    true    成功
    false   失败