topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • December 12, 2019, 12:13 AM
  • Proudly celebrating 13 years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: Reverse Geocoding in Go  (Read 446 times)

Tuxman

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 2,240
    • View Profile
    • Donate to Member
Reverse Geocoding in Go
« on: September 30, 2019, 05:20 AM »
From a project of mine:

I have a latitude and a longitude, e.g. from Google Maps or OSM, and I need a street name for that.

There is an API named Nominatim to solve this issue. Go code:

import (
    "fmt"
    "encoding/xml"
    "io/ioutil"
    "net/http"
)

// ...

type ReverseGeoCode struct {
    // <reversegeocode> mapping
    XMLName     xml.Name    `xml:"reversegeocode"`
    AdressParts AdressParts `xml:"addressparts"`
}

type AdressParts struct {
    // <adressparts> mapping
    XMLName      xml.Name   `xml:"addressparts"`
    HouseNumber  string     `xml:"house_number"`
    Road         string     `xml:"road"`
    Suburb       string     `xml:"suburb"`
    District     string     `xml:"city_district"`
    City         string     `xml:"city"`
    State        string     `xml:"state"`
    Postcode     string     `xml:"postcode"`
    Country      string     `xml:"country"`
    CountryCode  string     `xml:"country_code"`
}

func CheckError(err error) {
    if err != nil {
        panic(err)
    }
}

func GetXML(url string) ([]byte, error) {
    resp, err := http.Get(url)
    CheckError(err)
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return []byte{}, fmt.Errorf("Statusfehler: %v", resp.StatusCode)
    }

    data, err := ioutil.ReadAll(resp.Body)
    CheckError(err)

    return data, nil
}

func FindAddress(lat float32, lon float32) {
    url := fmt.Sprintf("https://nominatim.openstreetmap.org/reverse?lat=%s&lon=%s", lat, lon)
    xmlBytes, err := GetXML(url)

    CheckError(err)

    var xmlFile ReverseGeoCode
    xml.Unmarshal(xmlBytes, &xmlFile)

    adressData := xmlFile.AdressParts

    p1 := ""
    p2 := ""
    p3 := ""

    if adressData.Road != "" {
        p1 = fmt.Sprintf("%s %s, ", adressData.Road, adressData.HouseNumber)
    }

    if adressData.District != "" {
        p2 = fmt.Sprintf("%s, ", adressData.District)
    }

    if adressData.Postcode != "" {
        p3 = fmt.Sprintf("%s %s", adressData.Postcode, adressData.City)
    }

    location := fmt.Sprintf("%s%s%s", p1, p2, p3)

    // location has something like "John Doe Street 123, Random District, 12345 Imaginary City" now.
    // Save it or whatever.
}