コード例 #1
0
function generateMapImages($version)
{
    require ROOT . 'lib/GoogleMaps.php';
    $dbObj = DBPool::getInstance();
    $versionClause = " AND version={$version}";
    $logger = Logger::getInstance();
    $zipFileContents = array();
    $basePathOrig = "./data/images/{$version}/orig_static_maps/";
    $basePathConverted = "./data/images/{$version}/";
    //If the images already exist, we're re-generating. Delete the existing images
    if (file_exists($basePathConverted)) {
        Util::deleteAll($basePathConverted);
    }
    //Constants
    define("LEFT_EDGE", 28);
    define("RIGHT_EDGE", 28);
    define("TOP_EDGE", 130);
    define("BOTTOM_EDGE", 10);
    define("MAP_SIZE_X", 320);
    define("MAP_SIZE_Y", 600);
    define("FOOTER_HEIGHT", 30);
    define("FINAL_MAP_SIZE_Y", 367);
    //NOTE: The co-ordinate system starts at the top left corner for the purposes of
    //these calculations
    define("MARKER_MIN_X", LEFT_EDGE);
    define("MARKER_MAX_X", MAP_SIZE_X - RIGHT_EDGE);
    define("MARKER_MIN_Y", TOP_EDGE);
    define("MARKER_MAX_Y", FINAL_MAP_SIZE_Y - BOTTOM_EDGE);
    define("BASE_ZOOM", 13);
    define("PATH_LINE_WEIGHT", 2);
    $agencyArray = Agency::getAgencies();
    $xmlStr = '<?xml version="1.0" encoding="UTF-8" ?><body></body>';
    $xml = new SimpleXMLElement($xmlStr);
    foreach ($agencyArray as $agencyTitle => $agencyObj) {
        //if("bart" == $agencyTitle || "actransit" == $agencyTitle) { continue; }
        if ("bart" == $agencyTitle) {
            continue;
        }
        //print $agencyTitle;
        $agencyNode = $xml->addChild("agency");
        $agencyNode->addAttribute("title", $agencyObj->getTitle());
        $agencyNode->addAttribute("shortTitle", $agencyObj->getShortTitle());
        //Get the routes
        $routeArray = Route::getRoutes($agencyObj);
        foreach ($routeArray as $routeTag => $routeObj) {
            //if("1" != $routeObj->getTag()) { continue; }
            $zoom = BASE_ZOOM;
            $routeNode = $agencyNode->addChild("route");
            $routeNode->addAttribute("tag", $routeObj->getTag());
            //Calculate the co-ordinates for the center of the map
            $lat_avg = ($routeObj->getLatMin() + $routeObj->getLatMax()) / 2;
            $lon_avg = ($routeObj->getLonMin() + $routeObj->getLonMax()) / 2;
            //Calculate center as pixel coordinates in world map
            $center_y = Google_Maps::LatToY($lat_avg);
            $center_x = Google_Maps::LonToX($lon_avg);
            //Calculate center as pixel coordinates in image
            $center_offset_x = round(MAP_SIZE_X / 2);
            $center_offset_y = round(MAP_SIZE_Y / 2);
            $SW_target_y = Google_Maps::LatToY($routeObj->getLatMin());
            $SW_target_x = Google_Maps::LonToX($routeObj->getLonMin());
            $NE_target_y = Google_Maps::LatToY($routeObj->getLatMax());
            $NE_target_x = Google_Maps::LonToX($routeObj->getLonMax());
            //Fetch the last stop for all the directions in this route (with show=true)
            //NOTE: I know, very inefficient
            $dbObj->bindParams(array($routeObj->getId()));
            $dirs = $dbObj->get_results("SELECT id, tag FROM direction WHERE \n                    route_id=? AND show=true {$versionClause}");
            //if($dbObj->num_rows == 0) { print "<br />$agencyTitle - ". $routeObj->getTag() . "<br />"; }
            while (true) {
                $SW_delta_x = $SW_target_x - $center_x >> 21 - $zoom;
                $SW_delta_y = $SW_target_y - $center_y >> 21 - $zoom;
                $SW_marker_x = $center_offset_x + $SW_delta_x;
                $SW_marker_y = $center_offset_y + $SW_delta_y;
                $NE_delta_x = $NE_target_x - $center_x >> 21 - $zoom;
                $NE_delta_y = $NE_target_y - $center_y >> 21 - $zoom;
                $NE_marker_x = $center_offset_x + $NE_delta_x;
                $NE_marker_y = $center_offset_y + $NE_delta_y;
                $SW_X_LIMIT = LEFT_EDGE;
                $SW_Y_LIMIT = MAP_SIZE_Y / 2 + round((FINAL_MAP_SIZE_Y - TOP_EDGE - BOTTOM_EDGE) / 2);
                $NE_X_LIMIT = MAP_SIZE_X - RIGHT_EDGE;
                $NE_Y_LIMIT = MAP_SIZE_Y / 2 - round((FINAL_MAP_SIZE_Y - TOP_EDGE - BOTTOM_EDGE) / 2);
                if ($SW_marker_x > $SW_X_LIMIT && $SW_marker_y < $SW_Y_LIMIT && $NE_marker_x < $NE_X_LIMIT && $NE_marker_y > $NE_Y_LIMIT) {
                    break;
                } else {
                    $zoom--;
                }
            }
            //This iteration is to determine the x and y co-ordinates with the final
            //calculated zoom
            $dirIds = array();
            $dirXYDetails = array();
            foreach ($dirs as $d) {
                $dbObj->bindParams(array($d->id));
                $stopDetails = $dbObj->get_row("SELECT * FROM stop WHERE id =\n                                                (SELECT stop_id FROM stop_direction_map\n                                                    WHERE direction_id = ? {$versionClause}\n                                                    ORDER BY position DESC LIMIT 1) {$versionClause}");
                $target_y = Google_Maps::LatToY($stopDetails->latitude);
                $target_x = Google_Maps::LonToX($stopDetails->longitude);
                $delta_x = $target_x - $center_x >> 21 - $zoom;
                $delta_y = $target_y - $center_y >> 21 - $zoom;
                $marker_x = $center_offset_x + $delta_x;
                $marker_y = $center_offset_y + $delta_y;
                //print "Route:".$routeObj->getTag()." | Direction: ".$d->tag." | zoom:".($zoom)." | x:$marker_x | y:$marker_y<br />";
                $dirXYDetails[$d->tag] = array('x' => $marker_x, 'y' => $marker_y);
                $dirIds[] = $d->id;
            }
            $routeNode->addAttribute("center", "{$lat_avg},{$lon_avg}");
            $routeNode->addAttribute("zoom", $zoom);
            //Get the path co-ordinates
            //We fetch the direction with the largest number of stops and draw a
            //path for that
            $dirWithStops = $dbObj->get_results("SELECT direction_id, COUNT(*) as stops\n                                                FROM stop_direction_map\n                                                WHERE direction_id IN (" . implode(",", $dirIds) . ") {$versionClause}\n                                                    GROUP BY direction_id\n                                                    ORDER BY stops DESC");
            //$dbObj->debug();
            $dirStopsArray = array();
            foreach ($dirWithStops as $dirStops) {
                $skipCondition = $dirStops->stops % 2 == 0 ? " AND mod(b.position, 2) = 0 " : " AND mod(b.position, 2) = 1 ";
                $stopsForPath = $dbObj->get_results("SELECT a.tag, b.position, a.latitude, a.longitude\n                                                        FROM stop AS a, stop_direction_map AS b\n                                                        WHERE a.id=b.stop_id AND a.id IN\n                                                            (SELECT stop_id\n                                                                FROM stop_direction_map\n                                                                WHERE direction_id = " . $dirStops->direction_id . " {$versionClause})\n                                                                AND b.direction_id = " . $dirStops->direction_id . $skipCondition . " AND a.version={$version}\n                                                                ORDER BY b.position DESC");
                //$dbObj->debug();exit;
                $pathArray = array();
                foreach ($stopsForPath as $sp) {
                    $pathArray[] = $sp->latitude . "," . $sp->longitude;
                }
                if ("actransit" == $agencyTitle) {
                    $pathColor = "0x008969";
                } elseif ("sf-muni" == $agencyTitle) {
                    $pathColor = "0xC74F3A";
                }
                $getParamStr = "path=weight:" . PATH_LINE_WEIGHT . "|" . getPathString($pathArray);
                $dirStopsArray[$dirStops->direction_id] = $getParamStr;
            }
            //Get the image from the Google Static Maps API
            $url = "http://maps.google.com/maps/api/staticmap?center={$lat_avg},{$lon_avg}&zoom={$zoom}&size=" . MAP_SIZE_X . "x" . MAP_SIZE_Y . "&maptype=roadmap&sensor=false&" . implode("&", $dirStopsArray);
            $pngImgFileName = $agencyTitle . "_" . $routeObj->getTag() . ".png";
            if (!file_exists($basePathOrig)) {
                //print $basePathOrig;exit;
                Util::createDir($basePathOrig);
            }
            $filePath = $basePathOrig . $pngImgFileName;
            //print "$url<br />$fileName<br /><br />";
            if (!copy($url, $filePath)) {
                $logStr = "Failed to copy {$fileName} \n";
                $logger->log($logStr, Logger::WARN, "IMAGE");
            }
            //Crop the image
            $intermediateImg_Y = MAP_SIZE_Y / 2 + round((FINAL_MAP_SIZE_Y - TOP_EDGE - BOTTOM_EDGE) / 2) + BOTTOM_EDGE;
            $intermediateImg = imagecreatetruecolor(MAP_SIZE_X, $intermediateImg_Y);
            list($current_width, $current_height) = getimagesize($filePath);
            if (!imagecopy($intermediateImg, imagecreatefrompng($filePath), 0, 0, 0, 0, $current_width, $current_height)) {
                $logStr = "Failed to crop and copy image [{$filePath}]";
                $logger->log($logStr, Logger::WARN, "IMAGE");
            }
            $fileName = $agencyTitle . "_" . $routeObj->getTag() . ".jpg";
            $newFilePath = $basePathConverted . $fileName;
            $startFromTop_Y = $intermediateImg_Y - FINAL_MAP_SIZE_Y;
            $newImage = imagecreatetruecolor(MAP_SIZE_X, FINAL_MAP_SIZE_Y);
            if (!imagecopy($newImage, $intermediateImg, 0, 0, 0, $startFromTop_Y, MAP_SIZE_X, FINAL_MAP_SIZE_Y)) {
                $logStr = "Failed to crop and copy image [{$newFilePath}]";
                $logger->log($logStr, Logger::WARN, "IMAGE");
            } else {
                imagejpeg($newImage, $newFilePath);
            }
            imagedestroy($newImage);
            imagedestroy($intermediateImg);
            //Add file name to zip file contents array
            $zipFileContents[] = $newFilePath;
            foreach ($dirXYDetails as $dirTag => $xyDetails) {
                $dirFinalY = $xyDetails['y'] - $startFromTop_Y;
                $dirNode = $routeNode->addChild("direction");
                $dirNode->addAttribute("tag", $dirTag);
                $dirNode->addAttribute("x", $xyDetails['x']);
                $dirNode->addAttribute("y", $dirFinalY);
            }
            $routeNode->addAttribute("yCropPixels", $startFromTop_Y);
            sleep(1);
            //if($cnt++ == 1) { break;}
        }
    }
    $fileName = Util::getBaseDirectoryPath(Util::IMAGE_FILE) . "map_overlay_coordinates.xml";
    Util::prettyPrintXml($xml, $fileName);
    //Create the zip file
    $zipFileContents[] = $fileName;
    Util::createZip($zipFileContents, getImagesPath(), true);
}
コード例 #2
0
 static function adjustLatByPixels($lat, $delta, $zoom)
 {
     return Google_Maps::YToLat(Google_Maps::LatToY($lat) + ($delta << 21 - $zoom));
 }