Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bekerja dengan data spasial dengan Gorm dan MySQL

Berikut pendekatan lain; gunakan pengkodean biner.

Menurut doc ini , MySQL menyimpan nilai geometri menggunakan 4 byte untuk menunjukkan SRID (Spatial Reference ID) diikuti dengan representasi nilai WKB (Well Known Binary).

Jadi suatu tipe dapat menggunakan penyandian WKB dan menambah dan menghapus awalan empat byte dalam fungsi Value() dan Scan(). Pustaka go-geom yang ditemukan di jawaban lain memiliki paket penyandian WKB, github.com/twpayne/go-geom/encoding/wkb.

Misalnya:

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
}

Mendefinisikan Tag menggunakan jenis 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())
}

Membuat tag menggunakan jenis:

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)
}

Hasil 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) |
+--------+------------------------+
  • (Kata ArcGIS 4326 adalah referensi spasial paling umum untuk menyimpan data referensi di seluruh dunia. Ini berfungsi sebagai default untuk database spasial PostGIS dan standar GeoJSON. Ini juga digunakan secara default di sebagian besar perpustakaan pemetaan web.)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah menggunakan Tabel Master untuk kolom bersama praktik yang baik untuk seluruh database?

  2. Model Yii dengan kunci primer komposit

  3. Bagaimana saya bisa mengulang hasil MySQL yang ditetapkan lebih dari sekali menggunakan fungsi mysql_*?

  4. jumlah yang berbeda (*)

  5. MySQL ke MS Access