Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Praca z danymi przestrzennymi z Gorm i MySQL

Oto inne podejście; użyj kodowania binarnego.

Zgodnie z tym doc , MySQL przechowuje wartości geometrii za pomocą 4 bajtów, aby wskazać SRID (Spatial Reference ID), po którym następuje reprezentacja wartości WKB (Well Known Binary).

Zatem typ może używać kodowania WKB oraz dodawać i usuwać czterobajtowy prefiks w funkcjach Value() i Scan(). Biblioteka go-geom znaleziona w innych odpowiedziach ma pakiet kodowania WKB, github.com/twpayne/go-geom/encoding/wkb.

Na przykład:

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
}

Definiowanie tagu za pomocą typu 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())
}

Tworzenie tagu przy użyciu typu:

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

Wyniki 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 mówi 4326 to najczęstsze odniesienie przestrzenne do przechowywania danych referencyjnych na całym świecie. Służy jako domyślna zarówno dla przestrzennej bazy danych PostGIS, jak i standardu GeoJSON. Jest również domyślnie używany w większości bibliotek map internetowych).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyświetl wszystkie ograniczenia klucza obcego dla całej bazy danych MySQL

  2. Pobierz dane MySQL w node.js (express) i drukuj za pomocą EJS

  3. Rozróżnianie wielkości liter w ograniczeniach „equals id” w ograniczeniach hibernacji

  4. Naprawdę potrzebujesz puli połączeń db do szyn jednorożca?

  5. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Nieznana kolumna „Smith” w „klauzula where”