-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for importing non-area relations as MultiLineString
- Loading branch information
Showing
12 changed files
with
395 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package geom | ||
|
||
import ( | ||
"errors" | ||
osm "github.com/omniscale/go-osm" | ||
"github.com/omniscale/imposm3/geom/geos" | ||
"runtime" | ||
) | ||
|
||
func BuildMultiLinestring(rel *osm.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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package geom | ||
|
||
import ( | ||
"testing" | ||
|
||
osm "github.com/omniscale/go-osm" | ||
"github.com/omniscale/imposm3/geom/geos" | ||
) | ||
|
||
func TestSimpleMultiLineString(t *testing.T) { | ||
w1 := makeWay(1, osm.Tags{}, []coord{ | ||
{1, 1, 0}, | ||
{2, 2, 0}, | ||
}) | ||
w2 := makeWay(2, osm.Tags{}, []coord{ | ||
{3, 2, 0}, | ||
{4, 3, 0}, | ||
}) | ||
|
||
rel := osm.Relation{ | ||
Element: osm.Element{ID: 1, Tags: osm.Tags{}}} | ||
rel.Members = []osm.Member{ | ||
{ID: 1, Type: osm.WayMember, Role: "", Way: &w1}, | ||
{ID: 2, Type: osm.WayMember, 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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?xml version='1.0' encoding='UTF-8'?> | ||
<osmChange version="1"> | ||
<create> | ||
<node id="10009" version="1" timestamp="2016-01-01T00:00:00Z" lat="51.5512379" lon="-0.0405630"/> | ||
<node id="10010" version="1" timestamp="2016-01-01T00:00:00Z" lat="51.5515113" lon="-0.0406333"/> | ||
<way id="1006" version="1" timestamp="2016-01-01T00:00:00Z"> | ||
<nd ref="10009"/> | ||
<nd ref="10010"/> | ||
</way> | ||
|
||
<node id="10008" version="1" timestamp="2016-01-01T00:00:00Z" lat="51.5515683" lon="-0.0406486"/> | ||
<node id="10007" version="1" timestamp="2016-01-01T00:00:00Z" lat="51.5515883" lon="-0.0406757"/> | ||
<way id="1007" version="1" timestamp="2016-01-01T00:00:00Z"> | ||
<nd ref="10008"/> | ||
<nd ref="10007"/> | ||
</way> | ||
|
||
<relation id="102" version="1" timestamp="2016-01-01T00:00:00Z"> | ||
<member type="way" ref="1006" role=""/> | ||
<member type="way" ref="1007" role=""/> | ||
<tag k="network" v="lcn"/> | ||
<tag k="route" v="bicycle"/> | ||
<tag k="type" v="route"/> | ||
</relation> | ||
</create> | ||
|
||
<modify> | ||
<way id="1004" version="2" timestamp="2016-01-01T00:00:00Z"> | ||
<nd ref="10004"/> | ||
<nd ref="10005"/> | ||
<nd ref="10006"/> | ||
<nd ref="10004"/> | ||
<tag k="building" v="residential"/> | ||
<!-- tag with area=yes removed --> | ||
</way> | ||
</modify> | ||
</osmChange> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version='1.0' encoding='UTF-8'?> | ||
<osm version="1"> | ||
<node id="10002" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5107973" lon="-0.0930300" /> | ||
<node id="10003" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5108542" lon="-0.0930091" /> | ||
<way id="1000" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<nd ref="10002"/> | ||
<nd ref="10003"/> | ||
<tag k="highway" v="trunk"/> | ||
</way> | ||
|
||
<node id="10000" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5107776" lon="-0.0930375"/> | ||
<way id="1005" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<nd ref="10000"/> | ||
<nd ref="10002"/> | ||
</way> | ||
|
||
<node id="10001" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5106434" lon="-0.0930826" /> | ||
<way id="1001" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<nd ref="10001"/> | ||
<nd ref="10000"/> | ||
</way> | ||
<relation id="100" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<member type="way" ref="1000" role=""/> | ||
<member type="way" ref="1005" role=""/> | ||
<member type="way" ref="1001" role=""/> | ||
<tag k="route" v="bicycle"/> | ||
<tag k="type" v="route"/> | ||
</relation> | ||
|
||
<node id="10004" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.4860918" lon="-0.0873508"/> | ||
<node id="10006" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.4860020" lon="-0.0875372"/> | ||
<node id="10005" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.4853370" lon="-0.0864133"/> | ||
<way id="1004" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<nd ref="10004"/> | ||
<nd ref="10005"/> | ||
<nd ref="10006"/> | ||
<nd ref="10004"/> | ||
<tag k="building" v="residential"/> | ||
<tag k="area" v="yes"/> | ||
</way> | ||
|
||
<node id="10011" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5004084" lon="-0.0824810"/> | ||
<node id="10012" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5003998" lon="-0.0833872"/> | ||
<node id="10013" version="1" timestamp="2015-12-31T23:59:99Z" lat="51.5003917" lon="-0.0836970"/> | ||
<way id="1008" version="1" timestamp="2015-12-31T23:59:99Z"> | ||
<nd ref="10011"/> | ||
<nd ref="10012"/> | ||
<nd ref="10013"/> | ||
<nd ref="10011"/> | ||
<tag k="leisure" v="park"/> | ||
</way> | ||
</osm> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
areas: | ||
area_tags: | ||
- leisure | ||
tables: | ||
multilinestring: | ||
type: linestring | ||
columns: | ||
- name: osm_id | ||
type: id | ||
- name: geometry | ||
type: geometry | ||
- name: name | ||
type: string | ||
key: name | ||
- name: type | ||
type: mapping_value | ||
relation_types: | ||
- route | ||
mapping: | ||
type: | ||
- route | ||
highway: | ||
- trunk | ||
building: | ||
- residential | ||
leisure: | ||
- park | ||
multilinestring_no_relations: | ||
type: linestring | ||
columns: | ||
- name: osm_id | ||
type: id | ||
- name: geometry | ||
type: geometry | ||
- name: name | ||
type: string | ||
key: name | ||
- name: type | ||
type: mapping_value | ||
mapping: | ||
type: | ||
- route |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package test | ||
|
||
import ( | ||
"database/sql" | ||
"io/ioutil" | ||
|
||
"testing" | ||
|
||
"github.com/omniscale/imposm3/geom/geos" | ||
) | ||
|
||
func TestMultiLineString(t *testing.T) { | ||
if testing.Short() { | ||
t.Skip("system test skipped with -test.short") | ||
} | ||
t.Parallel() | ||
|
||
ts := importTestSuite{ | ||
name: "multilinestring", | ||
} | ||
|
||
t.Run("Prepare", func(t *testing.T) { | ||
var err error | ||
|
||
ts.dir, err = ioutil.TempDir("", "imposm_test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
ts.config = importConfig{ | ||
connection: "postgis://", | ||
cacheDir: ts.dir, | ||
osmFileName: "build/multilinestring.pbf", | ||
mappingFileName: "multilinestring_mapping.yml", | ||
} | ||
ts.g = geos.NewGeos() | ||
|
||
ts.db, err = sql.Open("postgres", "sslmode=disable") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
ts.dropSchemas() | ||
}) | ||
|
||
const mlsTable = "osm_multilinestring" | ||
|
||
t.Run("Import", func(t *testing.T) { | ||
if ts.tableExists(t, ts.dbschemaImport(), mlsTable) != false { | ||
t.Fatalf("table %s exists in schema %s", mlsTable, ts.dbschemaImport()) | ||
} | ||
ts.importOsm(t) | ||
if ts.tableExists(t, ts.dbschemaImport(), mlsTable) != true { | ||
t.Fatalf("table %s does not exists in schema %s", mlsTable, ts.dbschemaImport()) | ||
} | ||
}) | ||
|
||
t.Run("Deploy", func(t *testing.T) { | ||
ts.deployOsm(t) | ||
if ts.tableExists(t, ts.dbschemaImport(), mlsTable) != false { | ||
t.Fatalf("table %s exists in schema %s", mlsTable, ts.dbschemaImport()) | ||
} | ||
if ts.tableExists(t, ts.dbschemaProduction(), mlsTable) != true { | ||
t.Fatalf("table %s does not exists in schema %s", mlsTable, ts.dbschemaProduction()) | ||
} | ||
}) | ||
|
||
t.Run("CheckMultiLineStringGeometry", func(t *testing.T) { | ||
element := checkElem{mlsTable, -100, "*", nil} | ||
ts.assertGeomType(t, element, "MultiLineString") | ||
ts.assertGeomValid(t, element) | ||
ts.assertGeomLength(t, element, 38) | ||
}) | ||
|
||
t.Run("CheckLineStringGeometry", func(t *testing.T) { | ||
element := checkElem{mlsTable, 1000, "*", nil} | ||
ts.assertGeomType(t, element, "LineString") | ||
ts.assertGeomValid(t, element) | ||
ts.assertGeomLength(t, element, 10) | ||
}) | ||
|
||
t.Run("CheckFilters", func(t *testing.T) { | ||
if records := ts.queryRows(t, mlsTable, 1008); len(records) > 0 { | ||
t.Fatalf("The way 1008 should be filtered out by typed filter") | ||
} | ||
if records := ts.queryRows(t, mlsTable, 1004); len(records) > 0 { | ||
t.Fatalf("The way 1004 should be filtered out as it is closed path with area=yes") | ||
} | ||
}) | ||
|
||
t.Run("RelationTypesFilter", func(t *testing.T) { | ||
if records := ts.queryRows(t, "osm_multilinestring_no_relations", -100); len(records) > 0 { | ||
t.Fatalf("The relation -100 should not be imported due to empty relation_types") | ||
} | ||
}) | ||
|
||
t.Run("Update", func(t *testing.T) { | ||
ts.updateOsm(t, "build/multilinestring.osc.gz") | ||
}) | ||
|
||
t.Run("CheckFilters2", func(t *testing.T) { | ||
if records := ts.queryRows(t, mlsTable, 1004); len(records) == 0 { | ||
t.Fatalf("The way 1004 should now be there as we removed area=yes in the update") | ||
} | ||
}) | ||
|
||
t.Run("CheckNewRelation", func(t *testing.T) { | ||
if records := ts.queryRows(t, mlsTable, -102); len(records) == 0 { | ||
t.Fatalf("The relation -102 should be created") | ||
} | ||
}) | ||
} | ||
|
Oops, something went wrong.