问题
I'm trying to extract geoJson values and store it to an array and listing array of values in a tableview to show the route in mapview. Here I am using Mapbox for mapview because it supports indoor navigation. Right now I am able to show routes in the mapview directly from geoJson file. But I need to extract values to an array for listing values in a tableview.
Here is the code I tried for extracting geoJson value:
Struct which I have created for extracting values:
struct Collection : Decodable {
let type : String
let features : [Feature]
}
struct Feature : Decodable {
let type : String
let properties : Properties
let geometry : Geometry
// there is also geometry
}
struct Properties : Decodable {
let name : String
}
struct Geometry : Decodable{
let coordinates: [CLLocationCoordinate2D]
}
Here is the code used for loading geoJson file:
func loadGeoJson() {
DispatchQueue.global().async {
// Get the path for example.geojson in the app’s bundle tbiMapbox.
guard let jsonUrl = Bundle.main.url(forResource: "newData", withExtension: "geojson") else { return }
guard let jsonData = try? Data(contentsOf: jsonUrl) else { return }
DispatchQueue.main.async {
self.drawPolyline(geoJson: jsonData)
print("data::\(jsonData)")
}
}
}
This function used drawing polylines for coordinates:
func drawPolyline(geoJson: Data) {
guard let style = self.mapView.style else { return }
let shapeFromGeoJSON = try! MGLShape(data: geoJson, encoding: String.Encoding.utf8.rawValue)
let source = MGLShapeSource(identifier: "polyline", shape: shapeFromGeoJSON, options: nil)
style.addSource(source)
let layer = MGLLineStyleLayer(identifier: "polyline", source: source)
layer.lineJoin = NSExpression(forConstantValue: "round")
layer.lineCap = NSExpression(forConstantValue: "round")
layer.lineColor = NSExpression(forConstantValue: UIColor(red: 59/255, green:178/255, blue:208/255, alpha:1))
layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
[14: 2, 18: 20])
let casingLayer = MGLLineStyleLayer(identifier: "polyline-case", source: source)
casingLayer.lineJoin = layer.lineJoin
casingLayer.lineCap = layer.lineCap
casingLayer.lineGapWidth = layer.lineWidth
casingLayer.lineColor = NSExpression(forConstantValue: UIColor(red: 41/255, green:145/255, blue:171/255, alpha:1))
casingLayer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
[14: 1, 18: 4])
let dashedLayer = MGLLineStyleLayer(identifier: "polyline-dash", source: source)
dashedLayer.lineJoin = layer.lineJoin
dashedLayer.lineCap = layer.lineCap
dashedLayer.lineColor = NSExpression(forConstantValue: UIColor.red)
dashedLayer.lineOpacity = NSExpression(forConstantValue: 0.5)
dashedLayer.lineWidth = layer.lineWidth
dashedLayer.lineDashPattern = NSExpression(forConstantValue: [0, 1.5])
style.addLayer(layer)
style.addLayer(dashedLayer)
style.insertLayer(casingLayer, below: layer)
}
For table view, right now i am loading static data:
var nameArray = [String]()
var coordinatesArray = [CLLocationCoordinate2D]()
var nameARR = ["1", "2", "3"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nameARR.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! newTableViewCell
cell.companyName.text = nameARR[indexPath.row]
return cell
}
And geoJson value I used:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
80.2226534485817,
12.871137160770251
],
[
80.22263333201408,
12.871145658917484
],
[
80.22264339029789,
12.871184881131773
],
[
80.2225998044014,
12.871194686684378
],
[
80.22260718047619,
12.87121625889878
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "Entrance - CZSM"
},
"geometry": {
"type": "LineString",
"coordinates": [
[
80.22256962954998,
12.87123848481471
],
[
80.22255957126617,
12.871204819088353
],
[
80.22259946912527,
12.871195013536129
],
[
80.22264305502176,
12.871184881131773
],
[
80.22263266146183,
12.871145658917484
],
[
80.22265445441008,
12.871135526511145
]
]
}
}
]
}
My question is 1.) How to extract values geoJson file? 2.) How to pass the extracted values to the tableview?, when tapping tableview cell, it perform segue and also pass the respected index of coordinates too.
回答1:
You can use this struct to parse the JSON you've posted:
struct Geodata: Codable {
let type: String
let features: [Feature]
}
struct Feature: Codable {
let type: String
let properties: Properties
let geometry: Geometry
}
struct Geometry: Codable {
let type: String
let coordinates: [[Double]]
}
struct Properties: Codable {
let name: String?
}
and parse it with something like
guard let jsonUrl = Bundle.main.url(forResource: "newData", withExtension: "geojson") else { return }
guard let jsonData = try? Data(contentsOf: jsonUrl) else { return }
do {
let geoData = try JSONDecoder().decode(Geodata.self, from: jsonData)
} catch {
print("\(error)")
}
来源:https://stackoverflow.com/questions/52706649/how-to-extract-values-from-geojson-file-and-pass-the-value-to-tableview-in-ios-s