180 lines
5.7 KiB
Python
180 lines
5.7 KiB
Python
import json
|
|
from app.apiController import apiController
|
|
|
|
|
|
def swap_latlon(coords):
|
|
# return [[lon, lat] for lat, lon in coords]
|
|
# print(coords)
|
|
# return [
|
|
# [ [lon, lat] for lat, lon in ring ]
|
|
# for ring in coords
|
|
# ]
|
|
|
|
return [
|
|
[
|
|
[
|
|
[lon, lat] for lat, lon in ring
|
|
] for ring in polygon
|
|
] for polygon in coords
|
|
]
|
|
|
|
def swap_latlon2(coords):
|
|
try:
|
|
sample = coords[0][0][0]
|
|
lat, lon = sample
|
|
# if not (-180 <= sample[0] <= 180 and -90 <= sample[1] <= 90):
|
|
if -90 <= lat <= 90 and -180 <= lon <= 180:
|
|
return [
|
|
[
|
|
[
|
|
[lon, lat] for lat, lon in ring
|
|
] for ring in polygon
|
|
] for polygon in coords
|
|
]
|
|
else:
|
|
return coords
|
|
except Exception as e:
|
|
print(f"[swap_latlon] Error during coordinate swap: {e}")
|
|
return None
|
|
|
|
def normalize_to_multipolygon(coords):
|
|
if isinstance(coords, list):
|
|
if (
|
|
isinstance(coords[0], list)
|
|
and isinstance(coords[0][0], list)
|
|
and isinstance(coords[0][0][0], list)
|
|
and isinstance(coords[0][0][0][0], (int, float))
|
|
):
|
|
return coords # Sudah valid
|
|
else:
|
|
# Kurang dimensi → bungkus
|
|
return [[[coord for coord in ring] for ring in coords]]
|
|
return coords
|
|
|
|
def audit_geojson_paths(conn, table):
|
|
cur = conn.cursor()
|
|
cur.execute(f"SELECT id, path FROM {table}")
|
|
errors = []
|
|
for row in cur.fetchall():
|
|
try:
|
|
coords = json.loads(row[1])
|
|
sample_point = coords[0][0][0]
|
|
if not (-180 <= sample_point[0] <= 180 and -90 <= sample_point[1] <= 90):
|
|
errors.append(row[0])
|
|
except Exception as e:
|
|
errors.append(row[0])
|
|
# print(f"[AUDIT] Invalid GeoJSON paths found in {table}: {errors}")
|
|
return errors
|
|
|
|
#MAP DATA
|
|
#=========================================================
|
|
def fetch_geojson(conn, level, parent_code=None):
|
|
|
|
table_name = {
|
|
'provinsi': 'wil_provinsi',
|
|
'kabupaten': 'wil_kabupatenkota',
|
|
'kecamatan': 'wil_kecamatan',
|
|
'desa': 'wil_desa'
|
|
}.get(level)
|
|
|
|
if not table_name:
|
|
return {"type": "FeatureCollection", "features": []}
|
|
|
|
# Jalankan audit
|
|
# invalid_ids = audit_geojson_paths(conn, table_name)
|
|
|
|
cur = conn.cursor()
|
|
if level == 'provinsi':
|
|
old_sql = """
|
|
SELECT id, kode, nama, lat, lng,
|
|
CONCAT(
|
|
REPEAT('[', 4 - (LENGTH(path) - LENGTH(REPLACE(path, '[', '')))),
|
|
path,
|
|
REPEAT(']', 4 - (LENGTH(path) - LENGTH(REPLACE(path, ']', ''))))
|
|
) AS path
|
|
FROM wil_provinsi
|
|
"""
|
|
|
|
sql = """
|
|
SELECT
|
|
wp.id,
|
|
wp.kode,
|
|
wp.nama,
|
|
lat,
|
|
lng,
|
|
path,
|
|
pip.persen as idx
|
|
FROM wil_provinsi wp
|
|
JOIN vw_persentase_indeks_provinsi pip on pip.kode = wp.kode
|
|
WHERE lower(pip.status) in ('maju','mandiri')
|
|
"""
|
|
cur.execute(sql)
|
|
elif level == 'kabupaten':
|
|
cur.execute(""" SELECT wk.id, wk.kode, wk.nama,lat,wk.lng,wk.path, pik.persen_per_status as idx
|
|
FROM wil_kabupatenkota wk
|
|
JOIN vw_persentase_indeks_kabkota pik on pik.kode = wk.kode
|
|
WHERE provinsi_id = %s
|
|
""", (parent_code,))
|
|
elif level == 'kecamatan':
|
|
cur.execute("""
|
|
SELECT wkc.id, wkc.kode, wkc.nama,wkc.lat,wkc.lng,wkc.path , pic.persen as idx
|
|
FROM wil_kecamatan wkc
|
|
JOIN vw_persentase_indeks_kecamatan as pic on pic.id = wkc.id
|
|
WHERE kabupatenkota_id = %s""", (parent_code,))
|
|
elif level == 'desa':
|
|
cur.execute("""
|
|
SELECT wd.id, wd.kode, wd.nama, wd.lat, wd.lng,wd.path,
|
|
CASE
|
|
WHEN lower(mid.status) = 'mandiri' THEN 100
|
|
WHEN lower(mid.status) = 'maju' THEN 70
|
|
WHEN lower(mid.status) = 'berkembang' THEN 50
|
|
WHEN lower(mid.status) = 'tertinggal' THEN 20
|
|
WHEN lower(mid.status) = 'sangat tertinggal' THEN 0
|
|
END as idx
|
|
FROM wil_desa wd
|
|
JOIN metrik_indeks_desa mid on mid.kode_desa = wd.kode_int
|
|
WHERE kecamatan_id = %s""", (parent_code,))
|
|
else:
|
|
return {"type": "FeatureCollection", "features": []}
|
|
features = []
|
|
|
|
for row in cur.fetchall():
|
|
path = row[5]
|
|
|
|
#Multi poligons
|
|
try:
|
|
parsed_path = json.loads(path)
|
|
normalized = normalize_to_multipolygon(parsed_path)
|
|
corrected_path = swap_latlon2(normalized)
|
|
|
|
except Exception as e:
|
|
print(f"Error parsing path for row {row[0]}: {e}")
|
|
continue
|
|
|
|
if not corrected_path:
|
|
continue
|
|
|
|
geometry = {
|
|
"type": "MultiPolygon",
|
|
"coordinates": corrected_path
|
|
}
|
|
|
|
feature = {
|
|
"type": "Feature",
|
|
"geometry": geometry,
|
|
"properties": {
|
|
"id": row[0],
|
|
"kode": row[1],
|
|
"nama": row[2],
|
|
"lat": row[3],
|
|
"lng": row[4],
|
|
"idx": row[6]
|
|
}
|
|
}
|
|
features.append(feature)
|
|
|
|
return {
|
|
"type": "FeatureCollection",
|
|
"features": features
|
|
}
|