精华内容
下载资源
问答
  • 瓦片地图拼接

    千次阅读 2019-11-20 13:40:21
    随着现在地图信息愈加强大,为了更加详细地表示地图信息,瓦片地图成为了一种比较好的方式,这篇博客主要就是讲述了一下将瓦片拼接成为地图的原理,以及相关代码。 何为瓦片地图 何为瓦片地图,其实非常简单,可以...

    gdal的简单代码使用——瓦片地图拼接

    瓦片地图

    随着现在地图信息愈加强大,为了更加详细地表示地图信息,瓦片地图成为了一种比较好的方式,这篇博客主要就是讲述了一下将瓦片拼接成为地图的原理,以及相关代码。

    何为瓦片地图

    何为瓦片地图,其实非常简单,可以理解为小时候大家玩过的拼图,只不过拼图的数量更多,完成拼接的人,也从自己变为计算机,这样瓦片地图的作用和方法就变得非常清晰了。下面再来看看瓦片地图的参数,(x,y,z)。首先从z说起,当z = 1时,代表着瓦片地图的第一层,此时一副完整的世界地图切割了(z-1 )次,同理z等于多少就代表切割了多少次,并且此时瓦片的个数为2^(z - 1)。x和y则更加好理解,大致等于直角坐标系的横纵坐标。

    所用的库

    在这次所使用的库为gdal,GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。(后附gdal文件的相关库,可自行配置)

    代码

    #include<cstdio>
    #include<iostream>
    #include "gdal_priv.h"
    #include<iomanip>
    #include "cpl_conv.h"
    #include "ogrsf_frmts.h"
    #include<cmath>
    
    using namespace std;
    
    int main()
    {
    	int x_1 = 22390, x_2 = 22470, y_1 = 52017, y_2 = 52072;//在此处输入,x和y的值,尽量保证x_2 - x_1 = 80,y_2 - y_1 = 55
    	int i, j;
    	//如果想改成输入经纬度,可以研究一下中间被注释的代码
    	/*
    	//int pi = 3.1415
    	//int ix, iy, il;
    	//int lat_min,lon_max,lat_min,lon_max;
    	//int x_1 = ((lon_min + 180)/360) * pow(2,17);
    	//int x_2 = ((lon_max + 180)/360) * pow(2,17);
    	//int y_1 = (1 - ((log(tan(lat_min*(pi / 180))) + (1 / (cos(lat_min * (pi / 180))))) / pi)) * pow(2,16);
    	//int y_2 = (1 - ((log(tan(lat_max*(pi / 180))) + (1 / (cos(lat_max * (pi / 180))))) / pi)) * pow(2,16);
    	*/
    	typedef unsigned char       BYTE;//定义无符号性的char型为BYTE
    	typedef unsigned short      WORD;
    	typedef unsigned long       DWORD;
    	GDALDataset *poDataset2;//数据集对象指针
    	GDALAllRegister();//注册驱动
    	BYTE* data = new BYTE[256 * 256 * 3];
    	GDALDataset *poDataset;//GDAl数据集
    	GDALDriver* poDriver;//驱动,用于创建新的文件
    	poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");//获取GDALDriverManager类的tiff的单例
    	char** papszMetadata = poDriver->GetMetadata();//一系列键值对。可以分为不同的Domain。
    	poDataset = poDriver->Create("E:\\c++code\\test3\\photo generate\\tif\\CREATE1.tif", 85 * 256, 60 * 256, 3, GDT_Byte, papszMetadata);//在此处修改过渡文件tif的保存路径
    	//创建过渡用的TIF文件
    	for(i=x_1;i <=x_2;i++)//行号
    		for (j = y_1; j <= y_2; j++)//列号
    		{
    			std::string input = string("E:\\c++code\\test3\\17\\") + std::to_string(i) + "\\" + std::to_string(j) + ".png";
    			poDataset2 = (GDALDataset*)GDALOpen(input.c_str(), GA_ReadOnly);// , GA_ReadOnly);//打开数据
    			poDataset2->RasterIO(GF_Read, 0, 0, 256, 256, data, 256, 256, GDT_Byte, 3, 0, 0, 0, 0);//读取数据
    			poDataset->RasterIO(GF_Write, 256 * (i - x_1), 256 * (j - y_1), 256, 256, data, 256, 256, GDT_Byte, 3, 0, 0, 0, 0);//写入数据
    
    		}
    	poDriver = GetGDALDriverManager()->GetDriverByName("PNG");
    	poDataset2 = poDriver->CreateCopy("E:\\c++code\\test3\\photo generate\\png\\output1.png", poDataset, 3, papszMetadata, NULL, NULL); //在此处修改保存的路径
    
    }
    

    相关资源

    Gdal的相关库(不建议下载,毕竟要钱)
    有兴趣的同学也可以,自己去配Gdal库的环境,网上的教程很多。

    展开全文
  • 本软件可将存储于*.mbtiles文件中的地图/影像瓦片自动拼接为一副完整的大图(tif格式)。只要获取了目标区域地图/影像的MBTiles瓦片,利用本软件即可获得该区域完整的地图/影像。软件自带网络地图/影像下载为MBTiles...
  • https://blog.csdn.net/qq_35080168/article/details/106073143博客内需要展示的效果图 太大了没没发看 就传成资源
  • 有关瓦片地图拼接的相关库,如果有兴趣的同学也可以自己配环境,以帮助自己熟悉Vs以及C++,该库很全,基本可适应C++的大部分内容
  • 先打开谷歌地图下载器.exe,输入各项参数,先点击...最后拼接地图拼接.exe,打开newtask.egmd,选择要拼接的格式。 注意本软件单线程下载,且不能暂停,输入经纬度按照“度”为单位。   下载地址:http://yunpan.

    先打开谷歌地图下载器.exe,输入各项参数,先点击生成项目(!!!!),可以看出需要下载多少幅256*256大小的瓦片地图,然后开始就ok了


    下载完可用,地图浏览,打开刚刚生成的项目newtask.egmd


    最后拼接用地图拼接.exe,打开newtask.egmd,选择要拼接的格式。

    注意本软件单线程下载,且不能暂停,输入经纬度按照“度”为单位。

     

    下载地址:http://yunpan.cn/cVdgyiZTueu25(提取码:bc3f)

    展开全文
  • 将已下载的地图任务,拼接为Arcgis Server缓存瓦片步骤: 打开地图拼接窗口 2.选择已下载地图的任务文件 3.选择文件格式为导出ArcGIS Server缓存瓦片 ...

    将已下载的地图任务,拼接为Arcgis Server缓存瓦片步骤:

     

    1. 打开地图拼接窗口

     

    2.选择已下载地图的任务文件

     

     

    3.选择文件格式导出ArcGIS Server缓存瓦片 

     

    展开全文
  • flask表单查询经纬度获取瓦片地图拼接 瓦片服务器:tileserver-gl 启动命令:docker run --rm -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl 1. templates文件 404.html {% extends "base....

    flask表单查询经纬度获取瓦片地图并拼接

    瓦片服务器:tileserver-gl
    启动命令:docker run --rm -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl

    1. templates文件

    404.html

    {% extends "base.html" %}
    
    {% block title %}Map Search - Page Not Found{% endblock %}
    
    {% block page_content %}
    <div class="page-header">
        <h1>Not Found</h1>
    </div>
    {% endblock %}
    
    

    500.html

    {% extends "base.html" %}
    
    {% block title %}Map Search - Internal Server Error{% endblock %}
    
    {% block page_content %}
    <div class="page-header">
        <h1>Internal Server Error</h1>
    </div>
    {% endblock %}
    
    

    base.html

    {% extends "bootstrap/base.html" %}
    
    {% block title %}Map Search{% endblock %}
    
    {% block head %}
    {{ super() }}
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
    <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
    {% endblock %}
    
    {% block navbar %}
    <div class="navbar navbar-inverse" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Map Search</a>
            </div>
            <div class="navbar-collapse collapse">
    {#            <ul class="nav navbar-nav">#}
    {#                <li><a href="/">Home</a></li>#}
    {#            </ul>#}
            </div>
        </div>
    </div>
    {% endblock %}
    
    {% block content %}
    <div class="container">
        {% for message in get_flashed_messages() %}
        <div class="alert alert-warning">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            {{ message }}
        </div>
        {% endfor %}
        {% block page_content %}{% endblock %}
    </div>
    {% endblock %}
    
    {% block scripts %}
    {{ super() }}
    {{ moment.include_moment() }}
    {% endblock %}
    
    

    index.html

    {% extends "base.html" %}
    {% import "bootstrap/wtf.html" as wtf %}
    
    {% block title %}Map Search{% endblock %}
    
    {% block page_content %}
    <div class="page-header">
        <h1>您好,请输入您要查询的地图经纬度坐标:</h1>
    </div>
    {{ wtf.quick_form(form) }}
    {% endblock %}
    
    

    2. app.py(主要逻辑)

    import math
    import os
    import re
    
    from flask import Flask, render_template, redirect, url_for
    from flask_bootstrap import Bootstrap
    from flask_moment import Moment
    from flask_wtf import FlaskForm
    from wtforms import FloatField, SubmitField
    from wtforms.validators import DataRequired
    
    import requests
    import PIL.Image as Image
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'hard to guess string'
    
    bootstrap = Bootstrap(app)
    moment = Moment(app)
    
    
    class QueryForm(FlaskForm):
        longitude = FloatField('经度:', validators=[DataRequired()])
        latitude = FloatField('纬度:', validators=[DataRequired()])
        query = SubmitField('查询')
    
    
    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('404.html'), 404
    
    
    @app.errorhandler(500)
    def internal_server_error(e):
        return render_template('500.html'), 500
    
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        longitude = None
        latitude = None
        pic_folder = 'pics'
        form = QueryForm()
        if form.validate_on_submit():
            longitude = form.longitude.data
            latitude = form.latitude.data
            tile_x, tile_y = deg2num(latitude, longitude)
    
            if not os.path.exists(pic_folder):
                os.mkdir(pic_folder)
                os.chdir(os.getcwd() + '/' + pic_folder)
                get_tiles(tile_x, tile_y)
                tiles_path = os.getcwd()
                merge_tiles(tiles_path)
            return redirect(url_for('index'))
        return render_template('index.html', form=form)
    
    
    def deg2num(lat_deg, lon_deg, zoom=11):
        lat_rad = math.radians(lat_deg)
        n = 2.0 ** zoom
        tile_x = int((lon_deg + 180.0) / 360.0 * n)
        tile_y = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
        return tile_x, tile_y
    
    
    def get_tiles(tile_x, tile_y):
        count = 0
        offset = 2
        for y in range(tile_y-offset, tile_y+offset):
            for x in range(tile_x-offset, tile_x+offset):
                url = 'http://localhost:8080/styles/klokantech-basic/11/{0}/{1}@2x.png'.format(x, y)
                print(url)
                img = requests.get(url).content
                count += 1
                img_name = '{0}-{1}-{2}.png'.format(count, x, y)
                with open(img_name, 'wb+') as file:
                    file.write(img)
    
    
    def merge_tiles(tiles_path):
        IMAGE_SIZE = 256
        IMAGE_ROW = 4
        IMAGE_COLUMN = 4
        IMAGE_PATH = tiles_path
        image_names = [name for name in os.listdir(IMAGE_PATH)]
        # 图片名字格式为'16-1073-718.png',因为每张瓦片图需要按序排列,所以需要按第一个数字排序
        re_digits = re.compile(r'(\d+)')
        image_names = sorted(image_names, key=lambda s: int(re_digits.split(s)[1]))
    
        to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))
        for y in range(1, IMAGE_ROW + 1):
            for x in range(1, IMAGE_COLUMN + 1):
                from_image = Image.open(IMAGE_PATH + '/' + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
                    (IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
                print(image_names[IMAGE_COLUMN * (y - 1) + x - 1])
                to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
        return to_image.save(IMAGE_PATH + '/final.jpg')
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    
    1. 输入经纬度8.5375和47.3790查询,可以得到对应的小瓦片图,合并后效果如下:
      在这里插入图片描述
    展开全文
  • 瓦片地图制作(图片拼接

    热门讨论 2010-11-16 10:16:16
    瓦片地图的简单图片拼接,用js实现地图拖拽和缩放,内带有图片切割程序(c#),适合初学者。
  • 第四和第五章节里介绍了在得到瓦片行列号后如何获得离线和在线地图的URL,这个章节里,我们将介绍在通过URL得到瓦片后,如何将其显示在浏览器相对应的地方,拼接出整块地图。 2.左上角瓦片起始点屏幕
  • 离线地图瓦片下载器

    2018-07-14 15:58:58
    压缩包里包括下载下来的瓦片地图,以及js拼接地图程序,并在拼接成的离线地图上进行标注,适用于pc端地图网页制作
  • 采用div嵌套table的方式,每当拖拽地图区域时,添加新的行列,同时隐藏超出题图区域的行列,这样始终显示拖拽之后的地图数据,由于我采用的mvc3技术,但是主要代码还是基于javascript的,代码详见views/map文件夹,...
  • // 正常百度地图 // static String link = "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=20170712&scaler=1&p=1"; static String link = ...
  • maps.com和natgeomaps.com公开了很多地图,使用的正是Zoomify-flash图像浏览器,图像被分割为N个瓦片动态加载。想要下载下来离线使用的话就要批量下载瓦片并拼合。瓦片逐层分割,命名为“层-行-列”,放在TilesGroup...
  • ArcEngine环境下实现瓦片地图的访问与拼接
  • 第二章节里介绍了什么是瓦片行列号以及计算它的原因,第三章节里介绍了如何通过地理范围计算出这个范围内瓦片的行列号,第四和第五章节里介绍了在得到瓦片行列号后如何获得离线和在线地图的URL,这个章节里,我们
  • 首先打开WOLFMAP地图下载器,切换地图为谷歌地球。 切换成功了,不过连接不上谷歌的服务器,所以无法显示影像。现在很多地方都会出现这种情况,解决方法如下,选择工具->谷歌IP检测。 弹出如下对话框...
  • 第二章节里介绍了什么是瓦片行列号以及计算它的原因,第三章节里介绍了如何通过地理范围计算出这个范围内瓦片的行列号,第四和第五章节里介绍了在得到瓦片行列号后如何获得离线和在线地图的URL,...
  • 什么是地图瓦片地图瓦片是包含了一系列比例尺、一定地图范围内的地图切片文件。地图瓦片按照金字塔结构组织,每张瓦片都可通过级别、行列号唯一标记。在平移、缩放地图时,浏览器根据金字塔规则,计算出所需的...
  • Google地图瓦片拼图算法解析

    万次阅读 2014-04-10 20:41:06
    客户端地图拼图算法解析 概述:主要是阐述如何将瓦片地图图片拼接成完整地图的一些概念以及相关算法。...地图瓦片地址:... 现在就是要将一张张这类的地图瓦片,在客户端拼接成一幅完整
  • 什么是地图瓦片地图瓦片是包含了一系列比例尺、一定地图范围内的地图切片文件。地图瓦片按照金字塔结构组织,每张瓦片都可通过级别、行列号唯一标记。在平移、缩放地图时,浏览器根据金字塔规则,计算出所需的...
  • 百度地图瓦片包下载器

    热门讨论 2015-12-10 16:29:00
    百度地图瓦片图下载器,用户可根据自己的需要绘制下载区域,选择需要下载的层数,下载类型可选择都市圈,电子地图,标注,影像等,下载之后还可拼接
  • 从底层谈WebGIS 原理设计与实现(六):WebGIS中地图瓦片在Canvas上的拼接显示原理 作者:naaoveGI…文章来源:naaoveGIS点击数:1145更新时间:2014-9-14 摘要:在之前的五个章节中,我们在第一章节里介绍了...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 200
精华内容 80
关键字:

地图瓦片拼接