-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathextract.go
108 lines (90 loc) · 2.4 KB
/
extract.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
package topojson
import (
"fmt"
"github.com/paulmach/go.geojson"
)
func (t *Topology) extract() {
t.objects = make([]*topologyObject, 0, len(t.input))
for i, g := range t.input {
feature := t.extractFeature(g)
if len(feature.ID) == 0 {
// if multiple features exist without ids only one will be retained, so provide a synthetic id
feature.ID = fmt.Sprintf("feature_%d", i)
}
t.objects = append(t.objects, feature)
}
t.input = nil // no longer needed
}
func (t *Topology) extractFeature(f *geojson.Feature) *topologyObject {
g := f.Geometry
o := t.extractGeometry(g)
idProp := "id"
if t.opts != nil && t.opts.IDProperty != "" {
idProp = t.opts.IDProperty
}
id, err := f.PropertyString(idProp)
if err == nil {
o.ID = id
}
o.Properties = f.Properties
o.BoundingBox = f.BoundingBox
return o
}
func (t *Topology) extractGeometry(g *geojson.Geometry) *topologyObject {
o := &topologyObject{
Type: g.Type,
BoundingBox: g.BoundingBox,
}
switch g.Type {
case geojson.GeometryCollection:
for _, geom := range g.Geometries {
o.Geometries = append(o.Geometries, t.extractGeometry(geom))
}
case geojson.GeometryLineString:
o.Arc = t.extractLine(g.LineString)
case geojson.GeometryMultiLineString:
o.Arcs = make([]*arc, len(g.MultiLineString))
for i, l := range g.MultiLineString {
o.Arcs[i] = t.extractLine(l)
}
case geojson.GeometryPolygon:
o.Arcs = make([]*arc, len(g.Polygon))
for i, r := range g.Polygon {
o.Arcs[i] = t.extractRing(r)
}
case geojson.GeometryMultiPolygon:
o.MultiArcs = make([][]*arc, len(g.MultiPolygon))
for i, p := range g.MultiPolygon {
arcs := make([]*arc, len(p))
for j, r := range p {
arcs[j] = t.extractRing(r)
}
o.MultiArcs[i] = arcs
}
case geojson.GeometryPoint:
o.Point = g.Point
case geojson.GeometryMultiPoint:
o.MultiPoint = g.MultiPoint
}
return o
}
func (t *Topology) extractLine(line [][]float64) *arc {
n := len(line)
for i := 0; i < n; i++ {
t.coordinates = append(t.coordinates, line[i])
}
index := len(t.coordinates) - 1
arc := &arc{Start: index - n + 1, End: index}
t.lines = append(t.lines, arc)
return arc
}
func (t *Topology) extractRing(ring [][]float64) *arc {
n := len(ring)
for i := 0; i < n; i++ {
t.coordinates = append(t.coordinates, ring[i])
}
index := len(t.coordinates) - 1
arc := &arc{Start: index - n + 1, End: index}
t.rings = append(t.rings, arc)
return arc
}