ArcSDE C API Issue - Buffer (SE

1037
6
09-20-2011 02:25 AM
DeepLakhanpal
New Contributor
Hi,
I have to write a C code which will accept polygon features and create a buffer around them and store this buffer feature in a new feature of polygon type.

I am aware of the ArcSDE C API and I believe that this requirement can be completed through SE_shape_generate_buffer. But as per my code I am unable to create a buffer around the feature, instead of this buffer its copy and store the same feature in the output but the difference is that this new feature is tilted upwards.

Can anyone please help me and provide me some kind of support to complete this functionality. Please find below the code I have applied ...

##################################################################

char tps_trt[15];
char tps_trt_tuple[15];
time_t time_deb;
time_t time_deb_tuple;
time_t time_cour;
long featurecount = 0;
long result = 0;
long resultat=0;
long resultat1=0;
long lNumPoints=0;

long rc=0;
long fdp_db_rec=0;

long l_layerType=SE_AREA_TYPE_MASK|SE_MULTIPART_TYPE_MASK;
char pch_log[LG_MAX_ARG+1];

prim_shapes=(SE_SHAPE*)malloc(sizeof(SE_SHAPE)*MAX_SHAPES);
sec_shapes=(SE_SHAPE*)malloc(sizeof(SE_SHAPE)*MAX_SHAPES);
fdp_db = (SE_SHAPE *) malloc (sizeof (SE_SHAPE)* MAX_FDP_DB_RECORDS);
new_couv_shapes=(SE_SHAPE*)malloc(sizeof(SE_SHAPE)*MAX_SHAPES);
tab_coordRef=(SE_COORDREF*)malloc(sizeof(SE_COORDREF)*MAX_COORDREF);

long size_SE_SHAPE=sizeof(SE_SHAPE)*1;
/* DEBUT Initialisation du tuple */
enreg * tuple=(enreg*)malloc(sizeof(enreg));
/*****************************************************************************************************************************************************************/

ccf_initConnection_SDE(&tab_connections[0],psde_error, con_server, con_instance, con_dbase, con_user, con_pswd);

ccf_init_stream_SDE (0, &tab_connections[0],psde_error, &tab_streams[0], &tab_coordRef[0], &tab_layers[0],&tab_sqlConstruct[0], nomLayerIn, clauseWhere, NULL,l_layerType,tuple);

ccf_init_stream_SDE (1, &tab_connections[0],psde_error, &tab_streams[1], &tab_coordRef[1], &tab_layers[1],NULL, nomLayerOut, NULL, 0,l_layerType,tuple);

rc=SE_layerinfo_get_shape_types (tab_layers[0], (LONG *) &l_layerType);
/*********************************************************************************************/

long l_nbTuples = 0,ret_shapes=0;
long nb_mailles_20x20=0;
long countShapes=0;
BOOL isDisjoint_ret=TRUE;

char * var;

while ((resultat1=ccf_lire_tuple_SDE(psde_error, &tab_streams[0], tuple, &prim_shapes, &tab_coordRef[0])) == 0)
{
ccf_majTuple(tuple);

ret_shapes= SE_shape_generate_buffer (prim_shapes, 0.5, 30 , &new_couv_shapes);

tuple->tab_valChampsOut[0]=(char*) &(new_couv_shapes[0]);
ccf_ecrire_tuple_SDE (psde_error, &tab_streams[1], &tab_layers[1], tuple,&tab_coordRef[1]);

ccf_commit_SDE(&tab_connections[0],psde_error,&tab_streams[1]);
SE_shape_free(new_couv_shapes);
}


I have also reffer below mention link and tried to implement this code but didnt got any success.

http://edndoc.esri.com/arcsde/9.0/capi_concepts/shape_functions.htm


Please find attached images of output I got from this.
0 Kudos
6 Replies
by Anonymous User
Not applicable
Original User: vangelo

In order to get help with your code, you need to post it (not just the function which calls that code).

The code you did post has questionable use of array allocation (with no obvious need for arrays
and undefined MAX_* macros). All the code that contains "long" is incorrect -- ArcSDE uses the
"LONG" macro to hide the implementation of "long" on 32-bit platforms and "int" on 64-bit, so
using "long" can cause alignment issues that randomize results. From a 'C' coding standpoint,
you should *NEVER* cast the results of malloc (doing so should be unnecessary, and hides
possible warnings or errors which would be returned by the compiler).

The function which would perform a Cartesian buffer on a shape should probably look like this
(once they get the fixed-width CODE font straightened out):

LONG my_buffer(SE_SHAPE shape, LFLOAT distance)
{
    LONG        nparts = 0;
    LONG        npoints = 0;
    LONG        nsubs = 0;
    LONG        sr;
    SE_SHAPE    temp = NULL;
 
    sr = SE_shape_get_num_parts(shape,&nparts,&nsubs);
    if (sr != SE_SUCCESS) return sr;
 
    sr = SE_shape_get_num_points(shape,SE_ALL,SE_ALL,&npoints);
    if (sr != SE_SUCCESS) return sr;
 
    sr = SE_shape_create(NULL,&temp);
    if (sr != SE_SUCCESS) return sr;
 
    sr = SE_shape_duplicate(shape,temp);
    if (sr != SE_SUCCESS) goto bailout;
 
    npoints += (360 * nsubs) + 500;
 
    sr = SE_shape_generate_buffer(temp,distance,npoints,shape);
 
bailout:
    SE_shape_free(temp);
 
    return sr;
}


But you need quite a bit of validation code to make sure the coordinate references in the
source and destination layers are identical.

I strongly suggest you review the way you're using pointers and arrays, because the casting
you're doing between SE_SHAPE and char * is not valid and your SE_shape_free invocation
is likely to corrupt memory.

- V
0 Kudos
DeepLakhanpal
New Contributor
Hi Vince,
Thanks again for your quick reply. I really appreciate your response.

We have a legacy system in which we are using ArcSDE 9.0 along with its API and Oracle 9i. In here we have to develop where we will have a bulk of data in a polygon feature class and we have to generate a buffer on each and every polygon.

Their are some polygons which be need to merge before running this buffer functionality but as ArcSDE 9.0 C API dosen't have Merge functionality so we have skip this requirement.

But if you have seen we have problem which running the buffer functionality on these data. These feature classes dosent have any projection system and all operations happen on these features without any projection information. Earlier we deveopled a same kind of functionality related to intersect.

But we have major issue with Buffer, we will try to implement the solution you have provided, but as you can see our peace of code was earlier working reffer the attached images. But the result was not the same as we were expecting. Result feature is moved upwards instead of creating a buffer, quite a strange behavior.

Thanks
Deep
0 Kudos
by Anonymous User
Not applicable
Original User: vangelo

*EVERY* shape in ArcSDE has a coordinate reference (which includes coordinate system,
though this can be null, even though it shouldn't ever be).  As a programmer, you must be
extremely careful to be sure that the appropriate coordref is in use at all times.  HIGH
precision coordrefs were introduced at 9.0, but not supported until 9.2

The SE_SHAPE API also supports every possible spatial manipulation (the full suite of
"Clementini operators"), so I don't understand your "Merge" and "Intersect" comments.

It's been years since I last used the 9.0 API, but all the ugly spatial manipulation bugs I've run
into were at the 3.x and 8.[12] releases (I even provided the "chamber of horrors" QA code
used as part of regression testing of the shape engine).  Of course, if there was a bug at 9.0,
it's long past the time when it could be fixed (9.0 was "retired" in December, 2008).

It is highly unlikely that working code stopped working without: 1) a change to the code, or
2) data for which the code doesn't work.  Part of the joy of low-level coding is debugging
really nasty geometry issues ("Doh!  Look at that -- no wonder it doesn't work!").  If you
do find something which appears to be an API bug, I can test it with modern code for you.

- V
0 Kudos
DeepLakhanpal
New Contributor
Hi Vince,
Thanks again for your support, seems like i will fix my this issue soon. I have another issue for which i have raised a thread but didn't got any reply . This a critical issue for my application if you can please reply on that.

Please find below the link for the same.

http://forums.arcgis.com/threads/40055-ArcSDE-Post-Installation-Error?p=135755#post135755

Thanks & Regards
0 Kudos
by Anonymous User
Not applicable
Original User: abhijeet

hi Vince,
I am working on same issue which First Poster (Deep) mentioned. (Working together) We tried the solution given by you. I would like to elaborate some points.
We are reading featureclass from oracle. We are passing it as input shape as mentioned in your function.I hope this part is working fine since we are able to fetch nsubs, npoints correctly. When we call function SE_shape_generate_buffer we are getting error code -134 (The given shape object handle is invalid). Can you help for this issue?
0 Kudos
VinceAngelo
Esri Esteemed Contributor
It's difficult to debug someone else's code when the full source is provided, but it's impossible
to debug with missing source. 

Since the partial source uses several questionable techniques in memory management, I'd
recommend inspecting every line where a malloc or free is present, and replacing it with code
that reflects the fact that row-oriented processing functions only need one handle for each object.
You should certainly move the SE_shape_free call outside the loop, but you also need to call
SE_shape_create at some point before the loop starts (allocating a random block of memory,
typing it as an array of handles, and treating it like a single shape handle is an easy way to
produce run-time memory corruption errors).  It would certainly help to treat compilation
warnings as errors (and to enable pedantic warnings to look for memory management
problems at compile time).

It's also important to keep in mind that the ArcSDE API does not operate on feature classes.
"Feature class" is an ArcGIS / ArcObjects term.  The ArcSDE API operates on the tables on which
feature classes are modelled.  You need to be very careful while using ArcSDE primitives that
you don't corrupt the geodatabase organization imparted by ArcObjects.  It would be slower,
but much safer to use C# or Python to manipulate geodatabase objects in a framework that
is less vulnerable to memory management errors.

- V
0 Kudos