Skip to content

Commit

Permalink
Support for importing non-area relations as MultiLineString
Browse files Browse the repository at this point in the history
  • Loading branch information
talaj committed Oct 26, 2018
1 parent 8962720 commit 736f4b9
Show file tree
Hide file tree
Showing 12 changed files with 3,621 additions and 8 deletions.
4 changes: 2 additions & 2 deletions database/postgis/postgis.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ func addGeometryColumn(tx *sql.Tx, tableName string, spec TableSpec) error {
}

geomType := strings.ToUpper(spec.GeometryType)
if geomType == "POLYGON" {
geomType = "GEOMETRY" // for multipolygon support
if geomType == "POLYGON" || geomType == "LINESTRING" {
geomType = "GEOMETRY" // for multigeometry support
}
sql := fmt.Sprintf("SELECT AddGeometryColumn('%s', '%s', '%s', '%d', '%s', 2);",
spec.Schema, tableName, colName, spec.Srid, geomType)
Expand Down
43 changes: 43 additions & 0 deletions geom/multilinestring.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package geom

import (
"errors"
"github.com/omniscale/imposm3/element"
"github.com/omniscale/imposm3/geom/geos"
"runtime"
)

func BuildMultiLinestring(rel *element.Relation, srid int) (*geos.Geom, error) {
g := geos.NewGeos()
g.SetHandleSrid(srid)
defer g.Finish()

var lines []*geos.Geom

for _, member := range rel.Members {
if member.Way == nil {
continue
}

line, err := LineString(g, member.Way.Nodes)

// Clear the finalizer created in LineString()
// as we want to make the object a part of MultiLineString.
runtime.SetFinalizer(line, nil)

if err != nil {
return nil, err
}

lines = append(lines, line)
}

result := g.MultiLineString(lines)
if result == nil {
return nil, errors.New("Error while building multi-linestring.")
}

g.DestroyLater(result)

return result, nil
}
43 changes: 43 additions & 0 deletions geom/multilinestring_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package geom

import (
"testing"

"github.com/omniscale/imposm3/element"
"github.com/omniscale/imposm3/geom/geos"
)

func TestSimpleMultiLineString(t *testing.T) {
w1 := makeWay(1, element.Tags{}, []coord{
{1, 1, 0},
{2, 2, 0},
})
w2 := makeWay(2, element.Tags{}, []coord{
{3, 2, 0},
{4, 3, 0},
})

rel := element.Relation{
OSMElem: element.OSMElem{Id: 1, Tags: element.Tags{}}}
rel.Members = []element.Member{
{Id: 1, Type: element.WAY, Role: "", Way: &w1},
{Id: 2, Type: element.WAY, Role: "", Way: &w2},
}

geom, err := BuildMultiLinestring(&rel, 3857)

if err != nil {
t.Fatal(err)
}

g := geos.NewGeos()
defer g.Finish()

if !g.IsValid(geom) {
t.Fatal("geometry not valid", g.AsWkt(geom))
}

if length := geom.Length(); length != 2 {
t.Fatal("length invalid", length)
}
}
1 change: 1 addition & 0 deletions import_/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func Import(importOpts config.Import) {
tagmapping.Conf.SingleIdSpace,
relations,
db, progress,
tagmapping.LineStringMatcher,
tagmapping.PolygonMatcher,
tagmapping.RelationMatcher,
tagmapping.RelationMemberMatcher,
Expand Down
7 changes: 6 additions & 1 deletion mapping/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const (
type Mapping struct {
Conf config.Mapping
PointMatcher NodeMatcher
LineStringMatcher WayMatcher
LineStringMatcher RelWayMatcher
PolygonMatcher RelWayMatcher
RelationMatcher RelationMatcher
RelationMemberMatcher RelationMatcher
Expand Down Expand Up @@ -356,6 +356,11 @@ func (m *Mapping) addRelationFilters(tableType TableType, filters tableElementFi
return false
}
filters[name] = append(filters[name], f)
} else if TableType(t.Type) == LineStringTable {
f := func(tags element.Tags, key Key, closed bool) bool {
return false
}
filters[name] = append(filters[name], f)
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion mapping/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@ func (m *Mapping) pointMatcher() (NodeMatcher, error) {
}, err
}

func (m *Mapping) lineStringMatcher() (WayMatcher, error) {
func (m *Mapping) lineStringMatcher() (RelWayMatcher, error) {
mappings := make(TagTableMapping)
m.mappings(LineStringTable, mappings)
filters := make(tableElementFilters)
m.addFilters(filters)
m.addTypedFilters(LineStringTable, filters)
relFilters := make(tableElementFilters)
m.addRelationFilters(LineStringTable, relFilters)
tables, err := m.tables(LineStringTable)
return &tagMatcher{
mappings: mappings,
filters: filters,
tables: tables,
relFilters: relFilters,
matchAreas: false,
}, err
}
Expand Down
Loading

0 comments on commit 736f4b9

Please sign in to comment.