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); }
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; }
/* 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; }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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; }
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); }