Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relation outer members centroid #1

Merged
merged 16 commits into from
Sep 9, 2021
Merged
Changes from 1 commit
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
43b9b05
feat(relation-outer-members-centroid): move LevelDB functions to cach…
timonmasberg Jul 22, 2021
213adc1
feat(relation-outer-members-centroid): create util functions for misc…
timonmasberg Jul 22, 2021
a3791a5
feat(relation-outer-members-centroid): add length check to IsPointSet…
timonmasberg Jul 22, 2021
ec5f5fd
feat(relation-outer-members-centroid): change findMemberWayLatLons to…
timonmasberg Aug 9, 2021
1e97416
feat(relation-outer-members-centroid): add util function to convert l…
timonmasberg Aug 9, 2021
2168915
feat(relation-outer-members-centroid): add functionality to compute o…
timonmasberg Aug 9, 2021
13b4990
feat(relation-outer-members-centroid): add relation centroid computin…
timonmasberg Aug 9, 2021
1152e2f
feat(relation-outer-members-centroid): move LevelDB functions to cach…
timonmasberg Jul 22, 2021
9f4c151
feat(relation-outer-members-centroid): create util functions for misc…
timonmasberg Jul 22, 2021
33a052d
feat(relation-outer-members-centroid): add length check to IsPointSet…
timonmasberg Jul 22, 2021
e7b7503
feat(relation-outer-members-centroid): change findMemberWayLatLons to…
timonmasberg Aug 9, 2021
3fd4ae6
feat(relation-outer-members-centroid): add util function to convert l…
timonmasberg Aug 9, 2021
f3b92bd
feat(relation-outer-members-centroid): add functionality to compute o…
timonmasberg Aug 9, 2021
85f302b
feat(relation-outer-members-centroid): add relation centroid computin…
timonmasberg Aug 9, 2021
1dce805
Revert "feat(relation-outer-members-centroid): move LevelDB functions…
timonmasberg Aug 15, 2021
7f9f617
Merge remote-tracking branch 'origin/relation-outer-members-centroid'…
timonmasberg Aug 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(relation-outer-members-centroid): add relation centroid computin…
…g functionality to print and refactor entrance extraction
timonmasberg committed Aug 15, 2021
commit 85f302bf8fdd11b4dc4c42e331d6a09cc65e97a7
14 changes: 7 additions & 7 deletions centroid_test.go
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ func TestComputeCentroidWithEntranceNode(t *testing.T) {
map[string]string{"lat": "1", "lon": "2", "entrance": "1"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "1", centroid["lat"])
assert.Equal(t, "2", centroid["lon"])
assert.Equal(t, +1.0, bounds.North())
@@ -29,7 +29,7 @@ func TestComputeCentroidWithMainEntranceNode(t *testing.T) {
map[string]string{"lat": "-1", "lon": "-2", "entrance": "1", "wheelchair": "2"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "1", centroid["lat"])
assert.Equal(t, "2", centroid["lon"])
assert.Equal(t, +1.0, bounds.North())
@@ -45,7 +45,7 @@ func TestComputeCentroidWithAccessibleEntranceNode(t *testing.T) {
map[string]string{"lat": "-1", "lon": "-2", "entrance": "1", "wheelchair": "2"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "-1", centroid["lat"])
assert.Equal(t, "-2", centroid["lon"])
assert.Equal(t, +0.0, bounds.North())
@@ -60,7 +60,7 @@ func TestComputeCentroidWithRegularEntranceNode(t *testing.T) {
map[string]string{"lat": "0", "lon": "0", "entrance": "1"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "0", centroid["lat"])
assert.Equal(t, "0", centroid["lon"])
assert.Equal(t, +0.0, bounds.North())
@@ -79,7 +79,7 @@ func TestComputeCentroidForClosedPolygon(t *testing.T) {
map[string]string{"lat": "1", "lon": "1"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "0.0000000", centroid["lat"])
assert.Equal(t, "0.0000000", centroid["lon"])
assert.Equal(t, +1.0, bounds.North())
@@ -100,7 +100,7 @@ func TestComputeCentroidForHillboroPublicLibrary(t *testing.T) {
map[string]string{"lat": "45.5424694", "lon": "-122.9356798"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "45.5428760", centroid["lat"])
assert.Equal(t, "-122.9359955", centroid["lon"])
assert.Equal(t, +45.5433259, bounds.North())
@@ -117,7 +117,7 @@ func TestComputeCentroidForOpenLineString(t *testing.T) {
map[string]string{"lat": "-1", "lon": "-1"},
}

var centroid, bounds = computeCentroidAndBounds(latlons)
var centroid, bounds = ComputeCentroidAndBounds(latlons)
assert.Equal(t, "0.0000000", centroid["lat"])
assert.Equal(t, "0.0000000", centroid["lon"])
assert.Equal(t, +1.0, bounds.North())
73 changes: 22 additions & 51 deletions pbf2json.go
Original file line number Diff line number Diff line change
@@ -279,7 +279,7 @@ func print(d *osmpbf.Decoder, masks *BitmaskMap, db *leveldb.DB, config settings
}

// compute centroid
centroid, bounds := computeCentroidAndBounds(latlons)
centroid, bounds := ComputeCentroidAndBounds(latlons)

// trim tags
v.Tags = trimTags(v.Tags)
@@ -318,55 +318,15 @@ func print(d *osmpbf.Decoder, masks *BitmaskMap, db *leveldb.DB, config settings
continue
}

// best centroid and bounds to use
var largestArea = 0.0
var centroid map[string]string
var bounds *geo.Bound
// consult https://wiki.openstreetmap.org/wiki/DE:Relation:multipolygon on how osm handles outer members
centroid, bounds := ComputeRelationCentroidAndBounds(memberWayLatLons)

// iterate over each way, selecting the largest way to use
// for the centroid and bbox
for _, latlons := range memberWayLatLons {

// compute centroid
wayCentroid, wayBounds := computeCentroidAndBounds(latlons)

// if for any reason we failed to find a valid bounds
if nil == wayBounds {
log.Println("[warn] failed to calculate bounds for relation member way")
continue
}

area := GetAreaOfBounds(wayBounds)

// find the way with the largest area
if area > largestArea {
largestArea = area
centroid = wayCentroid
bounds = wayBounds
}
}

// if for any reason we failed to find a valid bounds
if nil == bounds {
log.Println("[warn] denormalize failed for relation:", v.ID, "no valid bounds")
if centroid == nil || bounds == nil {
// the relation is probably not a whole part of the osm dump
log.Printf("[warn] could not find centroid and bounds of %d", v.ID)
continue
}

// use 'admin_centre' node centroid where available
// note: only applies to 'boundary=administrative' relations
// see: https://github.com/pelias/pbf2json/pull/98
if v.Tags["boundary"] == "administrative" {
for _, member := range v.Members {
if member.Type == 0 && member.Role == "admin_centre" {
if latlons, err := CacheLookupNodeByID(db, member.ID); err == nil {
latlons["type"] = "admin_centre"
centroid = latlons
break
}
}
}
}

// trim tags
v.Tags = trimTags(v.Tags)

@@ -682,10 +642,7 @@ func selectEntrance(entrances []map[string]string) map[string]string {
return centroid
}

// compute the centroid of a way and its bbox
func computeCentroidAndBounds(latlons []map[string]string) (map[string]string, *geo.Bound) {

// check to see if there is a tagged entrance we can use.
func getEntrance(latlons []map[string]string) (bool, map[string]string, *geo.Bound) {
var entrances []map[string]string
for _, latlon := range latlons {
if _, ok := latlon["entrance"]; ok {
@@ -703,9 +660,23 @@ func computeCentroidAndBounds(latlons []map[string]string) (map[string]string, *

// use the mapped entrance location where available
if len(entrances) > 0 {
return selectEntrance(entrances), points.Bound()
return true, selectEntrance(entrances), points.Bound()
}

return false, nil, nil
}

// ComputeCentroidAndBounds compute the centroid of a way and its bbox for polygons and lines
func ComputeCentroidAndBounds(latlons []map[string]string) (map[string]string, *geo.Bound) {
hasEntrance, entranceLatLon, entranceBounds := getEntrance(latlons)

if hasEntrance {
return entranceLatLon, entranceBounds
}

// convert lat/lon map to geo.PointSet
points := LatLngMapToPointSet(latlons)

// determine if the way is a closed centroid or a linestring
// by comparing first and last coordinates.
isClosed := IsPointSetClosed(points)