Commit 76c8e915 by dliangx

update

parent 7fe6dc89
......@@ -5,6 +5,8 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"time"
"com.dliangx.xplot/appserver/model"
......@@ -436,10 +438,86 @@ func GetRelatedAdmArea(obj model.GeoJson) ([]model.GeoJson, error) {
return results, err
}
func CalcAreasCenter(ids []string) (float64, float64, error) {
db, err := connectDB()
if err != nil {
return 0, 0, fmt.Errorf("database connection failed: %v", err)
}
defer db.Close()
// Convert string slice to comma separated string for SQL IN clause
idList := strings.Join(ids, ",")
var wktPoint string
err = db.QueryRow(`
SELECT
ST_AsText(ST_Centroid(ST_Collect(geom))) AS overall_centroid
FROM
geojson_data
WHERE id in (` + idList + `)
`).Scan(&wktPoint)
if err != nil {
if err == sql.ErrNoRows {
return 0, 0, fmt.Errorf("no areas found")
}
return 0, 0, fmt.Errorf("calculate center failed: %w", err)
}
// Parse WKT point string (format: "POINT(lon lat)")
wktPoint = strings.TrimPrefix(wktPoint, "POINT(")
wktPoint = strings.TrimSuffix(wktPoint, ")")
coords := strings.Split(wktPoint, " ")
if len(coords) != 2 {
return 0, 0, fmt.Errorf("invalid point format")
}
lon, err := strconv.ParseFloat(coords[0], 64)
if err != nil {
return 0, 0, fmt.Errorf("parse longitude failed: %w", err)
}
lat, err := strconv.ParseFloat(coords[1], 64)
if err != nil {
return 0, 0, fmt.Errorf("parse latitude failed: %w", err)
}
return lat, lon, nil
}
func CheckAreasCross(obj1, obj2 model.GeoJson) (bool, error) {
if obj1.Geometry == nil || obj2.Geometry == nil {
return false, errors.New("found no geometry")
return false, fmt.Errorf("invalid geometry: geometry cannot be nil")
}
db, err := connectDB()
if err != nil {
return false, fmt.Errorf("database connection failed: %v", err)
}
defer db.Close()
// 将两个 GeoJSON 转换为 WKT
geom1, err := json.Marshal(obj1.Geometry)
if err != nil {
return false, fmt.Errorf("marshal geometry 1 failed: %w", err)
}
geom2, err := json.Marshal(obj2.Geometry)
if err != nil {
return false, fmt.Errorf("marshal geometry 2 failed: %w", err)
}
var intersects bool
err = db.QueryRow(`
SELECT ST_Intersects(
ST_GeomFromGeoJSON($1),
ST_GeomFromGeoJSON($2)
)
`, string(geom1), string(geom2)).Scan(&intersects)
if err != nil {
return false, fmt.Errorf("check intersection failed: %w", err)
}
return false, nil
return intersects, nil
}
......@@ -3,6 +3,7 @@ package handler
import (
"context"
"strconv"
"strings"
"com.dliangx.xplot/appserver/geo"
"com.dliangx.xplot/appserver/model"
......@@ -178,6 +179,35 @@ func FindRelatedGeometry(ctx context.Context, c *app.RequestContext) {
}
func CalcAreasCenter(ctx context.Context, c *app.RequestContext) {
// 获取 ids 参数
idsStr := c.Query("ids")
if idsStr == "" {
c.JSON(consts.StatusBadRequest, utils.H{"message": "ids parameter required"})
return
}
// 分割 ids 字符串为数组
ids := strings.Split(idsStr, ",")
if len(ids) == 0 {
c.JSON(consts.StatusBadRequest, utils.H{"message": "invalid ids format"})
return
}
// 调用 geo.CalcAreasCenter 计算中心点
lat, lon, err := geo.CalcAreasCenter(ids)
if err != nil {
c.JSON(consts.StatusOK, utils.H{"code": 10012, "message": err.Error()})
return
}
// 返回结果
c.JSON(consts.StatusOK, utils.H{
"latitude": lat,
"longitude": lon,
})
}
func CheckTwoOptAreaIsCross(ctx context.Context, c *app.RequestContext) {
var req []model.GeoJson
err := c.BindAndValidate(&req)
......
......@@ -12,4 +12,5 @@ func Register(r *server.Hertz) {
r.DELETE("/geometry", handler.DeleteGeometry)
r.POST("/geometry/related", handler.FindRelatedGeometry)
r.POST("/geometry/check", handler.CheckTwoOptAreaIsCross)
r.POST("/geometry/calc_center", handler.CalcAreasCenter)
}
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