一.java实现

所用jar包:

<dependency>
			<groupId>nl.cloudfarming.client</groupId>
			<artifactId>lib-geotools</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>com.vividsolutions</groupId>
			<artifactId>jts</artifactId>
			<version>1.13</version>
		</dependency>

1.传入点或多边形的wkt字符串

/**
     * 判断点是否在某个多边形上
     * @param pointWkt
     * @param ploygonWkt
     * @param isContainsEdge 是否包含边界,如果为true,那么在边界上时也算在多边形内
     * @return
     */
    public static boolean judgePointIfInRegion(String pointWkt, String ploygonWkt,
                                               boolean isContainsEdge) {

        WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory(null));
        Geometry point = null;
        Geometry poly = null;
        try {
            point = reader.read(pointWkt);
            poly = reader.read(ploygonWkt);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(!isContainsEdge){
            // 判断是否在区域内
            return poly.contains(point);
        }else{
            // 判断是否相交或在区域内
            return poly.intersects(point) || poly.contains(point);
        }
    }

测试:

public static void main(String[] args) {

        String wktPoly = "POLYGON ((116.37150802 39.76183098000003,116.38340802 39.76183098000003,116.38340802 39.7579994886348,116.3798506328265 39.75717762188538,116.3780662872948 39.75685062893655,116.3769283831572 39.75675043493624,116.376230979047 39.75674108396044,116.3755731966328 39.75678290806371,116.3742240792109 39.75690322058387,116.3735865028596 39.75704296592238,116.3731405117154 39.75722575706936,116.372299771974 39.75765971936517,116.3718584872889 39.75793849075126,116.3715491604592 39.75817657788684,116.37150802 39.75821656329189,116.37150802 39.76183098000003))"; //请自行搜素了解wkt格式
        String wktPoint = "POINT (116.37150802 39.76183098000003)";

        System.out.println(judgePointIfInRegion(wktPoint,wktPoly,true));


    }

输出:

true

2.传入点或多边形的坐标列表

/**
     * 判断点是否在某个多边形上
     * @param pointCoord
     * @param ploygonCoords
     * @param isContainsEdge 是否包含边界,如果为true,那么在边界上时也算在多边形内
     * @return
     */
    public static boolean judgePointIfInRegion(List<Double> pointCoord,
                                               List<List<List<Double>>> ploygonCoords,boolean isContainsEdge) {

        String pointWkt = "POINT " + pointCoord.toString().
                replace("[","(").replace("]",")").
                replace(","," ");

        String ploygonWkt = "POLYGON " + ploygonCoords.toString().replace(" ", "").
                replace("]],[[", ");(").replace("],[", ";").
                replace("[[[", "((").replace("]]]", "))").
                replace(",", " ").replace(";", ",");

        WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory(null));
        Geometry point = null;
        Geometry poly = null;
        try {
            point = reader.read(pointWkt);
            poly = reader.read(ploygonWkt);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(!isContainsEdge){
            // 判断是否在区域内
            return poly.contains(point);
        }else{
            // 判断是否相交或在区域内
            return poly.intersects(point) || poly.contains(point);
        }
        
    }

测试:

public static void main(String[] args) {

        Gson gson = new Gson();
        String pointCoordStr = "[113.775698, 30.236892]";
        List pointCoord = gson.fromJson(pointCoordStr,List.class);

        String ploygonCoordsStr = "[[[113.76708006000003,30.231097985000019],[113.77808006000006,30.231097985000019],[113.77808006000006,30.240197984999959]," +
                "[113.76708006000003,30.240197984999959],[113.76708006000003,30.231097985000019]]]";
        List ploygonCoords = gson.fromJson(ploygonCoordsStr,List.class);

        System.out.println(judgePointIfInRegion(pointCoord,ploygonCoords,true));
    }

输出:

true

二.Python实现

射线法实现

java 求多边形内点的数量 java判断点是否在多边形内_点

 法一:

'''
判断某个坐标是否在某个封闭区域内

'''


# 判断该点是否在该条线上

# point:点坐标,如:[113.775698, 30.236892]
# o : 该条线的起点
# d : 该条线的终点
def is_in_line(point, o, d):
    # 先判断该点是否在线段范围内,如果不在,
    # 则就算在该方程的直线上但也不在该线段上
    if o[1] > point[1] and d[1] > point[1]:  # 该点纵坐标小于线段最小纵坐标
        return False
    if o[1] < point[1] and d[1] < point[1]:  # 该点纵坐标大于线段最大纵坐标
        return False
    if o[0] > point[0] and d[0] > point[0]:  # 该点横坐标小于线段最小横坐标
        return False
    if o[0] < point[0] and d[0] < point[0]:  # 该点横坐标大于线段最大横坐标
        return False

    # 若线段为垂直直线,则该点的横坐标等于该线段的横坐标才说明在该线段上
    if o[0] == d[0]:
        return True if point[0] == o[0] else False

    # 通过输入的两个点计算一元一次方程,通过输入x,计算y
    a = (d[1] - o[1]) / (d[0] - o[0])
    b = (d[0] * o[1] - o[0] * d[1]) / (d[0] - o[0])
    y = a * point[0] + b
    return True if y == point[1] else False


# 假设以该点向右水平做射线,判断该点是否与该线段有交点(只要线段与射线相交则为true)
# point:点坐标,如:[113.775698, 30.236892]
# o : 该条线的起点
# d : 该条线的终点
def is_ray_intersects_segment(point, o, d):
    if o[1] == d[1]:  # 如果线段是水平直线,则直接无交点
        return False
    # 先判断该点是否在线段范围内,如果不在,
    # 则就算在该方程的直线上但也不在该线段上
    if o[1] > point[1] and d[1] > point[1]:  # 该点纵坐标小于等于线段最小纵坐标
        return False
    if o[1] < point[1] and d[1] < point[1]:  # 该点纵坐标大于等于线段最大纵坐标
        return False

    # 先求出一元一次方程求交点
    # 若线段为垂直直线,则该点的横坐标应该小于该点的横坐标才能有交点
    # if o[0] == d[0]:
    #     return True if point[0] < o[0] else False
    #
    # # 通过输入的两个点计算一元一次方程,通过输入x,计算y
    # a = (d[1] - o[1]) / (d[0] - o[0])
    # b = (d[0] * o[1] - o[0] * d[1]) / (d[0] - o[0])
    # x = (point[1] - b) / a

    # 利用三角形比例关系求交点
    x = d[0] - (d[0] - o[0]) * (d[1] - point[1]) / (d[1] - o[1])

    # 如果该点的横坐标小于相同水平线上交点的横坐标,则有交点
    return True if point[0] < x else False


"""
判断是否在矩形区域内

point_coord:点坐标,如:[113.775698, 30.236892]
polygon_coords:封闭多边形,如:[[[113.76708006000003,30.231097985000019],
[113.77808006000006,30.231097985000019],[113.76708006000003,30.231097985000019]]]
is_contains_edge: 是否包含边界,如果为true,那么在边界上时也算在多边形内
"""


def is_point_in_polygon(point_coord, polygon_coords, is_contains_edge):
    intersect_count = 0  # 交点个数
    for polygon in polygon_coords:
        # 循环每条边
        for i in range(len(polygon) - 1):
            origin_point = polygon[i]
            destination_point = polygon[i + 1]

            # 是否包含存在直线上的点
            if is_in_line(point_coord, origin_point, destination_point):
                return True if is_contains_edge else False

            if is_ray_intersects_segment(point_coord, origin_point, destination_point):
                # 有交点就加1
                intersect_count += 1

    # 如果恰好与端点相交,则查看相应的端点,并减去与该点相同纵坐标且在该点右侧的点的个数
    endpoint_intersects_count = 0
    for polygon in polygon_coords:
        # 遍历每一个点,但是因为最后一个点和第一个点是重复的,所以最后一个不遍历
        for i in polygon[:-1]:
            if i[1] == point_coord[1] and i[0] > point_coord[0]:
                endpoint_intersects_count += 1
    intersect_count -= endpoint_intersects_count
    return True if intersect_count % 2 == 1 else False


poly = [[
    [2.0, 4.0],
    [2.0, 6.0],
    [4.0, 8.0],
    [6.0, 8.0],
    [8.0, 6.0],
    [8.0, 4.0],
    [6.0, 2.0],
    [4.0, 2.0],
    [2.0, 4.0]
],
    [
        [3.0, 5.0],
        [4.0, 7.0],
        [6.0, 7.0],
        [7.0, 6.0],
        [6.0, 5.0],
        [3.0, 5.0]
    ]
]

poi = [6.5, 7]

print(is_point_in_polygon(poi, poly, False))

 法二:

'''
判断某个坐标是否在某个封闭区域内

'''


# 判断该点是否在该条线上

# point:点坐标,如:[113.775698, 30.236892]
# o : 该条线的起点
# d : 该条线的终点
def is_in_line(point, o, d):
    # 先判断该点是否在线段范围内,如果不在,
    # 则就算在该方程的直线上但也不在该线段上
    if o[1] > point[1] and d[1] > point[1]:  # 该点纵坐标小于线段最小纵坐标
        return False
    if o[1] < point[1] and d[1] < point[1]:  # 该点纵坐标大于线段最大纵坐标
        return False
    if o[0] > point[0] and d[0] > point[0]:  # 该点横坐标小于线段最小横坐标
        return False
    if o[0] < point[0] and d[0] < point[0]:  # 该点横坐标大于线段最大横坐标
        return False

    # 若线段为垂直直线,则该点的横坐标等于该线段的横坐标才说明在该线段上
    if o[0] == d[0]:
        return True if point[0] == o[0] else False

    # 通过输入的两个点计算一元一次方程,通过输入x,计算y
    a = (d[1] - o[1]) / (d[0] - o[0])
    b = (d[0] * o[1] - o[0] * d[1]) / (d[0] - o[0])
    y = a * point[0] + b
    return True if y == point[1] else False


# 假设以该点向右水平做射线,判断该点是否与该线段有交点(当射线与线段下端点相交时为False)
# point:点坐标,如:[113.775698, 30.236892]
# o : 该条线的起点
# d : 该条线的终点
def is_ray_intersects_segment(point, o, d):
    if o[1] == d[1]:  # 如果线段是水平直线,则直接无交点
        return False
    # 先判断该点是否在线段范围内,如果不在,
    # 则就算在该方程的直线上但也不在该线段上
    if o[1] > point[1] and d[1] > point[1]:  # 该点纵坐标小于等于线段最小纵坐标
        return False
    if o[1] < point[1] and d[1] < point[1]:  # 该点纵坐标大于等于线段最大纵坐标
        return False
    if o[1] == point[1] and d[1] > point[1]:  # 若o点为下端点且交点为下端点时
        return False
    if d[1] == point[1] and o[1] > point[1]:  # 交d点为下端点且交点为下端点时
        return False

    # 注释部分为 先求出一元一次方程求交点
    # 若线段为垂直直线,则该点的横坐标应该小于该点的横坐标才能有交点
    # if o[0] == d[0]:
    #     return True if point[0] < o[0] else False
    #
    # # 通过输入的两个点计算一元一次方程,通过输入x,计算y
    # a = (d[1] - o[1]) / (d[0] - o[0])
    # b = (d[0] * o[1] - o[0] * d[1]) / (d[0] - o[0])
    # x = (point[1] - b) / a

    # 利用三角形比例关系求交点
    x = d[0] - (d[0] - o[0]) * (d[1] - point[1]) / (d[1] - o[1])
    # 如果该点的横坐标小于相同水平线上交点的横坐标,则有交点
    return True if point[0] < x else False


"""
判断是否在矩形区域内

point_coord:点坐标,如:[113.775698, 30.236892]
polygon_coords:封闭多边形,如:[[[113.76708006000003,30.231097985000019],
[113.77808006000006,30.231097985000019],[113.76708006000003,30.231097985000019]]]
is_contains_edge: 是否包含边界,如果为true,那么在边界上时也算在多边形内
"""


def is_point_in_polygon(point_coord, polygon_coords, is_contains_edge):
    intersect_count = 0  # 交点个数
    for polygon in polygon_coords:
        # 循环每条边
        for i in range(len(polygon) - 1):
            origin_point = polygon[i]
            destination_point = polygon[i + 1]

            # 是否包含存在直线上的点
            if is_in_line(point_coord, origin_point, destination_point):
                return True if is_contains_edge else False

            if is_ray_intersects_segment(point_coord, origin_point, destination_point):
                # 有交点就加1
                intersect_count += 1
    return True if intersect_count % 2 == 1 else False


poly = [[
    [2.0, 4.0],
    [2.0, 6.0],
    [4.0, 8.0],
    [6.0, 8.0],
    [8.0, 6.0],
    [8.0, 4.0],
    [6.0, 2.0],
    [4.0, 2.0],
    [2.0, 4.0]
],
    [
        [3.0, 5.0],
        [4.0, 7.0],
        [6.0, 7.0],
        [7.0, 6.0],
        [6.0, 5.0],
        [3.0, 5.0]
    ]
]

poi = [5, 5]

print(is_point_in_polygon(poi, poly, False))