You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
9.1 KiB
284 lines
9.1 KiB
/**
|
|
* 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
|
|
};
|
|
});
|