Running Spatial Interaction Models in JAVA

Overview

Recently we have been developing a Java based set of software components for the field of land use transportation modeling. The system has being designed for integrating various open source tools for the rapid assessment of urban futures. We have made use of extensive object oriented technologies to implement a general framework and data exchange environment, with the potential to embed common subsystems like GIS, simulation models, management tools, databases and other external data sources.

In this post, I am going to describe how to run spatial interaction models in Java platform using a basic library we have developed in the context SIMULACRA. The library defines a group of classes that represent a set of possible behaviors for spatial interaction models based on Wilson’s (1972).

Probably one of the more interesting parts of this library from a design standpoint is the use of the Strategy pattern to implement the family of spatial interaction models. These behaviors should be flexible to be plugged into an application, changing the functionality on the fly. A UML class diagram is shown here:

some_text

Based on the UML class diagram, there are four ways to perform the running of a spatial interaction models (gravity, production constrained, attraction constrained and double constrained) and two ways to perform the generalization of the travel cost matrix (inverse power function and negative exponential function).

SpatialInteractionModel – This is the class that will use different strategies to run the models. It keeps a reference to the ISpatialInterationModel instance. This class uses the setTypeOfSpatialInteractionModel method to replace the current strategy with another strategy. Also will use the different strategies to calculate the generalized travel cost using the method setTypeOfDistanceFunction.

ISpatialInteractionModel – The interface defines all the methods available for the SpatialInteractionModel to use.

GravityModel, ProductionConstrainedModel, AttractionConstrainedModel and ProductionAttractionConstrainedModel – These classes implement the ISpatialInteractionModel interface using the specific set of rules for each calculateInteractions method.

InversePowerFunction and NegativeExponentialFunction – These classes implement the IDistanceFunction interface using the specific set of rules for each calculateDistanceFuntion method.

Where to start?

This quick guide describes the usage of our spatial interaction model library in Eclipse as a Java IDE.

For the realization of this tutorial is necessary to be familiar with the basic concepts of spatial interaction models and object oriented programming with Java and the use of Eclipse IDE.

If you are not familiar with spatial interaction models I will advice you to first read this article by Professor Sir Alan Wilson.

If you are not familiar with Eclipse IDE I will advice you to first try this tutorial by Lars Vogel.

Used Libraries

For the development of the tutorial will need the following tools

  • For the spatial interaction models we are going to use the latest jar file from our Google Code project home page casa-simulacra.

Step 1. Defining the problem

To explain how to run spatial interaction models with our library we will consider a problem of predicting flows shopping expenditure between a four-zones city.

Shopping expenditure data for the four-region city will be:

Weekly shopping expenditure (GBP)

Zonal Retail Floorspace (square metres)

Travel cost between zones

Step 2. Import project into Eclipse

First you will need to download an eclipse project we have prepared for this guide from here.

After start Eclipse, select from the menu File -> Import.

In the import wizard select “Existing  Projects into Workspace” and click Next.

Select the “Select archive file” option and click on Browse to select the file that you just had downloaded.

After select the file click Finish to import the project into the workspace. A new project is created and displayed as a folder in the project explorer view. Open the corresponding folder to the “uk.ac.ucl.casa.simulacra.first” project.

Select the folder src, select the package “uk.ac.ucl.casa.simulacra.first” and then open the class MyFirstSpatialInteractionModel. The class should be something like:

package uk.ac.ucl.casa.simulacra.first;

public class MyFirstSpatialInteractionModel {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		double[] shoppingExpenditure = {355,455,255,570};
		double[] retailFloorspace = {720,376,930,321};
		double[][] travelCost = {{3,11,18,22},{12,3,13,19},{15,13,5,7},{24,18,8,5}};

	}

}

Note that the class has already declared the variables related with the definition of the problem in Step 1.

Step 3. Creating an Spatial Interaction model object

To create the spatial interaction model we just will need to add few lines after the following line

double[][] travelCost = {{3,11,18,22},{12,3,13,19},{15,13,5,7},{24,18,8,5}};

The lines are

SpatialInteractionModel model = new SpatialInteractionModel(shoppingExpenditure, retailFloorspace);
model.setTypeSpatialInteractionModel(new AttractionConstrainedModel());
model.setTypeDistanceFunction(new NegativeExponentialFunction());

Step 4. Run the model and print the results

To obtain the predicted trip matrix for shopping expenditure flows for the four-zones city we just need to run the model with the following line of code

double[][] tripMatrix = model.calculateInteractions(travelCost, 0.1);

Note that to run the model, the calculateInteractions() method needs to parameters, travelCost which has already been defined and the frictionParameter. For the purpose of this tutorial we will use a naive approach to assign a value of the friction parameter, we will simple guess the value. In following posts we will discuss the implementation of different methods to calculate a better estimation of the friction parameter.

Now, we just need to print the predicted trip matrix for shopping expenditure flows adding the following lines

System.out.println("Origin   " + "Destination   " + "Flow");
for (int i = 0; i < shoppingExpenditure.length; i++) {
	for (int j = 0; j < retailFloorspace.length; j++) {
		System.out.println(i + "        "  + j + "             " + tripMatrix[i][j]);
	}
}

Finally, to see the results you just need to run the application by right click on the MyFirstSpatialInteractionModel.java editor -> Run as -> Java Applciation

At the end your class should look like:

package uk.ac.ucl.casa.simulacra.first;

import uk.ac.ucl.casa.scale.spatialinteraction.exception.SpatialUnitsException;
import uk.ac.ucl.casa.scale.spatialinteraction.model.AttractionConstrainedModel;
import uk.ac.ucl.casa.scale.spatialinteraction.model.NegativeExponentialFunction;
import uk.ac.ucl.casa.scale.spatialinteraction.model.SpatialInteractionModel;

public class MyFirstSpatialInteractionModel {

	/**
	 * @param args
	 * @throws SpatialUnitsException
	 */
	public static void main(String[] args) throws SpatialUnitsException {
		// TODO Auto-generated method stub
		double[] shoppingExpenditure = {355,455,255,570};
		double[] retailFloorspace = {720,376,930,321};
		double[][] travelCost = {{3,11,18,22},{12,3,13,19},{15,13,5,7},{24,18,8,5}};

		SpatialInteractionModel model = new SpatialInteractionModel(shoppingExpenditure, retailFloorspace);
		model.setTypeSpatialInteractionModel(new AttractionConstrainedModel());
		model.setTypeDistanceFunction(new NegativeExponentialFunction());

		double[][] tripMatrix = model.calculateInteractions(travelCost, 0.1);

		System.out.println("Origin   " + "Destination   " + "Flow");
		for (int i = 0; i < shoppingExpenditure.length; i++) {
			for (int j = 0; j < retailFloorspace.length; j++) {
				System.out.println(i + "        "  + j + "             " + tripMatrix[i][j]);
			}
		}
	}

}

And, the results should look like

Final Comments

This library has been the based for the implementation of one of the first models of Simulacra dealing with residential, retail and employment location. Here you can see a sample of what the application looks like