Go! Map Server
Today
- Let it Go
- GIS Server with Go
- Talk is cheap, Let me show you the code
I am
- Engineer @Samsung SDS
- @iam_keen
- github.com/ehrudxo
I did
- Write a Node GIS Server code
- Participate in QGIS menu Korean translation
Let it Go
https://golang.org/
Go is Good
- Concurrency
- It has compiler!
- Cross-Compiler!
- Light-weight
- Various Tools (Python?)
- Rapid Dev
- Easy To Use
- Functional Programming
- ....
Go Spec
Go is a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming. Programs are constructed from packages, whose properties allow efficient management of dependencies. The existing implementations use a traditional compile/link model to generate executable binaries
Feature
-
Strongly Typed
-
Garbage Collected
-
Concurrent Programming
-
Package
-
No class, but structs
-
Executable Binaries
http://golang.org/ref/spec
Strongly Typed
package main
import "fmt"
func main(){
hiString := "Hello "
objString := "World"
fmt.Println(hiString + objString +1)
}
# command-line-arguments
.\Test.go:7: cannot convert 4 to type string
.\Test.go:7: invalid operation: (hiString + objString) + 4 (mismatched types string and int)
package main
import (
"fmt"
"strconv"
)
func main(){
hiString := "Hello "
objString := "World"
fmt.Println(hiString + objString +strconv.Itoa(1))
}
Garbage Collection
Executable File
GC
Go
Virtual Machint
GC
Java, C#, Ruby, Python
Concurrent Programming
Go's concurrency primitives make it easy to construct streaming data pipelines that make efficient use of I/O and multiple CPUs.
- The Go Blog
package main
import "fmt"
func f(n int) {
for i := 0; i < 10; i++ {
fmt.Println(n, ":", i)
}
}
func main() {
go f(0)
var input string
fmt.Scanln(&input)
}
Package
package main
import "fmt"
import "github.com/ehrudxo/mApi/math"
func main() {
xs := []float64{1,2,3,4}
avg := math.Average(xs)
fmt.Println(avg)
}
import m "github.com/ehrudxo/mApi/math"
func main() {
xs := []float64{1,2,3,4}
avg := m.Average(xs)
fmt.Println(avg)
}
No class,but struct
class House {
public String getHouseName() { //method defined within class
//implementation
}
}
type House struct { }
func (h House) GetHouseName() string { }
//method defined outside of struct,
//but works on House
Java
Go
Executable Binaries
$ cd $GOPATH/src/github.com/user/hello
$ go install
This command builds the hello command, producing an executable binary
$ $GOPATH/bin/hello
Hello, world.
Go Spec
Go is a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming. Programs are constructed from packages, whose properties allow efficient management of dependencies. The existing implementations use a traditional compile/link model to generate executable binaries
Feature
-
Strongly Typed
-
Garbage Collected
-
Concurrent Programming
-
Package
-
No class, but structs
-
Executable Binaries
http://golang.org/ref/spec
https://github.com/golang/go/wiki
GIS Server with Go
https://golang.org/
Go Map
- Image Service
- Vector Service
Tile Service
- Leaflet
DB Connector(pq+GORM)
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
type User struct {
gorm.Model
Name string
}
Web Module
https://revel.github.io/
Image Processor
llgcode -> ninjasphere
Talk is cheap, Let me show you the code
https://github.com/ehrudxo
{...}
Install Go
golang.org
Install Revel
# get revel framework
go get github.com/revel/revel
# get 'revel' command
go get github.com/revel/cmd/revel
# get samples and run chat app
go get github.com/revel/samples
revel run github.com/revel/samples/chat
&
Make a new App
$someshell/> revel new github.com/ehrudxo/MapTutorial
github.com/
ehrudxo/
MapTutorial/ App root
app/ App sources
controllers/ App controllers
app.go Sample Contoller
views/ Templates
App/ View Files
index.html Sample View File
errors/ error file
init.go Interceptor registration
tests/ Test suites
conf/ Configuration files
app.conf Main configuration file
routes Routes definition
messages/ Message files
public/ Public assets
css/ CSS files
js/ Javascript files
images/ Image files
SHAPE -> POSTGIS
1. convert shape file to sql file
shp2pgsql -I -W euc-kr -s 2097 <PATH/TO/SHAPEFILE> <DBTABLE> > SHAPEFILE.sql
2. sql loading
psql -d <DATABASE> -f SHAPEFILE.sql
GORM CODE
import "github.com/ehrudxo/GoMap/app/controllers" // add cotroller
func init() {
....
revel.OnAppStart(controllers.InitDB)
revel.InterceptMethod((*controllers.GormController).Begin, revel.BEFORE)
revel.InterceptMethod((*controllers.GormController).Commit, revel.AFTER)
revel.InterceptMethod((*controllers.GormController).Rollback, revel.FINALLY)
...
}
type GormController struct {
*revel.Controller
Tx *gorm.DB
}
var Db gorm.DB
func InitDB() {
var err error
Db, err = gorm.Open("postgres", "user=gouser dbname=postgres password=gopassword sslmode=disable")
if err != nil {
revel.ERROR.Println("FATAL", err)
panic(err)
}
...
}
init.go
gorm.go
Draw2D in Go
import (
"github.com/ninjasphere/draw2d/draw2dkit"
"github.com/ninjasphere/draw2d/draw2dimg"
)
..
func DrawPoint( toilets []models.Toilet, b *models.Bounds, imgWidth int, imgHeight int)
string{
...
for _,toilet := range toilets{
dx := (toilet.Geom.Lng-float64(b.Min.X))/float64(HRes)//x
dy := float64(imgHeight) - (toilet.Geom.Lat-float64(b.Min.Y))/float64(VRes)//y
// fmt.Println("toilet :", toilet,dx,dy);
draw2dkit.Circle(gc, dx, dy, 3)
gc.FillStroke()
}
gc.Close()
draw2dimg.SaveToPngFile(revel.BasePath+"/output/wms/"+filename, dest)
...
return filename
}
Make an Image Service
import (
...
"github.com/ehrudxo/GoMap/app/services"
...
)
type GoMap struct {
*revel.Controller
}
func (c GoMap) Toilet() revel.Result {
srsNo:=2097
c.Params.Bind(&bbox, "BBOX")
c.Params.Bind(&srs, "SRS")
c.Params.Bind(&widthStr, "WIDTH")
c.Params.Bind(&heightStr, "HEIGHT")
...
selectQuery:="Gid,Gu_nm,Hnr_nam,Mtc_at,Masterno,Slaveno,Neadres_nm,Wc_nam,Wc_gbn,Hd_wc_yno,Creat_de,Po_fe_nm,"
selectQuery+="ST_Transform(Geom,3857) as Geom"
whereQuery:="geom && ST_Transform(ST_MakeEnvelope(?,?,?,?,?),2097)"
Db.Where(whereQuery,minx,miny,maxx,maxy,srsNo).Select(selectQuery).Find(&toilets)
...
filename := services.DrawPoint( toilets, bnd, width,height )
return c.RenderFile(file, revel.Inline )//Not an attachment. But Who disconnect the file.
}
Leaflet Settings
{{set . "title" "Home"}}
{{append . "moreStyles" "css/map.css"}}
{{append . "moreScripts" "js/jquery-1.9.1.min.js"}}
{{append . "moreScripts" "js/map.js"}}
{{template "header.html" .}}
var map
$( document ).ready(function() {
map= L.map('map').setView([37.519459, 126.983113], 13);
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
L.tileLayer(osmUrl, { attribution: '...', maxZoom: 18}).addTo(map);
var toilet = L.tileLayer.wms("http://localhost:9000/toilet", {
layers: 'toilet',
format: 'image/png',
transparent: true,
attribution: "public toilet"
});
map.addLayer(toilet);
});
Toilet.html
map.js
Done!
License
ABOB License
?
A Bucket Of Beer!
image from : gettyImage
Q&A
Gis Server with Go
By Keen Dev
Gis Server with Go
- 4,801