Revision: 6529
          http://sourceforge.net/p/jump-pilot/code/6529
Author:   michaudm
Date:     2020-09-24 07:01:53 +0000 (Thu, 24 Sep 2020)
Log Message:
-----------
Improve strahler stream order calculation by two orders of magnitude

Modified Paths:
--------------
    plug-ins/GraphToolboxPlugin/trunk/build.xml
    plug-ins/GraphToolboxPlugin/trunk/doc/GraphToolboxExtension4OJ.odt
    plug-ins/GraphToolboxPlugin/trunk/doc/GraphToolboxExtension4OJ_fr.odt
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/CycleFinderPlugIn.java
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphExtension.java
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphNodesPlugIn.java
    
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/StrahlerNumberPlugIn.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 2020-09-23 18:48:37 UTC (rev 
6528)
+++ plug-ins/GraphToolboxPlugin/trunk/build.xml 2020-09-24 07:01:53 UTC (rev 
6529)
@@ -17,7 +17,7 @@
     <property name="dist"    value="dist" />
     <property name="javadoc" value="javadoc" />
 
-    <property name="version" value="0.6.3" />
+    <property name="version" value="0.7.0" />
     
     <!-- =================================================================== 
-->
     <!-- Defines the classpath used for compilation and test.                
-->
@@ -37,7 +37,7 @@
     <!-- =================================================================== 
-->
     <target name="compile" id="compile" depends="clean">
         <mkdir dir="${build}"/>
-        <javac destdir="${build}" debug="true" deprecation="false" 
nowarn="true" source="1.5" target="1.5">
+        <javac destdir="${build}" debug="true" deprecation="false" 
nowarn="true" source="1.8" target="1.8">
             <src path="${src}"/>
             <classpath refid="classpath"/>
             <include name="**/*.java"/>

Modified: plug-ins/GraphToolboxPlugin/trunk/doc/GraphToolboxExtension4OJ.odt
===================================================================
(Binary files differ)

Modified: plug-ins/GraphToolboxPlugin/trunk/doc/GraphToolboxExtension4OJ_fr.odt
===================================================================
(Binary files differ)

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/CycleFinderPlugIn.java
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/CycleFinderPlugIn.java
  2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/CycleFinderPlugIn.java
  2020-09-24 07:01:53 UTC (rev 6529)
@@ -463,7 +463,7 @@
         }
         if (use_attribute && heterogeneous_cycles_FC.size()>0) {
             context.addLayer(StandardCategoryNames.RESULT,
-                layer.getName()+"-CyclesHeterog\xE8nes", 
heterogeneous_cycles_FC);
+                layer.getName()+"-CyclesHeterogènes", heterogeneous_cycles_FC);
         }
         if (homogeneous_cycles_FC.size() == 0 && 
heterogeneous_cycles_FC.size() == 0) {
             context.getWorkbenchFrame().warnUser(NO_CYCLE_FOUND);

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphExtension.java
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphExtension.java
     2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphExtension.java
     2020-09-24 07:01:53 UTC (rev 6529)
@@ -35,8 +35,9 @@
  * <li>CycleFinderPlugIn : computes a graph from a linear network and find 
base cycles</li>
  * </ul>
  * @author Micha&euml;l Michaud
- * @version 0.6.3 (2019-06-24)
+ * @version 0.7.0 (2020-09-18)
  */
+//version 0.7.0 (2020-09-23) Make strahlerNumber plugin more memory friendly 
and way faster
 //version 0.6.3 (2019-06-24) SkeletonPlugIn : improve meanWidth calculation
 //version 0.6.2 (2019-05-22) fix bug in SkeletonPlugIn : incorrect 
relativeMinForkLength
 //version 0.6.1 (2018-06-17) refactor to use AbstractPlugIn parameters in 
GraphNodesPlugIn
@@ -63,7 +64,7 @@
     }
 
     public String getVersion() {
-        return "0.6.3 (2019-06-24)";
+        return "0.7.0 (2020-09-23)";
     }
 
     public void configure(PlugInContext context) throws Exception {

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphNodesPlugIn.java
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphNodesPlugIn.java
   2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphNodesPlugIn.java
   2020-09-24 07:01:53 UTC (rev 6529)
@@ -48,6 +48,8 @@
 
 import fr.michaelm.jump.feature.jgrapht.*;
 import org.jgrapht.DirectedGraph;
+import org.jgrapht.WeightedGraph;
+import org.jgrapht.graph.DirectedWeightedPseudograph;
 
 /**
  * Creates a graph from a linear layer with JGraphT and returns degree 1 nodes
@@ -312,7 +314,7 @@
         outdegree0 = getBooleanParam(P_OUT_DEGREE_0);
         for (Object k : map.keySet()) {
             monitor.report(GRAPH_COMPUTATION + " (" + k + ")");
-            DirectedGraph graph = 
(DirectedGraph)GraphFactory.createDirectedPseudograph(map.get(k), dim3);
+            DirectedWeightedPseudograph graph = 
(DirectedWeightedPseudograph)GraphFactory.createDirectedPseudograph(map.get(k), 
dim3);
 
             for (Iterator<INode> it = graph.vertexSet().iterator() ; 
it.hasNext() ; ) {
                 INode node = it.next();

Modified: 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/StrahlerNumberPlugIn.java
===================================================================
--- 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/StrahlerNumberPlugIn.java
       2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/StrahlerNumberPlugIn.java
       2020-09-24 07:01:53 UTC (rev 6529)
@@ -1,36 +1,21 @@
 package fr.michaelm.jump.plugin.graph;
 
-import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jump.I18N;
 import com.vividsolutions.jump.feature.*;
 import com.vividsolutions.jump.task.TaskMonitor;
 import com.vividsolutions.jump.util.CollectionUtil;
-import com.vividsolutions.jump.workbench.model.Category;
 import com.vividsolutions.jump.workbench.model.Layer;
 import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
-import com.vividsolutions.jump.workbench.model.UndoableCommand;
 import com.vividsolutions.jump.workbench.plugin.*;
 import com.vividsolutions.jump.workbench.ui.GUIUtil;
-import com.vividsolutions.jump.workbench.ui.HTMLFrame;
 import com.vividsolutions.jump.workbench.ui.MenuNames;
 import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
 import com.vividsolutions.jump.workbench.ui.renderer.style.*;
-import com.vividsolutions.jump.workbench.ui.style.StylePanel;
-import de.latlon.deejump.plugin.style.DeeChangeStylesPlugIn;
 import fr.michaelm.jump.feature.jgrapht.FeatureAsEdge;
 import fr.michaelm.jump.feature.jgrapht.GraphFactory;
 import fr.michaelm.jump.feature.jgrapht.INode;
-import org.jgrapht.DirectedGraph;
-import org.jgrapht.Graph;
-import org.jgrapht.Graphs;
-import org.jgrapht.UndirectedGraph;
-import org.jgrapht.alg.ConnectivityInspector;
-import org.jgrapht.event.EdgeTraversalEvent;
-import org.jgrapht.graph.DefaultDirectedGraph;
-import org.jgrapht.graph.DirectedWeightedMultigraph;
 import org.jgrapht.graph.DirectedWeightedPseudograph;
-import org.jgrapht.graph.WeightedPseudograph;
-import org.jgrapht.traverse.BreadthFirstIterator;
 
 import javax.swing.*;
 import java.awt.*;
@@ -44,24 +29,28 @@
 
     private static String LAYER;
 
-    private static String GRAPH;
     private static String STRAHLER_NUMBERS;
     private static String GRAPH_COMPUTATION;
+    private static String OLD_ALGO;
 
     private static final String STREAM_ORDER    = "StreamOrder";
-    //private static final String STRAHLER_NUMBER = "StrahlerNb";
+    private static final String SEGMENT_ORIGIN  = "SegmentOrig";
 
     Layer layer;
+    boolean old_algo = false;
 
     public String getName() {return "Graph nodes PlugIn";}
 
     public void initialize(final PlugInContext context) throws Exception {
 
-        GRAPH                   = I18NPlug.getI18N("Graph");
+        String GRAPH            = I18NPlug.getI18N("Graph");
+
+        LAYER                   = I18N.get("ui.GenericNames.LAYER");
         GRAPH_COMPUTATION       = I18NPlug.getI18N("Graph-computation");
         STRAHLER_NUMBERS        = 
I18NPlug.getI18N("StrahlerNumberPlugIn.strahler-numbers");
+        OLD_ALGO                = 
I18NPlug.getI18N("StrahlerNumberPlugIn.old-algorithm");
 
-        context.getFeatureInstaller().addMainMenuItem(
+        context.getFeatureInstaller().addMainMenuPlugin(
                 this, new String[]{MenuNames.PLUGINS, GRAPH},
                 STRAHLER_NUMBERS + "...",
                 false, null, new MultiEnableCheck()
@@ -76,6 +65,7 @@
         dialog.setSideBarImage(new 
ImageIcon(this.getClass().getResource("StrahlerNumber.png")));
         
dialog.setSideBarDescription(I18NPlug.getI18N("StrahlerNumberPlugIn.description"));
         dialog.addLayerComboBox(LAYER, context.getCandidateLayer(0), null, 
context.getLayerManager());
+        dialog.addCheckBox(OLD_ALGO, old_algo);
 
         GUIUtil.centreOnWindow(dialog);
         dialog.setPreferredSize(new Dimension(400,480));
@@ -82,6 +72,7 @@
         dialog.setVisible(true);
         if (dialog.wasOKPressed()) {
             layer = dialog.getLayer(LAYER);
+            old_algo = dialog.getBoolean(OLD_ALGO);
             return true;
         }
         else return false;
@@ -94,9 +85,9 @@
         FeatureCollection sourceFC = layer.getFeatureCollectionWrapper();
 
         // Creates the schema for the output dataset (nodes)
-        final FeatureSchema newSchema = 
(FeatureSchema)sourceFC.getFeatureSchema().clone();
+        final FeatureSchema newSchema = sourceFC.getFeatureSchema().clone();
         newSchema.addAttribute(STREAM_ORDER, AttributeType.INTEGER);
-        //newSchema.addAttribute(STRAHLER_NUMBER, AttributeType.INTEGER);
+        newSchema.addAttribute(SEGMENT_ORIGIN, AttributeType.OBJECT);
         FeatureCollection resultFC = new FeatureDataset(newSchema);
         for (Object o : sourceFC.getFeatures()) {
             Feature f = (Feature)o;
@@ -111,11 +102,21 @@
                 .createDirectedPseudograph(resultFC.getFeatures(), false);
         //HTMLFrame htmlFrame = context.getOutputFrame();
         //htmlFrame.createNewDocument();
-        Map<Integer,Set<Integer>> ancestorMap = new 
HashMap<Integer,Set<Integer>>();
+        int count = 0;
+        int total = resultFC.size();
         for (FeatureAsEdge arc : graph.edgeSet()) {
             if (arc.getAttribute(STREAM_ORDER) != null) continue;
-            computeStreamOrder(graph, arc, ancestorMap);
+            if (old_algo) computeOldStreamOrder(graph, arc);
+            else computeNewStreamOrder(graph, arc);
+            monitor.report(count++, total, " features processed");
         }
+        // Change -1 (cycles or cycle successors) to null
+        for (FeatureAsEdge arc : graph.edgeSet()) {
+            Object order = arc.getAttribute(STREAM_ORDER);
+            if (order != null && (Integer)order == -1) {
+                arc.setAttribute(STREAM_ORDER,null);
+            }
+        }
 
         context.getLayerManager().addLayer(StandardCategoryNames.RESULT, 
layer.getName()+"-strahler",resultFC);
         Layer resultLayer = context.getLayerManager().getLayer(layer.getName() 
+ "-strahler");
@@ -125,49 +126,170 @@
         resultLayer.addStyle(getColorThemingStyle());
     }
 
-    private void 
computeStreamOrder(DirectedWeightedPseudograph<INode,FeatureAsEdge> graph,
-                                    FeatureAsEdge arc, 
Map<Integer,Set<Integer>> ancestorMap) {
-        Set<Integer> ancestors = ancestorMap.get(arc.getID());
-        if (ancestors == null) {
-            ancestors = new HashSet<Integer>();
-            ancestorMap.put(arc.getID(), ancestors);
-        }
+
+    /**
+     * This version of Stream Order calculation is a re-implementation of the 
very first
+     * version proposed in OpenJUMP which used too much memory. While the 
first version
+     * was storing a list of all ancestors of each edge in a map, this one 
computes the
+     * list of ancestors again and again. It is slower than the former version 
but can
+     * terminate on a computer with less RAM.
+     * The algorithm differs from the following (computeStreamOrder3) in the 
case where
+     * an edge has two input streams a and b with the same StreamOrder :
+     * In the following algorithm, if a and b have at least one common 
ancestor, the
+     * stream order of the downstream edge will not be incremented.
+     * In computeStreamOrder3, the downstream edge will not be incremented 
only if a and
+     * b have the same segment head (see comments in computeStreamOrder3 
method).
+     * @param graph
+     * @param arc
+     */
+    private void 
computeOldStreamOrder(DirectedWeightedPseudograph<INode,FeatureAsEdge> graph,
+                                   FeatureAsEdge arc) {
+
         int maxOrder = 0;
         int occ = 0;
+        FeatureAsEdge maxUpstream = null;
         for (FeatureAsEdge upstream : 
graph.incomingEdgesOf(graph.getEdgeSource(arc))) {
             Object att = upstream.getAttribute(STREAM_ORDER);
+            // Process current stream only if all upstreams are already 
processed
             if (att == null) return;
             int upstreamOrder = (Integer)att;
+            // Case 1 : upstream order > all previous ones
+            // (when the loop is finished : upstreamOrder > all others)
             if (upstreamOrder > maxOrder) {
                 maxOrder = upstreamOrder;
-                occ = 1;
-                ancestors.addAll(ancestorMap.get(upstream.getID()));
-                ancestors.add(upstream.getID());
+                occ = 1; // there is only 1 upstream > all others
+                maxUpstream = upstream;
             }
+            // Case 2 : upstream order = max order of previous ones (ex aequo)
             else if (upstreamOrder == maxOrder) {
-                int card = ancestors.size();
-                Set<Integer> newSet = ancestorMap.get(upstream.getID());
-                ancestors.addAll(newSet);
-                if (ancestors.size() == card + newSet.size()) {
-                    occ++;
+                if (!hasCommonAncestors(graph, upstream, maxUpstream)) {
+                    occ++; // there are several upstreams = maxOrder
                 }
             }
+            // If upstream order is < max, it does not contribute to downstream
+            // order calculation
             else;
         }
-        if (maxOrder == 0) arc.setAttribute(STREAM_ORDER, 1);
+        // Head water of a stream (edge without predecessor) has order 1
+        if (maxOrder == 0) {
+            arc.setAttribute(STREAM_ORDER, 1);
+        }
         else {
+            // Stream order of the current edge is incremented if it has 2 or 
more
+            // predecessors = maxOrder
             arc.setAttribute(STREAM_ORDER, occ>1?maxOrder+1:maxOrder);
         }
+        // Try to compute stream order recursively on all downstream edges
         Set<FeatureAsEdge> downStreams = 
graph.outgoingEdgesOf(graph.getEdgeTarget(arc));
 
         for (FeatureAsEdge downStream : downStreams) {
             // In case of anastomosis, compute the downstream edge only once
             if (downStream.getAttribute(STREAM_ORDER) == null) {
-                computeStreamOrder(graph, downStream, ancestorMap);
+                computeOldStreamOrder(graph, downStream);
             }
         }
     }
 
+    private Set<Integer> 
getAncestors(DirectedWeightedPseudograph<INode,FeatureAsEdge> graph,
+                                   FeatureAsEdge arc, Set<Integer> ancestors) {
+        for (FeatureAsEdge e : 
graph.incomingEdgesOf(graph.getEdgeSource(arc))) {
+            if (ancestors.contains(e.getID())) continue;
+            ancestors.add(e.getID());
+            getAncestors(graph, e, ancestors);
+        }
+        return ancestors;
+    }
+
+    private boolean 
hasCommonAncestors(DirectedWeightedPseudograph<INode,FeatureAsEdge> graph,
+                                       FeatureAsEdge arc1, FeatureAsEdge arc2) 
{
+        Set<Integer> ancestors1 = getAncestors(graph, arc1, new HashSet<>());
+        Set<Integer> ancestors2 = getAncestors(graph, arc2, new HashSet<>());
+        int card1 = ancestors1.size();
+        int card2 = ancestors2.size();
+        ancestors1.addAll(ancestors2);
+        return ancestors1.size() < card1 + card2;
+    }
+
+    // Implements algorithm described in
+    // A FAST RECURSIVE GIS ALGORITHM FOR COMPUTING STRAHLER STREAM ORDER
+    // IN BRAIDED AND NON BRAIDED NETWORKS
+    // Alexander Gleyzer, Michael Denisyuk, Alon Rimmer, and Yigal Salingar 
(2004)
+    private void 
computeNewStreamOrder(DirectedWeightedPseudograph<INode,FeatureAsEdge> graph,
+                                     FeatureAsEdge arc) {
+
+        Object streamOrder = arc.getAttribute(STREAM_ORDER);
+        // If arc already has a positive stream order, don't process it again
+        // If its stream-order = -1, it means it belongs to a cycle, or it 
belongs
+        // to an ancestor and has been pre-set to -1 to detect cycles
+        // In all of these case, we don't want to process it
+        if (streamOrder != null) return;
+        // Flag current edge to be able to identify cycles while exploring 
ancestors
+        // recursively
+        arc.setAttribute(STREAM_ORDER, -1);
+
+        // Stream order of the current edge has not yet been computed.
+        // Compute predecessors stream order first (recursion)
+        Set<FeatureAsEdge> upStreams = 
graph.incomingEdgesOf(graph.getEdgeSource(arc));
+        boolean cycle = false;
+        for (FeatureAsEdge upStream : upStreams) {
+            // Visit/compute ancestors recursively
+            computeNewStreamOrder(graph, upStream);
+            // Post order : check that current stream is not part of a cycle
+            // if upstream == -1, it means it has already been initialized in 
the context
+            // of this recursive process (cycle)
+            Object upStreamOrder = upStream.getAttribute(STREAM_ORDER);
+            assert upStreamOrder != null; // stream order is initialized to -1 
in pre-order
+            if ((Integer)upStreamOrder == -1) {
+                cycle = true;
+            }
+        }
+
+        // If one of the upstream is part of a cycle, current edge cannot be 
computed
+        if (cycle) {
+            return;
+        }
+        // We are now in the normal situation of an edge which has all its 
ancestors
+        // computed and which does not belong to a cycle nor have a cycle as 
ancestor
+        int maxOrder = 0;
+        INode maxOrderOrigin = null;
+        int occ = 0;
+        for (FeatureAsEdge upstream : 
graph.incomingEdgesOf(graph.getEdgeSource(arc))) {
+            Object att1 = upstream.getAttribute(STREAM_ORDER);
+            assert att1 != null;
+
+            int upstreamOrder = (Integer)att1;
+            INode segmentOrigin = (INode)upstream.getAttribute(SEGMENT_ORIGIN);
+            // Case 1 : upstream order > all previous ones
+            if (upstreamOrder > maxOrder) {
+                maxOrderOrigin = segmentOrigin;
+                maxOrder = upstreamOrder;
+                occ = 1;
+            }
+            // Case 2 : upstream order = max order of previous ones (ex aequo)
+            else if (upstreamOrder == maxOrder) {
+                if (!segmentOrigin.equals(maxOrderOrigin)) {
+                    occ++;
+                }
+            }
+        }
+        // Set the stream order and segment origin of the current edge
+        if (maxOrder == 0) {
+            arc.setAttribute(STREAM_ORDER, 1);
+            arc.setAttribute(SEGMENT_ORIGIN, graph.getEdgeSource(arc));
+        }
+        else if (occ > 1) {
+            arc.setAttribute(STREAM_ORDER, maxOrder+1);
+            arc.setAttribute(SEGMENT_ORIGIN, graph.getEdgeSource(arc));
+        }
+        else {
+            arc.setAttribute(STREAM_ORDER, maxOrder);
+            arc.setAttribute(SEGMENT_ORIGIN, maxOrderOrigin);
+        }
+
+    }
+
+
+
     ColorThemingStyle getColorThemingStyle() {
         BasicStyle dbs = new BasicStyle();   dbs.setLineColor(new 
Color(255,0,0));      dbs.setLineWidth(2);
         BasicStyle bs1  = new BasicStyle();  bs1.setLineColor(new 
Color(120,240,255));  bs1.setLineWidth(1);

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
        2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties
        2020-09-24 07:01:53 UTC (rev 6529)
@@ -121,7 +121,12 @@
 StrahlerNumberPlugIn.description = This plugin adds an attribute containing 
the Strahler Number.\
   The Strahler number qualifies each edge of a hierarchical network. The value 
is 1 for source edges, \
   and n+1 for an edge with at least two parents of value n.\nWarning : 
presence of cycles in the \
-  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.
+  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.\n\
+  The new algorithm implements "A fast recursive GIS algorithm for computing 
Strahler stream order \
+  in braided and nonbraided networks". It differs slightly from the old 
algorithm in the way to manage \
+  braided networks (see documentation), and is way more efficient (both from a 
memory and from a speed \
+  perspective).
+StrahlerNumberPlugIn.old-algorithm = Old algorithm (legacy)
 
 SkeletonPlugIn = Skeleton
 SkeletonPlugIn.skeletonize = Skeletonize

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
     2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_cz.properties
     2020-09-24 07:01:53 UTC (rev 6529)
@@ -115,7 +115,12 @@
 StrahlerNumberPlugIn.description = This plugin adds an attribute containing 
the Strahler Number.\
   The Strahler number qualifies each edge of a hierarchical network. The value 
is 1 for source edges, \
   and n+1 for an edge with at least two parents of value n.\nWarning : 
presence of cycles in the \
-  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.
+  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.\n\
+  The new algorithm implements "A fast recursive GIS algorithm for computing 
Strahler stream order \
+  in braided and nonbraided networks". It differs slightly from the old 
algorithm in the way to manage \
+  braided networks (see documentation), and is way more efficient (both from a 
memory and from a speed \
+  perspective).
+StrahlerNumberPlugIn.old-algorithm = Old algorithm (legacy)
   
 SkeletonPlugIn = #T: Skeleton
 SkeletonPlugIn.skeletonize = #T: Skeletonize

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
     2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties
     2020-09-24 07:01:53 UTC (rev 6529)
@@ -109,9 +109,14 @@
 StrahlerNumberPlugIn.description = T\u00E4m\u00E4 laajennus lis\u00E4\u00E4 
tasolle ominaisuuden johon tallennetaan Strahlerin numerot.\
   Strahlerin numero luokittelee hierarkisen verkon jokaisen s\u00E4rm\u00E4n. 
Arvo on 1 l\u00E4hdes\u00E4rmille, \
   ja n+1 jokaiselle s\u00E4rm\u00E4lle jolla on v\u00E4hint\u00E4\u00E4n 2 
emoa, jonka arvo on n.\n Varoitus : Jos tasossa on piirej\u00E4 niin \
-  ne rikkovat algoritmin, joka siin\u00E4 tapauksessa asettaa tyhj\u00E4n 
arvon kaikille s\u00E4rmille jotka erkanevat piirin s\u00E4rmist\u00E4.
+  ne rikkovat algoritmin, joka siin\u00E4 tapauksessa asettaa tyhj\u00E4n 
arvon kaikille s\u00E4rmille jotka erkanevat piirin s\u00E4rmist\u00E4.\n\
+  The new algorithm implements "A fast recursive GIS algorithm for computing 
Strahler stream order \
+  in braided and nonbraided networks". It differs slightly from the old 
algorithm in the way to manage \
+  braided networks (see documentation), and is way more efficient (both from a 
memory and from a speed \
+  perspective).
+StrahlerNumberPlugIn.old-algorithm = Old algorithm (legacy)
   
-  SkeletonPlugIn=Luurankograafi
+SkeletonPlugIn=Luurankograafi
 SkeletonPlugIn.skeletonize = Luo luurankograafi
 SkeletonPlugIn.source-layer = L\u00E4ht\u00F6taso
 SkeletonPlugIn.auto-width-parameter = Automaattinen leveyden laskenta

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
     2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties
     2020-09-24 07:01:53 UTC (rev 6529)
@@ -122,7 +122,11 @@
   Le nombre de Strahler qualifie chaque arc d'un r\xE9seau hi\xE9rarchique. Un 
arc situ\xE9 \xE0 une source du r\xE9seau \
   prend la valeur 1 tandis qu'un arc ayant au moins 2 ant\xE9c\xE9dents de 
valeur n prend la valeur n+1.\
   \nAttention : la pr\xE9sence de cycles casse l'algorithme qui affecte une 
valeur nulle \xE0 tous les arcs \
-  descendant de l'un des arcs du cycle.
+  descendant de l'un des arcs du cycle.\n\
+  Le nouvel algorihme impl\xE9mente "A fast recursive GIS algorithm for 
computing Strahler stream order \
+  in braided and nonbraided networks". Il diff\xE8re de l'ancien par la 
fa\xE7on de g\xE9rer les r\xE9seaux anastamos\xE9s.\n\
+  (cf. documentation), ainsi que par son efficacit\xE9 (tant en m\xE9moire 
qu'en vitesse d'ex\xE9cution).
+StrahlerNumberPlugIn.old-algorithm = Ancien algorithme (historique)
 
 SkeletonPlugIn = Squelettisation
 SkeletonPlugIn.skeletonize = Squelettiser

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
     2020-09-23 18:48:37 UTC (rev 6528)
+++ 
plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties
     2020-09-24 07:01:53 UTC (rev 6529)
@@ -105,7 +105,13 @@
 StrahlerNumberPlugIn.description = This plugin adds an attribute containing 
the Strahler Number.\
   The Strahler number qualifies each edge of a hierarchical network. The value 
is 1 for source edges, \
   and n+1 for an edge with at least two parents of value n.\nWarning : 
presence of cycles in the \
-  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.
+  graph break the algorithm which will set a null value to all edges flowing 
from a cycle edge.\n\
+  The new algorithm implements "A fast recursive GIS algorithm for computing 
Strahler stream order \
+  in braided and nonbraided networks". It differs slightly from the old 
algorithm in the way to manage \
+  braided networks (see documentation), and is way more efficient (both from a 
memory and from a speed \
+  perspective).
+StrahlerNumberPlugIn.old-algorithm = Old algorithm (legacy)
+
 use-attribute=Usa un attributo
 use-attribute-tooltip=Crea grafici distinti per didtinti valori di attributo
 



_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to