这次日本地理空间信息局我将使用 Ruby 发布的 GSI 瓦片制作地图应用程序。

GSI瓷砖的规格是“关于 GSI 瓷砖”作为参考。
粗略地说,它看起来像这样。

https://cyberjapandata.gsi.go.jp/xyz/{t}/{z}/{x}/{y}.{ext}
{t}:数据 ID
{x}:瓦片坐标的X值
{y}:瓦片坐标的Y值
{z}:缩放级别
{ext}:扩展名

Step1 显示平铺图像

第一的,标准地图我将只下载并显示其中的一个。

样本1.rb
require 'open-uri'
require 'dxruby'

url = "http://cyberjapandata.gsi.go.jp/xyz/std/7/110/51.png"
file = "51.png"
open(file, 'wb') do |path|
  URI.open(url) do |recieve|
    path.write(recieve.read)
  end
end

image = Image.load(file)

Window.loop do
  Window.draw(0, 0, image)
end

这次我只在 Windows 上使用 DXRuby,但是任何可以读取和显示 png 图像的库都可以。
命令行上的 DxRuby

>gem install dxruby

可以安装

以前,我只能用它来运行它,但从 Windows 10 开始,可能需要 Dll 等。
https://qiita.com/noanoa07/items/0ce14c2404df38de94b7

执行者:从命令行

>ruby sample1.rb

使用 执行时,将打开一个窗口并显示单个地图图像。
地理院タイルの地図を表示する

Step2 像地图一样并排显示图块

接下来,获取一些并将它们排列在瓷砖中,使其看起来像一张地图。
此外,下载的图像在本地缓存,以免服务器过载(这很重要)。

样本2.rb
require 'open-uri'
require 'fileutils'
require 'dxruby'

def download(z: 0, x: 0, y: 0)
  url = "http://cyberjapandata.gsi.go.jp/xyz/std/#{z}/#{x}/#{y}.png"
  uri = URI.parse(url)
  file = Dir.pwd + uri.path
  unless FileTest.exist?(file)
    dir = File.dirname(file)
    FileUtils.mkdir_p(dir) unless FileTest.exist?(dir)
    open(file, 'wb') do |path|
      URI.open(uri) do |recieve|
        path.write(recieve.read)
      end
    end
  end
  file
end

images = []
2.times do |y|
  cols = []
  3.times do |x|
    file = download(z: 7, x: 110 + x, y: 51 + y)
    cols << Image.load(file)
  end
  images << cols
end

view_x = 0
view_y = 0

Window.loop do
  view_x += Input.x
  view_y += Input.y

  2.times do |y|
    3.times do |x|
      image = images[y][x]
      Window.draw(view_x + x * 256, view_y + y * 256, image)
    end
  end
end

地理院タイルの地図を表示する

我可以使用光标键向上、向下、向左和向右滚动,但只显示第一个下载的图块,所以当它到达边缘时它是黑色的。

Step3 根据滚动显示图块

所以,这一次,我们将对其进行改进,以便根据屏幕的滚动实时下载图像。
最开始机制是编程检测滚动和下载,但是代码变得又长又复杂,所以我改变了思路,只显示了世界坐标屏幕上显示的部分(相机)。(如果没有图像,获取它) ) 我可以简单地实现它。
(出于这个原因,我们正在创建一个边为 2 ^ 缩放级别的空数组,因此在缩放级别增加时要小心)

样本3.rb
require 'open-uri'
require 'fileutils'
require 'dxruby'

def download(z: 0, x: 0, y: 0)
  url = "http://cyberjapandata.gsi.go.jp/xyz/std/#{z}/#{x}/#{y}.png"
  uri = URI.parse(url)
  file = Dir.pwd + uri.path
  unless FileTest.exist?(file)
    dir = File.dirname(file)
    FileUtils.mkdir_p(dir) unless FileTest.exist?(dir)
    open(file, 'wb') do |path|
      URI.open(uri) do |recieve|
        path.write(recieve.read)
      end
    end
  end
  file
end

MAX_WIDTH = 2 ** 7
MAX_HEIGHT = 2 ** 7
tiles = Array(MAX_HEIGHT * MAX_WIDTH)

view_x = 110 * 256
view_y = 51 * 256

Window.loop do
  view_x += Input.x
  view_y += Input.y

  (Window.height / 256 + 2).times do |j|
    (Window.width / 256 + 2).times do |i|
      y = view_y / 256 + j
      x = view_x / 256 + i
      index = y * MAX_WIDTH + x
      unless tiles[index]
        file = download(z: 7, x: x, y: y)
        tiles[index] = Image.load(file)
      end
      image = tiles[index]
      Window.draw(-(view_x % 256) + i * 256, -(view_y % 256) + j * 256, image)
    end
  end
end

地理院タイルの地図を表示する

现在您可以垂直和水平滚动。
即使没有异步处理,也会比较流畅的显示出来。日本地理空间信息局令人惊叹
但是,如果事情照原样进行,不再显示的图像不会被删除(垃圾收集),因此内存消耗越来越多。

因此,仅使用此代码,它看起来就像一个地图应用程序。接下来,我想实现缩放级别的更改。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308629697.html

相关文章: