GMsg VectorBuffer::EraseFeatureFromInteraction( const feature_ptr &src, const string &proj, const std::unordered_set<long> &targets, const std::unordered_set<long> &immunes) { GRect ext = MapnikUtils::Box2d2GRect(src->envelope()); unordered_map<long, feature_ptr> fs = GetFeaturesInRect( proj, ext, _config_app().VIEW_VECTORBUFFER_SELECTION_MAX); unordered_map<long, feature_ptr> edited_in_clipping; unordered_set<long> removed_in_clipping; for (unordered_map<long, feature_ptr>::const_iterator it = fs.begin(); it != fs.end(); it++) { feature_ptr f = it->second; if (immunes.find(f->id()) != immunes.end()) continue; if (!targets.empty() && targets.find(f->id()) == targets.end()) continue; if (MapnikUtils::contains( src, f, wkbPolygon, _book->GetGeomType(), proj, _layer->proj())) { removed_in_clipping.insert(it->first); } else if (MapnikUtils::intersects( src, f, wkbPolygon, _book->GetGeomType(), proj, _layer->proj())) { feature_ptr clipped = MapnikUtils::difference( f, src, _book->GetGeomType(), wkbPolygon, _layer->proj(), proj); if (clipped != nullptr) { edited_in_clipping.insert(pair<long, feature_ptr>(it->first, clipped)); } } } unsigned int num = removed_in_clipping.size() + edited_in_clipping.size(); if (num == 0) return G_NOERR; _undoStack->beginMacro(num == 1 ? "Erase feature" : "Erase features"); for (unordered_set<long>::const_iterator it = removed_in_clipping.begin(); it != removed_in_clipping.end(); it++) { _undoStack->push(new VBCommandDeleteFeature(this, *it)); } for (unordered_map<long, feature_ptr>::const_iterator it = edited_in_clipping.begin(); it != edited_in_clipping.end(); it++) { long fid = it->first; feature_ptr f = it->second; Q_ASSERT(_deletedFeatures.find(fid) == _deletedFeatures.end()); f->put<value_unicode_string>( _config_app().VIEW_VECTORBUFFER_FIELD_EDITED, transcoder("utf-8").transcode("edited")); _undoStack->push(new VBCommandEditFeature(this, fid, f)); } _undoStack->endMacro(); return G_NOERR; }
GMsg VectorBuffer::SplitFeatureFromInteraction( const feature_ptr &src, const string &proj) { GRect ext = MapnikUtils::Box2d2GRect(src->envelope()); unordered_map<long, feature_ptr> fs = GetFeaturesInRect( proj, ext, _config_app().VIEW_VECTORBUFFER_SELECTION_MAX); unordered_map<long, vector<feature_ptr> > edited_in_splitting; GMsg retmsg; for (unordered_map<long, feature_ptr>::const_iterator it = fs.begin(); it != fs.end(); it++) { feature_ptr f = it->second; if (MapnikUtils::intersects( src, f, wkbLineString, _book->GetGeomType(), proj, _layer->proj())) { vector<mapnik::feature_ptr> splitted; GMsg msg = MapnikUtils::split(f, src, _book->GetGeomType(), splitted, _layer->proj(), proj); if (msg != G_NOERR) { if (msg.is_error()) retmsg = msg; } else { edited_in_splitting.insert(pair<long, vector<feature_ptr> >(it->first, splitted)); } } } unsigned int num = edited_in_splitting.size(); if (num == 0) return retmsg; _undoStack->beginMacro(num == 1 ? "Split feature" : "Split features"); for (unordered_map<long, vector<feature_ptr> >::const_iterator it = edited_in_splitting.begin(); it != edited_in_splitting.end(); it++) { long fid = it->first; vector<feature_ptr> fs = it->second; Q_ASSERT(_deletedFeatures.find(fid) == _deletedFeatures.end()); _undoStack->push(new VBCommandDeleteFeature(this, fid)); for (unsigned int i = 0; i != fs.size(); i++) { feature_ptr f = fs.at(i); f->set_id(_fidCandidate); f->put<value_unicode_string>( _config_app().VIEW_VECTORBUFFER_FIELD_EDITED, transcoder("utf-8").transcode("edited")); _undoStack->push(new VBCommandAddFeature(this, _fidCandidate, f)); _fidCandidate++; } } _undoStack->endMacro(); return retmsg; }