[Commits] r1302 - in core/trunk/geoext: examples examples/data lib lib/GeoExt/data tests tests/lib/GeoExt/data

commits at geoext.org commits at geoext.org
Tue Aug 4 23:05:17 CEST 2009


Author: tschaub
Date: 2009-08-04 23:05:17 +0200 (Tue, 04 Aug 2009)
New Revision: 1302

Added:
   core/trunk/geoext/examples/attributes.html
   core/trunk/geoext/examples/attributes.js
   core/trunk/geoext/examples/data/describe_feature_type.xml
   core/trunk/geoext/lib/GeoExt/data/AttributeReader.js
   core/trunk/geoext/lib/GeoExt/data/AttributeStore.js
   core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.html
   core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.js
Modified:
   core/trunk/geoext/lib/GeoExt.js
   core/trunk/geoext/tests/list-tests.html
Log:
Adding an AttributeReader and AttributeStore.  By default, the latter is configured with an instance of the former, which uses an OL WFSDescribeFeatureType format to parse feature type schema.  The store can also be configured with an array of attributes.  r=elemoine (closes #17)

Added: core/trunk/geoext/examples/attributes.html
===================================================================
--- core/trunk/geoext/examples/attributes.html	                        (rev 0)
+++ core/trunk/geoext/examples/attributes.html	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,23 @@
+<html>
+    <head>
+        <title>GeoExt AttributeReader and AttributeStore</title>
+
+        <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.js"></script>
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+        <script src="http://openlayers.org/api/2.8/OpenLayers.js"></script>
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+        <script type="text/javascript" src="attributes.js"></script>
+
+    </head>
+    <body>
+        <h1>AttributeReader and AttributeStore</h1>
+        <p>This is example that shows how create an AttributeStore with
+        records read from a WFS DescribeFeatureType response.</p>
+
+        <p>Note that the js is not minified so it is readable.
+        See <a href="attributes.js">attributes.js</a>.</p>
+
+    </body>
+</html>

Added: core/trunk/geoext/examples/attributes.js
===================================================================
--- core/trunk/geoext/examples/attributes.js	                        (rev 0)
+++ core/trunk/geoext/examples/attributes.js	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+var store;
+Ext.onReady(function() {
+    
+    // create a new attributes store
+    store = new GeoExt.data.AttributeStore({
+        url: "data/describe_feature_type.xml"
+    });
+    store.load();
+
+    // create a grid to display records from the store
+    var grid = new Ext.grid.GridPanel({
+        title: "Feature Attributes",
+        store: store,
+        cm: new Ext.grid.ColumnModel([
+            {id: "name", header: "Name", dataIndex: "name", sortable: true},
+            {id: "type", header: "Type", dataIndex: "type", sortable: true}
+        ]),
+        sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
+        autoExpandColumn: "name",
+        renderTo: document.body,
+        height: 300,
+        width: 350
+    });    
+
+});

Added: core/trunk/geoext/examples/data/describe_feature_type.xml
===================================================================
--- core/trunk/geoext/examples/data/describe_feature_type.xml	                        (rev 0)
+++ core/trunk/geoext/examples/data/describe_feature_type.xml	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><xs:schema  targetNamespace="http://www.openplans.org/topp"  xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"><xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://localhost:8080/geoserver/schemas/gml/2.1.2.1/feature.xsd"/><xs:complexType xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" name="states_Type"><xs:complexContent><xs:extension base="gml:AbstractFeatureType"><xs:sequence><xs:element name="the_geom" minOccurs="0" nillable="true" type="gml:MultiPolygonPropertyType"/><xs:element name="STATE_NAME" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2147483647"/></xs:restriction></xs:simpleType></xs:element><xs:element name="STATE_FIPS" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2147483647"/></xs:restriction></xs:simpleType></xs:element><xs:element name="SUB_REGION" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2147483647"/></xs:restriction></xs:simpleType></xs:element><xs:element name="STATE_ABBR" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2147483647"/></xs:restriction></xs:simpleType></xs:element><xs:element name="LAND_KM" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="WATER_KM" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="PERSONS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="FAMILIES" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="HOUSHOLD" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="MALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="FEMALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="WORKERS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="DRVALONE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="CARPOOL" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="PUBTRANS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="EMPLOYED" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="UNEMPLOY" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="SERVICE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="MANUAL" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="P_MALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="P_FEMALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="SAMP_POP" minOccurs="0" nillable="true" type="xs:double"/></xs:sequence></xs:extension></xs:complexContent></xs:complexType><xs:element name="states" type="topp:states_Type" substitutionGroup="gml:_Feature"/></xs:schema>
\ No newline at end of file

Added: core/trunk/geoext/lib/GeoExt/data/AttributeReader.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/data/AttributeReader.js	                        (rev 0)
+++ core/trunk/geoext/lib/GeoExt/data/AttributeReader.js	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+/** api: (define)
+ *  module = GeoExt.data
+ *  class = AttributeReader
+ *  base_link = `Ext.data.DataReader <http://extjs.com/deploy/dev/docs/?class=Ext.data.DataReader>`_
+ */
+Ext.namespace("GeoExt.data");
+
+/** api: constructor
+ *  .. class:: AttributeReader(meta, recordType)
+ *  
+ *      :arg meta: ``Object`` Reader configuration.
+ *      :arg recordType: ``Array or Ext.data.Record`` An array of field
+ *          configuration objects or a record object.
+ *
+ *      Create a new attributes reader object.
+ *      
+ *      Valid meta properties:
+ *      
+ *      * format - ``OpenLayers.Format`` A parser for transforming the XHR response
+ *        into an array of objects representing attributes.  Defaults to
+ *        an ``OpenLayers.Format.WFSDescribeFeatureType`` parser.
+ *      * ignore - ``Object`` Properties of the ignore object should be field names.
+ *        Values are either arrays or regular expressions.
+ */
+GeoExt.data.AttributeReader = function(meta, recordType) {
+    meta = meta || {};
+    if(!meta.format) {
+        meta.format = new OpenLayers.Format.WFSDescribeFeatureType();
+    }
+    GeoExt.data.AttributeReader.superclass.constructor.call(
+        this, meta, recordType || meta.fields
+    );
+};
+
+Ext.extend(GeoExt.data.AttributeReader, Ext.data.DataReader, {
+
+    /** private: method[read]
+     *  :arg request: ``Object`` The XHR object that contains the parsed doc.
+     *  :return: ``Object``  A data block which is used by an ``Ext.data.Store``
+     *      as a cache of ``Ext.data.Records``.
+     *  
+     *  This method is only used by a DataProxy which has retrieved data from a
+     *  remote server.
+     */
+    read: function(request) {
+        var data = request.responseXML;
+        if(!data || !data.documentElement) {
+            data = request.responseText;
+        }
+        return this.readRecords(data);
+    },
+
+    /** private: method[readRecords]
+     *  :arg data: ``DOMElement or String or Array`` A document element or XHR
+     *      response string.  As an alternative to fetching attributes data from
+     *      a remote source, an array of attribute objects can be provided given
+     *      that the properties of each attribute object map to a provided field
+     *      name.
+     *  :return: ``Object`` A data block which is used by an ``Ext.data.Store``
+     *      as a cache of ``Ext.data.Records``.
+     *  
+     *  Create a data block containing Ext.data.Records from an XML document.
+     */
+    readRecords: function(data) {
+        var attributes;
+        if(data instanceof Array) {
+            attributes = data;
+        } else {
+            // only works with one featureType in the doc
+            attributes = this.meta.format.read(data).featureTypes[0].properties;
+        }
+        var recordType = this.recordType;
+        var fields = recordType.prototype.fields;
+        var numFields = fields.length;
+        var attr, values, name, record, ignore, matches, value, records = [];
+        for(var i=0, len=attributes.length; i<len; ++i) {
+            ignore = false;
+            attr = attributes[i];
+            values = {};
+            for(var j=0; j<numFields; ++j) {
+                name = fields.items[j].name;
+                value = attr[name];
+                if(this.meta.ignore && this.meta.ignore[name]) {
+                    matches = this.meta.ignore[name];
+                    if(typeof matches == "string") {
+                        ignore = (matches === value);
+                    } else if(matches instanceof Array) {
+                        ignore = (matches.indexOf(value) > -1);
+                    } else if(matches instanceof RegExp) {
+                        ignore = (matches.test(value));
+                    }
+                    if(ignore) {
+                        break;
+                    }
+                }
+                values[name] = attr[name];
+            }
+            if(!ignore) {
+                records[records.length] = new recordType(values);
+            }
+        }
+
+        return {
+            success: true,
+            records: records,
+            totalRecords: records.length
+        };
+
+    }
+
+});

Added: core/trunk/geoext/lib/GeoExt/data/AttributeStore.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/data/AttributeStore.js	                        (rev 0)
+++ core/trunk/geoext/lib/GeoExt/data/AttributeStore.js	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+/**
+ * @include GeoExt/data/AttributeReader.js
+ */
+
+/** api: (define)
+ *  module = GeoExt.data
+ *  class = AttributeStore
+ *  base_link = `Ext.data.DataStore <http://extjs.com/deploy/dev/docs/?class=Ext.data.DataStore>`_
+ */
+Ext.namespace("GeoExt.data");
+
+/** api: constructor
+ *  .. class:: AttributeStore(config)
+ *  
+ *      Small helper class to make creating stores for remotely-loaded attributes
+ *      data easier. AttributeStore is pre-configured with a built-in
+ *      ``Ext.data.HttpProxy`` and :class:`gxp.data.AttributeReader`.  The
+ *      HttpProxy is configured to allow caching (disableCaching: false) and
+ *      uses GET. If you require some other proxy/reader combination then you'll
+ *      have to configure this with your own proxy or create a basic
+ *      ``Ext.data.Store`` and configure as needed.
+ */
+
+/** api: config[format]
+ *  ``OpenLayers.Format``
+ *  A parser for transforming the XHR response into an array of objects
+ *  representing attributes.  Defaults to an
+ *  ``OpenLayers.Format.WFSDescribeFeatureType`` parser.
+ */
+
+/** api: config[fields]
+ *  ``Array or Function``
+ *  Either an array of field definition objects as passed to
+ *  ``Ext.data.Record.create``, or a record constructor created using
+ *  ``Ext.data.Record.create``.  Defaults to ``["name", "type"]``. 
+ */
+GeoExt.data.AttributeStore = function(c) {
+    GeoExt.data.AttributeStore.superclass.constructor.call(
+        this,
+        Ext.apply(c, {
+            proxy: c.proxy || (!c.data ?
+                new Ext.data.HttpProxy({url: c.url, disableCaching: false, method: "GET"}) :
+                undefined
+            ),
+            reader: new GeoExt.data.AttributeReader(
+                c, c.fields || ["name", "type"]
+            )
+        })
+    );
+};
+Ext.extend(GeoExt.data.AttributeStore, Ext.data.Store);
\ No newline at end of file

Modified: core/trunk/geoext/lib/GeoExt.js
===================================================================
--- core/trunk/geoext/lib/GeoExt.js	2009-08-02 18:17:28 UTC (rev 1301)
+++ core/trunk/geoext/lib/GeoExt.js	2009-08-04 21:05:17 UTC (rev 1302)
@@ -64,6 +64,8 @@
      */
     if(!singleFile) {
         var jsfiles = new Array(
+            "GeoExt/data/AttributeReader.js",
+            "GeoExt/data/AttributeStore.js",
             "GeoExt/data/FeatureRecord.js",
             "GeoExt/data/FeatureReader.js",
             "GeoExt/data/FeatureStore.js",

Added: core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.html
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.html	                        (rev 0)
+++ core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.html	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html debug="true">
+  <head>
+    <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script>
+    <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script>
+
+    <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script>
+    <script type="text/javascript" src="../../../../lib/GeoExt.js"></script>
+    <script type="text/javascript" src="AttributeReader.js"></script>
+
+    <script type="text/javascript">
+
+    function test_read(t) {
+        t.plan(3);
+
+        var reader = new GeoExt.data.AttributeReader({}, [
+            "name",
+            "type"
+        ]);
+
+        var records = reader.read({responseXML : doc});
+
+        //1 test
+        t.eq(records.totalRecords, 23, 'readRecords returns correct number of records');
+
+        var record = records.records[2];
+
+        //2 tests -- testing the fields of a record
+        t.eq(record.get("name"), "STATE_FIPS", "[2] correct attribute name");
+        t.eq(record.get("type"), "xsd:string", "[2] correct attribute type name");
+
+    }
+
+    function test_ignoreString(t) {
+        t.plan(1);
+
+        var reader = new GeoExt.data.AttributeReader({
+            ignore: {type: "xsd:string"}
+        }, [
+            "name",
+            "type"
+        ]);
+
+        var records = reader.read({responseXML : doc});
+
+        //1 test
+        t.eq(records.totalRecords, 19, 'right number of records are ignored (ignores String)');
+    }
+
+    function test_ignoreArray(t) {
+         t.plan(1);
+
+         var reader = new GeoExt.data.AttributeReader({
+             ignore: {type: ["xsd:double", "gml:MultiSurfacePropertyType"]}
+         }, [
+             "name",
+             "type"
+         ]);
+
+         var records = reader.read({responseXML : doc});
+
+         //1 test
+         t.eq(records.totalRecords, 4, 'right number of records are ignored (ignores Array)');
+    }
+
+    function test_ignoreRegexp(t) {
+        t.plan(1);
+
+        var reader = new GeoExt.data.AttributeReader({
+            ignore: {name: new RegExp('^S')}
+        }, [
+            "name",
+            "type"
+        ]);
+
+        var records = reader.read({responseXML : doc});
+
+        //1 test
+        t.eq(records.totalRecords, 17, 'right number of records are ignored (ignores RegExp)');
+    }
+
+    </script>
+  <body>
+    <div id="map"></div>
+  </body>
+</html>

Added: core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.js
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.js	                        (rev 0)
+++ core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.js	2009-08-04 21:05:17 UTC (rev 1302)
@@ -0,0 +1,39 @@
+var doc = (new OpenLayers.Format.XML).read(
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:topp="http://www.openplans.org/topp" elementFormDefault="qualified" targetNamespace="http://www.openplans.org/topp">' +
+  '<xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://sigma.openplans.org:80/geoserver/schemas/gml/3.1.1/base/gml.xsd"/>' +
+  '<xsd:complexType name="statesType">' +
+    '<xsd:complexContent>' +
+      '<xsd:extension base="gml:AbstractFeatureType">' +
+        '<xsd:sequence>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="the_geom" nillable="true" type="gml:MultiSurfacePropertyType"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_NAME" nillable="true" type="xsd:string"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_FIPS" nillable="true" type="xsd:string"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="SUB_REGION" nillable="true" type="xsd:string"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_ABBR" nillable="true" type="xsd:string"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="LAND_KM" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="WATER_KM" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="PERSONS" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="FAMILIES" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="HOUSHOLD" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="MALE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="FEMALE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="WORKERS" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="DRVALONE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="CARPOOL" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="PUBTRANS" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="EMPLOYED" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="UNEMPLOY" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="SERVICE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="MANUAL" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="P_MALE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="P_FEMALE" nillable="true" type="xsd:double"/>' +
+          '<xsd:element maxOccurs="1" minOccurs="0" name="SAMP_POP" nillable="true" type="xsd:double"/>' +
+        '</xsd:sequence>' +
+      '</xsd:extension>' +
+    '</xsd:complexContent>' +
+  '</xsd:complexType>' +
+  '<xsd:element name="states" substitutionGroup="gml:_Feature" type="topp:statesType"/>' +
+'</xsd:schema>'
+);
+

Modified: core/trunk/geoext/tests/list-tests.html
===================================================================
--- core/trunk/geoext/tests/list-tests.html	2009-08-02 18:17:28 UTC (rev 1301)
+++ core/trunk/geoext/tests/list-tests.html	2009-08-04 21:05:17 UTC (rev 1302)
@@ -1,5 +1,6 @@
 <ul id="testlist">
   <li>lib/GeoExt/adapter/override-ext-ajax.html</li>
+  <li>lib/GeoExt/data/AttributeReader.html</li>
   <li>lib/GeoExt/data/FeatureRecord.html</li>
   <li>lib/GeoExt/data/FeatureReader.html</li>
   <li>lib/GeoExt/data/FeatureStore.html</li>



More information about the Commits mailing list