GoLang数据库中以地理点类型存储的Lat Long值的存储和检索

kq0g1dla  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(167)

我尝试将纬度和经度值作为地理点数据类型保存到数据库中,并且希望能够相应地检索这些值。
我的模型设备Go看起来像这样
device.go

package models

import (
    "bytes"
    "database/sql/driver"
    "encoding/binary"
    "encoding/hex"
    "fmt"
    "time"

    "gorm.io/gorm"
)

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

func (p *GeoPoint) String() string {
    return fmt.Sprintf("SRID=4326;POINT(%v %v)", p.Lng, p.Lat)
}

// Scan implements the sql.Scanner interface.
func (p *GeoPoint) Scan(val interface{}) error {
    b, err := hex.DecodeString(string(val.(string)))
    if err != nil {
        return err
    }

    r := bytes.NewReader(b)
    var wkbByteOrder uint8
    if err := binary.Read(r, binary.LittleEndian, &wkbByteOrder); err != nil {
        return err
    }

    var byteOrder binary.ByteOrder
    switch wkbByteOrder {
    case 0:
        byteOrder = binary.BigEndian
    case 1:
        byteOrder = binary.LittleEndian
    default:
        return fmt.Errorf("invalid byte order %d", wkbByteOrder)
    }

    var wkbGeometryType uint32
    if err := binary.Read(r, byteOrder, &wkbGeometryType); err != nil {
        return err
    }

    if err := binary.Read(r, byteOrder, p); err != nil {
        return err
    }

    return nil
}

// Value impl.
func (p GeoPoint) Value() (driver.Value, error) {
    return p.String(), nil
}

type Device struct {
    gorm.Model
    Id                int       `json:"id" gorm:"primaryKey"`
    UserId            int       `json:"user_id" gorm:"uniqueIndex"`
    LatestLocation    GeoPoint  `json:"latest_location" gorm:"type:geography(POINT, 4326)"`
    CreatedAt         time.Time
    UpdatedAt         time.Time
}

我可以将数据保存到数据库中,这是数据库中的外观

但当我想检索记录与纬度和经度,我得到了错误的数据记录,我不知道为什么。
这是我密码
location.go

package apisLocation

import (
    "fmt"
    db "atm/pkg/configs/database"
    models "atm/pkg/models"
    "strconv"

    "github.com/gofiber/fiber/v2"
)

func GetLocation(c *fiber.Ctx) error {
    userId, err := strconv.Atoi(c.Params("userId"))
    if err != nil {
        return c.Status(400).JSON(err.Error())
    }

    if checkIfUserExists(userId) {
        return c.Status(400).JSON(fiber.Map{"error": "User does not exist"})
    }
    var device models.Device
    db.DB.Db.Find(&device, models.Device{UserId: userId})
    return c.Status(200).JSON(fiber.Map{"location": device.LatestLocation})
}

func checkIfUserExists(userId int) bool {
    var device models.Device
    db.DB.Db.Find(&device, models.Device{UserId: userId})
    return device.Id == 0
}

当我运行GetLocation方法时,得到的响应不准确,得到的值为

"location": {
        "lat": 1.7689674224598998e+71,
        "lng": -3.639753837714837e+173
    },

而不是保存在数据库中的经纬度。
我想不知何故,当它被解码时,一些东西发生了变化,但我不知道如何解决这个问题。
任何帮助都是感激不尽的

llycmphe

llycmphe1#

我在此处找到了解决您问题的方法https://github.com/go-pg/pg/issues/829#issuecomment-505882885
代码中的问题只是将wkbGeometryType声明为uint32,而不是uint64。

相关问题