-
Notifications
You must be signed in to change notification settings - Fork 4
/
output.go
124 lines (113 loc) · 3.26 KB
/
output.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package geohashtree
/*
This files handles abstracting the core function geohashtree.go uses.
*/
import (
"fmt"
"github.com/paulmach/go.geojson"
"io/ioutil"
"os"
"strings"
)
var Increment = 2 // change this if you want the increment to increase
// creates a string that can be appended to a csv file
func CleanOutput(outputgeohashs []string, idstring string, minval int) string {
// creating stringlist
mymap := map[string]string{}
newlist := []string{}
for i, val := range outputgeohashs {
currentval := val
for len(currentval) != minval {
_, boolval := mymap[currentval[:len(currentval)-1]]
if !boolval {
mymap[currentval[:len(currentval)-1]] = ""
newlist = append(newlist, fmt.Sprintf("%s,%s", currentval[:len(currentval)-1], "-1"))
}
currentval = currentval[:len(currentval)-1]
}
outputgeohashs[i] = fmt.Sprintf("%s,%s", val, idstring)
}
return strings.Join(append(newlist, outputgeohashs...), "\n") + "\n"
}
type IndexOutput struct {
Min, Max int
File *os.File
FileName string
TotalPolygons int
}
// creates a csv to start appending to
func CreateCSV(filename string, minp, maxp int) (*IndexOutput, error) {
os.Create(filename)
file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
file.WriteString(fmt.Sprintf("GEOHASH,ID\nmin,%d\nmax,%d\ndummy,-1\n", minp, maxp))
return &IndexOutput{
Min: minp,
Max: maxp,
File: file,
FileName: filename,
TotalPolygons: 0,
}, err
}
func (output *IndexOutput) AddFeature(feature *geojson.Feature, field string) string {
val, boolval := feature.Properties[field]
var valstr string
if !boolval {
return ""
} else {
valstr, boolval = val.(string)
if !boolval {
return ""
}
}
output.TotalPolygons++
if feature.Geometry.Type == "Polygon" {
return CleanOutput(
MakePolygonIndex(feature.Geometry.Polygon, output.Min, output.Max),
valstr,
output.Min,
)
} else if feature.Geometry.Type == "MultiPolygon" {
totaloutput := []string{}
for _, polygon := range feature.Geometry.MultiPolygon {
totaloutput = append(totaloutput, MakePolygonIndex(polygon, output.Min, output.Max)...)
}
return CleanOutput(totaloutput, valstr, output.Min)
}
return ""
}
// creates an index from geojson and dumps it into a csv
func IndexFromGeoJSON(filename string, outfilename string, minp, maxp int, geojsonfield string) error {
bs, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
fc, err := geojson.UnmarshalFeatureCollection(bs)
if err != nil {
return err
}
output, err := CreateCSV(outfilename, minp, maxp)
if err != nil {
return err
}
current := 0
for current < len(fc.Features) {
nextcurrent := current + Increment
if nextcurrent > len(fc.Features) {
nextcurrent = len(fc.Features)
}
c := make(chan string, nextcurrent-current)
for _, feature := range fc.Features[current:nextcurrent] {
go func(feature *geojson.Feature, c chan string) {
c <- output.AddFeature(feature, geojsonfield)
}(feature, c)
}
for i := current; i < nextcurrent; i++ {
val := <-c
output.File.WriteString(val)
}
current = nextcurrent
fmt.Printf("\r[%d/%d] of features written to output csv.", current, len(fc.Features))
}
fmt.Printf("\nFinished making output csv: %s\n", outfilename)
return err
}