Files
zmkgC/api/v1/common/shp/shp.go

255 lines
6.6 KiB
Go
Raw Normal View History

2025-07-07 20:11:59 +08:00
package shp
import (
"fmt"
"github.com/tomchavakis/turf-go"
"github.com/tiger1103/gfast/v3/api/v1/common/globe"
"github.com/tiger1103/gfast/v3/api/v1/common/tool"
"github.com/tiger1103/gfast/v3/api/v1/common/tool/shp"
"github.com/tomchavakis/geojson/geometry"
)
const (
DefaultColor = "#12f6f6"
DefaultWidth = "2"
)
type Point struct {
Lng float64 `json:"lng"`
Lat float64 `json:"lat"`
Alt float64 `json:"alt"` // 裝點更新 只更新這一個,更新立柱的高程時 這個字段不動
Width float64 `json:"width"`
Property
}
type Polyline struct {
Positions []Point `json:"positions"`
Width string `json:"width"`
Color string `json:"color"`
Alpha string `json:"alpha"`
Degree string `json:"degree"`
// Name string `json:"name"` // text
// Property string `json:"property"`
Range Box `json:"range"`
Property
}
type Polygon struct {
Positions []Point `json:"positions"`
Color string `json:"color"`
Range Box `json:"range"`
}
type Box struct {
MinX float64 `json:"min_x"`
MinY float64 `json:"min_y"`
MaxX float64 `json:"max_x"`
MaxY float64 `json:"max_y"`
}
type ShpObj struct {
Points []Point `json:"points"`
Polylines []Polyline `json:"polylines"`
Polygons []Polygon `json:"polygons"`
}
type Detail struct {
// Rotation []interfac e{} `json:"rotation"`
Position Point `json:"position"`
}
type Degree struct {
Position PointDegree `json:"position"`
}
type PointDegree struct {
Lng float64 `json:"lng"`
Lat float64 `json:"lat"`
Alt float64 `json:"alt"` // 裝點更新 只更新這一個,更新立柱的高程時 這個字段不動
Degree string `json:"degree"`
}
type Property struct {
Name string `json:"name"`
Beizhu string `json:"beizhu"`
Tishi string `json:"tishi"`
Height float64 `json:"height"` // 更新立柱的時 更新這個字段
Difference float64 `json:"difference"` // height - alt
SourceId string `json:"sourceId"`
}
/*读取shp数据*/
func ReadShp(file string) (error, *ShpObj) {
//if !globe.IS_OFFLINE_VERSION {
// file = globe.SOURCE + file
//}
if !tool.PathExists(file) {
return globe.GetErrors("资源不存在," + file), nil
}
shape, err := shp.Open(file)
if err != nil {
return err, nil
}
defer shape.Close()
obj := ShpObj{
Polygons: []Polygon{},
Polylines: []Polyline{},
Points: []Point{},
}
fields := shape.Fields()
for shape.Next() {
n, p := shape.Shape()
name := ""
beizhu := ""
tishi := ""
var O_LClr, O_LWidth, O_LAlpha /*, O_LType, O_SType, O_TType, O_Name, O_Comment*/ string
O_LClr = DefaultColor
O_LWidth = DefaultWidth
// Text := ""
for k, f := range fields {
val := shape.ReadAttribute(n, k)
bb := f.String()
// // 记录本次判断开始前的名字
// temp := name
switch bb {
// case "名称": // 方阵的名称
// if len(name) == 0 {
// name = val
// }
// case "TxtMemo": // 方阵的名称
// if len(name) == 0 {
// name = val
// }
case "name": // 方阵的名称
if len(name) == 0 {
name = val
}
// case "O_Name": // 方阵的名称
// if len(name) == 0 {
// name = val
// }
case "Text": // 方阵的名称
if len(name) == 0 {
name = val
}
case "备注": // 方阵的名称
beizhu = val
case "提示": // 方阵的名称
tishi = val
}
// 如果本次循环后名字被清空,则替换为原本的名字
// if name == "" {
// name = temp
// }
// fmt.Printf("\t%v: %v\n", f, val)
}
// fmt.Println(O_Name, O_Comment, O_LClr, O_LWidth, O_LAlpha, O_LType, O_SType, O_TType, Shape_Leng, Text, TxtMemo)
// fmt.Println("Text", Text)
// fmt.Println("O_Name", O_Name)
// fmt.Println("O_Comment", O_Comment)
// fmt.Println("O_LType", O_LType)
// fmt.Println("O_SType", O_SType)
// fmt.Println("O_TType", O_TType)
if p2, ok := p.(*shp.PolyLine); ok {
polyline := Polyline{}
polyline.Alpha = O_LAlpha
polyline.Color = O_LClr
polyline.Width = O_LWidth
polyline.Name = name
polyline.Range.MinX = p.BBox().MinX
polyline.Range.MinY = p.BBox().MinY
polyline.Range.MaxX = p.BBox().MaxX
polyline.Range.MaxY = p.BBox().MaxX
for _, po := range p2.Points {
point := Point{Lng: po.X, Lat: po.Y}
polyline.Positions = append(polyline.Positions, point)
}
obj.Polylines = append(obj.Polylines, polyline)
} else if p3, ok2 := p.(*shp.Polygon); ok2 {
polyline := Polyline{}
polyline.Alpha = O_LAlpha
polyline.Color = O_LClr
polyline.Width = O_LWidth
polyline.Name = name
polyline.Beizhu = beizhu
polyline.Tishi = tishi
// polyline.Property = Property
polyline.Range.MinX = p.BBox().MinX
polyline.Range.MinY = p.BBox().MinY
polyline.Range.MaxX = p.BBox().MaxX
polyline.Range.MaxY = p.BBox().MaxX
for _, po := range p3.Points {
point := Point{Lng: po.X, Lat: po.Y}
polyline.Positions = append(polyline.Positions, point)
}
obj.Polylines = append(obj.Polylines, polyline)
// fmt.Println(p3.Points)
} else if p3, ok3 := p.(*shp.Point); ok3 {
point := Point{Lng: p3.X, Lat: p3.Y}
point.Name = name
point.Tishi = tishi
point.Beizhu = beizhu
obj.Points = append(obj.Points, point)
} else if p3, ok2 := p.(*shp.PolygonZ); ok2 {
polyline := Polyline{}
polyline.Alpha = O_LAlpha
polyline.Color = O_LClr
polyline.Width = O_LWidth
polyline.Name = name
polyline.Beizhu = beizhu
polyline.Tishi = tishi
// polyline.Property = Property
polyline.Range.MinX = p.BBox().MinX
polyline.Range.MinY = p.BBox().MinY
polyline.Range.MaxX = p.BBox().MaxX
polyline.Range.MaxY = p.BBox().MaxX
for _, po := range p3.Points {
point := Point{Lng: po.X, Lat: po.Y}
polyline.Positions = append(polyline.Positions, point)
}
obj.Polylines = append(obj.Polylines, polyline)
// fmt.Println(p3.Points)
} else if p3, ok3 := p.(*shp.PointZ); ok3 {
point := Point{Lng: p3.X, Lat: p3.Y}
point.Name = name
point.Tishi = tishi
point.Beizhu = beizhu
obj.Points = append(obj.Points, point)
} else {
fmt.Println("其他类型")
}
}
return nil, &obj
}
/*判断点是否被区域包含*/
func PointInPolygon(point Point, positions []Point) (bool, error) {
if len(positions) < 3 {
return false, globe.GetErrors("坐标点数量不能小于3")
}
polygon := geometry.Polygon{}
var pts []geometry.Point
for _, position := range positions {
pts = append(pts, geometry.Point{Lat: position.Lat, Lng: point.Lng})
}
// pts = append(pts, pts[len(pts)-1])
LineString := geometry.LineString{}
LineString.Coordinates = pts
polygon.Coordinates = []geometry.LineString{LineString}
return turf.PointInPolygon(geometry.Point{Lat: point.Lat, Lng: point.Lng}, polygon)
}