精华内容
参与话题
问答
  • 中国高清地图

    2018-10-30 10:58:53
    中国高清地图,可供放大,高清查看地图,下载即可查看
  • 中国地图shp文件

    千次下载 热门讨论 2012-01-11 11:48:48
    1:400万shp文件,主要包括:国界、国界与省界、首都和省级行政中心、地级行政界线、县级行政界线、地市级以上居民地、县级居民地、主要公路、主要铁路、一级河流、三级以上河流、四级河流、五级河流
  • 全国分乡镇地图

    热门讨论 2014-08-12 20:47:53
    全国各省的分乡镇地图,详细得让你不敢相信。
  • 做过数据分析的人都知道,老板最喜欢的莫过于数据可视化,可视化中最喜欢的莫过于地图可视化。但是想要做地图可视化也并非易事,对于大多数人来说,Excel一直都是首选,但是Excel真的是实现地图可视化的最好工具吗?...

    做过数据分析的人都知道,老板最喜欢的莫过于数据可视化,可视化中最喜欢的莫过于地图可视化。但是想要做地图可视化也并非易事,对于大多数人来说,Excel一直都是首选,但是Excel真的是实现地图可视化的最好工具吗?

    目前市场上,能够实现地图可视化的工具有很多,可以分为编程类、平台类和软件类三种:

    • 编程类:Matlab、Python、Echarts
    • 平台类:FineBI、高德Maplab
    • 软件类:Excel

    当然,还有一些别的,如国外的BatchGeo、Fusion Tables等,这里就不一一列举了。

    究竟哪一个工具做地图可视化最简单、最省力、最强大呢?今天我们就来实测一下!

     

    地图可视化是什么?

    在此之前,我们先要知道什么是地图可视化?

    简单点说,地图可视化就是将地理数据转换成可视化形态,通过将具有地域特征的数据或者数据分析结果形象地表现在地图上,使得用户可以更加容易理解数据规律和趋势。

    通俗地讲,地图可视化可以将地理数据更清晰直白地展现出来,比如下面这种:

     

    FineBI热力图

    场景准备

    为了测试各个工具性能如何,我设计了一个简单的场景,使用各个工具制作可视化地图并对最后的效果进行对比。

    • 现有数据:2018年中国各省市常住人口数量(数据来自国家统计局-2018年统计年鉴)
    • 场景:需要通过地图可视化展示各省市人口的分布情况,方便进行直观对比

    制作可视化地图

    1、Excel

    Excel是大多数人都很熟悉的数据处理工具,将数据导入Excel中,选中省份和人口数两个字段后,再点击上方的三维地图,就进入了地图可视化编辑界面。

     

    然后,再将省份字段拖入位置选项,并选择省/市/自治区层级,将人口数字段拖入高度(值)选项,最后在类别选项中选择省份字段,切换为区域地图,一张各省市的常住人口可视化地图就完成了。

     

    评价:

    Excel实现地图可视化的操作相对来说较为简单,但是功能也比较少,类型只有柱形图、气泡图、热度图以及区域地图等,目前大数据领域常见的流向地图等并不在可选范围内,可用的主题也是微软经典的几款,显得有一些“视觉疲劳”。

    2、Echarts

    Echarts是一款商业级数据图表平台,它是一个纯JavaScript的图表库,因此使用Echarts进行地图可视化会稍显复杂,需要有一定JS基础才能较为轻松地上手。

    由于Echarts的官方示例没有区域地图的选项(一个小缺点),因此采用气泡图来进行展示。在Echarts中,数据需要预先进行清洗,再放入代码中。代码块主要分为三部分:字段定义地理位置、字段赋值以及图表框架搭建,部分代码如下所示:

     

    地理字段赋值部分代码

     

    图表框架搭建部分代码

    写了大约300行代码,完成了Echarts的可视化地图,气泡的大小表示各省市人口数量的对比,并且标出了人口数量Top5的省份。

     

    评价:

    纯JavaScript书写的特点让Echarts在实现地图可视化的过程中具有极大的自由度,但与此同时,也带来了上手难度大、花费时间长等问题,总体来看,Echarts作为一款国产工具,可以说瑕不掩瑜,推荐有编程基础的读者使用。

    3、FineBI

    FineBI是新一代自助大数据分析的商业智能产品,提供了从数据准备、自助数据处理、数据分析与挖掘、数据可视化于一体的完整解决方案,也是我比较推崇的可视化工具之一。

    下面就使用FineBI来演示地图可视化的过程。

    • 第一步:抽取数据

    其实就是将准备好的Excel上传到FineBI平台上,好在FineBI可以支持30多种数据库表,多维数据库、程序数据集等数据源,可以说很方便了。

     

    上传数据

    • 第二步:创建仪表板,进行地图可视化编辑

    数据抽取完成后,再添加一个仪表板用于制作和展示可视化地图,然后再添加一个组件,并选取刚上传的数据集,这样就进入了地图可视化编辑界面。

     

    可视化编辑界面

    将省份维度转换成地理角色,并将生成的经度和纬度分别拖入横、纵轴,同时,将人口数指标拖入颜色区域。全程只需要鼠标拖拽,完全不需要进行编程,一个高质量的可视化地图就完成了。

     

    FineBI可视化地图制作过程

    不仅如此,还可以添加组件对省份进行筛选过滤,比如我们需要查看江浙沪三地的情况:

     

    江浙沪三地视图

    同时,也可以根据人口数量区间进行筛选,比如人口数量在7000万以上的省份分布:

     

    人口数量7000万以上省份视图

    • 第三步:展示模板

    对于这一步展示,excel和echart是比不上FineBI的,因为FineBI平台可以将做好的地图可视化模板挂出,领导、同事都可以在平台上查看,不需要再制作PPT或者导出成pdf格式进行汇报,对于有工作需要的人来说,确实是一个大大解放了劳动力的功能。

     

    挂出展示模板

    评价:

    与其他几款工具对比,FineBI操作比较简单,完成效果也很出色。而且,除了上述功能之外,FineBI还支持实时数据更新、地图钻取、自定义区域、模板复用等功能,并涵盖了绝大部分的图表类型,丰富了地图可视化的实用性。

    总结

    通过实际体验三款地图可视化的工具,可以发现不同类型的工具各有各的特色:

    在操作方面,Excel无疑是最简单的,但是它的显示效果不佳,功能丰富性一般,并且用Excel做完图后还需要做一个PPT或者Word用于展示,额外了增加工作量;

    在功能丰富性方面,Echarts作为一款编程型工具占据了极大的优势,但是需要制作者有一定的编程基础,且花费的时间较长;

    在综合性方面,FineBI的表现比较突出,不需要编程而且简单易做,能够实现平台展示,比较适合企业用户,在数据可视化方面是一个不错的选择。

    展开全文
  • 免费地图资源(持续更新)

    万次阅读 多人点赞 2018-06-07 00:19:26
    GISer们在构建GIS应用时,常需要各种GIS数据,地形、影像、行政区划、道路、POI数据等等,我将平时的地图下载渠道、地图服务地址等罗列出来,供GISer们使用。在线的地图下载:...

    GISer们在构建GIS应用时,常需要各种GIS数据,地形、影像、行政区划、道路、POI数据等等,我将平时的地图下载渠道、地图服务地址等罗列出来,供GISer们使用。

    在线的地图下载:

    http://www.gscloud.cn/

    http://www.tianditu.com/service/query.html


    在线的地图服务:

    http://services.arcgisonline.com/arcgis/rest/services

    https://www.geoq.cn/basemap.html

    深色地图

    http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer


    OL代码:

     baseLayers: [  
              {
                  layerName: 'vector',
                  isDefault: true,
                  layerType: 'TileXYZ',
                  layerUrl: 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer'
              }
            ]

    天地图

    http://t3.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}


    OL代码

    var layer = new ol.layer.Tile({
                title: "航班",
                source: new ol.source.XYZ({
                    url: "http://t3.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}"
                })
            });
            map.addLayer(layer);

    4个GeoQ不同颜色的版本

    经典彩色版:"http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer",
    国际英文版:"http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunityENG/MapServer",
    低调灰色版:"http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetGray/MapServer",
    典雅蓝黑版:"http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer"


    地图下载器软件:

    太乐地图下载器 http://www.arctiler.com




    展开全文
  • 地图

    2018-01-08 08:05:51
    package com.example.mygaodeditu; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log;...import android.view.View;...import an
    package com.example.mygaodeditu;
    
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import com.amap.api.services.core.LatLonPoint;
    import com.amap.api.services.geocoder.GeocodeAddress;
    import com.amap.api.services.geocoder.GeocodeQuery;
    import com.amap.api.services.geocoder.GeocodeResult;
    import com.amap.api.services.geocoder.GeocodeSearch;
    import com.amap.api.services.geocoder.RegeocodeResult;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private EditText Edit_start;
        private EditText Edit_End;
        private Button start_But;
        private String mStartPlace;
        private String mEndPlace;
        private GeocodeSearch mStart;
        private GeocodeSearch mEnd;
        //坐标点
        private LatLonPoint mStratLat;
        private LatLonPoint mEndLat;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            mStart = new GeocodeSearch(MainActivity.this);
            mEnd = new GeocodeSearch(MainActivity.this);
        }
    
        private void initView() {
            Edit_start = (EditText) findViewById(R.id.Edit_start);
            Edit_End = (EditText) findViewById(R.id.Edit_End);
            start_But = (Button) findViewById(R.id.start_But);
    
            start_But.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.start_But:
                    mStartPlace = Edit_start.getText().toString().trim();
                    mEndPlace = Edit_End.getText().toString().trim();
                    if (mStartPlace.isEmpty() || mEndPlace.isEmpty()) {
                        Toast.makeText(this, "参数不能为空", Toast.LENGTH_SHORT).show();
                    } else {
                        initStart();
                    }
                    break;
            }
        }
    
        private void initStart() {
            GeocodeQuery query = new GeocodeQuery(mStartPlace, null);
            mStart.getFromLocationNameAsyn(query);
            mStart.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
                @Override
                public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
    
                }
    
                @Override
                public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                    GeocodeAddress address = geocodeResult.getGeocodeAddressList().get(0);
                    mStratLat = address.getLatLonPoint();
                    Log.e("看看开始经纬度", "经度是:" + mStratLat.getLongitude() + ",纬度是:" + mStratLat.getLatitude());
                    initEnd();
                }
            });
        }
    
        private void initEnd() {
            GeocodeQuery query = new GeocodeQuery(mEndPlace, null);
            mEnd.getFromLocationNameAsyn(query);
            mEnd.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
                @Override
                public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
    
                }
    
                @Override
                public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                    GeocodeAddress address = geocodeResult.getGeocodeAddressList().get(0);
                    mEndLat = address.getLatLonPoint();
                    Log.e("看看结尾经纬度", "经度是:" + mEndLat.getLongitude() + ",纬度是:" + mEndLat.getLatitude());
                    Intent intent = new Intent(MainActivity.this, AtlasActivity.class);
                    intent.putExtra("start", mStratLat);
                    intent.putExtra("end", mEndLat);
                    startActivity(intent);
                }
            });
        }
    }
    
    
    
    
    
    package com.example.mygaodeditu;
    
    import android.os.Bundle;
    import android.os.Parcelable;
    import android.support.v7.app.AppCompatActivity;
    
    import com.amap.api.maps.AMap;
    import com.amap.api.maps.MapView;
    import com.amap.api.services.core.LatLonPoint;
    import com.amap.api.services.route.BusRouteResult;
    import com.amap.api.services.route.DrivePath;
    import com.amap.api.services.route.DriveRouteResult;
    import com.amap.api.services.route.RideRouteResult;
    import com.amap.api.services.route.RouteSearch;
    import com.amap.api.services.route.WalkRouteResult;
    import com.example.mygaodeditu.overlay.DrivingRouteOverlay;
    
    public class AtlasActivity extends AppCompatActivity implements RouteSearch.OnRouteSearchListener {
    
        private MapView map;
        private AMap mapMap;
        private LatLonPoint mStart;
        private LatLonPoint mEnd;
    
        private RouteSearch routeSearch;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_atlas);
            map = (MapView) findViewById(R.id.map);
            //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
            map.onCreate(savedInstanceState);
            if (mapMap == null) {
                mapMap = map.getMap();
            }
    
            mStart = getIntent().getParcelableExtra("start");
            mEnd = getIntent().getParcelableExtra("end");
    
            routeSearch = new RouteSearch(this);
            routeSearch.setRouteSearchListener(this);
            //这个是死值 开始是马池口
            //RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(new LatLonPoint(40.1767200000, 116.16502000000), new LatLonPoint(39.9111400000, 116.4113500000));
            RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(mStart,mEnd);
            // fromAndTo包含路径规划的起点和终点,drivingMode表示驾车模式
            // 第三个参数表示途经点(最多支持16个),第四个参数表示避让区域(最多支持32个),第五个参数表示避让道路
            RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, null, null, "");
            routeSearch.calculateDriveRouteAsyn(query);// 异步路径规划驾车模式查询
    //        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
    //        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
    //        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
    //        aMap.getUiSettings().setMyLocationButtonEnabled(true);//设置默认定位按钮是否显示,非必需设置。
    //        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
            map.onDestroy();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
            map.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
            map.onPause();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
            map.onSaveInstanceState(outState);
        }
    
    
        @Override
        public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {
    
        }
    
        @Override
        public void onDriveRouteSearched(DriveRouteResult result, int i) {
            //自驾查询结果
            mapMap.clear();// 清理地图上的所有覆盖物
    
            final DrivePath drivePath = result.getPaths()
                    .get(0);
            DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
                    AtlasActivity.this, mapMap, drivePath,
                    result.getStartPos(),
                    result.getTargetPos(), null);
            drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
            drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true
            drivingRouteOverlay.removeFromMap();
            drivingRouteOverlay.addToMap();
            drivingRouteOverlay.zoomToSpan();
    
        }
    
        @Override
        public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {
    
        }
    
        @Override
        public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {
    
        }
    }
    

    展开全文
  • 一张新型肺炎地区分布地图是怎么制作的?

    万次阅读 多人点赞 2020-02-01 17:12:24
    一张新型肺炎地区分布地图是怎么制作的? 前言 让我们从环境开始 创建工程,添加引用 GIS数据 剩下的工作就很简单了 叠加世界数据 叠加中国数据 调整可视范围 连接动态数据 样式化地图 写在最后 前言 2020年刚...
    
    

    前言

    2020年刚开始,各钟不幸的消息满天飞。新型肺炎的蔓延,科比去世… 无时无刻让我感到痛楚。为了不给国家添乱,新年几天都在窝在家里。时不时拿起手机,观察一下现在病情蔓延情况。下面这张地图就是一张典型的GIS应用。

    infection-cover-status-demo

    每当我看到这张静态图时,很想要知道几个信息无法获知。

    1. 我们能通过颜色和图例比较一个省的确诊人数范围,看不到一个省具体患病人数。
    2. 由于是一张静态图,我们没法获市级数据。如果地图可以拖动,放大缩小就简单多了。
    3. 每次看到红色,心里都很焦虑。能换成其他颜色,我自己更加能接受点。

    基于这两个小功能,我准备介绍一下怎么去制作一张地图。我准备分两个阶段来做介绍。

    1. 先用最简洁的代码来生成一张静态图片。通过这个阶段,让我们认识一下一般地图应用开发的流程。
    2. 当我们了解流程以后,我们就把这个程序改造成地图服务,让她和知名的地图前端库Leaflet合并开发一个可交互的地图,集成点有趣的功能。

    这篇文章,我准备先从制作一张静态图片开始。

    让我们从环境开始

    以前开发地图应用软件,可能需要掌握很多编程语言技能,才能胜任一个完整的项目。比如一个典型的GIS B/S应用一般会使用Java, C#或其他后端编程语言来开发后端,然后用JavaScript + HTML来开发前端展现。

    今天用我们熟悉的JavaScript;即使是前端开发人员也可以开发后端地图应用了。追求极简开发环境的话,我们只需要2个工具。Node.js (推荐8以上,或者直接安装最新版本都是兼容的)和 vscode.

    这篇文章照顾新手,写的比较多。老鸟请自行过滤。勿喷。

    创建工程,添加引用

    接着,我们创建一个工程目录。用以下命令就可以了。(我个人比较喜欢使用命令行,由于平时都是用macOS做日常使用机器。所以以下命令行都是macOS执行验证的)。

    # 创建项目目录
    cd [your workspace]
    md nCoV-map
    cd nCoV-map
    
    # 创建功能,添加引用
    npm init -y
    npm i --save ginkgoch-map canvas lodash
    
    # 新建一个文件,这个将是我们写代码的地方
    touch tutorial-01.js
    

    这里引用了canvas库,是因为Node.js没有提供绘图API,我们只能引用一个第三方Node.js库来替代使用。

    到这里,我们的工程已经建立好了。

    GIS数据

    GIS应用里面数据是很重要的。我把她分为静态数据和动态数据。静态数据就是我们的几何图形以及她们特定的特征数据。如地区的名字等。动态数据就是我们实时关注的疫情变化。

    一般静态数据比较容易找到。百度搜索中国地图数据csv, json, shapefile都可以找到。这个项目里面,我准备使用shapefile作为我的静态数据。这里你可以找到以下数据,我们一会儿会使用到。把上面数据下载下来以后,放到工程的data目录下面。

    • chn/
      • gadm36_CHN_1_3857.shp - 省级数据
      • gadm36_CHN_2_3857.shp - 市级数据
    • cntry02.shp - 世界国家数据

    动态数据会麻烦点。我是写了一个爬虫,定时爬取。有兴趣可以私聊。不过作为例子,我放上了几份疫情数据在data/infected目录里面以便做示例。

    剩下的工作就很简单了

    叠加世界数据

    首先,我们定义一个函数来创建一个地图的图层,一个数据源即一个数据图层,多个数据图层叠加起来就可以构成我们期望的样式。使用ginkgoch-map,我们是这样定义一个图层的。

    function createLayerWithDefaultStyle(filePath) {
        // create a source with the specified shapefile file path
        let source = new GK.ShapefileFeatureSource(path.resolve(__dirname, filePath));
    
        // wrap the source as a world layer
        let layer = new GK.FeatureLayer(source);
    
        // set a style on the layer
        layer.styles.push(new GK.FillStyle('#f0f0f0', '#636363', 1));
    
        return layer;
    }
    

    有了layer, 我们可以简单查看我们数据图层的样子。比如对于数据cntry02.shp:

    let worldLayer = createLayerWithDefaultStyle('../data/cntry02.shp');
    await worldLayer.open();
    let worldImage = await worldLayer.thumbnail(512, 512);
    fs.writeFileSync(path.resolve(__dirname, './images/tutorial-01-world.png'), worldImage.toBuffer());
    

    我们通过命令行执行下面的语句。我们可以找到图片:

    node tutorial-01.js
    

    tutorial-01-world

    叠加中国数据

    当然这个不是我们想要的样子,我们还需要把省份的数据叠加在上面,才能看到我们中国详细一点的数据。我们接着做。

    const [imageWidth, imageHeight] = [512, 512];
    
    // create a world layer with cntry02.shp
    let worldLayer = createLayerWithDefaultStyle('../data/cntry02.shp');
    
    // create a province layer with gadm36_CHN_1_3857.shp
    let provinceLayer = createLayerWithDefaultStyle('../data/chn/gadm36_CHN_1_3857.shp');
    
    let mapEngine = new GK.MapEngine(imageWidth, imageHeight);
    mapEngine.srs = new GK.Srs('EPSG:900913');
    mapEngine.pushLayer(worldLayer);
    mapEngine.pushLayer(provinceLayer);
    
    let image = await mapEngine.image();
    fs.writeFileSync(path.resolve(__dirname, './images/tutorial-01-default.png'), image.toBuffer());
    

    现在再打开图片tutorial-01-default.png, 注意查看中国的数据已经叠加成功了。

    tutorial-01-default

    调整可视范围

    哦?太小了~ 好,我们调整下地图的可视范围。

    await provinceLayer.open();
    let chinaEnvelope = await provinceLayer.envelope();
    chinaEnvelope = GK.ViewportUtils.adjustEnvelopeToMatchScreenSize(chinaEnvelope, imageWidth, imageHeight);
    
    let image = await mapEngine.image(chinaEnvelope);
    fs.writeFileSync(path.resolve(__dirname, './images/tutorial-01-china.png'), image.toBuffer());
    

    tutorial-01-china

    连接动态数据

    我们对静态数据进行了渲染,同时对中国省份级别的边框进行绘制。接下来,我们将连接动态数据,把动态的感染人数和地图对应起来。我们怎么做呢?

    首先,我们先看下静态数据的特征数据。Shapefile的特征数据存放在*.dbf文件里面。你可以选择使用你常用的工具打开dbf文件。我个人一般使用的是shapefile viewer来查看。参考这里获取程序及使用说明

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NUD1zDlD-1580548031579)(./tutorials/images/china-attributes.png)]

    NL_NAME_1就是我们需要的省份名字,然后我们来看看动态数据的一个片段。

    [
        {
            "provinceName": "湖北省",
            "provinceShortName": "湖北",
            "confirmedCount": 4586,
            "suspectedCount": 0,
            "curedCount": 90,
            "deadCount": 162,
            "comment": "待明确地区:治愈 30",
            "cities": [
                {
                    "cityName": "武汉",
                    "confirmedCount": 2261,
                    "suspectedCount": 0,
                    "curedCount": 54,
                    "deadCount": 129
                },
                {
                    "cityName": "黄冈",
                    "confirmedCount": 496,
                    "suspectedCount": 0,
                    "curedCount": 5,
                    "deadCount": 12
                },
                ...
    

    有趣的是,动态数据也包含省份的名字provinceShortName;以及感染,疑似,治愈以及死亡的人数。现在,我们要做的就是通过静态数据的NL_NAME_1和动态数据的provinceShortName相等的数据相关联。在ginkgoch-map里面是这样做的。

    首先,我们定义一个函数来帮助我们定义一个关系。

    /**
     * field - the dynamic field value to return.
     * infectedData - the infected data in JSON format.
     */
    function _getDynamicFieldForProvince(field, infectedData) {
        return {
            name: field, fieldsDependOn: ['NL_NAME_1'], mapper: feature => {
                const fullName = feature.properties.get('NL_NAME_1');
                const infectionInfo = _.find(infectedData, d => {
                    return fullName.includes(d.provinceShortName);
                });
    
                if (infectionInfo === undefined) {
                    return undefined;
                } else {
                    return infectionInfo[field];
                }
            }
        };
    }
    

    然后建立4个列的映射函数。

    function connectDynamicData(layer) {
        // load dynamic data
        let dynamicData = fs.readFileSync(path.resolve(__dirname, '../data/infected/1580376765333.json')).toString();
        dynamicData = JSON.parse(dynamicData);
        
        // connect 4 dynamic attribute fields to the source.
        const source = layer.source;
        source.dynamicFields.push(_getDynamicFieldForProvince('confirmedCount', dynamicData));
        source.dynamicFields.push(_getDynamicFieldForProvince('suspectedCount', dynamicData));
        source.dynamicFields.push(_getDynamicFieldForProvince('curedCount', dynamicData));
        source.dynamicFields.push(_getDynamicFieldForProvince('deadCount', dynamicData));
    }
    

    最后,我们调用这个函数进行映射。

    //...省略前后重复的代码
    let provinceLayer = createLayerWithDefaultStyle('../data/chn/gadm36_CHN_1_3857.shp');
    connectDynamicData(provinceLayer);
    

    至此,我们可以认为provinceLayer已经包含了动态数据。她将在需要的时候动态的去通过映射关系找到需要的数据来使用。

    样式化地图

    做到这里,大家可以去休息一下。迎接最后一步:地图样式化。我们把感染人数分成几个等级,根据等级渲染不同的颜色来表示严重程度。比较好的是,ginkgoch-map提供了对应的API来渲染。

    我们先定义个函数来创建样式化对象Style.

    function _getClassBreakStyle(field) {
        const strokeColor = '#636363';
        const strokeWidth = 1;
    
        let countStops = [1, 10, 50, 100, 300, 500, 750, 1000, Number.MAX_SAFE_INTEGER];
        let activePallette = ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#67000d']
        let style = new GK.ClassBreakStyle(field);
    
        for (let i = 1; i < countStops.length; i++) {
            style.classBreaks.push({ minimum: countStops[i - 1], maximum: countStops[i], style: new GK.FillStyle(activePallette[i - 1], strokeColor, strokeWidth) });
        }
    
        return style;
    }
    

    再应用到layer上即可看到效果。

    let confirmedCountStyle = _getClassBreakStyle('confirmedCount');
    provinceLayer.styles.push(confirmedCountStyle);
    
    // 顺便我们把文字渲染上去,即可完成。
    let provinceLabelStyle = new GK.TextStyle('[NL_NAME_1]', 'black', 'Arial 12px');
    provinceLabelStyle.lineWidth = 2;
    provinceLabelStyle.strokeStyle = 'white';
    provinceLabelStyle.location = 'interior';
    provinceLayer.styles.push(provinceLabelStyle);
    

    chn-confirmed-map.png

    是不是很有趣?我们现在可以随意替换调色板,让她变成蓝色系的。替换这一句即可。

    // let activePallette = ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#67000d'];
    let activePallette = ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c'];
    

    final-infection-map.png

    写在最后

    最终的代码可以在这里下载:https://github.com/ginkgoch/nCoV-map/tree/develop/tutorials

    看起来很多,大多数代码都是业务代码,和对样式的设置。了解起来还是挺简单的。今天就到这里,后面有时间,我再写一篇搭建一个地图服务,制作一个可以交互的地图应用。有问题可以随时联系我, ginkgoch@outlook.com

    Happy Mapping!

    展开全文
  • 阜阳市地图2006年

    2019-07-10 02:21:06
    阜阳市地图2006年
  • 如何下载中国卫星地图高清版大图

    万次阅读 2019-02-28 16:30:38
    如何下载中国卫星地图高清版大图 中国行政区域简介 中国,是以华夏文明为源泉、中华文化为基础,并以汉族为主体民族的多民族国家,通用汉语、汉字,汉族与少数民族被统称为“中华民族”,又自称为炎黄子孙、龙的...
  • pyecharts的基础还是echart,echart是百度地图开源的一个数据可视化 JS 库,从我个人使用的情况来看,目前pyecharts(博主pyecharts版本是0.5.11)有这两个问题: 地图精度不够。目前pyecharts...
  • 最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地图入手,其实他们的用法都差不多,本篇文章就带领大家在自己的Android项目中加入百度地图的功能,接下来我会写一系列关于百度...
  • 2.2百度地图环境 2.3高德地图环境 2.4腾讯地图环境 3、工程配置 3.1 添加jar包 3.2 添加so文件 3.3 AndroidMainfest.xml配置 4.百度地图与定位 5.高德地图与定位 6.腾讯地图与定位 1、开发背景 由于公司在开发安卓...
  • Android 百度地图 SDK v3.0.0 (四) 引入离线地图功能

    万次阅读 多人点赞 2014-07-14 13:20:57
    一直觉得地图应用支持离线地图很重要啊,我等移动2G屌丝,流量不易,且用且珍惜。 对于官方开发指南对于离线地图的教程,提供了两种方案: 第一,手动导入,先将从官网下载的离线包解压,把vmp文件夹拷入SD卡根目录...
  • 百度地图坐标系统解析

    万次阅读 2019-06-22 14:55:52
    在地球上我们通过经纬度来描述某个位置,而经过投影之后的地图也有自己的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各种坐标体系。 在百度地图API中,你需要了解如下坐标系: 经纬度:通过经度...
  • 百度地图 地图选点

    千次阅读 2015-05-06 15:02:10
    最近要做一个导航项目,看了百度地图app后,自己的项目中要用到地图选点功能,于是在网上找地图选点功能,找是找到了,可是对于现在的百度地图sdk不再适用,于是自己根据api文档自己研究了一下。 import ...
  • 百度地图开发(三)之地图控制 + 定位

    万次阅读 多人点赞 2015-02-21 14:47:45
     前两篇关于百度地图的blog写的是,一些基本图层的展示 和 覆盖物的添加+地理编码和反地理编码。  接下来,这篇blog主要说一些关于地图控制方面的内容和定位功能。  百度地图提供的关于地图的操作主要有:单击...
  • 基于百度地图API的WinForm地图

    万次阅读 2013-07-08 13:47:17
    大概去年的这个时候,我用VB写了一个百度地图的Demo,使用了webBrowser加载本地网页的方式,只是限于当时的技术,好多功能都没实现,昨天,我重新对这个程序进行了编写,这一次我使用的是C#。在正式开始之前,先来...
  • 今天,想给大家带来一个基于百度地图官方开放的API开发的高仿百度地图的Demo(还称不上是一个APP),基本实现了百度地图的几大核心功能,百度地图中的基本地图,百度地图的定位,百度地图的全景显示,百度地图的导航等...
  • 百度地图3.0离线地图教程和echarts的结合使用

    万次阅读 热门讨论 2019-01-21 11:31:05
    百度地图版本2.0和3.0区别对比 http://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/usage 1、找到百度地图的主文件 1.1 输入地址:http://api.map.baidu.com/api?v=3.0&amp;ak=您的密钥 找到&...
  • 一、最新动态新一代的朋友,我们好好的加油,大家一起大声的说,NO NO NO NO NO我可以改变世界,改变自己,改变隔膜,改变消极,要一直 努力 ...百度地图接触好久了,从1.3.0的版本就认识百度地图了。那个时候谷歌...
  • Android App跳转百度地图、高德地图、腾讯地图进行目的地导航。 先放上百度、高德、腾讯地图调起API文档地址,有些参数不懂可以参考。 百度地图:http://lbsyun.baidu.com/index.php?title=uri/api/android 高德...
  • 百度地图api离线开发包

    千次下载 热门讨论 2015-11-02 15:10:19
    本离线开发包,支持百度地图离线开发。用于无网络环境下的百度地图二次开发。 包含以下文件: 1,基础API:apiv1.3.min.js ,有注释可参考; 2,基础CSS: bmap.css ; 3,依赖文件:map,oppc,tile,control,marker; 4...
  • Android简单实现百度地图显示及定位

    万次阅读 多人点赞 2017-12-29 14:12:17
    1、下载百度地图的SDK 下载地址:http://lbsyun.baidu.com/index.php?title=android-locsdk/geosdk-android-download 2、申请key值 注册百度账号——>登录百度地图官网——>控制台—–>创建应用 获取key(也就是...
  • 今天,想给大家带来一个基于百度地图官方开放的API开发的高仿百度地图的Demo(还称不上是一个APP),基本实现了百度地图的几大核心功能,百度地图中的基本地图,百度地图的定位,百度地图的全景显示,百度地图的导航等...
  • 百度地图API的使用

    万次阅读 2019-05-23 14:21:26
    ------------------自说自话----------------------------- 好奇怪,习惯性使用有道云笔记记录心得与知识后就很少用博客园来记录了。...下面正题,最近公司项目用百度地图API较多。后面还有使用...
  • 百度地图API开发指南

    千次阅读 2017-03-14 22:18:03
    简介什么是百度地图API? 百度地图API是一套由JavaScript语言编写的应用程序接口,它能够帮助您在网站中构建功能丰富、交互性强的地图应用。百度地图API包含了构建地图基本功能的各种接口,提供了诸如本地搜索、...
  • 百度地图定位和地图点击选点

    千次阅读 2018-09-03 15:07:28
    工作的时候几乎很多个项目都会用到这个百度地图的定位,位置显示,等等的一些功能,本文呢就写一个百度地图简单的定位和地图点击选点,话不多说,直接上图,类似于做的这个效果 就是你点击地图上任何一点,都会...
  • android 百度地图系列之地图初始化及定位

    万次阅读 多人点赞 2016-06-30 16:06:38
    在Android应用中,很多时候需要地图功能,回顾过去写的项目和百度地图api,开始总结一下Android百度地图的实现。首先总结一下怎么开始一个Android百度地图功能。
  • 1.需求在Android应用中打开百度地图或者高德地图进行路线规划,如果没有安装则打开网页百度地图进行路线规划。2.API2.1 打开百度地图应用地址:http://lbsyun.baidu.com/index.php?title=uri/api/android打开文档...
  • 百度地图离线API 2.0(含示例,可完全断网访问)

    千次下载 热门讨论 2015-02-05 14:25:04
    由于公司需求,自己修改的离线地图API.该压缩包具有如下功能: 1.支持使用google地图瓦片(不建议使用,效率不高,缩放级别较高时拖动有些卡顿,建议注释该代码块:overlayTileLayer.getTilesUrl,使用google转baidu的jar...

空空如也

1 2 3 4 5 ... 20
收藏数 414,493
精华内容 165,797
关键字:

地图