.. _geoext.wfs.layer: A Synchronized Map and Table View of Vector Features ==================================================== In Ext JS, grids can not only have a store and a column model, but also a selection model. The FeatureStore provides everything to synchronize itself with the features of an OpenLayers vector layer, and the `GeoExt.grid.FeatureSelectionModel `_ can be used to synchronize highlighting (feature selection) between layer and grid. Let the Layer Fetch the Features, not the Store ----------------------------------------------- We will now configure a vector layer with the WFS protocol and get rid of the ProtocolProxy. .. rubric:: Tasks #. Open :file:`wfs-editor.html` again in your text editor. Find the store definition, and add the following code above it to create a layer: .. code-block:: javascript var layer = new OpenLayers.Layer.Vector("vector", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.WFS({ url: "/geoserver/wms", version: "1.1.0", featureType: "poly_landmarks", featureNS: "http://www.census.gov", srsName: "EPSG:4326" }) }); #. Now remove the ``proxy`` and ``autoLoad`` properties from the store definition, and add a ``layer`` property pointing to the layer that we created above. .. code-block:: javascript var store = new GeoExt.data.FeatureStore({ fields: [ {name: "LANAME", type: "string"}, {name: "CFCC", type: "string"}, {name: "LAND", type: "float"}, {name: "AREA", type: "int", defaultValue: 10000} ], layer: layer }); The ``protocol`` property we added to the layer definition is exactly the same that we had in the ProtocolProxy configuration in the :ref:`previous version `. Adding a MapPanel to Display The Layer -------------------------------------- Configured like above, our application does the same as before. The only difference is that OpenLayers takes care of loading features now. This means that unless we add the layer to a map, features won't be loaded, and we won't see anything in the grid. So let's add a map to our application. .. rubric:: Tasks #. Create a map panel. To do so, add the following code above the gridPanel definition: .. code-block:: javascript var mapPanel = new GeoExt.MapPanel({ title: "Map", region: "west", width: 400, layers: [layer], extent: new OpenLayers.Bounds(-74.047, 40.68, -73.908, 40.882) }); #. Add the mapPanel to the application's main panel, by modifying the main panel definition to look like this: .. code-block:: javascript var mainPanel = new Ext.Panel({ renderTo: document.body, layout: "border", height: 450, width: 800, items: [gridPanel, mapPanel] }); Now the application has a map window with a vector layer sharing its content with the grid. Synchronizing Feature Selection between Map and Grid ---------------------------------------------------- We are almost there. We just have to add some code to enable feature selection on the layer and synchronize it with the grid. Surprisingly, this requires just one line of code. .. rubric:: Tasks #. Configure the grid with a FeatureSelectionModel to get feature selection (highlighting) synchronized between map and grid. Your gridPanel definition should now start like this: .. code-block:: javascript var gridPanel = new Ext.grid.GridPanel({ title: "Feature Table - Manhattan (NY) landmarks", region: "center", viewConfig: {forceFit: true}, store: store, sm: new GeoExt.grid.FeatureSelectionModel(), cm: new Ext.grid.ColumnModel({ #. Save your changes. Open or reload @workshop_url@/wfs-editor.html in your browser. Select some features in the map and/or in the feature table and see how they synchronize. .. figure:: layer.png Map and table view of vector features with synchronized highlighting. What's Next? ------------ Having a map viewer like this is really close to a Desktop GIS. But for the ultimate user experience, we have to add editing capabilities. This is explained in the :ref:`next section `.