OpenLayers OpenLayers

Changeset 5361

Show
Ignore:
Timestamp:
12/07/07 19:18:56 (1 year ago)
Author:
tschaub
Message:

adding getBy and related methods to map - this allows flexible retrieval of things like controls and layers - thanks elem for the review (closes #1153).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/Map.js

    r5349 r5361  
    449449         return this.tileSize; 
    450450     }, 
     451 
     452 
     453    /** 
     454     * APIMethod: getBy 
     455     * Get a list of objects given a property and a match item. 
     456     * 
     457     * Parameters: 
     458     * array - {String} A property on the map whose value is an array. 
     459     * property - {String} A property on each item of the given array. 
     460     * match - {String | Object} A string to match.  Can also be a regular 
     461     *     expression literal or object.  In addition, it can be any object 
     462     *     with a method named test.  For reqular expressions or other, if 
     463     *     match.test(map[array][i][property]) evaluates to true, the item will 
     464     *     be included in the array returned.  If no items are found, an empty 
     465     *     array is returned. 
     466     * 
     467     * Returns: 
     468     * {Array} An array of items where the given property matches the given 
     469     *     criteria. 
     470     */ 
     471    getBy: function(array, property, match) { 
     472        var found = []; 
     473        var item; 
     474        var list = this[array]; 
     475        var test = (typeof match.test == "function"); 
     476        if(list instanceof Array) { 
     477            for(var i=0; i<list.length; ++i) { 
     478                item = list[i]; 
     479                if(item[property] == match || 
     480                   (test && match.test(item[property]))) { 
     481                    found.push(item); 
     482                } 
     483            } 
     484        } 
     485        return found; 
     486    }, 
     487 
     488    /** 
     489     * APIMethod: getLayersBy 
     490     * Get a list of layers with properties matching the given criteria. 
     491     * 
     492     * Parameter: 
     493     * property - {String} A layer property to be matched. 
     494     * match - {String | Object} A string to match.  Can also be a regular 
     495     *     expression literal or object.  In addition, it can be any object 
     496     *     with a method named test.  For reqular expressions or other, if 
     497     *     match.test(layer[property]) evaluates to true, the layer will be 
     498     *     included in the array returned.  If no layers are found, an empty 
     499     *     array is returned. 
     500     * 
     501     * Returns: 
     502     * {Array(<OpenLayers.Layer>)} A list of layers matching the given criteria. 
     503     *     An empty array is returned if no matches are found. 
     504     */ 
     505    getLayersBy: function(property, match) { 
     506        return this.getBy("layers", property, match); 
     507    }, 
     508 
     509    /** 
     510     * APIMethod: getLayersByName 
     511     * Get a list of layers with names matching the given name. 
     512     * 
     513     * Parameter: 
     514     * match - {String | Object} A layer name.  The name can also be a regular 
     515     *     expression literal or object.  In addition, it can be any object 
     516     *     with a method named test.  For reqular expressions or other, if 
     517     *     name.test(layer.name) evaluates to true, the layer will be included 
     518     *     in the list of layers returned.  If no layers are found, an empty 
     519     *     array is returned. 
     520     * 
     521     * Returns: 
     522     * {Array(<OpenLayers.Layer>)} A list of layers matching the given name. 
     523     *     An empty array is returned if no matches are found. 
     524     */ 
     525    getLayersByName: function(match) { 
     526        return this.getLayersBy("name", match); 
     527    }, 
     528 
     529    /** 
     530     * APIMethod: getLayersByType 
     531     * Get a list of layers of a given type (CLASS_NAME). 
     532     * 
     533     * Parameter: 
     534     * match - {String | Object} A layer class name.  The type can also be a 
     535     *     regular expression literal or object.  In addition, it can be any 
     536     *     object with a method named test.  For reqular expressions or other, 
     537     *     if type.test(layer.CLASS_NAME) evaluates to true, the layer will 
     538     *     be included in the list of layers returned.  If no layers are 
     539     *     found, an empty array is returned. 
     540     * 
     541     * Returns: 
     542     * {Array(<OpenLayers.Layer>)} A list of layers matching the given type. 
     543     *     An empty array is returned if no matches are found. 
     544     */ 
     545    getLayersByType: function(match) { 
     546        return this.getLayersBy("CLASS_NAME", match); 
     547    }, 
     548 
     549    /** 
     550     * APIMethod: getControlsBy 
     551     * Get a list of controls with properties matching the given criteria. 
     552     * 
     553     * Parameter: 
     554     * property - {String} A control property to be matched. 
     555     * match - {String | Object} A string to match.  Can also be a regular 
     556     *     expression literal or object.  In addition, it can be any object 
     557     *     with a method named test.  For reqular expressions or other, if 
     558     *     match.test(layer[property]) evaluates to true, the layer will be 
     559     *     included in the array returned.  If no layers are found, an empty 
     560     *     array is returned. 
     561     * 
     562     * Returns: 
     563     * {Array(<OpenLayers.Control>)} A list of controls matching the given 
     564     *     criteria.  An empty array is returned if no matches are found. 
     565     */ 
     566    getControlsBy: function(property, match) { 
     567        return this.getBy("controls", property, match); 
     568    }, 
     569 
     570    /** 
     571     * APIMethod: getControlsByType 
     572     * Get a list of controls of a given type (CLASS_NAME). 
     573     * 
     574     * Parameter: 
     575     * match - {String | Object} A control class name.  The type can also be a 
     576     *     regular expression literal or object.  In addition, it can be any 
     577     *     object with a method named test.  For reqular expressions or other, 
     578     *     if type.test(control.CLASS_NAME) evaluates to true, the control will 
     579     *     be included in the list of controls returned.  If no controls are 
     580     *     found, an empty array is returned. 
     581     * 
     582     * Returns: 
     583     * {Array(<OpenLayers.Control>)} A list of controls matching the given type. 
     584     *     An empty array is returned if no matches are found. 
     585     */ 
     586    getControlsByType: function(match) { 
     587        return this.getControlsBy("CLASS_NAME", match); 
     588    }, 
    451589 
    452590  /********************************************************/ 
  • trunk/openlayers/tests/test_Map.html

    r5349 r5361  
    261261        var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, ["chicken"]); 
    262262        t.ok( gotLayer == null, "getLayer correctly returns null when layer not found"); 
     263    } 
     264 
     265    function test_Map_getLayersBy(t) { 
     266         
     267        var map = { 
     268            getBy: OpenLayers.Map.prototype.getBy, 
     269            getLayersBy: OpenLayers.Map.prototype.getLayersBy, 
     270            layers: [ 
     271                {foo: "foo", id: Math.random()}, 
     272                {foo: "bar", id: Math.random()}, 
     273                {foo: "foobar", id: Math.random()}, 
     274                {foo: "foo bar", id: Math.random()}, 
     275                {foo: "foo", id: Math.random()} 
     276            ] 
     277        }; 
     278 
     279        var cases = [ 
     280            { 
     281                got: map.getLayersBy("foo", "foo"), 
     282                expected: [map.layers[0], map.layers[4]], 
     283                message: "(string literal) got two layers matching foo" 
     284            }, { 
     285                got: map.getLayersBy("foo", "bar"), 
     286                expected: [map.layers[1]], 
     287                message: "(string literal) got one layer matching foo" 
     288            }, { 
     289                got: map.getLayersBy("foo", "barfoo"), 
     290                expected: [], 
     291                message: "(string literal) got empty array for no foo match" 
     292            }, { 
     293                got: map.getLayersBy("foo", /foo/), 
     294                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], 
     295                message: "(regexp literal) got three layers containing string" 
     296            }, { 
     297                got: map.getLayersBy("foo", /foo$/), 
     298                expected: [map.layers[0], map.layers[4]], 
     299                message: "(regexp literal) got three layers ending with string" 
     300            }, { 
     301                got: map.getLayersBy("foo", /\s/), 
     302                expected: [map.layers[3]], 
     303                message: "(regexp literal) got layer containing space" 
     304            }, { 
     305                got: map.getLayersBy("foo", new RegExp("BAR", "i")), 
     306                expected: [map.layers[1], map.layers[2], map.layers[3]], 
     307                message: "(regexp object) got layers ignoring case" 
     308            }, { 
     309                got: map.getLayersBy("foo", {test: function(str) {return str.length > 3;}}), 
     310                expected: [map.layers[2], map.layers[3]], 
     311                message: "(custom object) got layers with foo length greater than 3" 
     312            } 
     313        ]; 
     314        t.plan(cases.length); 
     315        for(var i=0; i<cases.length; ++i) { 
     316            t.eq(cases[i].got, cases[i].expected, cases[i].message); 
     317        } 
     318         
     319    } 
     320 
     321    function test_Map_getLayersByName(t) { 
     322         
     323        var map = { 
     324            getBy: OpenLayers.Map.prototype.getBy, 
     325            getLayersBy: OpenLayers.Map.prototype.getLayersBy, 
     326            getLayersByName: OpenLayers.Map.prototype.getLayersByName, 
     327            layers: [ 
     328                {name: "foo", id: Math.random()}, 
     329                {name: "bar", id: Math.random()}, 
     330                {name: "foobar", id: Math.random()}, 
     331                {name: "foo bar", id: Math.random()}, 
     332                {name: "foo", id: Math.random()} 
     333            ] 
     334        }; 
     335 
     336        var cases = [ 
     337            { 
     338                got: map.getLayersByName("foo"), 
     339                expected: [map.layers[0], map.layers[4]], 
     340                message: "(string literal) got two layers matching name" 
     341            }, { 
     342                got: map.getLayersByName("bar"), 
     343                expected: [map.layers[1]], 
     344                message: "(string literal) got one layer matching name" 
     345            }, { 
     346                got: map.getLayersByName("barfoo"), 
     347                expected: [], 
     348                message: "(string literal) got empty array for no match" 
     349            }, { 
     350                got: map.getLayersByName(/foo/), 
     351                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], 
     352                message: "(regexp literal) got three layers containing string" 
     353            }, { 
     354                got: map.getLayersByName(/foo$/), 
     355                expected: [map.layers[0], map.layers[4]], 
     356                message: "(regexp literal) got three layers ending with string" 
     357            }, { 
     358                got: map.getLayersByName(/\s/), 
     359                expected: [map.layers[3]], 
     360                message: "(regexp literal) got layer containing space" 
     361            }, { 
     362                got: map.getLayersByName(new RegExp("BAR", "i")), 
     363                expected: [map.layers[1], map.layers[2], map.layers[3]], 
     364                message: "(regexp object) got layers ignoring case" 
     365            }, { 
     366                got: map.getLayersByName({test: function(str) {return str.length > 3;}}), 
     367                expected: [map.layers[2], map.layers[3]], 
     368                message: "(custom object) got layers with name length greater than 3" 
     369            } 
     370        ]; 
     371        t.plan(cases.length); 
     372        for(var i=0; i<cases.length; ++i) { 
     373            t.eq(cases[i].got, cases[i].expected, cases[i].message); 
     374        } 
     375         
     376    } 
     377 
     378    function test_Map_getLayersByType(t) { 
     379         
     380        var map = { 
     381            getBy: OpenLayers.Map.prototype.getBy, 
     382            getLayersBy: OpenLayers.Map.prototype.getLayersBy, 
     383            getLayersByType: OpenLayers.Map.prototype.getLayersByType, 
     384            layers: [ 
     385                {CLASS_NAME: "foo", id: Math.random()}, 
     386                {CLASS_NAME: "bar", id: Math.random()}, 
     387                {CLASS_NAME: "foobar", id: Math.random()}, 
     388                {CLASS_NAME: "foo bar", id: Math.random()}, 
     389                {CLASS_NAME: "foo", id: Math.random()} 
     390            ] 
     391        }; 
     392 
     393        var cases = [ 
     394            { 
     395                got: map.getLayersByType("foo"), 
     396                expected: [map.layers[0], map.layers[4]], 
     397                message: "(string literal) got two layers matching type" 
     398            }, { 
     399                got: map.getLayersByType("bar"), 
     400                expected: [map.layers[1]], 
     401                message: "(string literal) got one layer matching type" 
     402            }, { 
     403                got: map.getLayersByType("barfoo"), 
     404                expected: [], 
     405                message: "(string literal) got empty array for no match" 
     406            }, { 
     407                got: map.getLayersByType(/foo/), 
     408                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], 
     409                message: "(regexp literal) got three layers containing string" 
     410            }, { 
     411                got: map.getLayersByType(/foo$/), 
     412                expected: [map.layers[0], map.layers[4]], 
     413                message: "(regexp literal) got three layers ending with string" 
     414            }, { 
     415                got: map.getLayersByType(/\s/), 
     416                expected: [map.layers[3]], 
     417                message: "(regexp literal) got layer containing space" 
     418            }, { 
     419                got: map.getLayersByType(new RegExp("BAR", "i")), 
     420                expected: [map.layers[1], map.layers[2], map.layers[3]], 
     421                message: "(regexp object) got layers ignoring case" 
     422            }, { 
     423                got: map.getLayersByType({test: function(str) {return str.length > 3;}}), 
     424                expected: [map.layers[2], map.layers[3]], 
     425                message: "(custom object) got layers with type length greater than 3" 
     426            } 
     427        ]; 
     428        t.plan(cases.length); 
     429        for(var i=0; i<cases.length; ++i) { 
     430            t.eq(cases[i].got, cases[i].expected, cases[i].message); 
     431        } 
     432         
     433    } 
     434 
     435    function test_Map_getControlsBy(t) { 
     436         
     437        var map = { 
     438            getBy: OpenLayers.Map.prototype.getBy, 
     439            getControlsBy: OpenLayers.Map.prototype.getControlsBy, 
     440            controls: [ 
     441                {foo: "foo", id: Math.random()}, 
     442                {foo: "bar", id: Math.random()}, 
     443                {foo: "foobar", id: Math.random()}, 
     444                {foo: "foo bar", id: Math.random()}, 
     445                {foo: "foo", id: Math.random()} 
     446            ] 
     447        }; 
     448 
     449        var cases = [ 
     450            { 
     451                got: map.getControlsBy("foo", "foo"), 
     452                expected: [map.controls[0], map.controls[4]], 
     453                message: "(string literal) got two controls matching foo" 
     454            }, { 
     455                got: map.getControlsBy("foo", "bar"), 
     456                expected: [map.controls[1]], 
     457                message: "(string literal) got one control matching foo" 
     458            }, { 
     459                got: map.getControlsBy("foo", "barfoo"), 
     460                expected: [], 
     461                message: "(string literal) got empty array for no foo match" 
     462            }, { 
     463                got: map.getControlsBy("foo", /foo/), 
     464                expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]], 
     465                message: "(regexp literal) got three controls containing string" 
     466            }, { 
     467                got: map.getControlsBy("foo", /foo$/), 
     468                expected: [map.controls[0], map.controls[4]], 
     469                message: "(regexp literal) got three controls ending with string" 
     470            }, { 
     471                got: map.getControlsBy("foo", /\s/), 
     472                expected: [map.controls[3]], 
     473                message: "(regexp literal) got control containing space" 
     474            }, { 
     475                got: map.getControlsBy("foo", new RegExp("BAR", "i")), 
     476                expected: [map.controls[1], map.controls[2], map.controls[3]], 
     477                message: "(regexp object) got layers ignoring case" 
     478            }, { 
     479                got: map.getControlsBy("foo", {test: function(str) {return str.length > 3;}}), 
     480                expected: [map.controls[2], map.controls[3]], 
     481                message: "(custom object) got controls with foo length greater than 3" 
     482            } 
     483        ]; 
     484        t.plan(cases.length); 
     485        for(var i=0; i<cases.length; ++i) { 
     486            t.eq(cases[i].got, cases[i].expected, cases[i].message); 
     487        } 
     488         
     489    } 
     490 
     491    function test_Map_getControlsByType(t) { 
     492         
     493        var map = { 
     494            getBy: OpenLayers.Map.prototype.getBy, 
     495            getControlsBy: OpenLayers.Map.prototype.getControlsBy, 
     496            getControlsByType: OpenLayers.Map.prototype.getControlsByType, 
     497            controls: [ 
     498                {CLASS_NAME: "foo", id: Math.random()}, 
     499                {CLASS_NAME: "bar", id: Math.random()}, 
     500                {CLASS_NAME: "foobar", id: Math.random()}, 
     501                {CLASS_NAME: "foo bar", id: Math.random()}, 
     502                {CLASS_NAME: "foo", id: Math.random()} 
     503            ] 
     504        }; 
     505 
     506        var cases = [ 
     507            { 
     508                got: map.getControlsByType("foo"), 
     509                expected: [map.controls[0], map.controls[4]], 
     510                message: "(string literal) got two controls matching type" 
     511            }, { 
     512                got: map.getControlsByType("bar"), 
     513                expected: [map.controls[1]], 
     514                message: "(string literal) got one control matching type" 
     515            }, { 
     516                got: map.getControlsByType("barfoo"), 
     517                expected: [], 
     518                message: "(string literal) got empty array for no match" 
     519            }, { 
     520                got: map.getControlsByType(/foo/), 
     521                expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]], 
     522                message: "(regexp literal) got three controls containing string" 
     523            }, { 
     524                got: map.getControlsByType(/foo$/), 
     525                expected: [map.controls[0], map.controls[4]], 
     526                message: "(regexp literal) got three controls ending with string" 
     527            }, { 
     528                got: map.getControlsByType(/\s/), 
     529                expected: [map.controls[3]], 
     530                message: "(regexp literal) got control containing space" 
     531            }, { 
     532                got: map.getControlsByType(new RegExp("BAR", "i")), 
     533                expected: [map.controls[1], map.controls[2], map.controls[3]], 
     534                message: "(regexp object) got controls ignoring case" 
     535            }, { 
     536                got: map.getControlsByType({test: function(str) {return str.length > 3;}}), 
     537                expected: [map.controls[2], map.controls[3]], 
     538                message: "(custom object) got controls with type length greater than 3" 
     539            } 
     540        ]; 
     541        t.plan(cases.length); 
     542        for(var i=0; i<cases.length; ++i) { 
     543            t.eq(cases[i].got, cases[i].expected, cases[i].message); 
     544        } 
     545         
    263546    } 
    264547