如何在.net核心中使用Openstreetmap(osm)离线切片文件?

问题描述 投票:5回答:1

我有web应用程序,使用Leaflet来显示一个小区域的地图。问题是应用程序必须脱机工作(在LAN上),并从Openstreetmap加载地图图块。我下载了我需要的磁贴但是我没有找到关于如何使用下载文件的好文档(这是一个带扩展名为.mbtiles的500MB文件)。这是Leaflet建议的默认方法:

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map); 

如何使用dotnet core设置服务器以使用我的离线图块和给定参数并获取图块图像?(如下所示):

L.tileLayer('https://example.com/DotnetCore/WepApi/GetTiles?{s}/{z}/{x}/{y}').addTo(map);
c# .net-core leaflet openstreetmap asp.net-core-webapi
1个回答
4
投票

以下是读取切片文件并在WebApi中提供它们的基本实现。

您需要安装NuGet System.Data.SQLite.Core(或类似的)才能访问数据库。

助手班:

public class MbTilesReader
{
    private string _mbTilesFilename;

    public MbTilesReader(string mbTilesFilename)
    {
        _mbTilesFilename = mbTilesFilename;
    }

    public byte[] GetImageData(int x, int y, int zoom)
    {
        byte[] imageData = null;
        using (SQLiteConnection conn = new SQLiteConnection(string.Format("Data Source={0};Version=3;", _mbTilesFilename)))
        {
            conn.Open();
            using (SQLiteCommand cmd = new SQLiteCommand(conn))
            {
                cmd.CommandText = "SELECT * FROM tiles WHERE tile_column = @x and tile_row = @y and zoom_level = @z";
                cmd.CommandType = System.Data.CommandType.Text;
                cmd.Parameters.Add(new SQLiteParameter("@x", x));
                cmd.Parameters.Add(new SQLiteParameter("@y", y));
                cmd.Parameters.Add(new SQLiteParameter("@z", zoom));
                SQLiteDataReader reader = cmd.ExecuteReader();
                if (reader.Read())
                {
                    imageData = reader["tile_data"] as byte[];
                }
            }
        }
        return imageData;
    }
}

然后在ConfigureServices方法中将类注册为单例,并将路径传递给该文件:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(new MbTilesReader("c:/temp/map.mbtiles"));
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

最后,您可以在Web Api操作中返回图像,如下所示:

[Route("api/[controller]")]
[ApiController]
public class MapController : ControllerBase
{
    private MbTilesReader _tileReader;

    public MapController(MbTilesReader tileReader)
    {
        _tileReader = tileReader;

    }

    [HttpGet]
    public IActionResult Get(int x, int y, int z)
    {
        byte[] imageData = _tileReader.GetImageData(x, y, z);
        return File(imageData, "image/png");
    }
}

可能的改进

  • 使用缓存可以避免始终查询相同的图像。
  • 使实现异步(请参阅this问题)。

编辑 - 格式

这个答案假设您的数据以PNG格式存储,.mbtiles文件可以使用以下格式存储数据:pbf(用于向量),jpg,png和webapp。要了解数据库使用的格式,请检查.mbtiles SQLite数据库的表元数据中的数据。

有关更多信息,请参阅以下链接:https://github.com/mapbox/mbtiles-spec/blob/master/1.3/spec.md

© www.soinside.com 2019 - 2024. All rights reserved.