IMDF 格式的 GeoJSON
使用 python 或 ChatGPT 將 GeoJSON 轉換成 IMDF 格式
將 GeoJSON 轉換成 IMDF 格式
轉換前再來複習一下 IMDF 格式的 GeoJSON 長什麼樣子:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "1781b56b-0f31-47c7-ab06-e1dccdc5bc66",
"feature_type": "unit",
"properties": {
"category": "room",
"restriction": null,
"accessibility": null,
"name": {"en": "Electrical Substation Room", "zh": "變電機械"},
"alt_name": null,
"level_id": "2a59caed-8774-459a-8c4a-9b344530f52d",
"display_point": {
"type": "Point",
"coordinates": [121.5157129, 25.1227997]
}
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[121.5158181, 25.1228286],
[121.5158037, 25.1228279],
[121.5157679, 25.1228263],
// ...
[121.5158239, 25.1228288],
[121.5158239, 25.1228289],
[121.5158181, 25.1228286]
]
]
}
},
// ...
]
}{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "polygon/1",
"properties": {
"id": "polygon/1"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[121.51585576187, 25.12280734062],
[121.51588158151, 25.12280856371],
[121.51588293238, 25.12278518661],
[121.51585711274, 25.12278396352],
[121.51585576187, 25.12280734062]
]
]
}
},
{
"type": "Feature",
"id": "polygon/2",
"properties": {
"id": "polygon/2"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[121.51577082241, 25.12274772282],
[121.51580148958, 25.12274917554],
[121.51580487456, 25.12269059823],
[121.51577420739, 25.12268914551],
[121.51577082241, 25.12274772282]
]
]
}
},
{
"type": "Feature",
"id": "polygon/3",
"properties": {
"id": "polygon/3"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[121.51564830902, 25.12276841409],
[121.51569480425, 25.12277061659],
[121.51569650191, 25.12274123847],
[121.51565000668, 25.12273903597],
[121.51564830902, 25.12276841409]
]
]
}
},
// ...
]
}要注意填寫的欄位包含以下幾個:
| Prop | Type | Default |
|---|---|---|
geometry? | polygon | - |
display_point? | point | e.g. [121.5158815, 25.1228118] |
level_id? | string | e.g. "b2c99096-281b-4d6e-b8c9-8042a264609b" |
alt_name? | string | e.g. { "en": "Lift", "zh": "升降梯" } |
name? | string | e.g. { "en": "Elevator", "zh": "電梯" } |
accessibility? | array | null, ["wheelchair", "hearing_impaired",...] |
restriction? | string | null |
category? | string | e.g. room, restroom, elevator, etc. |
id? | string | uuid v4 |
如何轉換成 IMDF 格式
目前有兩種方式進行轉換,一種是使用 python 腳本,另一種是使用 ChatGPT 協助轉換。
使用 python 轉換格式
這邊可以使用 Google Colab 使用 python ,開始前先確定環境中已經有安裝 shapely 套件,如果沒有安裝可以使用以下指令安裝 shapely 套件。
pip install shapelyimport json
from shapely.geometry import Polygon
# 定義原始的 GeoJSON 資料
input_geojson = # 這裡是從 osm 轉換完的 geojson 資料
# 定義自訂的 level_id
custom_level_id = "your_custom_level_id" # 替換為你想要的 level_id
# 建立一個字典來儲存已計算過的中心點
centroid_cache = {}
# 構建新的 FeatureCollection
new_feature_collection = {
"type": "FeatureCollection",
"features": []
}
for feature in input_geojson.get('features', []):
geometry = feature.get('geometry', {})
if geometry.get('type') != 'LineString':
continue # 跳過非 LineString 的幾何
coordinates = geometry.get('coordinates', [])
# 確保 LineString 是閉合的
if coordinates[0] != coordinates[-1]:
coordinates.append(coordinates[0])
# 將 LineString 轉換為 Polygon
polygon_coords = [coordinates]
polygon = Polygon(polygon_coords[0])
# 檢查是否有效的多邊形
if not polygon.is_valid:
print(f"Invalid polygon for feature id {feature.get('id')}, skipping.")
continue
# 使用 tuple 作為字典的鍵
coords_key = tuple(map(tuple, polygon_coords[0]))
if coords_key in centroid_cache:
centroid = centroid_cache[coords_key]
else:
centroid_point = polygon.centroid
centroid = [centroid_point.x, centroid_point.y]
centroid_cache[coords_key] = centroid
# 建立新的 Feature,以下是 unit 的格式
new_feature = {
"type": "Feature",
"id": "",
"feature_type": "unit",
"properties": {
"category": "room", # 如果要轉換的是level 那就再調整這整個區域的格式
"restriction": None,
"accessibility": None,
"name": None,
"alt_name": None,
"level_id": custom_level_id,
"display_point": {
"type": "Point",
"coordinates": centroid
}
},
"geometry": {
"type": "Polygon",
"coordinates": polygon_coords
}
}
new_feature_collection["features"].append(new_feature)
# 將新的 FeatureCollection 輸出為 JSON 字串
output_json_str = json.dumps(new_feature_collection, ensure_ascii=False, indent=4)
print(output_json_str)# 這裡是從 osm 轉換完的 geojson 資料
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "way/-18201",
"properties": {
"id": "way/-18201"
},
"geometry": {
"type": "LineString",
"coordinates": [
[121.51363570737, 25.12042655345],
[121.51373230432, 25.12043076093],
[121.51373902734, 25.12030422816],
[121.51364243031, 25.12030002067],
[121.51363570737, 25.12042655345]
]
}
},
{
"type": "Feature",
"id": "way/-18238",
"properties": {
"id": "way/-18238"
},
"geometry": {
"type": "LineString",
"coordinates": [
[121.5136113667, 25.12042549325],
[121.51361486493, 25.12035965334],
[121.51346685566, 25.1203532065],
[121.51346335743, 25.12041904642],
[121.5136113667, 25.12042549325]
]
}
}
]
}{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "",
"feature_type": "unit",
"properties": {
"category": "room",
"restriction": null,
"accessibility": null,
"name": null,
"alt_name": null,
"level_id": "your_custom_level_id",
"display_point": {
"type": "Point",
"coordinates": [
121.51368736733507,
25.12036539079371
]
}
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
121.51363570737,
25.12042655345
],
[
121.51373230432,
25.12043076093
],
[
121.51373902734,
25.12030422816
],
[
121.51364243031,
25.12030002067
],
[
121.51363570737,
25.12042655345
]
]
]
}
},
{
"type": "Feature",
"id": "",
"feature_type": "unit",
"properties": {
"category": "room",
"restriction": null,
"accessibility": null,
"name": null,
"alt_name": null,
"level_id": "your_custom_level_id",
"display_point": {
"type": "Point",
"coordinates": [
121.51353911117812,
25.1203893498774
]
}
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
121.5136113667,
25.12042549325
],
[
121.51361486493,
25.12035965334
],
[
121.51346685566,
25.1203532065
],
[
121.51346335743,
25.12041904642
],
[
121.5136113667,
25.12042549325
]
]
]
}
}
]
}ChatGPT 協助轉換
因為一份 GeoJSON 檔案包含了許多 polygon 每個 polygon 都需要改成 IMDF 格式,所以我們再次請到 ChatGPT 協助我們。
將下面這份geojson依照,請你幫我依照以下的格式修改檔案,id欄位不用調整,
level_id改成"27771348-3f21-4563-9f8d-f4e6096a13c0",name欄位改成跟id一樣
,完整輸出一份geojson描述給我
格式:
{
"type": "Feature",
"id": "d67fdc22-e585-464f-b705-c8c205295200",
"feature_type": "unit",
"properties": {
"category": "room",
"restriction": null,
"accessibility": null,
"name": null,
"alt_name": null,
"level_id": "27771348-3f21-4563-9f8d-f4e6096a13c0",
"display_point": null
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[121.5158817, 25.1228084],
[121.5158814, 25.1228084],
[121.5158559, 25.1228072],
[121.5158572, 25.1227839],
[121.5158572, 25.1227838],
[121.515883, 25.122785],
[121.5158829, 25.122787],
[121.5158817, 25.1228084]
]
]
}
}
// 你的 GeoJSON 檔案在這裡
// ...基本上完成後就可以將這份 GeoJSON 檔案放到 IMDF 資料夾中,這樣就完成了一份 IMDF 格式的 GeoJSON 檔案,壓縮後丟進 IMDF Sandbox 就可以看到你的建築了。
manifest.json
venue.geojson
address.geojson
building.geojson
footprint.geojson
level.geojson
unit.geojson
amenity.geojson
opening.geojson