First Initialize

This commit is contained in:
Supan Adit Pratama 2019-10-19 23:38:38 +07:00
commit a5a5e459bd
6 changed files with 182 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea
.vscode

35
README.md Normal file
View File

@ -0,0 +1,35 @@
# GEO Smart System
This is Tile38 Implementation for Golang, and also this software has a purpose to be real time tracking system
simulation such as Uber, Gojek, Grab, etc. The main feature of this software is that it must **lightweight**,
**less memory usage**, and **fast**, and for the live map it will integration with [Geo Smart Map](https://github.com/supanadit/geosmartmap)
## Requirements
- [Tile38 Server](https://tile38.com/)
- [Golang](https://golang.org/)
## Todo
- Work with Socket.IO (OK)
- Connect With Tile38 (OK)
- CORS Support (OK)
- Get Data From Tile38 by Command SCAN (OK)
- Set HOOK by GeoFencing Trigger
- Receive New Point by HTTP GET also By Socket.IO and Trigger by Socket.IO Only
- Send Realtime Point by Socket.IO
- Support Nearby Trigger Feature
- Support Enter Area Trigger Feature
- Support Exit Area Trigger Feature
## License
Copyright 2019 Supan Adit Pratama
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

75
main.go Normal file
View File

@ -0,0 +1,75 @@
package main
import (
"fmt"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis"
socketio "github.com/googollee/go-socket.io"
"github.com/supanadit/geosmartsystem/model"
"log"
)
func main() {
// Tile38
client := redis.NewClient(&redis.Options{
Addr: "localhost:9851",
})
router := gin.Default()
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:4200"},
AllowMethods: []string{"PUT", "PATCH", "POST", "GET"},
AllowHeaders: []string{"Origin"},
ExposeHeaders: []string{"Content-Length"},
AllowWebSockets: true,
AllowCredentials: true,
AllowWildcard: true,
}))
router.GET("/point", func(c *gin.Context) {
data, _ := model.FromScan(client, "sales")
c.JSON(200, data)
})
// Socket.IO Start
server, err := socketio.NewServer(nil)
if err != nil {
log.Fatal(err)
}
server.OnConnect("/", func(s socketio.Conn) error {
s.SetContext("")
fmt.Println("Connected:", s.ID())
return nil
})
server.OnEvent("/", "message", func(s socketio.Conn, msg string) {
s.Emit("message", "have "+msg)
})
server.OnEvent("/", "bye", func(s socketio.Conn) string {
last := s.Context().(string)
s.Emit("bye", last)
_ = s.Close()
return last
})
server.OnError("/", func(e error) {
fmt.Println("Meet Error:", e)
})
server.OnDisconnect("/", func(s socketio.Conn, msg string) {
fmt.Println("Closed", msg)
})
router.GET("/socket.io/", gin.WrapH(server))
router.POST("/socket.io/", gin.WrapH(server))
router.Handle("WS", "/socket.io/", WebSocketIO(server))
router.Handle("WSS", "/socket.io/", WebSocketIO(server))
router.GET("/ws", func(c *gin.Context) {
server.ServeHTTP(c.Writer, c.Request)
})
go server.Serve()
defer server.Close()
// End Socket.IO
_ = router.Run()
}
func WebSocketIO(server *socketio.Server) gin.HandlerFunc {
return func(c *gin.Context) {
server.ServeHTTP(c.Writer, c.Request)
}
}

50
model/tile38data.go Normal file
View File

@ -0,0 +1,50 @@
package model
import (
"encoding/json"
"github.com/go-redis/redis"
"github.com/tidwall/gjson"
"strconv"
)
type Tile38Data struct {
Object []Tile38Object `json:"data"`
}
func FromScan(client *redis.Client, name string) (Tile38Data, error) {
var tile38Data Tile38Data
var err error
v, err := client.Do("SCAN", name).Result()
if err == nil {
data, err := json.Marshal(v)
if err == nil {
jsonConverted := `{"data":` + string(data) + `}`
lengthData := gjson.Get(jsonConverted, "data.1.#")
if lengthData.Int() != 0 {
var x int64 = 0
for x = 0; x < lengthData.Int(); x++ {
name := "data.1." + strconv.FormatInt(int64(x), 10)
idName := name + ".0"
contentName := name + ".1"
id := gjson.Get(jsonConverted, idName)
content := gjson.Get(jsonConverted, contentName)
var tile38Object Tile38Object
var tile38SubObject Tile38SubObject
err = json.Unmarshal([]byte(content.String()), &tile38SubObject)
if err == nil {
tile38Object.Id = id.String()
tile38Object.Object = tile38SubObject
tile38Data.Object = append(tile38Data.Object, tile38Object)
}
}
}
}
}
return tile38Data, err
}
func (tile38Data Tile38Data) ToJsonString() (string, error) {
var err error
data, err := json.Marshal(tile38Data)
return string(data), err
}

6
model/tile38object.go Normal file
View File

@ -0,0 +1,6 @@
package model
type Tile38Object struct {
Id string `json:"id"`
Object Tile38SubObject `json:"object"`
}

14
model/tile38subobject.go Normal file
View File

@ -0,0 +1,14 @@
package model
type Tile38SubObject struct {
Type string `json:"type"`
Coordinates []float64 `json:"coordinates"`
}
func (tile38SubObject Tile38SubObject) Lng() float64 {
return tile38SubObject.Coordinates[0]
}
func (tile38SubObject Tile38SubObject) Lat() float64 {
return tile38SubObject.Coordinates[1]
}