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 }