Automating GIS Processes 2024 写経　Exercise １（Problem 2）

[前回](https://qiita.com/t_t_japan/items/19d26433f54283df5c39)の続きです。

https://github.com/Automating-GIS-processes-II-2024/exercise-1/blob/main/Exercise-1-problem-1-2.ipynb

# (2a)
> Create a function called get_centroid() that accepts one parameter, geom. The function should take any kind of Shapely’s geometry objects (any instance of shapely.geometry.base.BaseGeometry) as an input, and return the centroid of that geometry.

> Make sure to validate the function’s input arguments using assert statements:

> - check that the input is a shapely.geometry.base.BaseGeometry or one of its child classes. Otherwise, raise the error "Input must be a shapely geometry".


こんな感じでしょうか。

> BaseGeometry or one of its child classes

の箇所は、`isinstance(geom, BaseGeometry)`としています。
なお、`create_polygon_geometry`は前回作成した関数です。
```
from shapely.geometry.base import BaseGeometry

def get_centroid (geom: BaseGeometry) -> Point:

    assert isinstance(geom, BaseGeometry), "Input must be a shapely geometry"

    return geom.centroid


polygon1 = create_polygon_geometry([(1, 1), (2, 1) ,(2,2)])

centroid = get_centroid(polygon1)
print(centroid)
```
結果です。比較できるようにpolygon1もprintしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/1941bd99-c8e7-415a-9e5d-6032893524de.png)


assertionのテストコードとその結果です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/8bb6e1cd-0720-4c01-842f-f972035efe29.png)


# (2b)
> Create a function get_area() accepting one parameter polygon.

> The function should accept a shapely.geometry.Polygon and return its area. Again, use assert to make sure the input values are valid, in particular, check that:

> - the input is a shapely.geometry.Polygon. If the argument is anything else, raise an error: "Input should be a shapely.geometry.Polygon".

こんな感じでしょうか。
前述の通り、`create_polygon_geometry`は前回作成した関数です。
```
from shapely.geometry import Polygon

def get_area (polygon: Polygon) -> float:

    assert isinstance(polygon, Polygon), "Input should be a shapely.geometry.Polygon"

    return polygon.area


polygon1 = create_polygon_geometry([(1, 1), (2, 1) ,(2,2)])

# NON-EDITABLE CODE CELL FOR TESTING YOUR SOLUTION
area = get_area(polygon1)
print(round(area, 2))
```
結果です。比較できるようにpolygon1もprintしています。
（面積は1*1/2 = 0.5）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/e064b809-6e50-4857-a5c7-dd1737cc6fdf.png)

assertionのテストコードとその結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/5de7287b-d36b-4d65-8cf8-af7bf24ea893.png)


> (2c)
> Create a function get_length() accepting one parameter, geometry.

> The function should accept either a shapely.geometry.LineString or a shapely.geometry.Polygon as input. Check the type of the input and return the length of the line if input is a LineString and length of the exterior ring if the input is a Polygon.

> If something else is passed to the function, raise an error "‘geometry’ should be either a LineString or a Polygon". Use assert or (advanced, optional) raise a ValueError exception.

こんな感じでしょうか。
今回は、`ValueError exception`を`raise`してみました。
`get_length`、`create_polygon_geometry`は前回作成した関数です。

```
from shapely.geometry.base import BaseGeometry
from shapely.geometry import LineString, Polygon

def get_length (geom: BaseGeometry)  -> float:

    if isinstance(geom, LineString) == False and  isinstance(geom, Polygon)  == False: 
        raise ValueError("Input should be a LineStirng or a Polygon") 

    # Check the type of the input and return the length of the line if input is a LineString
    if isinstance(geom, LineString):
        return geom.length
  
    # Check the type of the input and return the length of the exterior ring if the input is a Polygon
    if isinstance(geom, Polygon):
        return geom.exterior.length


line1 = create_line_geometry([Point(1, 1), Point(2, 2)])
line_length = get_length(line1)
print("Line length:", round(line_length,2))

polygon1 = create_polygon_geometry([(1, 1), (2, 1) ,(2,2), (1,2)])
poly_exterior_length = get_length(polygon1)
print("Polygon exterior length:", round(poly_exterior_length,2))
```

結果です。比較できるようにline1、polygon1もprintしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/b0a79827-7789-42a1-9127-5d3697ca9580.png)


`ValueError exception`のテストコードとその結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/6784f3de-403c-4c64-823e-7af941379fe2.png)

# Docstrings

> id you add a docstring to all the functions you defined? If not, add them now :) A short one-line docstring is enough in this exercise.
> You can run the code cell below to check all the docstrings:

関数にはdocstring（ドキュメンテーション文字列、ドキュメント文字列）を付けましょう、という話。
詳細はこちら。

https://peps.python.org/pep-0257/#what-is-a-docstring

次回は Problem 3です。