Skip to content

Commit

Permalink
new possibility in the save statement: possibility to export graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
ptaillandier committed Jul 1, 2021
1 parent bc4e8c7 commit f92e8a5
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 130 deletions.
4 changes: 2 additions & 2 deletions msi.gama.core/src/msi/gama/util/file/GamaGraphFile.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, DefaultEdge> graph = new DirectedMultigraph<>(
SupplierUtil.createStringSupplier(), SupplierUtil.DEFAULT_EDGE_SUPPLIER, true);

Expand Down
Expand Up @@ -39,7 +39,7 @@
* @author Patrick Taillandier
*
*/
public class GraphParsers {
public class GraphImporters {

private static final Map<String, Class<? extends GraphImporter>> name2parser =
new HashMap<String, Class<? extends GraphImporter>>() {
Expand Down

This file was deleted.

96 changes: 96 additions & 0 deletions 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<String, Class<? extends GraphExporter>> name2writer =
new HashMap<String, Class<? extends GraphExporter>>() {

{
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<String> getAvailableWriters() {
return name2writer.keySet();
}

private static Map<String, GraphExporter> name2singleton = new HashMap<>();

public static GraphExporter getGraphWriter(final String name) {
GraphExporter res = name2singleton.get(name);

if ( res == null ) {
// no singleton created
Class<? extends GraphExporter> 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;
}
}
41 changes: 24 additions & 17 deletions msi.gama.core/src/msi/gaml/statements/SaveStatement.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -623,6 +622,14 @@ public static String getGeometryType(final List<? extends IShape> 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<? extends IShape> agents, final File f, final IScope scope, final boolean geoJson)
throws GamaRuntimeException {
Expand Down Expand Up @@ -892,15 +899,15 @@ private void computeInitsFromAttributesFacet(final IScope scope, final Map<Strin
private static Geometry fixesPolygonCWS(final Geometry g) {
if (g instanceof Polygon) {
final Polygon p = (Polygon) g;
final boolean clockwise = CGAlgorithms.isCCW(p.getExteriorRing().getCoordinates());
final boolean clockwise = Orientation.isCCW(p.getExteriorRing().getCoordinates());
if (p.getNumInteriorRing() == 0) { return g; }
boolean change = false;
final LinearRing[] holes = new LinearRing[p.getNumInteriorRing()];
final GeometryFactory geomFact = new GeometryFactory();
for (int i = 0; i < p.getNumInteriorRing(); i++) {
final LinearRing hole = (LinearRing) p.getInteriorRingN(i);
if (!clockwise && !CGAlgorithms.isCCW(hole.getCoordinates())
|| clockwise && CGAlgorithms.isCCW(hole.getCoordinates())) {
if (!clockwise && !Orientation.isCCW(hole.getCoordinates())
|| clockwise && Orientation.isCCW(hole.getCoordinates())) {
change = true;
final Coordinate[] coords = hole.getCoordinates();
ArrayUtils.reverse(coords);
Expand Down Expand Up @@ -1008,7 +1015,7 @@ public static void saveGeoJSonFile(final IScope scope, final File f, final List<

final FeatureJSON io = new FeatureJSON();
io.writeFeatureCollection(featureCollection, f.getAbsolutePath());

}

// AD 2/1/16 Replace IAgent by IShape so as to be able to save geometries
Expand Down

0 comments on commit f92e8a5

Please sign in to comment.