/******************************************************************************* * *N {geom_spatial_rel.c} -- demonstrates the relationship between shapes; and the * usage of spatial filter in spatial queries * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *P Purpose: * This sample C program demonstrates the relationship between shapes and * the usage of spatial filter in spatial query * * Sample high level overview: * * Show shape relationships and query the polygon layer with different filters; * (1) Point filter; * (2) Line filter; * (3) Polygon filter; * * The following sptial relationship will be checked: * * SE_shape_is_containing() * SE_shape_is_containing(); * SE_shape_is_within(); * SE_shape_is_touching(); * SE_shape_is_crossing(); * SE_shape_is_overlapping(); * SE_shape_is_equal(); * The following filters will be demostrated: * * SM_ENVP : Envelopes overlap * SM_CP : Common point * SM_LCROSS : Line cross * SM_COMMON : Common edge/line * SM_CP_OR_LCROSS : Common point or line cross * SM_AI_OR_ET : Edge touch or area intersect * SM_AI : Area intersect * SM_PC : Primary contained in secondary * SM_SC : Secondary contained in primary * SM_IDENTICAL : Identical *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * How to compile:: * Please refer section "Build C Samples" in the SDE sample * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Usage: * geom_spatial_rel {server} {instance} {database} {user} {password} {keywords} * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *X Legalese: * * Copyright © 2007 ESRI * * All rights reserved under the copyright laws of the United States and * applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or without * modification, provided you include the original copyright notice and use * restrictions. * * Disclaimer: THE SAMPLE CODE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ESRI OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) SUSTAINED BY YOU OR A THIRD PARTY, HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT ARISING IN ANY WAY OUT OF THE USE OF THIS SAMPLE CODE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * For additional information, contact: * Environmental Systems Research Institute, Inc. * Attn: Contracts and Legal Services Department * 380 New York Street * Redlands, California, 92373 * USA * * email: contracts@esri.com * *E ****************************************************************************/ #include #include #include #include #include "sdetype.h" #include "sdeerno.h" typedef enum { SP_FILTER_POINT, SP_FILTER_LINE, SP_FILTER_POLYGON } SP_FILTER_SHPTYPE; /* Function macros */ #define check_rc_return_on_failure(c,s,rc,f) \ {if(rc!= SE_SUCCESS) {check_rc_(c,s,rc,f,__LINE__,__FILE__);return SE_FAILURE; }} /* Local Function Prototypes */ void check_rc_(SE_CONNECTION Connection, SE_STREAM Stream, LONG rc, char *comment, LONG line_no, char* file_name) ; static LONG S_create_layer (SE_CONNECTION, const CHAR *,const CHAR*,LONG,const CHAR *); static LONG S_populate_sample_layer (SE_CONNECTION ,const CHAR *,const CHAR*); static LONG S_populate_line_layer (SE_CONNECTION ,const CHAR *,const CHAR*); static LONG S_populate_point_layer (SE_CONNECTION,const CHAR *,const CHAR* ); static LONG S_prepare_filter_shape(SE_CONNECTION, CHAR*,CHAR*,SP_FILTER_SHPTYPE,SE_SHAPE*); static LONG S_apply_filters(SE_CONNECTION, const CHAR *,const CHAR*,CHAR*, SE_FILTER); static LONG S_execute_queries(SE_CONNECTION,CHAR *,CHAR* ); static LONG S_query_layer(SE_CONNECTION, const CHAR *,const CHAR*,const CHAR*,SE_FILTER*,BOOL); LONG main(int argc, char *argv[]){ CHAR *server, *user, *passwd, *database, *instance, *keyword; SE_CONNECTION conn; SE_ERROR error; LONG result; CHAR lay_name[SE_MAX_TABLE_LEN+1], shapecol[SE_MAX_COLUMN_LEN+1]; LONG layer_type; /*check input parmerters*/ if(argc<7){ printf("Usage %s ",argv[0]); exit(1); } server=argv[1]; instance=argv[2]; database=argv[3]; user=argv[4]; passwd=argv[5]; keyword=argv[6]; /*Connect to SDE server*/ result = SE_connection_create( server, instance, database, user, passwd, &error, &conn ); check_rc_return_on_failure (conn,NULL,result,"SE_connection_create"); printf("\nconnected to %s:%s as %s.\n\n",argv[1],argv[2], argv[4]); /*Prepare three sample layers*/ strcpy(lay_name,"SAMPLE_SP_POLY"); strcpy(shapecol,"SHAPE"); printf("***************************************************\n"); printf("Prepare Sample Layer: \n"); printf("***************************************************\n\n"); /*Create and populate a polygon layer*/ printf("\n Create a smaple layer...\n"); layer_type=SE_AREA_TYPE_MASK|SE_NIL_TYPE_MASK|SE_MULTIPART_TYPE_MASK; result=S_create_layer(conn,lay_name,shapecol,layer_type,keyword); if(result!=SE_SUCCESS) return result; printf("\n Populated the sample layer...\n"); result=S_populate_sample_layer(conn,lay_name,shapecol); if(result!=SE_SUCCESS) return result; /*Query the sample layer*/ printf("\n***************************************************\n"); printf("Execute Queries: \n"); printf("***************************************************\n\n"); result=S_execute_queries(conn,lay_name,shapecol); /*Free resources*/ result = SE_table_delete(conn,lay_name); SE_connection_free(conn); return SE_SUCCESS; } /*********************************************************************** * *N {S_create_layer} - create a SDE layer with provided specification * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * create a layer to store sample data *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. * == (CHAR*) the result layer name * == (CHAR*) the spatial column name * == (LONG) layer type mask * == (CHAR*) the keyword for layer creation *E ***********************************************************************/ static LONG S_create_layer (SE_CONNECTION connection, const CHAR *table,const CHAR* spatailcol, LONG layertype,const CHAR *keyword) { SE_LAYERINFO layer; SHORT number_of_columns; SE_COLUMN_DEF column_definitions[2]; SE_COORDREF coordref; LONG result; SE_REGINFO registration; CHAR rowidcol[SE_MAX_COLUMN_LEN]; /* Create the base table. */ //init base table column names number_of_columns = 1; strcpy(column_definitions[0].column_name,"SHPNAME"); column_definitions[0].sde_type = SE_STRING_TYPE; column_definitions[0].size = 10; column_definitions[0].decimal_digits = -1; column_definitions[0].nulls_allowed = FALSE; //Delete the table if it existed result = SE_table_delete(connection,table); if(result!=SE_TABLE_NOEXIST) check_rc_return_on_failure (connection,NULL,result,"SE_table_delete"); //Create the table result = SE_table_create (connection,table,number_of_columns, column_definitions,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_table_create"); /* Add an SDE maintained rowid */ result = SE_reginfo_create (®istration); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_create"); result = SE_registration_get_info (connection,table,registration); check_rc_return_on_failure (connection,NULL,result,"SE_registration_get_info"); result = SE_reginfo_set_creation_keyword (registration,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_creation_keyword"); strcpy(rowidcol,"ROWIDCOL"); result = SE_reginfo_set_rowid_column (registration,rowidcol, SE_REGISTRATION_ROW_ID_COLUMN_TYPE_SDE); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_rowid_column"); result = SE_registration_alter (connection,registration); check_rc_return_on_failure (connection,NULL,result,"SE_registration_alter"); /* Add the spatial column to the table */ result = SE_coordref_create (&coordref); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_create"); result = SE_coordref_set_xy (coordref,0.0,0.0,10.0); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_set_xy"); result = SE_layerinfo_create (coordref,&layer); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_create"); result = SE_layerinfo_set_grid_sizes (layer,1000.0,0.0,0.0); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_grid_sizes"); result = SE_layerinfo_set_shape_types (layer,layertype); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_shape_types"); result = SE_layerinfo_set_spatial_column (layer,table,spatailcol); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_spatial_column"); result = SE_layerinfo_set_creation_keyword (layer,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_creation_keyword"); result = SE_layer_create (connection,layer,20,10); check_rc_return_on_failure (connection,NULL,result,"SE_layer_create"); SE_reginfo_free(registration); SE_coordref_free(coordref); SE_layerinfo_free(layer); return(SE_SUCCESS); } /*********************************************************************** * *N {S_populate_sample_layer} - populate the sample polygon layer * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * populated the polygon sample layer *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the result layer name * == (CHAR*) the spatial column name *E ***********************************************************************/ static LONG S_populate_sample_layer (SE_CONNECTION handle, const CHAR *table,const CHAR* spatialcol) { SE_STREAM stream; LONG result,i; SHORT number_of_columns; CHAR **base_columns; SE_LAYERINFO layer; SE_COORDREF coordref; SE_SHAPE shape,tmpshape; SE_ENVELOPE rectangle,tmprect; CHAR shpname[10]; SHORT shpname_ind,shpdesc_ind,shape_ind; /* Init column names for insert */ base_columns = (CHAR **) malloc (2 * sizeof(CHAR *)); for(i=0;i<2;i++) base_columns[i]=(CHAR *) malloc (SE_MAX_COLUMN_LEN); strcpy(base_columns[0], "SHPNAME"); strcpy(base_columns[1] ,spatialcol); /*Init a shape object*/ result = SE_layerinfo_create (NULL,&layer); check_rc_return_on_failure (handle,NULL,result,"SE_layerinfo_create"); result = SE_coordref_create (&coordref); check_rc_return_on_failure (handle,NULL,result,"SE_coordref_create"); result = SE_layer_get_info (handle,table,spatialcol,layer); check_rc_return_on_failure (handle,NULL,result,"SE_layer_get_info"); result = SE_layerinfo_get_coordref (layer,coordref); check_rc_return_on_failure (handle,NULL,result,"SE_layerinfo_get_coordref"); result = SE_shape_create (coordref,&shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_create"); result = SE_shape_create (coordref,&tmpshape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_create"); //Start transation result = SE_connection_start_transaction (handle); check_rc_return_on_failure (handle,NULL,result,"SE_connection_start_transaction"); //Prepare an insert stream result = SE_stream_create (handle,&stream); check_rc_return_on_failure (handle,NULL,result,"SE_stream_create"); number_of_columns =2; result = SE_stream_insert_table (stream,table,number_of_columns, (const CHAR **)base_columns); check_rc_return_on_failure (NULL,stream,result,"SE_stream_insert_table"); result = SE_stream_set_write_mode (stream,TRUE); check_rc_return_on_failure (NULL,stream,result,"SE_stream_set_write_mode"); result = SE_stream_bind_input_column (stream,1,shpname,&shpname_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,2,shape,&shape_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); /* Perform the inserts. */ shpname_ind = SE_IS_NOT_NULL_VALUE; shpdesc_ind = SE_IS_NOT_NULL_VALUE; shape_ind = SE_IS_NOT_NULL_VALUE; //insert shp1 rectangle.minx = 2000.0; rectangle.miny = 2000.0; rectangle.maxx = 4000.0; rectangle.maxy = 4000.0; strcpy(shpname,"POLY1"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp2 rectangle.minx = 2000.0; rectangle.miny = 4000.0; rectangle.maxx = 4000.0; rectangle.maxy = 6000.0; strcpy(shpname,"POLY2"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp3 rectangle.minx = 5000.0; rectangle.miny = 6000.0; rectangle.maxx = 6000.0; rectangle.maxy = 8000.0; strcpy(shpname,"POLY3"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp4 rectangle.minx = 6000.0; rectangle.miny = 9000.0; rectangle.maxx = 10000.0; rectangle.maxy = 10000.0; strcpy(shpname,"POLY4"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp5 rectangle.minx = 6000.0; rectangle.miny = 10000.0; rectangle.maxx = 10000.0; rectangle.maxy = 12000.0; tmprect.minx = 4000.0; tmprect.miny = 8000.0; tmprect.maxx = 5000.0; tmprect.maxy = 10000.0; strcpy(shpname,"POLY5"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_shape_generate_rectangle (&tmprect,tmpshape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); //add second part to target shape result = SE_shape_add_part (tmpshape, shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_add_part"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp6 rectangle.minx = 10000.0; rectangle.miny = 10000.0; rectangle.maxx = 12000.0; rectangle.maxy = 12000.0; tmprect.minx = 9000.0; tmprect.miny = 9000.0; tmprect.maxx = 10000.0; tmprect.maxy = 10000.0; strcpy(shpname,"POLY6"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_shape_generate_rectangle (&tmprect,tmpshape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); //add second part to target shape result = SE_shape_add_part (tmpshape, shape); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp7 rectangle.minx = 10000.0; rectangle.miny = 6000.0; rectangle.maxx = 12000.0; rectangle.maxy = 10000.0; tmprect.minx = 8000.0; tmprect.miny = 6000.0; tmprect.maxx = 9000.0; tmprect.maxy = 7000.0; strcpy(shpname,"POLY7"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_shape_generate_rectangle (&tmprect,tmpshape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); //add second part to target shape result = SE_shape_add_part (tmpshape, shape); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp8 rectangle.minx = 2000.0; rectangle.miny = 4000.0; rectangle.maxx = 9000.0; rectangle.maxy = 9000.0; strcpy(shpname,"POLY8"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //insert shp9: small polygon rectangle.minx = 9995.0; rectangle.miny = 3995.0; rectangle.maxx = 10005.0; rectangle.maxy = 4005.0; strcpy(shpname,"POLY9"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_shape_generate_rectangle (&rectangle,shape); check_rc_return_on_failure (handle,NULL,result,"SE_shape_generate_rectangle"); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //flush the insert stream result = SE_stream_flush_buffered_writes (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_flush_buffered_writes"); result = SE_stream_free(stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_free"); //commit the transation result = SE_connection_commit_transaction (handle); check_rc_return_on_failure (handle,NULL,result,"SE_connection_commit_transaction"); SE_coordref_free(coordref); SE_shape_free(shape); SE_layerinfo_free(layer); free(base_columns); return(SE_SUCCESS); } /*********************************************************************** * *N {S_query_layer} - perform the queries. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Query the layer, and showing either relationships between the filter * shape and each feature in the layer;or the result the spatial query. *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the result layer name * == (CHAR*) the spatial column name * == (CHAR*) the where clause * == (SE_FILTER*) the spatial filter to be used * == (BOOL) TRUE to print relationship between the * shape in shpfilter and each feature in test layer; * False to apply the filter and do the spatial query *E ***********************************************************************/ static LONG S_query_layer(SE_CONNECTION connection, const CHAR *table,const CHAR* spatialcol, const CHAR* where,SE_FILTER* shpfilter,BOOL queryrelations){ LONG result,num_of_column,rowid; CHAR **columns; CHAR shpname[10]; SHORT shpname_ind,rowid_ind,shape_ind; CHAR byclause[128]; SE_LAYERINFO layer; SE_COORDREF coordref; SE_SHAPE shape; SE_QUERYINFO qinfo; SE_STREAM query_stream; BOOL iscontaining, iswithin,istouching,iscrossing,isoverlapping,isequal; LONG returned_shps_count=0,i; BOOL matched=TRUE; if(shpfilter==NULL){ printf("Invalid filter.\n"); return SE_FAILURE; } //prepare a shape object result = SE_layerinfo_create (NULL,&layer); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_create"); result = SE_coordref_create (&coordref); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_create"); result = SE_layer_get_info (connection,table,spatialcol,layer); check_rc_return_on_failure (connection,NULL,result,"SE_layer_get_info"); result = SE_layerinfo_get_coordref (layer,coordref); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_get_coordref"); result = SE_shape_create (coordref,&shape); check_rc_return_on_failure (connection,NULL,result,"SE_shape_create"); //prepare a query stream result=SE_stream_create(connection, &query_stream); check_rc_return_on_failure (connection,NULL,result,"SE_stream_create"); columns = (CHAR **) malloc (4 * sizeof(CHAR *)); for(i=0;i<3;i++) columns[i]=(CHAR *) malloc (SE_MAX_COLUMN_LEN); strcpy(columns[0], "ROWIDCOL"); strcpy(columns[1], "SHPNAME"); strcpy(columns[2],spatialcol); num_of_column=3; result = SE_queryinfo_create(&qinfo); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_create"); result = SE_queryinfo_set_tables (qinfo, 1, &table, NULL); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_tables"); result = SE_queryinfo_set_columns (qinfo, num_of_column, (const CHAR**)columns); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_columns"); result = SE_queryinfo_set_where_clause(qinfo,where); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_where_clause"); strcpy(byclause,"order by SHPNAME"); result = SE_queryinfo_set_by_clause(qinfo,byclause); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_by_clause"); result = SE_stream_query_with_info (query_stream,qinfo); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_query_with_info"); /*Apply spatial filter if needed: If queryrelations is true, we will only check spatial relationships betwee the filter shape and each feature in the layer. */ if(!queryrelations){ result = SE_stream_set_spatial_constraints (query_stream,SE_OPTIMIZE,FALSE,(SHORT)1,shpfilter); if(result==SE_DBMS_DOES_NOT_SUPPORT){ printf("\tDBMS NOT SUPPORTED.\n"); SE_shape_free(shape); SE_layerinfo_free(layer); SE_queryinfo_free(qinfo); SE_stream_free(query_stream); free(columns); return result; } check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_set_spatial_constraints"); } //binding output result = SE_stream_bind_output_column (query_stream,1,&rowid,&rowid_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,2,shpname,&shpname_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,3,shape,&shape_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_execute (query_stream); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_execute"); if(queryrelations){ printf("%-10s %-10s %-10s %-10s %-10s %-10s %-10s\n", "SHPNAME","CONTAIN","WITHIN","TOUCH","CROSS","OVERLAP","EQUAL"); printf("======================================================================\n"); }else printf("\tReturned Shapes:"); returned_shps_count=0; while(result==SE_SUCCESS){ result = SE_stream_fetch (query_stream); if(result!=SE_FINISHED){ check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_fetch"); if(queryrelations){//checking spatial relationships only, iscontaining=SE_shape_is_containing(shape, shpfilter->filter.shape); iswithin=SE_shape_is_within (shape,shpfilter->filter.shape); istouching=SE_shape_is_touching(shape,shpfilter->filter.shape); iscrossing=SE_shape_is_crossing(shape,shpfilter->filter.shape); isoverlapping=SE_shape_is_overlapping(shape,shpfilter->filter.shape); isequal=SE_shape_is_equal(shape,shpfilter->filter.shape); printf("%-10s ",shpname); printf("%-10s ",iscontaining?"YES":"NO"); printf("%-10s ",iswithin?"YES":"NO"); printf("%-10s ",istouching?"YES":"NO"); printf("%-10s ",iscrossing?"YES":"NO"); printf("%-10s ",isoverlapping?"YES":"NO"); printf("%-10s \n",isequal?"YES":"NO"); }else{ returned_shps_count++; printf("%s ",shpname); } }//end if(result!=SE_FINISHED) }//end while if(!queryrelations){ if(returned_shps_count==0) printf("No Feature selected\n"); else printf("\n"); } //clean up SE_coordref_free(coordref); SE_shape_free(shape); SE_layerinfo_free(layer); SE_queryinfo_free(qinfo); SE_stream_free(query_stream); free(columns); return (SE_SUCCESS); } /*********************************************************************** * *N {S_prepare_filter_shape} -- Prepare a shape for the spatial filter * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Prepare a shape for the spatial filter *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the result layer name * == (CHAR*) the spatial column name * == (CHAR*) filter shape type * == (OUT:SE_SHAPE*) the result shape *E ***********************************************************************/ static LONG S_prepare_filter_shape(SE_CONNECTION conn, CHAR* table,CHAR* spcol,SP_FILTER_SHPTYPE fshptype,SE_SHAPE* shape){ SE_POINT shape_points[10]; int num_of_points,num_of_parts, part_offsets[10]; SE_LAYERINFO layer; SE_COORDREF coordref; LONG result; //prepare the shape object result = SE_layerinfo_create (NULL,&layer); check_rc_return_on_failure (conn,NULL,result,"SE_layerinfo_create"); result = SE_coordref_create (&coordref); check_rc_return_on_failure (conn,NULL,result,"SE_coordref_create"); result = SE_layer_get_info (conn,table,spcol,layer); check_rc_return_on_failure (conn,NULL,result,"SE_layer_get_info"); result = SE_layerinfo_get_coordref (layer,coordref); check_rc_return_on_failure (conn,NULL,result,"SE_layerinfo_get_coordref"); result = SE_shape_create (coordref,shape); check_rc_return_on_failure (conn,NULL,result,"SE_shape_create"); shape_points[0].x=2000; shape_points[0].y=4000; shape_points[1].x=9000; shape_points[1].y=4000; shape_points[2].x=9000; shape_points[2].y=9000; shape_points[3].x=2000; shape_points[3].y=9000; shape_points[4].x=2000; shape_points[4].y=4000; num_of_points=5; num_of_parts=1; part_offsets[0]=0; if(fshptype==SP_FILTER_POINT){ result = SE_shape_generate_point(num_of_points, shape_points, NULL, NULL, *shape); check_rc_return_on_failure (conn,NULL,result,"SE_shape_generate_point"); }else if(fshptype==SP_FILTER_LINE ){ result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shape_points, NULL, NULL, *shape); check_rc_return_on_failure (conn,NULL,result,"SE_shape_generate_line"); }else if(fshptype==SP_FILTER_POLYGON){ result = SE_shape_generate_polygon(num_of_points, num_of_parts, part_offsets, shape_points, NULL, NULL, *shape); check_rc_return_on_failure (conn,NULL,result,"SE_shape_generate_polygon"); }else{ return SE_FAILURE; } SE_layerinfo_free(layer); SE_coordref_free(coordref); return SE_SUCCESS; } /*********************************************************************** * *N {S_prepare_filter_shape} -- Applied provided filter * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Excecute spatial querie using provided filter shape with different * seacg method * * The following filter will be demostrated: * SM_ENVP :Envelopes overlap * SM_CP : Common point * SM_LCROSS : Line cross * SM_COMMON : Common edge/line * SM_CP_OR_LCROSS : Common point or line cross * SM_AI_OR_ET : Edge touch or area intersect * SM_AI : Area intersect * SM_PC : Primary contained in secondary * SM_SC : Secondary contained in primary * SM_IDENTICAL : Identical *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the result layer name * == (CHAR*) the spatial column name * == (CHAR*) the where clause * == (SE_FILTER*) the spatial filter to be used * == (BOOL) TRUE to print relationship between the * shape in shpfilter and each feature in test layer; * False to apply the filter and do the spatial query *E ***********************************************************************/ static LONG S_apply_filters(SE_CONNECTION conn, const CHAR *table,const CHAR* shapecol, CHAR* where, SE_FILTER spfilter){ LONG result; printf("\nSearch Method=SM_ENVP\n"); spfilter.method=SM_ENVP; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_CP\n"); spfilter.method=SM_CP; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_LCROSS\n"); spfilter.method=SM_LCROSS; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_COMMON\n"); spfilter.method=SM_COMMON; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_CP_OR_LCROSS\n"); spfilter.method=SM_CP_OR_LCROSS; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_AI_OR_ET:\n"); spfilter.method=SM_AI_OR_ET; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_AI:\n"); spfilter.method=SM_AI; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_PC:\n"); spfilter.method=SM_PC; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_SC:\n"); spfilter.method=SM_SC; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); printf("Search Method=SM_IDENTICAL:\n"); spfilter.method=SM_IDENTICAL; result=S_query_layer(conn , table,shapecol,where,&spfilter,FALSE); return SE_SUCCESS; } /*********************************************************************** * *N {S_execute_queries} -- Exceute different spatial query againt the * the target layer. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Funtion to execute different spatial querys against the target layer *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the result layer name * == (CHAR*) the spatial column name *E ***********************************************************************/ static LONG S_execute_queries(SE_CONNECTION conn,CHAR *table,CHAR* shapecol){ SE_FILTER spfilter; SE_SHAPE shape; CHAR where[256]; LONG result; shape=NULL; strcpy(where,""); strcpy(spfilter.table,table); strcpy(spfilter.column,shapecol); spfilter.filter_type = SE_SHAPE_FILTER; spfilter.truth = TRUE; /*Case 1. Demo point filter */ printf("Case 1. Point Filter...\n"); result=S_prepare_filter_shape(conn,table,shapecol,SP_FILTER_POINT,&shape); spfilter.filter.shape = shape; //show ther relation between the filter shape and features in the layer printf("Relationship between filter shape and features in the layer:\n"); result=S_query_layer(conn , table,shapecol,where,&spfilter,TRUE); if(result!=SE_SUCCESS) return result; //apply different search methods result=S_apply_filters(conn,table,shapecol,where,spfilter); if(result!=SE_SUCCESS) return result; SE_shape_free(shape); /*Case 2. Demo Line filter */ printf("\nCase 2. Line Filter...\n"); result=S_prepare_filter_shape(conn,table,shapecol,SP_FILTER_LINE,&shape); spfilter.filter.shape = shape; //show ther relation between the filter shape and features in the layer printf("Relationship between filter shape and features in the layer:\n"); result=S_query_layer(conn , table,shapecol,where,&spfilter,TRUE); if(result!=SE_SUCCESS) return result; //apply different search methods result=S_apply_filters(conn,table,shapecol,where,spfilter); if(result!=SE_SUCCESS) return result; SE_shape_free(shape); /*Case 3. Demo Polygon filter*/ printf("\nCase 3. Polygon Filter...\n"); result=S_prepare_filter_shape(conn,table,shapecol,SP_FILTER_POLYGON,&shape); spfilter.filter.shape = shape; //show ther relation between the filter shape and features in the layer printf("Relationship between filter shape and features in the layer:\n"); result=S_query_layer(conn , table,shapecol,where,&spfilter,TRUE); if(result!=SE_SUCCESS) return result; //apply different search methods result=S_apply_filters(conn,table,shapecol,where,spfilter); if(result!=SE_SUCCESS) return result; SE_shape_free(shape); return SE_SUCCESS; } /*********************************************************************** * *N {check_rc_} - check the returned code * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Check returned sde error code and print the error messages. ***********************************************************************/ void check_rc_(SE_CONNECTION Connection, SE_STREAM Stream, LONG rc, char *comment, LONG line_no, char* file_name) { SE_ERROR error; CHAR error_string [SE_MAX_MESSAGE_LENGTH]; LONG temp_rc=SE_FAILURE; if ((rc != SE_SUCCESS) && (rc != SE_FINISHED)) { error_string[0] = '\0'; SE_error_get_string (rc, error_string); printf ("%s encountered a %d error:\"%s\" \nat line %ld in file %s\n",comment, rc,error_string, line_no, file_name); /*Print extended error info, if any */ if ((SE_DB_IO_ERROR == rc) | (SE_INVALID_WHERE == rc) | (SE_SSA_FUNCTION_ERROR == rc)) { if (NULL != Stream) { /* Assume this is a stream error */ temp_rc = SE_stream_get_ext_error (Stream, &error); }else if (NULL != Connection) { /*Assume this is a connection error */ temp_rc = SE_connection_get_ext_error (Connection, &error); } if (SE_SUCCESS == temp_rc) { printf("Extended error code: %d, extended error string:\n%s\n", error.ext_error, error.err_msg1); } } /*End SE_DB_IO_ERROR */ } }