Commit 3d1511e4 by dliangx

导入山西村界地理数据

parent 1a206334
package geo package geo
import ( import (
"bufio"
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
...@@ -46,7 +45,7 @@ func ProcessGeoJSONFile(filename string) error { ...@@ -46,7 +45,7 @@ func ProcessGeoJSONFile(filename string) error {
} }
func connectDB() (*sql.DB, error) { func connectDB() (*sql.DB, error) {
connStr := "postgres://username:password@localhost/dbname?sslmode=disable" connStr := "postgres://liang:postgres@localhost/xpolt?sslmode=disable"
return sql.Open("postgres", connStr) return sql.Open("postgres", connStr)
} }
...@@ -54,6 +53,7 @@ func createTable(db *sql.DB) error { ...@@ -54,6 +53,7 @@ func createTable(db *sql.DB) error {
_, err := db.Exec(` _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS geojson_data ( CREATE TABLE IF NOT EXISTS geojson_data (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
type VARCHAR(64),
geom geometry(Geometry,4326), geom geometry(Geometry,4326),
properties JSONB properties JSONB
) )
...@@ -68,10 +68,36 @@ func processFile(filename string, db *sql.DB) error { ...@@ -68,10 +68,36 @@ func processFile(filename string, db *sql.DB) error {
} }
defer file.Close() defer file.Close()
scanner := bufio.NewScanner(file) // 创建 JSON decoder
const maxCapacity = 10 * 1024 * 1024 // 10MB decoder := json.NewDecoder(file)
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity) // 读取开始的 '{'
if _, err := decoder.Token(); err != nil {
return fmt.Errorf("读取文件开始标记失败: %v", err)
}
// 读取 "type" 字段
for decoder.More() {
token, err := decoder.Token()
if err != nil {
return fmt.Errorf("读取字段名失败: %v", err)
}
// 找到 "features" 数组开始
if key, ok := token.(string); ok && key == "features" {
// 读取数组开始标记 '['
if _, err := decoder.Token(); err != nil {
return fmt.Errorf("读取features数组开始标记失败: %v", err)
}
break
}
// 跳过其他字段的值(替换 Skip 方法)
_, err = decoder.Token()
if err != nil {
return fmt.Errorf("跳过字段值失败: %v", err)
}
}
// 开始事务 // 开始事务
tx, err := db.Begin() tx, err := db.Begin()
...@@ -81,10 +107,11 @@ func processFile(filename string, db *sql.DB) error { ...@@ -81,10 +107,11 @@ func processFile(filename string, db *sql.DB) error {
defer tx.Rollback() defer tx.Rollback()
count := 0 count := 0
for scanner.Scan() { // 逐个读取并处理特征
for decoder.More() {
var feature Feature var feature Feature
if err := json.Unmarshal(scanner.Bytes(), &feature); err != nil { if err := decoder.Decode(&feature); err != nil {
log.Printf("解析JSON失败: %v", err) log.Printf("解析特征失败: %v", err)
continue continue
} }
...@@ -93,11 +120,15 @@ func processFile(filename string, db *sql.DB) error { ...@@ -93,11 +120,15 @@ func processFile(filename string, db *sql.DB) error {
log.Printf("转换geometry失败: %v", err) log.Printf("转换geometry失败: %v", err)
continue continue
} }
propertiesJSON, err := json.Marshal(feature.Properties)
if err != nil {
log.Printf("转换properties失败: %v", err)
continue
}
_, err = tx.Exec(` _, err = tx.Exec(`
INSERT INTO geojson_data (geom, properties) INSERT INTO geojson_data (type, geom, properties)
VALUES (ST_GeomFromGeoJSON($1), $2) VALUES ($1, ST_GeomFromGeoJSON($2), $3)
`, string(geometryJSON), feature.Properties) `, feature.Type, string(geometryJSON), string(propertiesJSON))
if err != nil { if err != nil {
log.Printf("插入数据失败: %v", err) log.Printf("插入数据失败: %v", err)
continue continue
...@@ -121,10 +152,6 @@ func processFile(filename string, db *sql.DB) error { ...@@ -121,10 +152,6 @@ func processFile(filename string, db *sql.DB) error {
return err return err
} }
if err := scanner.Err(); err != nil {
return err
}
log.Printf("总共处理 %d 条记录", count) log.Printf("总共处理 %d 条记录", count)
return nil return nil
} }
......
package geo
import "testing"
func TestInitProcessFile(t *testing.T) {
filename := "/Users/liang/Downloads/山西省村界.geojson"
ProcessGeoJSONFile(filename)
}
...@@ -13,6 +13,8 @@ import ( ...@@ -13,6 +13,8 @@ import (
) )
func main() { func main() {
filename := "/Users/liang/Downloads/山西省村界.geojson"
geo.ProcessGeoJSONFile(filename)
h := server.Default() h := server.Default()
h.GET("/ping", func(ctx context.Context, c *app.RequestContext) { h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
......
...@@ -6,8 +6,6 @@ import ( ...@@ -6,8 +6,6 @@ import (
geojson "github.com/paulmach/go.geojson" geojson "github.com/paulmach/go.geojson"
) )
type GeoData geojson.Feature
// FlyDefenseRoute 飞防路线 // FlyDefenseRoute 飞防路线
type OptRoute struct { type OptRoute struct {
ID string `json:"id"` // 路线ID ID string `json:"id"` // 路线ID
...@@ -15,7 +13,7 @@ type OptRoute struct { ...@@ -15,7 +13,7 @@ type OptRoute struct {
Type string `json:"type"` Type string `json:"type"`
Properties map[string]interface{} `json:"properties"` Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"` OptTime time.Time `json:"opt_time"`
RouteLine geojson.Feature `json:"route_line"` // 路线坐标点 (PostGIS LineString) RouteLine geojson.Geometry `json:"route_line"` // 路线坐标点 (PostGIS LineString)
} }
// OptArea 作业区域 // OptArea 作业区域
...@@ -25,6 +23,6 @@ type OptArea struct { ...@@ -25,6 +23,6 @@ type OptArea struct {
Type string `json:"type"` Type string `json:"type"`
Properties map[string]interface{} `json:"properties"` Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"` OptTime time.Time `json:"opt_time"`
Area geojson.Feature `json:"area"` // 区域边界坐标点 Area geojson.Geometry `json:"area"` // 区域边界坐标点
RelatedAdmDds []string RelatedAdmDds []string
} }
...@@ -6,7 +6,7 @@ create table opt_routes ( ...@@ -6,7 +6,7 @@ create table opt_routes (
type VARCHAR(64), type VARCHAR(64),
properties JSONB, properties JSONB,
opt_time date, opt_time date,
route_line geometry(linestring,3005) route_line geometry(linestring,4326)
); );
drop table if EXISTS opt_area ; drop table if EXISTS opt_area ;
...@@ -17,7 +17,7 @@ create table opt_area( ...@@ -17,7 +17,7 @@ create table opt_area(
properties JSONB, properties JSONB,
related_adm_ids text[], related_adm_ids text[],
opt_time date, opt_time date,
area geometry(multipolygon,3005) area geometry(multipolygon,4326)
); );
DROP table if EXISTS administrative_area; DROP table if EXISTS administrative_area;
...@@ -27,5 +27,5 @@ create table administrative_area( ...@@ -27,5 +27,5 @@ create table administrative_area(
parent int, parent int,
properties JSONB, properties JSONB,
DEGREE int, DEGREE int,
area geometry(multipolygon,3005) area geometry(multipolygon,4326)
); );
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment