go实现获取地址的省市区域信息

以下代码,使用go语言借助百度地理位置服务,实现了获取地址的省市区域信息的功能。

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "strings"
    "unsafe"

    _ "github.com/go-sql-driver/mysql"
    "github.com/xuri/excelize/v2"
)

func main() {
    f, err := excelize.OpenFile("address.xlsx")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer func() {
        // Close the spreadsheet.
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()

    rows, err := f.GetRows("Sheet1")

    if err != nil {
        fmt.Println(err)
        return
    }

    total := len(rows) - 1
    successCount := 0
    wrongCount := 0
    result := make([]ReverseGeocodingResponse, 0, total)

    for i, row := range rows {
        if i > 0 {
            for j, colCell := range row {
                if j == 6 {
                    address := strings.TrimSpace(colCell)
                    success := false

                    if geoCodingResponse, err := GeoCoding(address); err != nil {
                        fmt.Println(err)
                    } else if geoCodingResponse.Status == 0 {
                        if reverseGeocodingResponse, err := ReverseGeocoding(*geoCodingResponse); err != nil {
                            fmt.Println(err)
                        } else if reverseGeocodingResponse.Status == 0 {
                            result = append(result, *reverseGeocodingResponse)

                            success = true
                        }
                    }

                    if success {
                        successCount += 1
                    } else {
                        wrongCount += 1
                    }
                }
            }

            fmt.Println()
        }
    }

    fmt.Println(total, successCount, wrongCount)

    if len(result) > 0 {
        if file, err := os.OpenFile("address.txt", os.O_APPEND|os.O_WRONLY, os.ModeAppend); err != nil {
            fmt.Println(err)
        } else {
            for _, item := range result {
                if _, err := io.WriteString(file, fmt.Sprintf("%s %s %s %s %s", item.Result.FormattedAddress, item.Result.AddressComponent.Province, item.Result.AddressComponent.City, item.Result.AddressComponent.District, item.Result.AddressComponent.Adcode)); err != nil {
                    fmt.Println(err)
                } else {
                    io.WriteString(file, "\n")
                }
            }

            file.Close()
        }
    }
}

func BytesToString(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

type GeoLocation struct {
    Lng float64 `json:"lng"`
    Lat float64 `json:"lat"`
}

type GeoCodingResult struct {
    Location      GeoLocation `json:"location"`
    Precise       int         `json:"precise"`
    Confidence    int         `json:"confidence"`
    Comprehension int         `json:"comprehension"`
    Level         string      `json:"level"`
}

type GeoCodingResponse struct {
    Status int             `json:"status"`
    Result GeoCodingResult `json:"result"`
}

const ak = ""
const geoCodingApiUrl = "https://api.map.baidu.com/geocoding/v3/"

var client = &http.Client{}

func GeoCoding(address string) (*GeoCodingResponse, error) {
    apiUrl, err := url.Parse(geoCodingApiUrl)

    if err != nil {
        fmt.Println(err)

        return nil, err
    }

    params := url.Values{}

    params.Set("address", address)
    params.Set("output", "json")
    params.Set("ak", ak)

    apiUrl.RawQuery = params.Encode()
    urlPath := apiUrl.String()

    if resp, err := client.Get(urlPath); err != nil {
        fmt.Println(err)

        return nil, err
    } else {
        body, _ := io.ReadAll(resp.Body)

        geoCodingResponse := &GeoCodingResponse{}

        if err := json.Unmarshal(body, &geoCodingResponse); err != nil {
            fmt.Println(err)

            return nil, err
        }

        return geoCodingResponse, nil
    }
}

type AddressComponent struct {
    Country         string `json:"country"`
    CountryCode     int    `json:"country_code"`
    CountryCodeIso  string `json:"country_code_iso"`
    CountryCodeIso2 string `json:"country_code_iso2"`
    Province        string `json:"province"`
    City            string `json:"city"`
    CityLevel       int    `json:"city_level"`
    District        string `json:"district"`
    Town            string `json:"town"`
    TownCode        string `json:"town_code"`
    Distance        string `json:"distance"`
    Direction       string `json:"direction"`
    Adcode          string `json:"adcode"`
    Street          string `json:"street"`
    StreetNumber    string `json:"street_number"`
}

type ReverseGeocodingResult struct {
    Location           GeoLocation      `json:"location"`
    FormattedAddress   string           `json:"formatted_address"`
    Business           string           `json:"business"`
    AddressComponent   AddressComponent `json:"addressComponent"`
    Pois               []interface{}    `json:"pois"`
    Roads              []interface{}    `json:"roads"`
    SematicDescription string           `json:"sematic_description"`
    CityCode           int              `json:"cityCode"`
}

type ReverseGeocodingResponse struct {
    Status int                    `json:"status"`
    Result ReverseGeocodingResult `json:"result"`
}

const reverseGeocodingApiUrl = "https://api.map.baidu.com/reverse_geocoding/v3/"

func ReverseGeocoding(geoCodingResponse GeoCodingResponse) (*ReverseGeocodingResponse, error) {
    apiUrl, err := url.Parse(reverseGeocodingApiUrl)

    if err != nil {
        fmt.Println(err)

        return nil, err
    }

    params := url.Values{}

    params.Set("location", fmt.Sprintf("%f,%f", geoCodingResponse.Result.Location.Lat, geoCodingResponse.Result.Location.Lng))
    params.Set("output", "json")
    params.Set("coordtype", "wgs84ll")
    params.Set("ak", ak)

    apiUrl.RawQuery = params.Encode()
    urlPath := apiUrl.String()

    if resp, err := client.Get(urlPath); err != nil {
        fmt.Println(err)

        return nil, err
    } else {
        body, _ := io.ReadAll(resp.Body)

        reverseGeocodingResponse := &ReverseGeocodingResponse{}

        if err := json.Unmarshal(body, &reverseGeocodingResponse); err != nil {
            fmt.Println(err)

            return nil, err
        }

        return reverseGeocodingResponse, nil
    }
}

你可能感兴趣的:(go实现获取地址的省市区域信息)