Select to view content in your preferred language

How to retrieve polygon geometry?

1415
4
04-20-2011 04:49 AM
KarlHedlund
Emerging Contributor
It feels a bit weird that I would first have to get the geometry, then check its shape and geometry type, then retrieve it once again.

attrQueryRow.GetGeometry(geometry);
int shapeType;
geometry.GetShapeType(shapeType);
GeometryType geometryType = (GeometryType)(geometry.GeometryType(shapeType));

vector<Point> retrievedPoints;

  switch(geometryType)
  {
   case GeometryType::geometryPolygon:
    {
     int numPoints;
     ((MultiPointShapeBuffer*)&geometry)->GetNumPoints(numPoints);
     if(numPoints > 1)
     {
      retrievedPoints.resize(numPoints);
      Point* testP = &(retrievedPoints[0]);
      ((MultiPointShapeBuffer*)&geometry)->GetPoints(testP);



In this example, retrievedPoints gets filled with Point objects with x = 0 and y = 0, which is not correct. If I would take the same geometry and use it as a point geometry, I would get one correct point coordinate.

Am I missing something?
0 Kudos
4 Replies
KarlHedlund
Emerging Contributor
It seems you are supposed to just send a new pointer and the GetPoints() will allocate memory for its points and set the pointer to that memory, but is there a method that frees the memory?
0 Kudos
DavidSousa
Occasional Contributor
It feels a bit weird that I would first have to get the geometry, then check its shape and geometry type, then retrieve it once again. 

attrQueryRow.GetGeometry(geometry);
int shapeType;
geometry.GetShapeType(shapeType);
GeometryType geometryType = (GeometryType)(geometry.GeometryType(shapeType));

vector<Point> retrievedPoints;

  switch(geometryType)
  {
   case GeometryType::geometryPolygon:
    {
     int numPoints;
     ((MultiPointShapeBuffer*)&geometry)->GetNumPoints(numPoints);
     if(numPoints > 1)
     {
      retrievedPoints.resize(numPoints);
      Point* testP = &(retrievedPoints[0]);
      ((MultiPointShapeBuffer*)&geometry)->GetPoints(testP);



In this example, retrievedPoints gets filled with Point objects with x = 0 and y = 0, which is not correct. If I would take the same geometry and use it as a point geometry, I would get one correct point coordinate. 

Am I missing something?



It is not necessary to retrieve the geometry more than once. One way is to figure out ahead of time what the geometry type is and instantiate the appropriate ShapeBuffer derived class and use that in the call to GetGeometry. The other is to use the ShapeBuffer base class and then do a reinterpret cast to one of the derived classes based on the geometry type - it is possible to do this because the derived classes have no additional state beyond what the base class has. This is what you have in your bit of sample code.

The problem in your sample code appears to due to the fact that you are using the wrong shapebuffer derived class in your cast. You are casting to MultiPointShapeBuffer but for Polygons (and Polylines) you should be using MultiPartShapeBuffer.


-David Sousa
0 Kudos
DavidSousa
Occasional Contributor
It seems you are supposed to just send a new pointer and the GetPoints() will allocate memory for its points and set the pointer to that memory, but is there a method that frees the memory?



When using the ShapeBuffer classes, you need to keep in mind the fact that the accessor functions are working directly with the raw byte array.  None of these functions are allocating any memory, rather, they are calculating an offset to a particular position within the shape buffer (e.g., the parts array or points array) and then casting that pointer to the appropriate type (double, int, etc.).

The memory is freed automatically by the shape buffer destructor.

-David Sousa
0 Kudos
KarlHedlund
Emerging Contributor
Thank you, I've got it implemented and working here now.
0 Kudos