Friday, February 8, 2008

Docs: How to understand JGrass's console engine - part IV, how to use it without JGrass?

I really want to drop a note for developers interested in this.

Alright, The JGrass console engine can be used without JGrass. All you need are the two console plugins from the JGrass package:

  • eu.hydrologis.jgrass.console
  • eu.hydrologis.jgrass.console.editor

At that point lets code:



/*
* prepare to use the console environment
*/
PipedOutputStream out = new PipedOutputStream();
PrintStream pStream = new PrintStream(out);
JGrass console = ConsolePlugin.console();
if (null == console) {
// throw something
}


Set some options to the engine:



ProjectOptions projectOptions = new ProjectOptions(pStream, pStream, pStream);
PreferencesInitializer.initializeStartupProjectOptions(projectOptions);
projectOptions.setOption(ProjectOptions.COMMON_GRASS_DATABASE, new File(
locationPath).getParent());
projectOptions.setOption(ProjectOptions.COMMON_GRASS_LOCATION, new File(
locationPath).getName());
projectOptions.setOption(ProjectOptions.COMMON_GRASS_MAPSET, mapsetName);
projectOptions.setOption(ProjectOptions.CONSOLE_COMPILE_ONLY, new Boolean(false));
projectOptions.setOption(ProjectOptions.CONSOLE_ASYNC_MODE, new Boolean(false));
URL rtUrl = Platform.getBundle(ConsolePlugin.PLUGIN_ID).getResource("rt"); //$NON-NLS-1$
String rtPath = null;
try {
rtPath = FileLocator.toFileURL(rtUrl).getPath();
} catch (IOException e) {
HydrocarePlugin.log("HydrocarePlugin problem", e); //$NON-NLS-1$
e.printStackTrace();
return;
}
projectOptions.setOption(ProjectOptions.CONSOLE_DIRECTORY_INCLUDE,
new String[]{rtPath});


Note that the FileLocator.toFileURL stuff is needed only if inside an RCP application.

Now create the command you want to execute:


String command = "g.region -p";


And execute it!



console.dispatch(projectOptions, command);





UPDATE
_________


I just created a class to use the console in standalone mode:



/**
* Standalone console engine
*
* @author Andrea Antonello - www.hydrologis.com
*/
public class JGrassConsole {
private final String grassDbPath;

private final String locationName;

private final String mapsetName;

private final String rtPath;

private boolean doDebug = false;

private String gisbase = "/"; //$NON-NLS-1$

public JGrassConsole(String grassDbPath, String locationName,
String mapsetName, String rtPath, String cmd, boolean debug,
String grass) {
this.grassDbPath = grassDbPath;
this.locationName = locationName;
this.mapsetName = mapsetName;
this.rtPath = rtPath;
this.doDebug = debug;
if (grass != null) {
gisbase = grass;
}
/*
* prepare to use the console environment
*/
PrintStream outStream = new PrintStream(System.out);
PrintStream errStream = new PrintStream(System.err);
JGrass console = (JGrass) new ConsoleEngine();
if (null == console) {
// throw something
}

ProjectOptions projectOptions = new ProjectOptions(outStream,
outStream, errStream);

initialize(projectOptions);

console.dispatch(projectOptions, cmd);
}

/**
* @param args
*/
@SuppressWarnings("nls")
public static void main(String[] args) {

String grassDbPath = null;
String locationName = null;
String mapsetName = null;
String rtPath = null;
String cmd = null;
String grass = null;
boolean debug = false;

for (String arg : args) {
System.out.println(arg);
if (arg.startsWith("-db")) {
grassDbPath = arg.split("=")[1];
}
if (arg.startsWith("-loc")) {
locationName = arg.split("=")[1];
}
if (arg.startsWith("-maps")) {
mapsetName = arg.split("=")[1];
}
if (arg.startsWith("-rt")) {
rtPath = arg.split("=")[1];
}
if (arg.startsWith("-cmd")) {
cmd = arg.split("=")[1];
}
if (arg.startsWith("-deb")) {
debug = true;
}
if (arg.startsWith("-grass")) {
grass = arg.split("=")[1];
}
}

if (grassDbPath == null || locationName == null || mapsetName == null
|| rtPath == null || cmd == null) {
System.out
.println("USAGE: -db= -loc= -maps= -rt= -cmd= [-grass=] [-debug]");
System.exit(1);
}

new JGrassConsole(grassDbPath, locationName, mapsetName, rtPath, cmd,
debug, grass);

}

public void initialize(ProjectOptions options) {
options.setOption(ProjectOptions.CONSOLE_ASYNC_MODE, false);
options.setOption(ProjectOptions.CONSOLE_THREAD_RESTRICTION, 0);
options.setOption(ProjectOptions.CONSOLE_COMPILE_ONLY, false);

// Logging Level: DEBUG
options.setOption(ProjectOptions.CONSOLE_LOGGING_LEVEL_DEBUG, doDebug);
// Logging Level: TRACE
options.setOption(ProjectOptions.CONSOLE_LOGGING_LEVEL_TRACE, doDebug);
// Include directory; RTTI - runtime type informations - the
// reserved
// words...
options.setOption(ProjectOptions.CONSOLE_DIRECTORY_INCLUDE,
new String[] { rtPath });

// Source directory; default script file location...
options.setOption(ProjectOptions.CONSOLE_DIRECTORY_SOURCE, null);

// User information - the home directory of the current user...
options.setOption(ProjectOptions.NATIVE_MODEL_USER_HOME, System
.getProperty("user.home")); //$NON-NLS-1$

// User information - the user name of the current user...
options.setOption(ProjectOptions.NATIVE_MODEL_USER_NAME, System
.getProperty("user.name")); //$NON-NLS-1$

// Debug mode...
options.setOption(ProjectOptions.NATIVE_MODEL_DEBUG, doDebug);

// Installation folder of GRASS...
options.setOption(ProjectOptions.NATIVE_MODEL_GISBASE, gisbase);

// GRASS database, location, mapset path...
options.setOption(ProjectOptions.COMMON_GRASS_MAPSET, grassDbPath
+ File.separator + locationName + File.separator + mapsetName
+ File.separator);

options.setOption(ProjectOptions.JAVA_MODEL_TIME_DELTA, null);
options.setOption(ProjectOptions.JAVA_MODEL_TIME_ENDING_UP, null);
options.setOption(ProjectOptions.JAVA_MODEL_TIME_START_UP, null);
}

}

3 comments:

Unknown said...

I'm planning to integrate the JGRASS console in the GeoTools WPS package, but the console packages are not compiled against JDK 1.5: how can I compile them without resorting to a general JGRASS build ?

moovida said...

The easy way is to simply download the macosx version and exploit those plugins, since that one is compiled in java 1.5.

moovida said...

For your convenience I updated the post with a complete class to use the console in standalone mode.

Anyway there are several dependencies from rcp pachages that we would not need.
I changed the svn code to be able to work even without the rcp environment, so there should be no problem. Anyway you will have to add several modules to the classpath, in order to make it work. I had no time to check them all, if you are patient and able to define the needed classes, I would be glad to help to create a dummy substitutive package in order to not have to load all the unnecessary plugins. Feel free to contact me for more infos.