11赞
780
当前位置:  开发笔记 > 编程语言 > 正文

在卫星地图上绘制数据

如何解决《在卫星地图上绘制数据》经验,为你挑选了1个好方法。

如何(lat, lon, value)在python(笔记本)中使用高分辨率的卫星背景图像在地图上绘制数据?

我正在整个互联网上爬行,但找不到任何有用的东西。Folium不提供卫星图块。SimpleKML和googleearthplot似乎仅对巨大的低分辨率地球数据有用。EarthPy可以接受图像图块,但是它们到NASA网站的链接仅提供了> 0.1度的低分辨率图像。Cartopy是matplotlib用户的新希望,但我找不到任何有关卫星图像图块的示例。

R使用RGoogleMaps程序包可以非常轻松地完成此工作,例如,:

plotmap(lat, lon, col=palette(value), data=mydataframe, zoom = 17, maptype="satellite")

我们如何在Python中做到这一点?



1> Pasa..:

另一种选择是使用gmplot。基本上,它是围绕Google Maps Javascript API的python包装器,可让您生成.html在后台使用地图渲染图的文件。

在这里,我用它来绘制相对于卫星图像背景的随机游走(默认情况下不支持此地图类型,但是使其工作起来非常简单):

from gmplot import GoogleMapPlotter
from random import random

# We subclass this just to change the map type
class CustomGoogleMapPlotter(GoogleMapPlotter):
    def __init__(self, center_lat, center_lng, zoom, apikey='',
                 map_type='satellite'):
        super().__init__(center_lat, center_lng, zoom, apikey)

        self.map_type = map_type
        assert(self.map_type in ['roadmap', 'satellite', 'hybrid', 'terrain'])

    def write_map(self,  f):
        f.write('\t\tvar centerlatlng = new google.maps.LatLng(%f, %f);\n' %
                (self.center[0], self.center[1]))
        f.write('\t\tvar myOptiOns= {\n')
        f.write('\t\t\tzoom: %d,\n' % (self.zoom))
        f.write('\t\t\tcenter: centerlatlng,\n')

        # This is the only line we change
        f.write('\t\t\tmapTypeId: \'{}\'\n'.format(self.map_type))


        f.write('\t\t};\n')
        f.write(
            '\t\tvar map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);\n')
        f.write('\n')

initial_zoom = 16
num_pts = 40

lats = [37.428]
lOns= [-122.145]
for pt in range(num_pts):
    lats.append(lats[-1] + (random() - 0.5)/100)
    lons.append(lons[-1] + random()/100)
gmap = CustomGoogleMapPlotter(lats[0], lons[0], initial_zoom,
                              map_type='satellite')
gmap.plot(lats, lons, 'cornflowerblue', edge_width=10)

gmap.draw("mymap.html")

您可以.html在浏览器中打开生成的文件,并像使用Google Maps一样进行交互。不幸的是,这意味着您不会获得漂亮的matplotlib图形窗口或其他任何东西,因此,要生成图像文件,您需要自己拍摄屏幕快照或修改某些内容以为您呈现HTML。

要记住的另一件事是,您可能需要一个Google Maps API密钥,否则最终将得到像我一样的丑陋,加黑水印的地图:

另外,由于要将值描述为颜色,因此需要手动将其转换为颜色字符串并使用gmap.scatter()方法。如果您对这种方法感兴趣,请告诉我,这样我可以尝试一些代码来做到这一点。

更新资料

这是一个在卫星图像上的散点图中支持将值编码为颜色的版本。为了达到效果,我使用matplotlib的颜色图。您可以根据需要更改颜色图,请在此处查看选项列表。我还提供了一些代码来从文件中读取API密钥apikey.txt,这使每个研究人员都可以使用自己的密钥而不更改代码(如果未找到此类文件,则照常默认不设置任何API密钥)。

import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable
from gmplot import GoogleMapPlotter
from random import random


class CustomGoogleMapPlotter(GoogleMapPlotter):
    def __init__(self, center_lat, center_lng, zoom, apikey='',
                 map_type='satellite'):
        if apikey == '':
            try:
                with open('apikey.txt', 'r') as apifile:
                    apikey = apifile.readline()
            except FileNotFoundError:
                pass
        super().__init__(center_lat, center_lng, zoom, apikey)

        self.map_type = map_type
        assert(self.map_type in ['roadmap', 'satellite', 'hybrid', 'terrain'])

    def write_map(self,  f):
        f.write('\t\tvar centerlatlng = new google.maps.LatLng(%f, %f);\n' %
                (self.center[0], self.center[1]))
        f.write('\t\tvar myOptiOns= {\n')
        f.write('\t\t\tzoom: %d,\n' % (self.zoom))
        f.write('\t\t\tcenter: centerlatlng,\n')

        # Change this line to allow different map types
        f.write('\t\t\tmapTypeId: \'{}\'\n'.format(self.map_type))

        f.write('\t\t};\n')
        f.write(
            '\t\tvar map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);\n')
        f.write('\n')

    def color_scatter(self, lats, lngs, values=None, colormap='coolwarm',
                      size=None, marker=False, s=None, **kwargs):
        def rgb2hex(rgb):
            """ Convert RGBA or RGB to #RRGGBB """
            rgb = list(rgb[0:3]) # remove alpha if present
            rgb = [int(c * 255) for c in rgb]
            hexcolor = '#%02x%02x%02x' % tuple(rgb)
            return hexcolor

        if values is None:
            colors = [None for _ in lats]
        else:
            cmap = plt.get_cmap(colormap)
            norm = Normalize(vmin=min(values), vmax=max(values))
            scalar_map = ScalarMappable(norm=norm, cmap=cmap)
            colors = [rgb2hex(scalar_map.to_rgba(value)) for value in values]
        for lat, lon, c in zip(lats, lngs, colors):
            self.scatter(lats=[lat], lngs=[lon], c=c, size=size, marker=marker,
                         s=s, **kwargs)


initial_zoom = 12
num_pts = 40

lats = [37.428]
lOns= [-122.145]
values = [random() * 20]
for pt in range(num_pts):
    lats.append(lats[-1] + (random() - 0.5)/100)
    lons.append(lons[-1] + random()/100)
    values.append(values[-1] + random())
gmap = CustomGoogleMapPlotter(lats[0], lons[0], initial_zoom,
                              map_type='satellite')
gmap.color_scatter(lats, lons, values, colormap='coolwarm')

gmap.draw("mymap.html")

作为示例,我使用一系列单调递增的值,这些值在coolwarm颜色图中从蓝色阴影很好地映射为红色:

推荐阅读
devbox
饿狼传说少校_584_869_541
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有 京ICP备19059560号-4