Нахождение ближайшей точки данных и данных о солнечном свете в php - PullRequest
0 голосов
/ 03 октября 2011

У меня большая проблема. Проблема в следующем

1) У меня есть файл .dat (файл данных, используемый для хранения данных). Это файл размером 25 МБ, который содержит более 200 тысяч строк широты и долготы. Пример одной из таких строк:

-59,083 -26,583 9,4 5,2 3,3 4,3 8,1 6,6 5,3 8,4 8,3 10,0 9,1 5,1

Данные формируют данные о широте, долготе и солнечном свете (часы) в январе, феврале ... и т. Д. В декабрь.

У меня более 200К строк, как указано выше.

Моя задача состоит в том, чтобы рассчитать солнечные часы в определенной широте и долготе. Предположим, у меня широта = 3,86082 и долгота = 100,50509; Вторая проблема заключается в том, что у меня не будет точного совпадения заданной широты и долготы с теми, которые есть в файле. Прежде всего, мне нужно найти ближайшую точку, а затем вычислить солнечные часы.

Я использую следующий код для вычисления ближайшей точки. Но это занимает огромное время из-за большого объема данных в файле

$file_name='grid_10min_sunp.dat';

$handle = fopen($file_name, "r");

$lat1=13.86082;
$lan1=100.50509;

$lat_lon_sunshines = make_sunshine_dict($file_name);

$closest = 500;
for($c=0;$c<count($lat_lon_sunshines);$c++)
{

$lat2=$lat_lon_sunshines[$c]['lat'];
$lan2=$lat_lon_sunshines[$c]['lan'];
$sunshines=$lat_lon_sunshines[$c]['sunshine'];

$lat_diff = abs(round((float)($lat1), 4)-$lat2);

if ($lat_diff < $closest)
{
    $diff = $lat_diff +  abs(round((float)($lan1), 4)-$lan2); 

     if($diff < $closest)
     {
              $closest = $diff;
            $sunshinesfinal=$sunshines;
     }      
}
$sunshines='';

}
print_r($sunshinesfinal);die;

функция make_sunshine_dict ($ file_name) также проходит по каждой строке файла и подготавливает массив следующим образом

$sunshines_dict = array();      

  $f = file_get_contents($file_name);

  $handle = fopen($file_name, "r");

  while($buffer = fgets($handle))
  {

   $tok = strtok($buffer, " \n\t");

   $lat=$tok;

   $latArray[]=$tok;

   $tok = strtok(" \n\t");

   $months = '';

   $months = array();

   for ($k = 0; $tok !== false; $k+=1) 
   {

   if($k==0)
   {
   $lan=$tok;
   $lanArray[]=$tok;
   }

   if($k!=0)
   {
        $months[] = $tok ;
         "month $k : ".$months[$k]."<br>";

   }

    $tok = strtok(" \n\t");
    }

    $data[$kkk]['lat']=$lat;
    $data[$kkk]['lan']=$lan;

    foreach($months as $m=>$sunshine)
    {


         $sunshines=array();
          $sumD = 0;

          $iteration= 31;

          for($n=1;$n<=$iteration;$n++)
          {
              $J = ($m+1)*$n; 



             $P = asin(.39795*cos(.2163108 + 2*atan(.9671396*tan(.00860*($J-186)))));



          $value=(sin(0.8333*pi/180) + sin($lat*pi/180)*sin($P))/(cos($lat*pi/180)*cos($P));

            /* $value ? ($value > 1 and 1) : $value;

             $value ? ($value < -1 and -1): $value;*/


          $D = 24 - ((24/pi) * acos($value));



           $sumD = $sumD + $D;

             }

                $sunshinesdata=(($sumD/30)*(float)($sunshine)*.01);

           $data[$kkk]['sunshine'][$m]=$sunshinesdata; 

          $sunshines='';
    }

    }
return $data;

Пожалуйста, помогите и, пожалуйста, дайте мне знать, если вам нужна дополнительная информация

И, пожалуйста, помните, я не могу использовать функцию php по умолчанию для получения информации о солнечном свете здесь, потому что я также принимаю во внимание облачность и другие факторы

Ответы [ 2 ]

0 голосов
/ 03 октября 2011

Большая часть кода выглядит неправильно (с точки зрения просто подсчета солнечных часов).Хотя, признаюсь, я заблудился относительно того, что вы делаете в функции make_sunshine_dict.

Чтобы помочь вам ускорить процесс, вы читаете свой файл дважды:

 $f = file_get_contents($file_name);
 $handle = fopen($file_name, "r"); 

Кроме того, вы можете отобразить координаты широты / долготы в сетку.Другими словами, создайте двумерный массив, в котором каждая строка и каждый столбец представляют 1 градус широты и 1 градус долготы соответственно.Как вы читаете в своем файле, сбросьте записи в правильные лат / длинное ведро в сетке.Если вам нужно найти местоположение, наиболее близкое к указанному широте / долготе, вам нужно только сравнить это местоположение с точками в его сегменте.

0 голосов
/ 03 октября 2011

Загружайте .dat в базу данных SQL каждые x интервалов в задании Cron, а затем просто запрашивайте базу данных, как всегда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...