35 | | Using the metric of the number of conversions per second from UTM27-13 to CO83-C in a pure measurement environment (i.e. no coordinate retrieval or delivery code), the underlying CS-MAP library is capable of producing approximately 1 million conversions per second. Changes in the MapGuide API, therefore, cannot get us beyond this limit. Thus, in this RFC, we will write of performance in terms of the percentage of this theoretical maximum which the API can/will deliver. The current implementation of the API delivers performance of approximately 80% of this maximum. Research and test implementations indicate that it is not unreasonable to expect an improvement to 91% of the theoretical maximum when using the most efficient of the Transform function overloads. |
| 35 | Using the metric of the number of conversions per second from UTM27-13 to CO83-C in a pure measurement environment (i.e. no coordinate retrieval or delivery code), the underlying CS-MAP library is capable of producing approximately 1 million conversions per second on an average desktop machine. Changes in the MapGuide API, therefore, cannot get us beyond this limit. Thus, in this RFC, we will write of performance in terms of the percentage of this theoretical maximum which the API can/will deliver. The current implementation of the API delivers performance of approximately 80% of this maximum. Research and test implementations indicate that it is not unreasonable to expect an improvement to 91% of the theoretical maximum when using the most efficient of the Transform function overloads. |
60 | | The default behavior of the API is to throw an exception whenever such a warning is received from the CS-MAP library. This default behavior can be, and often is, modified at run-time using the IgnoreDatumShiftWarning and IgnoreOutsideDomainWarning members of the MgCoordinateSystem interface. Thus, it is recommended that applications using the API disable the exception throwing behavior of the API. It is further proposed that the MgCoordinateSystemTransformation object be enhanced to provide a status accumulation feature. By status accumulation, we refer to the concept of: a)counting each point converted, b) counting all source projective CRS warnings issued, c) counting all datum shift warnings issued, and d) counting all target projective CRS warnings. |
| 60 | The default behavior of the API is to throw an exception whenever such a warning is received from the CS-MAP library. This default behavior can be, and often is, modified at run-time using the IgnoreDatumShiftWarning and IgnoreOutsideDomainWarning members of the MgCoordinateSystem interface. Thus, it is recommended that applications using the API disable the exception throwing behavior of the API. It is further proposed that the MgCoordinateSystemTransform object be enhanced to provide a status accumulation feature. By status accumulation, we refer to the concept of: a) counting all source projective CRS warnings issued, b) counting all datum shift warnings issued, and c) counting all target projective CRS warnings. |
64 | | For example, a conversion where the target CRS warning count exceeds, say, 33% of the total number of points suggests that the target CRS chosen by the user is incorrect. On the other hand, warning counts which are less than, say, 10% of the total point count suggest a perfectly normal conversion. |
| 64 | For example, a conversion where the target CRS warning count exceeds, say, 20% of the total number of points suggests that the target CRS chosen by the user is incorrect. On the other hand, warning counts which are less than, say, 20% of the total point count suggest a perfectly normal conversion. |
66 | | Thus, the following additional member functions to the MgCoordinateSystemTransformation object are proposed: |
67 | | |
68 | | {{{ INT32 MgCoordinateSystemTransform::GetConversionStatus (INT32 failPercentage); }}} |
69 | | |
70 | | The argument to this function would indicate the threshold as the percentage of points converted which are to be considered a transformation failure. The returned integer would be zero for a successful conversion. A non-zero bitmap of would be returned in the event of a failure (i.e. a warning count excess the specified percentage of the total point count), the individual bits indicating the phase, or phases, (i.e. source CRS, datum shift, target CRS) which accumulated sufficient warning counts to indicate failure. |
71 | | |
72 | | {{{ INT32 MgCoordinateSystemTransform::GetTotalPointCount (void); }}} |
73 | | |
74 | | Returns the total number of points converted. |
| 66 | Thus, the following additional member functions to the MgCoordinateSystemTransform object are proposed: |
94 | | A batch coordinate conversion capability currently exists in the MgCoordinateSystemTransformation object. The performance of this capability is expected to increase due to the refactoring of the Transform code proposed immediately above. However, this function requires that, for example, 3D coordinates are provided in three distinct arrays; specifically the easting/X/Longitude coordinates in one single dimensional array of doubles, the northing/Y/Latitude coordinates in a separate single dimension array of doubles, and a third separate and distinct array of double for the elevation/Z/height coordinate. There are few, if any, applications which maintain or utilize coordinate data in this form. |
| 86 | A batch coordinate conversion capability currently exists in the MgCoordinateSystemTransform object. The performance of this capability is expected to increase due to the refactoring of the Transform code proposed immediately above. However, this function requires that, for example, 3D coordinates are provided in three distinct arrays; specifically the easting/X/Longitude coordinates in one single dimensional array of doubles, the northing/Y/Latitude coordinates in a separate single dimension array of doubles, and a third separate and distinct array of double for the elevation/Z/height coordinate. There are few, if any, applications which maintain or utilize coordinate data in this form. |
96 | | Thus, to take advantage of the batch conversion facility currently in place, the traditional form of coordinate data (e.g. a two dimensional array of doubles: ''double []![3]'') has to be reformatted (i.e. marshalled) into the distinct array form prior to conversion, and then reformatted back to the traditional form after the conversion has been performed. Thus, what performance improvement is provided by the batch conversion facility is typically consumed, and probably then some, by the formatting and reformatting processes. |
| 88 | Thus, to take advantage of the batch conversion facility currently in place, the traditional form of coordinate data (e.g. a two dimensional array of doubles: ''double []![3]'') has to be reformatted (i.e. marshaled) into the distinct array form prior to conversion, and then reformatted back to the traditional form after the conversion has been performed. Thus, what performance improvement is provided by the batch conversion facility is typically consumed, and probably then some, by the formatting and reformatting processes. |
| 115 | === Reentrancy === |
| 116 | |
| 117 | The reentrancy of all existing features of the MgCoordinateSystemTransform object remain intact; although it is expected that several minor behavior changes (the author considers them to be improvements) will be made as described immediately below. The new status accumulation feature, however, cannot be made totally reentrant in the current MapGuide environment due to multi-platform, multi-language, support considerations. |
| 118 | |
| 119 | That is, the status count feature cannot be implemented in an a "separate instance per thread" manner and passed to a reentrant MgCoordinateSystemTransform object. Thus, the data elements in which the status accumulation occurs must be included in the Transform object itself. This leads to the fact that using the same Transform object for the conversion for two distinct datasets (as would be possible if total reentrancy was achievable) will produce the correct numerical results, but all status warnings encountered in the two different datasets would be accumulated in the same data accumulation variables and thus conversion of a dataset which converted without warning be considered a failure due to the failure of the second dataset. |
| 120 | |
| 121 | Conversion of a very large dataset, a point cloud for example, can be achieved in a multi-threaded environment using the same MgCoordinateSystemTransform object as the resulting status accumulation will accurately reflect that status of the entire conversion effort. As this is possible and desirable, we propose this as the optimum balance of performance versus functionality. |
| 122 | |
116 | | 1. In the existing code, the behavior of the API with regard to the status of returned results in the event of an exception being thrown is inconsistent. In the proposed code, the basic CS-MAP contract will be honored: “Regardless of status returned and/or exceptions thrown, any and all Transform member calls will always produce rational converted results.” Thus, the proposed behavior will provide consistent return results and also contribute to higher performance levels. That is, even in the event of an exception, all coordinates requested to be convrted will have been conververted. |
117 | | 2. The four status values returned in the m_nTransformStatus member of the MgCoordinateSystemTransform object may be adjusted to form a severity level sequence which rates a geodetic datum “outside range” as more severe than a projected “outside range”. The names used will not change, only the numeric values assigned to them; so this should not require any coding changes. |
118 | | 3. The overloads of the MgCoordinateSystemTransform::Transform which deal with arrays will now always complete the conversion of the entire array before throwing any exception with regard to non-normal status encountered in the conversion. Also, these overloads will be modified so that the value of the m_nTransformStatus member, upon return, will always reflect the worst status encountered (per the severity level described in 2 above) in the transformation of the array (as opposed to the status of the last conversion perfromed as is currently done). |
| 126 | 1. In the existing code, the behavior of the API with regard to the status of returned results in the event of an exception being thrown is inconsistent. In the proposed code, conversion results will always be provided, even in the event of an exception being thrown. Thus, the proposed behavior will provide consistent return results and also contribute to higher performance levels. That is, even in the event of an exception, all coordinates requested to be converted will have been converted. |
| 127 | 2. The four status values returned in the m_nTransformStatus member of the MgCoordinateSystemTransform object will be adjusted to form a severity level sequence which rates a geodetic datum “outside range” as more severe than a projected “outside range”. The names used will not change, only the numeric values assigned to them; so this should not require any coding changes. |
| 128 | 3. The overloads of the MgCoordinateSystemTransform::Transform which deal with arrays will now always complete the conversion of the entire array before throwing any exception with regard to non-normal status encountered in the conversion. Also, these overloads will be modified so that the value of the m_nTransformStatus member, upon return, will always reflect the worst status encountered (per the severity level described in 2 above) in the transformation of the array (as opposed to the status of the last conversion performed as is currently done). |
| 130 | |
| 131 | Coordinate results provided in the case of an exception will be what CS-MAP considers to be a "rational result". In the case of a datum shift calculation failure, the rational result is either than calculated by the fallback specification or the unshifted input coordinates. This is considered rational as datums shifts are rarely more than 100 meters, and often in the range of 20 meters. Thus, given that the input coordinate is outside the useful range of the datum shift transformation (typically this means outside the coverage provided by grid shift data files), the result "rational result" is the unshifted input. |
| 132 | |
| 133 | In the case of projective conversions, the "rational result" is based on the nature of the projection. For many of the projections supported, the "rational result" is simply what the projection mathematics produce, even though the coordinate is known to be outside the region for which the projection's parameters suggest is the useful range of the conversion. In other cases, the projection will have singularity points, such as either pole in the case of the traditional Mercator. In such cases the "rational result" typically includes one or more coordinates with an unmistakably large number which suggests infinity, but will not cause a floating point exception if the value is used for any normal calculation. |