Commit c57d8515 by dliangx

圈地-路线检测

parent d5a72ec2
package geo
import "com.dliangx.xplot/appserver/model"
func SaveFlyDefenseRoute(flyDefenseRoute *model.FlyDefenseRoute) (string, error) {
return "", nil
}
func SaveAgrMachRoute(agriMachRoute *model.AgrMachRoute) (string, error) {
return "", nil
}
func SaveOptArea(optArea *model.OptArea) (string, error) {
return "", nil
}
func GetFlyDefenseRelatedArea(flyDefenseId string) ([]string, error) {
return []string{}, nil
}
func GetAgrMachRelatedArea(agriMachId string) ([]string, error) {
return []string{}, nil
}
func GetOptAreaRelatedAdmArea(optAreaId string) ([]string, error) {
return []string{}, nil
}
func CheckOptAreasCross(flyDefenseAreaId, agriMachAreaId string) (bool, error) {
return false, nil
}
package geo
import (
"bufio"
"context"
"database/sql"
"encoding/json"
"fmt"
"log"
"os"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
_ "github.com/lib/pq"
)
// Feature GeoJSON特征结构体
type Feature struct {
Id string `json:"id"`
Type string `json:"type"`
Geometry map[string]interface{} `json:"geometry"`
Properties map[string]interface{} `json:"properties"`
}
// ProcessGeoJSONFile 处理GeoJSON文件的主函数
func ProcessGeoJSONFile(filename string) error {
// 连接数据库
db, err := connectDB()
if err != nil {
return fmt.Errorf("database connection failed: %v", err)
}
defer db.Close()
// 创建表
if err := createTable(db); err != nil {
return fmt.Errorf("table creation failed: %v", err)
}
// 处理文件
if err := processFile(filename, db); err != nil {
return fmt.Errorf("file processing failed: %v", err)
}
return nil
}
func connectDB() (*sql.DB, error) {
connStr := "postgres://username:password@localhost/dbname?sslmode=disable"
return sql.Open("postgres", connStr)
}
func createTable(db *sql.DB) error {
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS geojson_data (
id SERIAL PRIMARY KEY,
geom geometry(Geometry,4326),
properties JSONB
)
`)
return err
}
func processFile(filename string, db *sql.DB) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
scanner := bufio.NewScanner(file)
const maxCapacity = 10 * 1024 * 1024 // 10MB
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
// 开始事务
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
count := 0
for scanner.Scan() {
var feature Feature
if err := json.Unmarshal(scanner.Bytes(), &feature); err != nil {
log.Printf("解析JSON失败: %v", err)
continue
}
geometryJSON, err := json.Marshal(feature.Geometry)
if err != nil {
log.Printf("转换geometry失败: %v", err)
continue
}
_, err = tx.Exec(`
INSERT INTO geojson_data (geom, properties)
VALUES (ST_GeomFromGeoJSON($1), $2)
`, string(geometryJSON), feature.Properties)
if err != nil {
log.Printf("插入数据失败: %v", err)
continue
}
count++
if count%1000 == 0 { // 每1000条提交一次事务
if err := tx.Commit(); err != nil {
return err
}
tx, err = db.Begin() // 开始新的事务
if err != nil {
return err
}
log.Printf("已处理 %d 条记录", count)
}
}
// 提交最后的事务
if err := tx.Commit(); err != nil {
return err
}
if err := scanner.Err(); err != nil {
return err
}
log.Printf("总共处理 %d 条记录", count)
return nil
}
func HandleProcessGeoJSON(ctx context.Context, c *app.RequestContext) {
var request struct {
FilePath string `json:"filepath"`
}
if err := c.BindJSON(&request); err != nil {
c.JSON(consts.StatusBadRequest, utils.H{"error": "invalid request body"})
return
}
if request.FilePath == "" {
c.JSON(consts.StatusBadRequest, utils.H{"error": "filepath is required"})
return
}
err := ProcessGeoJSONFile(request.FilePath)
if err != nil {
c.JSON(consts.StatusInternalServerError, utils.H{"error": err.Error()})
return
}
c.JSON(consts.StatusOK, utils.H{"message": "processing completed"})
}
module com.dliangx.xplot/app module com.dliangx.xplot/appserver
go 1.22.5 go 1.22.5
require github.com/cloudwego/hertz v0.9.2 require (
github.com/cloudwego/hertz v0.9.2
github.com/lib/pq v1.10.9
github.com/paulmach/go.geojson v1.5.0
)
require ( require (
github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect
...@@ -21,6 +25,7 @@ require ( ...@@ -21,6 +25,7 @@ require (
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/sys v0.17.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.27.1 // indirect google.golang.org/protobuf v1.27.1 // indirect
) )
...@@ -35,8 +35,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 ...@@ -35,8 +35,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg= github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg=
github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
github.com/paulmach/go.geojson v1.5.0 h1:7mhpMK89SQdHFcEGomT7/LuJhwhEgfmpWYVlVmLEdQw=
github.com/paulmach/go.geojson v1.5.0/go.mod h1:DgdUy2rRVDDVgKqrjMe2vZAHMfhDTrjVKt3LmHIXGbU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
...@@ -70,12 +74,14 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn ...@@ -70,12 +74,14 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
......
package handler
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
)
func SaveGeometry(ctx context.Context, c *app.RequestContext) {
}
func GetGeometry(ctx context.Context, c *app.RequestContext) {
}
func UpdateGeometry(ctx context.Context, c *app.RequestContext) {
}
func DeleteGeometry(ctx context.Context, c *app.RequestContext) {
}
func FindRelatedGeometry(ctx context.Context, c *app.RequestContext) {
}
func CheckTwoGeometryIsCross(ctx context.Context, c *app.RequestContext) {
}
...@@ -7,6 +7,9 @@ import ( ...@@ -7,6 +7,9 @@ import (
"github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils" "github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts" "github.com/cloudwego/hertz/pkg/protocol/consts"
"com.dliangx.xplot/appserver/geo"
"com.dliangx.xplot/appserver/route"
) )
func main() { func main() {
...@@ -16,5 +19,8 @@ func main() { ...@@ -16,5 +19,8 @@ func main() {
c.JSON(consts.StatusOK, utils.H{"message": "pong"}) c.JSON(consts.StatusOK, utils.H{"message": "pong"})
}) })
h.POST("/process-geojson", geo.HandleProcessGeoJSON)
route.Register(h)
h.Spin() h.Spin()
} }
package model
import (
"time"
geojson "github.com/paulmach/go.geojson"
)
type GeoData geojson.Feature
// FlyDefenseRoute 飞防路线
type FlyDefenseRoute struct {
ID string `json:"id"` // 路线ID
Name string `json:"name"` // 路线名称
Type string `json:"type"`
Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"`
RouteLine geojson.Feature `json:"route_line"` // 路线坐标点 (PostGIS LineString)
}
// AgrMachRoute 农机路线
type AgrMachRoute struct {
ID string `json:"id"` // 路线ID
Name string `json:"name"` // 路线名称
Type string `json:"type"`
Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"`
RouteLine geojson.Feature `json:"route_line"` // 路线坐标点
}
// OptArea 作业区域
type OptArea struct {
ID string `json:"id"` // 区域ID
Name string `json:"name"` // 区域名称
Type string `json:"type"`
Properties map[string]interface{} `json:"properties"`
OptTime time.Time `json:"opt_time"`
Area geojson.Feature `json:"area"` // 区域边界坐标点
RelatedAdmDds []string
}
package route
import (
"com.dliangx.xplot/appserver/handler"
"github.com/cloudwego/hertz/pkg/app/server"
)
func Register(r *server.Hertz) {
r.PUT("/geometry", handler.SaveGeometry)
r.GET("/geometry", handler.GetGeometry)
r.POST("/geometry", handler.UpdateGeometry)
r.DELETE("/geometry", handler.DeleteGeometry)
r.POST("/geometry/related", handler.FindRelatedGeometry)
r.POST("/geometry/check", handler.CheckTwoGeometryIsCross)
}
DROP table if EXISTS opt_agr_routes ;
create table opt_agr_routes (
id serial PRIMARY key,
name VARCHAR(64),
type VARCHAR(64),
properties JSONB,
opt_time DATE,
route_line geometry(Linestring,3005)
);
DROP table if EXISTS opt_fly_routes;
create table opt_fly_routes (
id serial PRIMARY key,
name VARCHAR(64),
type VARCHAR(64),
properties JSONB,
opt_time date,
route_line geometry(linestring,3005)
);
drop table if EXISTS opt_area ;
create table opt_area(
id serial PRIMARY key,
name VARCHAR(64),
type VARCHAR(64),
properties JSONB,
related_adm_ids text[],
opt_time date,
area geometry(multipolygon,3005)
);
DROP table if EXISTS administrative_area;
create table administrative_area(
id serial PRIMARY key,
name VARCHAR(64),
parent serial,
properties JSONB,
DEGREE int,
area geometry(multipolygon,3005)
);
CREATE EXTENSION postgis;
SELECT postgis_full_version();
DROP TABLE IF EXISTS "user";
CREATE TABLE "user" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_name" varchar(30) NOT NULL,
"phone_num" varchar(20) NOT NULL,
"salt" varchar(20) NOT NULL,
"password" varchar(32) NOT NULL,
"invite_type" varchar(16) NOT NULL,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "account";
CREATE TABLE "account" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" varchar(20) NOT NULL,
"open_code" varchar(255) NOT NULL,
"category" varchar(3),
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "permission";
CREATE TABLE "permission" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"parent_id" int4 ,
"category" varchar(3),
"name" varchar(30),
"value" varchar(255),
"status" bool,
"sort" int4,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "role";
CREATE TABLE "role" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"parent_id" int4 ,
"name" varchar(30),
"description" varchar(255),
"category" varchar(255),
"create_time" date,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "role_permission";
CREATE TABLE "role_permission" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"role_id" int4,
"permission_id" int4,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "user_role";
CREATE TABLE "user_role" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"role_id" int4 NOT NULL,
"user_id" int4 NOT NULL,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "suppliers";
CREATE TABLE "suppliers" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" int4 NOT NULL,
"type" varchar(3) NOT NULL,
"id_card" varchar(30) NOT NULL,
"id_card_front" varchar(255),
"id_card_back" varchar(255),
"legal_watchman" varchar(20),
"enterprise_name" varchar(100),
"enterprise_license" varchar(50),
"area" varchar(20),
"address" varchar(255),
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "land";
CREATE TABLE "land" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"land_code" varchar(50) NOT NULL,
"land_name" varchar(50) NOT NULL,
"land_area" float NOT NULL,
"user_id" int4 NOT NULL,
"user_name" varchar(30) NOT NULL,
"enterprise_name" varchar(100),
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "land_basic_info";
CREATE TABLE "land_basic_info" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"land_code" varchar(50) NOT NULL,
"land_name" varchar(50) NOT NULL,
"geom" geometry(point, 4326) NOT NULL,
"plant" varchar(50),
"variety" varchar(50),
"land_grade" varchar(30),
"land_type" varchar(30),
"land_area" float,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "land_plot_info";
CREATE TABLE "land_plot_info" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
DROP TABLE IF EXISTS "agriculture_layer";
CREATE TABLE "agriculture_layer" (
"id" int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"created_at" timestamp,
"updated_at" timestamp,
"deleted_at" timestamp NULL DEFAULT NULL ,
PRIMARY KEY ("id")
);
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