3. Shapely 사용하기#


 Shapely는 도형과 관련해 다양한 작업을 수행할 수 있습니다. 예를 들어 아래와 같은 작업들을 수행할 수 있습니다.

  • 점(Point), 선(line), 다각형(polygon) 생성

  • 도형의 면적, 길이, 둘레 등 계산

  • 도형 간의 병합(union), 빼기(difference), 거리 계산

  • 두 도형이 교차(intersect), 접촉(touch), 횡단(cross)하는지 등 여부 확인

3.1. 점(Point)#

 점(Point) 객체를 생성하는 것은 간단합니다. 좌표(x, y 또는 x, y, z)를 생성자(constructor)에 전달하면 됩니다.

# shapely.geometry.Point 클래스 임포트(import)
from shapely.geometry import Point

# 점(Point) 객체 생성
point1 = Point(2.2, 4.2)
point2 = Point(7.2, -25.1)
point3 = Point(9.26, -2.456)
point4_3D = Point(9.26, -2.456, 0.57)

 생성한 점 객체를 확인하려면 아래와 같이 도형을 표시할 수 있습니다. 또는 print 문을 사용하여 shapely 도형 객체에 대해 텍스트로 표시할 수도 있습니다.

point1
../../_images/e32cd8f99dad3181abe54558bec3343c07326535ae3840b0547bebefe82994d5.svg
print(point1)
print(point4_3D)
POINT (2.2 4.2)
POINT Z (9.26 -2.456 0.57)

 이 텍스트 표현은 OGC (Open Geospatial Consortium)Simple Feature Access에서 제시된 표준인 “WKT (Well-Known Text)” 형식입니다. 위 텍스트 표현 예시에서 print(point4_3D)가 “POINT Z …”로 프린트된 것을 볼 수 있습니다. 여기서 문자 “Z”는 도형의 3차원 버전을 의미합니다.

 점 객체의 데이터 유형도 확인해 보겠습니다. 점의 유형이 shapely.geometry.point.Point 임을 알 수 있습니다.

type(point1)
shapely.geometry.point.Point

Note

 Shapely는 GEOS를 사용하여 도형 객체를 처리합니다. GEOS는 C++ 라이브러리(Python보다 훨씬 빠름)로, GIS의 오픈소스 분야에서 QGIS를 비롯한 지리공간 연산 관련 많은 프로젝트들을 지원합니다.

3.1.1. Point 속성 및 메서드#

 점과 같은 shapely 도형 객체에는 유용한 속성 및 메서드들이 기본적으로 내장되어 있습니다. 사용 가능한 속성들을 활용하면, 점의 좌표 값을 추출하거나 점 사이의 유클리드 거리를 계산하는 등 다양한 기하학적 연산을 수행할 수 있습니다.

geom_type 속성에는 shapely 도형에 대한 유형 정보가 포함되어 있습니다.

point1.geom_type
'Point'

 도형 객체의 좌표값에 접근하기 위한 방법은 여러 가지가 있습니다. 예를 들어, 아래 예시의 속성 coordsshapely.coords.CoordinateSequence를 가리키며 좌표 리스트를 Iterator 형태로 반환합니다. 여기서 Iterator란, 항목들을 리스트 형태로 반환하는 파이썬 데이터 구조 중 한 종류입니다.

# 좌표값
list(point1.coords)
[(2.2, 4.2)]

 좌표값에 접근하기 위한 위 방법 외에도 shapely.geometry.Point 객체는 좌표값에 직접 접근할 수 있는 속성 x, y, (3차원 도형의 경우만) z을 갖습니다.

# x, y 좌표값 읽기
x = point1.x
y = point1.y

print(x, y)
2.2 4.2
# (3차원) x, y, z 좌표값 읽기
x = point4_3D.x
y = point4_3D.y
z = point4_3D.z

print(x, y, z)
9.26 -2.456 0.57

distance 메서드를 사용하여 두 객체 사이의 거리를 계산하는 것도 가능합니다.

 아래 예제에서 두 점 간의 거리는 데카르트(cartesian) 좌표계에서 계산됩니다. 하지만, 실제 GIS 데이터로 작업할 때에는 사용된 좌표 참조 시스템(CRS)을 기반으로 거리 계산을 수행합니다. 따라서 거리 계산시 사용된 좌표 참조 시스템(CRS)의 측정 단위(예. m)가 무엇인지 확인해야 합니다. point1point2 사이의 거리를 계산해 보겠습니다.

# point1과 point2 간 거리 계산
dist = point1.distance(point2)

print(f"점 사이의 거리는 {dist:.2f} unit 입니다.")
점 사이의 거리는 29.72 unit 입니다.

Caution

 Shapely를 사용하여 거리 및 면적을 계산할 때 기본적으로 내장된 메서드는,
  a) 평면, 데카르트(Cartesian), 유클리드 공간을 가정하고
  b) 계산된 값을 좌표계의 단위(예: m, 도; degree)에 따라 반환합니다.

3.2. 선 (Lines)#

 선(LineString) 객체 생성 방법은 점(Point) 생성과 유사합니다. 단일 좌표값을 갖는 튜플((2.2, 4.2)) 대신에, 좌표 튜플 리스트([(2.2, 4.2), (7.2, -25.1), (9.26, -2.456)]) 또는 선을 구성하는 점들의 리스트를 사용합니다.

# LineString 클래스 임포트
from shapely.geometry import LineString

# 점(Point) 객체로부터 선(LineString) 생성
line = LineString([point1, point2, point3])
line
../../_images/0dd31ba3b4a057207acbb77864aa8a612f4e0618c9d38c1859f6940fa0b4ba45.svg
# 좌표 튜플 리스트로부터 선 생성
line2 = LineString([(2.2, 4.2), (7.2, -25.1), (9.26, -2.456)])
line2
../../_images/0dd31ba3b4a057207acbb77864aa8a612f4e0618c9d38c1859f6940fa0b4ba45.svg

 아래의 텍스트 표현은 WKT 포맷입니다. WKT는 사람이 읽을 수 있는 텍스트 형식이므로 편리하며, 대부분의 GIS 도구에서도 사용됩니다. 또한 LineString이 여러 개의 좌표로 구성된 튜플로 되어 있음을 알 수 있습니다. WKT LINESTRING의 값은 쉼표,로 결합된 여러 개의 WKT POINTS의 값으로 구성됩니다.

print(line)
print(line2)
LINESTRING (2.2 4.2, 7.2 -25.1, 9.26 -2.456)
LINESTRING (2.2 4.2, 7.2 -25.1, 9.26 -2.456)

 데이터 유형도 확인해 보겠습니다.

# line 객체의 데이터 타입 확인
type(line)
shapely.geometry.linestring.LineString
# line 객체의 도형 타입(geometry type) 확인
line.geom_type
'LineString'

3.2.1. LineString 속성 및 메서드#

 Shapely의 선 관련 도형(LineString, LinearRing, MultiLineString)에는 유용한 기능을 제공하는 다양한 속성과 메서드가 있습니다. 예를 들어 도형의 좌표에 접근하고, 길이를 계산하고, 중심점을 찾고, 선을 따라서 지정된 간격으로 점을 찍거나, 선과 다른 도형 사이의 최근접 거리를 계산할 수 있습니다.

 선의 좌표에 접근하는 것은 점의 좌표에 접근하는 것과 매우 유사합니다. 선을 구성하기 위해서는 적어도 두 개 이상의 좌표 튜플이 있어야 하므로, 리스트에는 여러 개의 값이 포함됩니다.

# line 객체의 좌표 튜플
list(line.coords)
[(2.2, 4.2), (7.2, -25.1), (9.26, -2.456)]

 선의 모든 x 좌표 또는 모든 y 좌표에 접근해야 하는 경우 xy 속성을 사용할 수 있습니다.

# line 객체의 x, y 좌표
xcoords = list(line.xy[0])
ycoords = list(line.xy[1])

print(xcoords)
print(ycoords)
[2.2, 7.2, 9.26]
[4.2, -25.1, -2.456]

3D-LineStrings

 Shapely 도형의 xy 속성은 3차원 도형에서 z 값을 반환하지는 않습니다.

 GIS 분석에 유용한 또다른 속성으로, 선의 길이와 중심점(centroid)을 구할 수 있습니다. 선(또는 다른 타입의 도형)의 중심점은 shapely.geometry.Point 객체입니다.

# line 객체의 길이
line_length = line.length
print(f"선의 길이: {line_length:.1f} unit")
선의 길이: 52.5 unit
# line 객체의 중심점
print(line.centroid)
POINT (6.229961354035622 -11.892411157572392)

3.3. 다각형 (Polygon)#

../../_images/polygon.png

Fig. 3.2 다각형(Polygon) 예시#

 다각형(Polygon)을 생성하는 것은 점 또는 선을 생성하는 것과 동일한 논리를 따릅니다. 그러나 다각형을 생성하기 위해 성립해야 하는 규칙은 보다 더 복잡합니다. 다각형의 외부(shell)를 형성하는 하나의 선형 링이 존재해야 하며, 앞에서 생성된 다각형 쉘(shell)에서 잘라낼 부분을 가리키는 여러 개의 선형 링들로 구성됩니다.

 따라서, shapely.geometry.Polygon 생성자 함수는 두 개의 파라미터를 필요로 합니다. 첫 번째 파라미터인 쉘(shell)은 좌표 튜플 리스트 또는 점 리스트 또는 LinearRing이며, 다각형의 외부를 형성합니다. 두 번째 파라미터인 구멍(holes)은 선택적(사용해도 되고, 사용하지 않아도 됨)으로 사용되며, 쉘에서 잘라낼 구멍의 리스트 입니다. 이 리스트에 들어갈 항목들은 쉘과 동일한 데이터 타입 입니다.

 먼저, 구멍이 없는 간단한 다각형을 만들어 보겠습니다. 첫 번째 예제는 3개의 좌표로 구성된 튜플을 사용합니다.

from shapely.geometry import Polygon

# 좌표로부터 다각형 생성
polygon1 = Polygon([(2.2, 4.2), (7.2, -25.1), (9.26, -2.456)])
polygon1
../../_images/da6cc4b41d5635608d8abef45299f288edcded636e47bdb44f966e42a049139d.svg

 점 리스트에서 직접 다각형을 생성할 수도 있습니다.

polygon2 = Polygon([point1, point2, point3])
polygon2
../../_images/da6cc4b41d5635608d8abef45299f288edcded636e47bdb44f966e42a049139d.svg

 또는 LinearRing으로 다각형을 생성할 수도 있습니다. shapely.geometry.LinearRing을 구성할 때, 마지막에 첫 번째 점을 다시 나열하는 것을 생략할 수 있습니다. 이런 경우, Shapely는 점 리스트의 끝에 첫 번째 포인트를 자동으로 다시 추가합니다.

from shapely.geometry import LinearRing

shell = LinearRing([point1, point2, point3, point1])
polygon3 = Polygon(shell)
polygon3
../../_images/da6cc4b41d5635608d8abef45299f288edcded636e47bdb44f966e42a049139d.svg

 세 개의 다각형 polygon1, polygon2, polygon3를 생성하기 위해 동일한 값과 서로 다른 방법들을 사용했습니다. 이 다각형들이 동일한 도형을 표현하는지 확인해 보겠습니다.

polygon1 == polygon2 == polygon3
True

 점, 선과 마찬가지로 shapely.geometry.Polygon의 텍스트 표현은 WKT (Well-Known Text) 포맷입니다. WKT POLYGON은 하나 이상의 WKT LINEARRING으로 구성됩니다. 첫 번째 선형 링은 외부(shell)를 나타내며, 그 이후에 등장하는 선형 링들은 쉘에서 잘라낼 구멍들(holes)을 나타냅니다. 아래 코드에서는 구멍이 없는 다각형이므로, 하나의 선형 링으로만 구성되어 있습니다.

print(polygon1)
POLYGON ((2.2 4.2, 7.2 -25.1, 9.26 -2.456, 2.2 4.2))

 데이터 타입을 확인해 보겠습니다.

# 데이터 타입
type(polygon1)
shapely.geometry.polygon.Polygon
# 도형 타입
polygon1.geom_type
'Polygon'

Tip

 내장 help() 함수를 사용하여 함수 또는 클래스가 작동하는 방식, 필요한 파라미터, 사용할 수 있는 속성 및 메소드를 확인할 수 있습니다.

help(Polygon)
Hide code cell output
Help on class Polygon in module shapely.geometry.polygon:

class Polygon(shapely.geometry.base.BaseGeometry)
 |  Polygon(shell=None, holes=None)
 |  
 |  A geometry type representing an area that is enclosed by a linear ring.
 |  
 |  A polygon is a two-dimensional feature and has a non-zero area. It may
 |  have one or more negative-space "holes" which are also bounded by linear
 |  rings. If any rings cross each other, the feature is invalid and
 |  operations on it may fail.
 |  
 |  Parameters
 |  ----------
 |  shell : sequence
 |      A sequence of (x, y [,z]) numeric coordinate pairs or triples, or
 |      an array-like with shape (N, 2) or (N, 3).
 |      Also can be a sequence of Point objects.
 |  holes : sequence
 |      A sequence of objects which satisfy the same requirements as the
 |      shell parameters above
 |  
 |  Attributes
 |  ----------
 |  exterior : LinearRing
 |      The ring which bounds the positive space of the polygon.
 |  interiors : sequence
 |      A sequence of rings which bound all existing holes.
 |  
 |  Examples
 |  --------
 |  Create a square polygon with no holes
 |  
 |  >>> coords = ((0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.))
 |  >>> polygon = Polygon(coords)
 |  >>> polygon.area
 |  1.0
 |  
 |  Method resolution order:
 |      Polygon
 |      shapely.geometry.base.BaseGeometry
 |      shapely.lib.Geometry
 |      builtins.object
 |  
 |  Methods defined here:
 |  
 |  svg(self, scale_factor=1.0, fill_color=None, opacity=None)
 |      Returns SVG path element for the Polygon geometry.
 |      
 |      Parameters
 |      ==========
 |      scale_factor : float
 |          Multiplication factor for the SVG stroke-width.  Default is 1.
 |      fill_color : str, optional
 |          Hex string for fill color. Default is to use "#66cc99" if
 |          geometry is valid, and "#ff3333" if invalid.
 |      opacity : float
 |          Float number between 0 and 1 for color opacity. Default value is 0.6
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  from_bounds(xmin, ymin, xmax, ymax) from builtins.type
 |      Construct a `Polygon()` from spatial bounds.
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(self, shell=None, holes=None)
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Readonly properties defined here:
 |  
 |  __geo_interface__
 |      Dictionary representation of the geometry
 |  
 |  coords
 |      Access to geometry's coordinates (CoordinateSequence)
 |  
 |  exterior
 |  
 |  interiors
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from shapely.geometry.base.BaseGeometry:
 |  
 |  __and__(self, other)
 |  
 |  __bool__(self)
 |  
 |  __format__(self, format_spec)
 |      Format a geometry using a format specification.
 |  
 |  __nonzero__(self)
 |  
 |  __or__(self, other)
 |  
 |  __reduce__(self)
 |      Helper for pickle.
 |  
 |  __repr__(self)
 |      Return repr(self).
 |  
 |  __str__(self)
 |      Return str(self).
 |  
 |  __sub__(self, other)
 |  
 |  __xor__(self, other)
 |  
 |  almost_equals(self, other, decimal=6)
 |      True if geometries are equal at all coordinates to a
 |      specified decimal place.
 |      
 |      .. deprecated:: 1.8.0
 |          The 'almost_equals()' method is deprecated
 |          and will be removed in Shapely 2.1 because the name is
 |          confusing. The 'equals_exact()' method should be used
 |          instead.
 |      
 |      Refers to approximate coordinate equality, which requires
 |      coordinates to be approximately equal and in the same order for
 |      all components of a geometry.
 |      
 |      Because of this it is possible for "equals()" to be True for two
 |      geometries and "almost_equals()" to be False.
 |      
 |      Examples
 |      --------
 |      >>> LineString(
 |      ...     [(0, 0), (2, 2)]
 |      ... ).equals_exact(
 |      ...     LineString([(0, 0), (1, 1), (2, 2)]),
 |      ...     1e-6
 |      ... )
 |      False
 |      
 |      Returns
 |      -------
 |      bool
 |  
 |  buffer(self, distance, quad_segs=16, cap_style='round', join_style='round', mitre_limit=5.0, single_sided=False, **kwargs)
 |      Get a geometry that represents all points within a distance
 |      of this geometry.
 |      
 |      A positive distance produces a dilation, a negative distance an
 |      erosion. A very small or zero distance may sometimes be used to
 |      "tidy" a polygon.
 |      
 |      Parameters
 |      ----------
 |      distance : float
 |          The distance to buffer around the object.
 |      resolution : int, optional
 |          The resolution of the buffer around each vertex of the
 |          object.
 |      quad_segs : int, optional
 |          Sets the number of line segments used to approximate an
 |          angle fillet.
 |      cap_style : shapely.BufferCapStyle or {'round', 'square', 'flat'}, default 'round'
 |          Specifies the shape of buffered line endings. BufferCapStyle.round ('round')
 |          results in circular line endings (see ``quad_segs``). Both BufferCapStyle.square
 |          ('square') and BufferCapStyle.flat ('flat') result in rectangular line endings,
 |          only BufferCapStyle.flat ('flat') will end at the original vertex,
 |          while BufferCapStyle.square ('square') involves adding the buffer width.
 |      join_style : shapely.BufferJoinStyle or {'round', 'mitre', 'bevel'}, default 'round'
 |          Specifies the shape of buffered line midpoints. BufferJoinStyle.ROUND ('round')
 |          results in rounded shapes. BufferJoinStyle.bevel ('bevel') results in a beveled
 |          edge that touches the original vertex. BufferJoinStyle.mitre ('mitre') results
 |          in a single vertex that is beveled depending on the ``mitre_limit`` parameter.
 |      mitre_limit : float, optional
 |          The mitre limit ratio is used for very sharp corners. The
 |          mitre ratio is the ratio of the distance from the corner to
 |          the end of the mitred offset corner. When two line segments
 |          meet at a sharp angle, a miter join will extend the original
 |          geometry. To prevent unreasonable geometry, the mitre limit
 |          allows controlling the maximum length of the join corner.
 |          Corners with a ratio which exceed the limit will be beveled.
 |      single_side : bool, optional
 |          The side used is determined by the sign of the buffer
 |          distance:
 |      
 |              a positive distance indicates the left-hand side
 |              a negative distance indicates the right-hand side
 |      
 |          The single-sided buffer of point geometries is the same as
 |          the regular buffer.  The End Cap Style for single-sided
 |          buffers is always ignored, and forced to the equivalent of
 |          CAP_FLAT.
 |      quadsegs : int, optional
 |          Deprecated alias for `quad_segs`.
 |      
 |      Returns
 |      -------
 |      Geometry
 |      
 |      Notes
 |      -----
 |      The return value is a strictly two-dimensional geometry. All
 |      Z coordinates of the original geometry will be ignored.
 |      
 |      Examples
 |      --------
 |      >>> from shapely.wkt import loads
 |      >>> g = loads('POINT (0.0 0.0)')
 |      
 |      16-gon approx of a unit radius circle:
 |      
 |      >>> g.buffer(1.0).area  # doctest: +ELLIPSIS
 |      3.1365484905459...
 |      
 |      128-gon approximation:
 |      
 |      >>> g.buffer(1.0, 128).area  # doctest: +ELLIPSIS
 |      3.141513801144...
 |      
 |      triangle approximation:
 |      
 |      >>> g.buffer(1.0, 3).area
 |      3.0
 |      >>> list(g.buffer(1.0, cap_style=BufferCapStyle.square).exterior.coords)
 |      [(1.0, 1.0), (1.0, -1.0), (-1.0, -1.0), (-1.0, 1.0), (1.0, 1.0)]
 |      >>> g.buffer(1.0, cap_style=BufferCapStyle.square).area
 |      4.0
 |  
 |  contains(self, other)
 |      Returns True if the geometry contains the other, else False
 |  
 |  contains_properly(self, other)
 |      Returns True if the geometry completely contains the other, with no
 |      common boundary points, else False
 |      
 |      Refer to `shapely.contains_properly` for full documentation.
 |  
 |  covered_by(self, other)
 |      Returns True if the geometry is covered by the other, else False
 |  
 |  covers(self, other)
 |      Returns True if the geometry covers the other, else False
 |  
 |  crosses(self, other)
 |      Returns True if the geometries cross, else False
 |  
 |  difference(self, other, grid_size=None)
 |      Returns the difference of the geometries.
 |      
 |      Refer to `shapely.difference` for full documentation.
 |  
 |  disjoint(self, other)
 |      Returns True if geometries are disjoint, else False
 |  
 |  distance(self, other)
 |      Unitless distance to other geometry (float)
 |  
 |  dwithin(self, other, distance)
 |      Returns True if geometry is within a given distance from the other, else False.
 |      
 |      Refer to `shapely.dwithin` for full documentation.
 |  
 |  equals(self, other)
 |      Returns True if geometries are equal, else False.
 |      
 |      This method considers point-set equality (or topological
 |      equality), and is equivalent to (self.within(other) &
 |      self.contains(other)).
 |      
 |      Examples
 |      --------
 |      >>> LineString(
 |      ...     [(0, 0), (2, 2)]
 |      ... ).equals(
 |      ...     LineString([(0, 0), (1, 1), (2, 2)])
 |      ... )
 |      True
 |      
 |      Returns
 |      -------
 |      bool
 |  
 |  equals_exact(self, other, tolerance)
 |      True if geometries are equal to within a specified
 |      tolerance.
 |      
 |      Parameters
 |      ----------
 |      other : BaseGeometry
 |          The other geometry object in this comparison.
 |      tolerance : float
 |          Absolute tolerance in the same units as coordinates.
 |      
 |      This method considers coordinate equality, which requires
 |      coordinates to be equal and in the same order for all components
 |      of a geometry.
 |      
 |      Because of this it is possible for "equals()" to be True for two
 |      geometries and "equals_exact()" to be False.
 |      
 |      Examples
 |      --------
 |      >>> LineString(
 |      ...     [(0, 0), (2, 2)]
 |      ... ).equals_exact(
 |      ...     LineString([(0, 0), (1, 1), (2, 2)]),
 |      ...     1e-6
 |      ... )
 |      False
 |      
 |      Returns
 |      -------
 |      bool
 |  
 |  geometryType(self)
 |  
 |  hausdorff_distance(self, other)
 |      Unitless hausdorff distance to other geometry (float)
 |  
 |  interpolate(self, distance, normalized=False)
 |      Return a point at the specified distance along a linear geometry
 |      
 |      Negative length values are taken as measured in the reverse
 |      direction from the end of the geometry. Out-of-range index
 |      values are handled by clamping them to the valid range of values.
 |      If the normalized arg is True, the distance will be interpreted as a
 |      fraction of the geometry's length.
 |      
 |      Alias of `line_interpolate_point`.
 |  
 |  intersection(self, other, grid_size=None)
 |      Returns the intersection of the geometries.
 |      
 |      Refer to `shapely.intersection` for full documentation.
 |  
 |  intersects(self, other)
 |      Returns True if geometries intersect, else False
 |  
 |  line_interpolate_point(self, distance, normalized=False)
 |      Return a point at the specified distance along a linear geometry
 |      
 |      Negative length values are taken as measured in the reverse
 |      direction from the end of the geometry. Out-of-range index
 |      values are handled by clamping them to the valid range of values.
 |      If the normalized arg is True, the distance will be interpreted as a
 |      fraction of the geometry's length.
 |      
 |      Alias of `interpolate`.
 |  
 |  line_locate_point(self, other, normalized=False)
 |      Returns the distance along this geometry to a point nearest the
 |      specified point
 |      
 |      If the normalized arg is True, return the distance normalized to the
 |      length of the linear geometry.
 |      
 |      Alias of `project`.
 |  
 |  normalize(self)
 |      Converts geometry to normal form (or canonical form).
 |      
 |      This method orders the coordinates, rings of a polygon and parts of
 |      multi geometries consistently. Typically useful for testing purposes
 |      (for example in combination with `equals_exact`).
 |      
 |      Examples
 |      --------
 |      >>> from shapely import MultiLineString
 |      >>> line = MultiLineString([[(0, 0), (1, 1)], [(3, 3), (2, 2)]])
 |      >>> line.normalize()
 |      <MULTILINESTRING ((2 2, 3 3), (0 0, 1 1))>
 |  
 |  overlaps(self, other)
 |      Returns True if geometries overlap, else False
 |  
 |  point_on_surface(self)
 |      Returns a point guaranteed to be within the object, cheaply.
 |      
 |      Alias of `representative_point`.
 |  
 |  project(self, other, normalized=False)
 |      Returns the distance along this geometry to a point nearest the
 |      specified point
 |      
 |      If the normalized arg is True, return the distance normalized to the
 |      length of the linear geometry.
 |      
 |      Alias of `line_locate_point`.
 |  
 |  relate(self, other)
 |      Returns the DE-9IM intersection matrix for the two geometries
 |      (string)
 |  
 |  relate_pattern(self, other, pattern)
 |      Returns True if the DE-9IM string code for the relationship between
 |      the geometries satisfies the pattern, else False
 |  
 |  representative_point(self)
 |      Returns a point guaranteed to be within the object, cheaply.
 |      
 |      Alias of `point_on_surface`.
 |  
 |  reverse(self)
 |      Returns a copy of this geometry with the order of coordinates reversed.
 |      
 |      If the geometry is a polygon with interior rings, the interior rings are also
 |      reversed.
 |      
 |      Points are unchanged.
 |      
 |      See also
 |      --------
 |      is_ccw : Checks if a geometry is clockwise.
 |      
 |      Examples
 |      --------
 |      >>> from shapely import LineString, Polygon
 |      >>> LineString([(0, 0), (1, 2)]).reverse()
 |      <LINESTRING (1 2, 0 0)>
 |      >>> Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]).reverse()
 |      <POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))>
 |  
 |  segmentize(self, max_segment_length)
 |      Adds vertices to line segments based on maximum segment length.
 |      
 |      Additional vertices will be added to every line segment in an input geometry
 |      so that segments are no longer than the provided maximum segment length. New
 |      vertices will evenly subdivide each segment.
 |      
 |      Only linear components of input geometries are densified; other geometries
 |      are returned unmodified.
 |      
 |      Parameters
 |      ----------
 |      max_segment_length : float or array_like
 |          Additional vertices will be added so that all line segments are no
 |          longer this value.  Must be greater than 0.
 |      
 |      Examples
 |      --------
 |      >>> from shapely import LineString, Polygon
 |      >>> LineString([(0, 0), (0, 10)]).segmentize(max_segment_length=5)
 |      <LINESTRING (0 0, 0 5, 0 10)>
 |      >>> Polygon([(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)]).segmentize(max_segment_length=5)
 |      <POLYGON ((0 0, 5 0, 10 0, 10 5, 10 10, 5 10, 0 10, 0 5, 0 0))>
 |  
 |  simplify(self, tolerance, preserve_topology=True)
 |      Returns a simplified geometry produced by the Douglas-Peucker
 |      algorithm
 |      
 |      Coordinates of the simplified geometry will be no more than the
 |      tolerance distance from the original. Unless the topology preserving
 |      option is used, the algorithm may produce self-intersecting or
 |      otherwise invalid geometries.
 |  
 |  symmetric_difference(self, other, grid_size=None)
 |      Returns the symmetric difference of the geometries.
 |      
 |      Refer to `shapely.symmetric_difference` for full documentation.
 |  
 |  touches(self, other)
 |      Returns True if geometries touch, else False
 |  
 |  union(self, other, grid_size=None)
 |      Returns the union of the geometries.
 |      
 |      Refer to `shapely.union` for full documentation.
 |  
 |  within(self, other)
 |      Returns True if geometry is within the other, else False
 |  
 |  ----------------------------------------------------------------------
 |  Readonly properties inherited from shapely.geometry.base.BaseGeometry:
 |  
 |  area
 |      Unitless area of the geometry (float)
 |  
 |  boundary
 |      Returns a lower dimension geometry that bounds the object
 |      
 |      The boundary of a polygon is a line, the boundary of a line is a
 |      collection of points. The boundary of a point is an empty (null)
 |      collection.
 |  
 |  bounds
 |      Returns minimum bounding region (minx, miny, maxx, maxy)
 |  
 |  centroid
 |      Returns the geometric center of the object
 |  
 |  convex_hull
 |      Imagine an elastic band stretched around the geometry: that's a
 |      convex hull, more or less
 |      
 |      The convex hull of a three member multipoint, for example, is a
 |      triangular polygon.
 |  
 |  envelope
 |      A figure that envelopes the geometry
 |  
 |  geom_type
 |      Name of the geometry's type, such as 'Point'
 |  
 |  has_z
 |      True if the geometry's coordinate sequence(s) have z values (are
 |      3-dimensional)
 |  
 |  is_closed
 |      True if the geometry is closed, else False
 |      
 |      Applicable only to 1-D geometries.
 |  
 |  is_empty
 |      True if the set of points in this geometry is empty, else False
 |  
 |  is_ring
 |      True if the geometry is a closed ring, else False
 |  
 |  is_simple
 |      True if the geometry is simple, meaning that any self-intersections
 |      are only at boundary points, else False
 |  
 |  is_valid
 |      True if the geometry is valid (definition depends on sub-class),
 |      else False
 |  
 |  length
 |      Unitless length of the geometry (float)
 |  
 |  minimum_clearance
 |      Unitless distance by which a node could be moved to produce an invalid geometry (float)
 |  
 |  minimum_rotated_rectangle
 |      Returns the oriented envelope (minimum rotated rectangle) that
 |      encloses the geometry.
 |      
 |      Unlike `envelope` this rectangle is not constrained to be parallel to the
 |      coordinate axes. If the convex hull of the object is a degenerate (line
 |      or point) this degenerate is returned.
 |      
 |      Alias of `oriented_envelope`.
 |  
 |  oriented_envelope
 |      Returns the oriented envelope (minimum rotated rectangle) that
 |      encloses the geometry.
 |      
 |      Unlike envelope this rectangle is not constrained to be parallel to the
 |      coordinate axes. If the convex hull of the object is a degenerate (line
 |      or point) this degenerate is returned.
 |      
 |      Alias of `minimum_rotated_rectangle`.
 |  
 |  type
 |  
 |  wkb
 |      WKB representation of the geometry
 |  
 |  wkb_hex
 |      WKB hex representation of the geometry
 |  
 |  wkt
 |      WKT representation of the geometry
 |  
 |  xy
 |      Separate arrays of X and Y coordinate values
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from shapely.lib.Geometry:
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __setstate__(...)
 |      For unpickling pre-shapely 2.0 pickles

 이번에는 구멍이 있는 다각형을 만들어 보겠습니다. 외부 쉘과 구멍이 각각 어떻게 생겼는지 살펴보겠습니다.

# 외부(Shell) 정의
outer = LinearRing([(-180, 90), (-180, -90), (180, -90), (180, 90)])
outer
../../_images/1c4e55928e3c3e8df46a69946706ad99979281248ef64e9b0d3496f76bafefab.svg
# 구멍(Holes) 정의
hole = LinearRing([(-170, 80), (-100, -80), (100, -80), (170, 80)])
hole
../../_images/41a3d34cbd8ea127e956b1dfe7b8aa8602186feee57479cedda8c68aa7296085.svg

 외부 쉘과 하나의 구멍(holes는 리스트로 정의)으로 구성된 다각형을 생성합니다.

polygon_with_hole = Polygon(outer, [hole])
polygon_with_hole
../../_images/b821c3db33788157815e776ce96fe7eba73a773791a58f124df3e1d763f133a9.svg
print(polygon_with_hole)
POLYGON ((-180 90, -180 -90, 180 -90, 180 90, -180 90), (-170 80, -100 -80, 100 -80, 170 80, -170 80))

3.3.1. Polygon 속성 및 메서드#

shapely.geometry.Polygon은 앞에서 다룬 점, 선처럼 공간분석 작업에 유용한 여러 속성 및 메서드를 갖고 있습니다. 속성 및 메서드에 대한 전체 목록은 Shapely 공식 문서를 확인 바라며, 여기에서는 몇 가지 예를 사용해보도록 하겠습니다.

print(f"다각형 중심점(centroid): {polygon_with_hole.centroid}")
print(f"다각형 면적(area): {polygon_with_hole.area}")
print(f"다각형 경계 상자(bounding box): {polygon_with_hole.bounds}")
print(f"다각형 외부 링(exterior ring): {polygon_with_hole.exterior}")
print(f"다각형 둘레(circumference): {polygon_with_hole.exterior.length}")
다각형 중심점(centroid): POINT (0 -13.827160493827162)
다각형 면적(area): 21600.0
다각형 경계 상자(bounding box): (-180.0, -90.0, 180.0, 90.0)
다각형 외부 링(exterior ring): LINEARRING (-180 90, -180 -90, 180 -90, 180 90, -180 90)
다각형 둘레(circumference): 1080.0