source: trunk/src/inc/KMLFile.class.php@ 7776

Last change on this file since 7776 was 7776, checked in by Pieter Naber, 15 years ago

Oke... Couldn't resist it... Found the "Nodes in the ocean" bug and we have green placemarkers in the KML file :-)
See example.kml

  • Property svn:eol-style set to native
File size: 15.5 KB
RevLine 
[7725]1<?php
2/*
3 * Project: NodeMap2.0
4 * File: KMLHandler.class.php
5 * Purpose: Creating of editing KML files
6 */
7
[7775]8define('NODE_STATUS_UP', 0);
9define('NODE_STATUS_ERROR', 1);
10define('NODE_STATUS_UNREACHABLE', 2);
11
[7725]12class KMLFile {
13 private $template = '
14 <kml xmlns="http://www.opengis.net/kml/2.2">
15 <Document>
16 <name>Wireless Leiden Interactive Nodemap 2.0</name>
17 <open>1</open>
18 <description>Wireless Leiden Interactive Nodemap 2.0</description>
[7775]19 <LookAt>
20 <longitude>%OVERALL_LONGITUDE%</longitude>
21 <latitude>%OVERALL_LATITUDE%</latitude>
22 <altitude>%OVERALL_ALTITUDE%</altitude>
23 <heading>%OVERALL_HEADING%</heading>
24 <tilt>%OVERALL_TILT%</tilt>
25 <range>%OVERALL_RANGE%</range>
26 </LookAt>
27 <Style id="blackLine">
28 <LineStyle>
29 <color>%LINE_BLACK%</color>
30 <width>3</width>
31 </LineStyle>
32 </Style>
[7725]33 <Style id="greenArrowIcon">
34 <IconStyle>
35 <Icon>
[7765]36 <href>%NODE_GREEN%</href>
[7725]37 </Icon>
38 </IconStyle>
39 </Style>
40 <Style id="orangeArrowIcon">
41 <IconStyle>
42 <Icon>
[7765]43 <href>%NODE_ORANGE%</href>
[7725]44 </Icon>
45 </IconStyle>
46 </Style>
47 <Style id="redArrowIcon">
48 <IconStyle>
49 <Icon>
[7765]50 <href>%NODE_RED%</href>
[7725]51 </Icon>
52 </IconStyle>
53 </Style>
[7765]54 <Folder id="nodes">
[7725]55 <name>Nodes</name>
56 <description>Nodes from the Wireless Leiden network</description>
57 <LookAt>
[7775]58 <longitude>%OVERALL_LONGITUDE%</longitude>
59 <latitude>%OVERALL_LATITUDE%</latitude>
60 <altitude>%OVERALL_ALTITUDE%</altitude>
61 <heading>%OVERALL_HEADING%</heading>
62 <tilt>%OVERALL_TILT%</tilt>
63 <range>%OVERALL_RANGE%</range>
[7725]64 </LookAt>
[7765]65 %NODESCONTENT%
[7725]66 </Folder>
[7765]67 <Folder id="lines">
68 <name>Lines</name>
69 <description>Lines from nodes to nodes from the Wireless Leiden network</description>
70 <LookAt>
[7775]71 <longitude>%OVERALL_LONGITUDE%</longitude>
72 <latitude>%OVERALL_LATITUDE%</latitude>
73 <altitude>%OVERALL_ALTITUDE%</altitude>
74 <heading>%OVERALL_HEADING%</heading>
75 <tilt>%OVERALL_TILT%</tilt>
76 <range>%OVERALL_RANGE%</range>
[7765]77 </LookAt>
78 %LINESCONTENT%
79 </Folder>
80 </Document>
[7725]81 </kml>';
82
83 // First line of the status file must be like this:
84 static $fileFirst = 'type,host_name,has_been_checked,check_execution_time,current_state,last_hard_state,last_check,problem_has_been_acknowledged';
85 // Every following line will be checked using these functions
86 private $fileContent = array('string', 'string', 'int', 'double', 'int', 'int', 'int', 'int');
87
[7765]88 private $KMLNodes;
89 private $KMLLines;
[7773]90 private $NetworkList;
91
[7725]92 /*
93 * Function: __construct (constructor)
94 * Description: Creating a new KMLFile
95 * Parameters: -
96 * Returns: -
97 */
98 public function __construct() {
[7765]99 $this->KMLNodes = array();
100 $this->KMLLines = array();
[7773]101 $this->NetworkList = new NetworkList();
[7725]102 }
103
104 /*
[7765]105 * Function: addNode
106 * Description: Add a node to the local node array
107 * Parameters: KMLNode $node
[7725]108 * Returns: -
109 */
[7765]110 public function addNode(KMLNode $node) {
111 $this->KMLNodes[] = $node;
[7725]112 }
113
114 /*
[7765]115 * Function: addLIne
116 * Description: Add a line to the local line array
117 * Parameters: KMLLine $line
118 * Returns: -
119 */
120 public function addLine(KMLLine $line) {
121 $this->KMLLines[] = $line;
122 }
123
124 /*
[7725]125 * Function: toString
126 * Description: Converts the content of this file and the placemarks to a KML valid string
127 * Parameters: -
128 * Returns: KML valid string
129 */
130 public function toString() {
131 global $config;
132
133 $toString = $this->template;
134
[7773]135 // Add all nodes to the string
[7765]136 $nodeString = '';
137 $nodeCount = count($this->KMLNodes);
138 for ($i = 0; $i < $nodeCount; $i++) {
139 $nodeString .= $this->KMLNodes[$i]->toString();
[7725]140 }
141
[7773]142 // Add all connected lines to the string
[7765]143 $lineString = '';
144 $lineCount = count($this->KMLLines);
145 for ($i = 0; $i < $lineCount; $i++) {
[7773]146 // If longitude2 and latitude2 aren't set, ignore the lines
147 // This happens with all the connections that don't connect 2 nodes
148 if ($this->KMLLines[$i]->isConnected()) {
149 $lineString .= $this->KMLLines[$i]->toString();
150 }
[7765]151 }
[7725]152
[7765]153 $toString = str_replace('%NODE_GREEN%', $config['node_green'], $toString);
154 $toString = str_replace('%NODE_ORANGE%', $config['node_orange'], $toString);
155 $toString = str_replace('%NODE_RED%', $config['node_red'], $toString);
156 $toString = str_replace('%LINE_BLACK%', $config['line_black'], $toString);
157 $toString = str_replace('%NODESCONTENT%', $nodeString, $toString);
158 $toString = str_replace('%LINESCONTENT%', $lineString, $toString);
[7773]159
[7775]160 $toString = str_replace('%OVERALL_LONGITUDE%', $config['overall_longitude'], $toString);
161 $toString = str_replace('%OVERALL_LATITUDE%', $config['overall_latitude'], $toString);
162 $toString = str_replace('%OVERALL_ALTITUDE%', $config['overall_altitude'], $toString);
163 $toString = str_replace('%OVERALL_HEADING%', $config['overall_heading'], $toString);
164 $toString = str_replace('%OVERALL_TILT%', $config['overall_tilt'], $toString);
165 $toString = str_replace('%OVERALL_RANGE%', $config['overall_range'], $toString);
166
[7725]167 return $toString;
168 }
169
170 /*
[7765]171 * Function: getNodeByName
172 * Description: Find the first KMLNode with the name $name and return its position. If not found, return false
[7725]173 * Parameters: string $name
[7765]174 * Returns: Position of node in our array, if not found false
[7725]175 */
[7765]176 public function getNodeByName($name) {
177 $nodesCount = count($this->KMLNodes);
[7725]178 for ($i = 0; $i < $nodesCount; $i++) {
[7765]179 if ($this->KMLNodes[$i]->getName() == $name) {
[7725]180 return $i;
181 }
182 }
183
184 return false;
185 }
186
187 /*
188 * Function: parseLocationFile
[7765]189 * Description: Parse the node location file updating or adding KMLNode objects to the current KMLFile object
[7725]190 * Parameters: string $file
191 * Returns: true is successfull, otherwise false
192 */
193 public function parseLocationFile($file) {
[7773]194 // We want to find all the nodes in the location file and store information of the nodes...
[7725]195 $nodesCount = preg_match_all('/\[[a-zA-Z0-9]*\]/i', $file, $nodes, PREG_OFFSET_CAPTURE);
196 for ($i = 0; $i < $nodesCount; $i++) {
197 // Looking for "location" of the node
[7773]198 if (!$location = $this->findInLocationFile($file, 'location = ', $nodes[0][$i][1])) {
[7725]199 trigger_log(SYSLOG_WARNING, 'Could not find the "location" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
200 continue;
201 }
202 // Looking for "status" of the node
[7773]203 if (!$status = $this->findInLocationFile($file, 'status = ', $nodes[0][$i][1])) {
[7725]204 trigger_log(SYSLOG_WARNING, 'Could not find the "status" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
205 continue;
206 }
207 // Looking for "latitude" of the node
[7773]208 if (!$latitude = $this->findInLocationFile($file, 'latitude = ', $nodes[0][$i][1])) {
[7725]209 trigger_log(SYSLOG_WARNING, 'Could not find the "latitude" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
210 continue;
211 }
212 // Looking for "longitude" of the node
[7773]213 if (!$longitude = $this->findInLocationFile($file, 'longitude = ', $nodes[0][$i][1])) {
[7725]214 trigger_log(SYSLOG_WARNING, 'Could not find the "longitude" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
215 continue;
216 }
217 // Looking for "interfaces" of the node
[7773]218 if (!$interfaces = $this->findInLocationFile($file, 'interfaces = ', $nodes[0][$i][1])) {
[7725]219 trigger_log(SYSLOG_WARNING, 'Could not find the "interfaces" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
220 continue;
221 }
222 // Looking for "masterip" of the node
[7773]223 if (!$masterip = $this->findInLocationFile($file, 'masterip = ', $nodes[0][$i][1])) {
[7725]224 trigger_log(SYSLOG_WARNING, 'Could not find the "masterip" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
225 continue;
226 }
227 // Looking for "nodetype" of the node
[7773]228 if (!$nodetype = $this->findInLocationFile($file, 'nodetype = ', $nodes[0][$i][1])) {
[7725]229 trigger_log(SYSLOG_WARNING, 'Could not find the "nodetype" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
230 continue;
231 }
232 // Looking for "name" of the node
[7773]233 if (!$name = $this->findInLocationFile($file, 'name = ', $nodes[0][$i][1])) {
[7725]234 trigger_log(SYSLOG_WARNING, 'Could not find the "name" of node "' . $i . '", skipping to next', __FILE__, __LINE__);
235 continue;
236 }
237
238 // Creating a string with the complete description of the node using all data in the location file
[7775]239 $dataLocation = '
240 <Data name="location">
241 <value>
242 <![CDATA[
243 ' . $location . '
244 ]]>
245 </value>
246 </Data>
247 <Data name="status">
248 <value>' . $status . '</value>
249 </Data>
250 <Data name="interfaces">
251 <value>' . $interfaces . '</value>
252 </Data>
253 <Data name="masterIP">
254 <value>' . $masterip . '</value>
255 </Data>
256 <Data name="nodeType">
257 <value>' . $nodetype . '</value>
258 </Data>';
[7725]259
[7765]260 if ($placemarkPosition = $this->getNodeByName($name)) {
[7725]261 // Updating an excisting placemark
[7775]262 $this->KMLNodes[$placemarkPosition]->setDataLocation($dataLocation);
[7765]263 $this->KMLNodes[$placemarkPosition]->setLongitude($longitude);
264 $this->KMLNodes[$placemarkPosition]->setLatitude($latitude);
[7725]265 } else {
266 // Adding a new placemark
[7765]267 $placemark = new KMLNode();
[7725]268 $placemark->setID($name);
269 $placemark->setName($name);
[7775]270 $placemark->setDataLocation($dataLocation);
[7725]271 $placemark->setLongitude($longitude);
272 $placemark->setLatitude($latitude);
[7765]273 $this->addNode($placemark);
[7725]274 }
[7773]275
276 // Now let's find all interlinks with this node
277 $position = $nodes[0][$i][1];
278 while (($position = strpos($file, 'ip=', $position + 1)) && (isset($nodes[0][$i + 1][1]) && $position < $nodes[0][$i + 1][1])) {
279 $ipAddress = $this->findInLocationFile($file, 'ip=', $position);
280 $posSlash = strpos($ipAddress, '/');
281 $ip = substr($ipAddress, 0, $posSlash);
282 $netmask = substr($ipAddress, $posSlash + 1);
283
284 $posNetwork = $this->NetworkList->find($ip);
285 if ($posNetwork) {
286 // Network already excists in list, just need to add longitude2 en latitude2 to KMLLine
287 // and add the node name to the name of the line.
288 // Position in network equals position in KMLLine array :-)
289
290 $this->KMLLines[$posNetwork]->setName($this->KMLLines[$posNetwork]->getName() . $name);
291 $this->KMLLines[$posNetwork]->setLongitude2($longitude);
292 $this->KMLLines[$posNetwork]->setLatitude2($latitude);
293 } else {
294 // Network doesn't excist. We create a new network and a new line.
295
296 $network = new Network($ip, $netmask);
297 $this->NetworkList->add($network);
298
[7775]299 $data = '
300 <Data name="netmaskDecimal">
301 <value>' . $network->netmaskDecimal . '</value>
302 </Data>
303 <Data name="netmaskBinary">
304 <value>' . $network->netmaskBinary . '</value>
305 </Data>
306 <Data name="wildcardDecimal">
307 <value>' . $network->wildcardDecimal . '</value>
308 </Data>
309 <Data name="wildcardBinary">
310 <value>' . $network->wildcardBinary . '</value>
311 </Data>
312 <Data name="networkDecimal">
313 <value>' . $network->networkDecimal . '</value>
314 </Data>
315 <Data name="networkBinary">
316 <value>' . $network->networkBinary . '</value>
317 </Data>
318 <Data name="broadcastDecimal">
319 <value>' . $network->broadcastDecimal . '</value>
320 </Data>
321 <Data name="broadcastBinary">
322 <value>' . $network->broadcastBinary . '</value>
323 </Data>
324 <Data name="hostMinDecimal">
325 <value>' . $network->hostminDecimal . '</value>
326 </Data>
327 <Data name="hostMinBinary">
328 <value>' . $network->hostminBinary . '</value>
329 </Data>
330 <Data name="hostMaxDecimal">
331 <value>' . $network->hostmaxDecimal . '</value>
332 </Data>
333 <Data name="hostMaxBinary">
334 <value>' . $network->hostmaxBinary . '</value>
335 </Data>
336 <Data name="hosts">
337 <value>' . $network->numberHosts . '</value>
338 </Data>';
339
[7773]340 $line = new KMLLine();
[7775]341 $line->setID(str_replace('.', '', $network->networkDecimal));
[7773]342 $line->setName('Link: Van ' . $name . ' naar ');
[7775]343 $line->setData($data);
[7773]344 $line->setLongitude1($longitude);
345 $line->setLatitude1($latitude);
346 $this->KMLLines[] = $line;
347 }
348 }
[7725]349 }
350 }
351
352 /*
353 * Function: findInLocationFile
354 * Description: Find the $keyword in $file and return the value of $keyword, starting at $offset
355 * Parameters: string $file, string $keyword, integer $offset
356 * Returns: The value of the keyword if found, otherwise return false
357 */
358 private function findInLocationFile($file, $keyword, $offset) {
[7773]359 $start = strpos($file, $keyword, $offset) + strlen($keyword);
[7725]360 $end = strpos($file, "\n", $start);
361
362 if ($start && $end && ($start < $end)) {
363 return substr($file, $start, $end - $start);
364 } else {
365 return false;
366 }
367 }
368
369 /*
370 * Function: parseStatusFile
[7765]371 * Description: Parse the node status file updating or adding KMLNode objects to the current KMLFile object
[7725]372 * Parameters: string $file
373 * Returns: true is successfull, otherwise false
374 */
375 public function parseStatusFile($file) {
376 $fileContents = explode("\r\n", $file);
377
378 if ($fileContents[0] != KMLFile::$fileFirst) {
379 trigger_log(SYSLOG_WARNING, 'Contents of file do not match with template of first line', __FILE__, __LINE__);
380 }
381
382 // For loop for all the lines in the file. Skipping first line (headers) and last line (blank)
383 $linesCount = count($fileContents);
384 for ($i = 1; $i < $linesCount - 1; $i++) {
385 $lineContent = explode(',', $fileContents[$i]);
[7776]386 $lineContent[1] = str_replace('CNode', '', $lineContent[1]);
387 echo $lineContent[1];
[7725]388
389 if (count($lineContent) != count($this->fileContent)) {
390 trigger_log(LOG_WARNING, 'Contents of the file do not match with template of lines on line "' . $i . '"', __FILE__, __LINE__);
391 continue;
392 }
393
394 // Checking for valid entries on this line
395 for ($j = 0; $j < 8; $j++) {
396 try {
397 switch ($this->fileContent[$j]) {
398 case 'string':
399 $lineContent[$j] = (string) $lineContent[$j];
400 break;
401 case 'int':
402 $lineContent[$j] = (int) $lineContent[$j];
403 break;
404 case 'double':
405 $lineContent[$j] = (double) $lineContent[$j];
406 break;
407 default:
408 break;
409 }
410 } catch (Exception $err) {
411 trigger_log(SYSLOG_WARNING, 'The value "' . $j . '" on line "' . $i . '" is not valid, skipping to next line', __FILE__, __LINE__);
412 continue;
413 }
414 }
415
416 // Creating a string with the complete description of the node using all data in the status file
[7775]417 $dataStatus = '
418 <Data name="type">
419 <value>' . $lineContent[0] . '</value>
420 </Data>
421 <Data name="hostName">
422 <value>' . $lineContent[1] . '</value>
423 </Data>
424 <Data name="hasBeenChecked">
425 <value>' . $lineContent[2] . '</value>
426 </Data>
427 <Data name="checkExecutionTime">
428 <value>' . $lineContent[3] . '</value>
429 </Data>
430 <Data name="currentState">
431 <value>' . $lineContent[4] . '</value>
432 </Data>
433 <Data name="lastHardState">
434 <value>' . $lineContent[5] . '</value>
435 </Data>
436 <Data name="lastCheck">
437 <value>' . $lineContent[6] . '</value>
438 </Data>
439 <Data name="problemHasBeenAcknowledged">
440 <value>' . $lineContent[7] . '</value>
441 </Data>';
[7725]442
[7775]443 $style = NODE_RED;
444 if ($lineContent[4] == NODE_STATUS_ERROR) {
445 $style = NODE_ORANGE;
446 } elseif ($lineContent[4] == NODE_STATUS_UP) {
447 $style = NODE_GREEN;
448 }
449
[7765]450 if ($placemarkPosition = $this->getNodeByName($lineContent[1])) {
[7725]451 // Updating an excisting placemark
[7775]452 $this->KMLNodes[$placemarkPosition]->setDataStatus($dataStatus);
453 $this->KMLNodes[$placemarkPosition]->setStyle($style);
[7725]454 } else {
455 // Adding a new placemark
[7765]456 $placemark = new KMLNode();
[7725]457 $placemark->setID($lineContent[1]);
458 $placemark->setName($lineContent[1]);
[7775]459 $placemark->setDataStatus($dataStatus);
460 $placemark->setStyle($style);
[7765]461 $this->addNode($placemark);
[7725]462 }
463 }
464 }
465}
[7627]466?>
Note: See TracBrowser for help on using the repository browser.