[76] | 1 | .. highlight:: javascript |
---|
| 2 | :linenothreshold: 4 |
---|
| 3 | |
---|
| 4 | ==================== |
---|
| 5 | Vector Data Tutorial |
---|
| 6 | ==================== |
---|
| 7 | |
---|
| 8 | Base layers such as OpenStreetMap and Google Maps are generally distributed in |
---|
| 9 | pre-rendered tiles using file formats such as PNG or JPG. While these are great |
---|
| 10 | for **displaying** maps, they are not very useful for getting at the data behind |
---|
| 11 | a map. They don't allow you to provide functionality such as informational |
---|
| 12 | popups, selection and highlighting of individual features, and editing of data. |
---|
| 13 | For these, you need to use **vector data**, provided through file formats such |
---|
| 14 | as KML, GeoJSON, or GML which provide information about each feature on the map, |
---|
| 15 | rather than just the pixels to put on the screen. |
---|
| 16 | |
---|
| 17 | .. note:: Web browsers impose a same origin policy on JavaScript code to protect |
---|
| 18 | users from cross-site scripting attacks. This means that if your GeoExt |
---|
| 19 | application is hosted on a different host or port from your vector data, you |
---|
| 20 | will need to configure a proxy service. |
---|
| 21 | |
---|
| 22 | Reading KML |
---|
| 23 | =========== |
---|
| 24 | |
---|
| 25 | As an introduction to using vector data in GeoExt, let's create a simple map |
---|
| 26 | that displays data from a KML. Copy :download:`this sample KML file |
---|
| 27 | <sundials.kml>` to the same directory with your GeoExt and Ext libraries. Then |
---|
| 28 | we can load it with some JavaScript:: |
---|
| 29 | |
---|
| 30 | var map = new Openlayers.Map(); |
---|
| 31 | var bluemarble = new OpenLayers.Layer.WMS( |
---|
| 32 | "Global Imagery", |
---|
| 33 | "http://maps.opengeo.org/geowebcache/service/wms", |
---|
| 34 | {layers: "bluemarble"} |
---|
| 35 | ); |
---|
| 36 | var sundials = new OpenLayers.Layer.Vector("Sundials"); |
---|
| 37 | map.addLayer(bluemarble); |
---|
| 38 | map.addLayer(sundials); |
---|
| 39 | |
---|
| 40 | var store = new GeoExt.data.FeatureStore({ |
---|
| 41 | layer: sundials, |
---|
| 42 | proxy: new GeoExt.data.ProtocolProxy({ |
---|
| 43 | protocol: new OpenLayers.Protocol.HTTP({ |
---|
| 44 | url: "sundials.kml", |
---|
| 45 | format: new OpenLayers.Format.KML() |
---|
| 46 | }) |
---|
| 47 | }), |
---|
| 48 | fields: [ |
---|
| 49 | {name: 'title', type: 'string'}, |
---|
| 50 | {name: 'description', type: 'string'} |
---|
| 51 | ], |
---|
| 52 | autoLoad: true |
---|
| 53 | }); |
---|
| 54 | |
---|
| 55 | var mapPanel = new GeoExt.MapPanel({ |
---|
| 56 | title: "Sundials", |
---|
| 57 | map: map, |
---|
| 58 | renderTo: 'mapPanel', |
---|
| 59 | height: 400, |
---|
| 60 | width: 600 |
---|
| 61 | }); |
---|
| 62 | |
---|
| 63 | Here, we set up a map with two layers. ``bluemarble`` is a WMS layer, which you |
---|
| 64 | should have seen before in other tutorials. ``sundials`` is a vector layer, |
---|
| 65 | which handles client-side rendering of vector data. |
---|
| 66 | |
---|
| 67 | In **line 10** we initialize a :class:`GeoExt.data.FeatureStore`\ . This class |
---|
| 68 | functions as a normal ``Ext.data.Store`` to interoperate with ExtJS classes, as |
---|
| 69 | well as providing the ability to **bind** to an ``OpenLayers.Layer.Vector`` in |
---|
| 70 | order to display features on a map. In this example, we set up the store |
---|
| 71 | completely through constructor parameters: |
---|
| 72 | |
---|
| 73 | ``layer: sundials`` |
---|
| 74 | tells the store to render features using the ``sundials`` layer. This is |
---|
| 75 | equivalent to calling ``store.bind(sundials)`` after initializing the |
---|
| 76 | store. |
---|
| 77 | |
---|
| 78 | ``proxy: new GeoExt.data.ProtocolProxy(`` |
---|
| 79 | tells the store to use a ``ProtocolProxy`` for fetching features. |
---|
| 80 | ``ProtocolProxy`` wraps OpenLayers Protocol objects. Here we use an |
---|
| 81 | ``OpenLayers.Protocol.HTTP`` to fetch data over the web. The ``HTTP`` |
---|
| 82 | protocol works with a variety of ``OpenLayers.Format`` types; here we |
---|
| 83 | use ``KML`` to match our dataset. You can see all the available |
---|
| 84 | ``Protocol``\ s and ``Format``\ s in the `OpenLayers API documentation |
---|
| 85 | <http://openlayers.org>`_. |
---|
| 86 | |
---|
| 87 | ``fields: [...]`` |
---|
| 88 | tells the store which extra properties (aside from just the geometry) to |
---|
| 89 | look for. Here, we know that KML includes a ``title`` and a |
---|
| 90 | ``description`` for each point, and that both are string values. |
---|
| 91 | |
---|
| 92 | ``autoLoad: true`` |
---|
| 93 | tells the store to go ahead and fetch the feature data as soon as the |
---|
| 94 | constructor finishes. This is equivalent to calling ``store.load()`` |
---|
| 95 | after the store is initialized. |
---|
| 96 | |
---|
| 97 | Now we have a map with a background and some data hosted on our server. It looks |
---|
| 98 | like any other map; we can pan and zoom normally to navigate around. |
---|
| 99 | |
---|
| 100 | However, since GeoExt has access to the data *behind* the map, we now have some |
---|
| 101 | options that weren't available to us before. For example, we can add a control |
---|
| 102 | that allows us to view the features in a tabular format:: |
---|
| 103 | |
---|
| 104 | new Ext.grid.GridPanel({ |
---|
| 105 | title: 'Sundials', |
---|
| 106 | store: store |
---|
| 107 | columns: [{heading: 'Title', dataIndex: 'title'}, |
---|
| 108 | {heading: 'Description', dataIndex: 'description'}], |
---|
| 109 | renderTo: "grid", |
---|
| 110 | width: 200, |
---|
| 111 | height: 600 |
---|
| 112 | }); |
---|
| 113 | |
---|