Revision: 5809
          http://sourceforge.net/p/jump-pilot/code/5809
Author:   michaudm
Date:     2018-05-27 21:13:28 +0000 (Sun, 27 May 2018)
Log Message:
-----------
improvement of SkeletonPlugIn -> 0.5.8

Modified Paths:
--------------
    plug-ins/GraphToolboxPlugin/trunk/build.xml
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/SkeletonPlugIn.java
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_cz.properties
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties

Modified: plug-ins/GraphToolboxPlugin/trunk/build.xml
===================================================================
--- plug-ins/GraphToolboxPlugin/trunk/build.xml 2018-05-27 07:37:30 UTC (rev 
5808)
+++ plug-ins/GraphToolboxPlugin/trunk/build.xml 2018-05-27 21:13:28 UTC (rev 
5809)
@@ -17,7 +17,7 @@
     <property name="dist"    value="dist" />
     <property name="javadoc" value="javadoc" />
 
-    <property name="version" value="0.5.6" />
+    <property name="version" value="0.5.8" />
     
     <!-- =================================================================== 
-->
     <!-- Defines the classpath used for compilation and test.                
-->

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/SkeletonPlugIn.java
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/SkeletonPlugIn.java
     2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/SkeletonPlugIn.java
     2018-05-27 21:13:28 UTC (rev 5809)
@@ -9,6 +9,7 @@
 import com.vividsolutions.jts.operation.linemerge.LineMerger;
 import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
 import com.vividsolutions.jts.triangulate.VoronoiDiagramBuilder;
+import com.vividsolutions.jump.I18N;
 import com.vividsolutions.jump.feature.*;
 import com.vividsolutions.jump.geom.Angle;
 import com.vividsolutions.jump.task.TaskMonitor;
@@ -49,6 +50,8 @@
     private static String AUTO_WIDTH_PARAMETER_TT = 
I18NPlug.getI18N("SkeletonPlugIn.auto-width-parameter-tooltip");
     private static String MIN_WIDTH               = 
I18NPlug.getI18N("SkeletonPlugIn.min-width");
     private static String MIN_WIDTH_TT            = 
I18NPlug.getI18N("SkeletonPlugIn.min-width-tooltip");
+    private static String BUFFER_THINER_THAN      = 
I18NPlug.getI18N("SkeletonPlugIn.buffer-thiner-than");
+    private static String BUFFER_THINER_THAN_TT   = 
I18NPlug.getI18N("SkeletonPlugIn.buffer-thiner-than-tooltip");
     private static String MIN_FORK_LENGTH_FROM_MEAN_WIDTH    = 
I18NPlug.getI18N("SkeletonPlugIn.min-fork-length-from-mean-width");
     private static String MIN_FORK_LENGTH_FROM_MEAN_WIDTH_TT = 
I18NPlug.getI18N("SkeletonPlugIn.min-fork-length-from-mean-width-tooltip");
     private static String MIN_FORK_LENGTH_IN_MAP_UNITS       = 
I18NPlug.getI18N("SkeletonPlugIn.min-fork-length-in-map-units");
@@ -61,20 +64,24 @@
     private static String DESCRIPTION             = 
I18NPlug.getI18N("SkeletonPlugIn.description");
 
     private String  layerName;
-    private boolean autoWidth     = true;
-    private double  minWidth      = 1.0;   // minimum width of the polygon
-    private double  meanWidth     = 2.0;   // mean width of the polygon
-    private int     maxIterations = 8192;  // maximum iteration to eliminate 
forks
-    private double  forkLengthMul = 2.5;   // minimum length of a fork
-    private double  minForkLength = 10.0;  // minimum length of a fork
-    private boolean fromMeanWidth = true;  // minimum fork length from mean 
width
-    private boolean fromMapUnits  = false; // minimum fork length in map units
-    private boolean snapEnds = false;      // wheter the skeletton must snap 
the polygon boundary
+    private boolean autoWidth        = true;
+    private double  minWidth         = 1.0;   // minimum width of the polygon
+    private double  bufferThinerThan = 0.1;   // buffer polygon thiner than a 
value
+    private double  simplification   = 0.2;   // by default, simplification 
factor is minWidth/5
+    private double  densification    = 0.5;   // by default, densification 
factor is minWidth/2
+    private double  meanWidth        = 2.0;   // mean width of the polygon
+    private int     maxIterations    = 8192;  // maximum iteration to 
eliminate forks
+    private double  forkLengthMul    = 2.5;   // minimum length of a fork
+    private double  minForkLength    = 10.0;  // minimum length of a fork
+    private boolean fromMeanWidth    = true;  // minimum fork length from mean 
width
+    private boolean fromMapUnits     = false; // minimum fork length in map 
units
+    private boolean snapEnds         = false; // wheter the skeletton must 
snap the polygon boundary
+
     private boolean displayVoronoiEdges = false;
 
-    private static Collection debugGeometries = new ArrayList<Geometry>();
+    //private static Collection debugGeometries = new ArrayList<Geometry>();
 
-    public void initialize(PlugInContext context) throws Exception {
+    public void initialize(PlugInContext context) {
 
         workbenchContext = context.getWorkbenchContext();
         FeatureInstaller featureInstaller = new 
FeatureInstaller(workbenchContext);
@@ -87,6 +94,12 @@
                 createEnableCheck(context.getWorkbenchContext()));
     }
 
+    @Override
+    public String getName() {
+        // Otherwise, I18N class looks for SkeletonPlugIn key in the main 
OpenJUMP resource file
+        return I18NPlug.getI18N("SkeletonPlugIn");
+    }
+
     private static MultiEnableCheck createEnableCheck(WorkbenchContext 
workbenchContext) {
         EnableCheckFactory checkFactory = new 
EnableCheckFactory(workbenchContext);
         return new 
MultiEnableCheck().add(checkFactory.createAtLeastNLayersMustExistCheck(1));
@@ -93,7 +106,7 @@
     }
 
 
-    public boolean execute(PlugInContext context) throws Exception{
+    public boolean execute(PlugInContext context) {
         this.reportNothingToUndoYet(context);
 
         MultiInputDialog dialog = new MultiInputDialog(
@@ -114,11 +127,13 @@
 
         final JCheckBox autoWidthJcb = 
dialog.addCheckBox(AUTO_WIDTH_PARAMETER, autoWidth,AUTO_WIDTH_PARAMETER_TT);
         final JTextField minWidthTF = dialog.addDoubleField(MIN_WIDTH, 
minWidth, 12, MIN_WIDTH_TT);
+        minWidthTF.setEnabled(!autoWidth);
+        final JTextField bufferThinerThanTF = 
dialog.addDoubleField(BUFFER_THINER_THAN, bufferThinerThan, 12, 
BUFFER_THINER_THAN_TT);
 
         final JTextField minForkLengthTF = 
dialog.addDoubleField(MIN_FORK_LENGTH, forkLengthMul, 12, MIN_FORK_LENGTH_TT);
         final JRadioButton mflFromMinWidthJRB = 
dialog.addRadioButton(MIN_FORK_LENGTH_FROM_MEAN_WIDTH,
                 "fork-length-units", fromMeanWidth, 
MIN_FORK_LENGTH_FROM_MEAN_WIDTH_TT);
-        final JRadioButton mflFromMapUnitsJRB = 
dialog.addRadioButton(MIN_FORK_LENGTH_IN_MAP_UNITS,
+        final JRadioButton mflInMapUnitsJRB = 
dialog.addRadioButton(MIN_FORK_LENGTH_IN_MAP_UNITS,
                 "fork-length-units", fromMapUnits, 
MIN_FORK_LENGTH_IN_MAP_UNITS_TT);
 
         dialog.addCheckBox(SNAP_TO_BOUNDARY, snapEnds, SNAP_TO_BOUNDARY_TT);
@@ -129,6 +144,7 @@
             @Override
             public void actionPerformed(ActionEvent e) {
                 minWidthTF.setEnabled(!autoWidthJcb.isSelected());
+                bufferThinerThanTF.setEnabled(autoWidthJcb.isSelected());
             }
         });
     }
@@ -137,6 +153,7 @@
         layerName = dialog.getLayer(SOURCE_LAYER).getName();
         autoWidth = dialog.getBoolean(AUTO_WIDTH_PARAMETER);
         minWidth = dialog.getDouble(MIN_WIDTH);
+        bufferThinerThan = dialog.getDouble(BUFFER_THINER_THAN);
         forkLengthMul = dialog.getDouble(MIN_FORK_LENGTH);
         fromMeanWidth = dialog.getBoolean(MIN_FORK_LENGTH_FROM_MEAN_WIDTH);
         fromMapUnits = dialog.getBoolean(MIN_FORK_LENGTH_IN_MAP_UNITS);
@@ -153,6 +170,8 @@
         schema.addAttribute("min_width", AttributeType.DOUBLE);
         schema.addAttribute("min_fork_length", AttributeType.DOUBLE);
         schema.addAttribute("iteration_number", AttributeType.INTEGER);
+        schema.addAttribute("duration_ms", AttributeType.INTEGER);
+        schema.addAttribute("comment", AttributeType.STRING);
         //schema.addAttribute("snap_ends", AttributeType.BOOLEAN);
         FeatureCollection outputFC = new FeatureDataset(schema);
         int count = 0;
@@ -165,6 +184,7 @@
                 if (!geom.isValid()) geom = geom.buffer(0);
                 for (int i = 0 ; i < geom.getNumGeometries() ; i++) {
                     //Feature newFeature = feature.clone(false, false);
+                    long t0 = System.currentTimeMillis();
                     Feature newFeature = new BasicFeature(schema);
                     Object[] objects = new Object[schema.getAttributeCount()];
                     System.arraycopy(feature.getAttributes(), 0, objects, 0, 
feature.getSchema().getAttributeCount());
@@ -180,7 +200,9 @@
                     newFeature.setAttribute("min_fork_length", minForkLength);
                     g = skeletonize(g, edges);
                     newFeature.setGeometry(g);
-                    newFeature.setAttribute("iteration_number", 
g.getUserData());
+                    newFeature.setAttribute("iteration_number", 
((Object[])g.getUserData())[0]);
+                    newFeature.setAttribute("duration_ms", 
(int)(System.currentTimeMillis()-t0));
+                    newFeature.setAttribute("comment", 
((Object[])g.getUserData())[1]);
                     g.setUserData(null);
                     outputFC.add(newFeature);
                 }
@@ -202,7 +224,7 @@
     }
 
     // Get minWidth and meanWidth from the geometry
-    private void computeParams(Geometry geometry) throws Exception {
+    private void computeParams(Geometry geometry) {
         meanWidth = getMeanWidth(geometry);
         double SQRT2 = Math.sqrt(2.0);
         if (meanWidth==0) meanWidth = 
geometry.getLength()/geometry.getNumPoints()/5;
@@ -229,6 +251,8 @@
         } else if (fromMapUnits) {
             minForkLength = forkLengthMul;
         }
+        simplification = minWidth/5.0;
+        densification = minWidth/2.0;
     }
 
     // Computes the mean width of a polygon
@@ -248,12 +272,20 @@
     }
 
     // Simplification/densification of input geometry
-    private Geometry preprocess(Geometry geometry) throws Exception {
-        geometry = TopologyPreservingSimplifier.simplify(geometry, minWidth/5);
+    private Geometry preprocess(Geometry geometry) {
+        // 0.5.8 : create a buffer if the min width is very small compared to 
mean width
+        // to avoid very heavy calculation du to high densification of the 
outline
+        if (minWidth < bufferThinerThan) {
+            minWidth = bufferThinerThan;
+            geometry = geometry.buffer(minWidth);
+            simplification = minWidth/5.0;
+            densification = minWidth/2.0;
+        }
+        geometry = TopologyPreservingSimplifier.simplify(geometry, 
simplification);
         if (geometry.isEmpty() || Double.isNaN(minWidth)) {
             return geometry;
         } else {
-            geometry = Densifier.densify(geometry, minWidth/2);
+            geometry = Densifier.densify(geometry, densification);
             return geometry;
         }
     }
@@ -267,13 +299,17 @@
         
voronoiBuilder.setSites(geometry.getFactory().createMultiPoint(geometry.getCoordinates()));
         Envelope env = geometry.getEnvelopeInternal();
         env.expandBy(env.getWidth()/3, env.getHeight()/3);
-        voronoiBuilder.setClipEnvelope(env);
         try {
+            voronoiBuilder.setClipEnvelope(env);
             return voronoiBuilder.getDiagram(geometry.getFactory());
         } catch(Exception e) {
             e.printStackTrace();
-            Geometry newGeometry = preprocess(geometry.buffer(minWidth/10));
-            if (newGeometry.equals(geometry)) throw new Exception("Cannot 
process " + geometry);
+            simplification = simplification * Math.sqrt(2.0);
+            densification = densification * Math.sqrt(2.0);
+            Geometry newGeometry = preprocess(geometry);
+            //if (newGeometry.equals(geometry)) throw new Exception("Cannot 
process " + geometry);
+            if (minWidth > Math.sqrt(geometry.getArea())) throw new 
Exception("Cannot process " + geometry);
+            newGeometry.setUserData("Voronoi calculation problem");
             return getVoronoiDiagram(newGeometry);
         }
     }
@@ -345,10 +381,14 @@
 
     private Geometry skeletonize(Geometry geometry, List<Geometry> list) 
throws Exception {
 
+        Object userData[] = new Object[2];
+
         // 1 - Build voronoi diagram and extract the edges
         long t0 = System.currentTimeMillis();
         Set<LineString> edges = new HashSet<LineString>();
-        getEdges(getVoronoiDiagram(preprocess(geometry)), edges);
+        Geometry voronoi = getVoronoiDiagram(preprocess(geometry));
+        userData[1] = voronoi.getUserData();
+        getEdges(voronoi, edges);
         //System.out.println("voronoi : " + 
(System.currentTimeMillis()-t0)/1000);
 
         // 2 - Filter voronoi edges strictly included in the geometry
@@ -358,7 +398,7 @@
         // 3 - Merge filtered edges
         LineMerger merger = new LineMerger();
         merger.add(edges);
-        edges = new HashSet(merger.getMergedLineStrings());
+        edges = new HashSet<LineString>(merger.getMergedLineStrings());
         //System.out.println("merge : " + 
(System.currentTimeMillis()-t0)/1000);
 
         if (displayVoronoiEdges) list.addAll(edges);
@@ -386,11 +426,20 @@
         for (FeatureAsEdge f : finalEdges) {
             
f.setGeometry(TopologyPreservingSimplifier.simplify(f.getGeometry(), 
minWidth/5));
             EdgeNodes nodes = new EdgeNodes(graph, f);
+            String snapError;
             if (nodes.srcDegree == 1) {
-                f.setGeometry(snapStart(f.getGeometry(), 
geometry.getBoundary(), snapEnds));
+                try {
+                    f.setGeometry(snapStart(f.getGeometry(), 
geometry.getBoundary(), snapEnds));
+                } catch(Exception e) {
+                    userData[1] = "Snapping error";
+                }
             }
             if (nodes.tgtDegree == 1) {
-                f.setGeometry(snapEnd(f.getGeometry(), geometry.getBoundary(), 
snapEnds));
+                try {
+                    f.setGeometry(snapEnd(f.getGeometry(), 
geometry.getBoundary(), snapEnds));
+                } catch(Exception e) {
+                    userData[1] = "Snapping error";
+                }
             }
         }
 
@@ -399,7 +448,9 @@
         // 7 - Retourner une geometrie
         Geometry geom = graph2geometry(graph);
         geom = TopologyPreservingSimplifier.simplify(geom, minWidth/5);
-        geom.setUserData(i); // set the number of iteration used
+        userData[0] = i;
+        if (geom.isEmpty()) userData[1] = "Empty";
+        geom.setUserData(userData); // set the number of iteration used
         return geom;
     }
 

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties
        2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties
        2018-05-27 21:13:28 UTC (rev 5809)
@@ -130,6 +130,8 @@
 SkeletonPlugIn.auto-width-parameter-tooltip = Computes automatically a minimum 
width for each feature
 SkeletonPlugIn.min-width = Minimum width
 SkeletonPlugIn.min-width-tooltip = Boundary is densified according to this 
parameter
+SkeletonPlugIn.buffer-thiner-than = Buffer polygons thiner than
+SkeletonPlugIn.buffer-thiner-than-tooltip = Buffer the polygon to avoid 
over-densification
 
 SkeletonPlugIn.min-fork-length = Minimum length of forks
 SkeletonPlugIn.min-fork-length-tooltip = Minimum length of forks

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_cz.properties
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_cz.properties
     2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_cz.properties
     2018-05-27 21:13:28 UTC (rev 5809)
@@ -124,6 +124,8 @@
 SkeletonPlugIn.auto-width-parameter-tooltip = #T: Computes automatically a 
minimum width for each feature
 SkeletonPlugIn.min-width = #T: Minimum width
 SkeletonPlugIn.min-width-tooltip = #T: Boundary is densified according to this 
parameter
+SkeletonPlugIn.buffer-thiner-than = Buffer polygons thiner than
+SkeletonPlugIn.buffer-thiner-than-tooltip = Buffer the polygon to avoid 
over-densification
 
 SkeletonPlugIn.min-fork-length = #T: Minimum length of forks
 SkeletonPlugIn.min-fork-length-tooltip = #T: Minimum length of forks

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties
     2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties
     2018-05-27 21:13:28 UTC (rev 5809)
@@ -118,6 +118,8 @@
 SkeletonPlugIn.auto-width-parameter-tooltip = Laskee automaattisesti 
minimileveyden jokaiselle kohteelle
 SkeletonPlugIn.min-width = Minimileveys
 SkeletonPlugIn.min-width-tooltip = Reunaviiva tihennet\u00E4\u00E4n 
t\u00E4m\u00E4n parametrin perusteella
+SkeletonPlugIn.buffer-thiner-than = Buffer polygons thiner than
+SkeletonPlugIn.buffer-thiner-than-tooltip = Buffer the polygon to avoid 
over-densification
 
 SkeletonPlugIn.min-fork-length = Haarojen minimipituus
 SkeletonPlugIn.min-fork-length-tooltip = Haarojen minimipituus

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties
     2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties
     2018-05-27 21:13:28 UTC (rev 5809)
@@ -131,6 +131,8 @@
 SkeletonPlugIn.auto-width-parameter-tooltip = Calcul automatiquement une 
largeur minimale adapt\xE9e \xE0 chaque objet
 SkeletonPlugIn.min-width = Largeur minimale
 SkeletonPlugIn.min-width-tooltip = La fronti\xE8re est densifi\xE9e en 
fonction de se param\xE8tre
+SkeletonPlugIn.buffer-thiner-than = Elargir les polygones trop fins
+SkeletonPlugIn.buffer-thiner-than-tooltip = Elargir le polygone pour \xE9viter 
une densification trop importante
 
 SkeletonPlugIn.min-fork-length = Longueur minimale des embranchements
 SkeletonPlugIn.min-fork-length-tooltip = Longueur minimale des embranchements

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties
     2018-05-27 07:37:30 UTC (rev 5808)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties
     2018-05-27 21:13:28 UTC (rev 5809)
@@ -116,6 +116,8 @@
 SkeletonPlugIn.auto-width-parameter-tooltip = #T: Computes automatically a 
minimum width for each feature
 SkeletonPlugIn.min-width = #T: Minimum width
 SkeletonPlugIn.min-width-tooltip = #T: Boundary is densified according to this 
parameter
+SkeletonPlugIn.buffer-thiner-than = Buffer polygons thiner than
+SkeletonPlugIn.buffer-thiner-than-tooltip = Buffer the polygon to avoid 
over-densification
 
 SkeletonPlugIn.min-fork-length = #T: Minimum length of forks
 SkeletonPlugIn.min-fork-length-tooltip = #T: Minimum length of forks


------------------------------------------------------------------------------
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
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to