|
@@ -0,0 +1,440 @@
|
|
|
|
+package kpler
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "encoding/json"
|
|
|
|
+ "eta/eta_data_analysis/models"
|
|
|
|
+ "fmt"
|
|
|
|
+ "io/ioutil"
|
|
|
|
+ "net/http"
|
|
|
|
+ "net/url"
|
|
|
|
+ "strings"
|
|
|
|
+ "eta/eta_data_analysis/utils"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// 获取token登录凭证
|
|
|
|
+func login()(token string, err error){
|
|
|
|
+
|
|
|
|
+ url := "https://api.kpler.com/v1/login"
|
|
|
|
+ method := "POST"
|
|
|
|
+
|
|
|
|
+ payload := strings.NewReader(`{
|
|
|
|
+ "email": "` + utils.KplerApiAccount + `",
|
|
|
|
+ "password": "` + utils.KplerApiPassword + `"
|
|
|
|
+}`)
|
|
|
|
+
|
|
|
|
+ client := &http.Client {
|
|
|
|
+ }
|
|
|
|
+ req, err := http.NewRequest(method, url, payload)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ req.Header.Add("Content-Type", "application/json")
|
|
|
|
+
|
|
|
|
+ res, err := client.Do(req)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ defer res.Body.Close()
|
|
|
|
+
|
|
|
|
+ body, err := ioutil.ReadAll(res.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ fmt.Println(string(body))
|
|
|
|
+ //bodyStr := `{"token":"lfl883KgRgwsBg_yuHjv05vr6voK2ac8ju47jiUoR8ccs","user":{"accounts":["coal","lpg","lng","oil","cpp","merge","liquids"]}}`
|
|
|
|
+ //解析body
|
|
|
|
+ var result map[string]interface{}
|
|
|
|
+ err = json.Unmarshal(body, &result)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ token = result["token"].(string)
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 分别获取group为:Clean Products;Crude/Co; DPP)的产品
|
|
|
|
+func GetProductsByApi(params models.KplerProductLibReq, token string) (data []models.KplerProduct, err error) {
|
|
|
|
+ uri := "https://api.kpler.com/v1/products"
|
|
|
|
+ ancestorFamilyIds := url.QueryEscape(params.AncestorFamilyIds)
|
|
|
|
+ ancestorFamilyNames := url.QueryEscape(params.AncestorFamilyNames)
|
|
|
|
+ ancestorGroupIds := url.QueryEscape(params.AncestorGroupIds)
|
|
|
|
+ ancestorGroupNames := url.QueryEscape(params.AncestorGroupNames)
|
|
|
|
+ ancestorProductIds := url.QueryEscape(params.AncestorProductIds)
|
|
|
|
+ ancestorProductNames := url.QueryEscape(params.AncestorProductNames)
|
|
|
|
+ ancestorGradeIds := url.QueryEscape(params.AncestorGradeIds)
|
|
|
|
+ ancestorGradeNames := url.QueryEscape(params.AncestorGradeNames)
|
|
|
|
+ products := params.Products
|
|
|
|
+ productIds := params.ProductIds
|
|
|
|
+ uri = fmt.Sprintf("%s?ancestorFamilyIds=%s&ancestorFamilyNames=%s&ancestorGroupIds=%s&ancestorGroupNames=%s&ancestorProductIds=%s&ancestorProductNames=%s&ancestorGradeIds=%s&ancestorGradeNames=%s&products=%s&productIds=%s", uri, ancestorFamilyIds, ancestorFamilyNames, ancestorGroupIds, ancestorGroupNames, ancestorProductIds, ancestorProductNames, ancestorGradeIds, ancestorGradeNames, products, productIds)
|
|
|
|
+ method := "GET"
|
|
|
|
+
|
|
|
|
+ client := &http.Client {
|
|
|
|
+ }
|
|
|
|
+ req, err := http.NewRequest(method, uri, nil)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ req.Header.Add("Content-Type", "application/json")
|
|
|
|
+ req.Header.Add("Authorization", token)
|
|
|
|
+ res, err := client.Do(req)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ defer res.Body.Close()
|
|
|
|
+
|
|
|
|
+ body, err := ioutil.ReadAll(res.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ fmt.Println(string(body))
|
|
|
|
+ //bodystr := "Id (Product);Name;Type (Product);Family;Family Id;Group;Group Id;Product;Product Id;Grade;Grade Id;Density (Product);Density Unit;Energy Density;Energy Density Unit;Expansion Ratio
|
|
|
|
+// 2952;CPC Russia;grade;Dirty;1398;Crude/Co;1370;Crude;1368;CPC Russia;2952;805.0;kg/cm;26948.236;MJ/cm;1.0
|
|
|
|
+// 2953;CPC Kazakhstan;grade;Dirty;1398;Crude/Co;1370;Crude;1368;CPC Kazakhstan;2953;805.0;kg/cm;26948.236;MJ/cm;1.0
|
|
|
|
+// 1360;CPC;grade;Dirty;1398;Crude/Co;1370;Crude;1368;CPC;1360;805.0;kg/cm;26948.236;MJ/cm;1.0"
|
|
|
|
+// 解析body
|
|
|
|
+ var result map[string]interface{}
|
|
|
|
+ resErr := json.Unmarshal(body, &result)
|
|
|
|
+ if resErr == nil {
|
|
|
|
+ if result["message"] == "Unauthorized" {
|
|
|
|
+ fmt.Println("Unauthorized")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ err = fmt.Errorf(result["message"].(string))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 解析result
|
|
|
|
+ bodyStr := string(body)
|
|
|
|
+ lines := strings.Split(bodyStr, "\n")
|
|
|
|
+ for _, line := range lines {
|
|
|
|
+ fields := strings.Split(line, ";")
|
|
|
|
+ if len(fields) < 10 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ data = append(data, models.KplerProduct{
|
|
|
|
+ Id: fields[0],
|
|
|
|
+ Name: fields[1],
|
|
|
|
+ Type: fields[2],
|
|
|
|
+ Family: fields[3],
|
|
|
|
+ FamilyId: fields[4],
|
|
|
|
+ Group: fields[5],
|
|
|
|
+ GroupId: fields[6],
|
|
|
|
+ Product: fields[7],
|
|
|
|
+ ProductId: fields[8],
|
|
|
|
+ Grade: fields[9],
|
|
|
|
+ GradeId: fields[10],
|
|
|
|
+ Density: fields[11],
|
|
|
|
+ DensityUnit: fields[12],
|
|
|
|
+ EnergyDensity: fields[13],
|
|
|
|
+ EnergyDensityUnit: fields[14],
|
|
|
|
+ ExpansionRatio: fields[15],
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 根据flowDirection 和 products 循环调用
|
|
|
|
+func GetKplerDataByApi(params models.KplerFlowDataLibReq, token string) (ret *models.KplerFlowDataResp, err error) {
|
|
|
|
+ flowDirection := params.FlowDirection
|
|
|
|
+ granularity := params.Granularity
|
|
|
|
+ products := url.QueryEscape(params.Products)
|
|
|
|
+ split := url.QueryEscape(params.Split)
|
|
|
|
+ startDate := params.StartDate
|
|
|
|
+ endDate := params.EndDate
|
|
|
|
+ unit := params.Unit
|
|
|
|
+ withIntraRegion := params.WithIntraRegion
|
|
|
|
+ fromZones := url.QueryEscape(params.FromZones)
|
|
|
|
+ toZones := url.QueryEscape(params.ToZones)
|
|
|
|
+ onlyRealized := params.OnlyRealized
|
|
|
|
+ withForecast := params.WithForecast
|
|
|
|
+ withProductEstimation := params.WithProductEstimation
|
|
|
|
+ // fromInstallations := req.FromInstallations
|
|
|
|
+ // toInstallations := req.ToInstallations
|
|
|
|
+ // fromCountries := req.FromCountries
|
|
|
|
+ // toCountries := req.ToCountries
|
|
|
|
+ // vesselTypes := req.VesselTypes
|
|
|
|
+ // vesselTypesAlt := req.VesselTypesAlt
|
|
|
|
+ // withIntraCountry := req.WithIntraCountry
|
|
|
|
+ //
|
|
|
|
+ // withFreightView := req.WithFreightView
|
|
|
|
+
|
|
|
|
+ url := fmt.Sprintf("https://api.kpler.com/v1/flows?unit=%s&flowDirection=%s&granularity=%s&products=%s&split=%s&withIntraRegion=%s&startDate=%s&endDate=%s&fromZones=%s&toZones=%s&onlyRealized=%s&withForecast=%s&withProductEstimation=%s", unit, flowDirection, granularity, products, split, withIntraRegion, startDate, endDate, fromZones, toZones, onlyRealized, withForecast, withProductEstimation)
|
|
|
|
+ method := "GET"
|
|
|
|
+
|
|
|
|
+ client := &http.Client {
|
|
|
|
+ }
|
|
|
|
+ req, err := http.NewRequest(method, url, nil)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ req.Header.Add("Authorization", token)
|
|
|
|
+
|
|
|
|
+ res, err := client.Do(req)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ defer res.Body.Close()
|
|
|
|
+
|
|
|
|
+ body, err := ioutil.ReadAll(res.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ fmt.Println(string(body))
|
|
|
|
+ //{"message":"Unauthorized"}
|
|
|
|
+ // 解析body
|
|
|
|
+ var result map[string]interface{}
|
|
|
|
+ resErr := json.Unmarshal(body, &result)
|
|
|
|
+ if resErr == nil {
|
|
|
|
+ if result["message"] == "Unauthorized" {
|
|
|
|
+ fmt.Println("Unauthorized")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ err = fmt.Errorf(result["message"].(string))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// bodystr :=`Date;China;Period End Date
|
|
|
|
+// 2024-07;35763.15;2024-07-31
|
|
|
|
+// 2024-08;35386.42;2024-08-31
|
|
|
|
+// 2024-09;39657.10;2024-09-30
|
|
|
|
+// 2024-10;39909.08;2024-10-31
|
|
|
|
+// 2024-11;36541.03;2024-11-30
|
|
|
|
+// 2024-12;38551.49;2024-12-31
|
|
|
|
+// 2025-01;34607.56;2025-01-31
|
|
|
|
+// 2025-02;28280.53;2025-02-28
|
|
|
|
+// 2025-03;29965.73;2025-03-31
|
|
|
|
+// 2025-04;15157.51;2025-04-30
|
|
|
|
+// 2025-05;3795.25;2025-05-31
|
|
|
|
+// 2025-06;0;2025-06-30`
|
|
|
|
+
|
|
|
|
+ // 解析result
|
|
|
|
+ bodyStr := string(body)
|
|
|
|
+ lines := strings.Split(bodyStr, "\n")
|
|
|
|
+
|
|
|
|
+ // 解析lines
|
|
|
|
+ splitNameMap := make(map[int]string)
|
|
|
|
+ splitDataMap := make(map[int][]models.KplerBaseExcelData)
|
|
|
|
+ endDateCol := 0
|
|
|
|
+ for row, line := range lines {
|
|
|
|
+ fields := strings.Split(line, ";")
|
|
|
|
+ if len(fields) < 3 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ for col, field := range fields {
|
|
|
|
+ if col == 0 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // 处理表头
|
|
|
|
+ if row == 0 {
|
|
|
|
+ if field == "Period End Date" {
|
|
|
|
+ endDateCol = col
|
|
|
|
+ }else if field == "Date" {
|
|
|
|
+ continue
|
|
|
|
+ }else{
|
|
|
|
+ splitNameMap[col] = field
|
|
|
|
+ }
|
|
|
|
+ }else{
|
|
|
|
+ if col == endDateCol {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ date := fields[endDateCol]
|
|
|
|
+ value := fields[col]
|
|
|
|
+ splitDataMap[col] = append(splitDataMap[col], models.KplerBaseExcelData{
|
|
|
|
+ DataTime: date,
|
|
|
|
+ Value: value,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ data := make([]models.KplerFlowData, 0)
|
|
|
|
+ for col, name := range splitNameMap {
|
|
|
|
+ data = append(data, models.KplerFlowData{
|
|
|
|
+ SplitItem: name,
|
|
|
|
+ IndexData: splitDataMap[col],
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ ret = &models.KplerFlowDataResp{
|
|
|
|
+ List: data,
|
|
|
|
+ ApiQueryUrl: url,
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+func GetZonesByApi(token string, ancestorName string, descendantType string) (data []models.KplerZone, err error) {
|
|
|
|
+ //url := "https://api.kpler.com/v1/zones"
|
|
|
|
+ url := fmt.Sprintf("https://api.kpler.com/v1/zones?ancestorName=%s&descendantType=%s", ancestorName, descendantType)
|
|
|
|
+
|
|
|
|
+ method := "GET"
|
|
|
|
+
|
|
|
|
+ client := &http.Client {
|
|
|
|
+ }
|
|
|
|
+ req, err := http.NewRequest(method, url, nil)
|
|
|
|
+
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ req.Header.Add("Content-Type", "application/json")
|
|
|
|
+ req.Header.Add("Authorization", token)
|
|
|
|
+ res, err := client.Do(req)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ defer res.Body.Close()
|
|
|
|
+
|
|
|
|
+ body, err := ioutil.ReadAll(res.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ fmt.Println(string(body))
|
|
|
|
+// bodyStr := `Ancestor Id;Ancestor Name;Ancestor Type;Descendant Id;Descendant Name;Descendant Type
|
|
|
|
+// 87;Baltic Sea;gulf;1669;Kokkola;port
|
|
|
|
+// 87;Baltic Sea;gulf;1264;Stigsnaes;port
|
|
|
|
+// 87;Baltic Sea;gulf;110162;Uddevalla;port
|
|
|
|
+// 87;Baltic Sea;gulf;112012;Harnosand;port
|
|
|
|
+// 87;Baltic Sea;gulf;112945;Energihamnen;port
|
|
|
|
+// 87;Baltic Sea;gulf;112957;Falkenberg;port
|
|
|
|
+// 87;Baltic Sea;gulf;110567;Jakobstad;port
|
|
|
|
+// 87;Baltic Sea;gulf;112930;Sandefjord;port
|
|
|
|
+// 87;Baltic Sea;gulf;113141;Korsor;port
|
|
|
|
+// 87;Baltic Sea;gulf;3603;Inkoo;port
|
|
|
|
+// 87;Baltic Sea;gulf;112946;Skeppsbron;port
|
|
|
|
+// 87;Baltic Sea;gulf;112943;Vartahamnen;port
|
|
|
|
+// 87;Baltic Sea;gulf;112936;Solvesborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;3388;Pori;port
|
|
|
|
+// 87;Baltic Sea;gulf;112944;Stadsgarden;port
|
|
|
|
+// 87;Baltic Sea;gulf;1697;Nacka;port
|
|
|
|
+// 87;Baltic Sea;gulf;107545;Grenaa;port
|
|
|
|
+// 87;Baltic Sea;gulf;107515;Wismar;port
|
|
|
|
+// 87;Baltic Sea;gulf;2604;Vysotsk;port
|
|
|
|
+// 87;Baltic Sea;gulf;112752;Stockholm;port
|
|
|
|
+// 87;Baltic Sea;gulf;113125;Monsteras;port
|
|
|
|
+// 87;Baltic Sea;gulf;113161;Hirtshals;port
|
|
|
|
+// 87;Baltic Sea;gulf;116132;Trelleborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;1400;Lindø Industrial Park;port
|
|
|
|
+// 87;Baltic Sea;gulf;112013;Sandarne;port
|
|
|
|
+// 87;Baltic Sea;gulf;112011;Ornskoldsvik;port
|
|
|
|
+// 87;Baltic Sea;gulf;107089;Landskrona;port
|
|
|
|
+// 87;Baltic Sea;gulf;4689;Koping;port
|
|
|
|
+// 87;Baltic Sea;gulf;112745;Kaskinen;port
|
|
|
|
+// 87;Baltic Sea;gulf;112210;Vasteras;port
|
|
|
|
+// 87;Baltic Sea;gulf;112165;Kalmar;port
|
|
|
|
+// 87;Baltic Sea;gulf;112167;Paljassaare;port
|
|
|
|
+// 87;Baltic Sea;gulf;112152;Forby;port
|
|
|
|
+// 87;Baltic Sea;gulf;112194;Port of Koge;port
|
|
|
|
+// 87;Baltic Sea;gulf;112202;Lomonosov;port
|
|
|
|
+// 87;Baltic Sea;gulf;3423;Aarhus;port
|
|
|
|
+// 87;Baltic Sea;gulf;107591;Koloniya;port
|
|
|
|
+// 87;Baltic Sea;gulf;6812;Nyborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;113842;Halden;port
|
|
|
|
+// 87;Baltic Sea;gulf;1027;Porvoo;port
|
|
|
|
+// 87;Baltic Sea;gulf;116201;Nykobing Falster;port
|
|
|
|
+// 87;Baltic Sea;gulf;116181;Ostrand;port
|
|
|
|
+// 87;Baltic Sea;gulf;113276;Karlsborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;1651;Gdynia;port
|
|
|
|
+// 87;Baltic Sea;gulf;1102;Naantali;port
|
|
|
|
+// 87;Baltic Sea;gulf;112137;Drammen;port
|
|
|
|
+// 87;Baltic Sea;gulf;1165;Klaipeda;port
|
|
|
|
+// 87;Baltic Sea;gulf;6167;Hamina;port
|
|
|
|
+// 87;Baltic Sea;gulf;113292;Vastervik;port
|
|
|
|
+// 87;Baltic Sea;gulf;116242;Saetre;port
|
|
|
|
+// 87;Baltic Sea;gulf;116535;Frederikshavn;port
|
|
|
|
+// 87;Baltic Sea;gulf;1444;Aabenraa;port
|
|
|
|
+// 87;Baltic Sea;gulf;3725;Apatyth FSU;port
|
|
|
|
+// 87;Baltic Sea;gulf;1271;Primorsk;port
|
|
|
|
+// 87;Baltic Sea;gulf;1465;Karlshamn;port
|
|
|
|
+// 87;Baltic Sea;gulf;1399;Paldiski;port
|
|
|
|
+// 87;Baltic Sea;gulf;1684;Kemi;port
|
|
|
|
+// 87;Baltic Sea;gulf;1717;Vaasa;port
|
|
|
|
+// 87;Baltic Sea;gulf;110127;Nordjyllandsvaerket;port
|
|
|
|
+// 87;Baltic Sea;gulf;3467;Kiel;port
|
|
|
|
+// 87;Baltic Sea;gulf;4239;Kaliningrad;port
|
|
|
|
+// 87;Baltic Sea;gulf;3805;Loudden;port
|
|
|
|
+// 87;Baltic Sea;gulf;1404;Provestenen;port
|
|
|
|
+// 87;Baltic Sea;gulf;3403;Södertälje;port
|
|
|
|
+// 87;Baltic Sea;gulf;2002;Liepaja;port
|
|
|
|
+// 87;Baltic Sea;gulf;3389;Mussalo;port
|
|
|
|
+// 87;Baltic Sea;gulf;3407;Sundsvall;port
|
|
|
|
+// 87;Baltic Sea;gulf;3392;Halmstad;port
|
|
|
|
+// 87;Baltic Sea;gulf;2215;Raahe;port
|
|
|
|
+// 87;Baltic Sea;gulf;1334;Riga Harbour;port
|
|
|
|
+// 87;Baltic Sea;gulf;3381;Miiduranna;port
|
|
|
|
+// 87;Baltic Sea;gulf;1166;Gdansk;port
|
|
|
|
+// 87;Baltic Sea;gulf;107049;Oskarshamn;port
|
|
|
|
+// 87;Baltic Sea;gulf;3413;Holmsund;port
|
|
|
|
+// 87;Baltic Sea;gulf;3391;Rauma;port
|
|
|
|
+// 87;Baltic Sea;gulf;3393;Helsingborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;3438;Sjursoya;port
|
|
|
|
+// 87;Baltic Sea;gulf;1553;Rostock;port
|
|
|
|
+// 87;Baltic Sea;gulf;1155;Sillamäe;port
|
|
|
|
+// 87;Baltic Sea;gulf;3664;Szczecin;port
|
|
|
|
+// 87;Baltic Sea;gulf;1362;Malmo;port
|
|
|
|
+// 87;Baltic Sea;gulf;1104;Nynashamn;port
|
|
|
|
+// 87;Baltic Sea;gulf;1158;Butinge;port
|
|
|
|
+// 87;Baltic Sea;gulf;1700;Oulu;port
|
|
|
|
+// 87;Baltic Sea;gulf;5454;Slagen;port
|
|
|
|
+// 87;Baltic Sea;gulf;1477;Norrkoping;port
|
|
|
|
+// 87;Baltic Sea;gulf;6722;Kunda Bay;port
|
|
|
|
+// 87;Baltic Sea;gulf;6761;Pitea;port
|
|
|
|
+// 87;Baltic Sea;gulf;1020;Swinoujscie Area;port
|
|
|
|
+// 87;Baltic Sea;gulf;3426;Aalborg;port
|
|
|
|
+// 87;Baltic Sea;gulf;105360;Visby;port
|
|
|
|
+// 87;Baltic Sea;gulf;3151;Gavle;port
|
|
|
|
+// 87;Baltic Sea;gulf;1445;Oxelosund;port
|
|
|
|
+// 87;Baltic Sea;gulf;3411;Ronnskar;port
|
|
|
|
+// 87;Baltic Sea;gulf;113011;Husum;port
|
|
|
|
+// 87;Baltic Sea;gulf;2008;Lulea;port
|
|
|
|
+// 87;Baltic Sea;gulf;107538;Varberg;port
|
|
|
|
+// 87;Baltic Sea;gulf;107537;Orrskar;port
|
|
|
|
+// 87;Baltic Sea;gulf;4690;Uusikaupunki Port;port
|
|
|
|
+// 87;Baltic Sea;gulf;110094;Studstrup;port
|
|
|
|
+// 87;Baltic Sea;gulf;6723;Helsinki;port
|
|
|
|
+// 87;Baltic Sea;gulf;1028;St Petersburg;port
|
|
|
|
+// 87;Baltic Sea;gulf;107467;Valko;port
|
|
|
|
+// 87;Baltic Sea;gulf;116671;Skoghall;port
|
|
|
|
+// 87;Baltic Sea;gulf;2464;Ventspils;port
|
|
|
|
+// 87;Baltic Sea;gulf;113860;Soby Havn;port
|
|
|
|
+// 87;Baltic Sea;gulf;3382;Kopli;port
|
|
|
|
+// 87;Baltic Sea;gulf;1156;Muuga Harbour;port
|
|
|
|
+// 87;Baltic Sea;gulf;2601;Ust Luga;port`
|
|
|
|
+
|
|
|
|
+ // 解析result
|
|
|
|
+ bodyStr := string(body)
|
|
|
|
+ lines := strings.Split(bodyStr, "\n")
|
|
|
|
+ for i, line := range lines {
|
|
|
|
+ if i == 0 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ fields := strings.Split(line, ";")
|
|
|
|
+ if len(fields) < 6 {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ data = append(data, models.KplerZone{
|
|
|
|
+ AncestorId: fields[0],
|
|
|
|
+ AncestorName: fields[1],
|
|
|
|
+ AncestorType: fields[2],
|
|
|
|
+ DescendantId: fields[3],
|
|
|
|
+ DescendantName: fields[4],
|
|
|
|
+ DescendantType: fields[5],
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|