Fast indexing of PPLX data
One of the tasks that sometimes comes up during plugin development is the need to rapidly parse and spatially index a large number of PPLX files.
Performing this task by fully hydrating each PPLX file into O-Calc proper, while relatively quick, would still take more time than desired for a large number of poles. In this post is presented a code snippet that can parse the latitude, longitude, poleID, and MCU percentage from a PPLX file very rapidly and allow for the processing of tens to hundreds of PPLX files per second depending on your system’s IO performance.
First I need to create a structure to hold the data I intend to parse form the PPLX and then instantiate a list to hold an instance of that structure for each PPLX that I parse.
-
public struct Pole
-
{
-
public double cLat ;
-
public double cLon ;
-
public string cName ;
-
public string cPath ;
-
public double cMCU ;
-
}
-
-
public List <Pole > cPoles = new List <Pole > ( ) ;
Now if I create a list of file path strings of all of the PPLX files I wish to process *the construction of this list is not covered here but typically would involce one or more calls to files = Directory.GetFiles(directory, “*.pplx”);) I can process them as follows:
-
foreach ( String file in files )
-
{
-
using (StreamReader sr = new StreamReader (file ) )
-
{
-
using (XmlTextReader xr = new System.Xml . XmlTextReader (sr ) )
-
{
-
String poleId = System.IO . Path . GetFileNameWithoutExtension (file ) ;
-
double lat = 0 ;
-
double lon = 0 ;
-
while (xr . Read ( ) )
-
{
-
if (xr . NodeType == System.Xml . XmlNodeType . Element && xr . Name == "VALUE" )
-
{
-
String sname = xr . GetAttribute ( "NAME" ) ;
-
if (sname == "Latitude" )
-
{
-
xr . Read ( ) ;
-
if ( ! double . TryParse (xr . Value, out lat ) ) break ;
-
if (lat == 0 ) break ;
-
}
-
else if (sname == "Longitude" )
-
{
-
xr . Read ( ) ;
-
if ( ! double . TryParse (xr . Value, out lon ) ) break ;
-
if (lon == 0 ) break ;
-
-
double mcu = - 1 ;
-
try
-
{
-
sr . DiscardBufferedData ( ) ;
-
sr . BaseStream . Seek ( - 1024, SeekOrigin . End ) ;
-
String sbuff = sr . ReadToEnd ( ) ;
-
int idx = sbuff . IndexOf ( "PercentAtMCU" ) ;
-
if (idx > 0 )
-
{
-
mcu = Parse (sbuff . Substring (idx + 20, 100 ) ) ;
-
}
-
}
-
catch
-
{
-
mcu = - 1 ;
-
}
-
-
if (lat != 0 && lon != 0 )
-
{
-
Pole pole = new Pole ( ) ;
-
pole . cLat = lat ;
-
pole . cLon = lon ;
-
pole . cName = poleId ;
-
pole . cMCU = mcu ;
-
pole . cPath = file ;
-
cPoles . Add (pole ) ;
-
}
-
break ;
-
-
}
-
}
-
}
-
}
-
}
-
}
Supported by…
-
double Parse ( String pStr )
-
{
-
const char gt = ( char ) 62 ;
-
const char lt = ( char ) 60 ;
-
int idx = pStr . IndexOf (gt ) ;
-
String s = pStr . Substring (idx + 1 ) ;
-
idx = s . IndexOf (lt ) ;
-
s = s . Substring ( 0, idx ) ;
-
double v = 0 ;
-
if ( double . TryParse (s, out v ) ) return v ;
-
return 0 ;
-
}
The following video shows this code in operation…