我从前同事那里继承了两个Python脚本(更像是片段)。该代码应该将高分辨率图像(png)转换为可以由slippy-map在历史坐标空间(纬度/经度)中使用的可缩放图块(Leaflet.js)。
不是一个Python(或GIS)人,我很难让他们正常工作。我无法确定问题是我缺乏知识还是代码......
此第一个脚本按预期工作,从输入图像(myImgMaxRez.png)派生出五个逐渐降低分辨率的图像文件。我相信这被称为“图像金字塔”。每个z [1..5] .png的尺寸可以被256整除。
from skimage import io
from skimage import transform
import skimage
z1 = io.imread("myImgMaxRez.png", as_grey=True)
io.imsave("z1.png",skimage.img_as_uint(z1))
z2 = transform.pyramid_reduce(z1)
io.imsave("z2.png",skimage.img_as_uint(z2))
z3 = transform.pyramid_reduce(z2)
io.imsave("z3.png",skimage.img_as_uint(z3))
z4 = transform.pyramid_reduce(z3)
io.imsave("z4.png",skimage.img_as_uint(z4))
z5 = transform.pyramid_reduce(z4)
io.imsave("z5.png",skimage.img_as_uint(z5))
生成slippy-map tile的下一个脚本会抛出一个类型转换错误(float到int)。
import math
import os
from skimage import io
def createTiles(xStart, yStart, zoom, theData):
ncols = theData.shape[1]/256
nrows = theData.shape[0]/256
print(nrows, ncols)
topDir = "%d" % (zoom)
os.mkdir(topDir)
for i in range(0, ncols):
theDir = topDir + "/%d" % (i+xStart)
print (theDir)
os.mkdir(theDir)
for j in range(0, nrows):
theFile = topDir + "/%d/%d.png" % (i + xStart, j + yStart)
print (theFile)
io.imsave(theFile, theData[j*256:(j+1)*256, i*256(i+1)*256])
def num2deg(xtile, ytile, zoom):
n= 2.0 ** zoom
lon_deg = xtile / n *360.0 -180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n )))
lat_deg = math.degrees(lat_rad)
return (lat_deg, lon_deg)
def deg2num(lat_deg, lon_deg, zoom):
lat_rad = math.radians(lat_deg)
n= 2.0 ** zoom
xtile = int((lon_deg + 180.0) / 360.0 * n)
ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
return (xtile, ytile)
# Take center point of interest (MCK). Since z tile is 4x3 go 1 tile up and 2 left
startZoom = 18
centerLoc = deg2num(43.533942709166325, -96.71487003564836, startZoom)
startCol = centerLoc[0]
startRow = centerLoc[1]
# Now get lat/long of upper left tile corner
geoCoord = num2deg(startCol, startRow, startZoom)
loc = deg2num(geoCoord[0], geoCoord[1],18)
# EDIT: reading the .png thanks to JH comment below
z1 = io.imread("z1.png", as_grey=True)
createTiles(loc[0], loc[1], 18, z1)
loc = deg2num(geoCoord[0], geoCoord[1],19)
# EDIT: reading the .png thanks to JH comment below
z2 = io.imread("z2.png", as_grey=True)
createTiles(loc[0], loc[1], 19, z2)
loc = deg2num(geoCoord[0], geoCoord[1],20)
# EDIT: reading the .png thanks to JH comment below
z3 = io.imread("z3.png", as_grey=True)
createTiles(loc[0], loc[1], 20, z3)
loc = deg2num(geoCoord[0], geoCoord[1],21)
# EDIT: reading the .png thanks to JH comment below
z4 = io.imread("z4.png", as_grey=True)
createTiles(loc[0], loc[1], 21, z4)
loc = deg2num(geoCoord[0], geoCoord[1],22)
# EDIT: reading the .png thanks to JH comment below
z5 = io.imread("z5.png", as_grey=True)
createTiles(loc[0], loc[1], 22, z5)
CreateTiles()在行for i in range(0, ncols):
上抛出错误TypeError: float object cannot be interpreted as an integer
...有趣的是,它在抛出错误之前创建了第一个子目录18/
。我再次确认z [1..5] .png的大小是2的幂(或256的倍数)。
为什么我有这个错误将float转换为整数?
答案 0 :(得分:1)
z1
超出范围,因此第二个脚本无法使用它。您需要找到一种方法将其传入,例如就在调用createTiles()之前,您可能会这样做:
z1 = io.imread("z1.png", as_grey=True)
这些脚本的结构很差。将import
保持在最高级别(没有缩进)是有道理的,但将其他语句移动到自己的函数中会很好。他们至少应该在这个下面:
if __name__ == '__main__':
这样你就有可能一个脚本能够重用其他脚本中的函数,因为import
没有副作用。
答案 1 :(得分:0)
原来是一个Python版本问题..在2.7中,如果除法的结果是xx.0,那么它就是一个int。在Python 3.x中,它是一个浮点数。所以在Python 2.7中512/256 = 2,在python 3.x中它是= 2.0。
通过将除法的结果转换为INT,我能够让它运行。
ncols = int(theData.shape[1]/256)
nrows = int(theData.shape[0]/256)