/******************************************************************************* * *N {geom_distance.c} -- demonstrates distance between * different shapes * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *P Purpose: * This sample C program demonstrates the distance between * different shapes * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * How to compile:: * Please refer section "Build C Samples" in the SDE sample * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Usage: * geom_distance {server} {instance} {database} {user} {password} * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *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 "sdetype.h" #include "sdeerno.h" /* 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 void S_print_shape(SE_SHAPE shp); LONG main(int argc, char *argv[]) { CHAR *server, *user, *passwd, *database, *instance; SE_CONNECTION conn; SE_ERROR error; SE_COORDREF coordref; SE_SHAPE shp1,shp2; SE_ENVELOPE env; SE_POINT shp1_coords[10],shp2_coords[10]; int num_of_points,num_of_parts, part_offsets[10]; LONG result; LFLOAT distance; if(argc<6){ printf("Usage %s ",argv[0]); exit(1); } server=argv[1]; instance=argv[2]; database=argv[3]; user=argv[4]; passwd=argv[5]; result = SE_connection_create( server, instance, database, user, passwd, &error, &conn ); check_rc_return_on_failure (conn,NULL,result,"SE_connection_create"); /*prepare two shape handles*/ result = SE_coordref_create (&coordref); check_rc_return_on_failure (NULL,NULL,result,"SE_coordref_create"); result = SE_coordref_set_xy (coordref,0.0,0.0,1000.0); check_rc_return_on_failure (NULL,NULL,result,"SE_coordref_set_xy"); result = SE_shape_create (coordref,&shp1); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_create"); result = SE_shape_create (coordref,&shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_create"); /******************************************************************** * 1. Point Cases * *********************************************************************/ /*distance between two overlapping points*/ printf("\nDistance between two overlapping points:\n"); shp1_coords[0].x=100.0; shp1_coords[0].y=100.0; num_of_points=1; result = SE_shape_generate_point(num_of_points,shp1_coords, NULL, NULL, shp1); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); //We will demostrate SE_shape_duplicate() and create a overlapping point result=SE_shape_duplicate (shp1, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_duplicate"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); //In this sample, we will perform inside tests when calculating distances result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /*distance between two non-overlapping points*/ printf("\nDistance between two non-overlapping points:\n"); shp2_coords[0].x=110.0; shp2_coords[0].y=180.0; num_of_points=1; result = SE_shape_generate_point(num_of_points,shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f\n",distance); /*distance between a simple point and multipoint*/ printf("\nDistance between a simple point and multipoint :\n"); shp2_coords[0].x=150.0; shp2_coords[0].y=180.0; shp2_coords[1].x=130.0; shp2_coords[1].y=100.0; num_of_points=2; result = SE_shape_generate_point(num_of_points,shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /*Distance between completely overlapping multipoint shapes*/ printf("\nDistance between completely overlapping multipoint shapes:\n"); shp1_coords[0].x=150.0; shp1_coords[0].y=180.0; shp1_coords[1].x=130.0; shp1_coords[1].y=100.0; num_of_points=2; result = SE_shape_generate_point(num_of_points,shp1_coords, NULL, NULL, shp1); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /*Distance between partially overlapping multipoint shapess*/ printf("\nDistance between partially overlapping multipoint shapes:\n"); shp2_coords[0].x=150.0; shp2_coords[0].y=180.0; shp2_coords[1].x=100.0; shp2_coords[1].y=100.0; num_of_points=2; result = SE_shape_generate_point(num_of_points,shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /*Distance between non-overlapping multipoint shapes*/ printf("\nDistance between non-overlapping multipoint shapes:\n"); shp2_coords[0].x=140.0; shp2_coords[0].y=140.0; shp2_coords[1].x=160.0; shp2_coords[1].y=200.0; shp2_coords[2].x=300.0; shp2_coords[2].y=120.0; shp2_coords[3].x=300.0; shp2_coords[3].y=150.0; num_of_points=4; result = SE_shape_generate_point(num_of_points,shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_point"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /******************************************************************** * 2. Line Cases v * *********************************************************************/ /*Distance between overlapping simple line shapes*/ printf("\nDistance between overlapping simple line shapes:\n"); shp1_coords[0].x=100.0; shp1_coords[0].y=100.0; shp1_coords[1].x=200.0; shp1_coords[1].y=200.0; shp1_coords[2].x=300.0; shp1_coords[2].y=100.0; num_of_points=3; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shp1_coords, NULL, NULL, shp1); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); result=SE_shape_duplicate (shp1, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_duplicate"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /* Distance between partially overlapping simple line shapes*/ printf("\nDistance between partially overlapping simple line shapes:\n"); shp2_coords[0].x=200.0; shp2_coords[0].y=200.0; shp2_coords[1].x=300.0; shp2_coords[1].y=100.0; shp2_coords[2].x=400.0; shp2_coords[2].y=100.0; num_of_points=3; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /* Distance between non-overlapping simple line shapes*/ printf("\nDistance between non-overlapping simple line shapes:\n"); shp2_coords[0].x=300.0; shp2_coords[0].y=200.0; shp2_coords[1].x=400.0; shp2_coords[1].y=200.0; shp2_coords[2].x=400.0; shp2_coords[2].y=100.0; num_of_points=3; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f\n",distance); /* Distance between overlapping simple line shapes*/ printf("\nDistance between overlapping simple multi-line shapes:\n"); shp1_coords[0].x=100.0; shp1_coords[0].y=100.0; shp1_coords[1].x=200.0; shp1_coords[1].y=200.0; shp1_coords[2].x=300.0; shp1_coords[2].y=100.0; shp1_coords[3].x=400.0; shp1_coords[3].y=100.0; shp1_coords[4].x=400.0; shp1_coords[4].y=200.0; num_of_points=5; num_of_parts=2; part_offsets[0]=0; part_offsets[1]=3; result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shp1_coords, NULL, NULL, shp1); shp2_coords[0].x=100.0; shp2_coords[0].y=100.0; shp2_coords[1].x=200.0; shp2_coords[1].y=200.0; shp2_coords[2].x=300.0; shp2_coords[2].y=100.0; shp2_coords[3].x=400.0; shp2_coords[3].y=100.0; shp2_coords[4].x=400.0; shp2_coords[4].y=200.0; num_of_points=5; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_line(num_of_points, num_of_parts, part_offsets, shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /* Distance between partially overlapping polygon shapes*/ printf("\nDistance between partially overlapping polygon shapes:\n"); shp1_coords[0].x=1.0; shp1_coords[0].y=3.0; shp1_coords[1].x=3.0; shp1_coords[1].y=1.0; shp1_coords[2].x=6.0; shp1_coords[2].y=4.0; shp1_coords[3].x=4.0; shp1_coords[3].y=6.0; shp1_coords[4].x=2.0; shp1_coords[4].y=5.0; shp1_coords[5].x=1.0; shp1_coords[5].y=3.0; num_of_points=6; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_polygon(num_of_points, num_of_parts, part_offsets, shp1_coords, NULL, NULL, shp1); shp2_coords[0].x=4.0; shp2_coords[0].y=1.0; shp2_coords[1].x=6.0; shp2_coords[1].y=2.0; shp2_coords[2].x=7.0; shp2_coords[2].y=5.0; shp2_coords[3].x=6.0; shp2_coords[3].y=6.0; shp2_coords[4].x=4.0; shp2_coords[4].y=4.0; shp2_coords[5].x=4.0; shp2_coords[5].y=1.0; num_of_points=6; num_of_parts=1; part_offsets[0]=0; result = SE_shape_generate_polygon(num_of_points, num_of_parts, part_offsets, shp2_coords, NULL, NULL, shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); /* Distance between rectangles*/ printf("\nDistance between rectangles:\n"); env.minx=200.0; env.miny=200.0; env.maxx=400.0; env.maxy=400.0; result = SE_shape_generate_rectangle(&env,shp1); env.minx=600.0; env.miny=600.0; env.maxx=900.0; env.maxy=900.0; result = SE_shape_generate_rectangle(&env,shp2); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_generate_line"); printf("SHAPE1:"); S_print_shape(shp1); printf("SHAPE2:"); S_print_shape(shp2); result=SE_shape_calculate_distance (shp1, shp2,&distance,TRUE); check_rc_return_on_failure (NULL,NULL,result,"SE_shape_calculate_distance"); printf("Distance=%-7.3f \n",distance); SE_coordref_free(coordref); SE_shape_free(shp1); SE_shape_free(shp2); return SE_SUCCESS; } /*********************************************************************** * *N {S_print_shapes} - print coordinates of a shape * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * print coordinates of a shape *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_SHAPE) The shape to be printed. *E ***********************************************************************/ static void S_print_shape(SE_SHAPE shp){ LONG result; CHAR shp_desc[1024]; LONG shp_size; if(shp ==NULL) printf("NULL\n"); else if(SE_shape_is_nil(shp)) printf("nil shape\n"); else{ result=SE_shape_get_text_size(shp,&shp_size); result=SE_shape_as_text (shp,shp_size+1,shp_desc); printf("%s\n",shp_desc); } } /*********************************************************************** * *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 */ } }