Commit 3d1511e4 by dliangx

导入山西村界地理数据

parent 1a206334
package geo
import (
"bufio"
"context"
"database/sql"
"encoding/json"
......@@ -46,7 +45,7 @@ func ProcessGeoJSONFile(filename string) 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)
}
......@@ -54,6 +53,7 @@ func createTable(db *sql.DB) error {
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS geojson_data (
id SERIAL PRIMARY KEY,
type VARCHAR(64),
geom geometry(Geometry,4326),
properties JSONB
)
......@@ -68,10 +68,36 @@ func processFile(filename string, db *sql.DB) error {
}
defer file.Close()
scanner := bufio.NewScanner(file)
const maxCapacity = 10 * 1024 * 1024 // 10MB
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
// 创建 JSON decoder
decoder := json.NewDecoder(file)
// 读取开始的 '{'
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()
......@@ -81,10 +107,11 @@ func processFile(filename string, db *sql.DB) error {
defer tx.Rollback()
count := 0
for scanner.Scan() {
// 逐个读取并处理特征
for decoder.More() {
var feature Feature
if err := json.Unmarshal(scanner.Bytes(), &feature); err != nil {
log.Printf("解析JSON失败: %v", err)
if err := decoder.Decode(&feature); err != nil {
log.Printf("解析特征失败: %v", err)
continue
}
......@@ -93,11 +120,15 @@ func processFile(filename string, db *sql.DB) error {
log.Printf("转换geometry失败: %v", err)
continue
}
propertiesJSON, err := json.Marshal(feature.Properties)
if err != nil {
log.Printf("转换properties失败: %v", err)
continue
}
_, err = tx.Exec(`
INSERT INTO geojson_data (geom, properties)
VALUES (ST_GeomFromGeoJSON($1), $2)
`, string(geometryJSON), feature.Properties)
INSERT INTO geojson_data (type, geom, properties)
VALUES ($1, ST_GeomFromGeoJSON($2), $3)
`, feature.Type, string(geometryJSON), string(propertiesJSON))
if err != nil {
log.Printf("插入数据失败: %v", err)
continue
......@@ -121,10 +152,6 @@ func processFile(filename string, db *sql.DB) error {
return err
}
if err := scanner.Err(); err != nil {
return err
}
log.Printf("总共处理 %d 条记录", count)
return nil
}
......
package geo
import "testing"
func TestInitProcessFile(t *testing.T) {
filename := "/Users/liang/Downloads/山西省村界.geojson"
ProcessGeoJSONFile(filename)
}
......@@ -13,6 +13,8 @@ import (
)
func main() {
filename := "/Users/liang/Downloads/山西省村界.geojson"
geo.ProcessGeoJSONFile(filename)
h := server.Default()
h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
......
......@@ -6,8 +6,6 @@ import (
geojson "github.com/paulmach/go.geojson"
)
type GeoData geojson.Feature
// FlyDefenseRoute 飞防路线
type OptRoute struct {
ID string `json:"id"` // 路线ID
......@@ -15,7 +13,7 @@ type OptRoute struct {
Type string `json:"type"`
Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"`
RouteLine geojson.Feature `json:"route_line"` // 路线坐标点 (PostGIS LineString)
RouteLine geojson.Geometry `json:"route_line"` // 路线坐标点 (PostGIS LineString)
}
// OptArea 作业区域
......@@ -25,6 +23,6 @@ type OptArea struct {
Type string `json:"type"`
Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"`
Area geojson.Feature `json:"area"` // 区域边界坐标点
Area geojson.Geometry `json:"area"` // 区域边界坐标点
RelatedAdmDds []string
}
......@@ -6,7 +6,7 @@ create table opt_routes (
type VARCHAR(64),
properties JSONB,
opt_time date,
route_line geometry(linestring,3005)
route_line geometry(linestring,4326)
);
drop table if EXISTS opt_area ;
......@@ -17,7 +17,7 @@ create table opt_area(
properties JSONB,
related_adm_ids text[],
opt_time date,
area geometry(multipolygon,3005)
area geometry(multipolygon,4326)
);
DROP table if EXISTS administrative_area;
......@@ -27,5 +27,5 @@ create table administrative_area(
parent int,
properties JSONB,
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