[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