-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeojsonseq.go
More file actions
156 lines (132 loc) · 2.9 KB
/
Copy pathgeojsonseq.go
File metadata and controls
156 lines (132 loc) · 2.9 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package govector
import (
"bufio"
"encoding/json"
"errors"
"io"
"path/filepath"
"github.com/flywave/go-geom"
)
const resourceSep = byte('\x1E')
type chunk struct {
endReached bool
reader *bufio.Reader
buf []byte
err error
}
func newChunk(rd io.Reader) *chunk {
return &chunk{endReached: false, reader: bufio.NewReader(rd), buf: nil, err: nil}
}
func (ch *chunk) reset(r io.Reader) {
ch.reader.Reset(r)
}
func (ch *chunk) next() bool {
if ch.endReached {
return false
}
var err error
ch.buf, _, err = ch.reader.ReadLine()
if err == io.EOF {
ch.endReached = true
} else if err != nil {
ch.err = err
return true
}
if ch.buf == nil {
return false
}
ch.buf = ch.buf[:len(ch.buf)-1]
return true
}
func (ch *chunk) read() (*geom.Feature, error) {
if ch.err != nil {
return nil, ch.err
}
var fts []*geom.Feature
err := json.Unmarshal(append(append([]byte(`[`), ch.buf...), ']'), &fts)
if err != nil {
return nil, err
}
if len(fts) == 0 || len(fts) > 1 {
return nil, errors.New("geojson format error")
}
return fts[0], nil
}
type GeoJSONGSeqProvider struct {
chunk *chunk
file io.Reader
}
func (p *GeoJSONGSeqProvider) Open(filename string, file io.Reader) error {
p.file = file
p.chunk = newChunk(file)
return nil
}
func (p *GeoJSONGSeqProvider) Match(filename string, file io.Reader) bool {
ext := filepath.Ext(filename)
if ext != ".geojson" && ext != ".json" {
return false
}
buffer := bufio.NewReader(file)
buf, _, _ := buffer.ReadLine()
var fts []*geom.Feature
err := json.Unmarshal(append(append([]byte(`[`), buf...), ']'), &fts)
if err != nil {
return false
}
if len(fts) == 0 || len(fts) > 1 {
return false
}
return true
}
func (p *GeoJSONGSeqProvider) Reset() error {
p.chunk.reset(p.file)
return nil
}
func (p *GeoJSONGSeqProvider) Close() error {
return nil
}
func (p *GeoJSONGSeqProvider) Next() bool {
if p.chunk != nil {
return p.chunk.next()
}
return false
}
func (p *GeoJSONGSeqProvider) Read() *geom.Feature {
feat, err := p.chunk.read()
if err != nil {
return nil
}
return feat
}
type GeoJSONGSeqExporter struct {
writer io.WriteCloser
bufwrite *bufio.Writer
}
func newGeoJSONGSeqExporter(writer io.WriteCloser) Exporter {
return &GeoJSONGSeqExporter{writer: writer, bufwrite: bufio.NewWriter(writer)}
}
func (e *GeoJSONGSeqExporter) WriteFeature(feature *geom.Feature) error {
json, err := feature.MarshalJSON()
if err != nil {
return err
}
jsonline := append([]byte(json), resourceSep)
_, err = e.bufwrite.Write(jsonline)
return err
}
func (e *GeoJSONGSeqExporter) WriteFeatureCollection(feature *geom.FeatureCollection) error {
for i := range feature.Features {
err := e.WriteFeature(feature.Features[i])
if err != nil {
return err
}
}
return nil
}
func (e *GeoJSONGSeqExporter) Flush() error {
return e.bufwrite.Flush()
}
func (e *GeoJSONGSeqExporter) Close() error {
e.Flush()
return e.writer.Close()
}