从SQL / CSV数据生成地图图块(动态?)

时间:2017-03-28 10:52:43

标签: google-maps maps leaflet tile wms

这就是我所拥有的:

  • 带有“tile XYZ”坐标(web mercator tile coordinates)和“data / color”的SQL表/ CSV文件

    X Y Z Color 13 13 5 yellow 13 14 5 green 13 14 5 red ...

  • 数据结构非常简单,不需要花哨的东西,我可以通过代码绘制png。

  • 数据量很大,即全球平铺,比如zoomlevel 15

我想要的是什么:

  • png tiles
  • 无法访问基础数据
  • 在leaflet / google maps api
  • 的帮助下将png图块显示为网页地图

问题/问题:

  • 过多的数据在世界范围内生成所有瓷砖(需要数天)
  • 因此我考虑使用动态缓存/磁贴创建算法(可能之前创建缩放级别0-9,动态创建更高的缩放级别)
  • 似乎有很多工具(TileMill,TileStache,ArcGIS Server等),但它们似乎都有很高的学习曲线,或者用于更复杂的任务。
  • 有没有办法运行一个完全符合我需求的精益服务器?也许使用查询数据库的php脚本,绘制png并按需将其提供给地图?这怎么会完全奏效?什么是一个聪明的解决方案?

非常感谢。

1 个答案:

答案 0 :(得分:2)

我遇到了一个类似的问题:使用tile索引,返回落入相应边界框的表的点。

<强>后端

由于我使用PostgreSQL + PostGIS作为BBDD,我使用了Peter Warden's PostGIS2Gmap repo中定义的函数。

bounds_for_tile_indices(lat_index float8, lon_index float8, zoom_level int)
  

这会获取图块的纬度和经度坐标以及缩放   level,并返回包含边界框的地理对象   那个瓷砖。我主要使用它来限制对地理数据的查询   特定的瓷砖,例如;

SELECT * FROM checkins WHERE ST_Intersects(lonlat, bounds_for_tile_indices(6, 2, 4);

现在,对于您的用例,您可能没有将所有可能的图块存储到给定的表中,但您仍然可以使用所述函数来确定给定图块坐标的边界框:

SELECT Box2D(bounds_for_tile_indices(13, 14, 5)::geometry);

返回

BOX(-22.5 21.9430434618232,-11.25 31.9521604783552)

请注意,我明确地将bounds_for_tile_indices的输出转换为几何图形,因为它的原生输出是地理位置,您无法在地理位置上应用Box2D。

由于您说您将拥有一个瓦片坐标表而不是几何图形,因此前一种方法可能过度

您可能只需要查询表格中的给定x / y / x组合,获得所需的颜色,然后使用imagefill生成给定颜色的256x256px图像。引用文档示例:

$im = imagecreatetruecolor(100, 100);

// sets background to red
$red = imagecolorallocate($im, 255, 0, 0);
imagefill($im, 0, 0, $red);

或者,保留有限的256x256px PNG文件集合,然后使用从查询中获得的颜色构建到右图像的路径,然后使用imagecreatefrompng创建要发送到的最终结果前面有正确的图像标题被视为PNG。

如您所见,绘制普通彩色瓷砖相当容易,但我完成了第一部分,因为我认为这些瓷砖不像您的问题那样简单。

<强>前端

在前面,您只需要声明一个自定义地图类型(特别是,对于您的用例google.maps.ImageMapType

var myTilesMap = new google.maps.ImageMapType({
        getTileUrl: function (coord, zoom) {
            return "/my_backend/" + coord.x + "/" + coord.y + "/" + zoom;
        },
        tileSize: new google.maps.Size(256, 256),
        name: "MyTiles"
    });

map.overlayMapTypes.insertAt(0, myTilesMap);