OpenLayersのRule classとFilter classについて-1[Chapter 55]

OpenLayersを使ってみる。[Chapter 55]

OpenLayersのStyleのruleとfilterついて-2[Chapter 54] に引き続き、OpenLayersのRule calssとFilter calssついて基本を学んでいきます。

この章以降は、

  • いかにOpenLayersのVector layerのstyleを表示するか?
  • Style classをその使い方について
  • Ruleとfilterの使い方
  • Filter classの使い方 → 今回はここ

について順番に学んでいきます。

OpenLayers 2.10 Beginner's Guideなる書籍の章立てにあわせて、OpenLayersの使い方を学んでいきます。

OpenLayers.Rule class

Objectを特色とするために適用されるスタイルのタイプについて非常に明確になりたい場合、それをする最良の方法はrule classの使用によります。
Rule classを作成する場合、filter object、featureに適用するべきsymbolizer、およびruleの名前を指定するオプションを指定します。

Rule objectはstyle objectに適用されます。また、多くのstyle objectに関するruleを持つことができます。
Rule objectを作成するためのsyntax、以前に言及された次のような形です:

var my_rule = new OpenLayers.Rule({
  filter: new OpenLayers.Filter({}),
  symbolizer: { key:values }
});
style_object.addRules([my_rule]);

Style objectへの多数のruleを作成し適用するのがそれほど難しくはありません。
前例では、単一のfilterをrule objectに使用しました。しかし、OpenLayersは、feature styleに対するより多くを制御するために多数のfilterを指定することができます。

Ruleがfeatureに適用されるかどうか判断する際に仕事をするのはfilterです。
したがって、filter classへの注視、およびfeature styleをもっとカスタマイズするために、rule classを使用することになります。

OpenLayers.Filter class

Filter classは、ruleが適用されるべきかどうか確かめるようにfeatuer attribute propertyのロジックをコントロールします。
前の例でのように、単一のfilterを使用することができます。あるいは、filterをともに(例えば、property1が500を超えるもので、別のproperty2が200未満である場合)組み合わせることができます。

Filterはさらに、(spatial)がfeatureがgeometry objectと交差するかどうかチェックすることもできます。これらの物事をすべてするために、filter class(Layer classおよび他のclassのsubclassをどのように使用するかに似ている)のsubclassを使用します。

Filter Subclasses

Filterには4つのsubclassがあります。それは、ComparisonFeatureIdLogicalSpatialです。

Filter.Comparison

Comparison classはここまで使用しているfilter classです。
名前が意味するように、このclassはfilter objectの指定されたparameterに基づいたpropertyを比較する時に使います。
Comparisonは、type propertyによって指定されます。
さらに、filterの値(lowerBoundaryとupperBoundaryのような異なるpropertyを使用します)を使用することをチェックするために値を指定しなければなりません。
最後に、さらにfeatureの中でチェックするpropertyを指定しなければなりません。

例えば、前の例からのrule_pop_low規則の中で使用されるフィルタ・オブジェクトを見ましょう:

var rule_pop_mid = new OpenLayers.Rule({
  filter: new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.GREATER_THAN,
  property: 'population',
  value: 1500
}),

ここで、GREATER_THANのComparison typeを行ってくれるようにOpenLayersに依頼します。それはfeatureのpopulation propertyを見て、人口の値が1500より大きい場合、ruleと一致します。

Filter.Comparison Value property

Filter.Comparison objectにはすべてある程度の伴う値propertyが必要です。
Filter Comparison typeはほとんどすべて、GREATER_THANタイプのように、単に値propertyを使用します。
他のものは、Comparison typeのように、lowerBoundaryとupperBoundaryのpropertyを使用します。
Filterが捜すべき値を指定しなかった場合は、filterは作動しません。

Filter Comparison types

別段の定めがない限り、Comparison typeはそれぞれ値propertyを持ちます。
値propertyは別段の定めがない限り{Integer}タイプです。

Filter Type: BETWEEN

BETWEEN: propertyが2つの値の間にあるかどうかチェックします。
lowerBoundが500で、upperBoundが1500である場合、値は、中間の値および500〜1500を含んでいることになります。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.BETWEEN,
  property: 'population',
  lowerBoundary:500,
  upperBoundary:1500
});
Filter Type: EQUAL_TO

EQUAL_TO: propertyが指定された値と等しい場合にチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.EQUAL_TO,
  property: 'population',
  value: 1337
});
Filter Type: GREATER_THAN

GREATER_THAN: propertyがより大きい場合にチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.GREATER_THAN,
  property: 'population',
  value: 1000
});
Filter Type: GREATER_THAN_OR_EQUAL_TO

GREATER_THAN_OR_EQUAL_TO: propertyが指定された値以上である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
  property: 'population',
  value: 1000
});
Filter Type: LESS_THAN

LESS_THAN: propertyが未満で指定された値である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.LESS_THAN,
  property: 'population',
  value: 1000
});
Filter Type: LESS_THAN_OR_EQUAL_TO

LESS_THAN_OR_EQUAL_TO: propertyが未満で、あるいは含んで指定された値である場合チェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,
  property: 'population',
  value: 1000
});
Filter Type: LIKE

LIKE: propertyが値(それはこの場合{String}である)を含んでいる場合にチェックします。
例えば、もしpropertyの値が「village」で、指定する値が「village」ならば、それは一致するでしょう。
指定する値はさらにあります、1つの、正規表現それは一致し続けるために様々な特殊文字の中でできることを意味します。
例えば、*は、任意の文字の0以上の実例と一致するでしょう。
あるstringがproperty内に含まれるかどうかただ確かめたければ、単に正規表現とは何かどうかについて心配せずに、値をそのストリングにセットすることができます。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
    type: OpenLayers.Filter.Comparison.LIKE,
    property: 'settlement_type',
    value: 'village'
});
Filter Type: NOT_EQUAL_TO

NOT_EQUAL_TO: propertyがある値と等しくないか。(それは{Integer}タイプです)どうかチェックします。
constructorの呼び出し例:

var my_filter = new OpenLayers.Filter.Comparison({
  type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
  property: 'population',
  value: 1000
});

Filter.FeatureId

これは、FeatureIdに基づいたfeatureをfilterするでしょう。
特にWFSサービスあるいはSLDで働く場合、これは有用です。
WFSで、FeatureIDはユニークなfeatureとして載せる方法です。
WFSサーバーは、featureのユニークにそれを識別するFeatureIDを含んでいるデータを返します。
SLDは、さらにユニークなFeatureIDによってfeatureを識別することができます。
特定のfeatureのIDを知っていれば、これは有用になりえます。
FeatureID filterを使用する場合、それは配列として与えることができます:

var my_filter = new OpenLayers.Filter.FeatureId({
    fids: ['fid1', 'fid2']
});

Feature.Logical

既にrule filterを適用する例を学びましたが、別のfilter objectにfilter objectを適用することもでききます。
それは、filterを備えた論理演算子を使用することで可能になります。これは、実際に複雑なfilterをとても容易に作成することができます。
使用することができる3つのタイプの論理演算子があります:

  • OpenLayers.Filter.Logical.AND: Checks if multiple filters match
  • OpenLayers.Filter.Logical.OR: Checks if at least one of the multiple filters match
  • OpenLayers.Filter.Logical.NOT: If the filter does not match

論理的なfilterを作成するために、単にtype(それは上に3つの論理演算子のうちの1つである)、および他のfilter objectを含んでいるfilterの配列を指定します。

var my_logical_filter = new OpenLayers.Filter.Logical({
  type: OpenLayers.Filter.Logical.AND,
  filters: [
    new OpenLayers.Filter.Comparison({
      type: OpenLayers.Filter.Comparison.LESS_THAN,
      property: 'population',
      value: 1000
    }),
    new OpenLayers.Filter.Comparison({
      type: OpenLayers.Filter.Comparison.LIKE,
      property: 'settlement_type',
      value: 'village'
    })
  ]
});

上記のfilterはAND論理演算子および2つのcomparison filterを使用します。
結果は、この論理的なフィルタが両方のcomparison filter(settlement_typeが「village」で人工が1000未満)と一致するfeatureだけと一致するものをfilterしています。

logical filtersを使ったexample code

Rulesとfiltersを使った簡単なexample codeを作成してみましょう。以下のcodeを入力します。
保存先は、c:¥ms4w¥apache¥htdocs¥openlayer¥chapter10¥にしておきます。
ファイル名は、chapter10_ex5_customRules.htmlで保存します。

 
<!DOCTYPE html> 
<html lang='ja'> 
<head> 
    <meta charset='utf-8' /> 
		<script type='text/javascript' src='http://localhost/openlayers/OpenLayers.js'></script>
    <script type='text/javascript'>

    var map;
    var vector_layer;
    
    function init() {
        //Create a map with an empty array of controls
        map = new OpenLayers.Map('map_element');

        //Create a base layer
        var wms_layer = new OpenLayers.Layer.WMS(
            'OpenLayers WMS',
            'http://vmap0.tiles.osgeo.org/wms/vmap0',
            {layers: 'basic'},
            {}
        );
        map.addLayer(wms_layer);
        
        //Add vector layer
        vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer'
					);
					map.addLayer(vector_layer);

				var settlement_values = {
					0 : 'village',
					1 : 'city',
				}

        //Create some points
        for(var i=0; i<20; i++){
            vector_layer.addFeatures([new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(
                    (Math.floor(Math.random() * 360) - 180),
	                (Math.floor(Math.random() * 180) - 90)
	            ),
	            {
                    'population': Math.floor(Math.random() * 2000),
					'settlement_type': settlement_values[(Math.floor(Math.random() * 2))]
                }
            )]);
        }     

        //Create a style object
        var vector_style = new OpenLayers.Style();
                
        var filter_village_low_pop = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.AND,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LESS_THAN,
                    property: 'population',
                    value: 1000
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'village'
                })
            ]
        });

			var filter_village_high_pop = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.AND,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.BETWEEN,
                    property: 'population',
                    lowerBoundary: 1000,
					upperBoundary: 1500
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'village'
                })
            ]
        });
		
			var filter_city = new OpenLayers.Filter.Logical({
            type: OpenLayers.Filter.Logical.OR,
            filters: [
                new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.GREATER_THAN,
                    property: 'population',
                    value: 1500
                }),
				 new OpenLayers.Filter.Comparison({
                    type: OpenLayers.Filter.Comparison.LIKE,
                    property: 'settlement_type',
                    value: 'city'
                }),
            ]
        });
		

			//ADD RULES
			//We'll use three rules to check for population size
			var rule_village_low_pop = new OpenLayers.Rule({
				filter : filter_village_low_pop,
				symbolizer : {
					fillColor : '#ababab',
					fillOpacity : .8,
					pointRadius : 8,
					strokeColor : '#454545',
					strokeWidth : 2
				}
			});

			var rule_village_high_pop = new OpenLayers.Rule({
				filter : filter_village_high_pop,
				symbolizer : {
					fillColor : '#FFFA93',
					fillOpacity : .8,
					pointRadius : 8,
					strokeColor : '#AFAB57',
					strokeWidth : 4,
				}
			});

			var rule_city = new OpenLayers.Rule({
				filter : filter_city,
				symbolizer : {
					fillColor : '#BD1922',
					fillOpacity : .8,
					pointRadius : 16,
					strokeColor : '#812B30',
					strokeWidth : 6,
					fontSize : '.8em',
					fontColor : '#efefef',
					label : '${population}'
				}
			});

			//Add the rules to the style object
			vector_style.addRules([rule_village_low_pop, rule_village_high_pop, rule_city]);

			//Create a style map object
			var vector_style_map = new OpenLayers.StyleMap({
				'default' : vector_style
			});

			//Add the style map to the vector layer
			vector_layer.styleMap = vector_style_map;

			if (!map.getCenter()) {
				map.zoomToMaxExtent();
			}

			}

		</script>
</head>

<body onload='init();'>
    <div id='map_element' style='width: 600px; height: 400px;'></div>
</body>
</html>

codeでまずは、map objectを作成します。

//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');
 
//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
    'OpenLayers WMS',
    'http://vmap0.tiles.osgeo.org/wms/vmap0',
    {layers: 'basic'},
    {}
);
map.addLayer(wms_layer);

WMS layerをbase layerとして作成します。

次に、vector layerを追加します。

//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Basic Vector Layer');
map.addLayer(vector_layer);
 
var settlement_values = {
	0 : 'village',
	1 : 'city',
}

settlement_valuesを定義します。

次に、Pointの座標を

//Create some points
for(var i=0; i<20; i++){
    vector_layer.addFeatures([new OpenLayers.Feature.Vector(
        new OpenLayers.Geometry.Point(
           (Math.floor(Math.random() * 360) - 180),
           (Math.floor(Math.random() * 180) - 90)
         ),
         {
               'population': Math.floor(Math.random() * 2000),
               'settlement_type': settlement_values[(Math.floor(Math.random() * 2))]
                }
        )]);
}

randomに20カ所を作成するようにして、addFeaturesでvector_layerに追加します。
Attributeにpopulationとsettlement_typeを設定します。

次に、Styleを、

//Create a style object
var vector_style = new OpenLayers.Style();
 
var filter_village_low_pop = new OpenLayers.Filter.Logical({
    type: OpenLayers.Filter.Logical.AND,
    filters: [
        new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.LESS_THAN,
            property: 'population',
            value: 1000
        }),
        new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.LIKE,
            property: 'settlement_type',
            value: 'village'
        })
    ]
});
 
var filter_village_high_pop = new OpenLayers.Filter.Logical({
    type: OpenLayers.Filter.Logical.AND,
    filters: [
        new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.BETWEEN,
            property: 'population',
            lowerBoundary: 1000,
            upperBoundary: 1500
        }),
	new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.LIKE,
            property: 'settlement_type',
            value: 'village'
        })
   ]
});
 
var filter_city = new OpenLayers.Filter.Logical({
    type: OpenLayers.Filter.Logical.OR,
    filters: [
        new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.GREATER_THAN,
            property: 'population',
            value: 1500
        }),
        new OpenLayers.Filter.Comparison({
            type: OpenLayers.Filter.Comparison.LIKE,
            property: 'settlement_type',
            value: 'city'
        }),
   ]
});

filter_village_low_pop、filter_village_high_pop、filter_cityでfilterを作成します。
Comparison subclassを使って場合分けを行います。

そして、ruleを追加します。

//ADD RULES
//We'll use three rules to check for population size
var rule_village_low_pop = new OpenLayers.Rule({
	filter : filter_village_low_pop,
	symbolizer : {
		fillColor : '#ababab',
		fillOpacity : .8,
		pointRadius : 8,
		strokeColor : '#454545',
		strokeWidth : 2
	}
});
 
var rule_village_high_pop = new OpenLayers.Rule({
	filter : filter_village_high_pop,
	symbolizer : {
		fillColor : '#FFFA93',
		fillOpacity : .8,
		pointRadius : 8,
		strokeColor : '#AFAB57',
		strokeWidth : 4,
	}
});
 
var rule_city = new OpenLayers.Rule({
	filter : filter_city,
	symbolizer : {
		fillColor : '#BD1922',
		fillOpacity : .8,
		pointRadius : 16,
		strokeColor : '#812B30',
		strokeWidth : 6,
		fontSize : '.8em',
		fontColor : '#efefef',
		label : '${population}'
	}
});

のようにrule_village_low_pop、rule_village_high_pop、rule_cityの3パターンのruleを定義します。
それぞれのruleはfilterで定義したilter_village_low_pop、filter_village_high_pop、filter_cityを使います。

そして、addRules functionに、

//Add the rules to the style object
vector_style.addRules([rule_village_low_pop, rule_village_high_pop, rule_city]);

3つのrule objectを適用します。

最後に、vector_style_mapを追加して、

//Create a style map object
var vector_style_map = new OpenLayers.StyleMap({
	'default' : vector_style
});
 
//Add the style map to the vector layer
vector_layer.styleMap = vector_style_map;

vector_layer.styleMapのstyleを作成します。

保存後、FireFoxを立ち上げて、http://localhost/openlayers/chapter10/chapter10_ex5_customRules.htmlと入力すると、
blog.godo-tys.jp_wp-content_gallery_openlayers_55_image01.jpg

ようにStyleMapで定義されたvector layerが追加されて、ruleとfilterに従ったpoint dataが読み込まれてmapに表示されます。

今回のまとめ

OpenLayersの簡単なStyleのrule classとfiler classについて基本を学びました。
是非、ruleの値をいろいろと変更して、ruleについて学んでみましょう。
次回も、rule classとfiler classについて基本を学んでいきます。

また、本tutorialは、htmlやCSSやJavaScriptの基本的なことはある程度理解している前提で今後も話を進めていきます。また、誤字、脱字、spell間違いや勘違いも多々出てくると考えられます。
それは違うじゃん!!とかいろんな意見をいただければと思います。
そこんところ ヨロシク~~!!

OpenLayers Tutorialの目次に戻る。

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

WP-SpamFree by Pole Position Marketing

Social Widgets powered by AB-WebLog.com.