python通过射线法判定POI是否在多边形区块内

通过射线法判定POI是否在多边形区块内。

方法简介:
1、射线法:由目标点横向或纵向引出一条射线,和多边形区块的边相交,若相关点个数为奇数,则目标点在该区块内,否则不在该区块内;
2、根据已有的POI中心点坐标poi_xy和多边形区块wkt坐标,判断POI是否在多边形区块内。

from odps.udf import annotate

@annotate("string,string->bigint")
class IsInBusinessDistrict(object):
    def evaluate(self, poi_coordinate, multipolygon_str):
        try:
            multipolygon_list = multipolygon_str.split(",")
            poi_point = poi_coordinate.split(",")
            eps = 10**-8
            num = 0
            for i in range(len(multipolygon_list)-2):
                point1 = multipolygon_list[i].split(" ")
                point2 = multipolygon_list[i+1].split(" ")
                y_min = min(float(point1[1]), float(point2[1]))
                y_max = max(float(point1[1]), float(point2[1]))
                x = (float(poi_point[1])-float(point1[1]))*(float(point2[0])-float(point1[0]))/(float(point2[1])-float(point1[1]) + eps) + float(point1[0])
                if round(x, len(poi_point[0].split(".")[1])) == float(poi_point[0]):
                    return 1 
                elif x < float(poi_point[0]) and float(poi_point[1]) <= y_max and float(poi_point[1]) >= y_min:
                    # print (multipolygon_list[i], multipolygon_list[i+1], x, y_min, y_max)
                    num += 1
            print (num)
            if num % 2 == 1:
                return 1 
            else :
                return 0
        except:
            return 0


if __name__ == "__main__": 
    # case1
    poi_xy = "116.345736,39.917016"
    # sq1
    multi_str = "116.334202 39.932311,116.334353 39.932328,116.343731 39.932281,116.355389 39.932249,116.355395 39.932143,116.355505 39.930468,116.355512 39.930336,116.355623 39.928324,116.355744 39.925789,116.355503 39.925059,116.355421 39.924839,116.355457 39.923889,116.355293 39.923788,116.346404 39.923526,116.337348 39.923216,116.334995 39.923175,116.334784 39.923257,116.334510 39.925302,116.334179 39.930500,116.334144 39.930922,116.334098 39.931998,116.334098 39.932212,116.334202 39.932311"
    res = IsInBusinessDistrict().evaluate(poi_xy, multi_str)
    print(res)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值