add new enumerate type to replace zorder

master
Oliver Tonnhofer 2015-08-25 14:52:09 +02:00
parent 2b2d534082
commit 9e125aee02
7 changed files with 266 additions and 119 deletions

View File

@ -205,6 +205,32 @@ Convert ``true``, ``yes`` and ``1`` to the numeric ``1``, ``-1`` values to ``-1`
Convert values to an integer number. Other values will not be inserted. Useful for ``admin_levels`` for example.
``enumerate``
^^^^^^^^^^^^^
Enumerates a list of values and stores tag values as an integer.
The following `enum` column will contain ``1`` for ``landuse=forest``, ``4`` for ``landuse=grass`` and ``0`` for undefined values.
.. code-block:: javascript
{
"args": {
"values": [
"forest",
"park",
"cemetery",
"grass"
]
},
"type": "enumerate",
"name": "enum",
"key": "landuse"
}
``mapping_value`` will be used when ``key`` is not set or ``null``.
Element types
~~~~~~~~~~~~~
@ -255,7 +281,6 @@ Area of polygon geometries in square meters. This area is calculated in the webm
Calculate the z-order of an OSM highway or railway. Returns a numeric value that represents the importance of a way where ``motorway`` is the most important (9), and ``path`` or ``track`` are least important (0). ``bridge`` and ``tunnel`` will modify the value by -10/+10. ``layer`` will be multiplied by ten and added to the value. E.g. ``highway=motorway``, ``bridge=yes`` and ``layer=2`` will return 39 (9+10+2*10).
``hstore_tags``
^^^^^^^^^^^^^^^

View File

@ -71,58 +71,57 @@
},
{
"args": {
"ranks": [
"pedestrian",
"footway",
"playground",
"park",
"forest",
"cemetery",
"farmyard",
"farm",
"farmland",
"wood",
"meadow",
"grass",
"wetland",
"village_green",
"recreation_ground",
"garden",
"sports_centre",
"pitch",
"common",
"allotments",
"golf_course",
"university",
"school",
"college",
"library",
"baracks",
"fuel",
"parking",
"nature_reserve",
"cinema",
"theatre",
"place_of_worship",
"hospital",
"scrub",
"orchard",
"vineyard",
"zoo",
"quarry",
"residential",
"retail",
"commercial",
"industrial",
"railway",
"heath",
"values": [
"land",
"island",
"land"
"heath",
"railway",
"industrial",
"commercial",
"retail",
"residential",
"quarry",
"zoo",
"vineyard",
"orchard",
"scrub",
"hospital",
"place_of_worship",
"theatre",
"cinema",
"nature_reserve",
"parking",
"fuel",
"baracks",
"library",
"college",
"school",
"university",
"golf_course",
"allotments",
"common",
"pitch",
"sports_centre",
"garden",
"recreation_ground",
"village_green",
"wetland",
"grass",
"meadow",
"wood",
"farmland",
"farm",
"farmyard",
"cemetery",
"forest",
"park",
"playground",
"footway",
"pedestrian"
]
},
"type": "zorder",
"name": "z_order",
"key": "z_order"
"type": "enumerate",
"name": "z_order"
}
],
"type": "polygon",
@ -258,22 +257,21 @@
},
{
"args": {
"ranks": [
"country",
"state",
"region",
"county",
"city",
"town",
"village",
"hamlet",
"values": [
"locality",
"suburb",
"locality"
"hamlet",
"village",
"town",
"city",
"county",
"region",
"state",
"country"
]
},
"type": "zorder",
"name": "z_order",
"key": "z_order"
"type": "enumerate",
"name": "z_order"
},
{
"type": "integer",

View File

@ -31,6 +31,7 @@ func init() {
"wayzorder": {"wayzorder", "int32", WayZOrder, nil},
"pseudoarea": {"pseudoarea", "float32", PseudoArea, nil},
"zorder": {"zorder", "int32", nil, MakeZOrder},
"enumerate": {"enumerate", "int32", nil, MakeEnumerate},
"string_suffixreplace": {"string_suffixreplace", "string", nil, MakeSuffixReplace},
}
}
@ -224,6 +225,7 @@ func WayZOrder(val string, elem *element.OSMElem, geom *geom.Geometry, match Mat
}
func MakeZOrder(fieldName string, fieldType FieldType, field Field) (MakeValue, error) {
log.Print("warn: zorder type is deprecated and will be removed. See enumerate type.")
_rankList, ok := field.Args["ranks"]
if !ok {
return nil, errors.New("missing ranks in args for zorder")
@ -269,6 +271,42 @@ func MakeZOrder(fieldName string, fieldType FieldType, field Field) (MakeValue,
return zOrder, nil
}
func MakeEnumerate(fieldName string, fieldType FieldType, field Field) (MakeValue, error) {
_valuesList, ok := field.Args["values"]
if !ok {
return nil, errors.New("missing values in args for enumerate")
}
valuesList, ok := _valuesList.([]interface{})
if !ok {
return nil, errors.New("values in args for enumerate not a list")
}
values := make(map[string]int)
for i, value := range valuesList {
valueName, ok := value.(string)
if !ok {
return nil, errors.New("value in values not a string")
}
values[valueName] = i + 1
}
enumerate := func(val string, elem *element.OSMElem, geom *geom.Geometry, match Match) interface{} {
if field.Key != "" {
if r, ok := values[val]; ok {
return r
}
return 0
}
if r, ok := values[match.Value]; ok {
return r
}
return 0
}
return enumerate, nil
}
func MakeSuffixReplace(fieldName string, fieldType FieldType, field Field) (MakeValue, error) {
_changes, ok := field.Args["suffixes"]
if !ok {

View File

@ -107,6 +107,80 @@ func TestZOrder(t *testing.T) {
}
}
func TestEnumerate_Match(t *testing.T) {
// test enumerate by matched mapping key
match := Match{}
zOrder, err := MakeEnumerate("enumerate",
AvailableFieldTypes["enumerate"],
Field{
Name: "enumerate",
Key: "",
Type: "enumerate",
Args: map[string]interface{}{"values": []interface{}{"AA", "CC", "FF", "ZZ"}},
},
)
if err != nil {
t.Fatal(err)
}
elem := &element.OSMElem{}
elem.Tags = element.Tags{} // missing
if v := zOrder("", elem, nil, match); v != 0 {
t.Errorf(" -> %v", v)
}
match.Value = "ABCD" // unknown
if v := zOrder("", elem, nil, match); v != 0 {
t.Errorf(" -> %v", v)
}
match.Value = "AA"
if v := zOrder("", elem, nil, match); v != 1 {
t.Errorf(" -> %v", v)
}
match.Value = "CC"
if v := zOrder("", elem, nil, match); v != 2 {
t.Errorf(" -> %v", v)
}
match.Value = "ZZ"
if v := zOrder("", elem, nil, match); v != 4 {
t.Errorf(" -> %v", v)
}
}
func TestEnumerate_Key(t *testing.T) {
// test enumerate by key
match := Match{}
zOrder, err := MakeEnumerate("enumerate",
AvailableFieldTypes["enumerate"],
Field{
Name: "enumerate",
Key: "fips",
Type: "enumerate",
Args: map[string]interface{}{"values": []interface{}{"AA", "CC", "FF", "ZZ"}},
},
)
if err != nil {
t.Fatal(err)
}
elem := &element.OSMElem{}
if v := zOrder("", elem, nil, match); v != 0 {
t.Errorf(" -> %v", v)
}
if v := zOrder("ABCD", elem, nil, match); v != 0 {
t.Errorf(" -> %v", v)
}
if v := zOrder("AA", elem, nil, match); v != 1 {
t.Errorf(" -> %v", v)
}
if v := zOrder("CC", elem, nil, match); v != 2 {
t.Errorf(" -> %v", v)
}
if v := zOrder("ZZ", elem, nil, match); v != 4 {
t.Errorf(" -> %v", v)
}
}
func TestMakeSuffixReplace(t *testing.T) {
field := Field{
Name: "name", Key: "name", Type: "string_suffixreplace",

View File

@ -1021,4 +1021,36 @@
</node>
<node id="70002" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.02" lon="20.00"/>
<node id="100001" version="1" timestamp="2011-11-11T00:11:11Z" lat="80.01" lon="-40.00"/>
<node id="100002" version="1" timestamp="2011-11-11T00:11:11Z" lat="80.00" lon="-40.01"/>
<node id="100003" version="1" timestamp="2011-11-11T00:11:11Z" lat="80.01" lon="-40.02"/>
<way id="100001" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="100001"/>
<nd ref="100002"/>
<nd ref="100003"/>
<nd ref="100001"/>
<tag k="name" v="way 100001"/>
<tag k="enum_test" v="park"/>
<tag k="landuse" v="park"/>
</way>
<way id="100002" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="100001"/>
<nd ref="100002"/>
<nd ref="100003"/>
<nd ref="100001"/>
<tag k="name" v="way 100002"/>
<tag k="enum_test" v="unknown"/>
<tag k="landuse" v="park"/>
</way>
<way id="100003" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="100001"/>
<nd ref="100002"/>
<nd ref="100003"/>
<nd ref="100001"/>
<tag k="name" v="way 100003"/>
<tag k="enum_test" v="wood"/>
<tag k="landuse" v="wood"/>
</way>
</osm>

View File

@ -71,58 +71,32 @@
},
{
"args": {
"ranks": [
"pedestrian",
"footway",
"playground",
"values": [
"park",
"forest",
"cemetery",
"farmyard",
"farm",
"farmland",
"wood",
"meadow",
"grass",
"wetland",
"village_green",
"recreation_ground",
"garden",
"sports_centre",
"pitch",
"common",
"allotments",
"golf_course",
"university",
"school",
"college",
"library",
"baracks",
"fuel",
"parking",
"nature_reserve",
"cinema",
"theatre",
"place_of_worship",
"hospital",
"scrub",
"orchard",
"vineyard",
"zoo",
"quarry",
"residential",
"retail",
"commercial",
"industrial",
"railway",
"heath",
"island",
"land"
"cemetery",
"grass",
"farmyard",
"farm",
"farmland",
"orchard",
"vineyard",
"wood",
"meadow",
"village_green",
"recreation_ground",
"allotments",
"quarry"
]
},
"type": "zorder",
"name": "z_order",
"key": "z_order"
"type": "enumerate",
"name": "enum",
"key": "enum_test"
}
],
"type": "polygon",
@ -258,22 +232,21 @@
},
{
"args": {
"ranks": [
"country",
"state",
"region",
"county",
"city",
"town",
"village",
"hamlet",
"values": [
"locality",
"suburb",
"locality"
"hamlet",
"village",
"town",
"city",
"county",
"region",
"state",
"country"
]
},
"type": "zorder",
"name": "z_order",
"key": "z_order"
"type": "enumerate",
"name": "z_order"
},
{
"type": "integer",

View File

@ -298,6 +298,13 @@ def test_update_node_to_coord_1():
assert t.query_row(t.db_conf, 'osm_amenities', 70001)
assert not t.query_row(t.db_conf, 'osm_amenities', 70002)
def test_enumerate_key():
"""Enumerate from key."""
assert t.query_row(t.db_conf, 'osm_landusages', 100001)['enum'] == 1
assert t.query_row(t.db_conf, 'osm_landusages', 100002)['enum'] == 0
assert t.query_row(t.db_conf, 'osm_landusages', 100003)['enum'] == 15
#######################################################################
def test_update():
"""Diff import applies"""