目录

1 概述

2 添加新的地图文件

2.1 获取原始地图信息数据

2.1.1 获取区县以上行政区划

2.1.2 获取区县及以下行政区划

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

2.3 使用新添加的地图

3 修改现有的地图区块

4 可能涉及的编码转换

4.1 坐标转换

4.2 压缩编码转换

1概述

SaCa DataViz产品已经内置世界、中国、各省份直辖市、地市四个级别的地图数据,区县级以下(包括区县级)的地理数据则需要用户自己绘制或通过其他渠道获取。
地图资源文件存放路径为:dataviz[-web]\src\js\chartBuild\geojson\, 命名规则为行政区划编码.json,可百度或从中华人民共和国民政部官方网站 查询行政区划代码

特殊的,世界地图对应地图资源文件为0.json,中国地图资源为1.json,省份地图保留前两位。

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

  1. 添加新的地图文件;
  2. 修改内置地图的形状;

声明: 在此强调,地图文件的获取并不属于SaCa DataViz产品本身责任提供的服务,以下所述只是提供一种方法需要用户独立完成,本团队不承担任何法律责任。

2添加新的地图文件

2.1获取地图geojson数据

2.1.1区县以上行政区划

区县级以上的地理数据可以在DataV.GeoAtlas 或开源渠道获取。

2.1.2区县及以下行政区划

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

按以下步骤操作:

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

如果有飞地的情况,需要在后期手动编辑合并飞地各个区块的MultiPolygon数据。

copy描边数据保存到一个json后缀的文件中,注意文件编码格式为UTF-8,建议使用标准行政区划代码命名文件。

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

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

var regionCode = {  
    ...
    "官渡区":"530111",
    ...  
}

“官渡区”:“530111”,前面为地理名称,后面为geojson文件名前缀。地理名称的命名并不随意(上卷下钻功能依赖准确的地名),必须匹配上级geojson文件内对应区域的地理名称。

2.3使用新添加的地图

注意: 前述config.js有更新,需要清浏览器缓存并刷新方能生效。
图表大类“地图”中五款地图都可以使用新扩展的geojson,在属性中逐级选择区域,如在省级选择“云南”、市级选择“昆明市”、区县级选择“官渡区”,如下图所示。

图2-3-1 选择并使用官渡区地图

3修改现有的地图区块

针对用户修改地图区块形状的需求,可以使用在线geojson编辑工具:
http://newgateway.gitee.io/xdh-map/case/geo-edit.html
或者
http://geojson.io/
上传geojson文件,编辑后下载。

4可能涉及的编码转换

4.1 坐标转换

(新增地图无此步骤)

如果使用的是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  
};

4.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);  
  }

results matching ""

    No results matching ""

    results matching ""

      No results matching ""