KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现

时间:2024-04-12 08:43:07

KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现

项目需求

展现成都市地铁拓扑网络,要求要美观,性能要求高;美观方面,要求连线要平滑,地图缩放的时候没有延迟情况;要求支持10万也上的用户访问;客户端有web浏览器端,手机端等;用户点击站点可以看见站点的信息,拥挤成都等信息;地铁采用双线的方式显示,使用颜色表示该路段的拥挤程度;

思考

  1. 考虑到成都市地铁数据不大,可以通过离线下载到客户端的方式实现,这样可以解决地图大量用户访问的问题;这样就排除了使用动态地图等方案;
  2. 由于用户要求的是拓扑网络,所以数据应该是逻辑的,不是实际的;这个可以参考地铁上的车站图;连线要采用B样条曲线连接;
  3. 地图缩放的时候,需要重绘数据,可能会出现一个短暂的停顿情况,如下视频1所示;可以采用webgl/canvas/svg三种方式来解决,他们各自的优缺点可以在互联网上找到;我这里地铁的底图是不变的,我采用的是svg文件的方式绘制,逻辑网络在后台完成;拥堵情况采用webgl来绘制;
  4. 点击站点,通过气泡的方式显示站点的信息;这个需要在gis中有对应的要素,可以采用一个透明的图片的方式来实现;

实现

后台的工作需要通过KCGIS 地图平台生成逻辑点生成拓扑网络;

  1. 从用户哪里获取到所有站点的信息,连接关系等信息;通过arcmap等工具进行数据加工;当我们用到拐点的时候需要采用B样条插值计算;箭头所示的位置是一个隐藏的点,这个点是用于计算B样条.
    KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现
  2. 我们可以直接指定拓扑连接关系,录入天府广场是1号线和2号线的交叉口
    KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现
  3. 文字标注的位置,要通过用户指定的方式显示,一般分为在站点的上部,下部,左边,右边显示,如果发现有重叠,可以换一个位置显示;一般一条显示的站点,可以交叉的显示,例如前面一个在上面,后面一个就换成下面显示;
    KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现
  4. 地图查询这些功能,使用leaflet来加载SVG数据和空间数据;
  5. 这块需要考虑一个坐标匹配的问题,需要在后台处理好;
  6. 考虑后续要对每条线路进行图层控制显示,所以每条线路为一个图层
    **

前端实现

**

var map = L.map('map', { crs: L.CRS.EPSG3857 });
 
var myRenderer = L.svg({ padding: 0.5 });
 
var bounds = [[0, 0], [14.94, 20.00]];

function distance(x1, y1, x2, y2) {
    var calX =  Math.abs(x2 - x1);
    var calY =  Math.abs(y2 - y1);
    var d = Math.sqrt( calX * calX + calY * calY );
    return d;
}
 
function querySub(e)
{
    var text = "";
    var d = 100;
    var name = "";
    var x = e.latlng.lng;
    var y = e.latlng.lat;
    for(var i=0;i<points.length;i++)
    {
        var x1 = points[i].geometry.coordinates[0];
        var y1 = points[i].geometry.coordinates[1];
        var dd = distance(x, y, x1, y1);

        if (dd <d)
        {
            d = dd;
            name = points[i].properties.name;
        }
    }
    if (d < 0.15) {
        var popup = L.popup()
          .setLatLng(e.latlng)
          .setContent('当前站点是:' + name)
          .openOn(map);
    }
}

//每条线路为一个svg图层
var image0 = L.imageOverlay('subline0.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image1 = L.imageOverlay('subline1.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image2 = L.imageOverlay('subline2.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image3 = L.imageOverlay('subline3.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image4 = L.imageOverlay('subline4.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image5 = L.imageOverlay('subline5.svg', bounds, { opacity: 1, interactive: true }).on("click", querySub).addTo(map);
var image6 = L.imageOverlay('subline6.svg', bounds, { opacity:1, interactive: true }).on("click", querySub).addTo(map);
 

map.fitBounds(bounds);

var mark8 = {
    radius: 4,
    fillColor: "#fff",
    color: "#000",
    weight: 1,
    opacity: 1,
    fillOpacity: 1
};
var mark4 = {
    radius: 4,
    fillColor: "#fff",
    color: "#000",
    weight: 1,
    opacity: 1,
    fillOpacity: 1,
    labelAnchor: [4, -4]
};

function pointToLayer(feature, latlng) {

    var mark = L.circleMarker(latlng, mark4);
    if (feature.properties.t != null && feature.properties.t == 8)
        mark = L.circleMarker(latlng, mark8);
    return mark;
};

实现效果

KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现
KCGIS平台结合 Leaflet,SVG结合解决地铁拓扑网络展现
效果地址:
http://demo.cd-kc.com:8000/cdsubway/web/index2.html
http://demo.cd-kc.com:8000/cdsubway/web/index.html
更多信息请关注kcgis平台
联系方式:
QQ:823007509
网址:http://www.cd-kc.cn