Designing the application

Let's take a closer look at the various parts of the ShapeEditor to see what's involved in implementing it.

Importing a Shapefile

When the user imports a Shapefile, we have to store the contents of that Shapefile into the database so that GeoDjango can work with it. Because we don't know in advance what types of geometries the Shapefile will contain, or what attributes might be associated with each feature, we need to have a generic representation of a Shapefile's contents in the database rather than defining separate fields in the database for each of the Shapefile's attributes. To support this, we'll use the following collection of database objects:

Importing a Shapefile

Each imported Shapefile will be represented by a single Shapefile object in the database. Each Shapefile object will have a set of Attribute objects, which define the name and data type for each attribute within the Shapefile. The Shapefile object will also have a set of Feature objects, one for each imported feature. The Feature object will hold the feature's geometry, and will in turn have a set of AttributeValue objects holding the value of each attribute for that feature.

To see how this works, let's imagine that we import the World Borders Dataset into the ShapeEditor. The first feature in this Shapefile would be stored in the database in the following way:

Importing a Shapefile

The Shapefile object represents the uploaded TM_WORLD_BORDERS-0.3.shp Shapefile, and has a number of Attribute objects associated with it, one for each attribute in the Shapefile. There are a number of Feature objects associated with the Shapefile; the feature shown in the above image represents Antigua and Barbuda. The MultiPolygon geometry for this feature is stored in the Feature object, and has a number of AttributeValue objects holding the individual attribute values for this feature.

While this is a somewhat roundabout way of storing Shapefile data in a database (it would be more common to use the ogrinspect.py utility to create a static GeoDjango model out of the Shapefile's features), we have to do this because we don't know the Shapefile's structure ahead of time, and don't want to be constantly adding a new database table whenever a Shapefile is imported.

With this basic model in place to store a Shapefile's data in the database, we can continue designing the rest of the "Import Shapefile" logic.

Because Shapefiles are represented on disk by a number of separate files, we will expect the user to create a ZIP archive out of the Shapefile and upload the zipped Shapefile. This saves us having to handle multiple file uploads for a single Shapefile, and makes things more convenient for the user as Shapefiles often come in ZIP format already.

Once the ZIP archive has been uploaded, our code will need to decompress the archive and extract the individual files that make up the Shapefile. We'll then have to read through the Shapefile to find its attributes, create the appropriate Attribute objects, and then process the Shapefile's features one at a time, creating Feature and AttributeValue objects as we go. All of this will be quite straightforward to implement.

Selecting a feature

Before the user can edit a feature, we have to let the user select the desired feature. Unfortunately, this is an area where GeoDjango's built-in editing code lets us down: the GeoDjango admin module displays a text-based list of the features, and only shows a map once a particular feature has been selected. This is because GeoDjango can only display a single feature on a map at once thanks to the way GeoDjango's geometry editor has been implemented.

This isn't really suitable for the ShapeEditor as we have no useful information to display to the user, and simply seeing a list of attribute values isn't going to be very helpful. Instead, we will bypass GeoDjango's built-in editor and instead use OpenLayers directly to display a map showing all the features in the imported Shapefile. We'll then let the user click on a feature to select it for editing.

Here is how we'll implement this particular feature:

Selecting a feature

OpenLayers needs to have a source of map files to display, so we'll create our own simple Tile Map Server (TMS) built on top of a Mapnik-based map renderer to display the Shapefile's features stored in the database. We'll also write a simple "click handler" in JavaScript which intercepts clicks on the map and sends off an AJAX request to the server to see which feature the user clicked on. If the user does click on a feature (rather than just clicking on the map's background), the user's web browser will be redirected to the "Edit Feature" page so that the user can edit the clicked-on feature.

There's a lot here, requiring a fair amount of custom coding, but the end result is a friendly interface to ShapeEditor allowing the user to quickly point-and-click at a desired feature to edit it. In the process of building all this, we'll also learn how to use OpenLayers directly within a GeoDjango application, and how to implement our own Tile Map Server built on top of Mapnik.

Editing a feature

To let the user edit the feature, we'll use GeoDjango's built-in geo-spatial editing widget. There is a slight amount of work required here because we want to use this widget outside of GeoDjango's admin interface and will need to customize the interface slightly.

The only other issue that needs to be dealt with is the fact that we don't know in advance what type of feature we'll be editing. Shapefiles can hold any type of geometry, from Points and LineStrings through to MultiPolygons and GeometryCollections. Fortunately, all the features in a Shapefile have to have the same geometry type, so we can store the geometry type in the Shapefile object and use it to select the appropriate editor when editing that Shapefile's features.

Exporting a Shapefile

Exporting a Shapefile involves the reverse of the "Import Shapefile" process: we have to create a new Shapefile on disk, define the various attributes which will be stored in the Shapefile, and then process all the features and their attributes, writing them out to disk one at a time. Once this has been done, we can create a ZIP archive from the contents of the shapefile, and tell the user's web browser to download that ZIP archive to the user's hard disk.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.187.113