Data Spasial dengan Python (bagian 1)

· 9 min read
Data Spasial dengan Python (bagian 1)

Pertama kita harus mengimport library yang dibutuhkan yaitu pandas, geopandas, dan matplotlib inline

%matplotlib inline

import pandas as pd
import geopandas
/home/lenovo/anaconda3/lib/python3.8/site-packages/geopandas/_compat.py:106: UserWarning: The Shapely GEOS version (3.8.0-CAPI-1.13.1 ) is incompatible with the GEOS version PyGEOS was compiled with (3.9.0-CAPI-1.16.2). Conversions between both will be slow.
  warnings.warn(

Membuka data geospasial

Data geospasial tersedia dalam beberapa format file GIS atau penyimpanan data seperti ESRI shapefiles, GeoJSON files, geopackage files, PostGIS, dll.

Dengan menggunakan library geopandas kita dapat membaca beberapa file GIS tersebut. Geopandas di dalamanya menggunakan library fiona yang menjadi penghubung dengan GDAL/OGR.

FUngsi dari geopandas yang digunakan untuk membaca data GIS yaitu geopandas.read_file

berikut contoh membuka file SHP batas administrasi

batas_admin = geopandas.read_file("/home/lenovo/Downloads/admin_sleman/ADMINISTRASIDESA_AR_25K.shp")

Untuk menampilkan 5 baris data pertama dari data SHP dapat menggunakan fungsi head()

batas_admin.head()

Screenshot-from-2021-03-29-22-07-08

Untuk menampilkan 5 baris data terakhir dari data SHP dapat menggunakan fungsi tail()

batas_admin.tail()

Screenshot-from-2021-03-29-22-06-07

batas_admin.plot()

output_9_1

GeoDataFrame

data spasial yang dibaca oleh library geopandas akan menjadi GeoDataFrame:

type(batas_admin)
geopandas.geodataframe.GeoDataFrame

GeoDtaFrame berupa tabel dataset geospatial, yang berisi kolom geometry yang berisi informasi geometry dan kolom lainnya berupa atibut dari adta spasial

Sebenarnya GeoDataFram mirip dengan pandas DataFrame bedanya pada GeoDataFrame dapat dilakukan fungsi untuk geospasial.

Nama kolom yang berisi geometry tidak harus geometry namun isinya pasti berupa informasi geometry. spasial data di GeoDataFrame dapat dilakukan operasi spasial diantaranya luas, jarak, buffer, intersect, dll.

batas_admin.geometry
0      MULTIPOLYGON Z (((110.23297 -7.71338 0.00000, ...
1      POLYGON Z ((110.25000 -7.70852 0.00000, 110.24...
2      MULTIPOLYGON Z (((110.22105 -7.73526 0.00000, ...
3      POLYGON Z ((110.25000 -7.73329 0.00000, 110.24...
4      POLYGON Z ((110.24570 -7.72992 0.00000, 110.24...
                             ...                        
145    MULTIPOLYGON Z (((110.25063 -7.73895 0.00000, ...
146    POLYGON Z ((110.38003 -7.64589 0.00000, 110.37...
147    MULTIPOLYGON Z (((110.42250 -7.79874 0.00000, ...
148    MULTIPOLYGON Z (((110.37210 -7.60920 0.00000, ...
149    POLYGON Z ((110.33409 -7.64847 0.00000, 110.33...
Name: geometry, Length: 150, dtype: geometry

Saat kolom geometry diakses maka akan menjadi tipe GeoSeries

type(batas_admin.geometry)
geopandas.geoseries.GeoSeries

Pada GeoSeries ini dapat dilakukan operasi spasial misalnya untuk mengukur luas setiap feature dengan fungsi area sebgai berikut:

batas_admin.geometry.area
<ipython-input-9-332e230e2526>:1: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  batas_admin.geometry.area





0      1.323009e-06
1      3.304474e-09
2      1.349723e-06
3      6.517784e-05
4      5.054078e-04
           ...     
145    1.643987e-06
146    1.160500e-03
147    5.632477e-08
148    2.091632e-08
149    2.882021e-04
Length: 150, dtype: float64

Saat melakukan pengukuran luas tersebut akan muncul peringatan karena data tersebut memiliki proyeksi geografis sehingga pengukuruan dianggap kurang akurat, oleh karena itu untuk mengukur luar perlu dilakukan tranformasi proyeksi menjadi geodetik dengan menggunakan fungsi to_crs() baru kemudian fungsi area dan misalkan menggunakan proyeksi UTM 49M maka kode crsnya yaitu EPSG:32749, jadi fungsinya menjadi to_crs('EPSG:32749').area. hasilnya sebgai berikut:

batas_admin.geometry.to_crs('EPSG:32749').area
0      1.613149e+04
1      4.029172e+01
2      1.645682e+04
3      7.946961e+05
4      6.162268e+06
           ...     
145    2.004393e+04
146    1.415226e+07
147    6.866008e+02
148    2.550891e+02
149    3.514439e+06
Length: 150, dtype: float64

GeoDataFrame masih memilii fungsi dari Pandas DataFrame sehingga fungsi-fungsi yang yang dimiliki DataFrame dapat diterapkan pada data spasial di GeoDataFrame.
Misalnya untuk mengetahui rata-rata dari nilai, kita dapat menggunkan fungsi mean() seperti berikut:

batas_admin.geometry.to_crs('EPSG:32749').area.mean()
3838559.1016731923

Atau bisa juga melakukan filter dengan kondisional:

minggir = batas_admin[batas_admin['WADMKC'] == 'Minggir']
minggir.plot()

output_24_1

Geometry: Point, Linestring/Polyline and Polygon

Data spasial vector dapat berupa 3 vektor dasar yaitu:

  • Point: menggambarkan titik di dalam ruang
  • Polyine ("LineString"): menggambarkan sekumpilan titik yang membentuk garis
  • Polygon: menggambarkan sekumpulan titik yang membentuk area.

setiap bentuk dasar tersebut juga dapat berupa multi-part.
Untuk feature yang 3 dimensi memiliki 3 sumbu yaitu x, y, dan z, digambarkan dengan penambahan Z di belakang jenis featurenya

Misalnya seperti objek berikut yang berupa polygon 3 dimensi:

print(batas_admin.geometry[3])
POLYGON Z ((110.2499999993334 -7.73328800066664 0, 110.2498690010001 -7.73349799999994 0, 110.2497460010001 -7.733731000999946 0, 110.2495860000001 -7.734023999999941 0, 110.249446 -7.734284999999954 0, 110.2494429990001 -7.734288999999929 0, 110.2493980010001 -7.734385999999962 0, 110.24913 -7.734864000999988 0, 110.248613 -7.735056999999969 0, 110.2479170000001 -7.735188999999966 0, 110.247592 -7.735054999999893 0, 110.247430001 -7.734701000000001 0, 110.2473660000001 -7.7345130009999 0, 110.2474700000001 -7.734329999999947 0, 110.247728 -7.733873999999965 0, 110.2477950000001 -7.733749001000014 0, 110.2477590000001 -7.733095998999985 0, 110.2476270010001 -7.732270000999943 0, 110.247642 -7.731915999999963 0, 110.2477310000001 -7.731572999000004 0, 110.2479399990001 -7.731265999999916 0, 110.2481140010001 -7.730989000000001 0, 110.248309 -7.730712998999902 0, 110.248339 -7.73067100099998 0, 110.2484880000001 -7.730413999999943 0, 110.248591 -7.730247999999975 0, 110.2486190000001 -7.730209999999939 0, 110.2492499990001 -7.729169999999954 0, 110.249228 -7.729153999999962 0, 110.248063 -7.728577999999999 0, 110.2475300000001 -7.729208999999983 0, 110.2474220000001 -7.729287999999947 0, 110.2472370000001 -7.729488999999969 0, 110.2470160000001 -7.729777999999989 0, 110.2469460000001 -7.729924999999984 0, 110.2469180000001 -7.730039999999995 0, 110.2468440000001 -7.730244000999999 0, 110.246699 -7.730249999999963 0, 110.2463590000001 -7.730278999999964 0, 110.245931 -7.730115999999978 0, 110.2457020000001 -7.729923999999901 0, 110.2459040000001 -7.72957000000001 0, 110.2462140000001 -7.729037998999956 0, 110.246397001 -7.728707998999919 0, 110.2465510010001 -7.728445000000008 0, 110.2465510010001 -7.728444000999925 0, 110.2466789990001 -7.728206999999944 0, 110.2469010000001 -7.727826000999951 0, 110.2472460000001 -7.727233999999996 0, 110.247591 -7.726607999999981 0, 110.2476899990001 -7.726425999999933 0, 110.2478750010001 -7.726127000999973 0, 110.248221 -7.725496999999983 0, 110.2482359990001 -7.725466999999988 0, 110.248928 -7.724264999999921 0, 110.2489780000001 -7.724188999999939 0, 110.2490170000001 -7.72410599999991 0, 110.2491169990001 -7.723885999999915 0, 110.2490910000001 -7.723605000999935 0, 110.2490470000001 -7.723216999999984 0, 110.248966 -7.72278900100001 0, 110.2488220000001 -7.722402000999963 0, 110.2487870000001 -7.722009999999948 0, 110.2488010000001 -7.721663000999925 0, 110.2488560000001 -7.721374999999988 0, 110.2489880000001 -7.720627999999998 0, 110.249143001 -7.719976999999957 0, 110.249052 -7.720017999999886 0, 110.2485059990001 -7.720316999999934 0, 110.2479920010001 -7.720609000999936 0, 110.2473230000001 -7.720977999999914 0, 110.2472630000001 -7.720993999999994 0, 110.247082 -7.721034000999929 0, 110.246601 -7.721112000999899 0, 110.245843 -7.721234000999956 0, 110.2456580000001 -7.721168999999996 0, 110.2455390010001 -7.721080000000004 0, 110.2452640010001 -7.720879000999982 0, 110.245238 -7.720905999999996 0, 110.245929001 -7.719954000000008 0, 110.246223 -7.71955600099994 0, 110.246352 -7.719401999999988 0, 110.24638 -7.719377999999956 0, 110.246439 -7.719281000999924 0, 110.2467 -7.718941999999942 0, 110.2468660000001 -7.718719998999958 0, 110.246935 -7.718624000000009 0, 110.247434 -7.717955000999989 0, 110.2475400000001 -7.717812999999964 0, 110.2474400000001 -7.717793999999991 0, 110.2471209990001 -7.717827999999962 0, 110.246833 -7.717896999999898 0, 110.246511 -7.71796799999991 0, 110.2464050000001 -7.717923999999911 0, 110.2461279990001 -7.71774700000001 0, 110.2460260000001 -7.717729999999936 0, 110.2458800000001 -7.717713999999944 0, 110.2457570000001 -7.717628999999928 0, 110.245574 -7.717534999999966 0, 110.2454360010001 -7.717463999999953 0, 110.244917999 -7.717251999999998 0, 110.2448100000001 -7.717256000999974 0, 110.2447780000001 -7.717268999999895 0, 110.244712 -7.717315999999965 0, 110.244259 -7.717326999999987 0, 110.2439430000001 -7.717313000999983 0, 110.2437850010001 -7.717177999999915 0, 110.2437240010001 -7.717131999999928 0, 110.2440760000001 -7.716680999999916 0, 110.2442490000001 -7.716648000999939 0, 110.2442370000001 -7.716566999999898 0, 110.2442370000001 -7.716378000999981 0, 110.2442480000001 -7.716173999999977 0, 110.244156 -7.716089999999955 0, 110.2439760000001 -7.715961999999934 0, 110.243968 -7.715915999999947 0, 110.244013 -7.715851000999987 0, 110.2440360000001 -7.715769000999952 0, 110.2442010000001 -7.715452000000013 0, 110.2442020000001 -7.715441999999896 0, 110.244178 -7.715421999999929 0, 110.2440310000001 -7.715315999999952 0, 110.2438869990001 -7.715231999999929 0, 110.2436640000001 -7.715089999999993 0, 110.243645 -7.715011999999934 0, 110.2436970000001 -7.71483400099995 0, 110.243834 -7.714501999999925 0, 110.243851999 -7.71447199999993 0, 110.243885 -7.714428999999924 0, 110.2439340000001 -7.714325999999929 0, 110.243952 -7.714176999999946 0, 110.2439510000001 -7.714130999999959 0, 110.243953 -7.713954999999963 0, 110.24406 -7.713964999999991 0, 110.2442800000001 -7.714023999999899 0, 110.2448520010001 -7.71425099999994 0, 110.2451929990001 -7.714330999999987 0, 110.2455390000001 -7.714346999999979 0, 110.2459580000001 -7.714546999999918 0, 110.2470800010001 -7.713926999999956 0, 110.24717 -7.713945999999929 0, 110.247889 -7.714075000999944 0, 110.2483130000001 -7.713923999999974 0, 110.248557 -7.713869999999947 0, 110.2486180000001 -7.713862000999907 0, 110.2486649990001 -7.713830000000012 0, 110.249261 -7.713423999999993 0, 110.24936 -7.713356999999956 0, 110.249374 -7.713261999999911 0, 110.2493850000001 -7.713223999999965 0, 110.249461999 -7.712906999999937 0, 110.249421999 -7.712821000999927 0, 110.249289 -7.712677998999908 0, 110.2490230000001 -7.712521999999968 0, 110.24897 -7.712416999999984 0, 110.2488640000001 -7.712224998999908 0, 110.2487799990001 -7.712051999999982 0, 110.2486260000001 -7.711732000999973 0, 110.2489410000001 -7.711574000999956 0, 110.2493140000001 -7.711382999999962 0, 110.2493390000001 -7.711260999999993 0, 110.2494700000001 -7.711075999999963 0, 110.249579 -7.710823999999985 0, 110.249593 -7.710598999999931 0, 110.249598 -7.710357999999886 0, 110.249466 -7.710272999999958 0, 110.2492980000001 -7.710188999999936 0, 110.2490700000001 -7.710103999999919 0, 110.248249 -7.710072000999936 0, 110.2480530000001 -7.710104999999913 0, 110.2476010000001 -7.709968999999941 0, 110.2481710000001 -7.709701999999965 0, 110.2488220092559 -7.709092239264461 0, 110.2498684201416 -7.708542981231094 0, 110.2500000000001 -7.708524142999941 0, 110.2500000000001 -7.716666666499929 0, 110.2500000000001 -7.724999999499939 0, 110.2499999993334 -7.73328800066664 0))
bangunan = geopandas.read_file("/home/lenovo/Downloads/admin_sleman/BANGUNAN_PT_25K.shp")
print(bangunan.geometry[0])
POINT Z (110.224836558 -7.727023737999957 0)

Dan berikut contoh data sungaiyang berupa polyline/linestring:

sungai = geopandas.read_file("/home/lenovo/Downloads/admin_sleman/SUNGAI_LN_25K.shp")
print(sungai.geometry[0])
LINESTRING Z (110.4577371240001 -7.679254976999987 343.6000000000058, 110.458015124 -7.679722851999975 343.6000000000058, 110.4580798740001 -7.679839726999964 343.5209999999934, 110.4580750620001 -7.679904602000002 343.4829999999929, 110.4580115620001 -7.679954851999986 343.4349999999977, 110.4578659370001 -7.680066164999959 343.3270000000048, 110.4577916870001 -7.680094851999934 343.2810000000027, 110.4575729370001 -7.680131976999986 343.1499999999942, 110.4573740620001 -7.680159289999937 343.1499999999942, 110.4572989990001 -7.680163539999933 343.1499999999942, 110.4572750620001 -7.68030722699992 342.3399999999965, 110.4572234990001 -7.68046203999994 342.2700000000041, 110.4571721240001 -7.680552539999967 341.8600000000006, 110.457167499 -7.680556476999937 341.8300000000017, 110.4573087490001 -7.680821976999967 339.9499999999971, 110.4573494990001 -7.681079476999956 339.4100000000035, 110.4572979990001 -7.681351852000022 338.0299999999988, 110.4573689370001 -7.681661476999972 336.070000000007, 110.457482687 -7.681823101999933 334.7200000000012, 110.4576335620001 -7.682104976999897 333.9590000000026, 110.4577383120001 -7.682300789999934 333.429999999993, 110.4578310620001 -7.682477789999924 333.429999999993, 110.4579076870001 -7.682903914999921 332.8706999999995, 110.4579077490001 -7.682904476999967 332.8699999999953, 110.457908187 -7.682905664999977 332.8570000000036, 110.4579224370001 -7.682945101999954 332.4199999999983, 110.4579248120001 -7.682945414999979 332.1100000000006, 110.458134749 -7.683163914999939 330.599000000002, 110.458807937 -7.683864914999942 325.75, 110.4591709990001 -7.684177039999922 325.6300000000047)

Library shapely

Setiap geometry yang ada di dalam GeoDataFrame berupa shapely geometry

type(batas_admin.geometry[0])
shapely.geometry.multipolygon.MultiPolygon

membuat geometry shapely sendiri:

from shapely.geometry import Point, Polygon, LineString
p = Point(0, 0)
print(p)
POINT (0 0)
polygon = Polygon([(1, 1), (2,2), (2, 1)])
polygon.area
0.5

Untuk menghitung jarak antar geometry dapat menggunakan fungsi distance:

  • shapely_geometry.distance(shapely_geometry_lainnya) -> jarak antara 2 geometry shapely
  • GeoDataFrame.distance(shapely_geometry) -> jarak setiap feature dalam GeoDataFrame dengan shapely eometry

Misalnya jarak antara polygon dan titik yang dibuat sebelumnya:

polygon.distance(p)
1.4142135623730951

Memploting/menampilkan beberapa feature yang berbeda dalam satu layout

ax = batas_admin.plot(edgecolor='k', facecolor='none', figsize=(15, 10))
sungai.plot(ax=ax)
bangunan.plot(ax=ax, color='red')
ax.set(xlim=(110.35, 110.50), ylim=(-7.65, -7.55))
[(110.35, 110.5), (-7.65, -7.55)]

output_44_1

Membuat GeoDataFrame secara manual

geopandas.GeoDataFrame({
    'geometry': [Point(106, -7), Point(107, -6)],
    'atribut_1': [1, 2],
    'atribut_2': [0.1, 0.2]})
geometry atribut_1 atribut_2
0 POINT (106.00000 -7.00000) 1 0.1
1 POINT (107.00000 -6.00000) 2 0.2

Membuat GeoDataFrame dari Pandas DataFrame

Apabila pada DataFrame terdapat atribut koordinat maka dapat kita jadikan DataFrame tersebut menjadi GeoDataFrame seperti berikut:

  • Membuat DataFrame
df = pd.DataFrame(
    {'Desa': ['Sidorejo', 'Margoluwih', 'Sidoarum', 'Caturtunggal', 'Minomartani'],
     'Kecamatan': ['Godean', 'Seyegan', 'Sumberagung', 'Depok', 'Ngaglik'],
     'Latitude': [-7.65, -7.67, -7.7, -7.74, -7.74],
     'Longitude': [110, 110.1, 110.2, 110.4, 110.4]})
df
Desa Kecamatan Latitude Longitude
0 Sidorejo Godean -7.65 110.0
1 Margoluwih Seyegan -7.67 110.1
2 Sidoarum Sumberagung -7.70 110.2
3 Caturtunggal Depok -7.74 110.4
4 Minomartani Ngaglik -7.74 110.4
  • Mengubah DataFrame menjadi GeoDataFrame berdasarkan latitude dan longitude dengan fungsi points_from_xy dari geopandas
gdf = geopandas.GeoDataFrame(
    df, geometry=geopandas.points_from_xy(df.Longitude, df.Latitude))
gdf
Desa Kecamatan Latitude Longitude geometry
0 Sidorejo Godean -7.65 110.0 POINT (110.00000 -7.65000)
1 Margoluwih Seyegan -7.67 110.1 POINT (110.10000 -7.67000)
2 Sidoarum Sumberagung -7.70 110.2 POINT (110.20000 -7.70000)
3 Caturtunggal Depok -7.74 110.4 POINT (110.40000 -7.74000)
4 Minomartani Ngaglik -7.74 110.4 POINT (110.40000 -7.74000)

Related Articles

Membuat grid/Fishnet dengan Python

Saat akan melakukan survei ataupun analisis terkadang memerlukan grid. Grid atau Fishnet dapat dibuat dengan menggunakan python dengan menggunakan library

· 4 min read

Google Earth Engine untuk Pemodelan Kesesuaian Lokasi Budidaya Ikan Kerapu (GEE-015)

Sumberdaya perikanan di Indonesia sangat berlimpah dan dapat dimanfaatkan salah satunya untuk budidaya laut. Budidaya laut perlu didukung data lokasi

· 8 min read
Pengenalan GeoDjango (GDj-001)
· 1 min read