cartodb-4.42/lib/assets/javascripts/cartodb/table/geom_editor.js
2024-04-06 05:25:13 +00:00

217 lines
5.3 KiB
JavaScript

cdb.admin.GeometryEditor = cdb.core.View.extend({
className: "editing",
MAX_VERTEXES: 2000,
events: {
'click .done': 'finish',
'click .discard': 'discard',
'click .cancel': 'discard',
'mousedown': 'killEvent'
},
TEXTS: {
'invalid geometry': _t('Overlapping polygons is not supported for same record')
},
initialize: function() {
this.add_related_model(this.model);
this.geomBeingEdited = null;
this.drawer = null;
},
isEditing: function() {
return this.geomBeingEdited ? true: false;
},
/**
* finish the editing if there is some geometry being edited and save it
* triggers editFinish
*/
finish: function(e) {
this.killEvent(e);
if ((this.drawer && this.drawer.canFinish()) || this.isEditing()) {
var self = this;
if(this.geomBeingEdited) {
this.geomBeingEdited.destroy();
this.geomBeingEdited = null;
}
if(this.drawer) {
this.row.set('the_geom', JSON.stringify(this.drawer.getGeoJSON()));
this.drawer.clean();
this.drawer = null;
}
var isNew = this.row.isNew()
this.model.notice('Saving ... ', 'load');
$.when(this.row.save(null)).done(function() {
if(isNew){
self.trigger('geomCreated', self.row);
}
self.trigger('editFinish')
self.model.notice('Saved', 'info', 5000);
self.row = null;
}).fail(function(e) {
self.trigger('editFinish');
var err = 'Something has failed';
try {
err = JSON.parse(e.responseText || e.response).errors[0];
} catch(e) {}
err = self.TEXTS[err.toLowerCase()] || err;
self.model.notice(err , 'error', 5000);
self.row = null;
});
this.hide();
}
},
/**
* finish the editing and undo the changes done.
* triggers 'editDiscard'
*/
discard: function(e) {
this.killEvent(e);
if(this.geomBeingEdited) {
this.geomBeingEdited.destroy();
this.geomBeingEdited = null;
this.row.set('the_geom', this.originalGeom);
this.originalGeom = null;
this.row = null;
this.trigger('editDiscard');
}
if(this.drawer) {
this.drawer.clean();
this.drawer = null;
this.trigger('editDiscard');
}
this.mapView.unbind(null, null, this);
this.hide();
},
_getGeomCount: function(geojson) {
var count = 0;
_.each(geojson.coordinates, function(pol1, i){
_.each(pol1, function(pol2, j) {
count = count + pol2.length;
})
});
return count;
},
/**
* edits the row geometry
* the row should contain the_geom attribute.
* When the edit is finish the row is saved
*/
editGeom: function(row) {
var self = this;
//fetch to get the geometry
row.fetch({
success: function() {
var geojson = JSON.parse(row.get('the_geom'));
if (self._getGeomCount(geojson) > self.MAX_VERTEXES) {
self._showStopEdit(row);
return false;
} else {
self._startEdition(row);
}
}
});
},
_startEdition: function(row) {
this.trigger('editStart');
this.discard();
var geo = new cdb.geo.Geometry({
geojson: JSON.parse(row.get('the_geom')),
// Supporting leaflet and gmaps styles, overrriding them
style: {
fillColor: "white",
fillOpacity: 0.4,
weight: 4,
color:"#397DBA",
opacity: 1,
strokeColor: "#397DBA",
clickable: false
}
});
this.row = row;
this.originalGeom = row.get('the_geom');
this.geomBeingEdited = geo;
// when model is edited the model changes
geo.bind('change:geojson', function() {
row.set({the_geom: JSON.stringify(geo.get('geojson'))});
});
this.mapView.map.addGeometry(geo);
var geoView = this.mapView.geometries[geo.cid];
geoView.edit(true);
this.$('.finish_editing .tooltip').hide();
this.$el.fadeIn();
},
_showStopEdit: function(row) {
var dlg = cdb.editor.ViewFactory.createDialogByTemplate('common/dialogs/confirm_edit_geom');
// If user confirms, app removes the row
var self = this;
dlg.ok = function() {
self._startEdition(row);
};
dlg
.appendToBody()
.open();
},
/**
* create geometry
* @param row a row model, normally empty
* @param type can be 'point', 'polygon', 'line'
*/
createGeom: function(row, type) {
var self = this;
this.discard();
this.row = row;
this.geomType = type;
this.trigger('editStart');
var editors = {
'point': PointDrawTool,
'polygon': PolygonDrawTool,
'line': PolylineDrawTool
};
this.drawer = new editors[type]({
mapview: this.mapView
});
this.drawer.start();
var c;
this.mapView.bind('click', c = function() {
if(self.drawer.canFinish()) {
this.mapView.unbind('click', c);
self.$('.finish_editing .tooltip').fadeOut();
self.$('.finish_editing .done').removeClass("disabled");
}
}, this);
this.render();
this.$('.finish_editing .done').addClass("disabled");
this.$('.finish_editing .tooltip').show();
this.$el.fadeIn();
},
render: function() {
this.$el.html(this.getTemplate('table/views/geom_edit')({ geom_type: this.geomType}));
return this;
}
});