tile-mosaic.ps1 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. param(
  2. [int]$Zoom = 15,
  3. [double[]]$Bounds = @(110.328749941417, 28.3917230659234, 110.465779226663, 28.4913038992907),
  4. [int]$MaxWidth = 6500,
  5. [string]$Output = 'E:\City-Lifeline-Cockpit-TvT\.scratch\gis-investigation-subagent\city-z15.jpg'
  6. )
  7. $ErrorActionPreference = 'Stop'
  8. Add-Type -AssemblyName System.Drawing
  9. $n = [math]::Pow(2, $Zoom)
  10. function TileX([double]$lon) { return [int][math]::Floor(($lon + 180) / 360 * $n) }
  11. function GoogleY([double]$lat) {
  12. $rad = $lat * [math]::PI / 180
  13. return [int][math]::Floor((1 - [math]::Log([math]::Tan($rad) + 1 / [math]::Cos($rad)) / [math]::PI) / 2 * $n)
  14. }
  15. $x0 = TileX $Bounds[0]; $x1 = TileX $Bounds[2]
  16. $y0 = GoogleY $Bounds[3]; $y1 = GoogleY $Bounds[1]
  17. $scale = [math]::Min(1.0, [double]$MaxWidth / (($x1 - $x0 + 1) * 256.0))
  18. $tileSize = 256 * $scale
  19. $width = [int][math]::Round(($x1 - $x0 + 1) * $tileSize)
  20. $height = [int][math]::Round(($y1 - $y0 + 1) * $tileSize)
  21. $bitmap = New-Object System.Drawing.Bitmap($width, $height)
  22. $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
  23. $graphics.Clear([System.Drawing.Color]::Black)
  24. $graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
  25. $loaded = 0; $missing = 0
  26. for ($x = $x0; $x -le $x1; $x++) {
  27. for ($gy = $y0; $gy -le $y1; $gy++) {
  28. $tmsY = [int]$n - 1 - $gy
  29. $path = "D:\GIS\GIS\yuanlingPic3\$Zoom\$x\$tmsY.png"
  30. if (-not (Test-Path $path)) { $missing++; continue }
  31. $tile = [System.Drawing.Image]::FromFile($path)
  32. try {
  33. $left = [int][math]::Round(($x - $x0) * $tileSize)
  34. $top = [int][math]::Round(($gy - $y0) * $tileSize)
  35. $right = [int][math]::Round(($x - $x0 + 1) * $tileSize)
  36. $bottom = [int][math]::Round(($gy - $y0 + 1) * $tileSize)
  37. $graphics.DrawImage($tile, [System.Drawing.Rectangle]::new($left, $top, $right - $left, $bottom - $top))
  38. $loaded++
  39. } finally { $tile.Dispose() }
  40. }
  41. }
  42. $graphics.Dispose()
  43. $format = if ([System.IO.Path]::GetExtension($Output) -eq '.jpg') { [System.Drawing.Imaging.ImageFormat]::Jpeg } else { [System.Drawing.Imaging.ImageFormat]::Png }
  44. $bitmap.Save($Output, $format)
  45. $bitmap.Dispose()
  46. Write-Output "zoom=$Zoom x=$x0..$x1 googleY(top..bottom)=$y0..$y1 TMSY(top..bottom)=$([int]$n - 1 - $y0)..$([int]$n - 1 - $y1) dimensions=${width}x${height} loaded=$loaded missing=$missing output=$Output"