void gv_shapes_replace_shapes(GvShapes *shapes, gint num_shapes, gint *shape_id, GvShape **shps, int make_copy) { gint i; GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL}; change_info.num_shapes = num_shapes; change_info.shape_id = shape_id; gv_data_changing(GV_DATA(shapes), &change_info); for (i=0; i < num_shapes; ++i) { GvShape *shape; if( shape_id[i] < 0 || shape_id[i] >= shapes->shapes->len ) continue; else if( gv_shapes_get_shape(shapes, shape_id[i]) != NULL ) gv_shape_unref( gv_shapes_get_shape(shapes, shape_id[i]) ); else g_warning( "Missing shape in gv_shapes_replace_shapes()" ); if( make_copy ) shape = gv_shape_copy(shps[i]); else shape = shps[i]; gv_shape_ref( shape ); g_ptr_array_index(shapes->shapes, shape_id[i]) = shape; } gv_data_changed(GV_DATA(shapes), &change_info); }
static void gv_shapes_finalize(GObject *gobject) { GvShapes *shapes = GV_SHAPES(gobject); int i; if (shapes->shapes != NULL) { for( i = 0; i < gv_shapes_num_shapes(shapes); i++ ) { if( gv_shapes_get_shape(shapes, i) != NULL ) gv_shape_unref( gv_shapes_get_shape(shapes, i) ); } g_ptr_array_free(shapes->shapes,TRUE); shapes->shapes = NULL; } #ifdef HAVE_OGR if (shapes->hOGRds != NULL) OGR_DS_Destroy( shapes->hOGRds ); #endif /* Call parent class finalize */ G_OBJECT_CLASS(parent_class)->finalize(gobject); }
void gv_rotate_tool_terminate( GvRotateTool *tool ) { if( tool->rrmode == RRMODE_DISPLAY ) return; if( tool->original != NULL && gv_shapes_get_shape( tool->layer->data, tool->shape_id) != NULL ) { gv_shapes_replace_shapes( tool->layer->data, 1, &(tool->shape_id), &(tool->original), FALSE ); tool->original = NULL; gv_undo_enable(); gv_undo_open(); } else if( tool->original != NULL ) { gv_shape_delete( tool->original ); tool->original = NULL; gv_undo_enable(); gv_undo_open(); } tool->shape_id = -1; tool->rrmode = RRMODE_DISPLAY; gv_view_area_queue_draw(GV_TOOL(tool)->view); }
static void gv_rect_tool_reshape( GvRectTool *r_tool, gvgeocoord x, gvgeocoord y ) { GvShape *shape; gvgeocoord x1, y1, x2, y2; gv_tool_clamp_to_bounds( GV_TOOL(r_tool), &x, &y ); shape = gv_shapes_get_shape( r_tool->layer->data, r_tool->shape_id ); if( shape == NULL || gv_shape_get_nodes( shape, 0 ) != 5 ) return; shape = gv_shape_copy( shape ); x1 = gv_shape_get_x(shape,0,0); y1 = gv_shape_get_y(shape,0,0); x2 = gv_shape_get_x(shape,0,2); y2 = gv_shape_get_y(shape,0,2); if( r_tool->picked == PICK_SIDE_TOP ) y1 = y; else if( r_tool->picked == PICK_SIDE_RIGHT ) x2 = x; else if( r_tool->picked == PICK_SIDE_BOTTOM ) y2 = y; else if( r_tool->picked == PICK_SIDE_LEFT ) x1 = x; else if( r_tool->picked == PICK_CORNER_TOPLEFT ) { x1 = x; y1 = y; } else if( r_tool->picked == PICK_CORNER_TOPRIGHT ) { x2 = x; y1 = y; } else if( r_tool->picked == PICK_CORNER_BOTTOMRIGHT ) { x2 = x; y2 = y; } else if( r_tool->picked == PICK_CORNER_BOTTOMLEFT ) { x1 = x; y2 = y; } gv_shape_set_xyz( shape, 0, 0, x1, y1, 0 ); gv_shape_set_xyz( shape, 0, 1, x1, y2, 0 ); gv_shape_set_xyz( shape, 0, 2, x2, y2, 0 ); gv_shape_set_xyz( shape, 0, 3, x2, y1, 0 ); gv_shape_set_xyz( shape, 0, 4, x1, y1, 0 ); gv_shapes_replace_shapes( r_tool->layer->data, 1, &(r_tool->shape_id), &shape, FALSE ); }
void gv_shapes_get_extents(GvShapes *shapes, GvRect *rect) { if (!shapes->extents_valid) { gint i, num_shapes, valid_shapes = 0; GvVertex vmax, vmin; vmin.x = vmin.y = GV_MAXFLOAT; vmax.x = vmax.y = -GV_MAXFLOAT; num_shapes = gv_shapes_num_shapes(shapes); for (i=0; i < num_shapes; ++i) { GvRect rect; GvShape *shape = gv_shapes_get_shape(shapes,i); if( shape == NULL ) continue; gv_shape_get_extents( shape, &rect ); if( rect.x != 0 || rect.y != 0 || rect.width != 0 || rect.height != 0 ) { valid_shapes++; vmin.x = MIN(vmin.x,rect.x); vmax.x = MAX(vmax.x,rect.x+rect.width); vmin.y = MIN(vmin.y,rect.y); vmax.y = MAX(vmax.y,rect.y+rect.height); } } if (valid_shapes == 0) { shapes->extents.x = 0; shapes->extents.y = 0; shapes->extents.width = 0; shapes->extents.height = 0; } else { shapes->extents.x = vmin.x; shapes->extents.y = vmin.y; shapes->extents.width = vmax.x - vmin.x; shapes->extents.height = vmax.y - vmin.y; } shapes->extents_valid = TRUE; } *rect = shapes->extents; }
static void gv_shapes_get_memento(GvData *gv_data, gpointer data, GvDataMemento **memento) { GvShapes *shapes = GV_SHAPES(gv_data); GvShapesMemento *mem; GvShapeChangeInfo *info = (GvShapeChangeInfo *) data; int i; mem = g_new(GvShapesMemento, 1); mem->base.data = GV_DATA(shapes); mem->base.type = info->change_type; mem->ids = g_array_new(FALSE, FALSE, sizeof(gint)); g_array_append_vals(mem->ids, info->shape_id, info->num_shapes); /* Grab in ascending order */ if (info->num_shapes > 1) { g_sort_type(mem->ids->data, gint, mem->ids->len); } if (info->change_type == GV_CHANGE_ADD) { mem->shapes = NULL; } else { mem->shapes = g_ptr_array_new(); for (i=0; i < info->num_shapes; ++i) { GvShape *shape = gv_shapes_get_shape(shapes,info->shape_id[i]); shape = gv_shape_copy( shape ); gv_shape_ref( shape ); g_ptr_array_add(mem->shapes, shape ); } } *memento = (GvDataMemento*)mem; }
static gint gv_rotate_tool_setup_arrows( GvRotateTool *tool ) { GvVertex3d pivot_3d; GvShape *shape = gv_shapes_get_shape( tool->layer->data, tool->shape_id ); if( shape == NULL ) { CPLDebug( "OpenEV", "gv_rotate_tool_setup_arrows(), shape==NULL!" ); tool->shape_id = -1; return 0; } /* -------------------------------------------------------------------- */ /* Compute the pivot location. */ /* -------------------------------------------------------------------- */ if( !gv_shape_get_center( shape, &pivot_3d ) ) return 0; tool->v_pivot.x = pivot_3d.x; tool->v_pivot.y = pivot_3d.y; /* -------------------------------------------------------------------- */ /* Compute the up vector. */ /* -------------------------------------------------------------------- */ gv_view_area_correct_for_transform( GV_TOOL(tool)->view, 0.0, 1.0, &(tool->v_up.x), &(tool->v_up.y) ); gv_view_area_correct_for_transform( GV_TOOL(tool)->view, 1.0, 0.0, &(tool->v_right.x), &(tool->v_right.y) ); tool->rotation = 0.0; tool->scaling = 1.0; return 1; }
void gv_shapes_translate_shapes(GvShapes *shapes, gint num_shapes, gint *id_list, gvgeocoord dx, gvgeocoord dy) { GvShape *shape; gint i; GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL}; change_info.num_shapes = num_shapes; change_info.shape_id = id_list; gv_data_changing(GV_DATA(shapes), &change_info); for (i=0; i < num_shapes; ++i) { int ring; shape = gv_shapes_get_shape(shapes,id_list[i]); if( shape == NULL ) continue; for( ring = gv_shape_get_rings(shape)-1; ring >= 0; ring-- ) { int node; for( node = gv_shape_get_nodes(shape,ring)-1; node >= 0; node-- ) { gv_shape_set_xyz( shape, ring, node, gv_shape_get_x(shape, ring, node) + dx, gv_shape_get_y(shape, ring, node) + dy, gv_shape_get_z(shape, ring, node) ); } } } gv_data_changed(GV_DATA(shapes), &change_info); }
static void gv_rotate_tool_button_press(GvTool *r_tool, GdkEventButton *event) { GvRotateTool *tool = GV_ROTATE_TOOL(r_tool); if( event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) ) return; /* -------------------------------------------------------------------- */ /* Have we selected an active control point on the scale/rotate */ /* dohickey? */ /* -------------------------------------------------------------------- */ if( tool->rrmode == RRMODE_DISPLAY && tool->shape_id != -1 ) { gv_view_area_map_pointer(GV_TOOL(tool)->view, event->x, event->y, &tool->v_head.x, &tool->v_head.y); /* ** Is this location a hit on an arrow head? */ tool->rrmode = gv_rotate_tool_classify_hit( tool, tool->v_head.x, tool->v_head.y ); /* ** Copy the original state of this shape, and disable undo till we are ** done. */ if( tool->rrmode != RRMODE_DISPLAY ) { if( event->button != 1 ) tool->rrmode = RRMODE_ROTATESCALE; tool->original = gv_shape_copy( gv_shapes_get_shape( tool->layer->data, tool->shape_id )); gv_undo_close(); gv_undo_disable(); } } /* -------------------------------------------------------------------- */ /* Are we selecting a shape? Note, currently we cannot clear */ /* our selection in resize/rotate mode - should we be able to? */ /* -------------------------------------------------------------------- */ if (event->button == 1 && tool->rrmode == RRMODE_DISPLAY ) { int shape_id; if (!gv_rotate_tool_configure(tool)) return; if (gv_shape_layer_pick_shape(GV_SHAPE_LAYER(tool->layer), GV_TOOL(tool)->view, event->x, event->y, &shape_id)) { GvShape *shape; /* Is the shape rotatable? */ shape = gv_shapes_get_shape( tool->layer->data, shape_id ); if( TRUE ) { gv_shape_layer_clear_selection( GV_SHAPE_LAYER(tool->layer)); gv_shape_layer_select_shape( GV_SHAPE_LAYER(tool->layer), shape_id); tool->shape_id = shape_id; gv_view_area_queue_draw(GV_TOOL(tool)->view); } } return; } }
void gv_shapes_add_height(GvShapes *shapes, GvData *raster_data, double offset, double default_height) { int success, i, num_shapes; double x, y, z, last_z, imaginary, nodata_value; GvRaster *raster = GV_RASTER(raster_data); GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL}; int *id_list; /* * Notify of impending change. */ num_shapes = gv_shapes_num_shapes(shapes); id_list = g_new( int, num_shapes ); change_info.num_shapes = 0; change_info.shape_id = id_list; for (i=0; i < num_shapes; i++) { if( gv_shapes_get_shape(shapes,i) != NULL ) id_list[change_info.num_shapes++] = i; } gv_data_changing(GV_DATA(shapes), &change_info); /* * Establish the "nodata" value. */ success = gv_raster_get_nodata( raster, &nodata_value ); if( !success ) nodata_value = -1e8; /* * Loop over all shapes, applying height. */ for (i=0; i < num_shapes; i++) { GvShape *shape = gv_shapes_get_shape(shapes,i); int ring, ring_count = gv_shape_get_rings( shape ); if( shape == NULL ) continue; last_z = default_height; for( ring = 0; ring < ring_count; ring++ ) { int node, node_count = gv_shape_get_nodes( shape, ring ); for( node = 0; node < node_count; node++ ) { double x_orig, y_orig; /* get xy in image space */ x_orig = x = gv_shape_get_x( shape, ring, node ); y_orig = y = gv_shape_get_y( shape, ring, node ); z = 0.0; if (!gv_raster_georef_to_pixel(raster, &x, &y, &z)) { fprintf(stderr, "ERROR raster_georef_to_pixel failed!!!\n"); break; } if( x > -1.0 && x < 0.0 ) x = 0.0; if( y > -1.0 && y < 0.0 ) y = 0.0; if( x >= raster->width && x < raster->width+1 ) x = raster->width - 0.01; if( y >= raster->height && y < raster->height+1 ) y = raster->height - 0.01; /* Check if mesh xy values outside of height raster - leave as 0 */ if( x >= 0.0 && x < raster->width && y >= 0.0 && y < raster->height ) { if (!gv_raster_get_sample(raster, x, y, &z, &imaginary)) { fprintf(stderr, "ERROR raster_get_sample failed for (x y z) %f %f\n", x, y); } else { if( z == nodata_value && x > 0 ) gv_raster_get_sample(raster, x-1, y, &z, &imaginary); if( z == nodata_value && x < raster->width-1 ) gv_raster_get_sample(raster, x+1, y, &z, &imaginary); if( z == nodata_value && y > 0 ) gv_raster_get_sample(raster, x, y-1, &z, &imaginary); if( z == nodata_value && y < raster->height-1 ) gv_raster_get_sample(raster, x, y+1, &z, &imaginary); if( z == nodata_value && x > 1 ) gv_raster_get_sample(raster, x-2, y, &z, &imaginary); if( z == nodata_value && x < raster->width-2 ) gv_raster_get_sample(raster, x+2, y, &z, &imaginary); if( z == nodata_value && y > 1 ) gv_raster_get_sample(raster, x, y-2, &z, &imaginary); if( z == nodata_value && y < raster->height-2 ) gv_raster_get_sample(raster, x, y+2, &z, &imaginary); if( z == nodata_value ) z = last_z; else z += offset; last_z = z; } } gv_shape_set_xyz( shape, ring, node, x_orig, y_orig, z ); } } } /* notify of completed change */ gv_data_changed(GV_DATA(shapes), &change_info); g_free( id_list); }
static gboolean gv_rect_tool_button_press(GvTool *r_tool, GdkEventButton *event) { GvRectTool *tool = GV_RECT_TOOL(r_tool); if (event->button == 1 && !tool->drawing ) { GvNodeInfo edit_node; int before, shape_id, is_rectangle = FALSE; if (!gv_rect_tool_configure(tool)) return FALSE; if (gv_shape_layer_pick_shape(GV_SHAPE_LAYER(tool->layer), GV_TOOL(tool)->view, event->x, event->y, &shape_id)) { GvShape *shape; /* Is the shape a rectangle? */ shape = gv_shapes_get_shape( tool->layer->data, shape_id ); if( shape != NULL && gv_shape_type(shape) == GVSHAPE_AREA && gv_shape_get_rings( shape ) == 1 && gv_shape_get_nodes( shape, 0 ) == 5 ) { gvgeocoord x1, y1, x2, y2; x1 = gv_shape_get_x(shape,0,0); y1 = gv_shape_get_y(shape,0,0); x2 = gv_shape_get_x(shape,0,2); y2 = gv_shape_get_y(shape,0,2); tool->winding = 1; is_rectangle = gv_shape_get_x(shape,0,1) == x1 && gv_shape_get_y(shape,0,1) == y2 && gv_shape_get_x(shape,0,3) == x2 && gv_shape_get_y(shape,0,3) == y1 && gv_shape_get_x(shape,0,4) == x1 && gv_shape_get_y(shape,0,4) == y1; if( !is_rectangle ) { tool->winding = 0; is_rectangle = gv_shape_get_x(shape,0,1) == x2 && gv_shape_get_y(shape,0,1) == y1 && gv_shape_get_x(shape,0,3) == x1 && gv_shape_get_y(shape,0,3) == y2 && gv_shape_get_x(shape,0,4) == x1 && gv_shape_get_y(shape,0,4) == y1; } if( is_rectangle ) { gv_shape_layer_clear_selection( GV_SHAPE_LAYER(tool->layer)); gv_shape_layer_select_shape( GV_SHAPE_LAYER(tool->layer), shape_id); } } } /* Is the user selecting an existing rectangles edge/corner? */ if (is_rectangle && gv_shape_layer_pick_node(GV_SHAPE_LAYER(tool->layer), GV_TOOL(tool)->view, event->x, event->y, &before, &edit_node) ) { if( tool->winding == 0 ) { if( before ) edit_node.node_id = 5 - edit_node.node_id; else edit_node.node_id = 4 - edit_node.node_id; } if( before && edit_node.node_id == 1 ) tool->picked = PICK_SIDE_LEFT; else if( before && edit_node.node_id == 2 ) tool->picked = PICK_SIDE_BOTTOM; else if( before && edit_node.node_id == 3 ) tool->picked = PICK_SIDE_RIGHT; else if( before && edit_node.node_id == 4 ) tool->picked = PICK_SIDE_TOP; else if( edit_node.node_id == 0 ) tool->picked = PICK_CORNER_TOPLEFT; else if( edit_node.node_id == 1 ) tool->picked = PICK_CORNER_BOTTOMLEFT; else if( edit_node.node_id == 2 ) tool->picked = PICK_CORNER_BOTTOMRIGHT; else if( edit_node.node_id == 3 ) tool->picked = PICK_CORNER_TOPRIGHT; else if( edit_node.node_id == 4 ) tool->picked = PICK_CORNER_TOPLEFT; else { g_warning( "Yikes! What node is this?" ); return FALSE; } tool->reshaping = TRUE; tool->shape_id = edit_node.shape_id; /* Close down undo. A single operation describing the new ring will be pushed to undo when drawing stops. */ gv_undo_close(); gv_undo_disable(); return FALSE; } /* Map pointer position to tail vertex */ gv_view_area_map_pointer(GV_TOOL(tool)->view, event->x, event->y, &tool->v_tail.x, &tool->v_tail.y); if( gv_tool_check_bounds( GV_TOOL(tool), tool->v_tail.x, tool->v_tail.y ) ) { /* Start a new rect */ tool->drawing = TRUE; tool->v_head = tool->v_tail; } } return FALSE; }