[英]retrieving data from json response from an API
I'm trying to get data from json response by storing it in some structs (Airport + coordinates) but I don't know how to deal with that since I'm not good enough with maps and interfaces.我正在尝试通过将 json 响应存储在一些结构(机场+坐标)中来获取数据,但我不知道如何处理它,因为我对地图和接口不够好。 The code is showing no errors but MapofAirports is completely empty here is the code:
代码显示没有错误,但 MapofAirports 完全为空,代码如下:
package main
import (
//"api/client"
//"api/client/clienterrors"
//"api/client/openstreetmap"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"math"
"net/http"
"os"
"strconv"
"strings"
)
type Coordinates struct {
Longitude string `json:"lon"`
Latitude string `json:"lat"`
}
type Airport struct {
Co Coordinates `json:"location"`
IATACode string `json:"id"`
Distance float64 `json:"distance"` // distance to coordinates in kilometer
}
func GetCoordinatesFromURL(url string) (float64, float64) {
parts := strings.Split(url, "=")
lat0 := strings.Split(parts[2], "&")
lon0 := strings.Split(parts[3], "&")
lat1, _ := strconv.ParseFloat(lat0[0], 64)
lon1, _ := strconv.ParseFloat(lon0[0], 64)
return lat1, lon1
}
func CalcDistance(lat1 float64, long1 float64, lat2 float64, long2 float64) float64 {
var latitude1 = lat1 * math.Pi / 180
var latitude2 = lat2 * math.Pi / 180
var longitude1 = long1 * math.Pi / 180
var longitude2 = long2 * math.Pi / 180
var R = 6371.0
var d = R * math.Acos(math.Cos(latitude1)*math.Cos(latitude2)*math.Cos(longitude2-longitude1)+math.Sin(latitude1)*math.Sin(latitude2))
return d
}
func main() {
var Locations []Airport
Locations = make([]Airport, 0)
var url = fmt.Sprintf("https://api.skypicker.com/locations?type=radius&lat=40.730610&lon=-73.935242&radius=250&location_types=airport&limit=3&sort=id&active_only=true")
UrlLat, UrlLon := GetCoordinatesFromURL(url)
resp, err := http.Get(url)
if err != nil {
panic(err.Error())
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
var airportsJsonResponse interface{}
err = json.Unmarshal(body, &airportsJsonResponse)
MapofAirports, ok := airportsJsonResponse.([]interface{})
if ok {
lenAiroMap := len(MapofAirports)
locationsMaps := make(map[int]map[string]interface{})
for i := 0; i < lenAiroMap; i++ {
locationsMaps[i] = MapofAirports[i].(map[string]interface{})
}
var coords Coordinates
for i := 0; i < lenAiroMap; i++ {
if longitude, ok0 := locationsMaps[i]["lon"].(string); ok0 {
if latitude, ok1 := locationsMaps[i]["lat"].(string); ok1 {
coords = Coordinates{longitude, latitude}
}
}
code := locationsMaps[i]["id"].(string)
latFromCoordinates, _ := strconv.ParseFloat(Locations[i].Co.Latitude, 64)
lonFromCoordinates, _ := strconv.ParseFloat(Locations[i].Co.Longitude, 64)
dist := CalcDistance(latFromCoordinates, lonFromCoordinates, UrlLat, UrlLon)
Locations = append(Locations, Airport{
Co: coords,
IATACode: code,
Distance: dist,
})
}
}
LocationsJson, err := json.Marshal(Locations)
if err != nil {
log.Fatal("Cannot encode to JSON ", err)
}
fmt.Fprintf(os.Stdout, "%s", LocationsJson)
}
screenshot of json response json响应截图
in the screenshot this is the json response we have, and I'm processing like this:在屏幕截图中,这是我们收到的 json 响应,我正在这样处理:
{ locations[],meta,last_refresh,results_retrieved } ==> location : { id , location + distance(calculated with a function) }
Change this line MapofAirports, ok:= airportsJsonResponse.([]interface{})
to this将此行
MapofAirports, ok:= airportsJsonResponse.([]interface{})
更改为此
MapofAirports, ok := airportsJsonResponse.(map[string]interface{})
If you place a break point at this line you will see type of airportsJsonResponse
is map[string]interface{}
.如果您在此行放置一个断点,您将看到
airportsJsonResponse
的类型为map[string]interface{}
。 And you will have to change this lines into key value iteration你将不得不将此行更改为键值迭代
for i := 0; i < lenAiroMap; i++ {
locationsMaps[i] = MapofAirports[i].(map[string]interface{})
}
in to sth like below:像下面这样:
lenAiroMap := len(MapofAirports)
locationsMaps := make([]map[string]interface{},lenAiroMap)
for i, value := range MapofAirports["locations"].([]interface{}) {
converted := value.(map[string]interface{})
locationsMaps[i] = converted
}
this is my last update and while running the program it panics at unmarshaling step这是我的最后一次更新,在运行程序时它会在解组步骤中出现恐慌
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"math"
"net/http"
"strconv"
"strings"
)
type Coordinates struct {
Longitude string `json:"lon"`
Latitude string `json:"lat"`
}
type Airport struct {
Co Coordinates `json:"location"`
IATACode string `json:"id"`
Distance float64 `json:"distance"` // distance to coordinates in kilometer
}
type Response struct {
Locations []Airport `json:"locations"`
// add all the other fields you care about
}
func GetCoordinatesFromURL(url string) (float64, float64) {
parts := strings.Split(url, "=")
lat0 := strings.Split(parts[2], "&")
lon0 := strings.Split(parts[3], "&")
lat1, _ := strconv.ParseFloat(lat0[0], 64)
lon1, _ := strconv.ParseFloat(lon0[0], 64)
return lat1, lon1
}
func CalcDistance(lat1 float64, long1 float64, lat2 float64, long2 float64) float64 {
var latitude1 = lat1 * math.Pi / 180
var latitude2 = lat2 * math.Pi / 180
var longitude1 = long1 * math.Pi / 180
var longitude2 = long2 * math.Pi / 180
var R = 6371.0
var d = R * math.Acos(math.Cos(latitude1)*math.Cos(latitude2)*math.Cos(longitude2-longitude1)+math.Sin(latitude1)*math.Sin(latitude2))
return d
}
func main() {
var url = fmt.Sprintf("https://api.skypicker.com/locations?type=radius&lat=40.730610&lon=-73.935242&radius=250&location_types=airport&limit=3&sort=id&active_only=true")
UrlLat, UrlLon := GetCoordinatesFromURL(url)
resp, err := http.Get(url)
if err != nil {
panic(err.Error())
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
res := &Response{}
if err := json.Unmarshal(data, res); err != nil {
panic(err)
}
fmt.Println(res.Locations)
for i, item := range res.Locations {
latt,_ := strconv.ParseFloat(item.Co.Latitude, 64)
lonn,_ :=strconv.ParseFloat(item.Co.Longitude, 64)
res.Locations[i].Distance = CalcDistance(latt,lonn , UrlLat, UrlLon)
}
fmt.Println("after calculate distance")
fmt.Println(res.Locations)
}
what's wrong with that?那有什么问题?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.