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; }