geomap-0.4.1.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * GeoMap v0.4.1
  3. * https://github.com/x6doooo/GeoMap
  4. *
  5. * Copyright 2013 Dx. Yang
  6. * Released under the MIT license
  7. */
  8. (function(){
  9. var version = "0.4.1";
  10. var convertor = {
  11. "xmin": 360,
  12. "xmax": 0,
  13. "ymin": 180,
  14. "ymax": 0,
  15. "formatPoint": function(p){
  16. return [(p[0] < -168.5 ? p[0] + 360 : p[0]) + 170, 90 - p[1]];
  17. },
  18. "makePoint": function(p){
  19. var self = this,
  20. point = self.formatPoint(p),
  21. x = point[0],
  22. y = point[1];
  23. if(self.xmin > x) self.xmin = x;
  24. if(self.xmax < x) self.xmax = x;
  25. if(self.ymin > y) self.ymin = y;
  26. if(self.ymax < y) self.ymax = y;
  27. return [x, y];
  28. },
  29. "Point": function(coordinates){
  30. coordinates = this.makePoint(coordinates);
  31. return coordinates.join(',');
  32. },
  33. "LineString": function(coordinates){
  34. var str = '',
  35. self = this,
  36. i = 0,
  37. len = coordinates.length,
  38. point;
  39. for( ; i < len; i++){
  40. point = self.makePoint(coordinates[i]);
  41. if(i == 0){
  42. str = 'M' + point.join(',');
  43. }else{
  44. str = str + 'L' + point.join(',');
  45. }
  46. }
  47. return str;
  48. },
  49. "Polygon": function(coordinates){
  50. var str = '',
  51. i = 0,
  52. len = coordinates.length;
  53. for(; i < len; i++){
  54. str = str + convertor.LineString(coordinates[i]) + 'z';
  55. }
  56. return str;
  57. },
  58. "MultiPoint": function(coordinates){
  59. var arr = [],
  60. i = 0,
  61. len = coordinates.length;
  62. for(; i < len; i++){
  63. arr.push(convertor.Point(coordinates[i]));
  64. }
  65. return arr;
  66. },
  67. "MultiLineString": function(coordinates){
  68. var str = '',
  69. i = 0,
  70. len = coordinates.length;
  71. for(; i < len; i++){
  72. str += convertor.LineString(coordinates[i]);
  73. }
  74. return str;
  75. },
  76. "MultiPolygon": function(coordinates){
  77. var str = '',
  78. i = 0,
  79. len = coordinates.length;
  80. for(; i < len; i++){
  81. str += convertor.Polygon(coordinates[i]);
  82. }
  83. return str;
  84. }
  85. };
  86. var GeoMap = function(cfg){
  87. var self = this,
  88. defaultCfg = {
  89. container: 'body',
  90. offset: null,
  91. scale: null,
  92. mapStyle: {
  93. 'fill': '#fff',
  94. 'stroke': '#999',
  95. 'stroke-width': 0.7
  96. },
  97. crossline:{
  98. enable: true,
  99. color: '#ccc'
  100. },
  101. background:'#fff'
  102. };
  103. $.extend(true, defaultCfg, cfg);
  104. self.container = $(defaultCfg.container);
  105. self.width = defaultCfg.width || self.container.width();
  106. self.height = defaultCfg.height || self.container.height();
  107. self.left = self.container.offset().left;
  108. self.top = self.container.offset().top;
  109. self.canvas = new Raphael(self.container.get(0), self.width, self.height);
  110. self.shapes = self.canvas.set();
  111. self.config = defaultCfg;
  112. self.paths = null;
  113. };
  114. /*
  115. *
  116. * TODO: 将图上的坐标转换成实际经纬度
  117. *
  118. * */
  119. GeoMap.prototype = {
  120. load: function(json){
  121. this.paths = this.json2path(json);
  122. },
  123. render: function(){
  124. var self = this,
  125. shapes = self.shapes,
  126. paths = self.paths,
  127. canvas = self.canvas,
  128. config = self.config,
  129. style = config.mapStyle,
  130. offset = config.offset,
  131. scale = config.scale,
  132. background = config.background,
  133. crossline = config.crossline,
  134. width = self.width,
  135. height = self.height,
  136. left = self.left + 5,
  137. top = self.top + 7,
  138. mapleft = convertor.xmin,
  139. maptop = convertor.ymin,
  140. mapwidth = convertor.xmax - convertor.xmin,
  141. mapheight = convertor.ymax - convertor.ymin,
  142. aPath = null, linehead, linex, liney, back, idx, len, currentPath;
  143. if(!scale){
  144. var temx = width/mapwidth,
  145. temy = height/mapheight;
  146. temx > temy ? temx = temy : temy = temx;
  147. temx = temy * 0.73;
  148. scale = {
  149. x: temx,
  150. y: temy
  151. };
  152. }
  153. if(!offset){
  154. offset = {
  155. x: mapleft,
  156. y: maptop
  157. };
  158. }
  159. back = canvas.rect(mapleft, maptop, mapwidth, mapheight).scale(scale.x, scale.y, 0, 0).attr({
  160. 'fill': background, 'stroke-width': 0
  161. });
  162. linehead = 'M' + (mapleft) + ',' + (maptop);
  163. linex = linehead + 'H' + convertor.xmax * scale.x;
  164. liney = linehead + 'V' + convertor.ymax * scale.y;
  165. self.crosslineX = canvas.path(linex).attr({'stroke': crossline.color, 'stroke-width': '1px'}).hide();
  166. self.crosslineY = canvas.path(liney).attr({'stroke': crossline.color, 'stroke-width': '1px'}).hide();
  167. for(i = 0, len = paths.length; i < len; i++){
  168. currentPath = paths[i];
  169. if(currentPath.type == 'point' || currentPath.type == 'MultiPoint'){
  170. //TODO
  171. }else{
  172. aPath = canvas.path(currentPath.path).data({'properties': currentPath.properties, 'id': currentPath.id});
  173. }
  174. shapes.push(aPath);
  175. }
  176. canvas.setViewBox(offset.x, offset.y, width, height, false);
  177. shapes.attr(style).scale(scale.x, scale.y, mapleft, maptop);
  178. if(crossline.enable === true){
  179. shapes.mouseover(function(){
  180. showCrossLine();
  181. }).mousemove(function(e){
  182. moveCrossLine(e);
  183. }).mouseout(function(){
  184. hideCrossLine();
  185. });
  186. back.mouseover(function(){
  187. showCrossLine();
  188. }).mousemove(function(e){
  189. moveCrossLine(e);
  190. }).mouseout(function(){
  191. hideCrossLine();
  192. });
  193. }
  194. function showCrossLine(){
  195. self.crosslineX.toFront().show();
  196. self.crosslineY.toFront().show();
  197. }
  198. function moveCrossLine(e){
  199. var pos = getEventPos(e);
  200. self.crosslineX.transform('T0,'+pos.y);
  201. self.crosslineY.transform('T'+ pos.x + ',0');
  202. }
  203. function hideCrossLine(){
  204. self.crosslineX.hide();
  205. self.crosslineY.hide();
  206. }
  207. function getEventPos(e){
  208. return {
  209. x: parseInt(e.pageX - left) + 0.4,
  210. y: parseInt(e.pageY - top) + 0.4
  211. };
  212. }
  213. },
  214. setPoint: function(p){
  215. // 点的默认样式
  216. var self = this,
  217. a = {
  218. "x":0,
  219. "y":0,
  220. "r":1,
  221. "opacity":0.5,
  222. "fill": "#238CC3",
  223. "stroke": "#238CC3",
  224. "stroke-width": 0,
  225. "stroke-linejoin": "round"
  226. },
  227. matrixTrans = self.shapes[0].matrix;
  228. $.extend(true, a, p);
  229. p = convertor.makePoint([a.x, a.y]);
  230. //通过matrix去计算点变换后的坐标
  231. p[0] = matrixTrans.x(p[0], p[1]);
  232. p[1] = matrixTrans.y(p[0], p[1]);
  233. a.x = p[0];
  234. a.y = p[1];
  235. c = self.canvas.circle(p[0], p[1], a.r).attr(a);
  236. return c;
  237. },
  238. json2path: function(json){
  239. var self = this,
  240. shapes = json.features,
  241. shapeType,
  242. shapeCoordinates,
  243. str,
  244. geometries,
  245. pathArray = [],
  246. i, j,
  247. len, len2,
  248. val,
  249. shape;
  250. convertor.xmin = 360;
  251. convertor.xmax = 0;
  252. convertor.ymin = 180;
  253. convertor.ymax = 0;
  254. for(i = 0, len = shapes.length; i < len; i++){
  255. shape = shapes[i];
  256. if(shape.type == 'Feature'){
  257. pushApath(shape.geometry, shape);
  258. }else if(shape.type = 'GeometryCollection'){
  259. geometries = shape.geometries;
  260. for(j = 0, len2 = geometries.length; j < len2; j++){
  261. val = geometries[j];
  262. pushApath(val, val);
  263. }
  264. }
  265. }
  266. function pushApath(gm, shape){
  267. shapeType = gm.type;
  268. shapeCoordinates = gm.coordinates;
  269. str = convertor[shapeType](shapeCoordinates);
  270. pathArray.push({
  271. type: shapeType,
  272. path: str,
  273. properties: shape.properties,
  274. id: shape.id
  275. });
  276. }
  277. return pathArray;
  278. }
  279. };
  280. GeoMap.version = version;
  281. this.GeoMap = GeoMap;
  282. })();