| 1 | [[PageOutline]] |
| 2 | |
| 3 | This page is part of the [wiki:Future MapGuide Future] section, where ideas are proposed and refined |
| 4 | before being turned into RFCs (or discarded). Visit the [wiki:Future] page to view more! |
| 5 | |
| 6 | = Overview = |
| 7 | |
| 8 | This page is a living proposal for adding extra convenience methods to the MapGuide API |
| 9 | |
| 10 | = Motivation = |
| 11 | |
| 12 | 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 |
| 13 | |
| 14 | == Simplifying feature manipulation == |
| 15 | |
| 16 | === Inserting features === |
| 17 | |
| 18 | The current process of inserting features is currently: |
| 19 | |
| 20 | 1. Create a MgFeatureCommandCollection |
| 21 | 2. Create a MgPropertyCollection |
| 22 | 3. Populate the property collection with desired property values |
| 23 | 4. Create a MgInsertFeatures |
| 24 | 5. Add the property collection to the MgInsertFeatures command |
| 25 | 6. Add the MgInsertFeatures command to the MgFeatureCommandCollection |
| 26 | 7. Execute MgFeatureService::UpdateFeatures passing in the feature source id and the command collection and to specify whether this should be transactional or not |
| 27 | 8. Process each individual result of the UpdateFeatures() call, taking note of any thrown exceptions (non-transactional) and open feature readers |
| 28 | |
| 29 | 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. |
| 30 | |
| 31 | mg-desktop provides a simplified API for inserting features, that should also be brought over to the MapGuide API: |
| 32 | |
| 33 | {{{ |
| 34 | |
| 35 | class MG_PLATFORMBASE_API MgFeatureService : public MgService |
| 36 | { |
| 37 | PUBLISHED_API: |
| 38 | MgFeatureReader* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props); |
| 39 | MgFeatureReader* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, MgTransaction* trans); |
| 40 | MgPropertyCollection* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues); |
| 41 | MgPropertyCollection* InsertFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans); |
| 42 | }; |
| 43 | |
| 44 | class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable |
| 45 | { |
| 46 | PUBLISHED_API: |
| 47 | MgFeatureReader* InsertFeatures(MgPropertyCollection* props); |
| 48 | MgFeatureReader* InsertFeatures(MgPropertyCollection* props, MgTransaction* trans); |
| 49 | MgPropertyCollection* InsertFeatures(MgBatchPropertyCollection* batchPropertyValues); |
| 50 | MgPropertyCollection* InsertFeatures(MgBatchPropertyCollection* batchPropertyValues, MgTransaction* trans); |
| 51 | }; |
| 52 | |
| 53 | }}} |
| 54 | |
| 55 | Under this simplified API, the process is now. |
| 56 | |
| 57 | 1. Create a MgPropertyCollection or MgBatchPropertyCollection |
| 58 | 2. Load it up with the desired property values |
| 59 | 3. Execute InsertFeatures(), passing in the feature source, the property collection and optionally a transaction. |
| 60 | 4. Close the open feature reader, or process the property collection (if using a MgBatchPropertyCollection) |
| 61 | |
| 62 | === Updating features === |
| 63 | |
| 64 | The current process of update features is similarly complex: |
| 65 | |
| 66 | 1. Create a MgFeatureCommandCollection |
| 67 | 2. Create a MgPropertyCollection |
| 68 | 3. Populate the property collection with desired property values to update |
| 69 | 4. Create a MgUpdateFeatures |
| 70 | 5. Add the property collection to the MgUpdateFeatures command |
| 71 | 6. Specify the update filter for the MgUpdateFeatures command |
| 72 | 7. Add the MgUpdateFeaturescommand to the MgFeatureCommandCollection |
| 73 | 8. Execute MgFeatureService::UpdateFeatures passing in the feature source id and the command collection and to specify whether this should be transactional or not |
| 74 | 9. Process each individual result of the UpdateFeatures() call, taking note of any thrown exceptions (non-transactional) and open feature readers |
| 75 | |
| 76 | 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. |
| 77 | |
| 78 | mg-desktop provides a simplified API for updating features, that should also be brought over to the MapGuide API: |
| 79 | |
| 80 | {{{ |
| 81 | |
| 82 | class MG_PLATFORMBASE_API MgFeatureService : public MgService |
| 83 | { |
| 84 | PUBLISHED_API: |
| 85 | INT32 UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, CREFSTRING filter); |
| 86 | INT32 UpdateFeatures(MgResourceIdentifier* resource, CREFSTRING className, MgPropertyCollection* props, CREFSTRING filter, MgTransaction* trans); |
| 87 | }; |
| 88 | |
| 89 | class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable |
| 90 | { |
| 91 | PUBLISHED_API: |
| 92 | INT32 UpdateFeatures(MgPropertyCollection* props, CREFSTRING filter); |
| 93 | INT32 UpdateFeatures(MgPropertyCollection* props, CREFSTRING filter, MgTransaction* trans); |
| 94 | }; |
| 95 | |
| 96 | }}} |
| 97 | |
| 98 | Under this simplified API, the process is now. |
| 99 | |
| 100 | 1. Create a MgPropertyCollection |
| 101 | 2. Load it up with the desired property values to update with |
| 102 | 3. Execute UpdateFeatures(), passing in the feature source, the property collection, update filter and optionally a transaction. |
| 103 | |
| 104 | === Deleting Features === |
| 105 | |
| 106 | == Querying transformed features == |
| 107 | |
| 108 | This API is currently not implemented in MapGuide |
| 109 | |
| 110 | {{{ |
| 111 | class MG_PLATFORMBASE_API MgFeatureService : public MgService |
| 112 | { |
| 113 | PUBLISHED_API: |
| 114 | virtual MgFeatureReader* SelectFeatures(MgResourceIdentifier* resource, |
| 115 | CREFSTRING className, |
| 116 | MgFeatureQueryOptions* options, |
| 117 | CREFSTRING coordinateSystem) = 0; |
| 118 | }; |
| 119 | }}} |
| 120 | |
| 121 | Having this API implemented would be very useful. Along the same theme of convenience, MgLayerBase should have a shortcut form of the above API: |
| 122 | |
| 123 | {{{ |
| 124 | class MG_PLATFORMBASE_API MgLayerBase : public MgNamedSerializable |
| 125 | { |
| 126 | PUBLISHED_API: |
| 127 | virtual MgFeatureReader* SelectFeatures(MgFeatureQueryOptions* options, |
| 128 | CREFSTRING coordinateSystem); |
| 129 | }; |
| 130 | }}} |
| 131 | |
| 132 | == Getting a layer icon == |
| 133 | |
| 134 | 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. |
| 135 | |
| 136 | Since MgLayer possesses most of this knowledge, it makes sense to have convenience APIs in MgLayer itself: |
| 137 | |
| 138 | {{{ |
| 139 | |
| 140 | class MG_MAPGUIDE_API MgLayer : public MgLayerBase |
| 141 | { |
| 142 | PUBLISHED_API: |
| 143 | //Gets the list of geometry type styles for this layer at the map's current scale |
| 144 | MgIntCollection* GetGeometryTypeStyles(); |
| 145 | //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 |
| 146 | INT32 GetThemeCategoryCount(INT32 geomType); |
| 147 | //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 |
| 148 | MgByteReader* GenerateLegendImage(INT32 width, INT32 height, CREFSTRING format, INT32 geomType, INT32 themeCategory); |
| 149 | |
| 150 | //Gets the list of geometry type styles for this layer at the given scale |
| 151 | MgIntCollection* GetGeometryTypeStyles(double scale); |
| 152 | //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 |
| 153 | INT32 GetThemeCategoryCount(double scale, INT32 geomType); |
| 154 | //Gets the legend image icon for this layer at the at the given scale for the given geometry type style and theme category |
| 155 | MgByteReader* GenerateLegendImage(double scale, INT32 width, INT32 height, CREFSTRING format, INT32 geomType, INT32 themeCategory); |
| 156 | }; |
| 157 | |
| 158 | }}} |