Konversi data GeoJSON ke PostgreSQL menggunakan Jupyter Notebook.

HidayatullahHidayatullah
4 min read

pada kali ini kita mencoba mengexport data GeoJSON ke PostgreSQL menggunakan Jupyter Notebook. Pastikan kita sudah menginstall module yang dibutuhkan, yang berada di import pada kode. Berikut kode fullnya.

import geopandas as gpd
from sqlalchemy import create_engine
import time

# 1. Baca Data GeoJSON
print("Membaca file GeoJSON...")
geojson_file = "data/clipped_roads_bandung_raya.geojson"  # Sesuaikan dengan lokasi file
gdf = gpd.read_file(geojson_file)
print("File GeoJSON berhasil dibaca.")

# 2. Tampilkan data untuk verifikasi
print("Preview Data:")
print(gdf.head())

# 3. Koneksi ke PostgreSQL
db_host = "host"       # atau IP VPS
db_port = "5432"
db_name = "geodb"
db_user = "postgres"
db_password = "password"

print("Menghubungkan ke database PostgreSQL...")
time.sleep(1)
engine = create_engine(f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}")
print("Koneksi berhasil.")

# 4. Simpan data ke PostgreSQL
table_name = "clipped_roads_bandung_raya"
print(f"Mengunggah data ke tabel {table_name} di PostgreSQL...")
gdf.to_postgis(table_name, engine, if_exists="replace", index=False)
print("Data berhasil diekspor ke PostgreSQL.")

hasilnya seperti berikut:

Membaca file GeoJSON...
File GeoJSON berhasil dibaca.
Preview Data:
       highway                      source  \
0  residential  kota_bandung_roads.geojson   
1  residential  kota_bandung_roads.geojson   
2        track  kota_bandung_roads.geojson   
3  residential  kota_bandung_roads.geojson   
4  residential  kota_bandung_roads.geojson   

                                            geometry  
0  LINESTRING (107.82797 -7.08511, 107.82799 -7.0...  
1  LINESTRING (107.82946 -7.08838, 107.82962 -7.0...  
2  LINESTRING (107.82996 -7.08776, 107.83015 -7.0...  
3  LINESTRING (107.82835 -7.08582, 107.82844 -7.0...  
4  LINESTRING (107.82934 -7.08075, 107.82947 -7.0...  
Menghubungkan ke database PostgreSQL...
Koneksi berhasil.
Mengunggah data ke tabel clipped_roads_bandung_raya di PostgreSQL...
Data berhasil diekspor ke PostgreSQL.

kemudian untuk memastikan data tablenya terlihat di jupyter, gunakan kode berikut:

import geopandas as gpd
from sqlalchemy import create_engine
import matplotlib.pyplot as plt
import time

db_host = "host"       # atau IP VPS
db_port = "5432"
db_name = "geodb"
db_user = "postgres"
db_password = "password"

print("Menghubungkan ke database PostgreSQL...")
time.sleep(1)
engine = create_engine(f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}")
print("Koneksi berhasil.")

# 2. Ambil data dari PostgreSQL dan tampilkan di Matplotlib
table_name = "clipped_roads_bandung_raya"
print("Mengambil data dari PostgreSQL untuk visualisasi...")
gdf_postgres = gpd.read_postgis(f"SELECT * FROM {table_name}", engine, geom_col="geometry")
print("Data berhasil diambil.")

# 3. Plot data dengan Matplotlib
print("Menampilkan peta...")
gdf_postgres.plot(figsize=(10, 8), edgecolor='black')
plt.title("Visualisasi Clipped Roads Bandung Raya")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.show()

dengan hasil datanya sebagai berikut:

atau lebih expert lagi, dengan tampilkan tipe highwanya

import geopandas as gpd
from sqlalchemy import create_engine
import matplotlib.pyplot as plt
import time

# Aktifkan inline plotting di Jupyter Notebook (hanya untuk Jupyter)
%matplotlib inline  

# Koneksi ke database PostgreSQL
db_host = "host"  # IP VPS atau localhost jika lokal
db_port = "5432"
db_name = "geodb"
db_user = "postgres"
db_password = "password"

print("Menghubungkan ke database PostgreSQL...")
time.sleep(1)
engine = create_engine(f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}")
print("Koneksi berhasil.")

# Ambil data dari PostgreSQL
table_name = "clipped_roads_bandung_raya"
print(f"Mengambil data dari tabel {table_name}...")
gdf_postgres = gpd.read_postgis(f"SELECT * FROM {table_name}", engine, geom_col="geometry")
print(f"Data berhasil diambil: {len(gdf_postgres)} baris.")

# Validasi data
gdf_postgres = gdf_postgres[gdf_postgres.geometry.is_valid]
print(f"Data setelah validasi: {len(gdf_postgres)} baris.")

# Pastikan kolom 'highway' ada
if 'highway' not in gdf_postgres.columns:
    print("Kolom 'highway' tidak ditemukan di tabel.")
    exit()

# Tampilkan daftar tipe jalan
unique_highways = gdf_postgres['highway'].unique()
print("\nDaftar tipe jalan yang tersedia dalam dataset:")
for i, highway in enumerate(unique_highways, 1):
    print(f"{i}. {highway}")

# Mapping warna berdasarkan tipe jalan (OSM highway)
highway_colors = {
    "motorway": "red",
    "trunk": "orange",
    "primary": "yellow",
    "secondary": "green",
    "tertiary": "blue",
    "unclassified": "gray",
    "residential": "purple",
    "service": "brown",
    "footway": "pink",
    "cycleway": "cyan",
    "path": "magenta",
}

# Beri warna default jika tipe jalan tidak ada di mapping
gdf_postgres["color"] = gdf_postgres["highway"].map(highway_colors).fillna("black")

# Plot semua dataset dengan legenda tipe jalan
fig, ax = plt.subplots(figsize=(15, 10))
legend_handles = []

for highway_type, color in highway_colors.items():
    subset = gdf_postgres[gdf_postgres["highway"] == highway_type]
    if not subset.empty:
        subset.plot(ax=ax, color=color, linewidth=1, label=highway_type)
        legend_handles.append(plt.Line2D([0], [0], color=color, lw=2, label=highway_type))

# Konfigurasi plot
plt.title("Visualisasi Clipped Roads Bandung Raya Berdasarkan Tipe Jalan")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.legend(handles=legend_handles, title="Tipe Jalan", loc="upper right", fontsize="small", bbox_to_anchor=(1.2, 1))

# Simpan hasil plot
output_file = "output_plot.png"
plt.savefig(output_file, dpi=300, bbox_inches="tight")
print(f"Gambar disimpan sebagai {output_file}")

# Tampilkan plot
plt.show()

dengan hasil sebagai berikut:

  • tambahan

    berikut kode untuk melihat tabel di postgresql

import geopandas as gpd
import pandas as pd
from sqlalchemy import create_engine

# Koneksi ke database
db_host = "host"
db_port = "5432"
db_name = "geodb"
db_user = "postgres"
db_password = "password"

engine = create_engine(f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}")

# Ambil data
table_name = "clipped_roads_bandung_raya"
query = f"SELECT * FROM {table_name} LIMIT 300;"  # Ambil 100 data
gdf_postgres = gpd.read_postgis(query, engine, geom_col="geometry")

# Menampilkan tabel mirip Excel di Jupyter Notebook
gdf_postgres.head(20).style.set_properties(**{
    'background-color': '#f6eee3',  # Warna latar belakang
    'border': '1px solid black',
    'color': 'black',
    'text-align': 'center'
})
1
Subscribe to my newsletter

Read articles from Hidayatullah directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Hidayatullah
Hidayatullah

Hi, my name is Hidayatullah. I am a GIS Engineer, Analyst, Specialist, and everything related to GIS. With over 5 years of experience, I am highly proficient in ArcGIS and QGIS. I specialize in spatial topology methods, least square adjustment measurement methods, PostGIS with PostgreSQL, RDBMS databases, spatial generalization by scale, WebGIS Geoserveer/Mapserver/Mapproxy, and more. If you're interested in my services, feel free to reach out via email at genhidayatullah@icloud.com.