geomap-0.4.9.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * GeoMap v0.4.9
  3. * https://github.com/x6doooo/GeoMap
  4. *
  5. * Copyright 2013 Dx. Yang
  6. * Released under the MIT license
  7. */
  8. (function($, undefined){
  9. var version = "0.4.9"
  10. var convertor_parse = {
  11. "formatPoint": function(p){
  12. return [
  13. (p[0] < -168.5 ? p[0] + 360 : p[0]) + 170,
  14. 90 - p[1]
  15. ];
  16. },
  17. "makePoint": function(p){
  18. var self = this,
  19. point = self.formatPoint(p),
  20. x = point[0],
  21. y = point[1];
  22. if(self.xmin > x) self.xmin = x;
  23. if(self.xmax < x) self.xmax = x;
  24. if(self.ymin > y) self.ymin = y;
  25. if(self.ymax < y) self.ymax = y;
  26. },
  27. "Point": function(coordinates){
  28. this.makePoint(coordinates);
  29. },
  30. "LineString": function(coordinates){
  31. var self = this,
  32. i = 0,
  33. len = coordinates.length;
  34. for( ; i < len; i++){
  35. self.makePoint(coordinates[i]);
  36. }
  37. },
  38. "Polygon": function(coordinates){
  39. var i = 0,
  40. len = coordinates.length;
  41. for(; i < len; i++){
  42. convertor.LineString(coordinates[i]);
  43. }
  44. },
  45. "MultiPoint": function(coordinates){
  46. var i = 0,
  47. len = coordinates.length;
  48. for(; i < len; i++){
  49. convertor.Point(coordinates[i]);
  50. }
  51. },
  52. "MultiLineString": function(coordinates){
  53. var i = 0,
  54. len = coordinates.length;
  55. for(; i < len; i++){
  56. convertor.LineString(coordinates[i]);
  57. }
  58. },
  59. "MultiPolygon": function(coordinates){
  60. var i = 0,
  61. len = coordinates.length;
  62. for(; i < len; i++){
  63. convertor.Polygon(coordinates[i]);
  64. }
  65. }
  66. };
  67. function parseSrcSize(json){
  68. var
  69. shapes = json.features,
  70. shapeType,
  71. shapeCoordinates,
  72. geometries,
  73. i, j,
  74. len, len2,
  75. val,
  76. shape;
  77. convertor_parse.xmin = 360;
  78. convertor_parse.xmax = 0;
  79. convertor_parse.ymin = 180;
  80. convertor_parse.ymax = 0;
  81. for(i = 0, len = shapes.length; i < len; i++){
  82. shape = shapes[i];
  83. if(shape.type == 'Feature'){
  84. pushApath(shape.geometry, shape);
  85. }else if(shape.type = 'GeometryCollection'){
  86. geometries = shape.geometries;
  87. for(j = 0, len2 = geometries.length; j < len2; j++){
  88. val = geometries[j];
  89. pushApath(val, val);
  90. }
  91. }
  92. }
  93. function pushApath(gm){
  94. shapeType = gm.type;
  95. shapeCoordinates = gm.coordinates;
  96. convertor_parse[shapeType](shapeCoordinates);
  97. }
  98. json.srcSize = {
  99. left: convertor.xmin.toFixed(4) * 1,
  100. top: convertor.ymin.toFixed(4) * 1,
  101. width: (convertor.xmax - convertor.xmin).toFixed(4) * 1,
  102. height: (convertor.ymax - convertor.ymin).toFixed(4) * 1
  103. };
  104. return json;
  105. }
  106. var convertor = {
  107. /*!Private
  108. 让阿拉斯加地区在地图右侧显示
  109. */
  110. "formatPoint": function(p){
  111. return [
  112. (p[0] < -168.5 ? p[0] + 360 : p[0]) + 170,
  113. 90 - p[1]
  114. ];
  115. },
  116. "makePoint": function(p){
  117. var self = this,
  118. point = self.formatPoint(p),
  119. x = (point[0] - convertor.offset.x) * convertor.scale.x,
  120. y = (point[1] - convertor.offset.y) * convertor.scale.y;
  121. return [x, y];
  122. },
  123. "Point": function(coordinates){
  124. coordinates = this.makePoint(coordinates);
  125. return coordinates.join(',');
  126. },
  127. "LineString": function(coordinates){
  128. var str = '',
  129. self = this,
  130. i = 0,
  131. len = coordinates.length,
  132. point;
  133. for( ; i < len; i++){
  134. point = self.makePoint(coordinates[i]);
  135. if(i == 0){
  136. str = 'M' + point.join(',');
  137. }else{
  138. str = str + 'L' + point.join(',');
  139. }
  140. }
  141. return str;
  142. },
  143. "Polygon": function(coordinates){
  144. var str = '',
  145. i = 0,
  146. len = coordinates.length;
  147. for(; i < len; i++){
  148. str = str + convertor.LineString(coordinates[i]) + 'z';
  149. }
  150. return str;
  151. },
  152. "MultiPoint": function(coordinates){
  153. var arr = [],
  154. i = 0,
  155. len = coordinates.length;
  156. for(; i < len; i++){
  157. arr.push(convertor.Point(coordinates[i]));
  158. }
  159. return arr;
  160. },
  161. "MultiLineString": function(coordinates){
  162. var str = '',
  163. i = 0,
  164. len = coordinates.length;
  165. for(; i < len; i++){
  166. str += convertor.LineString(coordinates[i]);
  167. }
  168. return str;
  169. },
  170. "MultiPolygon": function(coordinates){
  171. var str = '',
  172. i = 0,
  173. len = coordinates.length;
  174. for(; i < len; i++){
  175. str += convertor.Polygon(coordinates[i]);
  176. }
  177. return str;
  178. }
  179. };
  180. function json2path(json, obj){
  181. var
  182. shapes = json.features,
  183. shapeType,
  184. shapeCoordinates,
  185. str,
  186. geometries,
  187. pathArray = [],
  188. i, j,
  189. len, len2,
  190. val,
  191. shape;
  192. convertor.scale = null;
  193. convertor.offset = null;
  194. if((!obj.config.scale || !obj.config.offset) && !json.srcSize){
  195. parseSrcSize(json);
  196. }
  197. if(!obj.config.offset){
  198. obj.offset = {
  199. x: json.srcSize.left,
  200. y: json.srcSize.top
  201. };
  202. }else if(json.srcSize){
  203. obj.offset.x = json.srcSize.left + obj.config.offset.x;
  204. obj.offset.y = json.srcSize.top + obj.config.offset.y;
  205. }
  206. if(!obj.config.scale){
  207. var temx = obj.width / json.srcSize.width,
  208. temy = obj.height / json.srcSize.height;
  209. temx > temy ? temx = temy : temy = temx;
  210. temx = temy * 0.73;
  211. obj.scale = {
  212. x: temx,
  213. y: temy
  214. };
  215. }else{
  216. obj.scale = obj.offset.scale;
  217. }
  218. convertor.scale = obj.scale;
  219. convertor.offset = obj.offset;
  220. for(i = 0, len = shapes.length; i < len; i++){
  221. shape = shapes[i];
  222. if(shape.type == 'Feature'){
  223. pushApath(shape.geometry, shape);
  224. }else if(shape.type = 'GeometryCollection'){
  225. geometries = shape.geometries;
  226. for(j = 0, len2 = geometries.length; j < len2; j++){
  227. val = geometries[j];
  228. pushApath(val, val);
  229. }
  230. }
  231. }
  232. function pushApath(gm, shape){
  233. shapeType = gm.type;
  234. shapeCoordinates = gm.coordinates;
  235. str = convertor[shapeType](shapeCoordinates);
  236. pathArray.push({
  237. type: shapeType,
  238. path: str,
  239. properties: shape.properties,
  240. id: shape.id
  241. });
  242. }
  243. return pathArray;
  244. }
  245. var GeoMap = function(cfg){
  246. var self = this,
  247. defaultCfg = {
  248. container: 'body',
  249. offset: null,
  250. scale: null,
  251. mapStyle: {
  252. 'fill': '#fff',
  253. 'stroke': '#999',
  254. 'stroke-width': 0.7
  255. },
  256. background:'#fff',
  257. sideSize: 4
  258. };
  259. $.extend(true, defaultCfg, cfg);
  260. self.container = $(defaultCfg.container);
  261. self.offset = defaultCfg.offset;
  262. self.scale = defaultCfg.scale;
  263. if(self.container.length == 0){
  264. throw new Error('map container is not defined!');
  265. }
  266. self.width = defaultCfg.width || self.container.width();
  267. self.height = defaultCfg.height || self.container.height();
  268. self.canvas = new Raphael(self.container.get(0), self.width, self.height);
  269. self.shapes = self.canvas.set();
  270. self.config = defaultCfg;
  271. self.paths = null;
  272. };
  273. GeoMap.prototype = {
  274. clear: function(){
  275. this.offset = null;
  276. this.scale = null;
  277. this.shapes.remove();
  278. },
  279. load: function(json){
  280. this.paths = json2path(json, this);
  281. },
  282. render: function(){
  283. var self = this,
  284. shapes = self.shapes,
  285. paths = self.paths,
  286. canvas = self.canvas,
  287. config = self.config,
  288. style = config.mapStyle,
  289. aPath = null, i, len, currentPath;
  290. for(i = 0, len = paths.length; i < len; i++){
  291. currentPath = paths[i];
  292. if(currentPath.type == 'point' || currentPath.type == 'MultiPoint'){
  293. //TODO
  294. }else{
  295. aPath = canvas.path(currentPath.path).data({'properties': currentPath.properties, 'id': currentPath.id}).attr(style);
  296. }
  297. shapes.push(aPath);
  298. }
  299. },
  300. /*!
  301. 将平面上的一个点的坐标,转换成实际经纬度坐标
  302. */
  303. getGeoPosition: function(p){
  304. var self = this,
  305. x = p[0],
  306. y = p[1];
  307. x = x / self.scale.x + self.offset.x - 170;
  308. x = x > 180 ? x - 360 : x;
  309. y = 90 - (y / self.scale.y + self.offset.y);
  310. return [x, y];
  311. },
  312. geo2pos: function(p){
  313. var self = this;
  314. convertor.offset = self.offset;
  315. convertor.scale = self.scale;
  316. p = convertor.makePoint([p.x, p.y]);
  317. return p;
  318. },
  319. setPoint: function(p){
  320. // 点的默认样式
  321. var self = this,
  322. a = {
  323. "x": 0,
  324. "y": 0,
  325. "r": 1,
  326. "opacity": 0.5,
  327. "fill": "#238CC3",
  328. "stroke": "#238CC3",
  329. "stroke-width": 0,
  330. "stroke-linejoin": "round"
  331. };
  332. p = self.geo2pos(p);
  333. p = {x:p[0],y:p[1]};
  334. $.extend(true, a, p);
  335. return self.canvas.circle(p.x, p.y, a.r).attr(a);
  336. }
  337. };
  338. //TODO: heat map
  339. GeoMap.version = version;
  340. this.GeoMap = GeoMap;
  341. })(jQuery);