我在空间字段上使用faceting热图,然后返回像这样的2d数组 “counts_ints2D” [ 空值, 空值, 空值, 空值, [ 0, 8, 4, 0, 0, 0, 0, 0, 0, ...
我想在地图上找到这些群集,但问题是我不知道如何在地理坐标中转换那个二维数组。
绝对没有文档显示如何处理这些整数。 有人可以提供一些指导吗?
答案 0 :(得分:0)
使用您为格拉斯哥提供的数据,并使用评论中给出的公式,让我们探索python repl中的坐标:
# setup
>>> minX = -180
>>> maxX = 180
>>> minY = -53.4375
>>> maxY = 74.53125
>>> columns = 256
>>> rows = 91
# calculate widths
>>> bucket_width = (maxX - minX) / columns
>>> bucket_width
1.40625
>>> bucket_height = (maxY - minY) / rows
>>> bucket_height
1.40625
# calculate area for bucket in heatmap facet for x = 124, y = 13
# point in lower left coordinate
>>> lower_left = {
... 'lat': maxY - (13 + 1) * bucket_height,
... 'lon': minX + 124 * bucket_width,
... }
>>> lower_left
{'lat': 54.84375, 'lon': -5.625}
# point in upper right
>>> upper_right = {
... 'lat': maxY - (13 + 1) * bucket_height + bucket_height,
... 'lon': minX + 124 * bucket_width + bucket_width,
... }
>>> upper_right
{'lat': 56.25, 'lon': -4.21875}
让我们用图表these points on a map来图片,由开放的街道地图提供。我们生成一个可以在umap上导入的小型CSV片段(选择向上箭头,选择'csv'作为类型,然后在文本框中输入内容)。到我们的坐标显示:
>>> bbox = [
... "lat,lon,description",
... str(lower_left['lat']) + "," + str(lower_left['lon']) + ",ll",
... str(upper_right['lat']) + "," + str(lower_left['lon']) + ",ul",
... str(upper_right['lat']) + "," + str(upper_right['lon']) + ",uu",
... str(lower_left['lat']) + "," + str(upper_right['lon']) + ",lu",
... ]
>>> print("\n".join(bbox))
lat,lon,description
54.84375,-5.625,ll
56.25,-5.625,ul
56.25,-4.21875,uu
54.84375,-4.21875,lu
将这些点粘贴到创建图层的导入框后,我们得到这张地图:
通过uMap基于Open Street Map数据进行地图。这个区域按照您的预期包围了格拉斯哥。
答案 1 :(得分:0)
以下代码将第180条子午线(日期行)换行考虑在内:
$columns = $heatmap['columns'];
$rows = $heatmap['rows'];
$minX = $heatmap['minX'];
$maxX = $heatmap['maxX'];
$minY = $heatmap['minY'];
$maxY = $heatmap['maxY'];
$counts = $heatmap['counts_ints2D'];
// If our min longitude is greater than max longitude, we're crossing
// the 180th meridian (date line).
$crosses_meridian = $minX > $maxX;
// Bucket width needs to be calculated differently when crossing the
// meridian since it wraps.
$bucket_width = $crosses_meridian
? $bucket_width = (360 - abs($maxX - $minX)) / $columns
: $bucket_width = ($maxX - $minX) / $columns;
$bucket_height = ($maxY - $minY) / $rows;
$points = [];
foreach ($counts as $rowIndex => $row) {
if (!$row) continue;
foreach ($row as $columnIndex => $column) {
if (!$column) continue;
$point = []
$point['count'] = $column;
// Put the count in the middle of the bucket (adding a half height and width).
$point['lat'] = $maxY - (($rowIndex + 1) * $bucket_height) + ($bucket_height / 2);
$point['lng'] = $minX + ($columnIndex * $bucket_width) + ($bucket_width / 2);
// We crossed the meridian, so wrap back around to negative.
if ($point['lng'] > 180) {
$point['lng'] = -1 * (180 - ($point['lng'] % 180));
}
$points[] = $point;
}
}