管理自定义 Highmaps 中的投影

Manage projections in custom Highmaps

我正在从 python(主要使用 geopandas 模块)生成 html 文件,其中包含 highmaps 对象。

(由于 geojson 包含在 html 文件中,代码太长无法放入 Whosebug 中:请不要检查包含的代码,而是参考小提琴)。

地图数据为:

这两个系列都使用 geopandas(我认为它在某处使用了 pyproj4 dll)在同一个测地系统中进行了预转换。

我从 spatialreference 中获得了作为 proj4 字符串的测地线系统,即:

当我转换 WGS 84 中的所有数据时,我得到了正确的结果(尽管地图对于法国用户来说看起来有些失真):参见 this fiddle

当我转换所有2154年的数据时,出现严重错误(如您所见,城市显示不正常,似乎还包括一些纬度反演);参见 this fiddle

当我将所有数据保存在 WGS 84 中并将 hc-transform 设置为 epsg2154 时,I still have strange results, though I think this is the correct way referenced in the doc(我不是 100% 确定,因为这些是使用远程 geojson 数据生成的地图,我我不习惯在 javascript) 中编程...

我也尝试使用地图点系列的 x/y 属性(而不是 lon/lat)但这并没有改善结果(尽管我检查了 QGis 中的数据并且这些坐标是 100% 正确的).

我应该怎么做?

代码示例(有关 geojson 的工作示例,请参阅小提琴):

<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.6/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<div id="container"></div>
<script type="text/javascript">
    Highcharts.mapChart("container", {
        title: {
            text: 'Testmap Highmaps Hauts-de-France'
        },                   

        mapNavigation: {
            enabled: true,
            buttonOptions: {
                verticalAlign: 'bottom'
            }
        },

        series: [
            {
                name: 'areas',
                type: 'map',
                mapData: {'type': 'FeatureCollection', 'features': [...], 'hc-transform': {'default': {'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'}}, 'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'},
            },
            {
                name: 'cities',
                type: 'mappoint',
                data: [{'lon': 727759.0000000142, 'lat': 6884382.999997055, 'name': 'Chateau-Thierry'}, ...],
                color: 'black',
                marker: {
                    radius: 2
                },
                dataLabels: {
                    align: 'left',
                    verticalAlign: 'middle'
                },
                animation: false,
                tooltip: {
                    pointFormat: '{point.name}'
                }
            },
        ]
    });
</script>
</body>
</html>

好吧,这是一个笨拙的解决方案:我仍然不明白这是如何解决问题的,但它确实有效... [EDIT:这确实是暂时的正确解决方案,请参阅 post]

末尾的编辑

我所做的是:

  • 使用 ESPG2154 的 proj4 字符串,如前所述:“+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 + lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"

  • 在 EPSG2154 的系统中使用 xy 坐标设置 mapData : [761574.9000000217, 6918670.299997976], [761648.2000000217, 6918469.799997974], ...

  • 如前所述在 mapData 上设置 hc-transform/crs: 'hc-transform': {'default': {'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 + lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'}}, 'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'

  • 使用 x/y 而不是 lat/lon 设置地图点数据,没有任何 'hc-transform' 或 crs, 但 y 坐标反转:数据:[{'x':727759.0000000142,'y':-6884382.999997055,'name':'Chateau-Thierry'},...]

注意:

  • 我为地图点数据反转了 y 坐标,并且这些 在任何意义上都不是正确的坐标;
  • 我还将 yAxis 设置为 reversed: true,这不应该是 API 文档中所述的默认值。但实际上,无论您是否删除此行,它都不会改变任何内容:不知何故,使用包括一个 mapData 在内的多个系列似乎正在更改默认值 属性(至少在此配置中使用 proj4 时)。事实上,如果你把它设置为reversed:false,你不会有任何正确的结果,即使你没有像前面所说的那样反转y坐标。

我认为这是某种未记录的错误(我可能仍然错了),我会尝试参考 highcharts 的工作人员...

请参阅 this fiddle 中的完整功能示例。

<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.6/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<div id="container"></div>
<script type="text/javascript">
    Highcharts.mapChart("container", {
        title: {
            text: 'Testmap Highmaps Hauts-de-France'
        },                   

        mapNavigation: {
            enabled: true,
            buttonOptions: {
                verticalAlign: 'bottom'
            }
        },

        yAxis: {
            reversed: true
        },

        series: [
            {
                name: 'areas',
                type: 'map',
                mapData: {'type': 'FeatureCollection', 'features': [{'id': '1', 'type': 'Feature', 'properties': {'DEP': '02'}, 'geometry': {'type': 'Polygon', 'coordinates': [[[761574.9000000217, 6918670.299997976], [761648.2000000217, 6918469.799997974], ..., [699287.6999999998, 6901218.199997955]]]}}], 'hc-transform': {'default': {'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'}}, 'crs': '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'},
            },
            {
                name: 'cities',
                type: 'mappoint',
                data: [{'x': 727759.0000000142, 'y': -6884382.999997055, 'name': 'Chateau-Thierry'}, ...],
                color: 'black',
                marker: {
                    radius: 2
                },
                dataLabels: {
                    align: 'left',
                    verticalAlign: 'middle'
                },
                animation: false,
                tooltip: {
                    pointFormat: '{point.name}'
                }
            },
        ]
    });
</script>
</body>
</html>

编辑

所以这确实是一个棘手的问题... 我一直在与 highsoft 联系,似乎有多个事实需要考虑: - 首先,yAxis.reverse=true IS 是默认行为,无论文档中当前声明的是什么; - 其次,一些关于 mapData 的内部算法纠正了这种行为,因为这种类型的图层被假定为 GeoJSON ; - 第三,mappoint aw 和 mapbubble 图层不是这种情况。

请注意,如果您设置 yAxis.reverse = false,您将度过一段糟糕的时光。地图点图层似乎与您的地图数据正确叠加(如果我理解正确,这与地图点图层的 y 范围或多或少与地图区域的 y 范围相似有关。

Highsoft has opened an issue 关于这个主题。

道德:我的解决方案实际上是好的(至少在他们决定如何处理这个 "issue" 之前)。 对于此版本的 Highmaps,始终使用 yAxis.reverse = true,并注意作为 GeoJSON 传递的 mapDatas 不受此命令的影响。