Mercurial > hg > batmud > gmap2
view tools/makegmaps.php @ 237:d858383547c7 gmap2
Comment cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 17 Mar 2014 01:21:24 +0200 |
parents | d0789eab0c47 |
children | 885ef4bdb0de |
line wrap: on
line source
#!/usr/bin/php <?php // Paths and files $binConvert = "convert"; $binMercurial = "hg"; $binMake = "make"; $pathMapUtils = "maputils/"; $pathImageCache = "cache/"; $pathMarkerData = "../"; $pathTileData = "../tiles/"; $pathRawMaps = $pathMapUtils."maps/"; $rawSuffix = ".new"; $rawAltSuffix = ".map"; $fontFile = "./lucon.ttf"; $tileDim = 256; $minZoom = 1; $maxZoom = 10; // Font sizes $fontSize = array(); $fontSize[ 8] = 7; $fontSize[16] = 13; $fontSize[32] = 26; /* Internal data and settings */ $locPath = $pathMapUtils."maps/"; $worldJS = $pathMarkerData."world.js"; $tradelaneOut = $pathMarkerData."tradelane.json"; $tradelaneOverlay = $pathMarkerData."trlines.json"; $binMkLoc = $pathMapUtils."mkloc"; $modes = array( "xml" => array("batclient.xml" , 0, 0), "json" => array("markers.json" , 0, 0), ); $mapPalette = array(); $mapPalette["!"] = array(204,255,255); $mapPalette["%"] = array( 0,170,170); $mapPalette["-"] = array( 51, 51, 51); $mapPalette["|"] = array( 51, 51, 51); $mapPalette["/"] = array( 51, 51, 51); $mapPalette["+"] = array( 51, 51, 51); $mapPalette["\\"] = array( 51, 51, 51); $mapPalette["="] = array( 72, 67, 57); $mapPalette["@"] = array(255,107, 0); $mapPalette["F"] = array( 0,136, 0); $mapPalette["L"] = array(255, 80, 0); $mapPalette["S"] = array( 68,204,204); $mapPalette["^"] = array(113,130,146); $mapPalette["c"] = array( 95, 86, 85); $mapPalette["f"] = array( 0,182, 0); $mapPalette["i"] = array(255,255,255); $mapPalette["l"] = array(100,100,255); $mapPalette["s"] = array(157,168, 10); $mapPalette["v"] = array( 34,221, 34); $mapPalette["x"] = array(138,131, 96); $mapPalette["z"] = array(177,164,133); $mapPalette["#"] = array( 79, 54, 69); $mapPalette["."] = array( 85,146, 0); $mapPalette[","] = array(140, 87, 56); $mapPalette["?"] = array(255,255, 0); $mapPalette["C"] = array(153,153, 0); $mapPalette["H"] = array(102, 63, 0); $mapPalette["R"] = array( 51,102,255); $mapPalette["V"] = array(255, 51, 0); $mapPalette["b"] = array(207,196,165); $mapPalette["d"] = array(238,187, 34); $mapPalette["h"] = array(153,102, 0); $mapPalette["j"] = array( 19,150, 54); $mapPalette["r"] = array(102,153,255); $mapPalette["t"] = array( 97,195,162); $mapPalette["w"] = array(119,170,255); $mapPalette["y"] = array(167,204, 20); $mapPalette["~"] = array( 51, 51,170); $mapPalette["1"] = array(255,102, 16); $mapPalette[3] = array(0,0, 0); // // Helper functions // function stMakeDir($path) { if (file_exists($path)) return TRUE; else return mkdir($path, 0755, TRUE); } function stOutputToFile($sfilename, $sdata) { if (file_put_contents($sfilename, $sdata, LOCK_EX) === FALSE) die("Error writing to '".$sfilename."'.\n"); } /* * Create htaccess files */ function makeHtAccessFile($surlprefix, $sprefix, $spath) { $sfile = $sprefix.$spath.".htaccess"; if (!file_exists($sfile) && file_exists($sprefix.$spath."sea.png")) { if (!isset($surlprefix)) { $sdone = FALSE; while (!$sdone) { echo "Enter URL prefix for tiles:\n"; $surlprefix = trim(fgets(STDIN)); if (substr($surlprefix, 0, 7) != "http://" && substr($surlprefix, 0, 8) != "https://") { echo "Prefix must start with http:// or https://\n"; } else if (substr($surlprefix, -1) != "/") { echo "Prefix must end with /\n"; } else if (preg_match("/^https?:\/\/[a-zA-Z0-9]+[a-zA-Z0-9\/\.\:\-]*?\//", $surlprefix) === FALSE) { echo "Malformed URL (or atleast this silly regexp does not want it.\n"; } else { echo "The URL prefix to be used is \"".$surlprefix."\", e.g.\n". "htaccess to be created would be: \"".$surlprefix."tiles/".$spath."sea.png\"\n". "Is this correct? [y/N]? "; $sprompt = strtolower(trim(fgets(STDIN))); if ($sprompt == "y") $sdone = TRUE; echo "\n"; } } } echo "Creating ".$sfile."\n"; outputToFile($sfile, "ErrorDocument 404 ".$surlprefix."tiles/".$spath."sea.png\n"); } } makeHtAccessFile(&$urlTilePrefix, $pathTileData, ""); for ($i = $minZoom; $i <= $maxZoom; $i++) makeHtAccessFile(&$urlTilePrefix, $pathTileData, $i."/"); if (!file_exists($pathMapUtils)) // // Build maputils and fetch latest map data // { // If maputils does not exist, clone the repository $tmp = $binMercurial." clone http://pupunen.net/hg/maputils/ ".escapeshellarg($pathMapUtils); echo "* $tmp\n"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); // Clone th-libs $tmp = $binMercurial." clone http://tnsp.org/hg/th-libs/ ".escapeshellarg($pathMapUtils."th-libs/"); echo "* $tmp\n"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); } else { $tmp = "cd ".escapeshellarg($pathMapUtils)." && ".$binMercurial." pull && ".$binMercurial." update"; echo "* $tmp\n"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); $tmp = "cd ".escapeshellarg($pathMapUtils."th-libs/")." && ".$binMercurial." pull && ".$binMercurial." update"; echo "* $tmp\n"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); } $tmp = "cd ".escapeshellarg($pathMapUtils)." && ".$binMake." ".escapeshellarg(basename($binMkLoc)); echo "* $tmp\n"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); if (!file_exists($binMkLoc)) die($binMkLoc." not found. Maputils package not built, or some other error occured.\n"); $tmp = "cd ".escapeshellarg($pathMapUtils)." && ".$binMake; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); $tmp = "cd ".escapeshellarg($pathRawMaps)." && ".$binMake." fetch 2> /dev/null"; passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); /* * Include continent and tradelane configuration */ $config = $pathMapUtils."www/world.inc.php"; if (!file_exists($config)) die("Required continent/tradelane configuration file '$config' not found.\n"); require $config; // // Generate continents JavasScript data file /// echo "* Generating $worldJS ...\n"; $str = "var pmapWorld = {"; foreach ($worldMap as $wkey => $wval) $str .= "\"".$wkey."\": ".$wval.", "; $str .= "};\n"; $str .= "var pmapContinents =\n[\n"; foreach ($continentList as $name => $data) if ($data[4] && $data[7]) { $str .= sprintf(" [%-15s, %5d, %5d, %5d, %5d, %5d, %5d],\n", "\"".$data[0]."\"", $data[1], $data[2], $data[1] + $data[5] - 1, $data[2] + $data[6] - 1, $data[5], $data[6]); } $str .= "];\n"; stOutputToFile($worldJS, $str); // // Generate marker files from LOC data /// echo "Converting location data from LOC files to GMaps markers...\n"; foreach ($modes as $mode => $mdata) { $tmp = escapeshellcmd($binMkLoc)." -v -o ".escapeshellarg($pathMarkerData.$mdata[0])." -G ".$mode." "; foreach ($continentList as $name => $data) { if ($data[4] && $data[7]) { // has a map $tmp .= "-l ".escapeshellarg($locPath.$name.".loc")." ". "-c ".escapeshellarg($data[0])." ". "-x ".escapeshellarg($worldMap["ox"] + $data[1] + $mdata[1])." ". "-y ".escapeshellarg($worldMap["oy"] + $data[2] + $mdata[2])." "; } } passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); } /* Calculate worldmap coordinates from continent coordinates */ function getWorldCoords($cont, $xp, $yp, &$xc, &$yc) { global $worldMap, $continentList; if (!isset($continentList[$cont])) return FALSE; $xc = $worldMap["ox"] + $continentList[$cont][1] + $xp - 1; $yc = $worldMap["oy"] + $continentList[$cont][2] + $yp - 1; return TRUE; } /* Get worldmap coordinates for a given tradelane waypoint */ function getWaypointCoords($waypoint, &$xc, &$yc) { global $tradelanePoints; if (!isset($tradelanePoints[$waypoint])) return FALSE; return getWorldCoords($tradelanePoints[$waypoint][0], $tradelanePoints[$waypoint][1], $tradelanePoints[$waypoint][2], $xc, $yc); } function outputToJSONFile($qfilename, $qdata) { outputToFile($qfilename, json_encode($qdata)); } // // Export tradelane waypoint data // if (!isset($tradelanePoints)) die("PHP array \$tradelanePoints not set, '$config' is old or incompatible.\n"); echo "\nCreating tradelane waypoint data '".$tradelaneOut."' ...\n"; $qdata = array(); foreach ($tradelanePoints as $name => $data) { $html = "<b>TRADELANE WPT</b><br>".htmlentities($name); if (!getWorldCoords($data[0], $data[1], $data[2], $xc, $yc)) die("Invalid tradelane waypoint '".$name."', continent '".$data[0]."' not defined.\n"); $qdata[] = array( "x" => $xc, "y" => $yc, "name" => $name, "html" => $html, "continent" => "", "type" => "tradelane", "flags" => 0, ); } stOutputToJSONFile($tradelaneOut, $qdata); // // Export tradelane polyline data // echo "\nCreating tradelane polyline data '".$tradelaneOverlay."' ...\n"; if (!isset($tradelaneDefs)) die("PHP array \$tradelaneDefs not set, '$config' is old or incompatible.\n"); $qdata = array(); foreach ($tradelaneDefs as $index => $points) { $qline = array(); foreach ($points as $point) { if (!getWaypointCoords($point, $xc, $yc)) die("Invalid tradelane definition #$index: waypoint '".$point."' not defined.\n"); $qline[] = array( "x" => $xc, "y" => $yc ); } $qdata[] = $qline; } stOutputToJSONFile($tradelaneOverlay, $qdata); // // Generate PNG maps // function makeMap($inFilename, $outFilename, $zlevel, $data) { global $mapPalette, $fontFile, $fontSize; // Try to open input file $file = @fopen($inFilename, "r"); if ($file === FALSE) { echo "Could not open input '".$inFilename."'\n"; return FALSE; } // Derp $zoom = pow(2, $zlevel - 1); $width = $data[5]; $height = $data[6]; // Create image and assign colors $im = @imagecreate($width*$zoom, $height*$zoom); if ($im === FALSE) { echo "Could not allocate image data for '".$inFilename."'\n"; return FALSE; } $black = imagecolorallocate($im, 0, 0, 0); foreach ($mapPalette as $id => $val) $colors[$id] = imagecolorallocate($im, $val[0], $val[1], $val[2]); imagefilledrectangle($im, 0, 0, $width*$zoom, $height*$zoom, $black); // Read input raw $y = 0; while ($y < $height && ($data = fgets($file, 4096)) !== FALSE) { for ($x = 0; $x < $width; $x++) { if ($zoom == 1) { imagesetpixel($im, $x, $y, $colors[$data[$x]]); } else if ($zoom < 6) { imagefilledrectangle($im, $x*$zoom, $y*$zoom, ($x+1)*$zoom-1, ($y+1)*$zoom-1, $colors[$data[$x]]); } else { imagettftext($im, $fontSize[$zoom], 0, $x*$zoom + $fontSize[$zoom]/4, $y*$zoom + $fontSize[$zoom], $colors[$data[$x]], $fontFile, $data[$x]); } } $y++; echo "."; } if (imagepng($im, $outFilename) === FALSE) { echo "Error creating '".$outFilename."'\n"; imagedestroy($im); return FALSE; } imagedestroy($im); return TRUE; } if (!stMakeDir($pathImageCache)) { die("Failed to create cache directory '".$pathImageCache."'!\n"); } echo "Generating basic map data...\n"; foreach ($continentList as $name => $data) if ($data[4] && $data[7]) { $inFilename = $pathRawMaps.$name.$rawSuffix; if (!file_exists($inFilename)) { $inFilename = $pathRawMaps.$name.$rawAltSuffix; if (!file_exists($inFilename)) die("Required file '".$pathRawMaps.$name."(".$rawSuffix."|".$rawAltSuffix.")' does not exist.\n"); } $inMtime = filemtime($inFilename); for ($zoom = 1; $zoom <= 5; $zoom++) { $outFilename = $pathImageCache.$name."_".($zoom + 4).".png"; $outMtime = file_exists($outFilename) ? filemtime($outFilename) : -1; echo "- ".$name." (".$data[0]."): "; if ($inMtime > $outMtime) { $res = makeMap($inFilename, $outFilename, $zoom, $data); echo ($res ? "OK" : "FAIL")."\n"; } else echo "SKIPPED\n"; } } /* * Generate small versions */ echo "\nGenerating scaled small map data...\n"; $mapScales = array("50", "25", "12.5", "6.25", "3.125"); foreach ($continentList as $name => $data) if ($data[4] && $data[7]) { $n = count($mapScales); $inFilename = $pathImageCache.$name."_".$n.".png"; if (!file_exists($inFilename)) { die("Required file '".$inFilename."' does not exist.\n"); } $inMtime = filemtime($inFilename); foreach ($mapScales as $scale) { $n--; $outFilename = $pathImageCache.$name."_".$n.".png"; $outMtime = file_exists($outFilename) ? filemtime($outFilename) : -1; echo "* ".$inFilename." -> ".$outFilename.": "; if ($inMtime > $outMtime) { $tmp = escapeshellcmd($binConvert)." ".escapeshellarg($inFilename)." -scale ".escapeshellarg($scale."%")." -type Palette ".escapeshellarg($outFilename); passthru($tmp) == 0 or die("Error executing: ".$tmp."\n"); echo "OK\n"; } else echo "SKIPPED\n"; } } /* * Build tiles */ function createTile($scale, $zoom, $x, $y, $mapData, $mapMtime) { global $continentList, $worldMap, $pathImageCache, $pathTileData, $tileDim; $outFilename = $pathTileData.$zoom."/".$y."/".$x.".png"; if (file_exists($outFilename) && filemtime($outFilename) >= $mapMtime) { echo "!"; return; } $drawn = 0; $im = false; foreach ($continentList as $continent => $data) { if (!$data[4] || !$data[7]) continue; $cx = $data[1] + $worldMap["ox"]; $cy = $data[2] + $worldMap["oy"]; $cw = $data[5]; $ch = $data[6]; $tx = -($cx*$scale - $x*$tileDim); $ty = -($cy*$scale - $y*$tileDim); if (($cx + $cw)*$scale > $x*$tileDim && ($cy + $ch)*$scale > $y*$tileDim && ($cx * $scale) < ($x+1)*$tileDim && ($cy * $scale) < ($y+1)*$tileDim) { if ($drawn == 0) { if ($zoom < 9) { $im = @imagecreate($tileDim, $tileDim); $sea = imagecolorallocate($im, 51, 51, 170); imagefilledrectangle($im, 0, 0, $tileDim, $tileDim, $sea); } else { $inFilename = $pathTileData.$zoom."/sea.png"; $im = @imagecreatefrompng($inFilename); if ($im === false) die("\nCould not open '".$inFilename."'.\n"); } } $dx = $tileDim; $dy = $tileDim; $xx = 0; $yy = 0; if ($tx < 0) { $xx -= $tx; $dx += $tx+1; $tx = 0; } if ($ty < 0) { $yy -= $ty; $dy += $ty+1; $ty = 0; } if ($dx > $cw*$scale-$tx) $dx = $cw*$scale - $tx; if ($dy > $ch*$scale-$ty) $dy = $ch*$scale - $ty; if ($im !== false) { imagecopy($im, $mapData[$continent], $xx, $yy, $tx, $ty, $dx, $dy); $drawn++; } } } if ($drawn > 0) { stMakeDir($pathTileData.$zoom."/".$y, 0755); imagepng($im, $outFilename); imagedestroy($im); } /* else { if (file_exists($outFilename)) unlink($outFilename); symlink($pathTileData."sea.png", $outFilename); echo "+"; } */ } echo "\nBuilding tiles data for all zoom levels ...\n"; $mapData = array(); for ($zoom = $minZoom; $zoom <= $maxZoom; $zoom++) { $zoom2 = $zoom - 1; $scale = pow(2, $zoom2 - 5); stMakeDir($pathTileData.$zoom); echo "\nzoom level $zoom: "; $mx = ceil(($worldMap["w"] * $scale) / $tileDim); $my = ceil(($worldMap["h"] * $scale) / $tileDim); $mw = ceil( $worldMap["w"] * $scale); $mh = ceil( $worldMap["h"] * $scale); $mapMtime = -1; foreach ($continentList as $continent => $data) if ($data[4] && $data[7]) { $mapFile = $pathImageCache.$continent."_".$zoom2.".png"; $mapData[$continent] = @imagecreatefrompng($mapFile); $tmp = filemtime($mapFile); if ($tmp > $mapMtime) $mapMtime = $tmp; } for ($y = 0; $y < $mx; $y++) { for ($x = 0; $x < $my; $x++) createTile($scale, $zoom, $x, $y, $mapData, $mapMtime); echo "."; } echo "\n"; // Free image data for each continent foreach($continentList as $continent => $data) { if ($data[4] && $data[7]) imagedestroy($mapData[$continent]); } } ?>