Ik probeer een georeferentie te geven aan een set afbeeldingstegels die is gedownload van een Google Maps-site. Alleen gebaseerd op elke afbeelding “s Google Maps-rasterreferentie en zoomniveau, hoe kan ik de coördinaten in de echte wereld berekenen?
De pagina op http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection toont de coördinaten en Google Maps-rasterverwijzing voor web mercator-tegels.
De middelste tegel is bijvoorbeeld x=49, y=30, z=6
en heeft de hoekcoördinaten 10644926.307106785, 626172.1357121654, 11271098.44281895, 1252344.27142432
:
Is het mogelijk om de hoekcoördinaten uitsluitend te berekenen op basis van de gridreferentie en het zoomniveau (49, 30, 6)?
Dit is vergelijkbaar met Hoe een Web Mercator-tegel correct te georefereren met gdal? maar ik heb een volledig programmatische oplossing nodig, zonder dat ik iets online hoeft op te zoeken. (Of, als ik waarden online moet opzoeken, moet het programmatisch zijn).
Bewerken: deze schermafbeelding toont de locatie van een voorbeeldtegel (zoomniveau 11, x = 1593, y = 933) . Hoe zou ik die tegel georefereren?
Reacties
- Komt het als een echte tegel? Geen omgeving?
- @FelixIP ja, alles wat ik weet is de gridreferentie en het zoomniveau van elke individuele JPG. Ik ‘ heb een screenshot toegevoegd om dit te demonstreren. PS Ik realiseer me dat dit een beetje onbetrouwbaar is, maar soms moet het worden gedaan – plus het ‘ is een interessante oefening!
- Ik denk dat je moet kunnen de hoek wordt afgebakend door alleen de zoomniveaus en rasterreferentie te gebruiken, voor zover ik weet, blijft het rasterreferentiesysteem constant, dus er zou een manier moeten zijn om dit te doen. Aangezien zoomniveau 0 de wereld in 1 tegel heeft en zoom 1 op 4 enzovoort, zou het mogelijk moeten zijn om de coördinaten op te halen.
- @StephenLead zou kunnen proberen om de wereld in elke zoomfactor ( iteratie) en verkrijg de coördinaten door dat op de een of andere manier te gebruiken. Het ‘ zal naar mijn mening een iteratieve functie moeten zijn.
- Mag je dit doen? dat wil zeggen, staan de termen van Google Maps dit toe?
Antwoord
Deze pagina http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection biedt algoritmen, geschreven in python, om tegelgrenzen te berekenen in EPSG: 900913 coördinaten en in latutude / longitude met behulp van WGS84 datum.
De klasse GlobalMercator
in dit script http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection / globalmaptiles .py bevat twee methoden, TileBounds()
en TileLatLonBounds()
om dit te doen.
Een aangepaste versie van het script om de tegelgrenzen-coördinaten weer te geven:
#!/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
Gebruik: tilebounds xTile yTile zoom
.
Bijvoorbeeld, de uitvoer voor de tegel x=49
, y=30
, z=6
is als volgt:
$./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)
Een tegel kan worden gedownload met de url http://mt.google.com/vt?x=xTile&y=yTile&z=zoom
, maar dit is verboden om er rechtstreeks toegang toe te hebben.
De software is oorspronkelijk geschreven door Klokan Petr Přidal.
Ik hoop dat dit kan helpen!
Reacties
- Welkom bij GIS Stack Exchange, en hartelijk dank hiervoor. Mijn vereiste is verstreken aangezien ik ‘ niet meer aan dit project werk, maar deze informatie zou hopelijk in de toekomst nuttig moeten blijken voor iemand anders
Antwoord
Dit gewoon toevoegen als onderdeel van de discussie over tegels, tegels in cache, georeferentie, enz.
Tegelschemas van wat Ik weet dat je niet per se een XY-georeferentiesysteem gebruikt …
Als je bijvoorbeeld de ESRI-basiskaart in QGIS laadt, zal het een mapstructuur van de tegelstache creëren zoals deze:
Wanneer u de afbeeldingen op het hoogste niveau bekijkt, moet u heeft de tegels opgevraagd, en ze zijn opgeslagen in die verschillende mappen.
Hier is de inhoud van de f / d-map:
Merk op dat er geen georeferentie-informatie in het bestand (wereldbestand, enz.) staat
Wanneer u brengt dit bestand naar MS paint, u kunt bijvoorbeeld de afbeelding manipuleren en deze opnieuw opslaan:
…dus wanneer u de kaart opnieuw bekijkt in QGIS – wat de tegels weergeeft – kunt u uw “bewerkte” tegel zien:
Dus ik denk dat ik alleen maar wil zeggen dat als je een set tegels van Google Earth had, je in theorie de tegel opnieuw zou kunnen maken structuur en plaats de tegels eenvoudig in die mappen, en ze zouden tekenen in QGIS …
Het is de software zelf die weet waar de tegels moeten worden getekend op basis van het cacheschema en de mapstructuur … dit gaat weer terug naar de tijd dat ik ArcGIS Server-cursussen gaf.
U zou ze dan vanuit QGIS kunnen exporteren met georeferentie-informatie en ze elders kunnen gebruiken.
Maar nogmaals, je zou ook gewoon google maps in QGIS kunnen laden en de afbeelding als een TIF met een wereldbestand kunnen exporteren …
(Nogmaals, niet echt een antwoord, alleen wat discussie …)
Reacties
- sorry voor het late antwoord. Om eerlijk te zijn kan ik ‘ zelfs niet herinneren waarom ik dit vroeg, aangezien het project al lang voorbij is;) Ik herinner me echter dat ik de voodoo die de software aan het doen was opnieuw moest maken wanneer het weet hoe afbeeldingen moeten worden geplaatst op basis van de mapstructuur
Antwoord
Dit probleem is onlangs opgetreden, u kunt gebruiken de code in de wiki.openstreetmap.org
Hier is de Java-code:
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))); }
Antwoord
Voor de onderliggende wiskundige benadering, zie mijn antwoord op een gerelateerde vraag hier: het begrenzingsvak berekenen op basis van bekende centrumcoördinaten en zoomen
U moet in staat zijn om tegelcoördinaten en pixels binnen een tegel om te zetten in pixelcoördinaten, maar dat is niet te moeilijk.