def is_multipoint_on_linestring(feature_1: Sequence, feature_2: Sequence) -> bool: """ Checks if feature_1 multipoint feature is in feature_2 polygon returns False, if all multipoints are on the boundary :param feature_1: Coordinates of multipoint feature :param feature_2: Coordinates of polygon feature 2 :return: boolean True/False if feature 1 is within feature 2 """ points_on_line = False points_on_line = all( boolean_point_on_line(coords_1, feature_2[1]) for coords_1 in feature_1[1]) if not points_on_line: return points_on_line points_on_line = any( boolean_point_on_line(coords_1, feature_2[1], {"ignoreEndVertices": True}) for coords_1 in feature_1[1]) return points_on_line
def disjoint(feature_1: List[Union[str, Sequence]], feature_2: List[Union[str, Sequence]]) -> bool: """ Returns true if the intersection of the two geometries is an empty set. :param feature_1: {List} a List with geometry type and coordinates :param feature_2: {List} a List with geometry type and coordinates :return: boolean True/False if features are disjoint """ is_disjoint = True if feature_1[0] in ["Point"]: if feature_2[0] in ["Point"]: is_disjoint = feature_1[1] != feature_2[1] elif feature_2[0] in ["LineString"]: is_disjoint = not boolean_point_on_line(feature_1[1], feature_2[1]) elif feature_2[0] in ["Polygon"]: is_disjoint = not boolean_point_in_polygon(feature_1[1], feature_2[1]) elif feature_1[0] in ["LineString"]: if feature_2[0] in ["Point"]: is_disjoint = not boolean_point_on_line(feature_2[1], feature_1[1]) elif feature_2[0] in ["LineString"]: is_disjoint = not is_line_on_line(feature_1[1], feature_2[1]) elif feature_2[0] in ["Polygon"]: is_disjoint = not is_line_in_poly(feature_2[1], feature_1[1]) elif feature_1[0] in ["Polygon"]: if feature_2[0] in ["Point"]: is_disjoint = not boolean_point_in_polygon(feature_2[1], feature_1[1]) elif feature_2[0] in ["LineString"]: is_disjoint = not is_line_in_poly(feature_1[1], feature_2[1]) elif feature_2[0] in ["Polygon"]: is_disjoint = not is_poly_in_poly(feature_2[1], feature_1[1]) return is_disjoint
def test_boolean_point_on_line(self, fixture): if "true" in fixture: features = fixture.get("true") point, line = features["features"] options = features.get("properties", {}) expected_result = True else: features = fixture.get("false") point, line = features["features"] options = features.get("properties", {}) expected_result = False test_result = boolean_point_on_line(point, line, options) assert test_result == expected_result
def is_line_on_line(feature_1: Sequence, feature_2: Sequence) -> bool: """ Checks if feature_1 linestring feature is in feature_2 linestring :param feature_1: Coordinates of linestring feature 1 :param feature_2: Coordinates of linestring feature 2 :return: boolean True/False if feature 1 is within feature 2 """ line_on_line = False for coords in feature_1: line_on_line = boolean_point_on_line(coords, feature_2) if not line_on_line: break return line_on_line
def check_within(feature_1: List[Union[str, Sequence]], feature_2: List[Union[str, Sequence]]) -> bool: """ Returns true if the first geometry is completely within the second geometry :param feature_1: {List} a List with geometry type and coordinates :param feature_2: {List} a List with geometry type and coordinates :return: boolean True/False if feature 1 is within feature 2 """ is_within = False if feature_1[0] in ["Point"]: if feature_2[0] in ["Point", "MultiPoint"]: is_within = boolean_point_on_point(feature_1[1], feature_2[1]) elif feature_2[0] in ["LineString", "MultiLineString"]: is_within = boolean_point_on_line(feature_1[1], feature_2[1], {"ignoreEndVertices": True}) elif feature_2[0] in ["Polygon", "MultiPolygon"]: is_within = boolean_point_in_polygon(feature_1[1], feature_2[1], {"ignoreBoundary": True}) if feature_1[0] in ["MultiPoint"]: if feature_2[0] in ["MultiPoint"]: is_within = all( boolean_point_on_point(coords_1, feature_2[1]) for coords_1 in feature_1[1]) elif feature_2[0] in ["LineString", "MultiLineString"]: is_within = is_multipoint_on_linestring(feature_1, feature_2) elif feature_2[0] in ["Polygon", "MultiPolygon"]: is_within = is_multipoint_on_polygon(feature_1, feature_2) elif feature_1[0] in ["LineString"]: if feature_2[0] in ["LineString"]: is_within = is_line_on_line(feature_1[1], feature_2[1]) if feature_2[0] in ["MultiLineString"]: is_within = is_line_on_multiline(feature_1[1], feature_2[1]) elif feature_2[0] in ["Polygon"]: is_within = is_line_in_poly(feature_1[1], feature_2[1]) elif feature_2[0] in ["MultiPolygon"]: is_within = is_line_in_multipoly(feature_1[1], feature_2[1]) elif feature_1[0] in ["MultiLineString"]: if feature_2[0] in ["MultiLineString"]: is_within = all( is_line_on_multiline(coords_1, feature_2[1]) for coords_1 in feature_1[1]) elif feature_2[0] in ["Polygon", "MultiPolygon"]: is_within = all( is_line_in_poly(coords_1, feature_2[1]) for coords_1 in feature_1[1]) elif feature_1[0] in ["Polygon"]: if feature_2[0] in ["Polygon"]: is_within = is_poly_in_poly(feature_1[1], feature_2[1]) if feature_2[0] in ["MultiPolygon"]: is_within = is_poly_in_multipoly(feature_1[1], feature_2[1]) elif feature_1[0] in ["MultiPolygon"]: if feature_2[0] in ["MultiPolygon"]: is_within = all( is_poly_in_multipoly(coords_1, feature_2[1]) for coords_1 in feature_1[1]) return is_within
def point_on_feature(features: GeoJSON) -> Point: """ Takes a Feature or FeatureCollection and returns a {Point} guaranteed to be on the surface of the feature. Given a {Polygon}, the point will be in the area of the polygon Given a {LineString}, the point will be along the string Given a {Point}, the point will the same as the input :param features: any GeoJSON feature or feature collection :return: Point GeoJSON Feature on the surface of `input` """ feature_collection = normalize_to_feature_collection(features) center_point = center(feature_collection) center_coords = center_point.get("geometry").get("coordinates") # check to see if centroid is on surface center_on_surface = False geometry_type = get_geometry_type(feature_collection) geometry_coords = get_coords_from_features(feature_collection) if isinstance(geometry_type, str): geometry_type = [geometry_type] for geo_type, geo_coords in zip(geometry_type, geometry_coords): if geo_type in ["Point", "MultiPoint"]: if geo_type == "Point": geo_coords = [geo_coords] for point_coords in geo_coords: if (center_coords[0] == point_coords[0]) and (center_coords[1] == point_coords[1]): center_on_surface = True break elif geo_type in ["LineString", "MultiLineString"]: if geo_type == "LineString": geo_coords = [geo_coords] for line_coords in geo_coords: if boolean_point_on_line(center_coords, line_coords): center_on_surface = True break elif geo_type in ["Polygon", "MultiPolygon"]: if geo_type == "Polygon": geo_coords = polygon(geo_coords) else: geo_coords = multi_polygon(geo_coords) if boolean_point_in_polygon(center_point, geo_coords): center_on_surface = True break if center_on_surface: point_on_surface = center_point else: point_on_surface = nearest_point(center_point, feature_collection) return point_on_surface