I'm having problems setting M values in a shapePolylineZM, and I suspect that the problem is that MultiPartShapeBuffer::GetMs() returns the wrong pointer value. Here's the relevant section of my code that creates and writes the shape: struct pointInfo
{
pointInfo(double _easting, double _northing, double _height, double _shotPoint)
: easting(_easting), northing(_northing), height(_height), shotPoint(_shotPoint)
{
}
double easting, northing, height, shotPoint;
};
vector<pointInfo> vPoints; // uses grid coordinates
// ... add elements to vPoints, here ...
// Now create and populate the geometry
MultiPartShapeBuffer polyline;
polyline.Setup(shapePolylineZM, 1 /*part*/, vPoints.size());
Point* point;
polyline.GetPoints(point);
double* z;
polyline.GetZs(z);
double* m;
polyline.GetMs(m);
for (vector<pointInfo>::const_iterator iter = vPoints.begin(); iter != vPoints.end(); ++iter)
{
*z = iter->height;
runParameters.geo->SetPointFromGrid(
point++,
runParameters.geo->MetersToDest(iter->easting),
runParameters.geo->MetersToDest(iter->northing),
z++);
*m++ = iter->shotPoint;
}
polyline.CalculateExtent();
row.SetGeometry(polyline);
I run this code then inspect the output by:- load the geodatabase in ArcCatalog - drag the feature class into ArcMap- edit the feature ("Sketch Properties") to see the M valuesI find that the M values are all in the wrong positions, offset by two. Eg given input data x, y, z, m of449419.597, 7772022.067, -104.192, 6459.000
449392.902, 7772057.754, -97.530, 6460.000
449364.398, 7772096.582, -109.500, 6461.000
449342.910, 7772129.191, -105.321, 6462.000
...
410753.369, 7830191.197 -238.440, 7864.000
410726.857, 7830233.149, -245.280, 7865.000
410701.461, 7830273.902, -250.414, 7866.000
410673.267, 7830313.504, -242.441, 7867.000
I get these x, y, z, m values in the output449419.597, 7772022.067, -104.192, 6461.000
449392.902, 7772057.754, -97.530, 6462.000
449364.398, 7772096.582, -109.500, ...
449342.910, 7772129.191, -105.321, ...
...
410753.369, 7830191.197 -238.440, 7866.000
410726.857, 7830233.149, -245.280, 7867.000
410701.461, 7830273.902, -250.414, 0.000
410673.267, 7830313.504, -242.441, 0.000
A similar discrepancy occurs when I read a geometry. Eg I create a new geodatabase and feature class in ArcCatalog, then use ArcMap's editor to insert a row with x, y, z, m:72.000, 38.518, 180.000, 41.000
74.328, 38.153, 181.000, 42.000
75.982, 35.619, 182.000, 43.000
78.201, 32.217, 183.000, 44.000
78.930, 30.795, 160.000, 45.000
80.105, 28.504, 161.000, 26.000
81.176, 26.415, 162.000, 27.000
83.455, 21.225, 163.000, 28.000
80.018, 15.917, 164.000, 29.000
84.599, 15.960, 165.000, 30.000
Then I use this code to read the geometry
MultiPartShapeBuffer polyline;
row.GetGeometry(polyline);
ShapeType st;
polyline.GetShapeType(st);
assert(st == shapePolylineZM);
int numPoints;
polyline.GetNumPoints(numPoints);
Point* p;
polyline.GetPoints(p);
double* m;
polyline.GetMs(m);
for (int i = 0; i < numPoints; ++i)
{
wcout << p.x << "\t" << p.y << "\t" << m << endl;
}
and I get this result:
72 38.5182 26
74.328 38.1528 45
75.9815 35.6188 41
78.2013 32.217 42
78.9303 30.7952 43
80.105 28.5039 44
81.1763 26.4145 45
83.4546 21.2247 26
80.0181 15.9173 27
84.5989 15.9598 28
again the M values are in the wrong postion, offset by 2It looks to me as if GetMs is returning the wrong value. In fact if I do this (after the code above):
double *mExtent;
err = polyline.GetMExtent(mExtent);
wcout << "pointers: " << m << ", " << mExtent << ", " << m - mExtent << endl;
I can see that GetMExtent and GetMs return the same value, whereas I expected m to be 2*sizeof(double) higher than mExtent, in accordance with the structure described in Extended Shapefile Record Format, M data section, which shows MMin and MMax before Ms.If I increment the pointer returned by GetMs by two, eg by using this class:
class MultiPartShapeBuffer_fix : public FileGDBAPI::MultiPartShapeBuffer
{
public:
fgdbError GetMs(double*& mArray) const
{
fgdbError err = MultiPartShapeBuffer::GetMs(mArray);
if (SUCCEEDED(err))
{
mArray += 2;
}
return err;
}
};
MultiPartShapeBuffer_fix polyline;
...
My code appears to work properly, both reading and writing the geometry.The problem appears in both v1.1 and 1.2 of FileGDB API.It doesn't affect Z, only M.I haven't tried other shapes, eg shapeGeneralPolylineSo....Am I doing something wrong, or is there a bug in the API library?If the library is correct, what am I doing wrong?If the library has a bug, does it affect other shapes? I'm particularly interested in:
MultiPartShapeBuffer polyline;
polyline.Setup(static_cast<ShapeType>(shapeGeneralPolyline | shapeHasZs | shapeHasMs | shapeHasCurves), ...);
because I have code that uses it, and I need to know whether my fix applies to all shapes or only some.