sql >> Database teknologi >  >> RDS >> Mysql

Arbejde med rumlige data med Gorm og MySQL

Her er en anden tilgang; brug binær kodning.

Ifølge denne dok , MySQL gemmer geometriværdier ved hjælp af 4 bytes til at angive SRID (Spatial Reference ID) efterfulgt af WKB-repræsentationen (Well Known Binary) af værdien.

Så en type kan bruge WKB-kodning og tilføje og fjerne de fire byte-præfikser i funktionerne Value() og Scan(). Go-geom-biblioteket, der findes i andre svar, har en WKB-kodningspakke, github.com/twpayne/go-geom/encoding/wkb.

For eksempel:

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
}

Definering af et tag ved hjælp af MyPoint-typen:

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

Oprettelse af et tag ved hjælp af typen:

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-resultater:

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 siger 4326 er den mest almindelige rumlige reference til lagring af referencedata i hele verden. Det fungerer som standard for både PostGIS rumlige database og GeoJSON standarden. Det bruges også som standard i de fleste webmapping-biblioteker.)


  1. Sikkerhedskopier en tabel med en GEOMETRY-kolonne ved hjælp af mysqldump?

  2. C# MySQL-fejl Kolonneantal stemmer ikke overens med værdiantallet i række 1

  3. Android:Hvordan importerer man kontakt fra telefonen?

  4. Advarsel:mysql_result() [function.mysql-result]:Kan ikke hoppe til række 0 på MySQL resultatindeks 5 i profile.php på linje 11