Beispiel #1
0
/* same as gv_shape_add_shape but do not fill the holes, always append shape at the end*/
gint
gv_shapes_add_shape_last(GvShapes *shapes, GvShape *new_shape)

{
    int  shape_id;
    GvShapeChangeInfo change_info = {GV_CHANGE_ADD, 1, NULL};


    shape_id = shapes->shapes->len;

    /* Make notification of impending change */
    change_info.shape_id = &shape_id;
    gv_data_changing(GV_DATA(shapes), &change_info);

    /* apply update */
    if( shape_id == shapes->shapes->len )
        g_ptr_array_add(shapes->shapes, new_shape );
    else
        g_ptr_array_index(shapes->shapes, shape_id) = new_shape;

    gv_shape_ref( new_shape );
    shapes->actual_num_shapes++;

    /* notify of completed change */
    gv_data_changed(GV_DATA(shapes), &change_info);

    return shape_id;
}
Beispiel #2
0
gint
gv_areas_new_area_with_data(GvAreas *areas, GvArea *area_data)
{
    GvArea *area;
    int area_id;
    GvShapeChangeInfo change_info = {GV_CHANGE_ADD, 1, NULL};

    change_info.shape_id = &area_id;

    area_id = areas->areas->len;
    if (area_data)
    {
	area = gv_area_copy(area_data);
    }
    else
    {
	area = gv_area_new(TRUE);
    }
    g_return_val_if_fail(area, 0);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    g_ptr_array_add(areas->areas, area);
    
    gv_data_changed(GV_DATA(areas), &change_info);
    
    /* Generate tesselation if necessary */
    if (area_data)
    {
	gv_areas_tessellate_areas(areas, 1, &area_id);
    }

    return area_id;
}
Beispiel #3
0
void
gv_areas_delete_areas(GvAreas *areas, gint num_areas, gint *area_id)
{
    GvArea *area;
    GvShapeChangeInfo change_info = {GV_CHANGE_DELETE, 0, NULL};

    change_info.num_shapes = num_areas;
    change_info.shape_id = area_id;
    
    gv_data_changing(GV_DATA(areas), &change_info);
    
    if (num_areas == 1)
    {
	area = (GvArea*)g_ptr_array_remove_index_fast(areas->areas, *area_id);
	if (area) gv_area_delete(area);
    }
    else
    {
	/* Strategy: sort the area_id buffer and delete lines in descending
	   order, so that indicies remain valid */
	gint *id, i;

	id = g_memdup_type(area_id, gint, num_areas);
	g_sort_type(id, gint, num_areas);

	for (i=num_areas-1; i >= 0; --i)
	{
	    area = (GvArea*)g_ptr_array_remove_index_fast(areas->areas, id[i]);
	    if (area) gv_area_delete(area);
	}
	g_free(id);
    }
    gv_data_changed(GV_DATA(areas), &change_info);
}
Beispiel #4
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);
}
Beispiel #5
0
gint
gv_areas_tessellate_areas(GvAreas *areas, gint num_areas, gint *area_id)
{
    gint i, hit, ok;
    GvArea *area;

    hit = FALSE;
    ok = TRUE;

    for (i=0; i < num_areas; ++i)
    {
	area = gv_areas_get_area(areas, area_id[i]);
	if (area->fill_objects == 0)
	{
	    if (!gv_area_tessellate(area)) ok = FALSE;
	    hit = TRUE;	    
	}
    }

    if (hit)
    {
	/* FIXME: need a change_info param which describes a
	   tesselation change.  For now use NULL */
	gv_data_changed(GV_DATA(areas), NULL);
    }

    return ok;
}
Beispiel #6
0
static void
gv_shapes_insert_shapes(GvShapes *shapes, gint num_shapes, gint *shape_ids,
                        GvShape **shps)
{
    gint i;
    GvShapeChangeInfo change_info = {GV_CHANGE_ADD, 0, NULL};

    change_info.num_shapes = num_shapes;
    change_info.shape_id = shape_ids;

    gv_data_changing(GV_DATA(shapes), &change_info);

    for (i=0; i < num_shapes; ++i)
    {
        int id = shape_ids[i];

        if( id >= shapes->shapes->len )
        {
            int  old_length = shapes->shapes->len;

            g_ptr_array_set_size( shapes->shapes, id+1 );
            while( old_length < id )
            {
                g_ptr_array_index(shapes->shapes, old_length) = NULL;
                old_length++;
            }

            gv_shape_ref( shps[i] );
            g_ptr_array_index( shapes->shapes, id ) = shps[i];

            shapes->actual_num_shapes++;
        }
        else if( g_ptr_array_index( shapes->shapes, id ) == NULL )
        {
            gv_shape_ref( shps[i] );
            g_ptr_array_index( shapes->shapes, id ) = shps[i];
            shapes->actual_num_shapes++;
        }
        else
        {
            g_warning( "gv_shapes_insert_shapes(): target shape_id not NULL!");
        }
    }

    gv_data_changed(GV_DATA(shapes), &change_info);
}
Beispiel #7
0
static void
gv_areas_insert_areas(GvAreas *areas, gint num_areas, gint *area_ids,
		      GvArea **area)
{
    /* The area_id array must be in ascending order! */
    gint i;
    GvShapeChangeInfo change_info = {GV_CHANGE_ADD, 0, NULL};

    change_info.num_shapes = num_areas;
    change_info.shape_id = area_ids;

    gv_data_changing(GV_DATA(areas), &change_info);
    
    for (i=0; i < num_areas; ++i)
    {
	g_ptr_array_insert_fast(areas->areas, area_ids[i], area[i]);
    }

    gv_data_changed(GV_DATA(areas), &change_info);    
}
Beispiel #8
0
void
gv_areas_delete_ring(GvAreas *areas, gint area_id, gint ring_id)
{
    GvArea *area;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 1, NULL};

    change_info.shape_id = &area_id;

    /* Can't delete ring 0 (outer ring) */
    g_return_if_fail(ring_id > 0);
    
    g_return_if_fail(area_id >= 0 && area_id < areas->areas->len);
    area = gv_areas_get_area(areas, area_id);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    g_ptr_array_remove_index(area->rings, ring_id);

    gv_data_changed(GV_DATA(areas), &change_info);    
}
Beispiel #9
0
void
gv_areas_translate_areas(GvAreas *areas, gint num_areas, gint *area_id,
						 gvgeocoord dx, gvgeocoord dy)
{
    int i, j, k;
    GArray *ring;
    GvArea *area;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL};

    change_info.num_shapes = num_areas;
    change_info.shape_id = area_id;

    gv_data_changing(GV_DATA(areas), &change_info);

    for (k=0; k < num_areas; ++k)
    {
	g_return_if_fail(area_id[k] >= 0 && area_id[k] < areas->areas->len);
	area = gv_areas_get_area(areas, area_id[k]);
	
	for (i=0; i < area->rings->len; ++i)
	{
	    ring = gv_areas_get_ring(area, i);
	    for (j=0; j < ring->len; ++j)
	    {
		g_array_index(ring, GvVertex, j).x += dx;
		g_array_index(ring, GvVertex, j).y += dy;
	    }
	}
	
	if (area->fill_objects > 0)
	{
	    for (i=0; i < area->fill->len; ++i)
	    {
		g_array_index(area->fill, GvVertex, i).x += dx;
		g_array_index(area->fill, GvVertex, i).y += dy;
	    }
	}
    }
    
    gv_data_changed(GV_DATA(areas), &change_info);
}
Beispiel #10
0
void
gv_areas_append_nodes(GvAreas *areas, gint area_id, gint ring_id,
		      gint num_nodes, GvVertex *vertex)
{
    GvArea *area;
    GArray *ring;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 1, NULL};

    change_info.shape_id = &area_id;

    g_return_if_fail(area_id >= 0 && area_id < areas->areas->len);
    area = gv_areas_get_area(areas, area_id);
    g_return_if_fail(ring_id >= 0 && ring_id < area->rings->len);
    ring = gv_areas_get_ring(area, ring_id);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    g_array_append_vals(ring, vertex, num_nodes);

    gv_data_changed(GV_DATA(areas), &change_info);    
}
Beispiel #11
0
static void
gv_areas_replace_areas(GvAreas *areas, gint num_areas, gint *area_id,
		       GvArea **area)
{
    int i;
    
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL};

    change_info.num_shapes = num_areas;
    change_info.shape_id = area_id;
    
    gv_data_changing(GV_DATA(areas), &change_info);

    for (i=0; i < num_areas; ++i)
    {
	gv_area_delete(gv_areas_get_area(areas, area_id[i]));
        g_ptr_array_index(areas->areas, area_id[i]) = area[i];
    }
    
    gv_data_changed(GV_DATA(areas), &change_info);    
}
Beispiel #12
0
gint
gv_shapes_add_shape(GvShapes *shapes, GvShape *new_shape)

{
    int  shape_id;
    GvShapeChangeInfo change_info = {GV_CHANGE_ADD, 1, NULL};

    /* Identify where to put it, reuse old holes if available */
    if( shapes->shapes->len != shapes->actual_num_shapes )
    {
        for( shape_id=0; shape_id < shapes->shapes->len; shape_id++ )
        {
            if( g_ptr_array_index(shapes->shapes, shape_id) == NULL )
                break;
        }
    }
    else
    {
        shape_id = shapes->shapes->len;
    }

    /* Make notification of impending change */
    change_info.shape_id = &shape_id;
    gv_data_changing(GV_DATA(shapes), &change_info);

    /* apply update */
    if( shape_id == shapes->shapes->len )
        g_ptr_array_add(shapes->shapes, new_shape );
    else
        g_ptr_array_index(shapes->shapes, shape_id) = new_shape;

    gv_shape_ref( new_shape );
    shapes->actual_num_shapes++;

    /* notify of completed change */
    gv_data_changed(GV_DATA(shapes), &change_info);

    return shape_id;
}
Beispiel #13
0
void
gv_areas_delete_nodes(GvAreas *areas, gint area_id, gint ring_id,
		      gint num_nodes, gint *node_id)
{
    GvArea *area;
    GArray *ring;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 1, NULL};

    change_info.shape_id = &area_id;

    g_return_if_fail(area_id >= 0 && area_id < areas->areas->len);
    area = gv_areas_get_area(areas, area_id);
    g_return_if_fail(ring_id >= 0 && ring_id < area->rings->len);
    ring = gv_areas_get_ring(area, ring_id);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    if (num_nodes == 1)
    {
	/* Need to preserve node order, so we can't use *_remove_fast */
	g_array_remove_index(ring, *node_id);
    }
    else
    {
	/* Strategy: sort the node_id buffer and delete nodes in desending
	   order, so that indicies remain valid */
	gint *id, i;

	id = g_memdup_type(node_id, gint, num_nodes);
	g_sort_type(id, gint, num_nodes);

	for (i=num_nodes-1; i >= 0; --i)
	{
	    g_array_remove_index(ring, id[i]);
	}
	g_free(id);
    }
    gv_data_changed(GV_DATA(areas), &change_info);
}
Beispiel #14
0
void
gv_shapes_delete_shapes(GvShapes *shapes, gint num_shapes, gint *id_list)
{
    GvShapeChangeInfo change_info = {GV_CHANGE_DELETE, 0, NULL};
    GvShape  *shape;
    gint     i;

    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++ )
    {
        if( id_list[i] < 0 || id_list[i] >= shapes->shapes->len )
            shape = NULL;
        else
            shape = g_ptr_array_index(shapes->shapes, id_list[i]);

        if( shape != NULL )
        {
            g_ptr_array_index(shapes->shapes,id_list[i]) = NULL;
            gv_shape_unref(shape);
            shapes->actual_num_shapes--;
        }
    }

    /* Boil NULLs off the end of the list */
    while( shapes->shapes->len > 0
           && g_ptr_array_index(shapes->shapes,
                                shapes->shapes->len-1) == NULL )
    {
        g_ptr_array_remove_index_fast( shapes->shapes,
                                       shapes->shapes->len-1 );
    }

    gv_data_changed(GV_DATA(shapes), &change_info);
}
Beispiel #15
0
void
gv_areas_move_node(GvAreas *areas, gint area_id, gint ring_id, gint node_id,
		   GvVertex *vertex)
{
    GvArea *area;
    GArray *ring;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 1, NULL};

    change_info.shape_id = &area_id;

    g_return_if_fail(area_id >= 0 && area_id < areas->areas->len);
    area = gv_areas_get_area(areas, area_id);
    g_return_if_fail(ring_id >= 0 && ring_id < area->rings->len);
    ring = gv_areas_get_ring(area, ring_id);
    g_return_if_fail(node_id >= 0 && node_id < ring->len);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    g_array_index(ring, GvVertex, node_id).x = vertex->x;
    g_array_index(ring, GvVertex, node_id).y = vertex->y;

    gv_data_changed(GV_DATA(areas), &change_info);
}
Beispiel #16
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);
}
Beispiel #17
0
gint
gv_areas_new_ring(GvAreas *areas, gint area_id)
{
    GArray *ring;
    GvArea *area;
    GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 1, NULL};

    change_info.shape_id = &area_id;

    g_return_val_if_fail(area_id >= 0 && area_id < areas->areas->len, 0);
    area = gv_areas_get_area(areas, area_id);

    gv_data_changing(GV_DATA(areas), &change_info);
    
    ring = g_array_new(FALSE, FALSE, sizeof(GvVertex));
    g_ptr_array_add(area->rings, ring);

    gv_areas_clear_fill(areas, area_id);
    area->fill_objects = -1;
    
    gv_data_changed(GV_DATA(areas), &change_info);
    
    return area->rings->len - 1;
}
Beispiel #18
0
int gv_raster_rasterize_shapes( GvRaster *raster, 
                                int shape_count, GvShape **shapes,
                                double dfBurnValue, int bFillShort )

{
    GDALDataType   eType;
    int            nYChunkSize, nScanlineBytes;
    unsigned char *pabyChunkBuf;
    int            iY;
    GvRasterChangeInfo change_info;

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    if( raster->gdal_type == GDT_Byte )
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = raster->width * (GDALGetDataTypeSize(eType)/8);
    nYChunkSize = 10000000 / nScanlineBytes;
    if( nYChunkSize > raster->height )
        nYChunkSize = raster->height;

    pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes);
    if( pabyChunkBuf == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Unable to allocate rasterization buffer." );
        return FALSE;
    }

/* ==================================================================== */
/*      Loop over image in designated chunks.                           */
/* ==================================================================== */
    for( iY = 0; iY < raster->height; iY += nYChunkSize )
    {
        int     nThisYChunkSize;
        int     iShape;

        nThisYChunkSize = nYChunkSize;
        if( nThisYChunkSize + iY > raster->height )
            nThisYChunkSize = raster->height - iY;

        GDALRasterIO( raster->gdal_band, GF_Read, 
                      0, iY, raster->width, nThisYChunkSize, 
                      pabyChunkBuf, raster->width, nThisYChunkSize, eType, 
                      0, 0 );

        for( iShape = 0; iShape < shape_count; iShape++ )
        {

            if (bFillShort < 2 )
                gv_rasterize_one_shape( pabyChunkBuf, iY, nThisYChunkSize,
                                        eType, raster, 
                                        shapes[iShape], dfBurnValue, bFillShort );
            else
                gv_rasterize_new_one_shape( pabyChunkBuf, iY, nThisYChunkSize,
                                            eType, raster, 
                                            shapes[iShape], dfBurnValue, bFillShort - 2 );
        }

        GDALRasterIO( raster->gdal_band, GF_Write, 
                      0, iY, raster->width, nThisYChunkSize, 
                      pabyChunkBuf, raster->width, nThisYChunkSize, eType, 
                      0, 0 );
    }

    VSIFree( pabyChunkBuf );

/* -------------------------------------------------------------------- */
/*      Invalidate the raster to force a reload.                        */
/* -------------------------------------------------------------------- */
    change_info.change_type = GV_CHANGE_REPLACE;
    change_info.x_off = 0;
    change_info.y_off = 0;
    change_info.width = raster->width;
    change_info.height = raster->height;

    gv_data_changed( GV_DATA(raster), &change_info );

    return TRUE;
}
Beispiel #19
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);
}