Solved

php: how to build array in foreach loop combining data under one unique name

Posted on 2011-03-15
4
378 Views
Last Modified: 2012-05-11
I am using simplexml_load_string to get water stream flow data from USGS. I am able to get streamflow and gage information and output it as seen here:
http://beta.realvail.com/feed/water

The feed is built from this url:
http://waterservices.usgs.gov/nwis/iv?sites=09058000,09058030,09070500,09071750,09085100,09085150,09095500,09106150,09163500,09180500,09380000,09402500,09521100&parameterCd=00060,00065


Unfortunately, the returned data does not lump the two parameters under a single site name. Each variable tree contains a duplicate site name. I would like to build an array so that the the site name is unique and has either two attributes or the site name contains the two parameters as objects. I want to access them like: $siteName, $siteName->streamflow and $siteName->gage.

Does anyone know how to build an array in a foreach loop to combine data under a unique site name? Note: My examples are simply echoing the variables not building the array.

The output desired is an ARRAY:
$siteName = COLORADO RIVER BELOW GLENWOOD SPRINGS, CO.
$siteName->streamflow = 1,840 Streamflow, ft³/s
$siteName->gage = 4 Gage height, ft

Thanks!


$url = 'http://waterservices.usgs.gov/nwis/iv?sites=09058000,09058030,09070500,09071750,09085100,09085150,09095500,09106150,09163500,09180500,09380000,09402500,09521100&parameterCd=00060,00065';
		// Fetch the data
		$data = trim(file_get_contents($url));
		if (!$data)
		{
		 	echo 'Error retrieving: ' . $url;
		 	exit;
		}
		
		// Remove the namespace prefix for easier parsing
		$data = str_replace('ns1:','', $data);
		// var_dump($data); die;
		// Load the XML returned into an object for easy parsing
		$obj = simplexml_load_string($data);
		if ($obj === FALSE)
		{
		 	echo 'Unable to parse USGS\'s XML';
		 	exit;
		}
		
		// var_dump($obj);
		// GET INFORMATION FROM THE OBJECT
		$names = array();
		$firstLine = 0;
		$rivers = array();
		foreach ($obj->timeSeries as $o)
		{	
			$r = $o->sourceInfo; 
		  	$var = $o->variable;
			$val = $o->values;
			
			$n = (string)$r->siteName;
			$siteCode = (string)$r->siteCode;
			if(!in_array($n,$names)) {
				array_push($names,$n);
				$firstLine = 1;
			}
			
			//var_dump($name); die;
			$g = $r->geoLocation;
			$geo = $g->geogLocation;
			$lat = (string)$geo->latitude;
			$long = (string)$geo->longitude;
			
			$varCode = (string)$var->variableCode;
			$varName = (string)$var->variableName;
			$varName = trim($varName);
			$varDescription = (string)$var->variableDescription;
			
			if($val->value['dateTime'] <> '') {
				$reading = $val->value['dateTime'];
				$displayed = substr($reading,0,10);
				$time = substr($reading,11,5);
				$tz = substr($reading,23);
				$date = $displayed . ' ' . $time . ' ' . $tz;
			} else {
				$date = '-';
			}
			
			$value = number_format((float) $val->value);
			if (($value == '-999,999') || ($value == '0') || (empty($value) || ($value == ''))) {
				$value = 'n/a';
			}
			//var_dump($o);
			
		    // REPORT THE CONDITIONS
			if($firstLine == 1) {
				echo $n . '<br />';
			}
		    echo "$value $varName<br />";
			if($firstLine == 0) {
				echo '<br />';
			}
			$firstLine = 0;
			
			/* Build array ? NOT SURE HOW TO DO THIS - VARIABLES aren't set to streamflow or gage specifically
			if($firstLine == 1) {
				$buildReport = array_push($names,n);
			}
			$buildReport = array_push($names,n,
				array(
					'siteName'=>$n,
					'streamflow'=>$value,
					'gage'=>$gage
				));
			*/
		}

Open in new window

0
Comment
Question by:kent3800
  • 3
4 Comments
 
LVL 8

Accepted Solution

by:
Rik-Legger earned 500 total points
Comment Utility
Do you mean something like this:

			${$n} = array(
				'siteName'=>$n,
				'streamflow'=>$value,
				'gage'=>$gage
			);
			${$n} = (object) ${$n};
			echo ${$n}->siteName;
			echo ${$n}->streamflow;

Open in new window


But your question is a little bit confusing because your are speaking of an ARRAY and given me an object notation:

The output desired is an ARRAY:
$siteName = COLORADO RIVER BELOW GLENWOOD SPRINGS, CO.
$siteName->streamflow = 1,840 Streamflow, ft³/s
$siteName->gage = 4 Gage height, ft
0
 
LVL 4

Author Comment

by:kent3800
Comment Utility
Isn't object notation inside an array? The ultimate goal is to filter out the $siteName from all of the variables and have only one $siteName that contains the variables. The problem exists because the xml doesn't group the variables with the site names or... actually it duplicates the $siteName.

Does that make sense?
0
 
LVL 4

Author Comment

by:kent3800
Comment Utility
The problem with your code is that the $streamflow and the $gage are both being returned by $value because each location is duplicated so the values are run through the foreach loop twice. That is why I added the $firstLine logic to determine if it is the first time in the foreach for a single location. If it is the second time through for the same location, then I just echo the $value for that loop.

I need to figure out how to combine the two loops under the one unique site name...

Thanks!
0
 
LVL 4

Author Comment

by:kent3800
Comment Utility
With this URL for the single location of COLORADO RIVER NEAR KREMMLING, CO:
http://waterservices.usgs.gov/nwis/iv?sites=09058000&parameterCd=00060,00065

you can see this:
<ns1:variableCode network="NWIS" vocabulary="NWIS:UnitValues" default="true" variableID="0">00060</ns1:variableCode>

and this:
<ns1:variableCode network="NWIS" vocabulary="NWIS:UnitValues" default="true" variableID="0">00065</ns1:variableCode>

each in its own timeSeries section with the same location names...

thanks for any help!
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
This article discusses four methods for overlaying images in a container on a web page
The viewer will learn how to count occurrences of each item in an array.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now