📄 gdfreader.java
字号:
package de.uni_stuttgart.informatik.canu.gdfreader;
/**
* <p>Title: GDF Reader</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: University of Stuttgart</p>
* @author Illya Stepanov
* @version 1.1
*/
import geotransform.coords.Gdc_Coord_3d;
import geotransform.coords.Utm_Coord_3d;
import geotransform.transforms.Gdc_To_Utm_Converter;
import java.io.*;
import de.uni_stuttgart.informatik.canu.spatialmodel.core.*;
import de.uni_stuttgart.informatik.canu.spatialmodel.geometry.*;
import de.uni_stuttgart.informatik.canu.mobisim.core.*;
import de.uni_stuttgart.informatik.canu.mobisim.notifications.*;
/**
* This class is used to parse and read geographic data in GDF format
* @author Illya Stepanov
*/
public class GDFReader extends ExtensionModule
{
/**
* Source stream
*/
protected BufferedReader source;
/**
* Text from current record
*/
protected java.util.ArrayList lines = new java.util.ArrayList();
/**
* Index of next symbol in lines[0] under analysis
*/
protected int ind;
/**
* Name of the GDF-file producer
*/
protected String supplierName="";
/**
* Storage for GDF sections:
* Key - Section id, Value - associated GDFSection
*/
protected java.util.Map sections = new java.util.HashMap();
/**
* Storage for default attributes values:
* Key - Attribute id, Value - default value
*/
protected java.util.Map defaultAttributesValues = new java.util.HashMap();
/**
* Spatial Model
*/
protected SpatialModel spatialModel;
/**
* Scale factor for x-coordinates
*/
protected double scale_x = 0.01;
/**
* Scale factor for y-coordinates
*/
protected double scale_y = 0.01;
/**
* UTM-coordinates of the point with minimal X- and Y-values
*/
protected Utm_Coord_3d origin;
/**
* Clipping Region
*/
protected Polygon clipArea;
/**
* Constructor
*/
public GDFReader()
{
super("GDFReader");
}
/**
* Returns the module's description. <br>
* <br>
* @return extension module's description
*/
public String getDescription()
{
return "GDF Reader module";
}
/**
* Executes the extension. <br>
* <br>
* The method is called on every simulation timestep.
* @return 0 - the module should be executed on next timesteps,
* -1 - the module should not be executed on further timesteps and should be removed from the extensions' list
*/
public int act()
{
return -1;
}
/**
* Reads the next record
* @return record type or null if eof reached
*/
protected String getNextRecord() throws Exception
{
// clear buffer
ind = 0;
lines.clear();
// mark the beginning of the record
source.mark(8192);
String s;
// read next record
while ((s = source.readLine())!=null)
{
lines.add(s);
// if part of multi-line record, check for continuation prefix
if (lines.size()>1)
{
if (!s.startsWith("00"))
throw new Exception("Invalid continuation prefix!");
}
// check if single-line record
if (s.charAt(79)=='0')
break;
}
// eof reached
if (lines.size()==0)
return null;
// get record type
s = ((String)lines.get(0)).substring(0, 2);
ind = 2;
return s;
}
/**
* Gets the next field of currently read record. <br>
* <br>
* Gets next field of currently read record.
* Set size to -1 to get the rest of current line
* @param size size of the field (in symbols)
* @return field value or null if eof reached
*/
protected String getNextField(int size) throws Exception
{
String s;
// get next field from the record
for (;;)
{
if (lines.size()==0)
return null;
s = (String)lines.get(0);
// get rest of this line
if (size==-1)
{
s = s.substring(ind, 79);
// advance to next line
ind = 2; // skip continuation symbols
lines.remove(0);
return s;
}
// check if move to next line
if (ind+size>79)
{
ind = 2; // skip continuation symbols
lines.remove(0);
continue;
}
break;
}
s = s.substring(ind, ind+size);
ind+=size;
return s;
}
/**
* Parses the string argument as an integer
* @param s string to be parsed
* @return integer value from argument
*/
protected static int parseInt(String s)
{
s = s.trim();
if (s.length()==0)
s="0";
return new Integer(s).intValue();
}
/**
* Processes the Volume Header Record
*/
protected void processVolumeHeaderRecord() throws Exception
{
supplierName = getNextField(20).trim();
}
/**
* Processes the Default Attribute Record
*/
protected void processDefaultAttributeRecord() throws Exception
{
String type = getNextField(2).trim();
String value = getNextField(10).trim();
// a hack for "NavTech"
if (supplierName.toLowerCase().indexOf("navtech")!=-1)
{
// direction of traffic flow
if (type.equals("DF"))
{
// convert the value to original GDF
if (value.equals("2"))
value = "3";
else
if (value.equals("3"))
value = "2";
}
}
defaultAttributesValues.put(type, value);
}
/**
* Processes the Section Header Record
*/
protected void processSectionHeaderRecord() throws Exception
{
String id = getNextField(10);
GDFSection section = new GDFSection(this);
sections.put(id, section);
section.load();
}
/**
* Loads GDF data from source stream
*/
protected void doLoad() throws Exception
{
String s;
// read until eof reached
while ((s = getNextRecord())!=null)
{
// check record type code
switch (parseInt(s))
{
case 01:
processVolumeHeaderRecord();
break;
case 15:
processDefaultAttributeRecord();
break;
case 16:
// check subcode
int subCode = parseInt(getNextField(2));
if (subCode==1)
{
processSectionHeaderRecord();
break;
}
// fall through...
// Sometimes the header for single section is omitted.
// If one from data elements is found, create new section and
// let it process it.
case 23:
case 24:
case 25:
case 29:
case 41:
case 44:
case 45:
case 46:
case 50:
case 51:
case 52:
case 53:
case 54:
if (sections.size()>0)
throw new Exception("Invalid Data in Global Context!");
// reset the stream
source.reset();
GDFSection section = new GDFSection(this);
sections.put("", section);
section.load();
break;
}
}
}
/**
* Resolves "lazy" links
*/
protected void resolveLinks()
{
java.util.Iterator iter = sections.values().iterator();
while (iter.hasNext())
{
((GDFSection)iter.next()).initialise();
}
}
/**
* Constructs elements from loaded point features
*/
protected void createPointFeatureElements()
{
java.util.Map elements = spatialModel.getElements();
Object sections[] = this.sections.values().toArray();
GDFSection section = (GDFSection)sections[0];
// process point features
java.util.Iterator iter = section.pointFeatures.keySet().iterator();
while (iter.hasNext())
{
String id = (String)iter.next();
GDFPointFeatureRecord feature = (GDFPointFeatureRecord)
section.pointFeatures.get(id);
String class_code = feature.featureClassCode.substring(0, 2);
String subclass_code = feature.featureClassCode.substring(2, 4);
// check if the feature is correct
if (feature.nodes.size()==0)
continue;
if (feature.nodes.get(0)==null)
continue;
// get geometry
GDFXYZRecord.XYZPoint coord = (GDFXYZRecord.XYZPoint)
((GDFNodeRecord)feature.nodes.get(0)).point.points.get(0);
Point shape = convertToLocalCoordinates(coord);
SpatialModelElement element = new SpatialModelElement(id, class_code, subclass_code, shape);
// copy default attributes
element.getAttributes().putAll(defaultAttributesValues);
// copy attributes
for (int i=0; i<feature.attributes.size(); i++)
{
GDFAttributeRecord attr = (GDFAttributeRecord)feature.attributes.get(i);
if (attr==null)
continue;
element.getAttributes().putAll(attr.attributes);
}
// clip
if (clipArea!=null)
{
if (clipArea.contains(shape))
elements.put(id, element);
}
else
elements.put(id, element);
}
}
/**
* Constructs elements from loaded line features
*/
protected void createLineFeatureElements()
{
java.util.Map elements = spatialModel.getElements();
Object sections[] = this.sections.values().toArray();
GDFSection section = (GDFSection)sections[0];
// process line features
java.util.Iterator iter = section.lineFeatures.keySet().iterator();
outer:
while (iter.hasNext())
{
String id = (String)iter.next();
GDFLineFeatureRecord feature = (GDFLineFeatureRecord)
section.lineFeatures.get(id);
String class_code = feature.featureClassCode.substring(0, 2);
String subclass_code = feature.featureClassCode.substring(2, 4);
// check if the feature is correct
if (feature.fPoint==null)
continue outer;
if (feature.tPoint==null)
continue outer;
for (int l=0; l<feature.edges.size(); l++)
if (feature.edges.get(l)==null)
continue outer;
Polyline shape = new Polyline();
java.util.ArrayList points = shape.getPoints();
GDFXYZRecord.XYZPoint point;
// add intermediate edges
for (int l=0; l<feature.edges.size(); l++)
{
GDFEdgeRecord edge = (GDFEdgeRecord)feature.edges.get(l);
int direction = ((Integer)feature.edgesDirections.get(l)).intValue();
if (l==0)
{
// add starting point of an edge
if (direction==0)
point = (GDFXYZRecord.XYZPoint)edge.fNode.point.points.get(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -