OpenSeaMap-dev Diskussion:Downloadable Raster Charts: Unterschied zwischen den Versionen
Kannix (Diskussion | Beiträge) (→tile server: py script added) |
Kannix (Diskussion | Beiträge) (→py script: update) |
||
Zeile 47: | Zeile 47: | ||
<pre> | <pre> | ||
+ | |||
import logging | import logging | ||
import shutil | import shutil | ||
import math | import math | ||
− | from landez import MBTilesBuilder | + | from landez import MBTilesBuilder, ImageExporter, TilesManager |
− | |||
logging.basicConfig(level=logging.DEBUG) | logging.basicConfig(level=logging.DEBUG) | ||
+ | |||
# to be imported from sqlite-queue | # to be imported from sqlite-queue | ||
− | sqBottomGeoPre = 53. | + | sqBottomGeoPre = 53.2 |
− | sqTopGeoPre = | + | sqTopGeoPre = 54.216666666667 |
− | sqLeftGeoPre = | + | sqLeftGeoPre = 4.2 |
− | sqRightGeoPre = | + | sqRightGeoPre = 6.715 |
− | sqNumTiles16 = | + | sqNumTiles16 = 143170 |
− | sqChart = " | + | sqChart = "1417" |
− | + | sqName = "Friesland Junction and GW/EMS to Vlieland and Borkum" | |
− | + | sqHO = "NL/GB" | |
sqMicrotime= 1234 | sqMicrotime= 1234 | ||
Zeile 72: | Zeile 73: | ||
myZoom = 18 | myZoom = 18 | ||
− | while (myNumTiles > | + | while (myNumTiles > 700): |
myNumTiles = myNumTiles / 4 | myNumTiles = myNumTiles / 4 | ||
myZoom = myZoom - 1 | myZoom = myZoom - 1 | ||
# settings | # settings | ||
+ | # myUrlBase = "http://tiles.grade.de/tiles.py/openriverboatmap/{z}/{x}/{y}.png" | ||
+ | myUrlBase = "http://otile1.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg" | ||
+ | myUrlSeamark = "http://tiles.grade.de/tiles.py/seamark/{z}/{x}/{y}.png" | ||
+ | |||
+ | if sqHO == "DE": | ||
+ | myUrlHydro = "http://tiles.grade.de/tiles.py/NAUTHIS_SkinOfEarth/{z}/{x}/{y}.png" | ||
+ | elif sqHO== "NL/GB": | ||
+ | myUrlHydro = "http://tiles.grade.de/tiles.py/ncp_diepte14/{z}/{x}/{y}.png" | ||
+ | else: | ||
+ | myUrlHydro = "" | ||
+ | |||
myFileName = sqChart | myFileName = sqChart | ||
myMbtilesFile = myFileName + ".mbtiles" | myMbtilesFile = myFileName + ".mbtiles" | ||
Zeile 86: | Zeile 98: | ||
myZoomLevel = myZoom | myZoomLevel = myZoom | ||
myTileSize = 256 | myTileSize = 256 | ||
+ | #myTileFormat = 'image/png' | ||
+ | myTileFormat = 'image/jpeg' | ||
# download and mbtiles build | # download and mbtiles build | ||
− | mb = MBTilesBuilder(tiles_url= | + | mb = MBTilesBuilder(tiles_url=myUrlBase, cache=True, filepath=myMbtilesFile, tile_size=myTileSize, tile_format=myTileFormat) |
mb.add_coverage(myBbox, myZoomLevels) | mb.add_coverage(myBbox, myZoomLevels) | ||
+ | |||
+ | if myUrlHydro != "": | ||
+ | hydro = TilesManager(tiles_url=myUrlHydro) | ||
+ | seamark = TilesManager(tiles_url=myUrlSeamark) | ||
+ | hydro.add_layer(seamark) | ||
+ | overlay = hydro | ||
+ | else: | ||
+ | seamark = TilesManager(tiles_url=myUrlSeamark) | ||
+ | overlay = seamark | ||
+ | |||
+ | mb.add_layer(overlay) | ||
mb.run(force=True) | mb.run(force=True) | ||
Zeile 138: | Zeile 163: | ||
# shall be exported to sqlite-queue | # shall be exported to sqlite-queue | ||
+ | logging.debug(" baselayer: " + str(myUrlBase)) | ||
+ | logging.debug(" seamark: " + str(myUrlSeamark)) | ||
+ | logging.debug(" hydro: " + str(myUrlHydro)) | ||
+ | logging.debug(" zoom: " + str(myZoom)) | ||
+ | |||
logging.debug(" width: " + str(sqWidth) + " tiles") | logging.debug(" width: " + str(sqWidth) + " tiles") | ||
logging.debug(" height: " + str(sqHeight) + " tiles") | logging.debug(" height: " + str(sqHeight) + " tiles") | ||
Zeile 155: | Zeile 185: | ||
# start imgkap to generate .kap file | # start imgkap to generate .kap file | ||
import subprocess | import subprocess | ||
− | |||
myImgkapCall = "./imgkap " + myImageFile + " " + str(sqTopGeoPost) + " " + str(sqLeftGeoPost) + " " + str(sqBottomGeoPost) + " " + str(sqRightGeoPost) + " " + myKapFile | myImgkapCall = "./imgkap " + myImageFile + " " + str(sqTopGeoPost) + " " + str(sqLeftGeoPost) + " " + str(sqBottomGeoPost) + " " + str(sqRightGeoPost) + " " + myKapFile | ||
print myImgkapCall | print myImgkapCall | ||
subprocess.call(myImgkapCall, shell=True) | subprocess.call(myImgkapCall, shell=True) | ||
− | + | ||
+ | |||
</pre> | </pre> | ||
Version vom 12. Februar 2015, 11:59 Uhr
Inhaltsverzeichnis
ideas
web frontend
- die INT-chart Grenzen (als Basis fuer ein download-tool) bekomme ich inzwischen auf den Schirm: http://kap.grade.de/int-chart-ol2.html , sicherlich verbesserungsbeduerftig
- workflow
- INT-Chart durch klick auf die Karte waehlen
- download iniziieren
- Weiterleitung auf neue Seite
- pruefen, ob und in welchem Format vorhanden
- wenn ja und nicht zu alt, downloadlinks anbieten
- wenn nein Job in queue-db schreiben
- number, name, bbox, scale, sessionid, ip-address, email, microtime, status=open, ...
- das ganze garnieren mit
- Pruefung, ob das script fuer diese karte schon in der Warteschlange ist
- Limitierung auf x downloads/jobs pro session ...
- email notifier
- captcha
prerequisites
- apache
- php
- sqlite
tile server
- cronjob checkt queue-db alle x Minuten
- waehlt aeltesten job aus queue-db mit status=open
- tiledownload ueber proxy mit landez
- sinnvolles zoom-level anhand bbox errechnen (max. 10MB/chart)
- mbtiles erzeugen (siehe auch mbtiles implementation)
- stitchen und .png/.jpg erzeugen
- .kap mit imgkap erstellen
- ...
- status=done, zoom-level, date, ... in queue-db setzen
- temp-dir bereinigen und results in charts-dir kopieren
prerequisites
py script
- relies on landez
import logging import shutil import math from landez import MBTilesBuilder, ImageExporter, TilesManager logging.basicConfig(level=logging.DEBUG) # to be imported from sqlite-queue sqBottomGeoPre = 53.2 sqTopGeoPre = 54.216666666667 sqLeftGeoPre = 4.2 sqRightGeoPre = 6.715 sqNumTiles16 = 143170 sqChart = "1417" sqName = "Friesland Junction and GW/EMS to Vlieland and Borkum" sqHO = "NL/GB" sqMicrotime= 1234 # to be calculated from numtiles16, numtiles < 700 # numtiles16 is right now hardcoded at int-chart.gejson for ol depth of view reasons, there might be smarter ways in future # https://github.com/makinacorpus/landez/issues/44 myNumTiles = sqNumTiles16 * 4 * 4 myZoom = 18 while (myNumTiles > 700): myNumTiles = myNumTiles / 4 myZoom = myZoom - 1 # settings # myUrlBase = "http://tiles.grade.de/tiles.py/openriverboatmap/{z}/{x}/{y}.png" myUrlBase = "http://otile1.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg" myUrlSeamark = "http://tiles.grade.de/tiles.py/seamark/{z}/{x}/{y}.png" if sqHO == "DE": myUrlHydro = "http://tiles.grade.de/tiles.py/NAUTHIS_SkinOfEarth/{z}/{x}/{y}.png" elif sqHO== "NL/GB": myUrlHydro = "http://tiles.grade.de/tiles.py/ncp_diepte14/{z}/{x}/{y}.png" else: myUrlHydro = "" myFileName = sqChart myMbtilesFile = myFileName + ".mbtiles" myImageFile = myFileName + ".jpg" myKapFile = myFileName + ".kap" myTextFile = myFileName + ".txt" myBbox = (sqLeftGeoPre, sqBottomGeoPre, sqRightGeoPre, sqTopGeoPre) myZoomLevels = [myZoom] myZoomLevel = myZoom myTileSize = 256 #myTileFormat = 'image/png' myTileFormat = 'image/jpeg' # download and mbtiles build mb = MBTilesBuilder(tiles_url=myUrlBase, cache=True, filepath=myMbtilesFile, tile_size=myTileSize, tile_format=myTileFormat) mb.add_coverage(myBbox, myZoomLevels) if myUrlHydro != "": hydro = TilesManager(tiles_url=myUrlHydro) seamark = TilesManager(tiles_url=myUrlSeamark) hydro.add_layer(seamark) overlay = hydro else: seamark = TilesManager(tiles_url=myUrlSeamark) overlay = seamark mb.add_layer(overlay) mb.run(force=True) # export image from mbtiles # not the best idea: causes IO at temp dir, again ie = ImageExporter(mbtiles_file=myMbtilesFile) ie.export_image(myBbox, myZoomLevel, imagepath=myImageFile) # save the geoinfo myGrid = ie.grid_tiles(myBbox, myZoomLevel) sqWidth = len(myGrid[0]) sqHeight = len(myGrid) sqWidthPix = sqWidth * myTileSize sqHeightPix = sqHeight * myTileSize # delete temp dir (ImageExporter does not!) # bad: path is hard coded. how do I get hold of landez's temp path? # https://github.com/makinacorpus/landez/issues/42 try: shutil.rmtree('/tmp/landez') except OSError: pass # geoinfo output logging.debug(" grid: " + str(myGrid)) myLeftColumn = myGrid[0] myTopLeft = myLeftColumn[0] sqLeftTile = myTopLeft[0] sqTopTile = myTopLeft[-1] myRightColumn = myGrid[-1] myBottomRight = myRightColumn[-1] sqRightTile = myBottomRight[0] sqBottomTile = myBottomRight[-1] # calculate coords from tilenumbers def num2deg(xtile, ytile, zoom): n = 2.0 ** zoom lon_deg = -180.0 + 360.0 * xtile / n lat_rad = math.atan(math.sinh(math.pi * (1.0 - 2.0 * (ytile / n)))) lat_deg = 180.0 * lat_rad / math.pi return (lon_deg, lat_deg) sqBottomGeoPost = (num2deg(sqRightTile + 1, sqBottomTile + 1, myZoom)[-1]) sqTopGeoPost = (num2deg(sqLeftTile, sqTopTile, myZoom)[-1]) sqLeftGeoPost = (num2deg(sqLeftTile, sqTopTile, myZoom)[0]) sqRightGeoPost = (num2deg(sqRightTile + 1, sqBottomTile + 1, myZoom)[0]) # shall be exported to sqlite-queue logging.debug(" baselayer: " + str(myUrlBase)) logging.debug(" seamark: " + str(myUrlSeamark)) logging.debug(" hydro: " + str(myUrlHydro)) logging.debug(" zoom: " + str(myZoom)) logging.debug(" width: " + str(sqWidth) + " tiles") logging.debug(" height: " + str(sqHeight) + " tiles") logging.debug(" widthpix: " + str(sqWidthPix) + " pixel") logging.debug(" heightpix: "+ str(sqHeightPix) + " pixel") logging.debug(" left tile " + str(sqLeftTile)) logging.debug(" right tile: " + str(sqRightTile)) logging.debug(" top tile: " + str(sqTopTile)) logging.debug(" bottom tile: "+ str(sqBottomTile)) logging.debug(" left: " + str(sqLeftGeoPost)) logging.debug(" right: " + str(sqRightGeoPost)) logging.debug(" top: " + str(sqTopGeoPost)) logging.debug(" bottom: " + str(sqBottomGeoPost)) # start imgkap to generate .kap file import subprocess myImgkapCall = "./imgkap " + myImageFile + " " + str(sqTopGeoPost) + " " + str(sqLeftGeoPost) + " " + str(sqBottomGeoPost) + " " + str(sqRightGeoPost) + " " + myKapFile print myImgkapCall subprocess.call(myImgkapCall, shell=True)
Reason for ChartBundler
- Lets talk a bit about amounts here and not low stress or high stress. Using the charts offline on a mobile device. Lets say the display is about 1024x1024 Pixel, then we will need at least 16 tiles per map. If we start on zoom level 8 with the bounding box and continue to zoom level 16 for the harbours, we need around 2 Mio tiles. This 16 tiles on zoom level 8 is about the northern Adria. If we want the Channel just skipping Lands End up to the belgian coast, this would be 6 by 5 on zoom level 8. --Alexej
- Hi Alexej, do not understand this paragraph!? 2 test datasets of mine:
- --Kannix (Diskussion) 16:22, 29. Jan. 2015 (UTC)