Incubator-echarts: 世界地图的视图中心点可以定制吗

Created on 22 Aug 2016  ·  21Comments  ·  Source: apache/incubator-echarts

问题简述 (One-line summary)

世界地图视图的缺省中心点是非洲, 这个中心点可以有选项定制吗?比如:世界地图

版本及环境 (Version & Environment)

  • ECharts 版本 (ECharts version):2.2.1
  • 浏览器类型和版本 (Browser version):CHROME
  • 操作系统类型和版本 (OS Version):

    重现步骤 (Steps to reproduce)

  1. 查看官方示例:http://echarts.baidu.com/echarts2/doc/example/map13.html

    期望结果 (Expected behaviour)

世界地图的中心点可以定制

可能哪里有问题 (What went wrong)

ECharts配置项 (ECharts option)

option = {

}

现在是这样 (Other comments)

default

希望是这样 (Other comments)

world1

pending stale

Most helpful comment

这个issue涉及的问题太多了,我提供一点思路供大家参考。如果我对问题理解有偏差,指正我。

1. 制作主题地图(Thematic Maps)和瓦片底图(Tile Maps)是不一样的。

  • 上面第一张图是主题地图,这个例子是典型的地区分布图(choropleth map)。基于GeoJSON这种数据格式里的地理信息以及对应属性(比如一个大州为一个多边形,可以为这个多边形赋予你需要的属性,该例是每个州作为出境目的地的人口统计),Echarts提供了接口帮你把每个州不同人口数通过一组发散颜色方案(diverging color scheme)可视化出来。但是GeoJSON本身并不包含任何中心点信息(GeoJSON规范)。不需要中心点的原因是最终只需呈现出这些多边形组成的边界框(bbox - bounding @box)就可以完全覆盖所有需要可视化的区域。 @pissang 提到自行编辑GeoJSON,我也很想知道要怎么弄。

  • 我其实不知道提这个问题的朋友是因为没有实例还是其他什么原因,因为第二张图已经完全和可视化没关系了,更像一张瓦片图。而要制作瓦片图是相当复杂的,首先瓦片图最基本分为栅格瓦片(Raster Tile)和矢量瓦片(Vector Tile),一般用作一个地图应用的底图,基于底图你可以叠加其他不同的图层。制作这种图的专业工具有很多,比如桌面应用ArcGIS(国外软件,商用),QGIS(国外软件,开源),SuperMap(国内软件,商用)和 MapGIS(国内软件,商用),或者网络应用MapboxOpenGeo Suite等。用这类软件制作完之后,一般会发布为符合OGC标准的服务,比如WMSWMTS。之后就可以把底图加载到地图应用中。而你使用的地图应用框架(比如百度地图,Echarts,GoogleMap, OpenLayers, Leaflet, Mapbox GL等等)会提供API让你指定地图中心和zoom level。之后就算加载了主题地图图层,地图也是被定位在指定中心的。

2. 解决这个issue需要注意的地方。

  • 如果只是想简单的修改地图中心,用Echarts先加载一个底图(不知道Echarts有没有提供空白底图,如果有是最好的),然后加载主题地图图层,之后用API指定地图中心和zoom level即可。
  • 如果非要做成第二张那种样式,你可以用上面讲的方法发布底图服务并加载到百度地图,之后再用Echarts和你的GeoJSON数据制作单独的主题地图图层。或者你可以直接把它们合并成一个地图服务也行,这样就不需要用Echarts处理主题地图了。
  • 需要注意,第二张图的投影不是通常GoogleMap,BingMap,OpenStreetMap,百度地图用的Web Mercator(EPSG:3857)。具体是哪种,你可以参考这里。顺便提一句,每种地图投影都有自己的优劣,不存在绝对好的投影,因为到目前为止,数学家也没有办法完美的将三维椭球体投影在二维平面上,因此出现了各种投影法解决不同需求。比如Web Mercator的好处是在街道这个级别,保持所有街道角度是准确的,由于大部分用户是用地图导航,所以保证街道角度的准确很重要。而缺点是在全球视角的时候,靠近南北两极的地区变形严重,比如格林兰看起来非常大,其实它没有这么大。
  • 如果觉得Echarts不能满足全部需求,用D3也可以,例子很多,我找了一个。不过这种可视化是基于SVG操作,看你选择了。

All 21 comments

需要自行编辑 geoJson 文件

OK, 可以说具体一点或有DEMO链接吗

@pissang 同求解决方法谢谢。

@pissang 请问如何编辑?有什么工具吗?

请问问题解决了吗

这个issue涉及的问题太多了,我提供一点思路供大家参考。如果我对问题理解有偏差,指正我。

1. 制作主题地图(Thematic Maps)和瓦片底图(Tile Maps)是不一样的。

  • 上面第一张图是主题地图,这个例子是典型的地区分布图(choropleth map)。基于GeoJSON这种数据格式里的地理信息以及对应属性(比如一个大州为一个多边形,可以为这个多边形赋予你需要的属性,该例是每个州作为出境目的地的人口统计),Echarts提供了接口帮你把每个州不同人口数通过一组发散颜色方案(diverging color scheme)可视化出来。但是GeoJSON本身并不包含任何中心点信息(GeoJSON规范)。不需要中心点的原因是最终只需呈现出这些多边形组成的边界框(bbox - bounding @box)就可以完全覆盖所有需要可视化的区域。 @pissang 提到自行编辑GeoJSON,我也很想知道要怎么弄。

  • 我其实不知道提这个问题的朋友是因为没有实例还是其他什么原因,因为第二张图已经完全和可视化没关系了,更像一张瓦片图。而要制作瓦片图是相当复杂的,首先瓦片图最基本分为栅格瓦片(Raster Tile)和矢量瓦片(Vector Tile),一般用作一个地图应用的底图,基于底图你可以叠加其他不同的图层。制作这种图的专业工具有很多,比如桌面应用ArcGIS(国外软件,商用),QGIS(国外软件,开源),SuperMap(国内软件,商用)和 MapGIS(国内软件,商用),或者网络应用MapboxOpenGeo Suite等。用这类软件制作完之后,一般会发布为符合OGC标准的服务,比如WMSWMTS。之后就可以把底图加载到地图应用中。而你使用的地图应用框架(比如百度地图,Echarts,GoogleMap, OpenLayers, Leaflet, Mapbox GL等等)会提供API让你指定地图中心和zoom level。之后就算加载了主题地图图层,地图也是被定位在指定中心的。

2. 解决这个issue需要注意的地方。

  • 如果只是想简单的修改地图中心,用Echarts先加载一个底图(不知道Echarts有没有提供空白底图,如果有是最好的),然后加载主题地图图层,之后用API指定地图中心和zoom level即可。
  • 如果非要做成第二张那种样式,你可以用上面讲的方法发布底图服务并加载到百度地图,之后再用Echarts和你的GeoJSON数据制作单独的主题地图图层。或者你可以直接把它们合并成一个地图服务也行,这样就不需要用Echarts处理主题地图了。
  • 需要注意,第二张图的投影不是通常GoogleMap,BingMap,OpenStreetMap,百度地图用的Web Mercator(EPSG:3857)。具体是哪种,你可以参考这里。顺便提一句,每种地图投影都有自己的优劣,不存在绝对好的投影,因为到目前为止,数学家也没有办法完美的将三维椭球体投影在二维平面上,因此出现了各种投影法解决不同需求。比如Web Mercator的好处是在街道这个级别,保持所有街道角度是准确的,由于大部分用户是用地图导航,所以保证街道角度的准确很重要。而缺点是在全球视角的时候,靠近南北两极的地区变形严重,比如格林兰看起来非常大,其实它没有这么大。
  • 如果觉得Echarts不能满足全部需求,用D3也可以,例子很多,我找了一个。不过这种可视化是基于SVG操作,看你选择了。

这个问题解决了吗? 或者是否有其他配置?

我至今未找到解决方案。理论上来说,需要把现有的geojson以新的中心为基准重新绘制。是的,d3可以做到。但是,我们需要的是重新绘制之后的geojson。d3是直接画成了svg,我未找到能输出geojson的选项。

我也遇到这个问题,有个简单的思路,将所有大于0的经度减180,小于0的经度加180,这样绘制地图的中心点就在太平洋中央了。但是其他描绘点位的操作也要做坐标的转换,否则会造成位置偏移。

我以为boundingCoords参数可以解决这个问题,但是测试之后发现没有用,而且boundingCoords参数完全没有效果,不太清楚这个参数是干什么的,和center是一样的吗

我找过了,geojson是不能随意设置地图中心的。唯一途径是改动echarts 来画。这也是d3的强项:你给我一个projection,center,zoom 我给你画。同时这也是个弱项:有多少人的脑袋能弄清楚这三个选项并呈现最佳地图呢?

我会改 联系qq89434057

将以非洲为中心的geojson改成以亚洲为中心的geojson,方法如下:

// 对纬度进行偏移
const processLng = lng => {
    return lng > -30 ? lng - 150 : lng + 210
}

//引入世界地图
import worldMap from '../data/world.json'

const coordinatesList = []

// 对世界地图的json文件中的经纬度坐标进行处理
worldMap.features.map(district => {
    if (district.geometry.type == 'Polygon') {
      district.geometry.coordinates.map(border => {
        border.map(coord => {
          coord[0] = processLng(coord[0])
          coordinatesList.push(coord)
        })
      })
  } else {
      district.geometry.coordinates.map(border => {
        border.map(coordinates => {
          coordinates.map(coord => {
            coord[0] = processLng(coord[0])
            coordinatesList.push(coord)
          })
        })
      })
    }
  })

这样世界地图的效果变成了期望的效果:
world

@liiiku, 格陵兰岛被外星人👽带走了。

这是我得到的效果:

Screenshot 2019-06-10 at 21 00 23

以上是所谓的 Antimeridian Cutting,你我都不是第一个人看到这个,看看其他人的抱怨吧

通过运用“数据可视化沙皇”的新工具,我可以实现满意的效果:

Screenshot 2019-06-10 at 23 11 06

非常感谢,提供该功能方法,请问,这个从echarts哪个版本开始,可以支持?

在 2019-06-10 23:04:04,"xiaopang" notifications@github.com 写道:

将以非洲为中心的geojson改成以亚洲为中心的geojson,方法如下:

// 对纬度进行偏移

const processLng = lng => {

return lng > -30 ? lng - 150 : lng + 210

}

//引入世界地图

import worldMap from '../data/world.json'

const coordinatesList = []

// 对世界地图的json文件中的经纬度坐标进行处理

worldMap.features.map(district => {

if (district.geometry.type == 'Polygon') {

  district.geometry.coordinates.map(border => {

    border.map(coord => {

      coord[0] = processLng(coord[0])

      coordinatesList.push(coord)

    })

  })

} else {

  district.geometry.coordinates.map(border => {

    border.map(coordinates => {

      coordinates.map(coord => {

        coord[0] = processLng(coord[0])

        coordinatesList.push(coord)

      })

    })

  })

}

})

这样世界地图的效果变成了期望的效果:


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

将以非洲为中心的geojson改成以亚洲为中心的geojson,方法如下:

// 对纬度进行偏移
const processLng = lng => {
    return lng > -30 ? lng - 150 : lng + 210
}

//引入世界地图
import worldMap from '../data/world.json'

const coordinatesList = []

// 对世界地图的json文件中的经纬度坐标进行处理
worldMap.features.map(district => {
    if (district.geometry.type == 'Polygon') {
      district.geometry.coordinates.map(border => {
        border.map(coord => {
          coord[0] = processLng(coord[0])
          coordinatesList.push(coord)
        })
      })
  } else {
      district.geometry.coordinates.map(border => {
        border.map(coordinates => {
          coordinates.map(coord => {
            coord[0] = processLng(coord[0])
            coordinatesList.push(coord)
          })
        })
      })
    }
  })

这样世界地图的效果变成了期望的效果:

自己按照这个方法实现是这个效果
3}CV_DP4T`USZC2CKLE5RA4

@liiiku

@ZhaoyangRao 以上是所谓的 Antimeridian Cutting,具体看楼上。

//格林兰岛表现怪异我把它单独进行了处理 就正常了

SZ{4973`<a href="FH@V6L@IUT2">FH@V6L@IUT2</a>}@AJ

// 对世界地图的json文件中的经纬度坐标进行处理
const processLng = lng => {
if (lng > -30) {
lng = lng - 180
} else {
lng = lng + 180
}
return lng
}
//格林兰岛表现怪异
const processLngGe = lng => {
return lng + 180
}
WORLDJSON.features.map((district, index) => {
if (district.properties.name == 'Greenland') {
// WORLDJSON.features.splice(index, 1)
if (district.geometry.type == 'Polygon') {
district.geometry.coordinates.map(border => {
border.map(coord => {
coord[0] = processLngGe(coord[0])

                })
            })
        } else {
            district.geometry.coordinates.map(border => {
                border.map(coordinates => {
                    coordinates.map(coord => {
                        coord[0] = processLngGe(coord[0])
                    })
                })
            })
        }
    } else {
        if (district.geometry.type == 'Polygon') {
            district.geometry.coordinates.map(border => {
                border.map(coord => {
                    coord[0] = processLng(coord[0])

                })
            })
        } else {
            district.geometry.coordinates.map(border => {
                border.map(coordinates => {
                    coordinates.map(coord => {
                        coord[0] = processLng(coord[0])
                    })
                })
            })
        }
    }

})

//格林兰岛表现怪异我把它单独进行了处理 就正常了

SZ{4973`<a href="FH@V6L@IUT2">FH@V6L@IUT2</a>}@AJ

// 对世界地图的json文件中的经纬度坐标进行处理
const processLng = lng => {
if (lng > -30) {
lng = lng - 180
} else {
lng = lng + 180
}
return lng
}
//格林兰岛表现怪异
const processLngGe = lng => {
return lng + 180
}
WORLDJSON.features.map((district, index) => {
if (district.properties.name == 'Greenland') {
// WORLDJSON.features.splice(index, 1)
if (district.geometry.type == 'Polygon') {
district.geometry.coordinates.map(border => {
border.map(coord => {
coord[0] = processLngGe(coord[0])

                })
            })
        } else {
            district.geometry.coordinates.map(border => {
                border.map(coordinates => {
                    coordinates.map(coord => {
                        coord[0] = processLngGe(coord[0])
                    })
                })
            })
        }
    } else {
        if (district.geometry.type == 'Polygon') {
            district.geometry.coordinates.map(border => {
                border.map(coord => {
                    coord[0] = processLng(coord[0])

                })
            })
        } else {
            district.geometry.coordinates.map(border => {
                border.map(coordinates => {
                    coordinates.map(coord => {
                        coord[0] = processLng(coord[0])
                    })
                })
            })
        }
    }

})

请问可以提供个 demo 页吗?

Was this page helpful?
0 / 5 - 0 ratings