トップMy OpenStreetMap > OSMタグの管理方法

OSMタグの管理方法

はじめに

highway=motorway や leisure=park といった OSMタグはキーの highway、leisure や 値の motorway、park を そのまま文字列として扱えば、管理は楽である。

レンダリングプログラムでは

 if (key.equals("highway") && val.equals("motorway")) {
    ... 
 }
といった書き方となる。管理は楽であるが、判定は何行にも及ぶため、実行に時間がかかる。 このため、キーと値は enum で宣言している。判定プログラムは次のようになり、高速である。 処理によっては switch 文も使えるため、オーバヘッドは小さい。
 if (key == Tag.Key.highway && val == Tag.Val.motorway) {
    ... 
 }

キーには通し番号が振られるため、あるキーが存在するか否かを1ビットで表せる。 long値を使った場合、最大64種類のキーが存在するか否かを1命令で判定できる。

このようにパフォーマンス上、キーや値は文字列ではなく、 enum で管理する方が格段に優れている。

enumによるタグ管理には問題はないが、現在、すでに、レンダリングに反映させるキーの数は 64 を超えている。 したがって、long値ひとつでは、全キーをカバーできない。

また、OSMタグには、値が文字列のものや数値のものがある。

enum をどのように割り振るかが課題である。

キー highway、railway などの値は多くあり、その値により、色や幅やレンダリング方法がことなるため、 これらをテーブル管理している。 ここでは、現在は、motorway、trunk、primary など OSM タグの値に当たるものを文字列としているが、 enum Tag.Val を使うべきであろう。

以上のように、enum によるOSMタグの管理方法をここで見直す。

タグ・キーの管理方法

これまでは以下のように分類してきた。

レンダリング上、タグの有無を瞬時に判定したいことが多いタグをメインタグ、 その可能性は小さいタグをサブタグに分類している。

タグの値が数値や文字列であるものを特殊タグとしている。プログラム処理上、 値が文字列になるもの、数値になるものそれぞれを連続して配置したい。

メインタグに属するものとサブタグに属するものがある。

一部、OSMタグではなく、独自に導入した疑似タグも存在する。

全タグ数は 64 を超える。メインタグには 1~63 を割り当てたい。サブタグの序数はいくらでもよい。

    // 旧コード
    public enum Key {
        // main tags
        unknown, aerialway, aeroway, amenity, barrier,
        boundary, building, highway, landuse, leisure,          // 10
        man_made, natural, power, railway, route,
        shop, tourism, water, waterway, place,                  // 20
        historic, office, emergency, wetland, military,

        // sub tags
        bridge, tunnel, intermittent, area, oneway,             // 30
        service, tower_type, tracktype, information, covered,
        access, parking, junction, religion, sport,             // 40
        playground, substance, construction, surface, pipeline,
        location, generator_source, power_source, basin, type,  // 50

        // special tags
        name, name_ja, name_en, bridge_name, tunnel_name,       // 55
        local_ref, operator, ref,                               // string tag, 58
        admin_level, layer, population,                         // int  tag,   61
        ele, height, width,                                     // float tag

        // pseudo tags 疑似キー(OSMレコードにはない)
        leisure_sport,
        placename_flags,
    }

main tags、special tags、sub tags、pseudo tags の順に変更したい。 main tags と special tags の合計は現在 40以下である。 将来 sub tags から main tags に格上げしたいものがでてきても、64個以内に収まるであろう。

unknownタグは存在しないが、序数 0 を使わないために空けておく。

    // 新コード
    public enum Key {
        // main tags
        unknown, aerialway, aeroway, amenity, barrier,
        boundary, building, highway, landuse, leisure,          // 10
        man_made, natural, power, railway, route,
        shop, tourism, water, waterway, place,                  // 20
        historic, office, emergency, wetland, military,

        // special tags
        name, name_ja, name_en, bridge_name, tunnel_name,       
        local_ref, operator, ref,                               // string tag, 
        admin_level, layer, population,                         // int  tag,   
        ele, height, width,                                     // float tag

        // sub tags
        bridge, tunnel, intermittent, area, oneway,            
        service, tower_type, tracktype, information, covered,
        access, parking, junction, religion, sport,            
        playground, substance, construction, surface, pipeline,
        location, generator_source, power_source, basin, type, 

        // pseudo tags 疑似キー(OSMレコードにはない)
        leisure_sport,
        placename_flags,
    }

タグの値の方は数が多い。現在、レンダリングに反映しているのは 300~400 位になるであろう。 この数は 500、1000 になっても問題はない。

OSMタグには存在しないが、便宜上、導入している値もいくつかある。 道路や鉄道のタグの値(motorway、trunk、primaryなど)は、幹線道路の判定などに序数を使うため、 順序に意味を持たせている。このため、前に置いて、位置固定としている。

一般のタグの値についてはどこに置いてもよい。

enum Val については、変更しない。今後、増えていくが問題はない。

    public enum Val {
        //========= fixed position ========================//
        // highway
        unknown, motorway, motorway_link, trunk, trunk_link,
        primary, primary_link, secondary, secondary_link,
        tertiary, tertiary_link, raceway, residential, unclassified,
        living_street, road, service, service_alley, pedestrian,
        pedestrian_wide, pedestrian_alley, track1, track2, track,
        path, footway, cycleway, bridleway, steps, platform,
        construction,

        // railway
        rail, subway, narrow_gauge, light_rail,
        funicular, preserved, monorail, miniature, turntable,
        tram, disused,

        // aeroway
        runway, taxiway,

        //================== common (free position) ===============//
        yes, no, error,

        //============ access ==========//
        customers, _private, permissive, destination,
        agricultural, permit, designated, emergency,
        discouraged,

        // 以下省略