/* simple3.c created by Laura Toma modded by Carl Morrissey */ #include #include #include #include #include "maptypes.h" #include "map_parse.h" #include "edgegraph.h" #include "djikstra.h" #ifdef __APPLE__ #include #else #include #endif const int WINDOW_WIDTH = 750; const int WINDOW_HEIGHT = 750; double correction_x = 0; double correction_y = 0; float scalef = 1; int flag = 1; int shapepoints = 0; const GLdouble N_BOUND = 42018799; const GLdouble S_BOUND = 41125821; const GLdouble E_BOUND = -71088571; const GLdouble W_BOUND = -71907258; GLdouble EW_AVG; GLdouble NS_AVG; float mouse_x = -10; float mouse_y = -10; double start_x, start_y, end_x, end_y; GraphNode* startNode, *endNode; int maxset = 0; GLfloat red[3] = {1.0, 0.0, 0.0}; GLfloat green[3] = {0.0, 1.0, 0.0}; GLfloat blue[3] = {0.0, 0.0, 1.0}; GLfloat black[3] = {0.0, 0.0, 0.0}; GLfloat white[3] = {1.0, 1.0, 1.0}; GLfloat gray[3] = {0.5, 0.5, 0.5}; GLfloat yellow[3] = {1.0, 1.0, 0.0}; GLfloat magenta[3] = {1.0, 0.0, 1.0}; GLfloat cyan[3] = {0.0, 1.0, 1.0}; const int ROAD = 0; const int RR = 1; const int HYDRO = 2; //Road, RR, Hydro int whatToDraw[3] = {1, 1, 1}; LinkMap* map; LinkNode* route = NULL; State* st; int num_states; /* forward declarations of functions */ void display(void); void keypress(unsigned char key, int x, int y); void main_menu(int value); void mousepress(int button, int state, int x, int y); void drawCircle(float x, float y); int main(int argc, char** argv) { /* testing distance function Location test1; Location test2; Location test3; Location test4; test1.lat = 42018799; test1.lon = -71088571; test2.lat = 41125821; test2.lon = -71907258; //test3.lat = 100; test3.lon = 0; //test4.lat = 3; test4.lon = 4; double d1, d2, d3, d4; d1 = distance(test1, test2); //d2 = distance(test1, test3); //d3 = distance(test1, test4); //d4 = distance(test2, test3); printf("First distance = %f\n", d1);//\n Second distance = %f\n Third distance = %f\n Fourth distance = %f\n", d1, d2, d3, d4); */ EW_AVG = (E_BOUND + W_BOUND) / 2; NS_AVG = (N_BOUND + S_BOUND) / 2; printf("initializing..."); fflush(stdout); st = (State *) malloc(sizeof(State) * argc); assert(st); num_states = argc - 1; int i; for(i = 1; i < num_states + 1; i++){ init(&(st[i-1]), argv[i]); } //LT: init is a bad name for a function that does all the work printf("Creating graph structure...\n"); fflush(stdout); Record* recs = st[0].counties[0].records; long size = st[0].counties[0].num_entries; map = createLinkMap(recs, size); printLinkMap(map); printf("done\nOpening window..."); fflush(stdout); /* open a window */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); printf("done\n"); fflush(stdout); /* OpenGL init */ glClearColor(0, 0, 0, 0); /* set background color black*/ /* callback functions */ glutDisplayFunc(display); glutKeyboardFunc(keypress); glutMouseFunc(mousepress); glutCreateMenu(main_menu); glutAddMenuEntry("Roads", 1); glutAddMenuEntry("Railroads", 2); glutAddMenuEntry("Hydrology", 3); glutAddMenuEntry("Toggle Shapepoints", 4); glutAddMenuEntry("Quit", 5); glutAttachMenu(GLUT_RIGHT_BUTTON); /* event handler */ glutMainLoop(); return 0; } void draw_features(){ gluOrtho2D(scalef * W_BOUND + (1 - scalef) * EW_AVG + correction_x, scalef * E_BOUND + (1 - scalef) * EW_AVG + correction_x, scalef * S_BOUND + (1 - scalef) * NS_AVG + correction_y, scalef * N_BOUND + (1 - scalef) * NS_AVG+ correction_y); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //LT these look arbitrary. Constants? //double scale_factor = 3700000; double scale_factor = 1; // double scale_term_lat = 42480471; //double scale_term_lon = -98785995; double scale_term_lat = 0; double scale_term_lon = 0; //LT same as above //double scale_term_lon = -71000000; //printf("num states = %d\n", num_states); int y; for(y = 0; y < num_states; y++){ State state = st[y]; //printf("opened state %d\n", state.state_num); //printf("state has %d counties\n", state.numcounties); int k; for(k = 0; k < state.numcounties; k++){ County* county = &(state.counties[k]); //printf("opened county %s\n", county->number); fflush(stdout); int idx; for(idx = 0; idx < county->num_entries; idx++){ char type = county->records[idx].type; int draw_category = 0; GLfloat* colorToDraw = yellow; //printf("Record # %d, type = %c\n", county->records[idx].TLID, type); switch(type){ case 'A': draw_category = ROAD; colorToDraw = red; break; case 'B': draw_category = RR; colorToDraw = green; break; case 'H': draw_category = HYDRO; colorToDraw = blue; } if(whatToDraw[draw_category]){ // printf("I'm trying to draw something!\n"); glBegin(GL_LINE_STRIP); glColor3fv(colorToDraw); glVertex2f((double)(county->records[idx].start.lon), (double)(county->records[idx].start.lat)); if(shapepoints){ //printf("num to plot = %d\n", county->records[idx].num_points); fflush(stdout); int i; for(i = 0; i < county->records[idx].num_points; i++){ glVertex2f((double)(county->records[idx].points[i].lon), (double)(county->records[idx].points[i].lat)); if(flag){ printf("plotting a shape point at lat = %ld lon = %ld", (county->records[idx].points[i].lat), (county->records[idx].points[i].lon)); fflush(stdout); flag = 0; } } } glVertex2f((double)(county->records[idx].end.lon), (double)(county->records[idx].end.lat)); /* printf("Ending at %d %d\n", county->records[idx].end.lon, county->records[idx].end.lat); printf("Which becomes %f %f\n", shifted_lon/scale_factor, shifted_lat/scale_factor); */ glEnd(); }//endif }//end record loop }//end county loop }//end state loop //printf("max long = %d min long = %d\n", max_lon, min_lon); //printf("max lat = %d min lat = %d\n", max_lat, min_lat); glColor3fv(yellow); //drawCircle(-(E_BOUND - W_BOUND)/2 + E_BOUND, (N_BOUND - S_BOUND)/2 + S_BOUND); drawCircle(mouse_x, mouse_y); if(route != NULL){ glBegin(GL_LINE_STRIP); glLineWidth(2.0); glVertex2f(map->gnodes[route->link_idx].pos.lon, map->gnodes[route->link_idx].pos.lat); LinkNode* current = route->next; printf("plotted route point at (%ld, %ld)\n", map->gnodes[route->link_idx].pos.lon, map->gnodes[route->link_idx].pos.lat); while(current != NULL){ glVertex2f(map->gnodes[current->link_idx].pos.lon, map->gnodes[current->link_idx].pos.lat); printf("plotted route point at (%ld, %ld)\n", map->gnodes[current->link_idx].pos.lon, map->gnodes[current->link_idx].pos.lat); current = current->next; } glLineWidth(1.0); glEnd(); } } void display(void) { glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* glBegin(GL_LINES); glColor3fv(red); glVertex2f(-0.5, -0.5); glVertex2f(0.5, 0.5); glEnd(); */ //glScalef(scalef, scalef, scalef); draw_features(); /* execute the drawing commands */ glFlush(); } void keypress(unsigned char key, int x, int y) { switch(key) { case 'q': exit(0); break; case 'w': correction_y += scalef * (N_BOUND - S_BOUND)/10; break; case 'a': correction_x -= scalef * (N_BOUND - S_BOUND)/10; break; case 's': correction_y -= scalef * (N_BOUND - S_BOUND)/10; break; case 'd': correction_x += scalef * (N_BOUND - S_BOUND)/10; break; case 'o': scalef /= .9 ; break; case 'p': scalef *= .9; break; } glutPostRedisplay(); } void mousepress(int button, int state, int x, int y){ mouse_x = (float)x / WINDOW_WIDTH *(E_BOUND-W_BOUND) + W_BOUND; mouse_y = -( (float)y / WINDOW_HEIGHT - 1) * (N_BOUND - S_BOUND) + S_BOUND; mouse_x = mouse_x * scalef + (1 - scalef) * EW_AVG + correction_x; mouse_y = mouse_y * scalef + (1 - scalef) * NS_AVG + correction_y; GraphNode g; Location loc; loc.lon = mouse_x; loc.lat = mouse_y; loc = findNearestNode(loc, map, &g); mouse_x = loc.lon; mouse_y = loc.lat; if(state == GLUT_DOWN) { start_x = mouse_x; start_y = mouse_y; long startNode_idx = bsearch_nodes(map->gnodes, loc, map->size); startNode = &(map->gnodes[startNode_idx]); printf("StartNode: pos = (%ld, %ld), edge_list = %d\n", startNode->pos.lat, startNode->pos.lon, startNode->edge_list); fflush(stdout); } else{ end_x = mouse_x; end_y = mouse_y; long endNode_idx = bsearch_nodes(map->gnodes, loc, map->size); endNode = &(map->gnodes[endNode_idx]); printf("EndNode: pos = (%ld, %ld), edge_list = %d\n", endNode->pos.lat, endNode->pos.lon, endNode->edge_list); fflush(stdout); route = shortestPath(map, startNode, endNode); } glutPostRedisplay(); } void main_menu(int value) { switch (value){ case 1: /* toggle Roads */ whatToDraw[ROAD] = !whatToDraw[ROAD]; break; case 2: /* toggle Railroads */ whatToDraw[RR] = !whatToDraw[RR]; break; case 3: /* toggle Hydro */ whatToDraw[HYDRO] = !whatToDraw[HYDRO]; break; case 4: shapepoints = !shapepoints; break; case 5: exit(0); } glutPostRedisplay(); } void drawCircle(float x, float y){ int i; int precision = 100; float r = (E_BOUND - W_BOUND) / 100 * scalef ; float theta = 0; glBegin(GL_POLYGON); for(i = 0; i < precision; i++){ theta = i * 2 * M_PI/precision; glVertex2f(x + r*cos(theta), y + r*sin(theta)); } glEnd(); }