从 SQL/CSV 数据生成地图图块(动态?)
Generating map tiles (dynamically?) from SQL/CSV data
这是我拥有的:
SQL table/CSV 具有 "tile XYZ" 坐标(网络墨卡托平铺坐标)和 "data/color"
的文件
X Y Z Color
13 13 5 yellow
13 14 5 green
13 14 5 red
...
数据结构非常简单,不需要花哨的东西,我可以通过代码绘制png。
- 数据量很大,即全球平铺,比如 zoomlevel 15
我想要的:
- png 图块
- 不应访问基础数据
- 借助 leaflet/google 地图 api
将 png 磁贴显示为网页地图
problem/question:
- 之前生成全球所有图块的数据太多(需要几天)
- 因此我在考虑动态 caching/tile 创建算法(可能之前创建 0-9 缩放级别,动态创建更高的缩放级别)
- 似乎有很多工具(TileMill、TileStache、ArcGIS Server 等),但它们似乎都具有较高的学习曲线或用于更复杂的任务。
- 有没有办法 运行 一个完全符合我需要的精简服务器?也许使用查询数据库的 php 脚本,绘制 png 并将其按需提供给地图?那将如何工作?什么是聪明的解决方案?
非常感谢。
我遇到了一个有点类似的问题:具有图块索引,return 落入相应边界框的 table 的点。
后端
由于我使用 PostgreSQL + PostGIS 作为 BBDD,因此我使用了 Peter Warden's PostGIS2Gmap 存储库中定义的函数。
bounds_for_tile_indices(lat_index float8, lon_index float8, zoom_level int)
This takes latitude and longitude coordinates for a tile, and a zoom
level, and returns a geography object containing the bounding box for
that tile. I mainly use this for limiting queries on geographic data
to a particular tile, eg;
SELECT * FROM checkins WHERE ST_Intersects(lonlat, bounds_for_tile_indices(6, 2, 4);
现在,对于您的用例,您可能没有将所有可能的图块都存储到给定的 table 中,但您仍然可以使用所述函数来确定给定图块坐标的边界框:
SELECT Box2D(bounds_for_tile_indices(13, 14, 5)::geometry);
哪个 returns
BOX(-22.5 21.9430434618232,-11.25 31.9521604783552)
请注意,我明确地将 bounds_for_tile_indices
的输出转换为几何图形,因为它的原始输出是地理图形,您不能在地理图形上应用 Box2D。
既然您说您将拥有 table 的图块坐标而不是几何图形,那么前一种方法可能有点矫枉过正。
您可能只需要在 table 中查询给定的 x/y/x 组合,获取所需的颜色,然后使用 imagefill 生成给定颜色的 256x256 像素图像.引用文档示例:
$im = imagecreatetruecolor(100, 100);
// sets background to red
$red = imagecolorallocate($im, 255, 0, 0);
imagefill($im, 0, 0, $red);
或者,保留有限 collection 个 256x256px PNG 文件,然后使用从查询中获得的颜色构建正确图像的路径,然后使用 imagecreatefrompng 创建最终图像结果你会发送到前面正确的图像 header 被视为 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);
这是我拥有的:
SQL table/CSV 具有 "tile XYZ" 坐标(网络墨卡托平铺坐标)和 "data/color"
的文件X Y Z Color 13 13 5 yellow 13 14 5 green 13 14 5 red ...
数据结构非常简单,不需要花哨的东西,我可以通过代码绘制png。
- 数据量很大,即全球平铺,比如 zoomlevel 15
我想要的:
- png 图块
- 不应访问基础数据
- 借助 leaflet/google 地图 api 将 png 磁贴显示为网页地图
problem/question:
- 之前生成全球所有图块的数据太多(需要几天)
- 因此我在考虑动态 caching/tile 创建算法(可能之前创建 0-9 缩放级别,动态创建更高的缩放级别)
- 似乎有很多工具(TileMill、TileStache、ArcGIS Server 等),但它们似乎都具有较高的学习曲线或用于更复杂的任务。
- 有没有办法 运行 一个完全符合我需要的精简服务器?也许使用查询数据库的 php 脚本,绘制 png 并将其按需提供给地图?那将如何工作?什么是聪明的解决方案?
非常感谢。
我遇到了一个有点类似的问题:具有图块索引,return 落入相应边界框的 table 的点。
后端
由于我使用 PostgreSQL + PostGIS 作为 BBDD,因此我使用了 Peter Warden's PostGIS2Gmap 存储库中定义的函数。
bounds_for_tile_indices(lat_index float8, lon_index float8, zoom_level int)
This takes latitude and longitude coordinates for a tile, and a zoom level, and returns a geography object containing the bounding box for that tile. I mainly use this for limiting queries on geographic data to a particular tile, eg;
SELECT * FROM checkins WHERE ST_Intersects(lonlat, bounds_for_tile_indices(6, 2, 4);
现在,对于您的用例,您可能没有将所有可能的图块都存储到给定的 table 中,但您仍然可以使用所述函数来确定给定图块坐标的边界框:
SELECT Box2D(bounds_for_tile_indices(13, 14, 5)::geometry);
哪个 returns
BOX(-22.5 21.9430434618232,-11.25 31.9521604783552)
请注意,我明确地将 bounds_for_tile_indices
的输出转换为几何图形,因为它的原始输出是地理图形,您不能在地理图形上应用 Box2D。
既然您说您将拥有 table 的图块坐标而不是几何图形,那么前一种方法可能有点矫枉过正。
您可能只需要在 table 中查询给定的 x/y/x 组合,获取所需的颜色,然后使用 imagefill 生成给定颜色的 256x256 像素图像.引用文档示例:
$im = imagecreatetruecolor(100, 100);
// sets background to red
$red = imagecolorallocate($im, 255, 0, 0);
imagefill($im, 0, 0, $red);
或者,保留有限 collection 个 256x256px PNG 文件,然后使用从查询中获得的颜色构建正确图像的路径,然后使用 imagecreatefrompng 创建最终图像结果你会发送到前面正确的图像 header 被视为 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);