Estou tentando georreferenciar um conjunto de blocos de imagem baixado de um site do Google Maps. Com base apenas em cada imagem Referência de grade do Google Maps e nível de zoom, como posso calcular as coordenadas do mundo real?
A página em http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection mostra as coordenadas e a referência de grade do Google Maps para blocos do Web Mercator.
Por exemplo, o bloco central é x=49, y=30, z=6
e tem o coordenadas de canto 10644926.307106785, 626172.1357121654, 11271098.44281895, 1252344.27142432
:
É possível calcular as coordenadas dos cantos com base apenas na referência da grade e nível de zoom (49, 30, 6)?
Isso é semelhante a Como georreferenciar um bloco de mercator da web corretamente usando gdal? mas eu preciso de uma solução completamente programática, sem precisar procurar nada online. (Ou, se eu precisar pesquisar valores online, ele precisa ser programático).
Editar: esta captura de tela mostra a localização de um bloco de amostra (nível de zoom 11, x = 1593, y = 933) . Como eu georreferenciaria esse bloco?
Comentários
- Ele vem como um bloco verdadeiro? Sem cercadura?
- @FelixIP sim, tudo que eu sei é a referência da grade e o nível de zoom de cada JPG individual. Eu ‘ adicionei uma captura de tela para demonstrar isso. PS Sei que isso é um pouco duvidoso, mas às vezes tem que ser feito – além disso, ‘ é um exercício interessante!
- acho que você deve conseguir fazer o canto cordina usando apenas os níveis de zoom e a referência da grade, pelo que eu sei, o sistema de referência da grade permanece constante, então deve haver uma maneira de fazer isso. Como o nível de zoom 0 tem o mundo em 1 bloco e o zoom de 1 em 4 e assim por diante, deve ser possível obter as coordenadas.
- @StephenLead talvez tente dividir o mundo em 4 partes em cada zoom ( iteração) e obter as coordenadas usando isso de alguma forma. Ela ‘ terá que ser uma função iterativa, embora pelo meu entendimento.
- você tem permissão para fazer isso? ou seja, os termos do google maps permitem isso?
Resposta
Esta página http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection fornece algoritmos, escritos em python, para calcular limites de blocos em EPSG: coordenadas 900913 e latutude / longitude usando datum WGS84.
A classe GlobalMercator
neste script http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection / globalmaptiles .py contém dois métodos, TileBounds()
e TileLatLonBounds()
para fazer isso.
Uma versão modificada do script para mostrar as coordenadas dos limites dos blocos:
#!/usr/bin/env python ############################################################################### # $Id$ # # Project: GDAL2Tiles, Google Summer of Code 2007 & 2008 # Global Map Tiles Classes # Purpose: Convert a raster into TMS tiles, create KML SuperOverlay EPSG:4326, # generate a simple HTML viewers based on Google Maps and OpenLayers # Author: Klokan Petr Pridal, klokan at klokan dot cz # Web: http://www.klokan.cz/projects/gdal2tiles/ # ############################################################################### # Copyright (c) 2008 Klokan Petr Pridal. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. ############################################################################### """ tilebounds.py Adapted from: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/globalmaptiles.py Global Map Tiles as defined in Tile Map Service (TMS) Profiles ============================================================== Functions necessary for generation of global tiles used on the web. It contains classes implementing coordinate conversions for: - GlobalMercator (based on EPSG:900913 = EPSG:3785) for Google Maps, Yahoo Maps, Microsoft Maps compatible tiles - GlobalGeodetic (based on EPSG:4326) for OpenLayers Base Map and Google Earth compatible tiles More info at: http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification http://wiki.osgeo.org/wiki/WMS_Tiling_Client_Recommendation http://msdn.microsoft.com/en-us/library/bb259689.aspx http://code.google.com/apis/maps/documentation/overlays.html#Google_Maps_Coordinates Created by Klokan Petr Pridal on 2008-07-03. Google Summer of Code 2008, project GDAL2Tiles for OSGEO. In case you use this class in your product, translate it to another language or find it usefull for your project please let me know. My email: klokan at klokan dot cz. I would like to know where it was used. Class is available under the open-source GDAL license (www.gdal.org). """ import math class GlobalMercatorLight(object): def __init__(self, tileSize=256): "Initialize the TMS Global Mercator pyramid" self.tileSize = tileSize self.initialResolution = 2 * math.pi * 6378137 / self.tileSize # 156543.03392804062 for tileSize 256 pixels self.originShift = 2 * math.pi * 6378137 / 2.0 # 20037508.342789244 def MetersToLatLon(self, mx, my ): "Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum" lon = (mx / self.originShift) * 180.0 lat = (my / self.originShift) * 180.0 lat = 180 / math.pi * (2 * math.atan( math.exp( lat * math.pi / 180.0)) - math.pi / 2.0) return lat, lon def PixelsToMeters(self, px, py, zoom): "Converts pixel coordinates in given zoom level of pyramid to EPSG:900913" res = self.Resolution( zoom ) mx = px * res - self.originShift my = py * res - self.originShift return mx, my def TileBounds(self, tx, ty, zoom): "Returns bounds of the given tile in EPSG:900913 coordinates" minx, miny = self.PixelsToMeters( tx*self.tileSize, ty*self.tileSize, zoom ) maxx, maxy = self.PixelsToMeters( (tx+1)*self.tileSize, (ty+1)*self.tileSize, zoom ) return ( minx, miny, maxx, maxy ) def TileLatLonBounds(self, tx, ty, zoom ): "Returns bounds of the given tile in latutude/longitude using WGS84 datum" bounds = self.TileBounds( tx, ty, zoom) minLat, minLon = self.MetersToLatLon(bounds[0], bounds[1]) maxLat, maxLon = self.MetersToLatLon(bounds[2], bounds[3]) return ( minLat, minLon, maxLat, maxLon ) def Resolution(self, zoom ): "Resolution (meters/pixel) for given zoom level (measured at Equator)" # return (2 * math.pi * 6378137) / (self.tileSize * 2**zoom) return self.initialResolution / (2**zoom) #--------------------- if __name__ == "__main__": import sys, os def Usage(s = ""): print "Usage: tilebounds.py tx ty zoomlevel" print sys.exit(1) profile = "mercator" zoomlevel = None tx, ty = None, None argv = sys.argv i = 1 while i < len(argv): arg = argv[i] if tx is None: tx = float(argv[i]) elif ty is None: ty = float(argv[i]) elif zoomlevel is None: zoomlevel = int(argv[i]) else: Usage("ERROR: Too many parameters") i = i + 1 if profile != "mercator": Usage("ERROR: Sorry, given profile is not implemented yet.") if zoomlevel == None or tx == None or ty == None: Usage("ERROR: Specify at least "lat", "lon" and "zoomlevel".") tz = zoomlevel mercator = GlobalMercatorLight() minx, miny, maxx, maxy = mercator.TileBounds( tx, ty, tz ) print "Bounds of the given tile in EPSG:900913 coordinates: " print " upper-left corner: " print (minx, miny) print " bottom-right corner: " print (maxx, maxy) print minLat, minLon, maxLat, maxLon = mercator.TileLatLonBounds( tx, ty, tz ) print "Bounds of the given tile in latitude/longitude using WGS84 datum: " print " upper-left corner: " print (minLat, minLon) print " bottom-right corner: " print (maxLat, maxLon) print
Uso: tilebounds xTile yTile zoom
.
Por exemplo, a saída para o bloco x=49
, y=30
, z=6
é o seguinte:
$./tilebounds.py 49 30 6 Bounds of the given tile in EPSG:900913 coordinates: upper-left corner: (10644926.307106785, -1252344.271424327) bottom-right corner: (11271098.44281895, -626172.1357121654) Bounds of the given tile in latitude/longitude using WGS84 datum: upper-left corner: (-11.178401873711772, 95.625) bottom-right corner: (-5.61598581915534, 101.25000000000001)
Um bloco pode ser baixado com o url http://mt.google.com/vt?x=xTile&y=yTile&z=zoom
, mas este é proibido de acessá-lo diretamente.
O software foi originalmente escrito por Klokan Petr Přidal.
Espero que isso possa ajudar!
Comentários
- Bem-vindo ao GIS Stack Exchange e muito obrigado por isso. Meu requisito foi aprovado porque eu ‘ não estou mais trabalhando neste projeto, mas espero que esta informação seja útil para outra pessoa no futuro
Resposta
Apenas lançando isso como parte da discussão sobre blocos, blocos em cache, georreferenciamento, etc.
Esquemas de blocos de quê Eu sei que não use um sistema de georreferenciamento XY per se …
Por exemplo, quando você carrega o mapa base ESRI no QGIS, ele criará uma estrutura de pasta stache de blocos como esta:
Ao visualizar as imagens de nível superior, você tem solicitou os blocos, e eles estão armazenados nessas várias pastas.
Aqui está o conteúdo da pasta f / d:
Não observe nenhuma informação de georreferenciamento no arquivo (arquivo mundial, etc.)
Quando você traz este arquivo para o MS pintar, por exemplo, você pode manipular a imagem e salvá-la novamente:
…então, quando você visualizar o mapa novamente no QGIS – que está renderizando os blocos – você poderá ver seu bloco “editado”:
Então, acho que tudo o que estou dizendo é que se você tivesse um conjunto de blocos do Google Earth, em teoria poderia recriar o bloco estrutura e simplesmente colocar os blocos nessas pastas, e eles desenhariam no QGIS …
É o próprio software que sabe onde desenhar os blocos com base no esquema de cache e estrutura de pastas … isso novamente remonta aos meus dias ensinando cursos do ArcGIS Server.
Você poderia então exportá-los do QGIS com informações de georreferenciamento e usá-los em outro lugar.
Mas, novamente, você também pode carregar o Google Maps no QGIS e exportar a imagem como um TIF com um arquivo mundial …
(Novamente, não é realmente uma resposta, apenas alguma discussão …)
Comentários
- desculpe pelo atraso na resposta. Para ser honesto, não consigo ‘ nem me lembrar por que estava perguntando isso, já que o projeto acabou;) Eu me lembro, porém, que precisava recriar qualquer vodu que o software estava fazendo quando ele sabe como colocar imagens com base na estrutura de pastas
Resposta
Este problema encontrou recentemente, você pode usar o código fornecido em wiki.openstreetmap.org
Aqui está o código Java:
class BoundingBox { double north; double south; double east; double west; } BoundingBox tile2boundingBox(final int x, final int y, final int zoom) { BoundingBox bb = new BoundingBox(); bb.north = tile2lat(y, zoom); bb.south = tile2lat(y + 1, zoom); bb.west = tile2lon(x, zoom); bb.east = tile2lon(x + 1, zoom); return bb; } static double tile2lon(int x, int z) { return x / Math.pow(2.0, z) * 360.0 - 180; } static double tile2lat(int y, int z) { double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z); return Math.toDegrees(Math.atan(Math.sinh(n))); }
Resposta
Para a abordagem matemática subjacente, veja minha resposta a uma pergunta relacionada aqui: calculando a caixa delimitadora a partir de uma coordenada central e zoom conhecidos
Você precisará ser capaz de converter de coordenadas de bloco e pixels dentro de um bloco para coordenadas de pixel, mas isso” s não muito difícil.