diff --git a/msi.gama.core/src/msi/gama/util/file/GamaGraphFile.java b/msi.gama.core/src/msi/gama/util/file/GamaGraphFile.java index c68aabeb10..512c9b37a4 100644 --- a/msi.gama.core/src/msi/gama/util/file/GamaGraphFile.java +++ b/msi.gama.core/src/msi/gama/util/file/GamaGraphFile.java @@ -21,7 +21,7 @@ import msi.gama.runtime.exceptions.GamaRuntimeException; import msi.gama.util.graph.GamaGraph; import msi.gama.util.graph.IGraph; -import msi.gama.util.graph.loader.GraphParsers; +import msi.gama.util.graph.loader.GraphImporters; import msi.gaml.species.ISpecies; import msi.gaml.types.IContainerType; import msi.gaml.types.Types; @@ -54,7 +54,7 @@ public Envelope3D computeEnvelope(final IScope scope) { @Override protected void fillBuffer(final IScope scope) throws GamaRuntimeException { if (getBuffer() != null) { return; } - GraphImporter parser = GraphParsers.getGraphImporter(getFileType()); + GraphImporter parser = GraphImporters.getGraphImporter(getFileType()); DirectedMultigraph graph = new DirectedMultigraph<>( SupplierUtil.createStringSupplier(), SupplierUtil.DEFAULT_EDGE_SUPPLIER, true); diff --git a/msi.gama.core/src/msi/gama/util/graph/loader/GraphParsers.java b/msi.gama.core/src/msi/gama/util/graph/loader/GraphImporters.java similarity index 99% rename from msi.gama.core/src/msi/gama/util/graph/loader/GraphParsers.java rename to msi.gama.core/src/msi/gama/util/graph/loader/GraphImporters.java index 8bfffa7321..004ace9c34 100644 --- a/msi.gama.core/src/msi/gama/util/graph/loader/GraphParsers.java +++ b/msi.gama.core/src/msi/gama/util/graph/loader/GraphImporters.java @@ -39,7 +39,7 @@ * @author Patrick Taillandier * */ -public class GraphParsers { +public class GraphImporters { private static final Map> name2parser = new HashMap>() { diff --git a/msi.gama.core/src/msi/gama/util/graph/writer/AvailableGraphWriters.java b/msi.gama.core/src/msi/gama/util/graph/writer/AvailableGraphWriters.java deleted file mode 100644 index 7999009ddc..0000000000 --- a/msi.gama.core/src/msi/gama/util/graph/writer/AvailableGraphWriters.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************************************* - * - * msi.gama.util.graph.writer.AvailableGraphWriters.java, in plugin msi.gama.core, is part of the source code of the - * GAMA modeling and simulation platform (v. 1.8.1) - * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners - * - * Visit https://github.com/gama-platform/gama for license information and contacts. - * - ********************************************************************************************************/ -package msi.gama.util.graph.writer; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.jgrapht.nio.GraphExporter; - -import msi.gama.runtime.GAMA; -import msi.gama.runtime.exceptions.GamaRuntimeException; - -/** - * Lists available graphs writers, independently of the underlying library. - * - * @author Samuel Thiriot - * - */ -public class AvailableGraphWriters { - - private static final Map> name2writer = - new HashMap>() { - - { - - // defaults - /* put("dgs", GraphStreamWriterDGS.class); - put("gml", GraphStreamWriterGML.class); - // put("tikz", GraphStreamWriterTikz.class); - // put("gexf", GephiWriterGEXF.class); - // put("pajek", GephiWriterPajek.class); - // put("dl_list", GephiWriterDLList.class); - // put("ucinet_list", GephiWriterDLList.class); - // put("dl_matrix", GephiWriterDLMatrix.class); - // put("ucinet_matrix", GephiWriterDLMatrix.class); - // put("csv", GephiWriterCSV.class); - - put("graphml", GraphStreamWriterGML.class); - // put("tlp", GephiWriterTLP.class); - // put("tulip", GephiWriterTLP.class); - // put("gdf", GephiWriterGDF.class); - // put("guess", GephiWriterGDF.class); - - // not ok: put("vna", GephiWriterVNA.class); - - // graphstream - put("graphstream.dgs", GraphStreamWriterDGS.class); - put("graphstream.gml", GraphStreamWriterGML.class); - put("graphstream.graphml", GraphStreamWriterGML.class); - // put("graphstream.tikz", GraphStreamWriterTikz.class); - - // prefuse - // Nota: prefuse writers are not active now; they will probably no more be active later, because - // prefuse - // is not more maintained. - // put("prefuse.gml", PrefuseWriterGraphML.class); - // put("prefuse.graphml", PrefuseWriterGraphML.class); - - // gephi - // put("gephi.gexf", GephiWriterGEXF.class); - // put("gephi.pajek", GephiWriterPajek.class); - // put("gephi.dl_list", GephiWriterDLList.class); - // put("gephi.ucinet_list", GephiWriterDLList.class); - // put("gephi.dl_matrix", GephiWriterDLMatrix.class); - // put("gephi.ucinet_matrix", GephiWriterDLMatrix.class); - // put("gephi.graphml", GephiWriterGraphML.class); - // put("gephi.tlp", GephiWriterGraphML.class); - // put("gephi.tulip", GephiWriterGraphML.class); - // put("gephi.gdf", GephiWriterGDF.class); - // put("gephi.guess", GephiWriterGDF.class); - // put("gephi.csv", GephiWriterCSV.class); - - // not ok: put("gephi.vna", GephiWriterVNA.class);*/ - - } - }; - - public static Set getAvailableWriters() { - return name2writer.keySet(); - } - - private static Map name2singleton = new HashMap<>(); - - public static GraphExporter getGraphWriter(final String name) { - GraphExporter res = name2singleton.get(name); - - if (res == null) { - // no singleton created - final Class classWriter = name2writer.get(name); - if (classWriter == null) { - throw GamaRuntimeException.error( - "unknown writer name: " + name + "; please choose one of " + getAvailableWriters().toString(), - GAMA.getRuntimeScope()); - } - - name2singleton.put(name, res); - } - - return res; - } -} diff --git a/msi.gama.core/src/msi/gama/util/graph/writer/GraphExporters.java b/msi.gama.core/src/msi/gama/util/graph/writer/GraphExporters.java new file mode 100644 index 0000000000..0a899e4777 --- /dev/null +++ b/msi.gama.core/src/msi/gama/util/graph/writer/GraphExporters.java @@ -0,0 +1,96 @@ +/******************************************************************************************************* + * + * msi.gama.util.graph.writer.AvailableGraphWriters.java, in plugin msi.gama.core, is part of the source code of the + * GAMA modeling and simulation platform (v. 1.8.1) + * + * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * + * Visit https://github.com/gama-platform/gama for license information and contacts. + * + ********************************************************************************************************/ +package msi.gama.util.graph.writer; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.jgrapht.nio.GraphExporter; +import org.jgrapht.nio.GraphImporter; +import org.jgrapht.nio.dimacs.DIMACSExporter; +import org.jgrapht.nio.dimacs.DIMACSImporter; +import org.jgrapht.nio.dot.DOTExporter; +import org.jgrapht.nio.dot.DOTImporter; +import org.jgrapht.nio.gexf.GEXFExporter; +import org.jgrapht.nio.gexf.SimpleGEXFImporter; +import org.jgrapht.nio.gml.GmlExporter; +import org.jgrapht.nio.gml.GmlImporter; +import org.jgrapht.nio.graph6.Graph6Sparse6Exporter; +import org.jgrapht.nio.graph6.Graph6Sparse6Importer; +import org.jgrapht.nio.graphml.GraphMLExporter; +import org.jgrapht.nio.graphml.GraphMLImporter; +import org.jgrapht.nio.tsplib.TSPLIBImporter; + +import msi.gama.runtime.GAMA; +import msi.gama.runtime.exceptions.GamaRuntimeException; + +/** + * Lists available graphs writers, independently of the underlying library. + * + * @author Patrick Taillandier + * + */ +public class GraphExporters { + + private static final Map> name2writer = + new HashMap>() { + + { + put("dimacs", DIMACSExporter.class); + put("dot", DOTExporter.class); + put("gexf", GEXFExporter.class); + put("graphml", GraphMLExporter.class); + put("graph6", Graph6Sparse6Exporter.class); + put("gml", GmlExporter.class); + } + }; + + public static Set getAvailableWriters() { + return name2writer.keySet(); + } + + private static Map name2singleton = new HashMap<>(); + + public static GraphExporter getGraphWriter(final String name) { + GraphExporter res = name2singleton.get(name); + + if ( res == null ) { + // no singleton created + Class clazz = name2writer.get(name); + if ( clazz == null ) { throw GamaRuntimeException.error( + "unknown exporter name: " + name + "; please choose one of " + getAvailableWriters().toString(), + GAMA.getRuntimeScope()); } + Constructor ctor; + try { + ctor = clazz.getConstructor(); + res = (GraphExporter) ctor.newInstance(); + name2singleton.put(name, res); + return res; + } catch (NoSuchMethodException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } catch (SecurityException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } catch (IllegalArgumentException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } catch (InvocationTargetException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } catch (InstantiationException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } catch (IllegalAccessException e) { + throw GamaRuntimeException.create(e, GAMA.getRuntimeScope()); + } + } + return res; + } +} diff --git a/msi.gama.core/src/msi/gaml/statements/SaveStatement.java b/msi.gama.core/src/msi/gaml/statements/SaveStatement.java index 96054c4acf..f853d2e042 100644 --- a/msi.gama.core/src/msi/gaml/statements/SaveStatement.java +++ b/msi.gama.core/src/msi/gaml/statements/SaveStatement.java @@ -11,8 +11,7 @@ package msi.gaml.statements; import static msi.gama.common.util.FileUtils.constructAbsoluteFilePath; -import static msi.gama.util.graph.writer.AvailableGraphWriters.getAvailableWriters; -import static msi.gama.util.graph.writer.AvailableGraphWriters.getGraphWriter; +import static msi.gama.util.graph.writer.GraphExporters.getAvailableWriters; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; @@ -47,14 +46,8 @@ import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geometry.Envelope2D; import org.geotools.referencing.CRS; -import org.opengis.coverage.grid.GridCoverageWriter; -import org.opengis.feature.simple.SimpleFeature; -import org.opengis.feature.simple.SimpleFeatureType; -import org.opengis.geometry.Envelope; -import org.opengis.referencing.FactoryException; -import org.opengis.referencing.crs.CoordinateReferenceSystem; - -import org.locationtech.jts.algorithm.CGAlgorithms; +import org.jgrapht.nio.GraphExporter; +import org.locationtech.jts.algorithm.Orientation; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.Geometry; @@ -68,6 +61,12 @@ import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.geom.impl.CoordinateArraySequenceFactory; +import org.opengis.coverage.grid.GridCoverageWriter; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; import msi.gama.common.geometry.GeometryUtils; import msi.gama.common.interfaces.IGamlIssue; @@ -99,6 +98,7 @@ import msi.gama.util.IModifiableContainer; import msi.gama.util.file.IGamaFile; import msi.gama.util.graph.IGraph; +import msi.gama.util.graph.writer.GraphExporters; import msi.gaml.compilation.IDescriptionValidator; import msi.gaml.compilation.annotations.validator; import msi.gaml.descriptions.IDescription; @@ -133,7 +133,7 @@ name = IKeyword.TYPE, type = IType.ID, optional = true, - values = { "shp", "text", "csv", "asc", "geotiff", "image", "kml", "kmz", "json" }, + values = { "shp", "text", "csv", "asc", "geotiff", "image", "kml", "kmz", "json", "dimacs", "dot", "gexf", "graphml", "gml","graph6" }, doc = @doc ("an expression that evaluates to an string, the type of the output file (it can be only \"shp\", \"asc\", \"geotiff\", \"image\", \"text\" or \"csv\") ")), @facet ( name = IKeyword.DATA, @@ -400,13 +400,12 @@ public Object privateExecuteIn(final IScope scope) throws GamaRuntimeException { } else { ((GamaKmlExport) kml).saveAsKmz(scope, path); } - break; default: if (getAvailableWriters().contains(type)) { final IGraph g = Cast.asGraph(scope, item); if (g == null) { return null; } - // getGraphWriter(type).writeGraph(scope, g, null, path); + this.saveGraph(g, fileToSave, type, scope); } else { throw GamaRuntimeFileException.error("Format is not recognized ('" + type + "')", scope); } @@ -623,6 +622,14 @@ public static String getGeometryType(final List agents) { } return geomType; } + + public void saveGraph(final IGraph g, final File f, final String type, final IScope scope) { + GraphExporter exp = GraphExporters.getGraphWriter(type); + if (exp != null) { + exp.exportGraph(g, f.getAbsoluteFile()); + } + } + public void saveShape(final IList agents, final File f, final IScope scope, final boolean geoJson) throws GamaRuntimeException { @@ -892,15 +899,15 @@ private void computeInitsFromAttributesFacet(final IScope scope, final Map