Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >玩转地球: 如何利用SAS绘制现代化地图(附代码)

玩转地球: 如何利用SAS绘制现代化地图(附代码)

作者头像
大数据文摘
发布于 2018-05-25 08:45:48
发布于 2018-05-25 08:45:48
3.9K0
举报
文章被收录于专栏:大数据文摘大数据文摘

投稿作者|巫银良

大数据文摘欢迎各类优质稿件

请联系tougao@bigdatadigest.cn

移动互联网应用和大规模社交网络催生了海量的数据分析需求,时空数据作为记录用户和设备在现实世界分布和活跃程度的基础数据,一直为各大互联网电子商务平台和商家所关注。地理空间数据结合其他业务数据如何被分析利用,以及如何在分析中可视化呈现一直是现代化分析平台的一个重要方向。一方面各种地图服务越来越多地集成到应用中,成为应用增强交互的组成部分(比如“附近的服务/人”,甚至连支付包红包都需要呈现各种方位关系,来增强乐趣),另一方面在分析行业,如何能够高效方便地绘制各种地图成为一种基本需求。

SAS 语言中提供了能够绘制地图的能力。 考虑到 SAS 并不是地图数据的生产者,SAS 只是利用数据。在早些年,尽管SAS提供的地图数据来源多种多样,但SAS花了大量的时间精力来保证用户地图数据的精确性。随着现代卫星和测绘技术的成熟和一些其他原因(比如不再从CIA 获得世界数据),SAS 不再维护既往的地图数据,而是和第三方厂商合作来提供能够定期更新的最新数据,这样就不必考虑不同地理坐标系统和地缘政治格局变化带来的基础地理数据更新。

在传统上,SAS 缺省提供 MAPSSAS 库和 PROC GMAP, PROC GPROJECT, PROC GREMOVE, GEONCODE 等若干过程步来支持地图绘制功能。利用这些基础数据和过程步,用户能很容易绘制世界地图,各大洲地图,各国家地区地图。从SAS 9.30M2 版本开始,SAS 和 GFK GeoMarketing 合作,提供MPASGFK基础库,它能为用户提供超过240个国家和地区精准的数字邮政代码和行政区划地理数据。Gfk GeoMarketing 的数字地图是世界范围内最全最完整的数字地图,坐标系统为 WGS84 并且定期更新。根据笔者的调查,MapGfK 基础库包括2个世界级(其中一个world_cities为世界城市),22个洲级,175个国家级6个美国州县的地理数据与对应属性数据。虽然看起来很全,但也并非十全十美,比如笔者发现有些版本China地图数据没有包括中国台湾岛的内容,也没有反映2010年的北京核心四区合并为两区 等变化。

下面,我们举个最简单的例子,来说明如何在SAS 里绘制地图:

proc gmap map=mapsgfk.world data=mapsgfk.world;

id id;

choro id / nolegend;

run;quit;

运行上面几行代码,SAS 会在结果窗口中输出如下结果:

如果你需要绘制亚洲或者中国地图,则只需要将上面world 改为 Asia或China 即可。

proc gmap map=mapsgfk.asia data=mapsgfk.asia;

id id;

choro id / nolegend;

run;quit;

细心的观众会发现,亚洲地图确实按照各个国家进行了准确的绘制,但中国地图则看起来黑压压的一片(…这个,其实反映的是俺们大中华确实是地大物博啊),并没有什么实用价值;九段线是确实包括在内,但其中竟然没有中国宝岛台湾(不要慌,下面我们介绍如何将缺失的中国台湾部分和中国地图合并为大中华地图)

data mytaiwan;

set mapsgfk.taiwan;

id2=id1; id1='CN-83';

run;

data GreatChina;

set mapsgfk.china mytaiwan; /*合并中国台湾到大中华*/

run;

proc gmap map= GreatChina data= GreatChina;

id id;

choro id / nolegend;

run;quit;

执行上面的代码,输出结果如下。中国台湾出现在地图正中央(四川盆地)位置。原因是各个分区地图有自己的投影基点,我们需要按照中国数据进行投影。

为了将中国台湾岛移到指定位置,需要在调用 PROC GMAP 前执行如下代码,对中国台湾岛的数据根据中国的投影进行变换:

...

proc GPROJECT data=GreatChina out=GreatChina LATLON PARMIN=mapsgfk.projparm PARMENTRY=china;

id id;

run;

proc gmap map=..

在实际制作地图时,并不需要这么多的细节数据。因此我们需要将不必要的地区和县的边界删除,然后再调用 PROC GMAI绘图。代码如下:

proc sort data=GreatChina out=tmpds;

by ID1;

run;

proc gremove data=tmpds out=tmpds;

by ID1;

id id;

run;

data GreatChina(drop=ID1);

set tmpds;

id=ID1;

run;

为了给各省标注上省名,我们可以利用 MAPSGFK库中已有的地图属性数据来绘制标签。此时需要利用系统自带的宏 %annomac 和 %maplabel 来生成描述数据数据。另外,需要对中国台湾岛的描述数据进行特殊处理,统一到大中华地图中来。代码如下:

data mytaiwan_attr;

set mapsgfk.taiwan_attr;

id2=id1; id2name=id1name;

id1='CN-83'; id1name="Taiwan Sheng"; isoname='China';/*增补*/

drop country ;

run;

data GreatChina_data;

set mapsgfk.China_attr mytaiwan_attr; /*合并中国台湾省的描述数据*/

keep id1 id1name;

rename id1=id id1name=idname;

run;

%annomac;

%maplabel (GreatChina, GreatChina_data, anno_label, idname, id, font=%str(SimSun), color=black, size=1.5, hsys=3);

proc gmap map=GreatChina data=GreatChina_data;

id id;

choro id / nolegend anno=anno_label;

run;quit;

上面的地图显示的是英文名称,而我们希望显示中文名称怎么办?很简单,我们只需要在代码中使用 id1nameU 列,并将字符进行转义即可显示正确:

data mytaiwan_attr;

set mapsgfk.taiwan_attr;

id2=id1; id2name=id1name;

id1='CN-83'; id1name="Taiwan Sheng"; isoname='China';

id1nameu= put('中国台湾省',$uesc200.);

drop country ;

run;

data GreatChina_data;

set mapsgfk.China_attr mytaiwan_attr; /*合并中国台湾省的描述数据*/

keep id1 id1nameU;

rename id1=id id1nameU=idname;

run;

%annomac;

%maplabel (GreatChina, GreatChina_data, anno_label, idname, id, font=%str(SimSun), color=black, size=1.5, hsys=3);

data anno_label; set anno_label; text=unicode(text);run;

proc gmap map= GreatChina data= GreatChina_data;

id id;

choro id / nolegend anno=anno_label;

run;quit;

虽然在 MAPSGFK 基础库中有很多基础地理数据,但在现实中依然不够用怎么办? 解决方案有两种:第一种是直接利用实际测绘的地理数据创建自定义地图;第二种方法是利用谷歌地球导出地球上任何地区/建筑的 KML 数据,然后再导入到 SAS 系统里创建地图。比如下图就是用第二种方法创建的谷歌总部第40号楼的地理数据。(下图为 Google Earth里的样子)

%MAPIMPORT(DATAFILE="test.kml",out=%str(mymap), ID=201);

data mymap; set mymap;

x=long;y=lat;

run;

data mymap_data;

attrib ID length=$15 label='Districts code';

attrib IDNAME length=$55 label='Districts name';

infile datalines dsd;

input

ID

IDNAME

;

datalines4;

201,Google Building 40

;;;;

data mymap_data; set mymap_data;

length my_html $100;

my_html='title='||quote(trim(left(idname)));

run;

goptions reset=all;

goptions hsize=1024pt vsize=768pt;

ods html;

%let mymap=mymap;

%let mymap_data=mymap_data;

%annomac;

%maplabel (&mymap, &mymap_data, anno_label, idname, id, font=%str(SimSun), color=WHITE, size=1.5, hsys=3);

proc gmap map=mymap data=mymap_data;

id id;

choro id / nolegend anno=anno_label;

run;quit;

ods html close;

以上代码生成结果如下,为Google总部40号楼的精确地理信息,可用于进一步分析处理。

在互联网上,有时听见一些人抱怨 SAS 语言做出的图表不够美观,显得比较粗陋。其实造成这误解的根本是没有掌握 SAS 强大的特性控制功能和实现的灵活性。为了展示 SAS 在绘制地图方面预留的灵活性和控制,下面将展示若干纯粹利用 SAS 代码绘制的各种现代化的复杂地图。SAS语言天生作为面向分析而设计的语言,它保留了非常多的扩展性;笔者甚至发现在 SAS 地图里可以绘制天气云图(见下图3)。正所谓倚天不出,谁与争锋?在分析行业里只有掌握了如何使用SAS这把倚天剑,才能使数据分析结果的展示一切皆有可能!

图1:SAS绘制空白中国省图

图2:SAS绘制的中国各省的卫星地图

图3:SAS 绘制的带有卫星云图的中国分省图

总结:

SAS GMAP 提供 2D (choropleth) 和 3D (block, prism, surface) 地图的绘制和渲染,用来将分析变量和结果显示在地图上。既往的研究表明,SAS 用户可以桥接任何地图服务商的数据,包括 MAPBOX, MAPQUEST, HERE, GOOGLE,ARCGIS和 AutoNavi(高德)的地图和他们的各种变体:卫星图(SATELLITE), (街道图)STREETS, (地形图)TERRAIN和(交通图)TRAFFIC 等。 PROC GMAP 的所有奥秘其实都藏在它的 MAP和DATA 参数里,至于如何实现,就需要在实际需求中与具体业务数据结合考虑。

作者 | 巫银良

赛仕软件研究开发(北京)有限公司

商业智能和可视化分析产品部 技术总监

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-02-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据文摘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
开心档之Java ArrayList
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
iOS Magician
2023/04/04
3410
开心档之Java ArrayList
五、集合基础【黑马JavaSE笔记】
注:以上方法时List集合特有的方法,Collection集合没有这些方法,但是ArrayLIst集合有这些方法,因为ArrayList继承自List集合。
啵啵鱼
2022/11/23
7790
五、集合基础【黑马JavaSE笔记】
Java Iterator(迭代器)
Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
默 语
2024/11/20
1040
Java Iterator(迭代器)
杨校老师课堂之Java基础集合专题知识点整理
LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList 的特有方法即可。在开发时,LinkedList集合也可以作为堆栈。
杨校
2019/08/01
6560
Java学习笔记(三):集合类与常用数据结构的典型用法
foochane :https://foochane.cn/article/2019122801.html 1 Collection集合 1.1 集合概述 在前面基础班我们已经学习过并使用过集合A
foochane
2020/02/13
9350
Java 基础
一是为了方便引用,比如,JDK安装在C:\jdk1.6.0目录里,则设置JAVA_HOME为该目录路径, 那么以后要使用这个路径的时候, 只需输入%JAVA_HOME%即可, 避免每次引用都输入很长的路径串;
云台大树
2021/09/13
5260
Java学习之基础
常用五大包:java.long(longuage)该包下的类,在使用时是不需要导包的;java.util 工具包;java,io 文件读写;java.net 网络编程包;java.sql 操作数据库
用户8447427
2022/08/18
4330
Java学习之基础
07 - JavaSE之容器
Collection 接口的子接口分为:Set接口(包含 HashSet类) + List接口(包含LinkedList 类和 ArrayLis t类) Map接口:包含HashMap类
Daotin
2018/08/31
3580
07 - JavaSE之容器
Java集合框架的全面分析和性能增强
Java集合框架在Java编程中起着至关重要的作用。它提供了一系列的数据结构和算法,用于存储、操作和访问数据。然而,为了充分利用集合框架的强大功能,开发人员需要深入了解其内部机制,并注意性能优化。本博客将深度解析Java集合框架的核心组件,包括List、Set、Map等接口及其实现类,同时提供优化技巧和示例,助力新手更好地理解和学习。
默 语
2024/11/20
1490
Java集合类型大揭秘
这里HashMap里面用到链式数据结构的一个概念。上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方,第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?
leon公众号精选
2022/04/27
3190
Java集合类型大揭秘
Java 基础教学:高级特性与实战-集合框架
Java 集合框架提供了一套性能优良、使用方便的接口和类,用于存储和操作群组数据。最常用的集合接口有 List、Set 和 Map。
世间万物皆对象
2024/11/06
1240
【17】JAVASE-集合专题【从零开始学JAVA】
Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。
用户4919348
2024/05/25
2070
【17】JAVASE-集合专题【从零开始学JAVA】
java集合类面试题_Java集合类相关面试题
java.util.Collection 是一个集合接口,Collection接口在Java类库中有非常多详细的实现。比如List、Set
全栈程序员站长
2022/09/08
2800
Java基础之集合
-集合结构只要发生改变,迭代器必须重新获取,如果还是用的之前的迭代器,就会出现异常java.util.ConcurrentModificationException
shaoshaossm
2022/12/27
5410
Java基础之集合
Java类集框架详细汇总
Java的类集框架比较多,也十分重要,在这里给出图解,可以理解为相应的继承关系,也可以当作重要知识点回顾;
BUG弄潮儿
2021/04/12
7470
Java常见集合类型及其异同点,简单使用
Java集合是Java编程语言中的一个非常重要的部分。Java集合类是Java开发中最通用的类之一,它提供了一种方便的方法来管理一组对象。Java集合框架提供了一个标准的框架来表示和操作集合对象。Java集合框架由一组接口、抽象类和实现类组成。在Java集合类中,主要有以下几种集合类型:
王也518
2023/10/16
2410
java 集合框架
集合概念:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有什么区别呢?
不期而遇丨
2022/09/09
8280
java 集合框架
Java集合:整体结构
一、Java中集合   Java中集合类是Java编程中使用最频繁、最方便的类。集合类作为容器类可以存储任何类型的数据,当然也可以结合泛型存储指定的类型(不过泛型仅仅在编译期有效,运行时是会被擦除的)。集合类中存储的仅仅是对象的引用,并不存储对象本身。集合类的容量可以在运行期间进行动态扩展,并且还提供很多很方便的方法,如求集合的并集、交集等。 二、集合类结构   Java中的集合包含多种数据结构,如链表、队列、哈希表等。从类的继承结构来说,可以分为两大类,一类是继承自Collection接口,这类集合包含L
用户2140019
2018/05/18
5850
Java集合
LinkedList使用的方法都是从List接口实现而来的方法,需要了解的是LinkedList特有方法:
闲花手札
2021/08/24
1.9K0
Java-集合
哈喽!大家好,我是小简。今天开始学习《Java-集合》,此系列是我做的一个 “Java 从 0 到 1 ” 实验,给自己一年左右时间,按照我自己总结的 Java-学习路线,从 0 开始学 Java 知识,并不定期更新所学笔记,期待一年后的蜕变吧!<有同样想法的小伙伴,可以联系我一起交流学习哦!>
小简
2023/01/04
1.2K0
Java-集合
相关推荐
开心档之Java ArrayList
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档