feat: 将地图服务切换至service

This commit is contained in:
zhouxhere 2025-06-14 18:02:27 +08:00
parent a4f49c7ee0
commit 02cb24f3e4
9 changed files with 111 additions and 20 deletions

View File

@ -65,9 +65,6 @@ func NewAPI(e *echo.Echo, s *store.Store) {
return c.Redirect(http.StatusMovedPermanently, "/swagger/index.html") return c.Redirect(http.StatusMovedPermanently, "/swagger/index.html")
}) })
// style
api.Static("/style", "./style")
api.Register() api.Register()
for _, route := range api.Routes() { for _, route := range api.Routes() {

View File

@ -10,6 +10,7 @@ import (
"git.zhouxhere.com/zhouxhere/maptile/api" "git.zhouxhere.com/zhouxhere/maptile/api"
"git.zhouxhere.com/zhouxhere/maptile/config" "git.zhouxhere.com/zhouxhere/maptile/config"
"git.zhouxhere.com/zhouxhere/maptile/service"
"git.zhouxhere.com/zhouxhere/maptile/store" "git.zhouxhere.com/zhouxhere/maptile/store"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -34,6 +35,7 @@ func NewServer(ctx context.Context, config *config.Config, store *store.Store) *
echoServer := echo.New() echoServer := echo.New()
api.NewAPI(echoServer, store) api.NewAPI(echoServer, store)
service.NewMapService(echoServer, store)
addr := fmt.Sprintf("%s:%d", config.Addr, config.Port) addr := fmt.Sprintf("%s:%d", config.Addr, config.Port)
s.httpServer = &http.Server{ s.httpServer = &http.Server{

8
service/geojson.go Normal file
View File

@ -0,0 +1,8 @@
package service
import "github.com/labstack/echo/v4"
func (s *MapService) GetGeoJSONByName(c echo.Context) error {
return c.JSON(200, "ok")
}

75
service/map.go Normal file
View File

@ -0,0 +1,75 @@
package service
import (
"context"
"fmt"
"log/slog"
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
_ "git.zhouxhere.com/zhouxhere/maptile/docs"
"git.zhouxhere.com/zhouxhere/maptile/store"
)
type MapService struct {
*echo.Echo
store *store.Store
}
func NewMapService(e *echo.Echo, s *store.Store) {
service := &MapService{e, s}
service.Use(middleware.Recover())
service.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{LogStatus: true,
LogURI: true,
LogError: true,
HandleError: true, // forwards error to the global error handler, so it can decide appropriate status code
LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
if v.Error != nil {
slog.LogAttrs(context.Background(), slog.LevelError, "REQUEST", slog.String("method", v.Method), slog.String("uri", v.URI), slog.Int("status", v.Status), slog.String("latency", v.Latency.String()), slog.String("error", v.Error.Error()))
} else {
slog.LogAttrs(context.Background(), slog.LevelInfo, "REQUEST", slog.String("method", v.Method), slog.String("uri", v.URI), slog.Int("status", v.Status), slog.String("latency", v.Latency.String()))
}
return nil
},
}))
service.HTTPErrorHandler = func(err error, c echo.Context) {
req := c.Request()
slog.LogAttrs(context.Background(), slog.LevelError, "REQUEST", slog.String("method", req.Method), slog.String("uri", req.RequestURI), slog.String("error", err.Error()))
c.JSON(http.StatusOK, err)
}
service.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete},
// AllowHeaders: []string{"Content-Type", "Authorization"},
}))
service.Register()
for _, route := range service.Routes() {
fmt.Println(route.Method, route.Path)
}
}
func (s *MapService) Register() {
group := s.Group("/map")
// style
group.Static("/style", "./style")
// mbtiles
group.GET("/mbtiles/:name", s.GetMBTilesByName)
group.GET("/mbtiles/:name/:z/:x/:y", s.GetMBTilesByNameAndZAndXAndY)
// pmtiles
group.GET("/pmtiles/:name", s.GetPMTilesByName)
group.GET("/pmtiles/:name/:z/:x/:y", s.GetPMTilesByNameAndZAndXAndY)
// postgis
// group.GET("/postgis/:name", s.GetPostGISByName)
}

View File

@ -1,4 +1,4 @@
package api package service
import ( import (
"fmt" "fmt"
@ -18,14 +18,14 @@ import (
// @Param name path string true "MBTiles名称" // @Param name path string true "MBTiles名称"
// @Success 200 {object} model.TileJSON // @Success 200 {object} model.TileJSON
// @Router /mbtiles/{name} [get] // @Router /mbtiles/{name} [get]
func (a *API) GetMBTilesByName(c echo.Context) error { func (s *MapService) GetMBTilesByName(c echo.Context) error {
name := c.Param("name") name := c.Param("name")
if ok := a.store.Tile.CheckPool(maptool.MBTilesName, name); !ok { if ok := s.store.Tile.CheckPool(maptool.MBTilesName, name); !ok {
return c.String(http.StatusBadRequest, "MBTiles not found") return c.String(http.StatusBadRequest, "MBTiles not found")
} }
data, err := a.store.Tile.GetTileJSON(maptool.MBTilesName, name) data, err := s.store.Tile.GetTileJSON(maptool.MBTilesName, name)
if err != nil { if err != nil {
return c.String(http.StatusBadRequest, "Failed to get metadata") return c.String(http.StatusBadRequest, "Failed to get metadata")
} }
@ -47,7 +47,7 @@ func (a *API) GetMBTilesByName(c echo.Context) error {
// @Param y path string true "y值" // @Param y path string true "y值"
// @Success 200 {string} string "成功" // @Success 200 {string} string "成功"
// @Router /mbtiles/{name}/{z}/{x}/{y} [get] // @Router /mbtiles/{name}/{z}/{x}/{y} [get]
func (a *API) GetMBTilesByNameAndZAndXAndY(c echo.Context) error { func (s *MapService) GetMBTilesByNameAndZAndXAndY(c echo.Context) error {
name := c.Param("name") name := c.Param("name")
z := c.Param("z") z := c.Param("z")
@ -66,11 +66,11 @@ func (a *API) GetMBTilesByNameAndZAndXAndY(c echo.Context) error {
return c.String(http.StatusBadRequest, "Invalid y value") return c.String(http.StatusBadRequest, "Invalid y value")
} }
if ok := a.store.Tile.CheckPool(maptool.MBTilesName, name); !ok { if ok := s.store.Tile.CheckPool(maptool.MBTilesName, name); !ok {
return c.String(http.StatusBadRequest, "MBTiles not found") return c.String(http.StatusBadRequest, "MBTiles not found")
} }
data, err := a.store.Tile.GetTile(maptool.MBTilesName, name, zValue, xValue, yValue) data, err := s.store.Tile.GetTile(maptool.MBTilesName, name, zValue, xValue, yValue)
if err != nil { if err != nil {
return c.String(http.StatusNotFound, "Tile not found") return c.String(http.StatusNotFound, "Tile not found")

View File

@ -1,4 +1,4 @@
package api package service
import ( import (
"fmt" "fmt"
@ -18,14 +18,14 @@ import (
// @Param name path string true "PMTiles名称" // @Param name path string true "PMTiles名称"
// @Success 200 {object} model.TileJSON // @Success 200 {object} model.TileJSON
// @Router /mbtiles/{name} [get] // @Router /mbtiles/{name} [get]
func (a *API) GetPMTilesByName(c echo.Context) error { func (s *MapService) GetPMTilesByName(c echo.Context) error {
name := c.Param("name") name := c.Param("name")
if ok := a.store.Tile.CheckPool(maptool.PMTilesName, name); !ok { if ok := s.store.Tile.CheckPool(maptool.PMTilesName, name); !ok {
return c.String(http.StatusBadRequest, "PMTiles not found") return c.String(http.StatusBadRequest, "PMTiles not found")
} }
data, err := a.store.Tile.GetTileJSON(maptool.PMTilesName, name) data, err := s.store.Tile.GetTileJSON(maptool.PMTilesName, name)
if err != nil { if err != nil {
return c.String(http.StatusBadRequest, "Failed to get metadata") return c.String(http.StatusBadRequest, "Failed to get metadata")
} }
@ -47,7 +47,7 @@ func (a *API) GetPMTilesByName(c echo.Context) error {
// @Param y path string true "y值" // @Param y path string true "y值"
// @Success 200 {string} string "成功" // @Success 200 {string} string "成功"
// @Router /mbtiles/{name}/{z}/{x}/{y} [get] // @Router /mbtiles/{name}/{z}/{x}/{y} [get]
func (a *API) GetPMTilesByNameAndZAndXAndY(c echo.Context) error { func (s *MapService) GetPMTilesByNameAndZAndXAndY(c echo.Context) error {
name := c.Param("name") name := c.Param("name")
z := c.Param("z") z := c.Param("z")
@ -66,11 +66,11 @@ func (a *API) GetPMTilesByNameAndZAndXAndY(c echo.Context) error {
return c.String(http.StatusBadRequest, "Invalid y value") return c.String(http.StatusBadRequest, "Invalid y value")
} }
if ok := a.store.Tile.CheckPool(maptool.PMTilesName, name); !ok { if ok := s.store.Tile.CheckPool(maptool.PMTilesName, name); !ok {
return c.String(http.StatusBadRequest, "PMTiles not found") return c.String(http.StatusBadRequest, "PMTiles not found")
} }
data, err := a.store.Tile.GetTile(maptool.PMTilesName, name, zValue, xValue, yValue) data, err := s.store.Tile.GetTile(maptool.PMTilesName, name, zValue, xValue, yValue)
if err != nil { if err != nil {
return c.String(http.StatusNotFound, "Tile not found") return c.String(http.StatusNotFound, "Tile not found")

8
service/vector.go Normal file
View File

@ -0,0 +1,8 @@
package service
import "github.com/labstack/echo/v4"
func (s *MapService) GetVectorByName(c echo.Context) error {
return c.JSON(200, "ok")
}

View File

@ -14,6 +14,7 @@
"@codemirror/language": "^6.11.1", "@codemirror/language": "^6.11.1",
"@codemirror/state": "^6.5.2", "@codemirror/state": "^6.5.2",
"@mapbox/mapbox-gl-draw": "^1.5.0", "@mapbox/mapbox-gl-draw": "^1.5.0",
"@simonwep/pickr": "^1.9.1",
"@turf/turf": "^7.2.0", "@turf/turf": "^7.2.0",
"@vueuse/nuxt": "^12.7.0", "@vueuse/nuxt": "^12.7.0",
"codemirror": "^6.0.1", "codemirror": "^6.0.1",

View File

@ -24,12 +24,12 @@
"sources": { "sources": {
"openmaptiles": { "openmaptiles": {
"type": "vector", "type": "vector",
"url": "/api/v1/pmtiles/zhejiang-pm", "url": "/map/pmtiles/zhejiang-pm",
"maxzoom": 14 "maxzoom": 14
} }
}, },
"sprite": "http://localhost:8080/style/sprite/icons/icons", "sprite": "http://localhost:8080/map/style/sprite/icons/icons",
"glyphs": "http://localhost:8080/style/font/{fontstack}/{range}.pbf", "glyphs": "http://localhost:8080/map/style/font/{fontstack}/{range}.pbf",
"layers": [ "layers": [
{ {
"id": "background", "id": "background",