Go to Bottom of Page

Visualization, Fall 2001
FINAL PROJECT
DUE: Dec 18, 2001

1  INTRODUCTION

The final project will be a class effort. We will divide the effort into 3 parts.

PART A: Constructing the search infrastructure for processing TIGER data into hierarchical LOD structures.

PART B: Constructing Search Structures, on both the client and server sides.

PART C: Constructing the Client/Server System.

We shall aim at working with 16 counties as the goal - these 16 counties will be the 5 boroughs of NYC, plus surrounding counties in New York and New Jersey. Parts and pieces of the necessary code are already embedded in our first 3 homeworks, so reuse them whenever possible. BUT I stree that it is important to stick to the specs and to the deadlines specified below. Any variation in these specs should be discussed with me.

2  DETAILS

2.1  PART A: Search Infrastructure

We need create an infra structure for merge them, and to simply them to create LOD structures.

But in what order do we merge counties? What we want is the merge tree for the 16 counties. In our TIGER resource page. there is a list of 435 counties from 14 states in North East USA, from Maine to Virginia. This list contains the adjacency graph of all the counties. We will take advantage of this information to construct our data structure. Since we only have 16 counties, we will construct the merge tree by hand.

We assume the merge tree is binary. At each node of the merge tree, we store the following information:

	///////////////////////////////////////////////////////
	//	Merge Node class
	///////////////////////////////////////////////////////

	class MergeNode {
	  public: 
		int xmin, xmax;		// bounding box 
		int ymin, ymax;		// 	information 
		int sScale;		// Level of Detail (LOD)
		MergeNode leftChild, rightChild;
		Outline   oStruct;	// outline layer (see below)
		Network   nStruct;	// road layer (see below)
		RangeTree rStruct;	// range tree search structure
		HashTable hStruct;	// hash table

	  // CONSTRUCTORS:

		MergeNode(TigerSubdiv & ts);  // create a leaf node
		MergeNode(MergeNode & mn1, MergeNode & mn2);
				 // create an internal node from two children
					
	  // METHODS:

		void Dump(char * fname);  // Write out to one or more files
	} //class MergeNode
	

The Outline and Network classes are derived from of TigerSubdiv class (see below). The RangeTree will contain all the endpoints of TLines in these two classes.

How we do a window query at a MergeNode? Actually, each window query is accompanied by a ßScale" (screen scale value). There are two cases:

CASE 1: The sScale at the current MergeNode is greater than the sScale of the query. Then the window search is recursively sent to the children of the current MergeNode. We send it to a child only if the query window intersects the bounding box of the child.

CASE 2: In this case we directly search the current node. We first use the range tree to determine retrieve all points in the query window. Each point knows whether it belongs to the Outline or the Network structure. For each point in either structure, we can retrieve all the TLines that are incident on it. Each TLine has a unique ID. We try to insert these TLines into the hash table. If unsuccessful, it means that the client already has this information. Otherwise, this is sent to the client. Similarly, we retrieve all polygons in the Outline structure, try to insert them in the hash table. Again, only send if the insertion is successful.

This completes the duty on the server side. What happens at the client side? The client also has the merge tree, but does not need the hash table. Also, its Outline and Network and Range structures are initially empty. As vertices, edges and polygons are sent, we fill them into the structure.

We need to worry about main memory: it is assumed that each MergeNode data is stored in a set of files and they are read into main memory as needed. We need to do a little bit of simple paging.

2.2  PART B: LOD Hierarchy

We will build upon the ideas in hw2. In hw2, we have a class TigerSubdiv with two methods TigerSubdiv::extractOutline and TigerSubdiv::extractRoads. The first method returns a true subdivision, but the second method returns only a skeleton. A skeleton is a 1-dimensional complex with only a Vertex List and a Line List; the Polygon List and Half-Edge List are empty. Hence we can continue to use a TigerSubdiv data structure to represent skeletons. You should think of the results of these two extractions as the main data for further simplifications and merging. Call these the outline layer and the network layer.

	///////////////////////////////////////////////////////
	//	Derived classes for Outline and Network
	///////////////////////////////////////////////////////

	class Outline : public Subdivision {
	  public:
		int sScale;		// screen scale
		int childSubdiv[2];	// the child subdivision
		
	}

	class Network : public Subdivision {
		// 
		// ...
	}

	

We now need to implement methods to merge and simplify these two layers of data. We treat these two layers as INDEPENDENT of each in the merging and simplication process. Merging is basically simple: it is just the union of the lists of vertices, edges, etc. However, you need to remove duplicates at the boundary.

Simplification is based on some maximum error bounds denoted sScale which, as in hw2, means the ßcreen scale". Thus sScale = 87 means 87 meters per pixel. There are two steps: (1) First, we simplify TLines, using the the same Douglas Peucker algorithm as specified in hw2. (2) Next, we eliminate small polygons. The rule here is that for any polygon whose bounding box area is less than MIN_PIXEL_AREA pixels will be eliminated.

	///////////////////////////////////////////////////////
	//	methods to reomve polygons
	///////////////////////////////////////////////////////

	void TigerSubdiv::checkPolygon(int polyID, int sScale)
		// Check if polyID has area that is too small
		// Remove it if so.

	void TigerSubdiv::removePolygon(int sScale)
		// Apply polyID if its area is too small

	

2.3  PART C: Client-Server Architecture

We assume that the server forks to serve each client and the messages between them are as follows:

  1. INIT(x,y): client sends this message to begin the visualization at position (x,y).
  2. DATA0: server sends the initial data to begin the visualization.
  3. WIN(xmin, xmax, ymin, ymax, level): client requests a data in a query window, at a given level of detail.
  4. DATA: response to Q(...).
  5. TERMINATE: client requests termination.

The client will have four threads, each with its own input queue ("Q").

  1. Input Thread: reads from the mouse and keyboard. It puts data into the NetworkQ or into the DisplayQ. The commands it accepts are PAN, ZOOM, JUMP, PRIORITIZE, QUIT.
  2. Network Thread: It processes the NetworkQ requests converts this into WIN(xmin, ymin, xmax, ymax, level) requests. At the same time, it puts a copy of this request into the DataQ.
  3. Data Thread: As soon as it read new data from the network, it compares them to the WIN requests. After decoding this, it informs the DisplayQ.
  4. Display Thread: it updates the display as requests and new data arrives.


Go to TOP of Page




File translated from TEX by TTH, version 3.01.
On 20 Dec 2001, 11:22.