Apache Solr热图:如何转换热图返回的可用坐标int2d数组

时间:2018-04-05 17:08:11

标签: reactjs solr esri

我在空间字段上使用faceting热图,然后返回像这样的2d数组  “counts_ints2D”                 [                     空值,                     空值,                     空值,                     空值,                     [                         0,                         8,                         4,                         0,                         0,                         0,                         0,                         0,                         0,     ...

我想在地图上找到这些群集,但问题是我不知道如何在地理坐标中转换那个二维数组。

绝对没有文档显示如何处理这些整数。 有人可以提供一些指导吗?

2 个答案:

答案 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

将这些点粘贴到创建图层的导入框后,我们得到这张地图:

Points shown on Open Street Map / Umap

通过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;
    }
}