Exemplo n.º 1
0
Arquivo: app.go Projeto: buckhx/diglet
// This is pulled out so that get_tile & get_raw_tile endpoitn can use the same code
func getTileHandler(ctx *dig.RequestContext) (tile interface{}, err *dig.CodedError) {
	params := ctx.Params
	x := params["x"].GetInt()
	y := params["y"].GetInt()
	z := params["z"].GetInt()
	slug := params["tileset"].GetString()
	xyz := TileXYZ{Tileset: slug, X: x, Y: y, Z: z}
	tile, tserr := tilesets.Read(xyz)
	if tserr != nil {
		err = dig.Cerrorf(500, tserr.Error())
	}
	return
}
Exemplo n.º 2
0
Arquivo: hub.go Projeto: buckhx/diglet
func (s *tileSubscription) notify(conn *dig.Connection) {
	//TODO ops will have specific tile in the future?
	for xyz := range s.tiles {
		var msg *dig.ResponseMessage
		if tile, err := tilesets.Read(xyz); err != nil {
			check(err)
			msg = dig.Cerrorf(dig.RpcInvalidRequest, err.Error()).ResponseMessage()
		} else {
			tile.Data = nil
			tile.Y = (1<<uint(tile.Z) - 1) - tile.Y
			id := sprintf("%d:%d:%d", tile.Z, tile.X, tile.Y)
			msg = dig.RespondMsg(id, tile)
		}
		conn.Respond(msg)
	}
}
Exemplo n.º 3
0
Arquivo: app.go Projeto: buckhx/diglet
func MBTServer(mbtPath string, port string) (app *dig.App, err error) {
	tilesets, err = ReadTilesets(mbtPath)
	if err != nil {
		return
	}
	info("Serving tiles from %s", mbtPath)
	hub = NewHub(tilesets)
	go hub.listen()
	app = dig.NewApp("Diglet")
	app.Port = port
	app.Prefix = "/tileset"
	app.Methods = []dig.Method{
		{
			Name:  "gallery",
			Route: "/gallery/{tileset}",
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to query for metadata"},
			},
			Handler: func(ctx *dig.RequestContext) (t interface{}, err *dig.CodedError) {
				template := resources.Static_html()
				static, errp := ctx.Render(template)
				warn(errp, "params?")
				//panic(errp)
				w := ctx.HTTPWriter
				w.Write([]byte(static))
				return
			},
			Help: "A simple tile viewer gallery app.\n" +
				"?lat={}&lon={}&zoom={} can be included to zoom tolocation",
		},
		{
			Name: GetTile,
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to read from"},
				"x":       {Validator: assertNumber, Help: "E/W Coordinate"},
				"y":       {Validator: assertNumber, Help: "N/S Cooredinate"},
				"z":       {Validator: assertNumber, Help: "Zoom level Coordinate"},
			},
			Handler: getTileHandler,
			Help:    "Retrieve a tile, the response's data field will be binary of the contents",
		},
		{
			Name:   ListTilesets,
			Route:  "/",
			Params: dig.MethodParams{},
			Handler: func(ctx *dig.RequestContext) (tile interface{}, err *dig.CodedError) {
				dict := make(map[string]map[string]string)
				for name, ts := range tilesets.Tilesets {
					dict[name] = ts.Metadata().Attributes()
				}
				return dict, nil
			},
			Help: "List all of the tilesets available, including their metadata",
		},
		{
			Name:  GetTileset,
			Route: "/{tileset}",
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to query for metadata"},
			},
			Handler: func(ctx *dig.RequestContext) (attrs interface{}, err *dig.CodedError) {
				params := ctx.Params
				slug := params["tileset"].GetString()
				if ts, ok := tilesets.Tilesets[slug]; ok {
					attrs = ts.Metadata().Attributes()
				} else {
					err = dig.Cerrorf(dig.RpcInvalidRequest, "No tileset named %s", slug)
				}
				return
			},
			Help: "Query for the tilesets metadata, all values are string representations",
		},
		{
			Name: SubscribeTile,
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to subscribe to"},
				"x":       {Validator: assertNumber, Help: "E/W Coordinate"},
				"y":       {Validator: assertNumber, Help: "N/S Cooredinate"},
				"z":       {Validator: assertNumber, Help: "Zoom level Coordinate"},
			},
			Handler: func(ctx *dig.RequestContext) (res interface{}, err *dig.CodedError) {
				params := ctx.Params
				x := params["x"].GetInt()
				y := params["y"].GetInt()
				z := params["z"].GetInt()
				slug := params["tileset"].GetString()
				if _, ok := tilesets.Tilesets[slug]; !ok {
					err = dig.Cerrorf(dig.RpcInvalidRequest, "Cannot find tileset %s", slug)
				} else {
					xyz := TileXYZ{Tileset: slug, X: x, Y: y, Z: z}
					if e := hub.bindTile(ctx, xyz); err != nil {
						err = dig.Cerrorf(dig.RpcInvalidRequest, e.Error())
					} else {
						// might need to make this a notifucation instead
						// -> no msg.Id
						res = sprintf("Subscribed to tile %s", xyz)
					}
				}
				return
			},
			Help: "Subscribe to changes on a specific tile, changes will be pushd with the same request id",
		},
		{
			Name: UnsubscribeTile,
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to subscribe to"},
				"x":       {Validator: assertNumber, Help: "E/W Coordinate"},
				"y":       {Validator: assertNumber, Help: "N/S Cooredinate"},
				"z":       {Validator: assertNumber, Help: "Zoom level Coordinate"},
			},
			Handler: func(ctx *dig.RequestContext) (res interface{}, err *dig.CodedError) {
				params := ctx.Params
				x := params["x"].GetInt()
				y := params["y"].GetInt()
				z := params["z"].GetInt()
				slug := params["tileset"].GetString()
				if _, ok := tilesets.Tilesets[slug]; !ok {
					err = dig.Cerrorf(dig.RpcInvalidRequest, "Cannot find tileset %s", slug)
				} else {
					xyz := TileXYZ{Tileset: slug, X: x, Y: y, Z: z}
					hub.unbindTile(ctx, xyz)
					res = sprintf("Unsubscribed from tile %s", xyz)
				}
				return
			},
			Help: "Unsubscribe from a tile",
		},
		{
			Name:  GetRawTile,
			Route: "/{tileset}/{z}/{x}/{y}",
			Params: dig.MethodParams{
				"tileset": {Validator: assertString, Help: "Tileset to subscribe to"},
				"x":       {Validator: assertNumber, Help: "E/W Coordinate"},
				"y":       {Validator: assertNumber, Help: "N/S Cooredinate"},
				"z":       {Validator: assertNumber, Help: "Zoom level Coordinate"},
			},
			Handler: func(ctx *dig.RequestContext) (otile interface{}, err *dig.CodedError) {
				itile, err := getTileHandler(ctx)
				if err != nil {
					return
				}
				r := ctx.HTTPReader
				w := ctx.HTTPWriter
				if tile, terr := castTile(itile); err != nil {
					errorlog(terr)
					terr = dig.Cerrorf(500, "Internal Error casting tile contents")
				} else {
					if dojson := r.URL.Query().Get("json"); toLower(dojson) == "true" {
						otile = tile
						return
					}
					//TODO roll sniff encoding into tile object?
					headers := formatEncoding[tile.SniffFormat()]
					for _, h := range headers {
						w.Header().Set(h.key, h.value)
					}
					w.Header().Set("Content-Length", sprintSizeOf(tile.Data))
					w.Header().Set("Access-Control-Allow-Origin", "*")
					w.Write(tile.Data)
				}
				return
			},
			Help: "Gets a tile and only writes it's raw contents. Used for hosting static tiles.",
		},
	}
	return
}