Mendownload Fitur Polygon Bangunan dari OpenStreetMap

HidayatullahHidayatullah
3 min read

Kali ini kita akan mencoba mengunduh data dari OpenStreetMap berupa Polygon Bangunan. Kita akan coba gunakan Metode XMax dan Xmin, serta Y Max dan Y Min.

Pertama kali saudara Buka Jupyter Notebook nya dan Gunakan Script Berikut.

import os
import requests
import geopandas as gpd
from shapely.geometry import Polygon

# Folder penyimpanan data
data_folder = "data"
os.makedirs(data_folder, exist_ok=True)

# Query Overpass API berdasarkan bounding box
def fetch_osm_buildings_bbox(xmin, ymin, xmax, ymax):
    print(f"๐Ÿ“ฅ Mengunduh data bangunan dalam BBOX ({xmin}, {ymin}, {xmax}, {ymax})...")
    query = f"""
    [out:json];
    (
        way["building"]({ymin},{xmin},{ymax},{xmax});
    );
    out body; >; out skel qt;
    """
    url = "http://overpass-api.de/api/interpreter"
    response = requests.get(url, params={"data": query})

    if response.status_code == 200:
        data = response.json()
        if "elements" in data and len(data["elements"]) > 0:
            print(f"โœ… Data berhasil diunduh dalam BBOX ({xmin}, {ymin}, {xmax}, {ymax}).")
            return data
        else:
            print(f"โš ๏ธ Tidak ada data bangunan yang ditemukan dalam BBOX tersebut.")
    else:
        print(f"โŒ Gagal mengambil data dalam BBOX ({xmin}, {ymin}, {xmax}, {ymax}).")
    return None

# Konversi data dari Overpass API ke GeoDataFrame
def convert_buildings_to_gdf(osm_data):
    if not osm_data or "elements" not in osm_data:
        print("โš ๏ธ Data kosong atau tidak valid.")
        return None

    buildings = []
    nodes = {node["id"]: (node["lon"], node["lat"]) for node in osm_data["elements"] if node["type"] == "node"}

    for element in osm_data["elements"]:
        if element["type"] == "way" and "nodes" in element:
            coordinates = [nodes[node_id] for node_id in element["nodes"] if node_id in nodes]
            if len(coordinates) > 2 and coordinates[0] == coordinates[-1]:  # Pastikan poligon tertutup
                buildings.append({
                    "geometry": Polygon(coordinates),
                    "building": element.get("tags", {}).get("building", "unknown"),
                    "name": element.get("tags", {}).get("name", "unknown"),
                    "levels": element.get("tags", {}).get("building:levels", "unknown"),
                    "material": element.get("tags", {}).get("building:material", "unknown")
                })

    if not buildings:
        print("โš ๏ธ Tidak ada bangunan yang ditemukan dalam data OSM.")
        return None

    return gpd.GeoDataFrame(buildings, geometry="geometry", crs="EPSG:4326")

# Koordinat Bounding Box (sesuaikan dengan area yang diinginkan)
xmin, ymin, xmax, ymax = 107.60235, -6.91000, 107.63879, -6.88949  # Contoh BBOX di Kota Bandung

# Unduh dan simpan data
osm_data = fetch_osm_buildings_bbox(xmin, ymin, xmax, ymax)

if osm_data:
    gdf = convert_buildings_to_gdf(osm_data)

    if gdf is not None and not gdf.empty:
        file_path = os.path.join(data_folder, "buildings_bbox.geojson")
        gdf.to_file(file_path, driver="GeoJSON")
        print(f"๐Ÿ“ Data bangunan berhasil disimpan di: {file_path}")
    else:
        print(f"โš ๏ธ Tidak ada data yang dapat disimpan dalam BBOX tersebut.")

print("๐ŸŽ‰ Semua proses selesai!")

Pada xmin, ymin, xmax, ymax = , bisa teman-teman gunakan export yang disediakan oleh OpenStreetMap. Contohnya sebagai berikut:

lalu lakukan download, dan setelah berhasil data berada di folder data/buildings_bbox.geojson

untuk memastikan data yang tersedia itu benar-benar ada, gunakan code dibawah:

import geopandas as gpd
import folium
from folium.plugins import MarkerCluster
from IPython.display import display

# Baca file GeoJSON
file_path = "data/buildings_bbox.geojson"
gdf = gpd.read_file(file_path)

# Pastikan koordinat dalam EPSG:4326 (Latitude, Longitude)
gdf = gdf.to_crs(epsg=4326)

# Buat peta dengan pusat di Bandung
m = folium.Map(location=[-6.9175, 107.6191], zoom_start=12, tiles="CartoDB dark_matter")

# Tambahkan data bangunan sebagai GeoJson
folium.GeoJson(
    gdf,
    name="Bangunan",
    style_function=lambda feature: {
        "fillColor": "yellow",
        "color": "orange",
        "weight": 1,
        "fillOpacity": 0.5
    },
    tooltip=folium.GeoJsonTooltip(fields=["name", "building"], aliases=["Nama", "Tipe Bangunan"])
).add_to(m)

# Tambahkan kontrol layer
folium.LayerControl().add_to(m)

# Tampilkan peta di Jupyter Notebook
display(m)

Hasilnya sebagai berikut:

Demikianlah hasil unduhan yang telah berhasil dilakukan. Apabila data yang didownload lebih besar, disarankan untuk menggunakan Aplikasi GIS Desktop.

0
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.