Revision: 5351
          http://sourceforge.net/p/jump-pilot/code/5351
Author:   michaudm
Date:     2017-03-04 13:33:12 +0000 (Sat, 04 Mar 2017)
Log Message:
-----------
Fix a bug in PostGIS writer happening in the evolution merging process

Modified Paths:
--------------
    core/trunk/ChangeLog
    core/trunk/src/language/jump_fr.properties
    
core/trunk/src/org/openjump/core/ui/plugin/datastore/WritableDataStoreDataSource.java
    
core/trunk/src/org/openjump/core/ui/plugin/datastore/transaction/Evolution.java
    
core/trunk/src/org/openjump/core/ui/plugin/edittoolbox/cursortools/CutFeaturesTool.java

Modified: core/trunk/ChangeLog
===================================================================
--- core/trunk/ChangeLog        2017-02-09 19:02:51 UTC (rev 5350)
+++ core/trunk/ChangeLog        2017-03-04 13:33:12 UTC (rev 5351)
@@ -3,6 +3,9 @@
 # 2. make sure that lines break at 80 chars for constricted display situations
 #<-------------------------------- 80 chars 
---------------------------------->#
 
+2017-03-04 mmichaud <[email protected]>
+  * Fix a bug in PostGIS writer happening in the evolution merging process
+
 2017-02-02 mmichaud <[email protected]>
   * Upgrade csv-driver to 1.0.0 (encoding option to writer + other 
improvements)
 

Modified: core/trunk/src/language/jump_fr.properties
===================================================================
--- core/trunk/src/language/jump_fr.properties  2017-02-09 19:02:51 UTC (rev 
5350)
+++ core/trunk/src/language/jump_fr.properties  2017-03-04 13:33:12 UTC (rev 
5351)
@@ -555,7 +555,7 @@
 
org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.update
 = Mettre \u00e0 jour
 
org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.update-tooltip
 = Mettre \u00e0 jour les couches \u00e0 partir de la base de donn\u00e9es
 
org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.layer-with-irrelevant-datastore-datasource
 = Le gestionnaire de transaction contient une couche non appropri\u00e9e
-org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.creations
 = {0} cr\u00e9ations
+org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.creations
 = {0} cr\u00e9ation(s)
 
org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.modifications
 = {0} modification(s)
 
org.openjump.core.ui.plugin.datastore.transaction.TransactionManagerPanel.suppressions
 = {0} suppression(s)
 org.openjump.core.ui.plugin.edit.ClipToFencePlugIn.Clip-Map-to-Fence = 
D\u00e9couper sur le cadre

Modified: 
core/trunk/src/org/openjump/core/ui/plugin/datastore/WritableDataStoreDataSource.java
===================================================================
--- 
core/trunk/src/org/openjump/core/ui/plugin/datastore/WritableDataStoreDataSource.java
       2017-02-09 19:02:51 UTC (rev 5350)
+++ 
core/trunk/src/org/openjump/core/ui/plugin/datastore/WritableDataStoreDataSource.java
       2017-03-04 13:33:12 UTC (rev 5351)
@@ -455,7 +455,11 @@
 
     public void addCreation(Feature feature) throws 
EvolutionOperationException {
         Evolution oldEvo = evolutions.remove(feature.getID());
-        Evolution newEvo = Evolution.createCreation(feature.clone(true, 
false)).mergeToPrevious(oldEvo);
+        //Evolution newEvo = Evolution.createCreation(feature.clone(true, 
false)).mergeToPrevious(oldEvo);
+        // copy the pk if exists (may happen when a new feature is build from 
an old one as in split command)
+        // the pk of a creation will not be committed to the database, but 
keeping it in the local feature
+        // may help in case of undo/redo
+        Evolution newEvo = Evolution.createCreation(feature.clone(true, 
true)).mergeToPrevious(oldEvo);
         if (newEvo != null) evolutions.put(feature.getID(), newEvo);
     }
 

Modified: 
core/trunk/src/org/openjump/core/ui/plugin/datastore/transaction/Evolution.java
===================================================================
--- 
core/trunk/src/org/openjump/core/ui/plugin/datastore/transaction/Evolution.java 
    2017-02-09 19:02:51 UTC (rev 5350)
+++ 
core/trunk/src/org/openjump/core/ui/plugin/datastore/transaction/Evolution.java 
    2017-03-04 13:33:12 UTC (rev 5351)
@@ -1,7 +1,6 @@
 package org.openjump.core.ui.plugin.datastore.transaction;
 
 import java.util.Arrays;
-import java.util.Set;
 
 import com.vividsolutions.jump.I18N;
 import com.vividsolutions.jump.feature.Feature;
@@ -16,15 +15,15 @@
 
     private final static String KEY = Evolution.class.getName();
 
-    public static enum Type {CREATION, MODIFICATION, SUPPRESSION}
+    public enum Type {CREATION, MODIFICATION, SUPPRESSION}
 
-    Type type;
-    Set<Integer> modifications;
+    private Type type;
+    // Set<Integer> modifications;
     // newFeature is null for a suppression
-    Feature newFeature;
+    private Feature newFeature;
     // oldFeature contains old values used for conflict resolution
     // It is null for a creation
-    Feature oldFeature;
+    private Feature oldFeature;
 
     private Evolution(Type type, Feature feature, Feature old) {
         assert type.equals(Type.CREATION) && oldFeature == null && feature != 
null ||
@@ -72,17 +71,21 @@
         Feature evo2New = this.getNewFeature();
         Evolution.Type type2 = this.getType();
 
+        // Before merging two evolutions, check that the final state of the 
first one
+        // has the same attributes as the initial state of the second
         if (type1 != Type.SUPPRESSION && type2 != Type.CREATION &&
                 !Arrays.equals(evo1New.getAttributes(), 
evo2Old.getAttributes())) {
-            Logger.info("Try to merge : " + previous);
-            Logger.info("        with : " + this);
-            throw new EvolutionOperationException(KEY + 
I18N.get(".cannot-merge-non-consecutive-evolutions"));
+            Logger.info("Try to merge evolution  : " + previous);
+            Logger.info(" which final state is   : " + 
Arrays.toString(evo1New.getAttributes()));
+            Logger.info("        with evolution  : " + this);
+            Logger.info(" which initial state is : " + 
Arrays.toString(evo2Old.getAttributes()));
+            throw new EvolutionOperationException(I18N.get(KEY + 
".cannot-merge-non-consecutive-evolutions"));
         }
 
         // previous evolution was a CREATION
         if (type1 == Type.CREATION) {
             switch (type2) {
-                case CREATION : throw new EvolutionOperationException(KEY + 
I18N.get(".cannot-merge-2-creations") +
+                case CREATION : throw new 
EvolutionOperationException(I18N.get(KEY + ".cannot-merge-2-creations") +
                         " (" + previous.getNewFeature().getID() + " - " + 
getNewFeature().getID() + ")");
                 case MODIFICATION : return Evolution.createCreation(evo2New);
                 case SUPPRESSION : return null;
@@ -92,7 +95,7 @@
         // previous evolution was a MODIFICATION
         else if (type1 == Type.MODIFICATION) {
             switch (type2) {
-                case CREATION : throw new EvolutionOperationException(KEY + 
I18N.get(".cannot-merge-a-modification-with-a-creation"));
+                case CREATION : throw new 
EvolutionOperationException(I18N.get(KEY + 
".cannot-merge-a-modification-with-a-creation"));
                 case MODIFICATION :
                     boolean unchanged = Arrays.equals(evo1Old.getAttributes(), 
evo2New.getAttributes());
                     return unchanged ? null : 
Evolution.createModification(evo2New, evo1Old);
@@ -105,10 +108,12 @@
             switch (type2) {
                 // This can happen with the undo/redo command
                 case CREATION :
+                    Logger.debug("State before deletion " + 
Arrays.toString(evo1Old.getAttributes()));
+                    Logger.debug("State after creation  " + 
Arrays.toString(evo2New.getAttributes()));
                     boolean unchanged = Arrays.equals(evo1Old.getAttributes(), 
evo2New.getAttributes());
                     return unchanged ? null : 
Evolution.createModification(evo2New, evo1Old);
-                case MODIFICATION : throw new EvolutionOperationException(KEY 
+ I18N.get(".cannot-merge-a-suppression-with-a-modification"));
-                case SUPPRESSION : throw new EvolutionOperationException(KEY + 
I18N.get(".cannot-merge-a-suppression-with-a-suppression"));
+                case MODIFICATION : throw new 
EvolutionOperationException(I18N.get(KEY + 
".cannot-merge-a-suppression-with-a-modification"));
+                case SUPPRESSION : throw new 
EvolutionOperationException(I18N.get(KEY + 
".cannot-merge-a-suppression-with-a-suppression"));
                 default : return null;
             }
         }
@@ -116,9 +121,9 @@
     }
 
     public String toString() {
-        if (type == Type.CREATION) return "Creation: " + newFeature;
-        if (type == Type.SUPPRESSION) return "Suppression: " + oldFeature;
-        else return "Change from:" + oldFeature + "\nto: " + newFeature;
+        if (type == Type.CREATION) return "Creation: fid=" + 
newFeature.getID();
+        if (type == Type.SUPPRESSION) return "Suppression: fid=" + 
oldFeature.getID();
+        else return "Change from: fid=" + oldFeature.getID() + "to: fid=" + 
newFeature.getID();
     }
 
 }

Modified: 
core/trunk/src/org/openjump/core/ui/plugin/edittoolbox/cursortools/CutFeaturesTool.java
===================================================================
--- 
core/trunk/src/org/openjump/core/ui/plugin/edittoolbox/cursortools/CutFeaturesTool.java
     2017-02-09 19:02:51 UTC (rev 5350)
+++ 
core/trunk/src/org/openjump/core/ui/plugin/edittoolbox/cursortools/CutFeaturesTool.java
     2017-03-04 13:33:12 UTC (rev 5351)
@@ -10,6 +10,7 @@
 import com.vividsolutions.jump.feature.FeatureUtil;
 import com.vividsolutions.jump.workbench.WorkbenchContext;
 import com.vividsolutions.jump.workbench.model.Layer;
+import com.vividsolutions.jump.workbench.model.UndoableCommand;
 import com.vividsolutions.jump.workbench.plugin.PlugInContext;
 import com.vividsolutions.jump.workbench.ui.EditTransaction;
 import com.vividsolutions.jump.workbench.ui.SelectionManager;
@@ -30,42 +31,29 @@
 import javax.swing.Icon;
 import javax.swing.JOptionPane;
 
+/*
+ * Giuseppe Aruta Dec 4 2015
+ * This tool partially derives from SplitPolygonPlugIn.class from Kosmo SAIG
+ * It has been modified to be used both with selected Linestrings and Polygons.
+ * It works only with one editable/selectable layer, already selected on layer 
list
+ * A warning message will points, multigeometries or geometry collections are
+ */
   
-  /*
-   * Giuseppe Aruta Dec 4 2015
-   * This tool partially derives from SplitPolygonPlugIn.class from Kosmo SAIG
-   * It has been modified to be used both with selected Linestrings and 
Polygons.
-   * It works only with one editable/selectable layer, already selected on 
layer list
-   * A warning message will points, multigeometries or geometry collections 
are 
-   */
   
-  
-  
-  public class CutFeaturesTool
-    extends MultiClickTool {
+public class CutFeaturesTool extends MultiClickTool {
 
-    Geometry geomSelected = null;
-    Geometry geomDraw = null;
-
-//    public CutFeaturesTool(EnableCheckFactory checkFactory) {
-//    }
-
-    PlugInContext context;
-
     public CutFeaturesTool(PlugInContext context) {
-      this.context = context;
       setColor(Color.red);
-      setStroke(new BasicStroke(1.5f,                      // Width
+      setStroke(new BasicStroke(1.5f,    // Width
               BasicStroke.CAP_SQUARE,    // End cap
               BasicStroke.JOIN_ROUND,    // Join style
               10.0f,                     // Miter limit
-              new float[]{10.0f, 5.0f}, // Dash pattern
+              new float[]{10.0f, 5.0f},  // Dash pattern
               0.0f));
       allowSnapping();
       setMetricsDisplay(new CoordinateListMetrics());
     }
 
-
     public Icon getIcon() {
       return IconLoader.icon("splitPolygon.png");
     }
@@ -78,10 +66,12 @@
       return 
createCursor(IconLoader.icon("splitPolygonCursor.png").getImage());
     }
 
+    protected void gestureFinished() throws Exception {
 
-    protected void gestureFinished()
-            throws Exception {
       WorkbenchContext context = getWorkbench().getContext();
+      Geometry geomSelected;
+      Geometry cuttingLine;
+
       reportNothingToUndoYet();
 
       SelectionManager selectionManager = 
context.getLayerViewPanel().getSelectionManager();
@@ -89,66 +79,95 @@
       for (Layer activeLayer : selectionManager.getLayersWithSelectedItems()) {
         if (!activeLayer.isEditable()) {
           JOptionPane.showMessageDialog(null,
-                  
I18N.getMessage("plugin.EnableCheckFactory.selected-items-layers-must-be-editable",
-                          new Object[]{Integer.valueOf(1)}), 
I18N.get("org.openjump.core.ui.plugin.edittoolbox.Information"),
-                  1);
+                  
I18N.getMessage("plugin.EnableCheckFactory.selected-items-layers-must-be-editable",
 1),
+                  
I18N.get("org.openjump.core.ui.plugin.edittoolbox.Information"), 1);
           return;
         }
       }
 
       for (Layer activeLayer : selectionManager.getLayersWithSelectedItems()) {
-        if (activeLayer.isEditable()) {
-          Collection selectedFeatures = context.getLayerViewPanel()
-                  
.getSelectionManager().getFeaturesWithSelectedItems(activeLayer);
-          EditTransaction edtr = new EditTransaction(new ArrayList(), "cut 
polygon", activeLayer, true, true, context.getLayerViewPanel());
-          for (Iterator k = selectedFeatures.iterator(); k.hasNext(); ) {
-            Feature featureSelected = (Feature) k.next();
-            this.geomSelected = featureSelected.getGeometry();
-            this.geomDraw = getLineString();
-            if ((this.geomSelected.isEmpty())) {
-              return;
-            }
-            if (this.geomSelected.contains(this.geomDraw)) {
-              return;
-            }
-            if 
((this.geomSelected.getClass().getSimpleName().equals("GeometryCollection"))) {
-              context.getWorkbench().getFrame().warnUser(
-                      
I18N.get("org.openjump.core.ui.plugin.tools.CutFeaturesTool.geometryCollection-cannot-be-processed"));
-            }
-            else if (this.geomDraw.intersects(this.geomSelected)) {
-              if (this.geomSelected instanceof Polygon || this.geomSelected 
instanceof MultiPolygon) {
-                edtr.deleteFeature(featureSelected);
-                List<Geometry> div = splitPolygon(this.geomDraw, 
this.geomSelected);
-                for (Geometry geom : div) {
-                  Feature featureIntersect = featureSelected.clone(true);
-                  FeatureUtil.copyAttributes(featureSelected, 
featureIntersect);
-                  featureIntersect.setGeometry(geom);
-                  edtr.createFeature(featureIntersect);
+        
activeLayer.getLayerManager().getUndoableEditReceiver().startReceiving();
+        try {
+          List<Feature> addedFeatures = new ArrayList<>();
+          List<Feature> removedFeatures = new ArrayList<>();
+          if (activeLayer.isEditable()) {
+            Collection<Feature> selectedFeatures = context.getLayerViewPanel()
+                    
.getSelectionManager().getFeaturesWithSelectedItems(activeLayer);
+            //EditTransaction edtr = new EditTransaction(new ArrayList(), "cut 
polygon", activeLayer, true, true, context.getLayerViewPanel());
+            for (Feature featureSelected : selectedFeatures) {
+              geomSelected = featureSelected.getGeometry();
+              cuttingLine = getLineString();
+              if ((geomSelected.isEmpty())) {
+                continue;
+              }
+              if (geomSelected.contains(cuttingLine)) {
+                continue;
+              }
+              if 
((geomSelected.getClass().getSimpleName().equals("GeometryCollection"))) {
+                context.getWorkbench().getFrame().warnUser(
+                        
I18N.get("org.openjump.core.ui.plugin.tools.CutFeaturesTool.geometryCollection-cannot-be-processed"));
+              }
+              else if (cuttingLine.intersects(geomSelected)) {
+                if (geomSelected instanceof Polygon || geomSelected instanceof 
MultiPolygon) {
+                  removedFeatures.add(featureSelected);
+                  //edtr.deleteFeature(featureSelected);
+                  List<Geometry> div = splitPolygon(cuttingLine, geomSelected);
+                  for (Geometry geom : div) {
+                    Feature featureIntersect = featureSelected.clone(true);
+                    FeatureUtil.copyAttributes(featureSelected, 
featureIntersect);
+                    featureIntersect.setGeometry(geom);
+                    //edtr.createFeature(featureIntersect);
+                    addedFeatures.add(featureIntersect);
+                  }
+                } else if (geomSelected instanceof LineString || geomSelected 
instanceof MultiLineString) {
+                  removedFeatures.add(featureSelected);
+                  //edtr.deleteFeature(featureSelected);
+                  List<Geometry> div = splitLines(cuttingLine, geomSelected);
+                  for (Geometry geom : div) {
+                    Feature featureIntersect = featureSelected.clone(true);
+                    FeatureUtil.copyAttributes(featureSelected, 
featureIntersect);
+                    featureIntersect.setGeometry(geom);
+                    //edtr.createFeature(featureIntersect);
+                    addedFeatures.add(featureIntersect);
+                  }
+                } else {
+                  // Point, MultiPoint, GeometryCollection : don't modify the 
selected feature
                 }
-              } else if (this.geomSelected instanceof LineString || 
this.geomSelected instanceof MultiLineString) {
-                edtr.deleteFeature(featureSelected);
-                List<Geometry> div = splitLines(this.geomDraw, 
this.geomSelected);
-                for (Geometry geom : div) {
-                  Feature featureIntersect = featureSelected.clone(true);
-                  FeatureUtil.copyAttributes(featureSelected, 
featureIntersect);
-                  featureIntersect.setGeometry(geom);
-                  edtr.createFeature(featureIntersect);
-                }
               } else {
-               // Point, MultiPoint, GeometryCollection : don't modify the 
selected feature
+                // No intersection : don't modify the selected feature
               }
-            } else {
-              // No intersection : don't modify the selected feature
             }
+            
context.getLayerViewPanel().getSelectionManager().unselectItems(activeLayer);
+            //edtr.commit();
+            //edtr.clearEnvelopeCaches();
+            UndoableCommand command = createCommand(activeLayer, 
removedFeatures, addedFeatures);
+            command.execute();
+            
activeLayer.getLayerManager().getUndoableEditReceiver().receive(command.toUndoableEdit());
           }
-          
context.getLayerViewPanel().getSelectionManager().unselectItems(activeLayer);
-          edtr.commit();
-          edtr.clearEnvelopeCaches();
         }
+        finally {
+          
activeLayer.getLayerManager().getUndoableEditReceiver().stopReceiving();
+        }
       }
       //}
     }
 
+    private UndoableCommand createCommand(final Layer layer,
+                                  final Collection<Feature> removedFeatures,
+                                  final Collection<Feature> addedFeatures) {
+      return new UndoableCommand(getName()) {
+        public void execute() {
+          layer.getFeatureCollectionWrapper().removeAll(removedFeatures);
+          layer.getFeatureCollectionWrapper().addAll(addedFeatures);
+        }
+
+        public void unexecute() {
+          layer.getFeatureCollectionWrapper().removeAll(addedFeatures);
+          layer.getFeatureCollectionWrapper().addAll(removedFeatures);
+        }
+      };
+    }
+
     protected boolean isRollingBackInvalidEdits(WorkbenchContext context) {
       return
               
PersistentBlackboardPlugIn.get(context).get(EditTransaction.ROLLING_BACK_INVALID_EDITS_KEY,
 false);
@@ -188,7 +207,7 @@
     public static List<Geometry> splitPolygon(Geometry digitizedGeometry, 
Geometry geomSel)
             throws Exception {
       // Create linearNetwork with selected geometry linear components and 
digitized linestring
-      List<Geometry> linearNetwork = new ArrayList();
+      List<Geometry> linearNetwork = new ArrayList<>();
       
linearNetwork.addAll(LinearComponentExtracter.getLines(digitizedGeometry));
       linearNetwork.addAll(LinearComponentExtracter.getLines(geomSel));
       Geometry nodedLinearNetwork = UnaryUnionOp.union(linearNetwork);
@@ -206,7 +225,7 @@
       double maxAbsY = Math.max(Math.abs(env.getMaxY()), 
Math.abs(env.getMinY()));
       Geometry buffer = geomSel.buffer(Math.ulp(Math.max(maxAbsX, 
maxAbsY))*1000);
       Iterator<Geometry> it = polys.iterator();
-      List<Geometry> result = new ArrayList<Geometry>();
+      List<Geometry> result = new ArrayList<>();
       while (it.hasNext()) {
         Geometry geometry = it.next();
         if ((buffer.contains(geometry))) {
@@ -222,7 +241,7 @@
 
     public static List<Geometry> splitLines(Geometry digitizedGeometry, 
Geometry geomSel) throws Exception {
     // Create linearNetwork with selected geometry linear components and 
digitized linestring
-      List<Geometry> linearNetwork = new ArrayList();
+      List<Geometry> linearNetwork = new ArrayList<>();
       
linearNetwork.addAll(LinearComponentExtracter.getLines(digitizedGeometry));
       linearNetwork.addAll(LinearComponentExtracter.getLines(geomSel));
       Geometry nodedLinearNetwork = UnaryUnionOp.union(linearNetwork);
@@ -234,7 +253,7 @@
       double maxAbsX = Math.max(Math.abs(env.getMaxX()), 
Math.abs(env.getMinX()));
       double maxAbsY = Math.max(Math.abs(env.getMaxY()), 
Math.abs(env.getMinY()));
       Geometry buffer = geomSel.buffer(Math.ulp(Math.max(maxAbsX, 
maxAbsY))*1000);
-      List<Geometry> result = new ArrayList<Geometry>();
+      List<Geometry> result = new ArrayList<>();
       for (int i = 0 ; i < nodedLinearNetwork.getNumGeometries() ; i++) {
         Geometry geometry = nodedLinearNetwork.getGeometryN(i);
         if ((buffer.contains(geometry))) {


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Jump-pilot-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to