예제 #1
0
 public static function json_cluster($controller, $edit_report_path = 'admin/reports/edit/', $list_reports_path = "admin/adminmap_reports/index/", $on_the_back_end = true, $extra_where_text = "", $joins = array(), $custom_category_to_table_mapping = array())
 {
     //$profiler = new Profiler;
     // Database
     $db = new Database();
     $json = "";
     $json_item = "";
     $json_array = array();
     $color = Kohana::config('settings.default_map_all');
     $default_color = Kohana::config('settings.default_map_all');
     $icon = "";
     $logical_operator = "or";
     $show_unapproved = "3";
     //1 show only approved, 2 show only unapproved, 3 show all
     if ($on_the_back_end) {
         //figure out if we're showing unapproved stuff or what.
         if (isset($_GET['u']) and !empty($_GET['u'])) {
             $show_unapproved = (int) $_GET['u'];
         }
         $approved_text = "";
         if ($show_unapproved == 1) {
             $approved_text = "incident.incident_active = 1 ";
         } else {
             if ($show_unapproved == 2) {
                 $approved_text = "incident.incident_active = 0 ";
             } else {
                 if ($show_unapproved == 3) {
                     $approved_text = " (incident.incident_active = 0 OR incident.incident_active = 1) ";
                 }
             }
         }
     } else {
         $approved_text = "incident.incident_active = 1 ";
         $show_unapproved = 1;
     }
     //should we color unapproved reports a different color?
     $color_unapproved = 2;
     if (isset($_GET['uc']) and !empty($_GET['uc'])) {
         $color_unapproved = (int) $_GET['uc'];
     }
     if (isset($_GET['lo']) and !empty($_GET['lo'])) {
         $logical_operator = $_GET['lo'];
     }
     // Get Zoom Level
     $zoomLevel = (isset($_GET['z']) and !empty($_GET['z'])) ? (int) $_GET['z'] : 8;
     //$distance = 60;
     $distance = (10000000 >> $zoomLevel) / 100000 / 2.5;
     // Category ID
     $is_all_categories = false;
     $category_ids = array();
     if (isset($_GET['c']) and !empty($_GET['c'])) {
         $category_ids = explode(",", $_GET['c'], -1);
         //get rid of that trailing ";"
     } else {
         $category_ids = array("0");
     }
     if (count($category_ids) == 0 || $category_ids[0] == '0') {
         $is_all_categories = true;
     }
     // Start Date
     $start_date = (isset($_GET['s']) and !empty($_GET['s'])) ? (int) $_GET['s'] : "0";
     // End Date
     $end_date = (isset($_GET['e']) and !empty($_GET['e'])) ? (int) $_GET['e'] : "0";
     // SouthWest Bound
     $southwest = (isset($_GET['sw']) and !empty($_GET['sw'])) ? $_GET['sw'] : "0";
     $northeast = (isset($_GET['ne']) and !empty($_GET['ne'])) ? $_GET['ne'] : "0";
     $filter = "";
     $filter .= $start_date ? " AND incident.incident_date >= '" . date("Y-m-d H:i:s", $start_date) . "'" : "";
     $filter .= $end_date ? " AND incident.incident_date <= '" . date("Y-m-d H:i:s", $end_date) . "'" : "";
     if ($southwest and $northeast) {
         list($latitude_min, $longitude_min) = explode(',', $southwest);
         list($latitude_max, $longitude_max) = explode(',', $northeast);
         $filter .= " AND location.latitude >=" . (double) $latitude_min . " AND location.latitude <=" . (double) $latitude_max;
         $filter .= " AND location.longitude >=" . (double) $longitude_min . " AND location.longitude <=" . (double) $longitude_max;
     }
     //stuff john just added
     $color = self::merge_colors($category_ids, $custom_category_to_table_mapping);
     //$incidents = reports::get_reports($category_ids, $approved_text, $filter, $logical_operator);
     $incidents = reports::get_reports_list_by_cat($category_ids, $approved_text, $filter . " " . $extra_where_text, $logical_operator, "incident.incident_date", "asc", $joins, $custom_category_to_table_mapping);
     // Create markers by marrying the the stuff together
     $markers = array();
     $last_incident = null;
     $curr_id = "no idea";
     $isnt_first = false;
     $cat_names = array();
     $colors = array();
     foreach ($incidents as $incident) {
         if ($isnt_first && $curr_id != $incident->id) {
             //echo $last_incident->incident_title."\n\r".Kohana::debug($cat_names)."\r\n\r\n";
             $incident_info = array("incident" => $last_incident, "colors" => $colors, "cat_names" => $cat_names);
             array_push($markers, $incident_info);
             //reset the arrays
             $cat_names = array();
             $colors = array();
         }
         $last_incident = $incident;
         $curr_id = $incident->id;
         $isnt_first = true;
         $incident_array = $incident->as_array();
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         //Now we try and figure out which category this report was matched to
         //////////////////////////////////////////////////////////////////////////////////////////////////////////////
         if (isset($incident_array["is_parent"]) && $incident_array["is_parent"] != 0) {
             //echo $incident->incident_title." parent matched\r\n";
             $cat_names[$incident->parent_id] = $incident->parent_title;
             $colors[$incident->parent_id] = $incident->parent_color;
         } elseif (isset($incident_array["is_child"]) && $incident_array["is_child"] != 0) {
             //echo $incident->incident_title." kid matched\r\n";
             $cat_names[$incident->cat_id] = $incident->category_title;
             $colors[$incident->cat_id] = $incident->color;
         }
         //now the fun part, loop through all the custom categories
         foreach ($custom_category_to_table_mapping as $name => $custom_cat) {
             if (isset($incident_array["is_" . $name . "_parent"]) && $incident_array["is_" . $name . "_parent"] != 0) {
                 //echo $incident->incident_title." $name parent matched\r\n";
                 $cat_names[$name . "_" . $incident_array[$name . "_parent_cat_id"]] = $incident_array[$name . "_parent_title"];
                 $colors[$name . "_" . $incident_array[$name . "_parent_cat_id"]] = $incident_array[$name . "_parent_color"];
             } elseif (isset($incident_array["is_" . $name . "_child"]) && $incident_array["is_" . $name . "_child"] != 0) {
                 //echo $incident->incident_title." $name kid matched. With color: ".$incident_array[$name."_color"]."\r\n";
                 $cat_names[$name . "_" . $incident_array[$name . "_cat_id"]] = $incident_array[$name . "_title"];
                 $colors[$name . "_" . $incident_array[$name . "_cat_id"]] = $incident_array[$name . "_color"];
             }
         }
     }
     //end loop
     //catch the last report
     if ($last_incident != null) {
         //echo "last one ".$last_incident->incident_title."\n\r".Kohana::debug($cat_names)."\r\n\r\n";
         $incident_info = array("incident" => $last_incident, "colors" => $colors, "cat_names" => $cat_names);
         array_push($markers, $incident_info);
     }
     //echo "___________________________________________________\r\n";
     $clusters = array();
     // Clustered
     $singles = array();
     // Non Clustered
     // Loop until all markers have been compared
     while (count($markers)) {
         $marker_info = array_pop($markers);
         $colors = $marker_info["colors"];
         $cat_names = $marker_info["cat_names"];
         $marker = $marker_info["incident"];
         //echo "\r\nLooking for clusters around ". $marker->incident_title. "\r\n";
         $cluster = array();
         $category_colors = array();
         //all the colors that were seen while making a cluster
         $category_count = array();
         //how many times we've seen a category while making this cluster
         $category_names = array();
         //all the names
         $contains_nonactive = false;
         // Compare marker against all remaining markers.
         foreach ($markers as $key => $target_info) {
             $target_colors = $target_info["colors"];
             $target_cat_names = $target_info["cat_names"];
             $target = $target_info["incident"];
             $pixels = abs($marker->location->longitude - $target->location->longitude) + abs($marker->location->latitude - $target->location->latitude);
             // If two markers are closer than defined distance, remove compareMarker from array and add to cluster.
             if ($pixels < $distance) {
                 //echo "\tFound cluster match with ". $target->incident_title. "\r\n";
                 unset($markers[$key]);
                 $cluster[] = $target;
                 //check if the colors and category names have been accounted for
                 if (!$is_all_categories) {
                     foreach ($target_colors as $cat_id => $target_color) {
                         //echo "\t\t".$target->incident_title. " has category: ".$target_cat_names[$cat_id]."\r\n";
                         //colors
                         $category_colors[$cat_id] = $target_color;
                         //name
                         $category_names[$cat_id] = $target_cat_names[$cat_id];
                         //count
                         if (isset($category_count[$cat_id])) {
                             $category_count[$cat_id] = $category_count[$cat_id] + 1;
                         } else {
                             $category_count[$cat_id] = 1;
                         }
                     }
                     //end loop
                 }
                 //end if
                 //check if this is a unapproved report
                 if ($target->incident_active == 0) {
                     $contains_nonactive = true;
                 }
             }
         }
         // If a marker was added to cluster, also add the marker we were comparing to.
         if (count($cluster) > 0) {
             $cluster[] = $marker;
             //check if the colors and category names have been accounted for
             if (!$is_all_categories) {
                 foreach ($colors as $cat_id2 => $marker_color) {
                     //echo "\t\t".$marker->incident_title. " has category: ".$cat_names[$cat_id2]."\r\n";
                     //colors
                     $category_colors[$cat_id2] = $marker_color;
                     //name
                     $category_names[$cat_id2] = $cat_names[$cat_id2];
                     //count
                     if (isset($category_count[$cat_id2])) {
                         $category_count[$cat_id2] = $category_count[$cat_id2] + 1;
                     } else {
                         $category_count[$cat_id2] = 1;
                     }
                 }
                 //end loop
             }
             //end if
             //check if this is a unapproved report
             if ($marker->incident_active == 0) {
                 $contains_nonactive = true;
             }
             if ($contains_nonactive) {
                 $clusters[] = array('contains_nonactive' => TRUE, 'cluster' => $cluster, 'category_count' => $category_count, 'category_names' => $category_names, 'category_colors' => $category_colors);
             } else {
                 $clusters[] = array('contains_nonactive' => FALSE, 'cluster' => $cluster, 'category_count' => $category_count, 'category_names' => $category_names, 'category_colors' => $category_colors);
             }
         } else {
             //echo "putting in single ". $marker_info["incident"]->incident_title."\n\r".Kohana::debug($marker_info["cat_names"])."\r\n\r\n";
             $singles[] = $marker_info;
         }
     }
     //echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n\r\n";
     $i = 0;
     // Create Json
     foreach ($clusters as $cluster_alpha) {
         $cluster = $cluster_alpha['cluster'];
         $cluster_cat_colors = $cluster_alpha['category_colors'];
         $cluster_cat_names = $cluster_alpha['category_names'];
         $cluster_cat_count = $cluster_alpha['category_count'];
         //make category description string
         $category_str = "";
         if (!$is_all_categories && $logical_operator != "and") {
             $count = 0;
             foreach ($cluster_cat_count as $cat_id => $cat_count) {
                 $count++;
                 if ($count > 1) {
                     //$category_str .= "<br/> ";
                 }
                 $category_str .= "<li>" . $cluster_cat_names[$cat_id] . " (" . $cat_count . ")</li>";
             }
             $category_str = "<br/><br/> Categories in this cluster (number of reports):<ul>" . $category_str . "</ul>";
         }
         $contains_nonactive = $cluster_alpha['contains_nonactive'];
         // Calculate cluster center
         $bounds = self::_calculateCenter($cluster);
         $cluster_center = $bounds['center'];
         $southwest = $bounds['sw'];
         $northeast = $bounds['ne'];
         // Number of Items in Cluster
         $cluster_count = count($cluster);
         $json_item = "{";
         $json_item .= "\"type\":\"Feature\",";
         $json_item .= "\"properties\": {";
         $categories_str = implode(",", $category_ids);
         //$json_item .= "\"name\":\"" . str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . $list_reports_path."?c=".$categories_str."&sw=".$southwest."&ne=".$northeast."&lo=".$logical_operator."&u=".$show_unapproved.">" . $cluster_count . " Reports</a> ".$category_str)) . "\",";
         $json_item .= "\"link\":\"" . str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . $list_reports_path . "?c=" . $categories_str . "&sw=" . $southwest . "&ne=" . $northeast . "&lo=" . $logical_operator . "&u=" . $show_unapproved . ">" . $cluster_count . " Reports</a> " . $category_str)) . "\",";
         $json_item .= "\"category\":[0], ";
         if ($contains_nonactive && $color_unapproved == 2) {
             $json_item .= "\"color\": \"000000\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } elseif ($is_all_categories) {
             $json_item .= "\"color\": \"" . $default_color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } elseif ($logical_operator == "and") {
             $json_item .= "\"color\": \"" . $color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } else {
             $dot_color = self::merge_colors_for_dots($cluster_cat_colors);
             $json_item .= "\"color\": \"" . $dot_color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         }
         $json_item .= "\"timestamp\": \"0\", ";
         $json_item .= "\"count\": \"" . $cluster_count . "\"";
         $json_item .= "},";
         $json_item .= "\"geometry\": {";
         $json_item .= "\"type\":\"Point\", ";
         $json_item .= "\"coordinates\":[" . $cluster_center . "]";
         $json_item .= "}";
         $json_item .= "}";
         array_push($json_array, $json_item);
     }
     //do singles
     foreach ($singles as $single_info) {
         $single = $single_info["incident"];
         $single_colors = $single_info["colors"];
         $single_cat_names = $single_info["cat_names"];
         //echo $single->incident_title."\n\r".Kohana::debug($single_cat_names)."\r\n\r\n";
         $category_description = "";
         if (!$is_all_categories && $logical_operator != "and") {
             $count = 0;
             foreach ($single_cat_names as $cat_name) {
                 $count++;
                 if ($count > 1) {
                     $category_description .= ", ";
                 }
                 $category_description .= $cat_name;
             }
             $category_description = "<br/><br/>Falls under categories:<br/>" . $category_description;
         }
         $json_item = "{";
         $json_item .= "\"type\":\"Feature\",";
         $json_item .= "\"properties\": {";
         //$json_item .= "\"name\":\"" .date("n/j/Y", strtotime($single->incident_date)).":<br/>". str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . $edit_report_path . $single->id . "/>".str_replace('"','\"',$single->incident_title)."</a>".$category_description)) . "\",";
         $json_item .= "\"link\":\"" . date("n/j/Y", strtotime($single->incident_date)) . ":<br/>" . str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . $edit_report_path . $single->id . "/>" . str_replace('"', '\\"', $single->incident_title) . "</a>" . $category_description)) . "\",";
         $json_item .= "\"category\":[0], ";
         //check if it's a unapproved/unactive report
         if ($single->incident_active == 0 && $color_unapproved == 2) {
             $json_item .= "\"color\": \"000000\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } elseif ($is_all_categories) {
             $json_item .= "\"color\": \"" . $default_color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } elseif ($logical_operator == "and") {
             $json_item .= "\"color\": \"" . $color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         } else {
             $dot_color = self::merge_colors_for_dots($single_colors);
             $json_item .= "\"color\": \"" . $dot_color . "\", \n";
             $json_item .= "\"icon\": \"" . $icon . "\", \n";
         }
         $json_item .= "\"timestamp\": \"0\", ";
         $json_item .= "\"count\": \"" . 1 . "\"";
         $json_item .= "},";
         $json_item .= "\"geometry\": {";
         $json_item .= "\"type\":\"Point\", ";
         $json_item .= "\"coordinates\":[" . $single->location->longitude . ", " . $single->location->latitude . "]";
         $json_item .= "}";
         $json_item .= "}";
         array_push($json_array, $json_item);
     }
     $json = implode(",", $json_array);
     header('Content-type: application/json');
     $controller->template->json = $json;
 }