Skip to content

Commit

Permalink
Merge pull request #15 from PDOK/cli-lib
Browse files Browse the repository at this point in the history
implement cli lib
  • Loading branch information
WouterVisscher authored Jun 8, 2022
2 parents 9d18c2f + 1ad5539 commit 481be6a
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 57 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ vector tiles can be omitted, and less data needs to be processed.
- A MULTIPOLYGON will be split into separate POLYGONs that will be sieved. So
a MULTIPOLYGON containing elements smaller then the given resolution will have
those parts removed.
- :warning: Spatialite lib is mandatory for running this application. This lib is needed for
creating the RTree triggers on the spatial tables for updating/maintaining the
RTree.

## Usage

Expand All @@ -53,10 +56,6 @@ the following.
![with interiors](./images/with-interiors.jpg) ![without
interiors](./images/without-interiors.jpg)

## TODO

- [ ] usage of a CLI package

## Inspiration

Code is inspired by the PostGis [Sieve
Expand Down
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ go 1.17
require (
github.com/go-spatial/geom v0.0.0-20220426070044-6e8855d2cfe6
github.com/mattn/go-sqlite3 v1.14.13 // indirect
github.com/urfave/cli/v2 v2.8.1
)

require github.com/gdey/errors v0.0.0-20190426172550-8ebd5bc891fb // indirect
require (
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/gdey/errors v0.0.0-20190426172550-8ebd5bc891fb // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/arolek/p v0.0.0-20191103215535-df3c295ed582/go.mod h1:JPNItmi3yb44Q5QWM+Kh5n9oeRhfcJzPNS90mbLo25U=
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gdey/errors v0.0.0-20190426172550-8ebd5bc891fb h1:FYO+lZtAUnakgSW9xYs7QvgawjCDM5wgHaXoDhYHNH4=
github.com/gdey/errors v0.0.0-20190426172550-8ebd5bc891fb/go.mod h1:PFaV7MgSRe92Wo9O2H2i1CIm7urUk10AgdSHKyBfjmQ=
Expand All @@ -13,14 +16,23 @@ github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4
github.com/mattn/goveralls v0.0.3-0.20180319021929-1c14a4061c1c/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191114222411-4191b8cbba09/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
107 changes: 107 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"fmt"
"log"
"os"

"github.com/go-spatial/geom/encoding/gpkg"
"github.com/urfave/cli/v2"
)

const SOURCE string = `source`
const TARGET string = `target`
const RESOLUTION string = `resolution`
const PAGESIZE string = `pagesize`

func main() {
app := cli.NewApp()
app.Name = "GOSieve"
app.Usage = "A Golang Polygon Sieve application"

app.Flags = []cli.Flag{
&cli.StringFlag{
Name: SOURCE,
Aliases: []string{"s"},
Usage: "Source GPKG",
Required: true,
EnvVars: []string{"SOURCE_GPKG"},
},
&cli.StringFlag{
Name: TARGET,
Aliases: []string{"t"},
Usage: "Target GPKG",
Required: true,
EnvVars: []string{"TARGET_GPKG"},
},
&cli.Float64Flag{
Name: RESOLUTION,
Aliases: []string{"r"},
Usage: "Resolution, the threshold area to determine if a feature is sieved or not",
Value: 0.0,
Required: false,
EnvVars: []string{"SIEVE_RESOLUTION"},
},
&cli.IntFlag{
Name: PAGESIZE,
Aliases: []string{"p"},
Usage: "Page Size, how many features are written per transaction to the target GPKG",
Value: 1000,
Required: false,
EnvVars: []string{"SIEVE_PAGESIZE"},
},
}

app.Action = func(c *cli.Context) error {

srcHandle, err := gpkg.Open(c.String(SOURCE))
if err != nil {
log.Fatalf("error opening source GeoPackage: %s", err)
}
defer srcHandle.Close()

trgHandle, err := gpkg.Open(c.String(TARGET))
if err != nil {
log.Fatalf("error opening target GeoPackage: %s", err)
}
defer trgHandle.Close()

tables := getSourceTableInfo(srcHandle)

err = initTargetGeopackage(trgHandle, tables)
if err != nil {
log.Fatalf("error initialization the target GeoPackage: %s", err)
}

log.Println("=== start sieving ===")

// Process the tables sequential
for _, table := range tables {
log.Printf(" sieving %s", table.name)
preSieve := make(chan feature)
postSieve := make(chan feature)
kill := make(chan bool)

go writeFeatures(postSieve, kill, trgHandle, table, c.Int(PAGESIZE))
go sieveFeatures(preSieve, postSieve, c.Float64(RESOLUTION))
go readFeatures(srcHandle, preSieve, table)

for {
if <-kill {
break
}
}
close(kill)
log.Println(fmt.Sprintf(` finished %s`, table.name))
log.Println("")
}

log.Println("=== done sieving ===")
return nil
}

err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
52 changes: 0 additions & 52 deletions sieve.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"flag"
"fmt"
"log"
"math"
Expand Down Expand Up @@ -401,57 +400,6 @@ func writeFeaturesArray(features [][]interface{}, h *gpkg.Handle, t table) {
tx.Commit()
}

func main() {
log.Println("=== start sieving ===")
sourceGeopackage := flag.String("s", "empty", "source geopackage")
targetGeopackage := flag.String("t", "empty", "target geopackage")
pageSize := flag.Int("p", 1000, "target geopackage")
resolution := flag.Float64("r", 0.0, "resolution for sieving")
flag.Parse()

srcHandle, err := gpkg.Open(*sourceGeopackage)
if err != nil {
log.Fatalf("error opening source GeoPackage: %s", err)
}
defer srcHandle.Close()

trgHandle, err := gpkg.Open(*targetGeopackage)
if err != nil {
log.Fatalf("error opening target GeoPackage: %s", err)
}
defer trgHandle.Close()

tables := getSourceTableInfo(srcHandle)

err = initTargetGeopackage(trgHandle, tables)
if err != nil {
log.Fatalf("error initialization the target GeoPackage: %s", err)
}

// Process the tables sequential
for _, table := range tables {
log.Printf(" sieving %s", table.name)
preSieve := make(chan feature)
postSieve := make(chan feature)
kill := make(chan bool)

go writeFeatures(postSieve, kill, trgHandle, table, *pageSize)
go sieveFeatures(preSieve, postSieve, *resolution)
go readFeatures(srcHandle, preSieve, table)

for {
if <-kill {
break
}
}
close(kill)
log.Println(fmt.Sprintf(` finished %s`, table.name))
log.Println("")
}

log.Println("=== done sieving ===")
}

// multiPolygonSieve will split it self into the separated polygons that will be sieved before building a new MULTIPOLYGON
func multiPolygonSieve(mp geom.MultiPolygon, resolution float64) geom.MultiPolygon {
var sievedMultiPolygon geom.MultiPolygon
Expand Down

0 comments on commit 481be6a

Please # to comment.