Próbuję utworzyć odniesienie geograficzne do zestawu kafelków obrazów pobranych z serwisu Google Maps. Na podstawie tylko każdego obrazu „Odniesienie do siatki w Mapach Google i poziom powiększenia, jak mogę obliczyć rzeczywiste współrzędne?
Strona pod adresem http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection pokazuje współrzędne i odniesienie do siatki Map Google dla kafelków kupców internetowych.
Na przykład środkowy kafelek to x=49, y=30, z=6
i ma współrzędne narożnika 10644926.307106785, 626172.1357121654, 11271098.44281895, 1252344.27142432
:
Czy można obliczyć współrzędne narożnika wyłącznie na podstawie odniesienia do siatki i poziomu powiększenia (49, 30, 6)?
Jest to podobne do Jak poprawnie utworzyć odniesienie geograficzne do kafelka merkatora internetowego za pomocą programu Gdal? , ale potrzebuję całkowicie programowego rozwiązania, bez konieczności wyszukiwania czegokolwiek w Internecie. (Lub, jeśli muszę wyszukiwać wartości online, musi to być programowe).
Edycja: ten zrzut ekranu pokazuje lokalizację przykładowego kafelka (poziom powiększenia 11, x = 1593, y = 933) . Jak mogę utworzyć odniesienie geograficzne do tego kafelka?
Komentarze
- Czy jest to prawdziwy kafelek? Nie ma otoczenia?
- @FelixIP tak, wszystko co wiem, to odniesienie do siatki i poziom powiększenia każdego pojedynczego pliku JPG. ' dodałem zrzut ekranu, aby to zademonstrować. PS Zdaję sobie sprawę, że to trochę podejrzane, ale czasami trzeba to zrobić – a ponadto ' to ciekawe ćwiczenie!
- myślę, że powinieneś być w stanie narożnik łączy, używając tylko poziomów powiększenia i odniesienia do siatki, o ile wiem, układ odniesienia siatki pozostaje stały, więc powinien być sposób, aby to zrobić. Ponieważ poziom powiększenia 0 ma świat na 1 kafelku i powiększenie 1 do 4 itd., Powinno być możliwe uzyskanie współrzędnych.
- @StephenLead może spróbować podzielić świat na 4 części w każdym powiększeniu ( iteracja) i jakoś uzyskaj współrzędne, używając tego. To ' musi być funkcją iteracyjną, choć według mojego rozumienia.
- czy możesz to zrobić? to znaczy, czy warunki Map Google na to pozwalają?
Odpowiedź
Ta strona http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection udostępnia algorytmy, napisane w Pythonie, do obliczania granic kafelków we współrzędnych EPSG: 900913 oraz szerokości / długości geograficznej przy użyciu układu odniesienia WGS84.
Klasa GlobalMercator
w tym skrypcie http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection / globalmaptiles .py zawiera dwie metody, TileBounds()
i TileLatLonBounds()
, aby to zrobić.
Zmodyfikowana wersja skryptu pokazująca współrzędne granic kafelków:
#!/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
Sposób użycia: tilebounds xTile yTile zoom
.
Na przykład dane wyjściowe dla kafelka x=49
, y=30
, z=6
wygląda następująco:
$./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)
Kafelek można pobrać z adresem URL http://mt.google.com/vt?x=xTile&y=yTile&z=zoom
, ale to jest nie ma do niego bezpośredniego dostępu.
Oprogramowanie zostało pierwotnie napisane przez Klokana Petra Přidala.
Mam nadzieję, że to pomoże!
Komentarze
- Witamy w GIS Stack Exchange i wielkie dzięki za to. Moje wymaganie zostało spełnione, ponieważ ' nie pracuję już nad tym projektem, ale mam nadzieję, że te informacje okażą się przydatne dla kogoś innego w przyszłości.
Odpowiedź
Po prostu wrzucam to w ramach dyskusji na temat kafelków, kafelków w pamięci podręcznej, georeferencji itp.
Schematy kafelków z czego Wiem, że nie używaj systemu georeferencji XY jako takiego …
Na przykład, kiedy załadujesz mapę bazową ESRI do QGIS, utworzy ona strukturę folderów składowanych kafelków w następujący sposób:
Podczas przeglądania obrazów najwyższego poziomu masz zażądał kafelków i są one przechowywane w tych różnych folderach.
Oto zawartość folderu f / d:
Nie zauważaj żadnych informacji georeferencyjnych w pliku (plik świata itp.)
Kiedy przenosisz ten plik do MS paint, na przykład możesz manipulować obrazem i ponownie go zapisać:
…więc kiedy ponownie wyświetlisz mapę w QGIS – czyli renderuje kafelki – możesz zobaczyć swój „edytowany” kafelek:
Więc myślę, że wszystko, co mówię, to jeśli masz zestaw kafelków z Google Earth, możesz teoretycznie odtworzyć kafelek struktury i po prostu umieść kafelki w tych folderach, a narysują w QGIS …
To samo oprogramowanie wie, gdzie narysować kafelki na podstawie schematu buforowania i struktury folderów … to znowu sięga do moich dni, kiedy prowadziłem kursy dotyczące ArcGIS Server.
Możesz następnie wyeksportować je z QGIS z informacjami georeferencyjnymi i użyć ich gdzie indziej.
Ale z drugiej strony możesz po prostu załadować mapy Google do QGIS i wyeksportować obraz jako TIF z plikiem świata …
(Ponownie, nie jest to odpowiedź, po prostu trochę dyskusji …)
Komentarze
- przepraszam za spóźnioną odpowiedź. Szczerze mówiąc, ' nawet nie pamiętam, dlaczego o to pytam, ponieważ projekt już dawno się skończył;) Pamiętam jednak, że musiałem odtworzyć to, co robi oprogramowanie voodoo, kiedy wie, jak umieszczać obrazy w oparciu o strukturę folderów
Odpowiedź
Niedawno napotkałeś ten problem, możesz użyć kod podany w wiki.openstreetmap.org
Oto kod 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))); }
Odpowiedź
Jeśli chodzi o podstawowe podejście matematyczne, zapoznaj się z moją odpowiedzią na powiązane pytanie tutaj: obliczanie obwiedni na podstawie znanych współrzędnych środka i powiększenia
Będziesz musiał mieć możliwość konwersji ze współrzędnych kafelka i pikseli w kafelku na współrzędne piksela, ale to niezbyt trudne.