bool Pset_to_cgrid_copier::copy( const Geostat_grid* server, const Grid_continuous_property* server_prop, Geostat_grid* client, Grid_continuous_property* client_prop ) { Cartesian_grid* cgrid = dynamic_cast< Cartesian_grid* >( client ); const Point_set* pset = dynamic_cast< const Point_set* >( server ); if( !cgrid || !pset ) return false; typedef Grid_continuous_property::property_type Property_type; copy_categorical_definition(server_prop,client_prop); // check if we already worked with "source" and "property_name" // If that's the case and we're not required to do the assignement // from scratch, use what we did last time. if( !from_scratch_ && server == server_ && server_prop == server_prop_ && client == client_ ) { for( unsigned int i = 0 ; i < last_assignement_.size() ; i++ ) { Property_type val = server_prop->get_value( last_assignement_[i].first ); client_prop->set_value( val, last_assignement_[i].second ); if( mark_as_hard_ ) client_prop->set_harddata( true, last_assignement_[i].second ); } return true; } last_assignement_.clear(); backup_.clear(); server_ = server; server_prop_ = server_prop; client_ = client; client_property_ = client_prop; typedef Point_set::location_type location_type; typedef std::vector<location_type> Location_vector; typedef std::vector<location_type>::const_iterator const_iterator; // We will need to obtain the coordinates of a grid node from its // node id. Hence we need a grid-cursor, set to multigrid level 1. SGrid_cursor cursor = *( cgrid->cursor() ); cursor.set_multigrid_level( 1 ); const Location_vector& locations = pset->point_locations(); GsTL_cube bbox = cgrid->bounding_box(); GsTLInt current_id = 0; // Use a map to record what point was assigned to which grid node // This map is used in case multiple points could be assigned to the // same grid node: in that case the new point is assigned if it is closer // to the grid node than the previously assigned node was. typedef std::map<GsTLInt,location_type>::iterator map_iterator; std::map<GsTLInt,location_type> already_assigned; overwrite_ = true; // added by Jianbing Wu, 03/20/2006 for( const_iterator loc_ptr = locations.begin(); loc_ptr != locations.end(); ++loc_ptr, current_id++ ) { if( !server_prop->is_informed( current_id ) ) continue; // only consider the points inside the target's bounding box if( !bbox.contains( *loc_ptr ) ) continue; GsTLInt node_id = cgrid->closest_node( *loc_ptr ); appli_assert( node_id >=0 && node_id < client_prop->size() ); appli_assert( current_id < server_prop->size() ); // If there is already a property value (not assigned by the // grid initializer), and we don't want to overwrite, leave it alone if( !overwrite_ && client_prop->is_informed( node_id ) ) continue; // bool perform_assignment = true; // check if a point was already assigned to that node map_iterator it = already_assigned.find( node_id ); if( it != already_assigned.end() ) { int i,j,k; GsTLCoordVector sizes = cgrid->cell_dimensions(); cursor.coords( node_id, i,j,k ); location_type node_loc( float(i)*sizes.x(), float(j)*sizes.y(), float(k)*sizes.z() ); // if the new point is further away to the grid node than // the already assigned node, don't assign the new point if( square_euclidean_distance( node_loc, *loc_ptr ) > square_euclidean_distance( node_loc, it->second ) ) continue; //perform_assignment = false; } // if( perform_assignment ) { // store the node id of the source and of the target and make a backup of the // property value of the client property last_assignement_.push_back( std::make_pair( current_id, node_id ) ); if( !undo_enabled_ ) { Property_type backup_val = Grid_continuous_property::no_data_value; if( client_prop->is_informed( node_id ) ) backup_val = client_prop->get_value( node_id ); backup_.push_back( std::make_pair( node_id, backup_val ) ); } Property_type val = server_prop->get_value( current_id ); client_prop->set_value( val, node_id ); already_assigned[node_id] = *loc_ptr; if( mark_as_hard_ ) client_prop->set_harddata( true, node_id ); } overwrite_ = false; // added by Jianbing Wu, 03/20/2006 unset_harddata_flag_ = mark_as_hard_; return true; }
bool Create_mgrid_from_cgrid::exec(){ // Get the grid from the manager SmartPtr<Named_interface> ni = Root::instance()->interface( gridModels_manager + "/" + cgrid_name_ ); if( ni.raw_ptr() == 0 ) { errors_->report( "Object " + cgrid_name_ + " does not exist." ); return false; } Cartesian_grid* cgrid = dynamic_cast<Cartesian_grid*>( ni.raw_ptr() ); if( cgrid == 0) { errors_->report( "Object " + cgrid_name_ + " is not a cartesian grid." ); return false; } // Get the region std::vector<Grid_region*> regions; std::vector<std::string>::iterator it = region_names_.begin(); for( ; it!= region_names_.end(); ++it) { Grid_region* region = cgrid->region( *it ); if(!region) { errors_->report( "Region " + (*it) + " does not exist." ); return false; } regions.push_back(region); } // Create the new masked_grid ni = Root::instance()->new_interface("reduced_grid://"+mgrid_name_, gridModels_manager + "/" + mgrid_name_); if( ni.raw_ptr() == 0 ) { errors_->report( "Object " + mgrid_name_ + " already exists. Use a different name." ); return false; } Reduced_grid* grid = dynamic_cast<Reduced_grid*>( ni.raw_ptr() ); //Create the grid if( regions.size() == 1 ) { //avoid a copy of the region array grid->set_dimensions( cgrid->geometry()->dim(0), cgrid->geometry()->dim(1), cgrid->geometry()->dim(2), cgrid->cell_dimensions()[0], cgrid->cell_dimensions()[1], cgrid->cell_dimensions()[2], regions[0]->data(), cgrid->rotation_z()); } else { int mask_size = regions[0]->size(); std::vector<bool> mask( mask_size ); for( int i=0; i< mask_size; ++i ) { bool ok = false; for( int j = 0; j<regions.size(); j++ ) { ok == ok || regions[j]->is_inside_region(i); } mask[i] = ok; } grid->set_dimensions( cgrid->geometry()->dim(0), cgrid->geometry()->dim(1), cgrid->geometry()->dim(2), cgrid->cell_dimensions()[0], cgrid->cell_dimensions()[1], cgrid->cell_dimensions()[2], mask, cgrid->rotation_z()); } grid->origin( cgrid->origin() ); proj_->new_object( mgrid_name_ ); return true; }