Revision: 5326 http://sourceforge.net/p/jump-pilot/code/5326 Author: michaudm Date: 2017-01-17 18:06:29 +0000 (Tue, 17 Jan 2017) Log Message: ----------- GraphNodesPlugin now computes a directed graph and add two attributes for in-degree and out-degree of nodes
Modified Paths: -------------- plug-ins/GraphToolboxPlugin/trunk/build.xml 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/graph.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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/build.xml 2017-01-17 18:06:29 UTC (rev 5326) @@ -17,7 +17,7 @@ <property name="dist" value="dist" /> <property name="javadoc" value="javadoc" /> - <property name="version" value="0.3.1" /> + <property name="version" value="0.4.0" /> <!-- =================================================================== --> <!-- Defines the classpath used for compilation and test. --> 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphExtension.java 2017-01-17 18:06:29 UTC (rev 5326) @@ -37,6 +37,7 @@ * @author Michaël Michaud * @version 0.3.1 (2016-11-24) */ +//version 0.4.0 (2017-01-12) add DirectedGraph option in GraphNodesPlugIn //version 0.3.1 (2016-11-24) fix a severe regression on StrahlerNumberPlugIn //version 0.3.0 (2016-10-23) upgrade jgrapht to 0.9, add SkeletonPlugIn //version 0.2.0 (2014-07-15) add Strahler number computation on hydrographic networks @@ -52,7 +53,7 @@ } public String getVersion() { - return "0.3.1 (2016-11-24)"; + return "0.4.0 (2017-01-17)"; } 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/GraphNodesPlugIn.java 2017-01-17 18:06:29 UTC (rev 5326) @@ -27,53 +27,48 @@ import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.DefaultComboBoxModel; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Envelope; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.index.strtree.STRtree; import com.vividsolutions.jump.feature.*; import com.vividsolutions.jump.task.TaskMonitor; import com.vividsolutions.jump.workbench.model.Layer; import com.vividsolutions.jump.workbench.model.StandardCategoryNames; import com.vividsolutions.jump.workbench.plugin.*; -import com.vividsolutions.jump.workbench.ui.ErrorDialog; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.MenuNames; import com.vividsolutions.jump.workbench.ui.MultiInputDialog; import fr.michaelm.jump.feature.jgrapht.*; -import org.jgrapht.UndirectedGraph; +import org.jgrapht.DirectedGraph; /** * Creates a graph from a linear layer with JGraphT and returns degree 1 nodes * (network dead-end), degree 2 nodes, degree 3+ nodes (intersection) or all * the nodes with their degree as attribute. * @author Michaël Michaud - * @version 0.1 (2010-04-22) + * @version 0.4.0 (2017-01-17) */ +//version 0.4.0 (2017-01-17) directedGraph support //version 0.1.2 (2011-07-16) typos and comments //version 0.1.1 (2010-04-22) first svn version //version 0.1 (2010-04-22) public class GraphNodesPlugIn extends ThreadedBasePlugIn { - + private static String LAYER; - + private static String GRAPH; private static String NODES; private static String DEGREE; + private static String IN_DEGREE; + private static String OUT_DEGREE; private static String GRAPH_NODES; private static String GRAPH_COMPUTATION; @@ -87,7 +82,7 @@ private static String DIM3; private static String DIM3_TOOLTIP; - + private static String DEGREE0; private static String DEGREE0_TOOLTIP; private static String DEGREE1; @@ -96,23 +91,34 @@ private static String DEGREE2_TOOLTIP; private static String DEGREE3P; private static String DEGREE3P_TOOLTIP; + private static String DIRECTED_AND; + private static String IN_DEGREE0; + private static String OUT_DEGREE0; + + private static String NO_NODE_FOUND; Layer layer; String attribute; boolean use_attribute; boolean ignore_empty; boolean dim3; - boolean degree0, degree1, degree2, degree3p; - - GeometryFactory gf = new GeometryFactory(); - + boolean indegree0 = false; + boolean outdegree0 = false; + boolean degree0 = false; + boolean degree1 = true; + boolean degree2 = false; + boolean degree3p = false; + public String getName() {return "Graph nodes PlugIn";} public void initialize(final PlugInContext context) throws Exception { - + + LAYER = I18NPlug.getI18N("Layer"); GRAPH = I18NPlug.getI18N("Graph"); NODES = I18NPlug.getI18N("Nodes"); DEGREE = I18NPlug.getI18N("Degree"); + IN_DEGREE = I18NPlug.getI18N("InDegree"); + OUT_DEGREE = I18NPlug.getI18N("OutDegree"); GRAPH_COMPUTATION = I18NPlug.getI18N("Graph-computation"); GRAPH_NODES = I18NPlug.getI18N("GraphNodesPlugIn.graph-nodes"); USE_ATTRIBUTE = I18NPlug.getI18N("use-attribute"); @@ -130,8 +136,12 @@ DEGREE2_TOOLTIP = I18NPlug.getI18N("GraphNodesPlugIn.degree2-tooltip"); DEGREE3P = I18NPlug.getI18N("GraphNodesPlugIn.degree3p"); DEGREE3P_TOOLTIP = I18NPlug.getI18N("GraphNodesPlugIn.degree3p-tooltip"); + DIRECTED_AND = I18NPlug.getI18N("GraphNodesPlugIn.directed-and"); + IN_DEGREE0 = I18NPlug.getI18N("GraphNodesPlugIn.in-degree0"); + OUT_DEGREE0 = I18NPlug.getI18N("GraphNodesPlugIn.out-degree0"); + NO_NODE_FOUND = I18NPlug.getI18N("GraphNodesPlugIn.no-node-found"); - context.getFeatureInstaller().addMainMenuItem( + context.getFeatureInstaller().addMainMenuPlugin( this, new String[]{MenuNames.PLUGINS, GRAPH}, GRAPH_NODES + "...", false, null, new MultiEnableCheck() @@ -158,14 +168,21 @@ jcb_ignore_empty.setEnabled(false); dialog.addSeparator(); - dialog.addCheckBox(DIM3, true, DIM3_TOOLTIP); + + dialog.addCheckBox(DIM3, dim3, DIM3_TOOLTIP); + dialog.addSeparator(); + + dialog.addCheckBox(DEGREE0, degree0, DEGREE0_TOOLTIP); + dialog.addCheckBox(DEGREE1, degree1, DEGREE1_TOOLTIP); + dialog.addCheckBox(DEGREE2, degree2, DEGREE2_TOOLTIP); + dialog.addCheckBox(DEGREE3P, degree3p, DEGREE3P_TOOLTIP); + + dialog.addSubTitle(DIRECTED_AND); + + dialog.addCheckBox(IN_DEGREE0, indegree0, IN_DEGREE0); + dialog.addCheckBox(OUT_DEGREE0, outdegree0, OUT_DEGREE0); - dialog.addCheckBox(DEGREE0, false, DEGREE0_TOOLTIP); - dialog.addCheckBox(DEGREE1, true, DEGREE1_TOOLTIP); - dialog.addCheckBox(DEGREE2, false, DEGREE2_TOOLTIP); - dialog.addCheckBox(DEGREE3P, false, DEGREE3P_TOOLTIP); - jcb_layer.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { List list = getFieldsFromLayerWithoutGeometry(dialog.getLayer(LAYER)); @@ -189,7 +206,6 @@ } }); - GUIUtil.centreOnWindow(dialog); dialog.setVisible(true); if (dialog.wasOKPressed()) { @@ -197,11 +213,13 @@ use_attribute = dialog.getBoolean(USE_ATTRIBUTE); attribute = dialog.getText(ATTRIBUTE); ignore_empty = dialog.getBoolean(IGNORE_EMPTY); - dim3 = dialog.getBoolean(DIM3); - degree0 = dialog.getBoolean(DEGREE0); - degree1 = dialog.getBoolean(DEGREE1); - degree2 = dialog.getBoolean(DEGREE2); - degree3p = dialog.getBoolean(DEGREE3P); + dim3 = dialog.getBoolean(DIM3); + indegree0 = dialog.getBoolean(IN_DEGREE0); + outdegree0 = dialog.getBoolean(OUT_DEGREE0); + degree0 = dialog.getBoolean(DEGREE0); + degree1 = dialog.getBoolean(DEGREE1); + degree2 = dialog.getBoolean(DEGREE2); + degree3p = dialog.getBoolean(DEGREE3P); return true; } else return false; @@ -220,54 +238,62 @@ if (use_attribute) { schemaNodes.addAttribute(attribute, fc.getFeatureSchema().getAttributeType(attribute)); } + schemaNodes.addAttribute(IN_DEGREE, AttributeType.INTEGER); + schemaNodes.addAttribute(OUT_DEGREE, AttributeType.INTEGER); schemaNodes.addAttribute(DEGREE, AttributeType.INTEGER); + FeatureCollection resultNodes = new FeatureDataset(schemaNodes); // Order features by attribute value in a map - Map<Object,List> map = new HashMap<Object,List>(); + Map<Object,List<Feature>> map = new HashMap<Object,List<Feature>>(); Object key = "NO_ATTRIBUTE_USED"; for (Iterator i = fc.iterator() ; i.hasNext() ; ) { Feature f = (Feature)i.next(); if (use_attribute) key = f.getAttribute(attribute); if (use_attribute && ignore_empty && (key == null || key.toString().trim().length() == 0)) {continue;} - else if (!map.containsKey(key)) {map.put(key, new ArrayList());} + else if (!map.containsKey(key)) {map.put(key, new ArrayList<Feature>());} else {} map.get(key).add(f); } //int count = 1; - for (Iterator i = map.keySet().iterator() ; i.hasNext() ; ) { - key = i.next(); - monitor.report(GRAPH_COMPUTATION + " (" + key + ")"); - UndirectedGraph<INode,FeatureAsEdge> graph = - (UndirectedGraph<INode,FeatureAsEdge>)GraphFactory.createGraph(map.get(key), dim3); - //int nbdegree1 = 0; + for (Object k : map.keySet()) { + monitor.report(GRAPH_COMPUTATION + " (" + k + ")"); + DirectedGraph graph = (DirectedGraph)GraphFactory.createDirectedPseudograph(map.get(k), dim3); + for (Iterator<INode> it = graph.vertexSet().iterator() ; it.hasNext() ; ) { INode node = it.next(); - int degree = graph.degreeOf(node); - if (degree == 0 && !degree0) continue; - if (degree == 1) { - //nbdegree1++; - if (!degree1) continue; + int indegree = graph.inDegreeOf(node); + int outdegree = graph.outDegreeOf(node); + int degree = indegree + outdegree; + if (degree0 && degree == 0 || + degree1 && degree == 1 || + degree2 && degree == 2 || + degree3p && degree > 2) { + if (indegree0 && indegree != 0) continue; + if (outdegree0 && outdegree != 0) continue; + Feature bf = new BasicFeature(schemaNodes); + bf.setGeometry(node.getGeometry()); + if (use_attribute) bf.setAttribute(attribute, k); + bf.setAttribute(IN_DEGREE, indegree); + bf.setAttribute(OUT_DEGREE, outdegree); + bf.setAttribute(DEGREE, degree); + resultNodes.add(bf); + } - if (degree == 2 && !degree2) continue; - if (degree > 2 && !degree3p) continue; - Feature bf = new BasicFeature(schemaNodes); - bf.setGeometry(node.getGeometry()); - if (use_attribute) bf.setAttribute(attribute, key); - bf.setAttribute(DEGREE, degree); - resultNodes.add(bf); } } context.getLayerManager().addCategory(StandardCategoryNames.RESULT); if (resultNodes.size()>0) { context.addLayer(StandardCategoryNames.RESULT, layer.getName()+"-" + NODES, resultNodes); + } else { + context.getWorkbenchFrame().warnUser(NO_NODE_FOUND); } } - private List getFieldsFromLayerWithoutGeometry(Layer l) { - List fields = new ArrayList(); + private List<String> getFieldsFromLayerWithoutGeometry(Layer l) { + List<String> fields = new ArrayList<String>(); FeatureSchema schema = l.getFeatureCollectionWrapper().getFeatureSchema(); for (int i = 0 ; i < schema.getAttributeCount() ; i++) { if (schema.getAttributeType(i) != AttributeType.GEOMETRY) { 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph.properties 2017-01-17 18:06:29 UTC (rev 5326) @@ -11,6 +11,8 @@ Graph = Graph Node = Node Nodes = Nodes +InDegree = InDegree +OutDegree = OutDegree Degree = Degree Graph-computation = Graph Computation @@ -28,7 +30,6 @@ GraphNodesPlugIn.ignore-empty-tooltip = Ignore features with empty values GraphNodesPlugIn.dim3 = Compute a 3D graph GraphNodesPlugIn.dim3-tooltip = Use z values to compute the graph -GraphNodesPlugIn.degree0 = Degree 0 nodes GraphNodesPlugIn.degree0-tooltip = Isolated nodes GraphNodesPlugIn.degree1 = Degree 1 nodes GraphNodesPlugIn.degree1-tooltip = Impasses or dead ends @@ -36,6 +37,10 @@ GraphNodesPlugIn.degree2-tooltip = Nodes having exactly two incident features GraphNodesPlugIn.degree3p = Degree 3+ nodes; GraphNodesPlugIn.degree3p-tooltip = Nodes having 3 incident features or more +GraphNodesPlugIn.directed-and = and (add condition on directed graph) +GraphNodesPlugIn.in-degree0 = InDegree 0 nodes +GraphNodesPlugIn.out-degree0 = OutDegree 0 nodes +GraphNodesPlugIn.no-node-found = No node found with selected criteria GraphComponentsPlugIn.connected-components = Connected components GraphComponentsPlugIn.use-attribute = Use an attribute 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fi.properties 2017-01-17 18:06:29 UTC (rev 5326) @@ -46,6 +46,8 @@ CycleFinderPlugIn.processed-cycles=prosessoituja piirej\u00E4 CycleFinderPlugIn.use-attribute=K\u00E4yt\u00E4 ominaisuustietoa CycleFinderPlugIn.use-attribute-tooltip=Analysoi piiriin kuuluvien ja siit\u00E4 l\u00E4htevien s\u00E4rmien ominaisuustiedot +InDegree=InDegree +OutDegree=OutDegree Degree=Asteluku dim3=Laske 3-ulotteinen graafi dim3-tooltip=K\u00E4yt\u00E4 graafin laskennassa my\u00F6s Z-arvoa @@ -84,11 +86,15 @@ GraphNodesPlugIn.degree2-tooltip=Liitt\u00E4v\u00E4t k\u00E4rjet GraphNodesPlugIn.degree3p=Asteluvun 3 ja yli k\u00E4rjet GraphNodesPlugIn.degree3p-tooltip=Haaroittavat k\u00E4rjet +GraphNodesPlugIn.directed-and = and (add condition on directed graph) +GraphNodesPlugIn.in-degree0 = InDegree 0 nodes +GraphNodesPlugIn.out-degree0 = OutDegree 0 nodes GraphNodesPlugIn.dim3=Laske 3-ulotteinen graafi GraphNodesPlugIn.dim3-tooltip=K\u00E4yt\u00E4 graafin laskennassa my\u00F6s Z-arvoa GraphNodesPlugIn.graph-nodes=Graafin k\u00E4rjet GraphNodesPlugIn.ignore-empty=\u00C4l\u00E4 k\u00E4yt\u00E4 tyhji\u00E4 arvoja GraphNodesPlugIn.ignore-empty-tooltip=\u00C4l\u00E4 ota huomioon kohteita, joilla ominaisuustiedo arvo on tyhj\u00E4 +GraphNodesPlugIn.no-node-found = No node found with selected criteria GraphNodesPlugIn.use-attribute=K\u00E4yt\u00E4 ominaisuustietoa GraphNodesPlugIn.use-attribute-tooltip=Luo erilliset graafit jokaiselle ominaisuustiedon arvolle ignore-empty=\u00C4l\u00E4 k\u00E4yt\u00E4 tyhji\u00E4 arvoja 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_fr.properties 2017-01-17 18:06:29 UTC (rev 5326) @@ -9,8 +9,10 @@ Attribute = Attribut Graph = Graphe -Node = N\x9Cud -Nodes = N\x9Cuds +Node = N\u0153ud +Nodes = N\u0153uds +InDegree = Degr\xE9 entrant +OutDegree = Degr\xE9 sortant Degree = Degr\xE9 Graph-computation = Calcul du graphe @@ -37,6 +39,10 @@ GraphNodesPlugIn.degree2-tooltip = Jonctions simples entre 2 objets GraphNodesPlugIn.degree3p = N\u0153uds de degr\u00E9 3 et plus GraphNodesPlugIn.degree3p-tooltip = N\u0153uds o\u00F9 3 objets o\u00F9 plus se rejoignent +GraphNodesPlugIn.directed-and = et (ajouter une condition sur le graphe orient\xE9) +GraphNodesPlugIn.in-degree0 = N\u0153uds entrants de degr\u00E9 0 +GraphNodesPlugIn.out-degree0 = N\u0153uds sortants de degr\u00E9 0 +GraphNodesPlugIn.no-node-found = Aucun n\u0153ud trouv\xE9 avec les crit\xE8res s\xE9lectionn\xE9s GraphComponentsPlugIn.connected-components = Composantes connexes GraphComponentsPlugIn.use-attribute = Utiliser un attribut 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 2017-01-15 16:33:20 UTC (rev 5325) +++ plug-ins/GraphToolboxPlugin/trunk/src/fr/michaelm/jump/plugin/graph/graph_it.properties 2017-01-17 18:06:29 UTC (rev 5326) @@ -46,6 +46,8 @@ CycleFinderPlugIn.processed-cycles=Cicli processati CycleFinderPlugIn.use-attribute=Usa attributo CycleFinderPlugIn.use-attribute-tooltip=Analiza i valori di attributo sul ciclo e sui bordi incidenti al ciclo +InDegree=InDegree +OutDegree=OutDegree Degree=Gradi dim3=Calcola un grafico 3D dim3-tooltip=Usa valore di z per calcolare il grafico @@ -83,11 +85,15 @@ GraphNodesPlugIn.degree2-tooltip=Nodi aventi esattamente due elementi incidenti GraphNodesPlugIn.degree3p=Nodi di grado 3+ GraphNodesPlugIn.degree3p-tooltip=Nodi aventi 3 elementi incidenti o pi\u00F9 +GraphNodesPlugIn.directed-and = and (add condition on directed graph) +GraphNodesPlugIn.in-degree0 = InDegree 0 nodes +GraphNodesPlugIn.out-degree0 = OutDegree 0 nodes GraphNodesPlugIn.dim3=Calcola un grafico 3D GraphNodesPlugIn.dim3-tooltip=Usa il valore z per calcolare il grafico GraphNodesPlugIn.graph-nodes=Nodi di grafico GraphNodesPlugIn.ignore-empty=Ignora valori vuoti GraphNodesPlugIn.ignore-empty-tooltip=Ignora elementi con valori vuoti +GraphNodesPlugIn.no-node-found = No node found with selected criteria GraphNodesPlugIn.use-attribute=Usa un attributo GraphNodesPlugIn.use-attribute-tooltip=Crea distinti grafici per distinti valori di attributo ignore-empty=Ignora valori vuoti ------------------------------------------------------------------------------ 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