sql >> Database >  >> RDS >> Mysql

Werken met ruimtelijke gegevens met Gorm en MySQL

Hier is een andere benadering; gebruik binaire codering.

Volgens deze doc , MySQL slaat geometriewaarden op met behulp van 4 bytes om de SRID (Spatial Reference ID) aan te geven, gevolgd door de WKB-representatie (Well Known Binary) van de waarde.

Een type kan dus WKB-codering gebruiken en het voorvoegsel van vier bytes toevoegen en verwijderen in de functies Value() en Scan(). De go-geom-bibliotheek die in andere antwoorden wordt gevonden, heeft een WKB-coderingspakket, github.com/twpayne/go-geom/encoding/wkb.

Bijvoorbeeld:

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
}

Een tag definiëren met behulp van het MyPoint-type:

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

Een tag maken met het type:

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

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 zegt 4326 is de meest voorkomende ruimtelijke referentie voor het opslaan van referentiegegevens over de hele wereld. Het dient als de standaard voor zowel de ruimtelijke database van PostGIS als de GeoJSON-standaard. Het wordt ook standaard gebruikt in de meeste webkaartbibliotheken.)


  1. Nauwkeuriger rapporteren dan normaal – Microsoft Access

  2. als mijn tabel 4 kolommen heeft en ik wil de 3e kolom ophalen, wat moet ik dan doen.

  3. Hoe de waarden van de NLS-parameters in Oracle Database te controleren?

  4. Blanco pagina aan de Opencart-beheerderszijde