Skip to main content

Mapbox で 路線を表示/色分けサンプル

やりたいこと

  • 路線データを読み込んで、指定した路線をハイライトしたい
  • その際、路線毎に色設定をできるようにしたい
  • ついでに駅も表示する

以下のことに応用するため

  • 公園の訪問済/未訪問
  • 置いてある遊具の種類

前提

試したコード

以下の感じで出来そうに思うのだが、以下のエラーが出て、いまのところ うまく行ってない。

[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
}
}
}