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…