360SDN.COM

首页/GIS/列表

Cesium 概述 (二) 空间数据可视化

来源:  2018-07-04 14:17:28    评论:0点击:

          空间数据可视化

Cesium提供Entity API来绘制空间数据,例如点、标记、标签、线、3D模型、形状、立体形状(volume)。

Entity API简介

Cesium提供两类API:

    (1)面向图形开发人员的底层API,通常称为“Primitive API”。该API暴露最小限度的抽象,使用图形学术语,具有很大的灵活性,需要具有图形学编程的知识
    (2)高级别的数据驱动的API,称为“Entity API”。该API使用一致性设计的、高级别的对象来管理一组相关性的可视化对象,其底层使用Primitive API

下面是Entity API的简单例子,用红色半透明区域标记出美国怀俄明州:

    var viewer = new Cesium.Viewer('cesiumContainer'); //创建一个查看器(Viewer widget)
    var wyoming = viewer.entities.add({  //添加一个实体,仅需要传递一个简单JSON对象,返回值是一个Entity对象
      name : 'Wyoming',
      polygon : {
        hierarchy : Cesium.Cartesian3.fromDegreesArray([//一组地理坐标
                                  -109.080842,45.002073,
                                  -105.91517,45.002073,
                                  -104.058488,44.996596,
                                  -104.053011,43.002989,
                                  -104.053011,41.003906,
                                  -105.728954,40.998429,
                                  -107.919731,41.003906,
                                  -109.04798,40.998429,
                                  -111.047063,40.998429,
                                  -111.047063,42.000709,
                                  -111.047063,44.476286,
                                  -111.05254,45.002073]),
        material : Cesium.Color.RED.withAlpha(0.5), //材质
        outline : true, //是否显示轮廓
        outlineColor : Cesium.Color.BLACK //轮廓的颜色
      }
    });
    viewer.zoomTo(wyoming);//缩放、平移视图使实体可见

形状与立体(Shapes and Volumes)

支持的形状与立体列表

(1) 立方体(Boxes):

    var blueBox = viewer.entities.add({
        name : 'Blue box',
         //中心的位置
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        box : {
            //长宽高
            dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
            material : Cesium.Color.BLUE
        }
    });
     
    var redBox = viewer.entities.add({
        name : 'Red box with black outline',
        position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
        box : {
            dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
            material : Cesium.Color.RED,
            outline : true, //显示轮廓
            outlineColor : Cesium.Color.BLACK
        }
    });
     
    var outlineOnly = viewer.entities.add({
        name : 'Yellow box outline',
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
        box : {
            dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
            fill : false,  //不显示填充
            outline : true,
            outlineColor : Cesium.Color.YELLOW
        }
    });


(2)圆和椭圆(Circles Ellipses)

    var viewer = new Cesium.Viewer('cesiumContainer');
    //浮空的绿色圆形
    var greenCircle = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-111.0, 40.0, 150000.0),
        name : 'Green circle at height',
        ellipse : {
            semiMinorAxis : 300000.0,
            semiMajorAxis : 300000.0,
            height: 200000.0, //浮空
            material : Cesium.Color.GREEN
        }
    });
    //红色椭圆形,位于地表,带轮廓
    var redEllipse = viewer.entities.add({
        //不带高度
        position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0),
        name : 'Red ellipse on surface with outline',
        ellipse : {
            semiMinorAxis : 250000.0,
            semiMajorAxis : 400000.0,
            material : Cesium.Color.RED.withAlpha(0.5),
            outline : true,
            outlineColor : Cesium.Color.RED
        }
    });
    //蓝色椭圆柱,旋转了角度
    var blueEllipse = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0),
        name : 'Blue translucent, rotated, and extruded ellipse',
        ellipse : {
            semiMinorAxis : 150000.0,
            semiMajorAxis : 300000.0,
            extrudedHeight : 200000.0,  //拉伸
            rotation : Cesium.Math.toRadians(45), //旋转
            material : Cesium.Color.BLUE.withAlpha(0.7),
            outline : true
        }
    });
     
    viewer.zoomTo(viewer.entities);

(3)走廊(Corridor)

    var redCorridor = viewer.entities.add({
        name : 'Red corridor on surface with rounded corners and outline',
        corridor : {
            positions : Cesium.Cartesian3.fromDegreesArray([
                                                            -100.0, 40.0,
                                                            -105.0, 40.0,
                                                            -105.0, 35.0
                                                        ]),
                                                        width : 200000.0,
            material : Cesium.Color.RED.withAlpha(0.5),
            outline : true,
            outlineColor : Cesium.Color.RED
        }
    });
     
    var greenCorridor = viewer.entities.add({
        name : 'Green corridor at height with mitered corners',
        corridor : {
            positions : Cesium.Cartesian3.fromDegreesArray(
            [    -90.0, 40.0,
                 -95.0, 40.0,
                 -95.0, 35.0
            ]),
            height: 100000.0,
            width : 200000.0,
            cornerType: Cesium.CornerType.MITERED,
            material : Cesium.Color.GREEN
        }
    });
     
    var blueCorridor = viewer.entities.add({
        name : 'Blue extruded corridor with beveled corners and outline',
        corridor : {
            positions : Cesium.Cartesian3.fromDegreesArray(
            [    80.0, 40.0,
                 -85.0, 40.0,
                 -85.0, 35.0
            ]),
            height : 200000.0,
            extrudedHeight : 100000.0,
            width : 200000.0,
            cornerType: Cesium.CornerType.BEVELED,
            material : Cesium.Color.BLUE.withAlpha(0.5),
            outline : true,
            outlineColor : Cesium.Color.BLUE
        }
    });


(4)圆柱和圆锥(Cylinder Cones)

    var greenCylinder = viewer.entities.add({
        name : 'Green cylinder with black outline',
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),
        cylinder : { //圆柱
            length : 400000.0,
            topRadius : 200000.0,
            bottomRadius : 200000.0,
            material : Cesium.Color.GREEN,
            outline : true,
            outlineColor : Cesium.Color.DARK_GREEN
        }
    });
     
    var redCone = viewer.entities.add({
        name : 'Red cone',
        position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0),
        cylinder : {//圆锥
            length : 400000.0,
            topRadius : 0.0,
            bottomRadius : 200000.0,
            material : Cesium.Color.RED
        }
    });


(5) 多边形(Polygons)

    var redPolygon = viewer.entities.add({
        name : '贴着地表的多边形',
        polygon : {
            hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,
                                                            -115.0, 32.0,
                                                            -107.0, 33.0,
                                                            -102.0, 31.0,
                                                            -102.0, 35.0]),
            material : Cesium.Color.RED
        }
    });
     
    var greenPolygon = viewer.entities.add({
        name : '绿色拉伸多边形',
        polygon : {
            hierarchy : Cesium.Cartesian3.fromDegreesArray([-108.0, 42.0,
                                                            -100.0, 42.0,
                                                            -104.0, 40.0]),
            extrudedHeight: 500000.0,
            material : Cesium.Color.GREEN
        }
    });
     
    var orangePolygon = viewer.entities.add({
        name : '每个顶点具有不同拉伸高度的橘色多边形',
        polygon : {
            hierarchy : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-108.0, 25.0, 100000,
                 -100.0, 25.0, 100000,
                 -100.0, 30.0, 100000,
                 -108.0, 30.0, 300000]),
            extrudedHeight: 0,
            perPositionHeight : true,
            material : Cesium.Color.ORANGE,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
     
    var bluePolygon = viewer.entities.add({
        name : '具有挖空效果的蓝色多边形',
        polygon : {
            hierarchy : {
                positions : Cesium.Cartesian3.fromDegreesArray(
                    [-99.0, 30.0,
                     -85.0, 30.0,
                     -85.0, 40.0,
                     -99.0, 40.0]),
                holes : [{
                    positions : Cesium.Cartesian3.fromDegreesArray([
                        -97.0, 31.0,
                        -97.0, 39.0,
                        -87.0, 39.0,
                        -87.0, 31.0
                    ]),
                    holes : [{
                        positions : Cesium.Cartesian3.fromDegreesArray([
                            -95.0, 33.0,
                            -89.0, 33.0,
                            -89.0, 37.0,
                            -95.0, 37.0
                        ]),
                        holes : [{
                            positions : Cesium.Cartesian3.fromDegreesArray([
                                -93.0, 34.0,
                                -91.0, 34.0,
                                -91.0, 36.0,
                                -93.0, 36.0
                            ])
                        }]
                    }]
                }]
            },
            material : Cesium.Color.BLUE,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });


(6)多段线(Polylines)

    var redLine = viewer.entities.add({
        name : '沿着地球表面的红线',
        polyline : {
            positions : Cesium.Cartesian3.fromDegreesArray(
                [-75, 35,
                 -125, 35]),
            width : 5,
            material : Cesium.Color.RED
        }
    });
     
    var glowingLine = viewer.entities.add({
        name : '具有发光效果的线',
        polyline : {
            positions : Cesium.Cartesian3.fromDegreesArray(
                [-75, 37, -125, 37]
            ),
            width : 10,
            material : new Cesium.PolylineGlowMaterialProperty({
                glowPower : 0.2,
                color : Cesium.Color.BLUE
            })
        }
    });
     
    var orangeOutlined = viewer.entities.add({
        name : '具有一定高度的线',
        polyline : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-75, 39, 250000,-125, 39, 250000]
            ),
            width : 5,
            material : new Cesium.PolylineOutlineMaterialProperty({
                color : Cesium.Color.ORANGE,
                outlineWidth : 2,
                outlineColor : Cesium.Color.BLACK
            })
        }
    });
     
    var yellowLine = viewer.entities.add({
        name : '不贴着地表的线',
        polyline : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-75, 43, 500000,-125, 43, 500000]
            ),
            width : 3,
            followSurface : false,  //是否贴着地表
            material : Cesium.Color.PURPLE
        }
    });

(7)多段线体(Polyline Volumes)

    var viewer = new Cesium.Viewer('cesiumContainer');
     
    function computeCircle(radius) {
        var positions = [];
        for (var i = 0; i < 360; i++) {
            var radians = Cesium.Math.toRadians(i);
            positions.push(new Cesium.Cartesian2(
                radius * Math.cos(radians), radius * Math.sin(radians)));
        }
        return positions;
    }
     
    function computeStar(arms, rOuter, rInner) {
        var angle = Math.PI / arms;
        var length = 2 * arms;
        var positions = new Array(length);
        for (var i = 0; i < length; i++) {
            var r = (i % 2) === 0 ? rOuter : rInner;
            positions[i] = new Cesium.Cartesian2(
                Math.cos(i * angle) * r, Math.sin(i * angle) * r);
        }
        return positions;
    }
     
    var redTube = viewer.entities.add({
        name : 'Red tube with rounded corners',
        polylineVolume : {
            positions : Cesium.Cartesian3.fromDegreesArray(
                [-85.0, 32.0,
                 -85.0, 36.0,
                 -89.0, 36.0]),
            shape : computeCircle(60000.0),
            material : Cesium.Color.RED
        }
    });
     
    var greenBox = viewer.entities.add({
        name : 'Green box with beveled corners and outline',
        polylineVolume : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-90.0, 32.0, 0.0,
                 -90.0, 36.0, 100000.0,
                 -94.0, 36.0, 0.0]),
            shape :[new Cesium.Cartesian2(-50000, -50000),
                    new Cesium.Cartesian2(50000, -50000),
                    new Cesium.Cartesian2(50000, 50000),
                    new Cesium.Cartesian2(-50000, 50000)],
            cornerType : Cesium.CornerType.BEVELED,
            material : Cesium.Color.GREEN,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
     
    var blueStar = viewer.entities.add({
        name : 'Blue star with mitered corners and outline',
        polylineVolume : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-95.0, 32.0, 0.0,
                 -95.0, 36.0, 100000.0,
                 -99.0, 36.0, 200000.0]),
            shape : computeStar(7, 70000, 50000),
            cornerType : Cesium.CornerType.MITERED,
            material : Cesium.Color.BLUE,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
     
    viewer.zoomTo(viewer.entities);


(8)矩形(Rectangles)

    <strong>//红色矩形
    var redRectangle = viewer.entities.add({
        name : 'Red translucent rectangle with outline',
        rectangle : {
            coordinates : Cesium.Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0),
            material : Cesium.Color.RED.withAlpha(0.5),
            outline : true,
            outlineColor : Cesium.Color.RED
        }
    });
    //绿色旋转、拉伸的矩形
    var greenRectangle = viewer.entities.add({
        name : 'Green translucent, rotated, and extruded rectangle',
        rectangle : {
            coordinates : Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0),
            material : Cesium.Color.GREEN.withAlpha(0.5),
            rotation : Cesium.Math.toRadians(45),
            extrudedHeight : 300000.0,
            height : 100000.0,
            outline : true,
            outlineColor : Cesium.Color.GREEN
        }
    });</strong>


(9)球和椭球(Spheres Ellipsoids)

    <pre name="code" class="javascript">var blueEllipsoid = viewer.entities.add({
        name : 'Blue ellipsoid',
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        ellipsoid : {
            //可以指定三个轴的半径
            radii : new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            material : Cesium.Color.BLUE
        }
    });
     
    var redSphere = viewer.entities.add({
        name : 'Red sphere with black outline',
        position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
        ellipsoid : {
            //正球体
            radii : new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),
            material : Cesium.Color.RED,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
     
    var outlineOnly = viewer.entities.add({
        name : 'Yellow ellipsoid outline',
        position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
        ellipsoid : {
            radii : new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
            fill : false,
            outline : true,
            outlineColor : Cesium.Color.YELLOW,
            slicePartitions : 24, //横向切割线
            stackPartitions : 36  //纵向切割线
        }
    });



(10) 墙(Walls)

    //东西方向的横墙
    var redWall = viewer.entities.add({
        name : 'Red wall at height',
        wall : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                 [-115.0, 44.0, 200000.0,//坐标点
                  -90.0, 44.0, 200000.0]
            ),
            minimumHeights : [100000.0, 100000.0], //按坐标点的最小高度数组
            material : Cesium.Color.RED
        }
    });
    //四边围墙
    var greenWall = viewer.entities.add({
        name : 'Green wall from surface with outline',
        wall : {
            positions : Cesium.Cartesian3.fromDegreesArrayHeights(
                [-107.0, 43.0, 100000.0,
                 -97.0, 43.0, 100000.0,
                 -97.0, 40.0, 100000.0,
                 -107.0, 40.0, 100000.0,
                 -107.0, 43.0, 100000.0]),
            material : Cesium.Color.GREEN,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });
    //曲折的墙
    var blueWall = viewer.entities.add({
        name : 'Blue wall with sawtooth heights and outline',
        wall : {
            //坐标点,不指定高度
            positions : Cesium.Cartesian3.fromDegreesArray(
                [-115.0, 50.0,
                 -112.5, 50.0,
                 -110.0, 50.0,
                 -107.5, 50.0,
                 -105.0, 50.0,
                 -102.5, 50.0,
                 -100.0, 50.0,
                 -97.5, 50.0,
                 -95.0, 50.0,
                 -92.5, 50.0,
                 -90.0, 50.0]),
            maximumHeights : [ //上高
                100000, 200000, 100000, 200000, 100000, 200000,
                100000, 200000, 100000, 200000, 100000],
            minimumHeights : [  //下高
                0, 100000,  0, 100000, 0, 100000, 0, 100000, 0,
                100000, 0],
            material : Cesium.Color.BLUE,
            outline : true,
            outlineColor : Cesium.Color.BLACK
        }
    });


材质(Material)与轮廓(Outline)

多数形状均支持通过一致的方式来设置属性、控制外观:

    (1)fill:布尔型,用于指定目标形状是否被填充
    (2)outline:布尔型,用于指定是否绘制形状的边缘
    (3)material:如果fill为true,该属性可以控制填充的材质类型

一个例外是多段线,可以设置outlineWidth 、outlineColor、glowPower 等属性。
高度与拉伸(Extrusion)

所有的形状均默认均是沿着地表的,目前圆形、椭圆、矩形可以在一定高度浮空显示,或者拉伸为Volume。

需要注意:Cesium总是使用米、弧度、秒为度量单位。下面是一个例子:

    wyoming.polygon.height = 200000;         //设置高度
    wyoming.polygon.extrudedHeight = 250000; //设置拉伸高度

在Viewer中可用的Entity特性

除非显式禁用,点击实体后会显示SelectionIndicator小器件,以及一个信息框。通过设置Entity.description,可以在信息框中显示任何HTML内容。
镜头控制

zoomTo方法可以立即定位到某个位置,而flyTo则是通过动画方式转移到某个位置,这两个方法均可以传递EntityCollection对象,并且均是异步方法,返回一个Promises对象

默认情况下,镜头是朝北、45度倾斜查看地球。下面的代码可以让镜头朝东、倾斜三十度查看:

    //镜头顺时针旋转九十度,即东向
    var heading = Cesium.Math.toRadians(90);
    //镜头倾斜30度俯视
    var pitch = Cesium.Math.toRadians(-30);
    viewer.zoomTo(wyoming, new Cesium.HeadingPitchRange(heading, pitch)).then(function(result){
        //执行完毕后,进行的动作
        if (result) { //如果镜头切换成功,则result=true
            viewer.selectedEntity = wyoming;
        }
    });


有时需要镜头跟踪某个实体(使居中)而不是地球,可以使用如下代码:

    wyoming.position = Cesium.Cartesian3.fromDegrees(-107.724, 42.68);
    viewer.trackedEntity = wyoming;  //跟踪某个实体。如果调用zoomTo、flyTo自动取消跟踪

管理Entity

EntityCollection对象是一个从Entity Id到Entity的关联数组,其提供例如add、remove、removeAll之类的常规函数,用于添加或者删除某个Entity:

    //添加一个实体,并且提供ID
    viewer.entities.add({
      id : '182bdba4-2b3e-47ae-bf0b-83f6fde285fd'
    });
    //获取一个实体
    var entity = viewer.entities.getById('uniqueId')
    //获取一个实体,如果不存在则创建之
    var entity = viewer.entities.getOrCreateEntity('uniqueId');
     
    //当添加、删除、修改EntityCollection中的Entity时,可以获得事件通知
    function onChanged(collection, added, removed, changed){
        //add、removed、changed是增删改的Entity数组
        for(var i = 0; i < added.length; i++) {
            
        }
    }
    viewer.entities.collectionChanged.addEventListener(onChanged);
     
    //大批量操作时,临时禁用事件可以提高性能
    viewer.entities.suspendEvents();
    //执行各种Entity操作
    viewer.entities.resumeEvents();

点、图标和标签

添加一个点、标签或者图标很简单:

    var viewer = new Cesium.Viewer( 'cesiumContainer' );
     
    var citizensBankPark = viewer.entities.add( {
        name : 'Citizens Bank Park',
        position : Cesium.Cartesian3.fromDegrees( -75.166493, 39.9060534 ),
        point : { //点
            pixelSize : 5,
            color : Cesium.Color.RED,
            outlineColor : Cesium.Color.WHITE,
            outlineWidth : 2
        },
        label : { //文字标签
            text : 'Citizens Bank Park',
            font : '14pt monospace',
            style : Cesium.LabelStyle.FILL_AND_OUTLINE,
            outlineWidth : 2,
            verticalOrigin : Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
            pixelOffset : new Cesium.Cartesian2( 0, -9 )   //偏移量
        }
        billboard : { //图标
            image : 'http://localhost:81/images/2015/02-02/Philadelphia_Phillies.png',
            width : 64,
            height : 64
        },
    } );
     
    viewer.zoomTo( viewer.entities );

3D模型

Cesium支持glTF格式的3D模型,glTF是WebGL、 OpenGL ES、 OpenGL的一种运行时模型格式,在Cesium中创建3D模型很简单:

    var viewer = new Cesium.Viewer('cesiumContainer');
    var entity = viewer.entities.add({
        position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
        model : {
            uri : '../../SampleData/models/CesiumGround/Cesium_Ground.gltf'
        },
        scale : 1,//和原始大小相比的缩放比例
        minimumPixelSize :100 //最小尺寸,防止太小而看不见
    });
    viewer.trackedEntity = entity;


默认情况下,模型竖直放置、并且面向东面。可以指定四元组(Quaternion)给Entity.orientation属性,以改变放置的方向:

    var viewer = new Cesium.Viewer('cesiumContainer');
    var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706); //位置
    var heading = Cesium.Math.toRadians(45.0);//绕垂直于地心的轴旋转
    var pitch = Cesium.Math.toRadians(15.0);  //绕纬度线旋转
    var roll = Cesium.Math.toRadians(0.0);    //绕经度线旋转
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, heading, pitch, roll);
     
    var entity = viewer.entities.add({
        position : position,
        orientation : orientation,
        model : {
            uri : '../../SampleData/models/CesiumGround/Cesium_Ground.gltf'
        }
    });
    viewer.trackedEntity = entity;

例子中的heading(yaw)、pitch、roll对应了绕Z(垂直轴)、Y(维度方向)、X(经度方向)进行旋转,正数表示顺时针旋转(由于相对运动,在浏览器上看起来是地球在逆时针旋转),可以参考下图理解(人面向北面,摇头heading、点头pitch、歪头roll):

                            

属性系统

Cesium提供了一些快捷方式来设置属性,例如outline:true,但是尝试使用e.polygon.outline这样的形式来获取轮廓时,会得到一个ConstantProperty对象,如果不使用快捷方式,则需要编写更多的代码,例如:

    polygon.outline = new Cesium.ConstantProperty(true);
    polygon.outlineColor = new Cesium.ConstantProperty(Cesium.Color.BLACK);


所有属性的实例均是Property的子类型,引入属性类层次而不是使用基本类型的原因是,某些属性是随着时间而变化的。

要得到属性的原始值,需要调用Property.getValue()方法,例如:

    //获取当前时间点,多边形轮廓是否存在
    polygon.outline.getValue(viewer.clock.currentTime)


来源:https://blog.csdn.net/happyduoduo1/article/details/51865811
为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权