目录

1 概述

2 添加新的地图文件

2.1 获取原始地图信息数据

2.1.1 获取区县及以上行政区划

2.1.2 获取区县以下行政区划

2.1.3 坐标转换

2.2 添加geojson文件及配置相关信息

2.3 使用新添加的地图

3 修改现有的地图区块

3.1 添加区块

3.2 修改区块

4 自定义地图区域

1概述

DataViz中所有的地图图表,均可以通过拓展的方式,修改现有地图或添加新地图。修改文件可能涉及地图资源文件(geojson格式的地理信息文件)和config.js配置文件(包含地名坐标、 地图资源文件的对应关系),文件路径分别为:

dataviz-web\common\config.js

dataviz-web\src\js\chartBuild\geojson\行政区划代码.json

下面按照不同的使用场景,将需求划分为以下三类:

  1. 添加新的地图文件;

  2. 在已有的地图文件中,修改地图的形状,如添加新的区域块和修改当前的区域块;

  3. 更高级应用,如自定义地图区域,如东北大区、西北大区等等;

注意:添加地图操作属于前台操作,暂时不支持自定义地图的地名匹配(2018-3-8)。

2添加新的地图文件

2.1获取原始地图信息数据

2.1.1获取区县及以上行政区划

区县级以上的地理数据可以通过Baidu或者Gaode的API获取,当前DataViz版本已经支持了绝大部分城市的地图(市级地图显示的是区县数据),区县级以下的地理数据则需要用户寻找其他渠道获取。在此强调,地图文件的获取并不属于DataViz产品本身责任提供的服务,以下所述只是提供一种方法方便用户,需要用户独立完成,并且不承担任何法律责任及经济纠纷。

以“昆明市”为例,访问http://ip:port/dataviz[-web]/src/mapPicker/mapPicker.html,使用Baidu的API获取地理数据。

图中右上方数据为昆明市的轮廓数据,对应geojson中“coordinates”对应中括号中的内容,之后按照geojson文件的格式补充其他字段(可参考DataViz现有的geojson格式),由于获取的是未压缩的经纬度数据,“ encodeOffsets”字段略过即可。

2.1.2获取区县以下行政区划

以“昆明市官渡区”为例,访问http://ip:port/dataviz[-web]/src/mapPicker/mapPicker.html

按以下步骤操作:

1.先搜索官渡得到官渡的外轮廓(便于描绘)。
2.手动描绘官渡区下属的各个街道/乡镇。描绘一个街道完毕后双击鼠标左键,会弹出界面用于输入街道名称与区域代码,“确定”即可得到该街道描边数据。

如果有飞地的情况请自行修改数据,geometry.type使用MultiPolygon类型并增加一层json数组。其他街道数据在此基础上继续描,描边后还可以编辑,点击“刷新描边数据” 即可更新。

拷贝描边得到的数据,在dataviz[-web]/src/js/chartBuild/geojson/路径新建一个json文件(注意文件编码格式为UTF-8)。文件名使用官渡区行政区划代码(2.2中会引用此区划代码,可百度搜索区划代码)。

2.1.3坐标转换

(新增地图无此步骤)

如果使用的是Baidu的API获取到的地理信息数据,并且用户的需求是修改已有的地图数据,就必须把Baidu坐标转换WGS84坐标。具体为:先通过bd09togcj02()转换为GCJ09坐标,再通过gcj02towgs84()转换为WGS84坐标。算法如下:

function gcj02towgs84(*lng*, *lat*) {  
var lat = +*lat*;  
var lng = +*lng*;

var PI = 3.1415926535897932384626;  
var dlat = transformlat(lng - 105.0, lat - 35.0);  
var dlng = transformlng(lng - 105.0, lat - 35.0);  
var radlat = lat / 180.0 \* PI;  
var magic = *Math*.sin(radlat);  
magic = 1 - ee \* magic \* magic;  
var sqrtmagic = *Math*.sqrt(magic);  
dlat = (dlat \* 180.0) / ((a \* (1 - ee)) / (magic \* sqrtmagic) \* PI);  
dlng = (dlng \* 180.0) / (a / sqrtmagic \* *Math*.cos(radlat) \* PI);  
var mglat = lat + dlat;  
var mglng = lng + dlng;  
return [lng \* 2 - mglng, lat \* 2 - mglat]  
};  

function bd09togcj02(*bd_lon*, *bd_lat*) {  
var bd_lon = +*bd_lon*;  
var bd_lat = +*bd_lat*;

var x_PI = 3.14159265358979324 \* 3000.0 / 180.0;  
var x = bd_lon - 0.0065;  
var y = bd_lat - 0.006;  
var z = *Math*.sqrt(x \* x + y \* y) - 0.00002 \* *Math*.sin(y \* x_PI);  
var theta = *Math*.atan2(y, x) - 0.000003 \* *Math*.cos(x \* x_PI);  
var gg_lng = z \* *Math*.cos(theta);  
var gg_lat = z \* *Math*.sin(theta);  
return [gg_lng, gg_lat]  
};

function transformlat(*lng*, *lat*) {  
var lat = +*lat*;  
var lng = +*lng*;

var PI = 3.1415926535897932384626;  
var ret = -100.0 + 2.0 \* lng + 3.0 \* lat + 0.2 \* lat \* lat + 0.1 \* lng \*
lat + 0.2 \* *Math*.sqrt(*Math*.abs(lng));  
ret += (20.0 \* *Math*.sin(6.0 \* lng \* PI) + 20.0 \* *Math*.sin(2.0 \* lng \*
PI)) \* 2.0 / 3.0;  
ret += (20.0 \* *Math*.sin(lat \* PI) + 40.0 \* *Math*.sin(lat / 3.0 \* PI)) \*
2.0 / 3.0;  
ret += (160.0 \* *Math*.sin(lat / 12.0 \* PI) + 320 \* *Math*.sin(lat \* PI /
30.0)) \* 2.0 / 3.0;  
return ret  
};

function transformlng(*lng*, *lat*) {

var PI = 3.1415926535897932384626;  
var lat = +*lat*;  
var lng = +*lng*;  
var ret = 300.0 + lng + 2.0 \* lat + 0.1 \* lng \* lng + 0.1 \* lng \* lat + 0.1
\* *Math*.sqrt(*Math*.abs(lng));  
ret += (20.0 \* *Math*.sin(6.0 \* lng \* PI) + 20.0 \* *Math*.sin(2.0 \* lng \*
PI)) \* 2.0 / 3.0;  
ret += (20.0 \* *Math*.sin(lng \* PI) + 40.0 \* *Math*.sin(lng / 3.0 \* PI)) \*
2.0 / 3.0;  
ret += (150.0 \* *Math*.sin(lng / 12.0 \* PI) + 300.0 \* *Math*.sin(lng / 30.0
\* PI)) \* 2.0 / 3.0;  
return ret  
};

2.2添加geojson文件及配置相关信息

将geojson文件放入dataviz-web\src\js\chartBuild\geojson\中。并在common\config.js文件中找到regionCode对象,regionCode如下:

var *regionCode* = {  
// "中国":"1",  
// "北京":"11",  
}

添加映射
“昆明市”:“行政区划代码”,前面为地理名称,后面为geojson文件名。地理名称的命名并不随意,否则会影响数据下钻/上卷,必须匹配省市区的层级关系,例如:添加了云南昆明市的geojson文件,那么地理名称必须和云南省geojson中“昆明市”的名字相同,如果云南省geojson中的是“昆明”,地理名称就必须写“昆明”,后面的文件名可以是拼音字母或数字(如行政编码),只要能区别其他文件即可。

如果上级geojson文件中没有对应的区域名字,例如:云南市geojson中没有“昆明市”,就需要在云南省geojson中添加“昆明市”的区块。

…
"铁门关市": "659006",  
"双河市": "659007",  
"可克达拉市": "659008",  
"昆玉市": "659009",  
"自治区直辖县级行政区划": "659000",  
"昆明": "kunming"  
};

之后在common/config.js中找到geoCoorMap对象,填入“昆明市”中各个区的政府经纬度坐标(此坐标不要求精确,看显示效果自行调整),至此完成了新地图的添加。

var *geoCoordMap* = {  
// "北京": [116.4551, 40.2539],  
"富民县":[102.5961987597655,25.2922035957032],  
"晋宁县":[102.52244753906251,24.603843000000047],
...

}

2.3使用新添加的地图

如果在上一步完成了省市区的层级匹配关系,那么在地图选择区域,对应的层级中选择了,如在“市级”选择“昆明市”,即可使用昆明市地图,如下图所示。并且可以拖拽 “云南”-“昆明”的维度层次,进行数据的上卷/下钻。

图2-3-1 选择并使用昆明市地图

3修改现有的地图区块

针对用户修改地图区块形状的需求:例如,为海南省添加三沙市,或修改当前地图文件不准确的地域。

可以使用在线geojson编辑工具:
http://newgateway.gitee.io/xdh-map/case/geo-edit.html

3.1添加区块

如果添加的区块,不含有更细粒度的区块(不含区县的市),或者用户不需要使用更细粒度的区块,则只需要在geojson中添加指定地理数据即可,否则还需要添加更细粒度的geojson文件,以添加“三亚市”为例,三亚市包含四个行政区:崖州区、天涯区、吉阳区、海棠区。
首先在“海南省”geojson中,添加三亚市地理区块,地理数据获取如上一章所述,之后建立新的geojson文件,写入崖州区、天涯区、吉阳区、海棠区四个地理区块,并按照上一章所述添加三亚市的geojson文件并完成配置。

3.2修改区块

针对用户需要修改现有的地图块,如把昆明五华区的范围扩大一条街或者缩小一条街,具体操作如下:
找到对应的geojson文件的待修改区块,找到相应的coordinates字段,如果coordinates字段后面有encodeoffset字段且不为空,则表明此coordinate为压缩后的字符串(例如下面),如果没有encodeoffset字段,则表明此coordinate数组未压缩,可以直接修改。

{"id":"810004","type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[["\@\@JBJAHBLCPAJCJDPCLOJM\@IBAFBBA\@CE\@AAE\@AAFIBQBADAFECCBEA\@GFCAYBABIRC\@QEGEACBEHMACECQACFE\`A\@GCK\@AFFHADMJBBF\@BB\@FBHCFI\@KLEBCAGWAAQDGCGJQHOPOHS\`KLN\@LDJAHETUDIJ\@HDxCZD"],["\@\@ACCBFB"],["\@\@D\@\@ACCCB\@CC\@CFBDJA"],["\@\@BA\@AG\@\@B\@BF\@"],["\@\@DABAGCADADBBDA"],["\@\@BAEBD\@"]],"encodeOffsets":[[[116946,22787]],[[116886,22776]],[[116934,22767]],[[117006,22758]],[[116932,22748]],[[116970,22738]]]},"properties":{"cp":[114.160023,22.245811],"name":"南区","childNum":6}}

修改压缩后的数组需要解压缩,解压缩算法如下decodePolygon(),参数与geojson中的字段匹配,encodeScale设为1024即可,解压缩后获得的经纬度数组即可直接修改。修改之后,还要把数组重新压缩,压缩算法为encodePolygon(),encodeOffsets字段与解压缩时相同即可。

function decodePolygon(*coordinate*, *encodeOffsets*, *encodeScale*) {  
var result = [];  
var prevX = *encodeOffsets*[0];  
var prevY = *encodeOffsets*[1];  

for (var i = 0; i \< *coordinate*.length; i += 2) {  
var x = *coordinate*.charCodeAt(i) - 64;  
var y = *coordinate*.charCodeAt(i + 1) - 64;  
// ZigZag decoding  
x = (x \>\> 1) \^ (-(x & 1));  
y = (y \>\> 1) \^ (-(y & 1));  
// Delta deocding  
x += prevX;  
y += prevY;  

prevX = x;  
prevY = y;  
// Dequantize  
result.push([x / *encodeScale*, y / *encodeScale*]);  
}  

return result;  
}

function encodePolygon(*coordinate*, *encodeOffsets*) {  
var result = '';  

var prevX = quantize(*coordinate*[0][0]);  
var prevY = quantize(*coordinate*[0][1]);  
// Store the origin offset  
*encodeOffsets*[0] = prevX;  
*encodeOffsets*[1] = prevY;  

for (var i = 0; i \< *coordinate*.length; i++) {  
var point = *coordinate*[i];  
result+=encode(point[0], prevX);  
result+=encode(point[1], prevY);  

prevX = quantize(point[0]);  
prevY = quantize(point[1]);  
}  

return result;  
}

function encode(*val*, *prev*){  
// Quantization  
*val* = quantize(*val*);  
// var tmp = val;  
// Delta  
*val* = *val* - *prev*;  

if (((*val* \<\< 1) \^ (*val* \>\> 15)) + 64 === 8232) {  
//WTF, 8232 will get syntax error in js code  
*val*--;  
}  
// ZigZag  
*val* = (*val* \<\< 1) \^ (*val* \>\> 15);  
// add offset and get unicode  
return String.fromCharCode(*val*+64);  
// var tmp = {'tmp' : str};  
// try{  
// eval("(" + JSON.stringify(tmp) + ")");  
// }catch(e) {  
// console.log(val + 64);  
// }  
}  

function quantize(*val*) {  
return *Math*.ceil(*val* \* 1024);  
}

4自定义地图区域

DataViz产品本身默认提供了中国、中国省份等地图资源文件,不包含全部地图资源,默认文件存放路径为:src\js\chartBuild\geojson\。

当用户需要对DataViz提供的特定地区的地图资源文件进行修改时,请先查找到该地图的地图资源文件,然后再对地图资源进行修改;中国下的地区对应的地图资源文件的文件名为该地图的标准行政区划代码,该标准行政区划代码用户可从中华人民共和国民政部官方网站获取,参考网站为:http://www.mca.gov.cn/article/sj/xzqh/,特殊的,世界地图对应地图资源文件为0.json,中国地图资源为1.json。

此情景及需求暂时没有遇到,待补。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""