Mapbar地图切片的抓取和拼接算法
转自:http://blog.csdn.net/mygisforum/article/details/7022860
1.MapBar 地图瓦片抓取算法
此地图瓦片抓取算法是根据Mapbarapi里的绘图算法写出来的,使用PHP编写,将代码保存为一个PHP文件后,然后使用命令行运行: $ php -f filename.php。
注:cmd>cd "x:\...\php.exe"。
- <?php
- /**
- * 抓取mapbar切片的算法 by CrossYou at 2011/01/22
- *
- * @version 1.0.0
- * @link http://crossyou.cn/
- */
- $mapbarImgRoot = './mapbar/';
- //每层地图切片的文件夹名称
- $levelFolder = array('W','0','1','2','3','4','5','6','7','8','9','10','11','12','13','16');
- //每层地图切片所跨的经度数
- $cutImgLonRange=array(90,40,20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002,0.001);
- //每层地图切片所跨的维度数
- $cutImgLatRange=array(90*0.8,40*0.8,20*0.8,10*0.8,5*0.8,2*0.8,0.8,0.5*0.8,0.2*0.8,0.1*0.8,0.05*0.8,0.02*0.8,0.01*0.8,0.005*0.8,0.002*0.8,0.001*0.8);
- $blockSize=array(10,10,10,10,10,10,10,10,10,10,50,50,50,50,50,50);
- for($zoomLevel=0;$zoomLevel<16;$zoomLevel++){
- $clipXNum=ceil(360/$cutImgLonRange[$zoomLevel]);
- $clipYNum=ceil(90/$cutImgLatRange[$zoomLevel]);
- $clipLonRange = $cutImgLonRange[$zoomLevel];
- $clipLatRange = $cutImgLatRange[$zoomLevel];
- $clipXGap = -180-$clipLonRange/2;
- //从缩放级别5开始,只抓取中国范围内的地图,因为此级别以后的,非国内的都是背景图,抓了无意义。
- if($zoomLevel>3){
- //--------中国范围的地图
- $west = 73;
- $east = 136;
- $north = 54;
- $south = 3;
- $chinaLonRange = 63;//中国经度跨度
- $chinaLatRange = 51;//中国维度跨度
- $chinaClipXNum = ceil($chinaLonRange/$clipLonRange);
- $chinaClipYNum = ceil($chinaLatRange/$clipLatRange);
- for($i=0;$i<$chinaClipXNum;$i++){
- $lon = $west+$clipLonRange*$i;
- for($j=0;$j<$chinaClipYNum;$j++){
- $lat = $south+$clipLatRange*$j;
- $clipXNo = floor($lon/$cutImgLonRange[$zoomLevel]);
- $clipYNo = floor($lat/$cutImgLatRange[$zoomLevel]);
- $clipXNo=($clipXNo)%$clipXNum;
- if($clipXNo>=$clipXNum/2)$clipXNo-=$clipXNum;
- if($clipXNo<-$clipXNum/2)$clipXNo+=$clipXNum;
- echo "\n新的切片... => \n";
- echo '经纬度:'.$lon.' , '.$lat."\n";
- echo "-------------------------------\n";
- echo '切片序号:'.$clipXNo.' , '.$clipYNo."\n";
- echo "-------------------------------\n";
- //切片分文件夹存放位置
- $folderXNo = (int)floor($clipXNo/$blockSize[$zoomLevel]);
- //切片分文件夹存放位置
- $folderYNo = (int)floor($clipYNo/$blockSize[$zoomLevel]);
- if($folderXNo<0){
- $folderXNo+=1;
- }
- if($folderYNo<0){
- $folderYNo+=1;
- }
- $fileXNo =($clipXNo)-$folderXNo*$blockSize[$zoomLevel];
- $fileYNo =($clipYNo)-$folderYNo*$blockSize[$zoomLevel];
- $imgPre = 'http://img.mapbar.com/maplite/mapbank/mapbar/';
- $imgDir = $levelFolder[$zoomLevel].'/'.$folderXNo.'_'.$folderYNo.'/';
- $imgName = $fileXNo.'_'.$fileYNo.'.png';
- $imgUrl = $imgPre.$imgDir.$imgName;
- $localImgDir = $mapbarImgRoot.$imgDir;
- $localImgName = $localImgDir.$imgName;
- if (!is_file($localImgName)){
- createdir($localImgDir);
- if(copy($imgUrl,$localImgName)){
- echo '图片:=> '.$imgDir.$imgName." 成功下载到本地\n\n";
- }
- }
- }
- }
- }else{
- for($i= -$clipXNum/2;$i<=$clipXNum/2;$i++){
- $lon = $clipLonRange*$i;
- if($i<0)$lon+=$clipLonRange/2;
- if($i==0)continue;
- if($i>0)$lon-=$clipLonRange/2;
- for($j=-$clipYNum;$j<=$clipYNum;$j++){
- $lat = $clipLatRange*$j;
- if($j<0)$lat+=$clipLatRange/2;
- if($j==0)continue;
- if($j>0)$lat-=$clipLatRange/2;
- $clipXNo = floor($lon/$cutImgLonRange[$zoomLevel]);
- $clipYNo = floor($lat/$cutImgLatRange[$zoomLevel]);
- $clipXNo=($clipXNo)%$clipXNum;
- if($clipXNo>=$clipXNum/2)$clipXNo-=$clipXNum;
- if($clipXNo<-$clipXNum/2)$clipXNo+=$clipXNum;
- echo "\n新的切片... => \n";
- echo '经纬度:'.$lon.' , '.$lat."\n";
- echo "-------------------------------\n";
- echo '切片序号:'.$clipXNo.' , '.$clipYNo."\n";
- echo "-------------------------------\n";
- //切片分文件夹存放位置
- $folderXNo = (int)floor($clipXNo/$blockSize[$zoomLevel]);
- //切片分文件夹存放位置
- $folderYNo = (int)floor($clipYNo/$blockSize[$zoomLevel]);
- if($folderXNo<0){
- $folderXNo+=1;
- }
- if($folderYNo<0){
- $folderYNo+=1;
- }
- $fileXNo =($clipXNo)-$folderXNo*$blockSize[$zoomLevel];
- $fileYNo =($clipYNo)-$folderYNo*$blockSize[$zoomLevel];
- $imgPre = 'http://img.mapbar.com/maplite/mapbank/mapbar/';
- $imgDir = $levelFolder[$zoomLevel].'/'.$folderXNo.'_'.$folderYNo.'/';
- $imgName = $fileXNo.'_'.$fileYNo.'.png';
- $imgUrl = $imgPre.$imgDir.$imgName;
- $localImgDir = $mapbarImgRoot.$imgDir;
- $localImgName = $localImgDir.$imgName;
- if (!is_file($localImgName)){
- createdir($localImgDir);
- if(copy($imgUrl,$localImgName)){
- echo '图片:=> '.$imgDir.$imgName." 成功下载到本地\n\n";
- }
- }
- }
- }
- }
- }
- /**
- * 创建多级目录 摘自网络
- * 如有好的建议,请到 http://crossyou.cn/给我留言 谢谢!
- *
- * @since 1.0.5
- * @param string $dir
- */
- function createdir($dir){
- $array_dir=explode("/",$dir);//把多级目录分别放到数组中
- $depth = count($array_dir);
- $path = '';
- for($i=0;$i<$depth;$i++){
- $path .= $array_dir[$i]."/";
- if(!is_dir($path)){
- mkdir($path);
- }
- }
- }
- ?>
2.MapBar地图瓦片拼接算法
作者制作的一个Demo:http://www.crossyou.cn/attachments/2011/03/mapbar.html。下面的源代码可能用到了一小点的jQuery。
- var divId = 'map';
- var imgWidth = 300;
- var imgHeight = 300;
- var imgExt = 'png';
- var centerpoint = '120.15689,35.96333';
- var point = centerpoint.split(',');
- var _centerLon = point[0];
- var _centerLat = point[1];
- var zoomlevel = 8;
- var $map = $('#'+divId);
- //每层地图切片的文件夹名称
- var levelFolder = new Array('W','0','1','2','3','4','5','6','7','8','9','10','11','12','13','16');
- //每层地图切片所跨的经度数
- var cutImgLonRange = new Array(90,40,20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002,0.001);
- //每层地图切片所跨的维度数
- var cutImgLatRange = new Array(90*0.8,40*0.8,20*0.8,10*0.8,5*0.8,2*0.8,0.8,0.5*0.8,0.2*0.8,0.1*0.8,0.05*0.8,0.02*0.8,0.01*0.8,0.005*0.8,0.002*0.8,0.001*0.8);
- //地图区块大小 将不同区块的放在不同的文件夹下面进行管理
- var blockSize = new Array(10,10,10,10,10,10,10,10,10,10,50,50,50,50,50,50);
- //纬度的偏移
- var latOffset = new Array(0,0,0,0,0,0,0,0,75,0,0,-150,0,0,0,0);
- function drawMap(){
- var LatLon = coordOffsetDecrypt(_centerLon,_centerLat);//解密Mapbar坐标
- centerLon = LatLon[0];
- centerLat = LatLon[1];
- var mapwidth = $map.width();
- var mapheight = $map.height();
- var halfNum5clipX = Math.ceil(mapwidth/imgWidth/2);
- var halfNum5clipY = Math.ceil(mapheight/imgHeight/2);
- var _blockSize = blockSize[zoomlevel];
- var clipLonRange = cutImgLonRange[zoomlevel];
- var clipLatRange = cutImgLatRange[zoomlevel];
- var multiple = 100000;
- var clipXNum=(360/clipLonRange);
- rotationCosVal=1.0;
- rotationSinVal=0.0;
- var Clip = [];
- clipNo5X=Math.floor((centerLon)/clipLonRange);
- clipNo5Y=Math.floor((centerLat)/clipLatRange);
- if(clipNo5X<0)clipNo5X+=1;
- var mapX=mapwidth/2-Math.round(((centerLon*multiple)%(clipLonRange*multiple))*imgWidth/(clipLonRange*multiple));
- if(centerLat>=0) {
- mapY=mapheight/2-imgHeight+Math.round(((centerLat*multiple)%(clipLatRange*multiple))*imgHeight/(clipLatRange*multiple));
- }else {
- mapY=mapheight/2+Math.round(((centerLat*multiple)%(clipLatRange*multiple))*imgHeight/(clipLatRange*multiple));
- }
- $map.html('');
- // -- 真正给力的开始
- for (var _clipXNo = -halfNum5clipX - 1; _clipXNo <= halfNum5clipX; _clipXNo++) {
- for (var _clipYNo = -halfNum5clipY - 1; _clipYNo <= halfNum5clipY; _clipYNo++) {
- try {
- var clipXNo = parseInt(clipNo5X + _clipXNo);//地图横向切片序列号
- var clipYNo = parseInt(clipNo5Y + _clipYNo);
- clipXNo = (clipXNo) % clipXNum
- if (clipXNo >= (clipXNum / 2))
- clipXNo -= clipXNum;
- if (clipXNo < (-clipXNum / 2))
- clipXNo += clipXNum;
- var folderX = parseInt(Math.floor((clipXNo) / _blockSize));
- var folderY = parseInt(Math.floor((clipYNo) / _blockSize));
- if (folderX < 0)
- folderX += 1;
- if (folderY < 0)
- folderY += 1;
- var fileXNo = (clipXNo) - folderX * _blockSize;
- var fileYNo = (clipYNo) - folderY * _blockSize;
- var _strImgUrl = 'http://img.mapbar.com/maplite/mapbank/mapbar/' + levelFolder[zoomlevel] + '/';
- if (zoomlevel >= 14)
- _strImgUrl += folderX + "/";
- _strImgUrl += folderX + "_" + folderY + "/";
- _strImgUrl += fileXNo + "_" + fileYNo + "." + imgExt;
- var clipLeft = (_clipXNo * imgWidth) + parseInt(mapX);
- var clipTop = (-(_clipYNo * imgHeight) + parseInt(mapY));
- clipTop = clipTop + latOffset[zoomlevel];
- var isClearImgUrl = false;
- if ((clipLeft < -imgWidth || clipLeft > mapwidth || clipTop > mapheight || clipTop < -imgHeight))
- isClearImgUrl = true;
- if (isClearImgUrl)
- continue;
- var clipId = ((zoomlevel).toString(16) + (clipNo5X + _clipXNo).toString(16) + 'l' + (clipNo5Y + _clipYNo).toString(16)).toLowerCase();
- if (_strImgUrl && _strImgUrl.indexOf("NaN") < 0) {
- if (Clip[clipId] == null) {
- Clip[clipId] = new Image();
- Clip[clipId].id = clipId;
- Clip[clipId].name = clipId;
- Clip[clipId].unselectable = "on";
- Clip[clipId].style.position = "absolute";
- Clip[clipId].style.MozUserSelect = "none";
- Clip[clipId].src = _strImgUrl;
- }
- var p2 = (clipLeft + imgWidth / 2 - mapwidth / 2) * rotationCosVal - (clipTop + imgHeight / 2 - mapheight / 2) * rotationSinVal + mapwidth / 2;
- var p5 = (clipLeft + imgWidth / 2 - mapwidth / 2) * rotationSinVal + (clipTop + imgHeight / 2 - mapheight / 2) * rotationCosVal + mapheight / 2;
- Clip[clipId].style.top = parseInt(p5 - imgHeight / 2) + "px";
- Clip[clipId].style.left = parseInt(p2 - imgWidth / 2) + "px";
- //var interval = parseInt($('#interval').val());
- $map.append(Clip[clipId]);
- }
- _strImgUrl = null;
- }
- catch (e) {
- throw (e);
- }
- }
- }
- }
- // The follow is two helper functions
- /**
- * 将真实地理坐标加密为Mapbar经纬度坐标
- *
- * @param x 经度值
- * @param y 维度值
- * @returns [x,y]
- */
- function coordOffsetEncrypt(x,y){
- x = parseFloat(x)*100000%36000000;
- y = parseFloat(y)*100000%36000000;
- _X = parseInt(((Math.cos(y/100000))*(x/18000))+((Math.sin(x/100000))*(y/9000))+x);
- _Y = parseInt(((Math.sin(y/100000))*(x/18000))+((Math.cos(x/100000))*(y/9000))+y);
- return [_X/100000.0,_Y/100000.0];
- }
- /**
- * 将Mapbar经纬坐标解密为真实地理坐标
- *
- * @param x 经度值
- * @param y 维度值
- * @returns [x,y]
- */
- function coordOffsetDecrypt(x,y){
- x = parseFloat(x)*100000%36000000;
- y = parseFloat(y)*100000%36000000;
- x1 = parseInt(-(((Math.cos(y/100000))*(x/18000))+((Math.sin(x/100000))*(y/9000)))+x);
- y1 = parseInt(-(((Math.sin(y/100000))*(x/18000))+((Math.cos(x/100000))*(y/9000)))+y);
- x2 = parseInt(-(((Math.cos(y1/100000))*(x1/18000))+((Math.sin(x1/100000))*(y1/9000)))+x+((x>0)?1:-1));
- y2 = parseInt(-(((Math.sin(y1/100000))*(x1/18000))+((Math.cos(x1/100000))*(y1/9000)))+y+((y>0)?1:-1));
- return [x2/100000.0,y2/100000.0];
- }
原文出自 CrossYou'Blog :
抓取算法:http://www.crossyou.cn/an-algorithm-to-crawl-mapbar-map.htm
瓦片拼接算法:http://www.crossyou.cn/a-simple-map-of-the-source-code-mapbar.htm
注:以上内容仅供学习,在此严重感谢作者分享。
后记:经验证,百度使用的MapBar的地图,算法相同,其url前缀为:
http://img.mapbar.com/maplite/mapbank/baidu/
Mapbar地图切片的抓取和拼接算法相关推荐
- 抓取Mapbar地图切片的一个算法
抓取Mapbar地图切片的一个算法 发表于 2011/03/26 这个算法去年的时候就写了,自己就是抓着玩,也算是验证了这个算法的可行性,今天特向大家分享一下,主要是根据Mapbarapi里的绘图算 ...
- 基于python的今日头条文章抓取内含signature算法
基于python的今日头条文章抓取内含signature算法 扫二维码添加微信 备注:爬虫 , 拉你进爬虫交流群 或许你会成为第一个加群的人~ 刚有的创群想法! 1. 简单文字描述头条爬虫注意点 由于 ...
- python下载谷歌地图瓦片_python抓取天地图瓦片
[实例简介] 抓取天地图瓦片 [实例截图] [核心代码] # _*_coding:utf-8_*_ from urllib import request import re import urllib ...
- 360站长平台提交站点地图sitemap.xml抓取的url数量为0的解决方法
解决方法一:不要提交https的sitemap,提交http的即可成功 解决方法二:如果提交http的还没有成功,请检查自己的sitemap.xml格式是否是UTF-8的,不是换成UTF-8即可成功 ...
- 英雄联盟世界的地图抓取与分析
0.背景 S11比赛正在如火如荼的举行.作为一个S3赛季的老玩家和地理人,我想从另外个角度带你了解LOL的世界. 1.数据获取 1.1数据初探 英雄联盟推出了其世界地图网页版,访问地址为:https: ...
- 求教一个关于网站抓取生成地图的问题
用爱站抓取网站生成地图,结果抓取了很多很多很多很多的页面,比如我站内某块内容只有16条列表页,然后URL是 xxx.xxxx.com/xx/1.html 然后结果给我抓取出xxx.xxxx.co ...
- 一份最简单的Mapbar地图源代码
一份最简单的Mapbar地图源代码 发表于 2011/03/29 恩,我想大家都懂的,本页代码源自Mapbar的Api,研究了一下它的绘制地图的算法,其实上篇文章<抓取Mapbar地图切片的一 ...
- 让你的网站快速被蜘蛛抓取收录的方法
据真实调查数据显示,90%的网民会利用搜索引擎服务查找需要的信息,而这之中有近70%的搜索者会直接在搜索结果的自然排名的第一页查找自己所需要的信息.由此可见,目前来讲SEO对于企业和产品,有着难以替代 ...
- 迅速提取网站URL链接-一键批量抓取网站链接
说到"网站地图",肯定很多SEOer或站长们不会感到生疏.网站地图.链接抓取.泛域名泛目录生成这些关于搜索引擎和用户来说都是相当重要的.网站地图,简单来说是一个包含网站所有一切链接 ...
最新文章
- 江苏“超牛”女博导:16岁考入北大,跨专业读博,成为全球第4个获此奖项的学者!...
- mysql复制模式第四部分-----环形复制
- 深度学习tensorflow数据流图基础知识点
- pytorch学习笔记(十二):权重衰减
- 正态分布某一点的概率怎么算_笔记|复习金融计量中概率随笔1(样本推整体)
- wxpython播放视频_opencv视屏流嵌入wxpython框架
- Opencores 无法点击submit的问题解决方案
- MapGIS67打开mpj文件无内容
- 泛微O A系统怎么获取服务器地址,泛微协同商务系统(Ecology)_系统底层包开发指南...
- labelcommand打印条码_Zebra条码打印机编程命令
- endpt matlab,将SDPT3配置到matlab
- 《惢客创业日记》2020.04.01-15(周三) 国家有难,匹夫有责(四)
- python spark pyspark——朴素贝叶斯习题整理
- 如何使用阿里云进行人脸和身份证头像验证比对(人证核验接口API)--java
- 手机号码11位以及格式验证规则
- LQ0266 巧排扑克牌【模拟】
- AQSW公司OA系统需求分析
- linux修改文件信息失败怎么办,【Linux】Linux修改openfiles后不生效问题?
- How to choose optimizer ?训练时,如何选择优化器?
- css怎么设置页面缩放最小宽度