# 判断一个点是否在楼层的轮廓里 ## 前置条件 业务空间必须有轮廓, 且合法 ## 处理逻辑 1. 业务空间外轮廓数据格式由如下示例所示, 由若干个元空间(子轮廓)的轮廓组成 2. 判断点在是否在某一个子轮廓内, 如果在, 则点在业务空间内(返回true) 1). 判断点在子轮廓内, 需要判断点在子轮廓的外轮廓内, 且不在任意1个子轮廓被排除的轮廓内 ## 业务空间轮廓结构示例 ``` [ [ [ {点坐标的XYZ信息}, {点坐标的XYZ信息}... ], // 子轮廓的外轮廓 [ {点坐标的XYZ信息}, {点坐标的XYZ信息}... ], // 子轮廓的第n个需要被排除的轮廓, 可能有若干个 ], // 子轮廓 [ [ {点坐标的XYZ信息}, {点坐标的XYZ信息}... ] ], ] ``` # 函数 ## 版本1
输入为浮点型 ``` CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v3"("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) def is_in_polygon(point, polygons): length = len(polygons) if length == 0: return False for j in range(length): polygon = polygons[j] if j == 0: if not is_in_meta_polygon(point, polygon, -0.001): return False else: if is_in_meta_polygon(point, polygon, 0.001): return False return True try: polygon_list = json.loads(json_poly) total_len = len(polygon_list) point_pair = (x, y) for index in range(total_len): if is_in_polygon(point_pair, polygon_list[index]): return True return False except Exception as e: return False $BODY$ LANGUAGE plpython3u VOLATILE COST 100 ```
## 版本2
输入为字符串类型 ``` CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v3_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) def is_in_polygon(point, polygons): length = len(polygons) if length == 0: return False for j in range(length): polygon = polygons[j] if j == 0: if not is_in_meta_polygon(point, polygon, -0.001): return False else: if is_in_meta_polygon(point, polygon, 0.001): return False return True try: polygon_list = json.loads(json_poly) total_len = len(polygon_list) point_pair = (float(x), float(y)) for index in range(total_len): if is_in_polygon(point_pair, polygon_list[index]): return True return False except Exception as e: return False $BODY$ LANGUAGE plpython3u VOLATILE COST 100 ```
## 输入 1. 点的x坐标 2. 点的y坐标 3. 业务空间的轮廓 ## 返回结果 true 成功 false 失败