Skip to content

Commit e37bbcd

Browse files
committed
Support for importing non-area relations as MultiLineString
1 parent 8962720 commit e37bbcd

File tree

12 files changed

+3621
-8
lines changed

12 files changed

+3621
-8
lines changed

database/postgis/postgis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ func addGeometryColumn(tx *sql.Tx, tableName string, spec TableSpec) error {
7272
}
7373

7474
geomType := strings.ToUpper(spec.GeometryType)
75-
if geomType == "POLYGON" {
76-
geomType = "GEOMETRY" // for multipolygon support
75+
if geomType == "POLYGON" || geomType == "LINESTRING" {
76+
geomType = "GEOMETRY" // for multigeometry support
7777
}
7878
sql := fmt.Sprintf("SELECT AddGeometryColumn('%s', '%s', '%s', '%d', '%s', 2);",
7979
spec.Schema, tableName, colName, spec.Srid, geomType)

geom/multilinestring.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package geom
2+
3+
import (
4+
"github.com/omniscale/imposm3/element"
5+
"github.com/omniscale/imposm3/geom/geos"
6+
"errors"
7+
"runtime"
8+
)
9+
10+
func BuildMultiLinestring(rel *element.Relation, srid int) (*geos.Geom, error) {
11+
g := geos.NewGeos()
12+
g.SetHandleSrid(srid)
13+
defer g.Finish()
14+
15+
var lines []*geos.Geom
16+
17+
for _, member := range rel.Members {
18+
if member.Way == nil {
19+
continue
20+
}
21+
22+
line, err := LineString(g, member.Way.Nodes)
23+
24+
// Clear the finalizer created in LineString()
25+
// as we want to make the object a part of MultiLineString.
26+
runtime.SetFinalizer(line, nil)
27+
28+
if err != nil {
29+
return nil, err
30+
}
31+
32+
lines = append(lines, line)
33+
}
34+
35+
result := g.MultiLineString(lines)
36+
if result == nil {
37+
return nil, errors.New("Error while building multi-linestring.")
38+
}
39+
40+
g.DestroyLater(result)
41+
42+
return result, nil
43+
}

geom/multilinestring_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package geom
2+
3+
import (
4+
"testing"
5+
6+
"github.com/omniscale/imposm3/element"
7+
"github.com/omniscale/imposm3/geom/geos"
8+
)
9+
10+
func TestSimpleMultiLineString(t *testing.T) {
11+
w1 := makeWay(1, element.Tags{}, []coord{
12+
{1, 1, 0},
13+
{2, 2, 0},
14+
})
15+
w2 := makeWay(2, element.Tags{}, []coord{
16+
{3, 2, 0},
17+
{4, 3, 0},
18+
})
19+
20+
rel := element.Relation{
21+
OSMElem: element.OSMElem{Id: 1, Tags: element.Tags{}}}
22+
rel.Members = []element.Member{
23+
{Id: 1, Type: element.WAY, Role: "", Way: &w1},
24+
{Id: 2, Type: element.WAY, Role: "", Way: &w2},
25+
}
26+
27+
geom, err := BuildMultiLinestring(&rel, 3857)
28+
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
33+
g := geos.NewGeos()
34+
defer g.Finish()
35+
36+
if !g.IsValid(geom) {
37+
t.Fatal("geometry not valid", g.AsWkt(geom))
38+
}
39+
40+
if length := geom.Length(); length != 2 {
41+
t.Fatal("length invalid", length)
42+
}
43+
}

import_/import.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ func Import(importOpts config.Import) {
180180
tagmapping.Conf.SingleIdSpace,
181181
relations,
182182
db, progress,
183+
tagmapping.LineStringMatcher,
183184
tagmapping.PolygonMatcher,
184185
tagmapping.RelationMatcher,
185186
tagmapping.RelationMemberMatcher,

mapping/mapping.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const (
8484
type Mapping struct {
8585
Conf config.Mapping
8686
PointMatcher NodeMatcher
87-
LineStringMatcher WayMatcher
87+
LineStringMatcher RelWayMatcher
8888
PolygonMatcher RelWayMatcher
8989
RelationMatcher RelationMatcher
9090
RelationMemberMatcher RelationMatcher
@@ -356,6 +356,11 @@ func (m *Mapping) addRelationFilters(tableType TableType, filters tableElementFi
356356
return false
357357
}
358358
filters[name] = append(filters[name], f)
359+
} else if TableType(t.Type) == LineStringTable {
360+
f := func(tags element.Tags, key Key, closed bool) bool {
361+
return false
362+
}
363+
filters[name] = append(filters[name], f)
359364
}
360365
}
361366
}

mapping/matcher.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,20 @@ func (m *Mapping) pointMatcher() (NodeMatcher, error) {
2020
}, err
2121
}
2222

23-
func (m *Mapping) lineStringMatcher() (WayMatcher, error) {
23+
func (m *Mapping) lineStringMatcher() (RelWayMatcher, error) {
2424
mappings := make(TagTableMapping)
2525
m.mappings(LineStringTable, mappings)
2626
filters := make(tableElementFilters)
2727
m.addFilters(filters)
2828
m.addTypedFilters(LineStringTable, filters)
29+
relFilters := make(tableElementFilters)
30+
m.addRelationFilters(LineStringTable, relFilters)
2931
tables, err := m.tables(LineStringTable)
3032
return &tagMatcher{
3133
mappings: mappings,
3234
filters: filters,
3335
tables: tables,
36+
relFilters: relFilters,
3437
matchAreas: false,
3538
}, err
3639
}

0 commit comments

Comments
 (0)