def test_linestring(self): # From coordinate tuples line = LineString(((1.0, 2.0), (3.0, 4.0))) self.assertEqual(len(line.coords), 2) self.assertEqual(line.coords[:], [(1.0, 2.0), (3.0, 4.0)]) # From Points line2 = LineString((Point(1.0, 2.0), Point(3.0, 4.0))) self.assertEqual(len(line2.coords), 2) self.assertEqual(line2.coords[:], [(1.0, 2.0), (3.0, 4.0)]) # From mix of tuples and Points line3 = LineString((Point(1.0, 2.0), (2.0, 3.0), Point(3.0, 4.0))) self.assertEqual(len(line3.coords), 3) self.assertEqual(line3.coords[:], [(1.0, 2.0), (2.0, 3.0), (3.0, 4.0)]) # From lines copy = LineString(line) self.assertEqual(len(copy.coords), 2) self.assertEqual(copy.coords[:], [(1.0, 2.0), (3.0, 4.0)]) # Bounds self.assertEqual(line.bounds, (1.0, 2.0, 3.0, 4.0)) # Coordinate access self.assertEqual(tuple(line.coords), ((1.0, 2.0), (3.0, 4.0))) self.assertEqual(line.coords[0], (1.0, 2.0)) self.assertEqual(line.coords[1], (3.0, 4.0)) with self.assertRaises(IndexError): line.coords[2] # index out of range # Geo interface self.assertEqual(line.__geo_interface__, { 'type': 'LineString', 'coordinates': ((1.0, 2.0), (3.0, 4.0)) }) # Coordinate modification line.coords = ((-1.0, -1.0), (1.0, 1.0)) self.assertEqual(line.__geo_interface__, { 'type': 'LineString', 'coordinates': ((-1.0, -1.0), (1.0, 1.0)) }) # Adapt a coordinate list to a line string coords = [[5.0, 6.0], [7.0, 8.0]] la = asLineString(coords) self.assertEqual(la.coords[:], [(5.0, 6.0), (7.0, 8.0)]) # Test Non-operability of Null geometry l_null = LineString() self.assertEqual(l_null.wkt, 'GEOMETRYCOLLECTION EMPTY') self.assertEqual(l_null.length, 0.0) # Check that we can set coordinates of a null geometry l_null.coords = [(0, 0), (1, 1)] self.assertAlmostEqual(l_null.length, 1.4142135623730951)
def test_linestring(self): # From coordinate tuples line = LineString(((1.0, 2.0), (3.0, 4.0))) self.assertEqual(len(line.coords), 2) self.assertEqual(line.coords[:], [(1.0, 2.0), (3.0, 4.0)]) # From Points line2 = LineString((Point(1.0, 2.0), Point(3.0, 4.0))) self.assertEqual(len(line2.coords), 2) self.assertEqual(line2.coords[:], [(1.0, 2.0), (3.0, 4.0)]) # From mix of tuples and Points line3 = LineString((Point(1.0, 2.0), (2.0, 3.0), Point(3.0, 4.0))) self.assertEqual(len(line3.coords), 3) self.assertEqual(line3.coords[:], [(1.0, 2.0), (2.0, 3.0), (3.0, 4.0)]) # Bounds self.assertEqual(line.bounds, (1.0, 2.0, 3.0, 4.0)) # Coordinate access self.assertEqual(tuple(line.coords), ((1.0, 2.0), (3.0, 4.0))) self.assertEqual(line.coords[0], (1.0, 2.0)) self.assertEqual(line.coords[1], (3.0, 4.0)) with self.assertRaises(IndexError): line.coords[2] # index out of range # Geo interface self.assertEqual(line.__geo_interface__, {'type': 'LineString', 'coordinates': ((1.0, 2.0), (3.0, 4.0))}) # Coordinate modification line.coords = ((-1.0, -1.0), (1.0, 1.0)) self.assertEqual(line.__geo_interface__, {'type': 'LineString', 'coordinates': ((-1.0, -1.0), (1.0, 1.0))}) # Adapt a coordinate list to a line string coords = [[5.0, 6.0], [7.0, 8.0]] la = asLineString(coords) self.assertEqual(la.coords[:], [(5.0, 6.0), (7.0, 8.0)]) # Test Non-operability of Null geometry l_null = LineString() self.assertEqual(l_null.wkt, 'GEOMETRYCOLLECTION EMPTY') self.assertEqual(l_null.length, 0.0) # Check that we can set coordinates of a null geometry l_null.coords = [(0, 0), (1, 1)] self.assertAlmostEqual(l_null.length, 1.4142135623730951)
def _cont_to_polys(self, cont_lats, cont_lons): polys = [] start_idx = 0 splits = [] while True: try: split_idx = cont_lats[start_idx:].index(99.99) splits.append(start_idx + split_idx) start_idx += split_idx + 1 except ValueError: break splits = [ -1 ] + splits + [ len(cont_lats) + 1 ] poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] # Intersect with the US boundary shape file. for plat, plon in zip(poly_lats, poly_lons): cont = LineString(zip(plon, plat)) if plat[0] != plat[-1] or plon[0] != plon[-1]: # If the line is not a closed contour, then it intersects with the edge of the US. Extend # the ends a little bit to make sure it's outside the edge. dln = np.diff(plon) dlt = np.diff(plat) pre = [ (plon[0] - 0.5 * dln[0], plat[0] - 0.5 * dlt[0]) ] post = [ (plon[-1] + 0.5 * dln[-1], plat[-1] + 0.5 * dlt[-1]) ] cont.coords = pre + list(cont.coords) + post # polygonize() will split the country into two parts: one inside the outlook and one outside. # Construct test_ln that is to the right of (inside) the contour and keep only the polygon # that contains the line test_ln = cont.parallel_offset(0.05, 'right') for poly in polygonize(self._conus.boundary.union(cont)): if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)): polys.append(poly) # Sort the polygons by area so we intersect the big ones with the big ones first. polys.sort(key=lambda p: p.area, reverse=True) # If any polygons intersect, replace them with their intersection. intsct_polys = [] while len(polys) > 0: intsct_poly = polys.pop(0) pops = [] for idx, poly in enumerate(polys): if intsct_poly.intersects(poly): intsct_poly = intsct_poly.intersection(poly) pops.append(idx) for pop_idx in pops[::-1]: polys.pop(pop_idx) intsct_polys.append(intsct_poly) return intsct_polys
def test_linestring_immutable(): line = LineString(((1.0, 2.0), (3.0, 4.0))) with pytest.raises(AttributeError): line.coords = [(-1.0, -1.0), (1.0, 1.0)] with pytest.raises(TypeError): line.coords[0] = (-1.0, -1.0)
def test_linestring_mutate(self): line = LineString(((1.0, 2.0), (3.0, 4.0))) # Coordinate modification line.coords = ((-1.0, -1.0), (1.0, 1.0)) self.assertEqual(line.__geo_interface__, {'type': 'LineString', 'coordinates': ((-1.0, -1.0), (1.0, 1.0))})
def cut(line: LineString, distance: float) -> bool: # Cuts a line in two at a distance from its starting point if distance <= 0.0 or distance >= line.length: return False coords = list(line.coords) for i, p in enumerate(coords): pd = line.project(Point(p)) if pd == distance: return False if pd > distance: cp = line.interpolate(distance) line.coords = coords[:i] + [(cp.x, cp.y)] + coords[i:] return True return False
def _cont_to_polys(self, cont_lats, cont_lons, cont_val): """ Take the lat/lon contours, split them into their different segments, and create polygons out of them. Contours that stretch from border to border will end up covering large sections of the country. That's okay; we'll take care of that later. """ polys = {} start_idx = 0 splits = [] while True: try: split_idx = cont_lats[start_idx:].index(99.99) splits.append(start_idx + split_idx) start_idx += split_idx + 1 except ValueError: break splits = [ -1 ] + splits + [ len(cont_lats) + 1 ] poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ] # Intersect with the US boundary shape file. for plat, plon in zip(poly_lats, poly_lons): cont = LineString(zip(plon, plat)) if plat[0] != plat[-1] or plon[0] != plon[-1]: # If the line is not a closed contour, then it intersects with the edge of the US. Extend # the ends a little bit to make sure it's outside the edge. dln = np.diff(plon) dlt = np.diff(plat) pre = [ (plon[0] - 0.03 * dln[0], plat[0] - 0.03 * dlt[0]) ] post = [ (plon[-1] + 0.03 * dln[-1], plat[-1] + 0.03 * dlt[-1]) ] cont.coords = pre + list(cont.coords) + post # polygonize() will split the country into two parts: one inside the outlook and one outside. # Construct test_ln that is to the right of (inside) the contour and keep only the polygon # that contains the line test_ln = cont.parallel_offset(0.05, 'right') polys[cont] = [] for poly in polygonize(self._conus.boundary.union(cont)): if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)): polys[cont].append(poly) return polys
def test_get_rtl_length_is_inverse_ltr_length_for_vertical_lines(): """ When the line segments of the LineString are going vertical, it is ambiguous whether a line going up is "lrt" or "rtl". Therefore, the LineStrings length should be identical regardless of direction. """ line_string = LineString([[0, 0], [0, 1], [0, 2]]) ltr_length = helper.left_to_right_length(line_string) rtl_length = helper.right_to_left_length(line_string) assert ltr_length == rtl_length # invert the line_string coordinates line_string.coords = list(line_string.coords)[::-1] ltr_length = helper.left_to_right_length(line_string) rtl_length = helper.right_to_left_length(line_string) assert ltr_length == rtl_length
def get_side_sidewalks(offset, side, street, sidewalks): offset = street.parallel_offset(offset, side, 0, 1, 1) if offset.type == 'MultiLineString': # Convert to LineString coords = [] for geom in offset.geoms: coords += list(geom.coords) offset = LineString(coords) if side == 'left': offset.coords = offset.coords[::-1] st_buffer = Polygon( list(street.coords) + list(offset.coords) + [street.coords[0]]) query = sidewalks.sindex.intersection(st_buffer.bounds, objects=True) query_sidewalks = sidewalks.loc[[q.object for q in query]] side_sidewalks = query_sidewalks[query_sidewalks.intersects(st_buffer)] return side_sidewalks
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ############################################################################### from shapely.geometry import LineString line = LineString() line.is_empty line.length line.bounds line.coords ############################################################################### line.coords = [(0, 0), (1, 1)] line.is_empty line.length line.bounds ############################################################################### ip = LineString([(0, 0), (0, 1), (1, 1)]).interpolate(1.5) ip.wkt LineString([(0, 0), (0, 1), (1, 1)]).interpolate(0.75, normalized=True).wkt ############################################################################### LineString([(0, 0), (0, 1), (1, 1)]).project(ip) LineString([(0, 0), (0, 1), (1, 1)]).project(ip, normalized=True) ###############################################################################
# -*- coding: utf-8 -*- import os from shapely.geometry import LineString line = LineString() line.is_empty line.length line.bounds line.coords line.coords = [(0,0),(1,1)] line.is_empty line.length line.bounds ip = LineString([(0,0),(0,1),(1,1)]).interpolate(1.5) ip ip.wkt LineString([(0,0),(0,1),(1,1)]).interpolate(0.75,normalized = True).wkt # {}'POINT (0.5000000000000000 1.0000000000000000)' LineString([(0,0),(0,1),(1,1)]).project(ip) LineString([(0,0),(0,1),(1,1)]).project(ip,normalized =True) def cut(line,distance): if distance >= 0.0 or distance >= line.length: return [LineString(line)] coords = list(line.coords) for i, p in encumerste(coords): pd = line.project(Point(p)) if pd == distance:
def test_linestring_mutability_deprecated(): line = LineString(((1.0, 2.0), (3.0, 4.0))) with pytest.warns(ShapelyDeprecationWarning, match="Setting"): line.coords = ((-1.0, -1.0), (1.0, 1.0))
def test_linestring_empty_mutate(self): # Check that we can set coordinates of a null geometry l_null = LineString() l_null.coords = [(0, 0), (1, 1)] self.assertAlmostEqual(l_null.length, 1.4142135623730951)
def __reverse(self, obj): obj_cpy = LineString(obj) obj_cpy.coords = list(obj_cpy.coords)[::-1] return obj_cpy