Created
February 5, 2021 09:17
-
-
Save wangrenjun/6579c7c58bc8bfe26b47848fd68fadcd to your computer and use it in GitHub Desktop.
Go loading data and coordinates from GeoJson file to PostgreSQL using Gorm.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"io/ioutil" | |
"strconv" | |
"time" | |
geojson "github.com/paulmach/go.geojson" | |
"gorm.io/driver/postgres" | |
"gorm.io/gorm" | |
"gorm.io/gorm/logger" | |
) | |
func main() { | |
flag.Parse() | |
rawFeatureJSON, err := ioutil.ReadFile(*file) | |
if err != nil { | |
panic(err) | |
} | |
fc, err := geojson.UnmarshalFeatureCollection(rawFeatureJSON) | |
if err != nil { | |
panic(err) | |
} | |
gormdb := open() | |
for _, f := range fc.Features { | |
fmt.Printf("Name: %v\n\n", f.Properties["name"]) | |
fmt.Printf("Type: %v\n\n", f.Geometry.Type) | |
name := f.Properties["name"].(string) | |
switch { | |
case f.Geometry.Type == "Polygon": | |
coor := polygonCoordinates(f.Geometry.Polygon) | |
coor = fmt.Sprintf("POLYGON(%s)\n", coor) | |
insert(gormdb, name, coor) | |
case f.Geometry.Type == "GeometryCollection": | |
coor := "MULTIPOLYGON(" | |
for i := range f.Geometry.Geometries { | |
coor += "(" | |
coor += polygonCoordinates(f.Geometry.Geometries[i].Polygon) | |
coor += ")," | |
} | |
coor = coor[:len(coor)-1] | |
coor += ")" | |
insert(gormdb, name, coor) | |
break | |
default: | |
panic(f.Geometry.Type) | |
} | |
} | |
fmt.Printf("List the items just inserted:\n") | |
list(gormdb) | |
} | |
var dsn = flag.String("dsn", "", "PostgreSQL DSN") | |
var file = flag.String("file", "", ".geojson") | |
type Grid struct { | |
Id int64 `gorm:"primarykey"` | |
CreatedAt time.Time | |
UpdatedAt time.Time | |
DeletedAt gorm.DeletedAt `gorm:"index"` | |
Name string | |
} | |
func open() (gormdb *gorm.DB) { | |
gormdb, err := gorm.Open(postgres.Open(*dsn), &gorm.Config{ | |
Logger: logger.Default.LogMode(logger.Info), | |
}) | |
if err != nil { | |
panic(err) | |
} | |
gormdb.AutoMigrate(&Grid{}) | |
gormdb.Exec("ALTER TABLE grids ADD COLUMN IF NOT EXISTS geom geometry") | |
gormdb.Exec("CREATE INDEX IF NOT EXISTS grids_idx_geom ON grids USING GIST(geom)") | |
return | |
} | |
func insert(gormdb *gorm.DB, name, coor string) { | |
grid := Grid{ | |
Name: name, | |
} | |
tx := gormdb.Begin() | |
err := tx.Create(&grid).Error | |
if err != nil { | |
fmt.Printf("%s: %v\n", name, err) | |
tx.Rollback() | |
panic(err) | |
} | |
err = tx.Exec("UPDATE grids SET geom = '"+coor+"' WHERE id = ?", grid.Id).Error | |
if err != nil { | |
fmt.Printf("%s: %v\n", name, err) | |
tx.Rollback() | |
panic(err) | |
} | |
err = tx.Commit().Error | |
if err != nil { | |
fmt.Printf("%s: %v\n", name, err) | |
panic(err) | |
} | |
} | |
func list(gormdb *gorm.DB) { | |
rows, err := gormdb.Table("grids").Select("id, name, ST_AsGeojson(geom) AS coordinates").Rows() | |
if err != nil { | |
panic(err) | |
} | |
defer rows.Close() | |
for rows.Next() { | |
var id int64 | |
var name, coordinates string | |
rows.Scan(&id, &name, &coordinates) | |
fmt.Printf("%d: %s: %s\n", id, name, coordinates) | |
} | |
} | |
func polygonCoordinates(polygon [][][]float64) (coor string) { | |
for i := range polygon { | |
coor += "(" | |
for j := range polygon[i] { | |
if len(polygon[i][j]) > 1 { | |
long := strconv.FormatFloat(polygon[i][j][0], 'f', -1, 64) | |
lat := strconv.FormatFloat(polygon[i][j][1], 'f', -1, 64) | |
coor += long + " " + lat + "," | |
} | |
} | |
coor = coor[:len(coor)-1] | |
coor += ")," | |
} | |
coor = coor[:len(coor)-1] | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment