Jeg prøver å georeferanse et sett med bildefliser lastet ned fra et Google Maps-nettsted. Bare basert på hvert bilde «s Google Maps rutenettreferanse og zoomnivå, hvordan kan jeg beregne de virkelige koordinatene?
Siden på http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection viser koordinatene og Google Maps-rutenettreferansen for nettkonkurrerende fliser.
For eksempel er midtflisen x=49, y=30, z=6
hjørnekoordinater 10644926.307106785, 626172.1357121654, 11271098.44281895, 1252344.27142432
:
Er det mulig å beregne hjørnekoordinatene utelukkende basert på rutenettreferansen og zoomnivået (49, 30, 6)?
Dette ligner på Hvordan georefererer jeg en web-mercator-flis riktig ved hjelp av gdal? men jeg trenger en helt programmatisk løsning uten å måtte slå opp noe på nettet. (Eller hvis jeg trenger å slå opp verdier på nettet, må det være programmatisk).
Rediger: dette skjermbildet viser plasseringen til en prøveflis (zoomnivå 11, x = 1593, y = 933) . Hvordan ville jeg georeferanse den flisen?
Kommentarer
- Kommer det som en ekte flis? Ingen omgivelser?
- @FelixIP ja alt jeg vet er nettverksreferansen og zoomnivået til hver enkelt JPG. Jeg ‘ har lagt til et skjermbilde for å demonstrere dette. PS Jeg skjønner at dette er litt dodgy, men noen ganger må det gjøres – pluss at det ‘ er en interessant øvelse!
- jeg tror du skal kunne få hjørnet kordinerer ved å bruke bare zoomnivåene og rutenettreferansen, så vidt jeg vet, forblir rutenettreferansesystemet konstant, så det burde være en måte å gjøre dette på. Siden zoomnivå 0 har verden i 1 flis og zoom 1 i 4 og så videre, bør det være mulig å få koordinatene.
- @StephenLead kanskje prøve å dele verden i 4 deler i hver zoom ( iterasjon) og få koordinatene ved hjelp av det på en eller annen måte. Det ‘ det må være en iterativ funksjon, men etter min forståelse.
- har du lov til å gjøre dette? det vil si, tillater google maps-vilkårene dette?
Svar
Denne siden http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection gir algoritmer, skrevet i python, for å beregne fliseregioner i EPSG: 900913-koordinater og i latutude / lengdegrad ved bruk av WGS84-henvisning.
Klassen GlobalMercator
i dette skriptet http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection / globalmaptiles .py inneholder to metoder, TileBounds()
og TileLatLonBounds()
for å gjøre dette.
En modifisert versjon av skriptet som viser koordinater for fliser:
#!/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
Bruk: tilebounds xTile yTile zoom
.
For eksempel, utgangen for flisen x=49
, y=30
, z=6
er som følger:
$./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)
En flis kan lastes ned med url http://mt.google.com/vt?x=xTile&y=yTile&z=zoom
forbudt å få tilgang til den direkte.
Programvaren ble opprinnelig skrevet av Klokan Petr Přidal.
Jeg håper dette kan hjelpe!
Kommentarer
- Velkommen til GIS Stack Exchange, og mange takk for dette. Kravet mitt har gått da jeg ‘ ikke lenger jobber med dette prosjektet, men denne informasjonen skal forhåpentligvis være nyttig for noen andre i fremtiden
Svar
Bare å kaste dette inn som en del av diskusjonen om fliser, bufret fliser, georeferanse osv.
Fliseskjemaer fra hva Jeg vet ikke bruker et XY-georeferansesystem i seg selv …
For eksempel, når du laster ESRI-basekartet inn i QGIS, vil det opprette en flisstache-mappestruktur slik:
Når du ser på toppnivåbildene, har du ba om flisene, og de lagres i de forskjellige mappene.
Her er innholdet i f / d-mappen:
Legg merke til ingen georeferanseinformasjon i filen (verdensfil osv.)
Når du tar denne filen inn i MS maling, for eksempel kan du manipulere bildet og lagre det på nytt:
…så når du viser kartet igjen i QGIS – som gjengir flisene – kan du se den «redigerte» flisen:
Så jeg antar at alt jeg sier er at hvis du hadde et sett med fliser fra google earth, kan du i teorien gjenopprette flisen struktur og rett og slett sette flisene i disse mappene, og de ville tegne i QGIS …
Det er selve programvaren som vet hvor de skal tegne flisene basert på cachingskjemaet og mappestrukturen … dette igjen går tilbake til mine dager med å lære ArcGIS Server-kurs.
Du kan deretter eksportere dem fra QGIS med georeferanseinformasjon og bruke dem andre steder.
Men igjen, du kan også bare laste google maps inn i QGIS og eksportere bildet som en TIF med en verdensfil …
(Igjen, egentlig ikke et svar, bare litt diskusjon …)
Kommentarer
- beklager det sene svaret. For å være ærlig kan jeg ‘ ikke engang huske hvorfor jeg spurte dette, ettersom prosjektet er overstått;) Jeg husker at jeg trengte å gjenskape hvilken voodoo programvaren gjør når den vet hvordan man plasserer bilder basert på mappestrukturen
Svar
Oppdaget dette problemet nylig, kan du bruke koden i wiki.openstreetmap.org
Her er Java-koden:
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))); }
Svar
For den underliggende matematiske tilnærmingen, se svaret mitt på et beslektet spørsmål her: beregning av avgrensningsboks fra kjent senterkoordinat og zoom
Du må kunne konvertere fra flisekoordinater og piksler i en flis til pikselkoordinater, men det er ikke for vanskelig.