wiki:Future/ConvenienceApis

This page is part of the MapGuide Future section, where ideas are proposed and refined before being turned into RFCs (or discarded). Visit the Future page to view more!

Overview

This page is a living proposal for adding extra convenience methods to the MapGuide API

Motivation

There are common scenarios in MapGuide application development where there is still lots of boilerplate code required to achieve desired tasks. Some of these scenarios are described below

Simplifying feature manipulation

Inserting features

The current process of inserting features is currently:

  1. Create a MgFeatureCommandCollection?
  2. Create a MgPropertyCollection?
  3. Populate the property collection with desired property values
  4. Create a MgInsertFeatures?
  5. Add the property collection to the MgInsertFeatures? command
  6. Add the MgInsertFeatures? command to the MgFeatureCommandCollection?
  7. Execute MgFeatureService::UpdateFeatures? passing in the feature source id and the command collection and to specify whether this should be transactional or not
  8. Process each individual result of the UpdateFeatures?() call, taking note of any thrown exceptions (non-transactional) and open feature readers

There is a lot of object creation and setup to insert a feature. Inserting multiple features increases the number of objects created and boilerplate code.

mg-desktop provides a simplified API for inserting features, that should also be brought over to the MapGuide API:

class MG_PLATFORMBASE_API MgFeatureService : public MgService
{
PUBLISHED_API:
    MgFeatureReader* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props);
    MgFeatureReader* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, MgTransaction* trans);
    MgPropertyCollection* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues);
    MgPropertyCollection* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans);
};

class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable
{
PUBLISHED_API:
    MgFeatureReader* InsertFeatures(MgPropertyCollection* props);
    MgFeatureReader* InsertFeatures(MgPropertyCollection* props, MgTransaction* trans);
    MgPropertyCollection* InsertFeatures(MgBatchPropertyCollection* batchPropertyValues);
    MgPropertyCollection* InsertFeatures(MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans);
};

Under this simplified API, the process is now.

  1. Create a MgPropertyCollection? or MgBatchPropertyCollection?
  2. Load it up with the desired property values
  3. Execute InsertFeatures?(), passing in the feature source, the property collection and optionally a transaction.
  4. Close the open feature reader, or process the property collection (if using a MgBatchPropertyCollection?)

Updating features

The current process of update features is similarly complex:

  1. Create a MgFeatureCommandCollection?
  2. Create a MgPropertyCollection?
  3. Populate the property collection with desired property values to update
  4. Create a MgUpdateFeatures?
  5. Add the property collection to the MgUpdateFeatures? command
  6. Specify the update filter for the MgUpdateFeatures? command
  7. Add the MgUpdateFeaturescommand? to the MgFeatureCommandCollection?
  8. Execute MgFeatureService::UpdateFeatures? passing in the feature source id and the command collection and to specify whether this should be transactional or not
  9. Process each individual result of the UpdateFeatures?() call, taking note of any thrown exceptions (non-transactional) and open feature readers

There is a lot of object creation and setup to insert a feature. Inserting multiple features increases the number of objects created and boilerplate code.

mg-desktop provides a simplified API for updating features, that should also be brought over to the MapGuide API:

class MG_PLATFORMBASE_API MgFeatureService : public MgService
{
PUBLISHED_API:
    INT32 UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, CREFSTRING filter);
    INT32 UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, CREFSTRING filter, MgTransaction* trans);
};

class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable
{
PUBLISHED_API:
    INT32 UpdateFeatures(MgPropertyCollection* props, CREFSTRING filter);
    INT32 UpdateFeatures(MgPropertyCollection* props, CREFSTRING filter, MgTransaction* trans);
};

Under this simplified API, the process is now.

  1. Create a MgPropertyCollection?
  2. Load it up with the desired property values to update with
  3. Execute UpdateFeatures?(), passing in the feature source, the property collection, update filter and optionally a transaction.

Deleting Features

Querying transformed features

This API is currently not implemented in MapGuide

class MG_PLATFORMBASE_API MgFeatureService : public MgService
{
PUBLISHED_API:
    virtual MgFeatureReader* SelectFeatures(MgResourceIdentifier* resource,
                                            CREFSTRING className,
                                            MgFeatureQueryOptions* options,
                                            CREFSTRING coordinateSystem) = 0;
};

Having this API implemented would be very useful. Along the same theme of convenience, MgLayerBase? should have a shortcut form of the above API:

class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable
{
PUBLISHED_API:
    virtual MgFeatureReader* SelectFeatures(MgFeatureQueryOptions* options,
                                            CREFSTRING coordinateSystem);
};

Getting a layer icon

The process to get the legend image icon for a given MgLayer? instance is especially cumbersome as a lot of boilerplate code is required in fetching the associated layer definition and walking through its styles to get the matching geometry type and theme category required for a MgMappingService::GenerateLegendImage?() call.

Since MgLayer? possesses most of this knowledge, it makes sense to have convenience APIs in MgLayer? itself:

class MG_MAPGUIDE_API MgLayer : public MgLayerBase
{
PUBLISHED_API:
    //Gets the list of geometry type styles for this layer at the map's current scale. Returns NULL if there are no applicable geometry types
    MgIntCollection* GetGeometryTypeStyles();
    //Gets the number of theme categories for this layer at the map's current scale for the given geometry type style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the current scale
    INT32 GetThemeCategoryCount(INT32 geomType);
    //Gets the legend image icon for this layer at the at the map's current scale for the given geometry type style and theme category. Returns NULL if there is no applicable icon at the given scale/geomType/themeCategory
    MgByteReader* GenerateLegendImage(INT32 width, INT32 height, CREFSTRING format, INT32 geomType, INT32 themeCategory);

    //Gets the list of geometry type styles for this layer at the given scale. Returns NULL if there are not applicable geometry types
    MgIntCollection* GetGeometryTypeStyles(double scale);
    //Gets the number of theme categories for this layer at the given scale for the given geometry type style. A count greater than 1 indicates a themed layer. Returns -1 if there are no applicable styles at the given scale
    INT32 GetThemeCategoryCount(double scale, INT32 geomType);
    //Gets the legend image icon for this layer at the at the given scale for the given geometry type style and theme category. Returns NULL if there is no applicable icon at the given scale/geomType/themeCategory
    MgByteReader* GenerateLegendImage(double scale, INT32 width, INT32 height, CREFSTRING format, INT32 geomType, INT32 themeCategory);
};

Converting between various geometry forms

Last modified 4 years ago Last modified on Jul 23, 2013 11:05:16 PM