Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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 );
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
    }

}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}