static/js/dncp/util/projection/normal.js
/**
* echarts地图一般投射算法
* modify from GeoMap v0.5.3 https://github.com/x6doooo/GeoMap
*
* @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
*
*/
define(function() {
function getBbox(json, specialArea) {
specialArea = specialArea || {};
if (!json.srcSize) {
parseSrcSize(json, specialArea);
}
return json.srcSize;
}
function parseSrcSize(json, specialArea) {
specialArea = specialArea || {};
convertorParse.xmin = 360;
convertorParse.xmax = -360;
convertorParse.ymin = 180;
convertorParse.ymax = -180;
var shapes = json.features;
var geometries;
var shape;
for (var i = 0, len = shapes.length; i < len; i++) {
shape = shapes[i];
if (shape.properties.name && specialArea[shape.properties.name]) {
continue;
}
switch (shape.type) {
case 'Feature':
convertorParse[shape.geometry.type](shape.geometry.coordinates);
break;
case 'GeometryCollection' :
geometries = shape.geometries;
for (var j = 0, len2 = geometries.length; j < len2; j++) {
convertorParse[geometries[j].type](
geometries[j].coordinates
);
}
break;
}
}
json.srcSize = {
left: convertorParse.xmin.toFixed(4)*1,
top: convertorParse.ymin.toFixed(4)*1,
width: (convertorParse.xmax - convertorParse.xmin).toFixed(4)*1,
height: (convertorParse.ymax - convertorParse.ymin).toFixed(4)*1
};
return json;
}
var convertor = {
//调整俄罗斯东部到地图右侧与俄罗斯相连
formatPoint: function (p) {
return [
((p[0] < -168.5 && p[1] > 63.8) ? p[0] + 360 : p[0]) + 168.5,
90 - p[1]
];
},
makePoint: function (p) {
var self = this;
var point = self.formatPoint(p);
// for cp
if (self._bbox.xmin > p[0]) { self._bbox.xmin = p[0]; }
if (self._bbox.xmax < p[0]) { self._bbox.xmax = p[0]; }
if (self._bbox.ymin > p[1]) { self._bbox.ymin = p[1]; }
if (self._bbox.ymax < p[1]) { self._bbox.ymax = p[1]; }
var x = (point[0] - convertor.offset.x) * convertor.scale.x
+ convertor.offset.left;
var y = (point[1] - convertor.offset.y) * convertor.scale.y
+ convertor.offset.top;
return [x, y];
},
Point: function (coordinates) {
coordinates = this.makePoint(coordinates);
return coordinates.join(',');
},
LineString: function (coordinates) {
var str = '';
var point;
for (var i = 0, len = coordinates.length; i < len; i++) {
point = convertor.makePoint(coordinates[i]);
if (i === 0) {
str = 'M' + point.join(',');
} else {
str = str + 'L' + point.join(',');
}
}
return str;
},
Polygon: function (coordinates) {
var str = '';
for (var i = 0, len = coordinates.length; i < len; i++) {
str = str + convertor.LineString(coordinates[i]) + 'z';
}
return str;
},
MultiPoint: function (coordinates) {
var arr = [];
for (var i = 0, len = coordinates.length; i < len; i++) {
arr.push(convertor.Point(coordinates[i]));
}
return arr;
},
MultiLineString: function (coordinates) {
var str = '';
for (var i = 0, len = coordinates.length; i < len; i++) {
str += convertor.LineString(coordinates[i]);
}
return str;
},
MultiPolygon: function (coordinates) {
var str = '';
for (var i = 0, len = coordinates.length; i < len; i++) {
str += convertor.Polygon(coordinates[i]);
}
return str;
}
};
var convertorParse = {
formatPoint: convertor.formatPoint,
makePoint: function (p) {
var self = this;
var point = self.formatPoint(p);
var x = point[0];
var y = point[1];
if (self.xmin > x) { self.xmin = x; }
if (self.xmax < x) { self.xmax = x; }
if (self.ymin > y) { self.ymin = y; }
if (self.ymax < y) { self.ymax = y; }
},
Point: function (coordinates) {
this.makePoint(coordinates);
},
LineString: function (coordinates) {
for (var i = 0, len = coordinates.length; i < len; i++) {
this.makePoint(coordinates[i]);
}
},
Polygon: function (coordinates) {
for (var i = 0, len = coordinates.length; i < len; i++) {
this.LineString(coordinates[i]);
}
},
MultiPoint: function (coordinates) {
for (var i = 0, len = coordinates.length; i < len; i++) {
this.Point(coordinates[i]);
}
},
MultiLineString: function (coordinates) {
for (var i = 0, len = coordinates.length; i < len; i++) {
this.LineString(coordinates[i]);
}
},
MultiPolygon: function (coordinates) {
for (var i = 0, len = coordinates.length; i < len; i++) {
this.Polygon(coordinates[i]);
}
}
};
function geoJson2Path(json, transform, specialArea) {
specialArea = specialArea || {};
convertor.scale = null;
convertor.offset = null;
if (!json.srcSize) {
parseSrcSize(json, specialArea);
}
transform.offset = {
x: json.srcSize.left,
y: json.srcSize.top,
left: transform.OffsetLeft || 0,
top: transform.OffsetTop || 0
};
convertor.scale = transform.scale;
convertor.offset = transform.offset;
var shapes = json.features;
var geometries;
var pathArray = [];
var val;
var shape;
for (var i = 0, len = shapes.length; i < len; i++) {
shape = shapes[i];
if (shape.properties.name && specialArea[shape.properties.name]) {
// 忽略specialArea
continue;
}
if (shape.type == 'Feature') {
pushApath(shape.geometry, shape);
}
else if (shape.type == 'GeometryCollection') {
geometries = shape.geometries;
for (var j = 0, len2 = geometries.length; j < len2; j++) {
val = geometries[j];
pushApath(val, val);
}
}
}
var shapeType;
var shapeCoordinates;
var str;
function pushApath(gm, shape) {
shapeType = gm.type;
shapeCoordinates = gm.coordinates;
convertor._bbox = {
xmin: 360,
xmax: -360,
ymin: 180,
ymax: -180
};
str = convertor[shapeType](shapeCoordinates);
pathArray.push({
// type: shapeType,
path: str,
cp: shape.properties.cp
? convertor.makePoint(shape.properties.cp)
: convertor.makePoint([
(convertor._bbox.xmin + convertor._bbox.xmax) / 2,
(convertor._bbox.ymin + convertor._bbox.ymax) / 2
]),
properties: shape.properties,
id: shape.id
});
}
return pathArray;
}
/**
* 平面坐标转经纬度
* @param {Array} p
*/
function pos2geo(obj, p) {
var x;
var y;
if (p instanceof Array) {
x = p[0] * 1;
y = p[1] * 1;
}
else {
x = p.x * 1;
y = p.y * 1;
}
x = x / obj.scale.x + obj.offset.x - 168.5;
x = x > 180 ? x - 360 : x;
y = 90 - (y / obj.scale.y + obj.offset.y);
return [x, y];
}
/**
* 经纬度转平面坐标
* @param {Array | Object} p
*/
function geo2pos(obj, p) {
convertor.offset = obj.offset;
convertor.scale = obj.scale;
return p instanceof Array
? convertor.makePoint([p[0] * 1, p[1] * 1])
: convertor.makePoint([p.x * 1, p.y * 1]);
}
return {
getBbox: getBbox,
geoJson2Path: geoJson2Path,
pos2geo: pos2geo,
geo2pos: geo2pos
};
});