<?
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ALRoute
//
// Author: Christian Mähler
// Version: 9.5
// Last update: April 2003
//
// Base library for map&guide routing functionalty
//
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//++++++++++ INCLUDE ++++++++++++++++++++++++++//"
@include_once(dirname(__FILE__)."/albasic.inc.php");
//+++++++++++++++++++++++++++++++++++++++++++++//"

class ALRoute extends ALBasic
{
    // public variables for reading and writing data

    var $RouteStation;				 // adding stations to the routing request
															 // NOTE: use BfAddParam to add STATION<x> 
															 // to the request
    var $RouteInfo;            // show routing list?
    var $AddToMap;             // add address layer to map?
    var $ParaTargetMap;        //	show map of target area?
    var $ParaTargetBorder;     // radius for target map
    var $RouteNodeLevel;       // not longer supported
    var $RouteDetailLimit;     // not longer supported
    var $FixHour;              // hour to arrive/depart 
    var $FixMinute;            // minute to arrive/depart
    var $RouteAdvancedField;   // add aadditional parameters to the request 
															 // NOTE: please use the BFAddParam statement
															 // instead, because RouteAdvancedField is a very
															 // old way of adding parameter 		
    var $RouteResponse;				 // answer of routing object
    var $RouteScan;            // array of three address layer to scan
    var $Vehiclename;					 // choose vehiclename  
    var $DistanceAsMile;			 // get distance in miles? if yes, recalculate values
    var $RouteDistance;        // distance of route computed
    var $RouteTime;            // time of route computed
    var $RowCount;             // number of route list entries
    
		// private variables for internal route object usage

    var $numRowBeginTCP;      // for function ReadRow() used ans set in GetRowCount()
    var $numRowBeginBC;       // for function ReadRow() used and set in GetRowCount()
    var $row;                 // content of current row, sparated by "|"
    var $rowPrio;             // priority of currently selected row
    var $Result;							// result of route object


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ALRoute - Constructor
// set default parameters to object

function ALRoute()
{
 		  $this->ALBasic();
	 		$this->NR_ROUTEREQUEST=3;			// base number for server ACTION
			$this->NR_ROUTEREQUEST_ROUTEID=30;			
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// GetRowBegin
// get base element for "node" from answer file ANS

function GetRowBegin()
{
   for ($i=0; $i<=count($this->BPTCPAnswer["ANS"]);$i++)
   {
     $search = explode("~", $this->BPTCPAnswer["ANS"][$i]);
     if ($search[0] == "RESULT")
     {
         $this->numRowBeginTCP = $i-1;
 	  		 $this->Log_to_file("ALRoute.GetRowBegin: passed successfully");
         return 0;
     }
   }
} //GetRowBegin()

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// KmToMile
// set kilometer to mile, rounded to one decimal

function KmToMile($distance)
{
   return round($distance/1.60934,1);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// CheckRes
// check result and set rowcount
  
function CheckRes()
{
  // get first node
  $this->GetRowBegin();

	// get routing distance										 
  $this->RouteDistance = $this->BFGetParam($this->eATAns, "SERVER", "DISTTODRIVE", 0);
	
  // distance in miles?
  if ($this->DistanceAsMile) 
		 $this->RouteDistance = $this->KmToMile($this->RouteDistance);
		 
  // get driving time
	$this->RouteTime = $this->BFGetParam($this->eATAns, "SERVER", "TIMETODRIVE", 0);
  
  // check whether station passed to server were geocoded
	// that means, that COR section has additional information
	
	$i = 1;
  $erg = $this->BFGetParam($this->eATCor, "VORSCHLAG".$i , "NUMDATA", "");
	
	// check every station in COR section if applicable
  while ($erg!="")
  {
      if ($erg<1)
      {
         $this->RouteResponse .= "Warning: Station" . $i .  " could not be found <br>";
				 $this->Log_to_file("ALRoute.CheckRes: Station passed for geocoding wasn't found");
         return $this->BPRouteStat_NoLocFound;
      }
      $i++;
      $erg = $this->BFGetParam($this->eATCor, "VORSCHLAG".$i , "NUMDATA", "");
  }

	// check error messages from server
  $erg = $this->BFGetParam($this->eATAns, "SERVER" , "ERROR1", "");
  if ($erg != "")
  {
    $this->RouteResponse = "Error: Error while routing";
		$this->Log_to_file("ALRoute.CheckRes: Error while Routing: " . $erg);
    return $this->BPStat_PropriError;
  }

   // take care of NodeLevel and DetailLimit 
	 // new result array is computed by checking every entry for concerning parameter
	 // NOTE: if you are using BFGetParam to read the single route list entries,
	 // the following commands can be ignored. In this case, RouteDetailLimit and
	 // NodeLevel have no effect on thee request/answer
	 
   $answer = $this->BPTCPAnswer;
   $split  = "~";
   $begin  = $this->numRowBeginTCP;
   $num    = 2;

   $ArraySize = count($answer["ANS"]);
   $ArraySize = $ArraySize-1; //with TCP/IP
 	 $elem = 0;

   // check RouteNodeLevel and build new answer list
   for ($i = $begin+1 ; $i<$ArraySize; $i++ )
   {
      $tmp = explode($split, $answer["ANS"][$i]);
      $rowPrio = substr($tmp[$num],0,1);

      $rowPrio = (int)$rowPrio;

      if ($rowPrio <= $this->RouteNodeLevel)
       {
         $this->Result[$elem] = $answer["ANS"][$i];
         $elem++;
       }
   }

	 // count new number of route list entries
   $this->RowCount = count($this->Result);

   // check RouteDetaillimit and build new answer list
   if  ($this->RouteNodeLevel > 2)
      if ( count($this->Result) > $this->RouteDetailLimit )
      {
         $elem = 0;
         for ($i = 0; $i<count($this->Result);$i++)
         {
           $tmp = explode($split, $this->Result[$i]);
           $rowPrio = substr($tmp[$num] ,0,1);

           if ($rowPrio < 3 )
            {
               $this->ResultDetail[$elem] = $this->Result[$i];
               $elem++;
            }
          } // end for
          $this->RowCount = count($this->ResultDetail);
      }
			
			$this->Log_to_file("ALRoute.CheckRes: Passed successfully");
			
	 return $this->BPStat_Success;

}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RouteLogicalRect
// return RouteLogicalRect

function RouteLogicalRect()
{
 		return $this->BFGetParam($this->eATAns, "SERVER","LOGICALRECT","");
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// TargetLogicalRect
// return TargetLogicalRect

function TargetLogicalRect()
{
 		return $this->BFGetParam($this->eATAns, "SERVER","LOGICALTARGETRECT","");
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ReadRow
// read next row of station list
// NOTE: please use BFGetParam instead for reading every single line
// of the route info, because this is an old function

function ReadRow($numRow)
{
    if  (($this->RouteNodeLevel > 2) and (count($this->Result) > $this->RouteDetailLimit))
        $tmp = explode("~", $this->ResultDetail[$numRow] );
    else
        $tmp = explode("~", $this->Result[$numRow] );

    $this->row = $tmp[2];
		$this->Log_to_file("ALRoute.ReadRow: Passed successfully. RowNumber: " . $numRow);		
    return substr($tmp[2],0,1);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// FieldValue
// return a fieldvalue of the row read by ReadRow; first column is 0
// NOTE: please use BFGetParam instead for reading every single line
// of the route info, because this is an old function

function FieldValue($fieldNum)
{
     $tmp = explode("|", $this->row);
		 $this->Log_to_file("ALRoute.FieldValue: Passed successfully. FieldNum: " . $fieldNum);				 
     if ($fieldNum == 2 && $this->DistanceAsMile)  
  		return round($this->KmToMile($tmp[$fieldNum-1]), 1);
     return $tmp[$fieldNum-1];
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// SetOrder
// build server request according to parameter set by user

function SetOrder()
{
   $this->BPRequest["SERVER"]["ACTION"] = 3;
	 $this->BPRequest["CLIENT"]["REQUEST"] =  "TRUE";
	 $this->BPRequest["CLIENT"]["MAPSBYSTREAM"] =  (($this->BPMapsByStream)  ? "TRUE" : "FALSE");
	
	 // add every single station set to RouteStation array
	 // NOTE: if you are using BFAddParam to add the STATION<x>, this loop
	 // will be ignored
	 
   for ($i=1; $i<=count($this->RouteStation); $i++)
    if (!empty($this->RouteStation[$i]))
       $this->BPRequest["CLIENT"]["STATION" . $i] = $this->RouteStation[$i];

   if (isset($this->RouteInfo))         
	 		$this->BPRequest["CLIENT"]["ROUTEINFO"]    = (($this->RouteInfo) ? "true" : "false");
   if (isset($this->AddToMap))          
	 		$this->BPRequest["CLIENT"]["ADDTOMAP"]     = (($this->AddToMap) ? "true" : "false");
   if (isset($this->ParaTargetMap))     
	 		$this->BPRequest["CLIENT"]["TARGETMAP"]    = (($this->ParaTargetMap) ? "true" : "false");
   if (!empty($this->ParaTargetBorder)) 
	 		$this->BPRequest["CLIENT"]["TARGETBORDER"] = $this->ParaTargetBorder;
   if (!empty($this->FixHour))          
	 		$this->BPRequest["CLIENT"]["FIXHOUR"]      = $this->FixHour;
   if (!empty($this->FixMinute))        
	 		$this->BPRequest["CLIENT"]["FIXMINUTE"]    = $this->FixMinute;
   if (!empty($this->VEHICLENAME))      
	 		$this->BPRequest["CLIENT"]["VEHICLENAME"]  = $this->Vehiclename;

   // set advancedfield parameter if applicable
	 // NOTE: if you are using BFAddParam to add single  
	 // parameters to the request, this loop can be ignored
	 /*
   for ($i=0; $i<count($this->RouteAdvancedField); $i++)
     if (!empty($this->RouteAdvancedField[$i]))
     {
       $arr = explode("=", $this->RouteAdvancedField[$i]);
       $this->BPRequest["CLIENT"][$arr[0]]= $arr[1];
     }
   */
   // set scan parameter if applicable
	 // NOTE: if you are using BFAddParam to add single  
	 // parameters to the request, this loop can be ignored
	 
   if (!empty($this->RouteScan[1]))
     for ($i = 1; $i<=3; $i++)
     {
       	 $scan = "SCAN". $i;
       	 if (!empty($this->RouteScan[$i])) 
				 		$this->BPRequest["CLIENT"][$scan] = $this->RouteScan[$i];
     } 

		 $this->Log_to_file("ALRoute.SetOrder: Passed successfully. ");		 
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RouteRequest
// Performs Request

function RouteRequest()
{
	 	if ($this->BPRequest["CLIENT"]["ROUTEID"]=="")
				 $rnr=$this->NR_ROUTEREQUEST;
			else				 
				 $rnr=$this->NR_ROUTEREQUEST_ROUTEID;				

  		// check param
	    if ($this->BPStat_Error == $this->BFCheckParam($this->NR_ROUTEREQUEST)  || ($this->BPMapsByStream && $this->BPStreamDirectory=='')) 
		  {
		 		$this->Log_to_file("ALRoute.RouteRequest: Too less parameters ");
		    return $this->BPStat_Error;
		  }

			// set request type
      $this->SetOrder();

			// build request
      $request = $this->BFBuildOrder(); 
      
			// send request
      $answerlength=$this->BFWriteOrder($request);

			if($answerlength>45)
		  {
     	   // receive answer
         $this->BFReadALSAnswer($rnr);
 	       // return result code
         return $this->CheckRes();
		  }
		  else
		     return $this->BPStat_Error;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// CorridorRequest
// same as RouetRequest, but with additional parameters

function CorridorRequest()
{
   		return $this->RouteRequest();
}

}//class

 
