Mapbox で 路線を表示/色分けサンプル
やりたいこと
- 路線データを読み込んで、指定した路線をハイライトしたい
- その際、路線毎に色設定をできるようにしたい
- ついでに駅も表示する
以下のことに応用するため
- 公園の訪問済/未訪問
- 置いてある遊具の種類
前提
- 1: 国交省からデータ Download しておく
- https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-2024.html
- 鉄道路線データ ( N02-24_RailroadSection )
- 駅データ ( N02-24_Station )
- 2: Mapbox Studio で Tilesets として読み込んでおく
試したコード
以下の感じで出来そうに思うのだが、以下のエラーが出て、いまのところ うまく行ってない。
[Error, maps-ios/StyleDSL]: StyleError(rawValue: "[4]: Branch labels must be unique.")
データ的には重複していないので、バグでは・・?と思ってしまうが...
キーが日本語(非ASCII)だとダメだったりする・・?
swift
import SwiftUI
import MapboxMaps
struct MapboxView: View {
@State private var railwayColorMap: [String: UIColor] = [
"京王電鉄 京王線": UIColor(red: 0.71, green: 0.00, blue: 0.51, alpha: 1.0), // #b60081
"小田急電鉄 小田原線": UIColor(red: 0.00, green: 0.48, blue: 0.76, alpha: 1.0) // #007ac2
]
@State private var railwaysColorExp: [Exp.Argument] = []
var body: some View {
let center = CLLocationCoordinate2D(latitude: 35.6598, longitude: 139.702389)
let camera = Viewport.camera(center: center, zoom: 13, bearing: 0, pitch: 0)
Map(initialViewport: camera) {
VectorSource(id: "railways")
.url("mapbox://takaaki024.3eh769le")
VectorSource(id: "stations")
.url("mapbox://takaaki024.bjvj2vjl")
LineLayer(id: "railwaysLine", source: "railways")
.sourceLayer("N02-24_RailroadSection-ds3v9c")
.lineColor(
Exp(operator: .match, arguments: railwaysColorExp)
)
.lineWidth(3)
LineLayer(id: "stationsLine", source: "stations")
.sourceLayer("N02-24_Station-c3sj8l")
.lineColor(.gray)
.lineWidth(5)
SymbolLayer(id: "stationsText", source: "stations")
.sourceLayer("N02-24_Station-c3sj8l")
.textField(Exp(.get) { "N02_005" })
.textSize(12)
.textAnchor(.top)
.textOffset(x: 0, y: 0.5)
.textOpacity(
Exp(.switchCase) {
Exp(.inExpression) {
Exp(.concat) {
Exp(.get) { "N02_004" }
Exp(.literal) { " " }
Exp(.get) { "N02_003" }
}
railwayColorMap.keys.map { String($0) }
}
Exp(.literal) { 1 }
Exp(.literal) { 0 }
}
)
}
.ignoresSafeArea()
.onChange(of: railwayColorMap, initial: true) {
print("onChange!!")
var exp: [Exp.Argument] = []
exp.append(
.expression(Exp(.concat) {
Exp(.get) { "N02_004" }
Exp(.literal) { " " }
Exp(.get) { "N02_003" }
})
)
// not works
for key in railwayColorMap.keys.sorted() {
let color = railwayColorMap[key] ?? .lightGray
print("\(key) -> \(color)")
exp.append(.expression(Exp(.literal) { key }))
exp.append(.expression(Exp(.literal) { color }))
// ★ ここで break すると(つまり1種類だけなら) 通る
// ★ break しなかった場合は キー重複のエラーが出て動作しない。。なぜ。。
// > [Error, maps-ios/StyleDSL]: StyleError(rawValue: "[4]: Branch labels must be unique.")
// break
}
exp.append(.expression(Exp(.literal) { UIColor.lightGray }))
railwaysColorExp = exp
}
}
}