Select to view content in your preferred language

Curve structure definitions

3981
3
10-18-2011 07:58 PM
__11
by
Deactivated User
I'm writing some code to use the API add curve sections to a polyline row.  Are there any structure definitions for the curves in the headers? The only definitions I can find are in doc\html\extended_shapefile_format.pdf

I can copy these into my own code, but it would seem more appropriate for the API headers to define them for me.
0 Kudos
3 Replies
DavidSousa
Occasional Contributor
This is being looked at for a future release.

Rather than simply use the curve structure definitions that are in the shape doc, it will probably be better to have a class hierarchy for the three curve types.  This avoids the ugliness of the nested unions which is shown in the doc.

One of the challenges is the fact that when serialized in the shape buffer, the three curve types are different in size, and the curves are packed in the buffer with no padding bytes.  That means that it is not possible to cast the byte array containing the curves into an array of curve objects.
0 Kudos
__11
by
Deactivated User
According to "File Geodatabase API 1.2 now available":


What�??s new at 1.2:
* Structure definitions for curves (CircularArcCurve, BezierCurve, EllipticArcCurve).


In v1.2, util.h includes class definitions for Curves:
[INDENT]class EXT_FILEGDB_API Curve
class EXT_FILEGDB_API CircularArcCurve : public Curve
[/INDENT]
etc, but there's no indication as to how we should use them.

No API function uses these classes, so I can't get/set a curve object from/to a shape.

I can't just use them as structs and cast the byte pointer from MultiPartShapeBuffer::GetCurves because:
* The classes/structs are not packed, so I can't guarantee alignment with the byte pointer data
* The members include ints, whose size is machine dependent, rather than the fixed size int32
* Objects derived from the base class Curve include the virtual function table pointer.

Is there a better way than my current methodology, which is to copy the structure definitions from doc\html\extended_shape_buffer_format.pdf and use them thus:


namespace FileGDBAPI 
{
/*-----------------------------------------------------------------------------
 Curve structure definition, from Extended Shape Buffer Format, February 9, 2012 (doc\html\extended_shape_buffer_format.pdf)
 The document uses "long" for some members, but we use int32 (from FileGDBCore.h) here to ensure a fixed size.
 (The necessary size of a "long" can be deduced from footnote 12.)
*/

#pragma pack(push, 1)

struct WKSPoint
{
 double x, y;
};

struct SegmentArc
{
 union {
  WKSPoint centerPoint; // If IsPoint is 0. Also, it is ignored if
                        // IsLine is 1.
  double angles[2];     // If IsPoint is 1: start and central angle
                        // centerPoint = endPoint
 };
 int32 Bits; // Contains, among others, bits for IsPoint, IsLine ...
};

struct esriSegmentModifier
{
 int32 startPointIndex,
 /* enum esriSegmentType */ segmentType;
 union {
  SegmentArc arc;
  SegmentBezierCurve bezierCurve;
  SegmentEllipticArc ellipticArc;
  // SegmentOther otherKindsOfSegment;
  // ...
 } segmentParams;
};

...

#pragma pack(pop)

} // namespace FileGDBAPI


// Build a vector of curves from my input data
 vector<esriSegmentModifier> vCurves;
 for (...)
 {
   esriSegmentModifier modifier;
   modifier.startPointIndex = ... 
   modifier.segmentType = esriSegmentArc;
   modifier.segmentParams.arc.centerPoint.x = ... 
   modifier.segmentParams.arc.centerPoint.y = ...
   modifier.segmentParams.arc.Bits = ...
   vCurves.push_back(modifier);
 }

// Put the curves into a MultiPartShapeBuffer for the database

 MultiPartShapeBuffer polyline;
 ...
 if (vCurves.size() != 0)
 {
  byte* curve;
  polyline.GetCurves(curve);
  for (vector<esriSegmentModifier>::const_iterator iter = vCurves.begin(); iter != vCurves.end(); ++iter)
  {
   // SegmentArc is the only curve supported by this code
   assert(iter->segmentType == esriSegmentArc);

   // copy the data from my vector to the ShapeBuffer
   esriSegmentModifier* modifier = reinterpret_cast<esriSegmentModifier*>(curve);
   *modifier = *iter; 
   curve += offsetof(esriSegmentModifier, segmentParams) +  sizeof(SegmentArc); 
  }
 }

 polyline.CalculateExtent();
 polyline.PackCurves();
 row.SetGeometry(polyline);
}

0 Kudos
__11
by
Deactivated User
My comments re v1.2 apply equally to v1.3
0 Kudos