Files
zmkgC/api/v1/common/source/mbt/mbt.go
2025-07-07 20:11:59 +08:00

124 lines
3.2 KiB
Go

package mbt
import (
"github.com/gogf/gf/v2/net/ghttp"
"github.com/tiger1103/gfast/v3/api/v1/common/globe"
"github.com/tiger1103/gfast/v3/api/v1/common/tool"
"github.com/tiger1103/gfast/v3/database"
"github.com/tiger1103/gfast/v3/database/sqlite"
"gorm.io/gorm"
"math"
"net/http"
"os"
"path"
"strings"
)
func InitMbtData(group *ghttp.RouterGroup) {
group.GET("/data/mbt/{source_id}/{z}/{x}/{y}.*", mbtCallback)
}
func mbtCallback(request *ghttp.Request) {
sourceId := request.Get("source_id").String()
mbtobj := database.GetSourceDB(sourceId)
if mbtobj.DB == nil {
request.Response.WriteStatus(http.StatusNotFound)
return
}
z := request.Get("z").Int()
x := request.Get("x").Int()
y := request.Get("y").Int()
y = int(math.Pow(2, float64(z))) - 1 - y
tile := Tile{}
RowsAffected := mbtobj.DB.Model(&Tile{}).
Select("tile_data").
Where(&Tile{ZoomLevel: z, TileColumn: x, TileRow: y}).First(&tile).RowsAffected
if RowsAffected > 0 {
request.Response.Header().Set("content-type", mbtobj.ContentType)
globe.RenderData(request, tile.TileData)
return
} else {
request.Response.WriteStatus(http.StatusNotFound)
}
}
type Tile struct {
TileData []byte `json:"tile_data"`
ZoomLevel int `json:"zoom_level"`
TileColumn int `json:"tile_column"`
TileRow int `json:"tile_row"`
}
type Metadata struct {
Name string
Value string
}
func OpenMbt(mbtPath string, sourceID string) (error, *database.SourceObj) {
//if !globe.IS_OFFLINE_VERSION {
// //网络版事 需要拼接数据地址,方便服务器迁移
// mbtPath = path.Join(globe.SOURCE, mbtPath)
//}
getwd, err := os.Getwd()
if err != nil {
return err, nil
}
mbtPath = path.Join(getwd, mbtPath)
if !tool.PathExists(mbtPath) {
return globe.GetErrors("资源不存在," + mbtPath), nil
}
db, err := sqlite.OpenDB(mbtPath)
if err != nil {
return err, nil
}
var obj database.SourceObj
obj.DB = db
obj.Type = globe.LAYER
var meta []Metadata
db.Model(&Metadata{}).Find(&meta)
obj.Info.MinLevel, obj.Info.MaxLevel = startQueryLevel(db)
var format = "png"
for _, v := range meta {
if v.Name == "format" {
format = v.Value
}
if v.Name == "bounds" {
arr := strings.Split(v.Value, ",")
obj.Info.West = arr[0]
obj.Info.South = arr[1]
obj.Info.East = arr[2]
obj.Info.North = arr[3]
}
if v.Name == "profile" {
obj.Info.ProFile = v.Value
}
if v.Name == "description" {
//lsv下载的 自带投影,此时不需要加
if strings.Contains(v.Value, "LSV") {
obj.Info.TilingScheme = 0
} else {
obj.Info.TilingScheme = 1
}
}
}
obj.ContentType = "image/" + format
obj.Url = "/zm/api/v1/data/mbt/" + sourceID + "/{z}/{x}/{y}." + format
database.SetSourceDB(sourceID, obj)
return err, &obj
}
func startQueryLevel(db *gorm.DB) (min, max int) {
zoom_level := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}
var existsLevels []int
for i := 0; i < len(zoom_level); i++ {
RowsAffected := db.Model(&Tile{}).Select("zoom_level").Where(&Tile{ZoomLevel: i}).Find(&Tile{}).RowsAffected
if RowsAffected > 0 {
existsLevels = append(existsLevels, i)
}
}
if len(existsLevels) > 0 {
min = existsLevels[0]
max = existsLevels[len(existsLevels)-1]
}
return
}