Mysql
 sql >> база данни >  >> RDS >> Mysql

Работа с пространствени данни с Gorm и MySQL

Ето още един подход; използвайте двоично кодиране.

Съгласно този doc , MySQL съхранява геометрични стойности, използвайки 4 байта, за да посочи SRID (Идентификатор на пространствена референция), последвано от WKB (Добре известно двоично) представяне на стойността.

Така че даден тип може да използва WKB кодиране и да добавя и премахва четирибайтовия префикс във функциите Value() и Scan(). Библиотеката go-geom, намерена в други отговори, има пакет за кодиране на WKB, github.com/twpayne/go-geom/encoding/wkb.

Например:

type MyPoint struct {
    Point wkb.Point
}

func (m *MyPoint) Value() (driver.Value, error) {
    value, err := m.Point.Value()
    if err != nil {
        return nil, err
    }

    buf, ok := value.([]byte)
    if !ok {
        return nil, fmt.Errorf("did not convert value: expected []byte, but was %T", value)
    }

    mysqlEncoding := make([]byte, 4)
    binary.LittleEndian.PutUint32(mysqlEncoding, 4326)
    mysqlEncoding = append(mysqlEncoding, buf...)

    return mysqlEncoding, err
}

func (m *MyPoint) Scan(src interface{}) error {
    if src == nil {
        return nil
    }

    mysqlEncoding, ok := src.([]byte)
    if !ok {
        return fmt.Errorf("did not scan: expected []byte but was %T", src)
    }

    var srid uint32 = binary.LittleEndian.Uint32(mysqlEncoding[0:4])

    err := m.Point.Scan(mysqlEncoding[4:])

    m.Point.SetSRID(int(srid))

    return err
}

Дефиниране на маркер с помощта на типа MyPoint:

type Tag struct {
    Name string   `gorm:"type:varchar(50);primary_key"`
    Loc  *MyPoint `gorm:"column:loc"`
}

func (t Tag) String() string {
    return fmt.Sprintf("%s @ Point(%f, %f)", t.Name, t.Loc.Point.Coords().X(), t.Loc.Point.Coords().Y())
}

Създаване на маркер с помощта на типа:

tag := &Tag{
    Name: "London",
    Loc: &MyPoint{
        wkb.Point{
            geom.NewPoint(geom.XY).MustSetCoords([]float64{0.1275, 51.50722}).SetSRID(4326),
        },
    },
}

err = db.Create(&tag).Error
if err != nil {
    log.Fatalf("create: %v", err)
}

Резултати от MySQL:

mysql> describe tag;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(50) | NO   | PRI | NULL    |       |
| loc   | geometry    | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+


mysql> select name, st_astext(loc) from tag;
+--------+------------------------+
| name   | st_astext(loc)         |
+--------+------------------------+
| London | POINT(0.1275 51.50722) |
+--------+------------------------+
  • (ArcGIS казва 4326 е най-често срещаната пространствена препратка за съхранение на референтни данни в целия свят. Той служи по подразбиране както за пространствената база данни PostGIS, така и за стандарта GeoJSON. Също така се използва по подразбиране в повечето библиотеки за уеб картографиране.)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL автоматично увеличаване на персонализираните стойности

  2. Възможно ли е това да се получи общ брой редове с ограничение за отместване

  3. Cheat Sheet за SQL команди – Как да научите SQL за 10 минути

  4. Изберете ред с най-новата дата на потребител

  5. JSON_OBJECTAGG() – Създайте JSON обект от резултатите от заявката в MySQL