forked from rubenv/topojson
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextract.go
118 lines (101 loc) · 2.9 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
109
110
111
112
113
114
115
116
117
118
package topojson
import (
"fmt"
"github.com/paulmach/orb"
"github.com/paulmach/orb/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(geojson.NewGeometry(g))
// TODO
// idProp := "id"
// if t.opts != nil && t.opts.IDProperty != "" {
// idProp = t.opts.IDProperty
// }
if f.ID != nil {
o.ID = fmt.Sprint(f.ID)
}
o.Properties = f.Properties
o.BoundingBox = f.BBox
return o
}
func (t *Topology) extractGeometry(g *geojson.Geometry) *topologyObject {
o := &topologyObject{
Type: g.Type,
}
// TODO
// if g.Coordinates != nil {
// o.BoundingBox = []float64{
// g.Coordinates.Bound().Min[0],
// g.Coordinates.Bound().Min[1],
// g.Coordinates.Bound().Max[0],
// g.Coordinates.Bound().Max[1],
// }
// }
switch g.Type {
default:
for _, geom := range g.Geometries {
o.Geometries = append(o.Geometries, t.extractGeometry(geom))
}
case geojson.TypeLineString:
o.Arc = t.extractLine(g.Coordinates.(orb.LineString))
case geojson.TypeMultiLineString:
o.Arcs = make([]*arc, len(g.Coordinates.(orb.MultiLineString)))
for i, l := range g.Coordinates.(orb.MultiLineString) {
o.Arcs[i] = t.extractLine(l)
}
case geojson.TypePolygon:
o.Arcs = make([]*arc, len(g.Coordinates.(orb.Polygon)))
for i, r := range g.Coordinates.(orb.Polygon) {
o.Arcs[i] = t.extractRing(r)
}
case geojson.TypeMultiPolygon:
o.MultiArcs = make([][]*arc, len(g.Coordinates.(orb.MultiPolygon)))
for i, p := range g.Coordinates.(orb.MultiPolygon) {
arcs := make([]*arc, len(p))
for j, r := range p {
arcs[j] = t.extractRing(r)
}
o.MultiArcs[i] = arcs
}
case geojson.TypePoint:
o.Point = []float64{g.Coordinates.(orb.Point)[0], g.Coordinates.(orb.Point)[1]}
case geojson.TypeMultiPoint:
for _, v := range g.Coordinates.(orb.MultiPoint) {
o.MultiPoint = append(o.MultiPoint, []float64{v[0], v[1]})
}
}
return o
}
func (t *Topology) extractLine(line orb.LineString) *arc {
n := len(line)
for i := 0; i < n; i++ {
t.coordinates = append(t.coordinates, []float64{line[i][0], line[i][1]})
}
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 orb.Ring) *arc {
n := len(ring)
for i := 0; i < n; i++ {
t.coordinates = append(t.coordinates, []float64{ring[i][0], ring[i][1]})
}
index := len(t.coordinates) - 1
arc := &arc{Start: index - n + 1, End: index}
t.rings = append(t.rings, arc)
return arc
}