Esempio n. 1
0
def _interp_polygon(polygon, dx):
    """Interpolates an irregular polygon to a regular step dx.

    Interior geometries are also interpolated if they are longer then 3*dx,
    otherwise they are ignored.

    Parameters
    ----------
    polygon: The shapely.geometry.Polygon instance to interpolate
    dx : the step (float)

    Returns
    -------
    an interpolated shapely.geometry.Polygon class instance.
    """

    # remove last (duplex) point to build a LineString from the LinearRing
    line = shpg.LineString(np.asarray(polygon.exterior.xy).T)

    e_line = []
    for distance in np.arange(0.0, line.length, dx):
        e_line.append(*line.interpolate(distance).coords)
    e_line = shpg.LinearRing(e_line)

    i_lines = []
    for ipoly in polygon.interiors:
        line = shpg.LineString(np.asarray(ipoly.xy).T)
        if line.length < 3 * dx:
            continue
        i_points = []
        for distance in np.arange(0.0, line.length, dx):
            i_points.append(*line.interpolate(distance).coords)
        i_lines.append(shpg.LinearRing(i_points))

    return shpg.Polygon(e_line, i_lines)
Esempio n. 2
0
    def test_stitch(self):
        # The following LinearRing wanders in/out of the map domain
        # but importantly the "vertical" lines at 0'E and 360'E are both
        # chopped by the map boundary. This results in their ends being
        # *very* close to each other and confusion over which occurs
        # first when navigating around the boundary.
        # Check that these ends are stitched together to avoid the
        # boundary ordering ambiguity.
        # NB. This kind of polygon often occurs with MPL's contouring.
        coords = [(0.0, -70.70499926182919),
                  (0.0, -71.25),
                  (0.0, -72.5),
                  (0.0, -73.49076371657017),
                  (360.0, -73.49076371657017),
                  (360.0, -72.5),
                  (360.0, -71.25),
                  (360.0, -70.70499926182919),
                  (350, -73),
                  (10, -73)]
        src_proj = ccrs.PlateCarree()
        target_proj = ccrs.Stereographic(80)

        linear_ring = sgeom.LinearRing(coords)
        rings, mlinestr = target_proj.project_geometry(linear_ring, src_proj)
        assert len(mlinestr) == 1
        assert len(rings) == 0

        # Check the stitch works in either direction.
        linear_ring = sgeom.LinearRing(coords[::-1])
        rings, mlinestr = target_proj.project_geometry(linear_ring, src_proj)
        assert len(mlinestr) == 1
        assert len(rings) == 0
Esempio n. 3
0
 def _InsureSinglePolygonCorrectWinding(coords):
   """Modifies in place the coords for correct windings."""
   exterior = coords[0]
   if not sgeo.LinearRing(exterior).is_ccw:
     exterior.reverse()
   for hole in coords[1:]:
     if sgeo.LinearRing(hole).is_ccw:
       hole.reverse()
Esempio n. 4
0
 def _HasSinglePolygonCorrectWinding(coords):
   exterior = coords[0]
   if not sgeo.LinearRing(exterior).is_ccw:
     return False
   for hole in coords[1:]:
     if sgeo.LinearRing(hole).is_ccw:
       return False
   return True
    def setUp(self):

        self.tslr1 = mg.TS_LinearRing(
            sg.LinearRing([(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)]),
            dt.datetime(2017, 07, 25, 20, 0, 0))
        self.tslr2 = mg.TS_LinearRing(
            sg.LinearRing([(3, 1), (4, 1), (4, 2), (3, 2), (3, 1)]),
            dt.datetime(2017, 07, 25, 20, 0, 10))

        self.t1 = dt.datetime(2017, 07, 25, 20, 0, 5)
    def test_create_diff_dict(self):

        lr = sg.LinearRing([(1.5, 1.5), (2, 1), (2, 2), (1, 2), (1, 1),
                            (1.5, 1.5)])
        lr_convex = sg.LinearRing(lr.convex_hull.exterior.coords[::-1])

        lr_seg = I_Helper.curve_segments(lr)
        lr_convex_seg = I_Helper.curve_segments(lr_convex)

        d_dict = I_Helper.create_diff_dict(lr_convex_seg, lr_seg)
        self.assertEqual(d_dict, {0: [(1.0, 1.0), (1.5, 1.5), (2.0, 1.0)]})
Esempio n. 7
0
    def _calculate_geometry(self, exterior):

        inside_direction = _get_inside_direction(exterior)

        interior = exterior.parallel_offset(self.thickness,
                                            side=inside_direction)

        if interior.type == 'MultiLineString':
            interior = shpl_geom.LinearRing(interior.geoms[0])
        else:
            interior = shpl_geom.LinearRing(interior)

        geometry = shpl_geom.Polygon(exterior) - shpl_geom.Polygon(interior)

        return interior, geometry
Esempio n. 8
0
    def _calculate_geometry(self, exterior):

        limited_box = shpl_geom.box(self._limits[0], exterior.bounds[1] * 1.1,
                                    self._limits[1], exterior.bounds[3] * 1.1)

        intersection = limited_box.intersection(exterior)

        side = _get_inside_direction(exterior)

        tmp_geometries = []

        tmp_interior = shpl_geom.Polygon(exterior)

        for ageo in intersection.geoms:
            tmp_geometry = _create_offset_box(ageo,
                                              self.thickness,
                                              side,
                                              symmetric=False)
            tmp_interior -= tmp_geometry
            tmp_geometries.append(tmp_geometry)

        geometry = shpl_geom.GeometryCollection(tmp_geometries)

        interior = shpl_geom.LinearRing(tmp_interior.exterior)

        return _refine_interior(interior), geometry
Esempio n. 9
0
	def snap_geom(self, gdf, geom1, geom2, index1, index2, tolerance):
		if isinstance(geom1, geom.Polygon) and isinstance(geom2, geom.Polygon):
			vertices1 = geom1.exterior.coords[:]
			vertices2 = geom2.exterior.coords[:]
			for i in range(0, len(vertices1)):
				vertex1 = vertices1[i]
				closest_vertex, vertex_index = self.get_closest_vertex(vertex1, vertices2, tolerance)
				
				if i not in self.snapped_vertices[str(index1)] and closest_vertex != None:
					self.snapped_vertices[str(index1)].append(i)
					# if code_entite in ['NRO_08_003_044', 'NRO_08_003_157']:
					# 	print "vertex ", vertex1, " at index ", i, " with closest vertex ", closest_vertex
					vertices1[i] = closest_vertex
				elif geom.Point(vertex1).distance(geom2) <= tolerance:
					self.snapped_vertices[str(index1)].append(i)
					linear_ring = geom.LinearRing(geom2.exterior.coords)
					
					geom2, vertex_added_at = self.insert_vertex_at(geom2, vertex1, nearest_points(geom.Point(vertex1), linear_ring)[1].coords[0])
					# if vertex_added_at > vertex_index +1:
					# 	print "different indices : get_closest_vertex index = ", vertex_index, " / insert_at index = ", vertex_added_at
					# elif vertex_added_at == vertex_index + 1:
					# 	print "same indices = ", vertex_added_at
					# else:
					# 	print "WTF case !"
					gdf.loc[index2, 'geometry'] = geom2
					self.snapped_vertices[str(index1)].append(vertex_added_at)
					
			return geom.Polygon(vertices1)	
Esempio n. 10
0
def _get_patterns(node):
    from .elements import EmbroideryElement
    from .elements.stroke import Stroke

    fills = []
    strokes = []
    xpath = "./parent::svg:g/*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
    patterns = node.xpath(xpath, namespaces=inkex.NSS)
    for pattern in patterns:
        if pattern.tag not in EMBROIDERABLE_TAGS:
            continue

        element = EmbroideryElement(pattern)
        fill = element.get_style('fill')
        stroke = element.get_style('stroke')

        if fill is not None:
            fill_pattern = Stroke(pattern).paths
            linear_rings = [shgeo.LinearRing(path) for path in fill_pattern]
            for ring in linear_rings:
                fills.append(shgeo.Polygon(ring))

        if stroke is not None:
            stroke_pattern = Stroke(pattern).paths
            line_strings = [shgeo.LineString(path) for path in stroke_pattern]
            strokes.append(shgeo.MultiLineString(line_strings))

    return {'fill_patterns': fills, 'stroke_patterns': strokes}
Esempio n. 11
0
 def joined_outer_ring(self):
     outer_ring = []  #2d array of geoms
     # TODO: Prune overlapping points when appending a ring section
     # or: add shapely for combining geometries
     for w in self.outer_ways():
         inserted = False
         new_segment = w.way.linestring
         if len(new_segment) == 0:
             continue
         for index in range(len(outer_ring)):
             linestring = outer_ring[index]
             if linestring[-1] == new_segment[0]:
                 outer_ring.insert(index + 1, new_segment)
                 inserted = True
             elif new_segment[-1] == linestring[0]:
                 outer_ring.insert(index, new_segment)
                 inserted = True
         if not inserted:
             outer_ring.append(new_segment)
     merged = linemerge(
         [shapely.LineString(segment) for segment in outer_ring])
     if merged.is_closed and merged.is_valid:
         return shapely.LinearRing(merged)
     else:
         # IPython.embed()
         # could be multipolygon with 2 non-touching outer rings
         # TODO: Split those
         print('found rel with multiple closed outer rings: %d' % self.id)
         return None
Esempio n. 12
0
def _create_geometry(default_range, num_points):
    if random.choice((True, False)):
        if not explore_queue.empty():
            try:
                return explore_queue.get(block=False)
            except:
                pass

    start_point = geometry.Point(random.uniform(-180, 180),
                                 random.uniform(-90, 90))
    tries = 1
    while geometry_collection.intersects(start_point):
        tries += 1
        start_point = geometry.Point(random.uniform(-180, 180),
                                     random.uniform(-90, 90))
    logger.debug('took %s tries to generate geo', tries)
    points = [start_point]
    for i in range(num_points - 1):
        new_x = start_point.x + random.uniform(*default_range)
        if new_x > 180:
            new_x = new_x % 180 + (-180)
        new_y = start_point.y + random.uniform(*default_range)
        if new_y > 90:
            new_y = new_y % 90 + (-90)
        points.append(geometry.Point(new_x, new_y))
    return geometry.Polygon(
        geometry.LinearRing(
            tuple(map(lambda x: (x.x, x.y), (*points, points[0])))))
Esempio n. 13
0
def get_external_contour(points, resolution=None):
    """ takes a list of `points` defining a linear ring, which can be 
    self-intersecting, and returns an approximation to the external contour """
    if resolution is None:
        # determine resolution from minimal distance of consecutive points
        dist_min = np.inf
        for p1, p2 in itertools.izip(np.roll(points, 1, axis=0), points):
            dist = curves.point_distance(p1, p2)
            if dist > 0:
                dist_min = min(dist_min, dist)
        resolution = 0.5 * dist_min

        # limit the resolution such that there are at most 2048 points
        dim_max = np.max(np.ptp(points, axis=0))  #< longest dimension
        resolution = max(resolution, dim_max / 2048)

    # build a linear ring with integer coordinates
    ps_int = np.array(np.asarray(points) / resolution, np.int)
    ring = geometry.LinearRing(ps_int)

    # get the image of the linear ring by plotting it into a mask
    x_min, y_min, x_max, y_max = ring.bounds
    shape = ((y_max - y_min) + 3, (x_max - x_min) + 3)
    x_off, y_off = int(x_min - 1), int(y_min - 1)
    mask = np.zeros(shape, np.uint8)
    cv2.fillPoly(mask, [ps_int], 255, offset=(-x_off, -y_off))

    # find the contour of this mask to recover the exterior contour
    contours = cv2.findContours(mask,
                                cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE,
                                offset=(x_off, y_off))[1]
    return np.array(np.squeeze(contours)) * resolution
Esempio n. 14
0
def _write_boat_area(pier, stg_manager, coords_transform: co.Transformation):
    if len(pier.nodes) < 3:
        return
    # Guess a possible position for realistic boat placement
    linear_ring = shg.LinearRing(pier.nodes)
    centroid = linear_ring.centroid
    # Simplify
    ring = linear_ring.convex_hull.buffer(
        40, cap_style=CAP_STYLE.square,
        join_style=JOIN_STYLE.bevel).simplify(20)
    for p in ring.exterior.coords:
        line_coords = [[centroid.x, centroid.y], p]
        target_vector = shg.LineString(line_coords)
        coords = linear_ring.coords
        for i in range(len(coords) - 1):
            segment = LineString(coords[i:i + 2])
            if segment.length > 20 and segment.intersects(target_vector):
                direction = math.degrees(
                    math.atan2(segment.coords[0][0] - segment.coords[1][0],
                               segment.coords[0][1] - segment.coords[1][1]))
                parallel = segment.parallel_offset(10, 'right')
                boat_position = parallel.interpolate(segment.length / 2)
                try:
                    pos_global = coords_transform.to_global(
                        (boat_position.x, boat_position.y))
                    _write_model(segment.length, stg_manager, pos_global,
                                 direction, pier.elevation)
                except AttributeError as reason:
                    logging.error(reason)
Esempio n. 15
0
    def test_cuts(self):
        # Check that fragments do not start or end with one of the
        # original ... ?
        linear_ring = sgeom.LinearRing([(-10, 30), (10, 60), (10, 50)])
        projection = ccrs.Robinson(170.5)
        rings, multi_line_string = projection.project_geometry(linear_ring)

        # The original ring should have been split into multiple pieces.
        assert len(multi_line_string) > 1
        assert not rings

        def assert_intersection_with_boundary(segment_coords):
            # Double the length of the segment.
            start = segment_coords[0]
            end = segment_coords[1]
            end = [end[i] + 2 * (end[i] - start[i]) for i in (0, 1)]
            extended_segment = sgeom.LineString([start, end])
            # And see if it crosses the boundary.
            intersection = extended_segment.intersection(projection.boundary)
            assert not intersection.is_empty, 'Bad topology near boundary'

        # Each line resulting from the split should start and end with a
        # segment that crosses the boundary when extended to double length.
        # (This is important when considering polygon rings which need to be
        # attached to the boundary.)
        for line_string in multi_line_string:
            coords = list(line_string.coords)
            assert len(coords) >= 2
            assert_intersection_with_boundary(coords[1::-1])
            assert_intersection_with_boundary(coords[-2:])
Esempio n. 16
0
    def test_at_boundary(self):
        # Check that a polygon is split and recombined correctly
        # as a result of being on the boundary, determined by tolerance.

        exterior = np.array(
            [[177.5, -79.912],
             [178.333, -79.946],
             [181.666, -83.494],
             [180.833, -83.570],
             [180., -83.620],
             [178.438, -83.333],
             [178.333, -83.312],
             [177.956, -83.888],
             [180., -84.086],
             [180.833, -84.318],
             [183., -86.],
             [183., -78.],
             [177.5, -79.912]])
        tring = sgeom.LinearRing(exterior)

        tcrs = ccrs.PlateCarree()
        scrs = ccrs.PlateCarree()

        rings, mlinestr = tcrs._project_linear_ring(tring, scrs)

        # Number of linearstrings
        assert len(mlinestr) == 4
        assert not rings

        # Test area of smallest Polygon that contains all the points in the
        # geometry.
        assert round(abs(mlinestr.convex_hull.area - 2347.75623076), 7) == 0
Esempio n. 17
0
    def test_out_of_bounds(self):
        # Check that a ring that is completely out of the map boundary
        # produces an empty result.
        # XXX Check efficiency?
        projection = ccrs.TransverseMercator(central_longitude=0, approx=True)

        rings = [
            # All valid
            ([(86, 1), (86, -1), (88, -1), (88, 1)], -1),
            # One NaN
            ([(86, 1), (86, -1), (130, -1), (88, 1)], 1),
            # A NaN segment
            ([(86, 1), (86, -1), (130, -1), (130, 1)], 1),
            # All NaN
            ([(120, 1), (120, -1), (130, -1), (130, 1)], 0),
        ]

        # Try all four combinations of valid/NaN vs valid/NaN.
        for coords, expected_n_lines in rings:
            linear_ring = sgeom.LinearRing(coords)
            rings, mlinestr = projection.project_geometry(linear_ring)
            if expected_n_lines == -1:
                assert rings
                assert not mlinestr
            else:
                assert len(mlinestr) == expected_n_lines
                if expected_n_lines == 0:
                    assert mlinestr.is_empty
Esempio n. 18
0
    def test_basic_linear(self):

        ts_lr1 = mg.TS_LinearRing(
            sg.LinearRing([(1, 0.5), (2.25, 0.75), (1.5, 1.25), (1.75, 1.75),
                           (1.25, 2.25), (0.5, 1.75), (0.5, 1.0), (1, 0.5)]),
            dt.datetime(2017, 07, 25, 20, 0, 0))
        ts_lr2 = mg.TS_LinearRing(
            sg.LinearRing([(3.0, 0.5), (4.5, 0.5), (3.75, 2.25), (3.0, 0.5)]),
            dt.datetime(2017, 07, 25, 20, 0, 20))

        ts_lr3 = mg.TS_LinearRing(
            sg.LinearRing([(1, 1), (1.25, 1.75), (1.5, 1.75), (1.5, 1.25),
                           (2, 1), (2, 2), (1.75, 1.75), (1, 2), (1, 1)]),
            dt.datetime(2017, 07, 25, 20, 0, 0))
        ts_lr4 = mg.TS_LinearRing(
            sg.LinearRing([(4.5, 1.5), (4, 2), (3.5, 1.5), (3.5, 0.5),
                           (3.75, 1.25), (4, 1.25), (4, 1), (4.5, 1),
                           (4.25, 1.25), (4.5, 1.5)]),
            dt.datetime(2017, 07, 25, 20, 0, 20))

        self.assertEqual(
            IRing.basic_linear(ts_lr1, ts_lr2,
                               dt.datetime(2017, 07, 25, 20, 0,
                                           10)).value.coords[:],
            [(3.375, 0.625), (2.8440513845721638, 1.2388801026649512),
             (2.872336158951433, 1.7145489624466568), (2.5, 2.25),
             (1.9816795819387427, 1.6655856911903992),
             (1.8624297859062504, 1.0123361671145843), (2.0, 0.5),
             (3.375, 0.625)])

        self.assertEqual(
            IRing.basic_linear(ts_lr3, ts_lr4,
                               dt.datetime(2017, 07, 25, 20, 0,
                                           10)).value.coords[:],
            [(3.25, 1.0), (3.125, 1.625), (3.125, 1.625), (2.5, 2.0),
             (2.25, 1.5428932188134525), (2.25, 0.75), (2.5, 1.5), (2.75, 1.5),
             (2.75, 1.125), (3.25, 1.0)])

        self.assertEqual(
            IRing.basic_linear(ts_lr1, ts_lr2,
                               dt.datetime(2017, 07, 25, 20, 0, 10),
                               "distance").value.coords[:],
            [(3.375, 0.625), (2.8440513845721638, 1.2388801026649512),
             (2.872336158951433, 1.7145489624466568), (2.5, 2.25),
             (1.9816795819387427, 1.6655856911903992),
             (1.8624297859062504, 1.0123361671145843), (2.0, 0.5),
             (3.375, 0.625)])
Esempio n. 19
0
    def build_shapely_geometry(self) -> BaseGeometry:
        """
        Builds the internal shapely representation of the geometry.  This is used by other base class methods
        to build the other output types.

        :return: A shapely geometry specific to the derived type.
        :rtype: :py:class:`BaseGeometry`
        """
        # Get the UTMSRID so we can transform the center point to a coordinate system where distance is
        # measured in meters.
        utmsrid: int = getutmsrid(self.longitude, self.latitude, self.sr_id)
        # Create the OGR Point
        center: ogr.Geometry = ogr.Geometry(ogr.wkbPoint)
        center.AssignSpatialReference(Geodetic2D.get_ogr_sr(self.sr_id))
        center.AddPoint(self.longitude, self.latitude)
        # Project the point from its native projection to the UTM system.
        center = reproject_geom(center, self.sr_id, utmsrid)

        # adjust for the fact that we're not doing standard geometry - back up 90 degress
        # to start from north.
        start_angle: float = 90 - self.start_angle
        # find the end angle, which is the sweep relative to the start angle going clockwise so we subtract.
        end_angle: float = start_angle - self.opening_angle

        # plot a line for the outer arc.
        outer_arc_x, outer_arc_y = \
            calculate_arc(center.GetX(), center.GetY(), self.outer_radius, start_angle, end_angle)

        # plot a line for the inner arc.
        inner_arc_x, inner_arc_y = \
            calculate_arc(center.GetX(), center.GetY(), self.inner_radius, start_angle, end_angle)

        # reverse the inner arc to set is up to be welded to the outer arc into a polygon.
        inner_arc_x = np.flip(inner_arc_x, 0)
        inner_arc_y = np.flip(inner_arc_y, 0)

        # glue the arcs together
        band_x = np.append(outer_arc_x, inner_arc_x)
        band_y = np.append(outer_arc_y, inner_arc_y)

        # complete the ring by adding taking the first point and adding it again at the end.
        first_x = band_x[0]
        first_y = band_y[0]
        band_x = np.append(band_x, first_x)
        band_y = np.append(band_y, first_y)

        # smash the x and y arrays together to get coordinate pairs.
        ring_coordinates = np.column_stack([band_x, band_y])

        # Build the shapely linear ring . . .
        line_string: shp_geom.LinearRing = shp_geom.LinearRing(ring_coordinates)
        # so we can build a shapely polygon . . .
        arc_band_polygon: shp_geom.Polygon = shp_geom.Polygon(line_string)
        # so we can create the OGR geometry . . .
        arcband: ogr.Geometry = ogr.CreateGeometryFromWkb(arc_band_polygon.wkb)
        # so we can reproject back to the original coordinate system
        arcband = reproject_geom(arcband, utmsrid, self._spatial_ref_id)
        # so we can build and return a shapely geometry.  (Whew!)
        return loads(arcband.ExportToWkt())
Esempio n. 20
0
    def test_curve_segments(self):

        lr = sg.LinearRing([(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)])
        lr_seg = I_Helper.curve_segments(lr)

        self.assertEqual(lr_seg,
                         [[(1.0, 1.0), (2.0, 1.0)], [(2.0, 1.0), (2.0, 2.0)],
                          [(2.0, 2.0), (1.0, 2.0)], [(1.0, 2.0), (1.0, 1.0)]])
 def test_degenerate_shapes(self):
     # Test all degenerate shapes (points, lines) have area zero
     points = sgeo.MultiPoint([(4, 59), (6, 59), (6, 61), (4, 61)])
     line = sgeo.LineString([(4, 59), (6, 59), (6, 61), (4, 61)])
     ring = sgeo.LinearRing([(4, 59), (6, 59), (6, 61), (4, 61)])
     self.assertEqual(utils.GeometryArea(points), 0)
     self.assertEqual(utils.GeometryArea(line), 0)
     self.assertEqual(utils.GeometryArea(ring), 0)
Esempio n. 22
0
def _create_dummy_shp(fname):
    if not os.path.exists(testdir):
        os.makedirs(testdir)

    e_line = shpg.LinearRing([(1.5, 1), (2., 1.5), (1.5, 2.), (1, 1.5)])
    i_line = shpg.LinearRing([(1.4, 1.4), (1.6, 1.4), (1.6, 1.6), (1.4, 1.6)])
    p1 = shpg.Polygon(e_line, [i_line])
    p2 = shpg.Polygon([(2.5, 1.3), (3., 1.8), (2.5, 2.3), (2, 1.8)])
    p3 = shpg.Point(0.5, 0.5)
    p4 = shpg.Point(1, 1)
    df = gpd.GeoDataFrame()
    df['name'] = ['Polygon', 'Line']
    df['geometry'] = gpd.GeoSeries([p1, p2])
    of = os.path.join(testdir, fname)
    df.crs = 'epsg:4326'
    df.to_file(of)
    return of
    def shift_polygons(self, shift=(0, 0)):
        """
        Returns the polygons shifted by the given values.

        Parameters
        ----------
        shift : list or tuple
            The [X, Y] shift to be added to the coordinates.

        Returns
        -------
        polygons : List of polygons
            Polygons shifted by the given values
        """
        polygons = []
        if type(self.shape) is geometry.multipolygon.MultiPolygon:
            for geom in self.shape.geoms:
                ext_coords = np.array(geom.exterior)
                ext_coords += shift
                if len(geom.interiors) > 0:
                    int_rings = []
                    for i in geom.interiors:
                        int_coords = np.array(i)
                        int_coords += shift
                        int_rings.append(geometry.LinearRing(int_coords))
                    poly = geometry.Polygon(ext_coords, int_rings)
                else:
                    poly = geometry.Polygon(ext_coords)
                polygons.append(poly)
        elif type(self.shape) is geometry.polygon.Polygon:
            ext_coords = np.array(self.shape.exterior)
            ext_coords += shift
            if len(self.shape.interiors) > 0:
                int_rings = []
                for i in self.shape.interiors:
                    int_coords = np.array(i)
                    int_coords += shift
                    int_rings.append(geometry.LinearRing(int_coords))
                poly = geometry.Polygon(ext_coords, int_rings)
            else:
                poly = geometry.Polygon(ext_coords)
            polygons.append(poly)
        else:
            raise TypeError('Shape not the correct type.')

        return polygons
Esempio n. 24
0
 def get_shape(self):
     ls = geom.LinearRing((
         (self.a[0], self.a[1]),
         (self.a[0], self.b[1]),
         (self.b[0], self.b[1]),
         (self.b[0], self.a[1]),
     ))
     return ls
Esempio n. 25
0
def create_dummy_shp(fname):

    import shapely.geometry as shpg
    import geopandas as gpd

    e_line = shpg.LinearRing([(1.5, 1), (2., 1.5), (1.5, 2.), (1, 1.5)])
    i_line = shpg.LinearRing([(1.4, 1.4), (1.6, 1.4), (1.6, 1.6), (1.4, 1.6)])
    p1 = shpg.Polygon(e_line, [i_line])
    p2 = shpg.Polygon([(2.5, 1.3), (3., 1.8), (2.5, 2.3), (2, 1.8)])
    p3 = shpg.Point(0.5, 0.5)
    p4 = shpg.Point(1, 1)
    df = gpd.GeoDataFrame()
    df['name'] = ['Polygon', 'Line']
    df['geometry'] = gpd.GeoSeries([p1, p2])
    of = os.path.join(testdir, fname)
    df.to_file(of)
    return of
Esempio n. 26
0
def regularize_linear_ring(linear_ring):
    """ regularize a list of points defining a contour """
    polygon = geometry.Polygon(linear_ring)
    regular_polygon = regularize_polygon(polygon)
    if regular_polygon.is_empty:
        return geometry.LinearRing()  #< empty linear ring
    else:
        return regular_polygon.exterior
Esempio n. 27
0
def generate_target_polygon(min_area=10, max_edge=6, max_size=50):
    edges = random.randint(3, max_edge)
    size = max_size
    # edges = 3
    logger.info("Generating polygon with {} edges".format(edges))
    while True:
        tuple_list = array_to_tuples(
            np.reshape([random.uniform(-size, size) for x in range(6)],
                       (3, 2)).astype(np.float32))
        shots = 0
        while len(tuple_list) < edges:
            shots += 1
            if shots > 100:
                tuple_list = array_to_tuples(
                    np.reshape([random.uniform(-size, size) for x in range(6)],
                               (3, 2)).astype(np.float32))
                shots = 0
            tuple_list_buffer = tuple_list.copy()
            tuple_list_buffer.insert(
                random.randint(0, len(tuple_list)),
                (random.uniform(-size, size), random.uniform(-size, size)))
            linear_ring = geometry.LinearRing(tuple(tuple_list_buffer))
            if linear_ring.is_simple:
                pointy = 90
                for s_ in range(len(tuple_list_buffer)):
                    arr = tuples_to_array(tuple_list_buffer)
                    logger.debug("{}; {}".format(arr[s_] - arr[s_ - 1],
                                                 arr[s_ - 1] - arr[s_ - 2]))

                    angle_ = np.abs(
                        py_ang(arr[s_] - arr[s_ - 1],
                               arr[s_ - 1] - arr[s_ - 2]))
                    angle_ = 90 - np.abs(angle_ - 90)
                    pointy = min(angle_, pointy)
                    logger.debug(angle_)
                if pointy > 15.0:
                    logger.debug("not pointy")
                    tuple_list = tuple_list_buffer.copy()

                logger.debug("simple")

            else:
                logger.debug("NOT simple")

        if get_spin(tuple_list) < 0:
            logger.info("REVERSE LIST")
            tuple_list.reverse()
        polygon_points = tuple_list
        logger.info("polygon_points: {}".format(polygon_points))
        polygon_obj = geometry.Polygon(polygon_points)
        point_array = np.array(
            [polygon_obj.exterior.xy[0][:-1],
             polygon_obj.exterior.xy[1][:-1]]).transpose()

        if polygon_obj.area >= min_area:
            logger.debug("area: {}".format(polygon_obj.area))
            break
    return point_array
Esempio n. 28
0
    def from_system(cls, system):
        """Convert a `System` instance to a `Polygons` instance.

        Parameters
        ----------
        system : System

        Returns
        -------
        Polygons
        """
        obj = cls()
        for e in system:
            if not hasattr(e, "paths"):
                continue
            # assert isinstance(e, PolygonPixelElectrode), (e, e.name)
            exts, ints = [], []
            for pi in e.paths:
                # shapely ignores f-contiguous arrays so copy
                # https://github.com/sgillies/shapely/issues/26
                ei = area_centroid(pi)[0]
                pi = geometry.LinearRing(pi.copy("C"))
                if ei < 0:
                    ints.append((abs(ei), pi))
                elif ei > 0:
                    exts.append((abs(ei), pi))
            if not exts:
                continue
            ints.sort(key=operator.itemgetter(0))
            exts.sort(key=operator.itemgetter(0))
            # the following needs to be complicated to cover
            # onion-like "ext in int in ext" cases.
            groups = []
            done = set()
            for exta, exterior in exts:
                ep = geometry.Polygon(exterior)
                gint = []
                for i, (inta, interior) in enumerate(ints):
                    if i in done:
                        continue
                    if inta >= exta:
                        break
                    if ep.contains(interior):
                        gint.append(interior)
                        done.add(i)
                pi = geometry.Polygon(exterior, gint)
                if pi.is_valid and pi.area > 0:
                    groups.append(pi)
                else:
                    logger.warn("polygon %s failed %s/%s", e.name, pi.is_valid,
                                pi.area)
            # remaining interiors must be top level or "free"
            #assert not ints, ints
            #mp = geometry.MultiPolygon(groups)
            #mp = mp.union(geometry.Point())
            mp = ops.unary_union(groups)
            obj.append((e.name, mp))
        return obj
Esempio n. 29
0
def polygon_polygon_touch(poly1, poly2):
    """
    :param poly1:
    :param poly2:
    :return: boolean
    """
    p1 = sg.LinearRing(poly1)
    p2 = sg.LinearRing(poly2)
    inter = p1.intersection(p2)

    if inter.type == 'LineString':
        return np.array(inter)
    elif inter.type == 'MultiLineString':
        ar = []
        for line in inter:
            ar += list(zip(line.xy[0], line.xy[1]))
        return np.array(ar)
    return np.zeros(0)
Esempio n. 30
0
def nearest_culture_point(cm):
    '''
    return the coordinates of nearest point in the boundary of the culture
    '''    
    cult = sg.LinearRing(sg.Point([0.,0.]).buffer(1000.).exterior.coords)
    min_d = cult.project(sg.Point(cm))
    ret = cult.interpolate(min_d)
    
    return list(ret.coords)[0]