123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- extends Node
- #var Downloader = preload("res://downloader.gd")
- var cache = {}
- var topoChunks = {}
- var maxheight = 10.783
- var minheight = -8.719
- signal fileReady
- signal chunkCached
- class topoChunk:
- var chunkPos: Vector2
- var filePrefix = "user://topo/"
- var formatString = "SLDEM2015_%s_%02d%s_%02d%s_%03d_%03d_FLOAT.IMG"
- var samplesPerLine = 23040
- var lines = 15360
- var offset = 1737.4*1000
- var scaleFact = 1
- var resolution = 512
- var orientation: String = "N"
- var latMin = 0
- var latMax = 30
- var lonMin = 0
- var lonMax = 45
- var chunkCached = false
- var fileReady = false
- var file: File
- # Called when the node enters the scene tree for the first time.
- func open(latMinIN, lonMinIN):
- chunkPos = Vector2(latMinIN, lonMinIN)
- latMin = (int(latMinIN)/30) * 30
- if latMinIN >= 0:
- orientation = "N"
- latMax = latMin+30
- else:
- orientation = "S"
- latMax = latMin-30
- lonMin = (int(lonMinIN)/45) * 45
- lonMax = lonMin+45
-
- file = File.new()
- print("opening topo: "+getFilepath())
- var err = file.open(getFilepath(), File.READ)
- if err == 7:
- Downloader.download(getFilename(), "topo")
- var dl = Downloader.Download.new()
- while not dl._file_name == getFilepath():
- dl = yield(Messenger, "fileDownloaded")
- file.open(getFilepath(), File.READ)
- _fileReady()
- return true
- elif err != 0:
- push_error("error opening file err:%s" %err)
- return false
- else:
- fileReady = true
- return true
-
- func getFilename():
- # example sldem2015_512_00n_30n_000_045_float.img
- # "%s/sldem2015_%s_%0*d%s_%0*d%s_%00*d_%00*d_float.img"
- var properties
- if orientation == "S":
- properties = [resolution, abs(latMax), orientation, abs(latMin), orientation, lonMin, lonMax]
- else:
- properties = [resolution, latMin, orientation, latMax, orientation, lonMin, lonMax]
- return formatString % properties
-
- func getFilepath():
- return filePrefix+getFilename()
- func _fileReady():
- fileReady = true
- Messenger.emit_signal("fileReady", self)
- func close():
- file.close()
- #queue_free()
-
- func clear():
- cache = {}
-
- func cacheChunk(chunkPos: Vector2):
- var tc
- if topoChunks.has(chunkPos.x) and topoChunks[chunkPos.x].has(chunkPos.y):
- tc = cache[chunkPos.y][chunkPos.x]
- return tc
-
- tc = topoChunk.new()
- tc.open(chunkPos.x, chunkPos.y)
- while tc.get_class() != topoChunk.get_class() and not tc.fileReady and tc.chunkPos != chunkPos:
- tc = yield(Messenger, "fileReady")
-
- var lat = chunkPos.x
- while lat <= chunkPos.x + 1.0:
- cache[lat]={}
- var line = abs(lat)*tc.resolution*tc.samplesPerLine*4
- # the origin of each .img file lies in it's upper left corner
- # so we need to read the files from the end on the northern hemisphere
- if lat >= 0:
- var origin = (chunkPos.x + 1.0)*tc.resolution*tc.samplesPerLine*4
- tc.file.seek((origin - line) + chunkPos.y*tc.resolution*4)
- else:
- tc.file.seek(line + chunkPos.y*tc.resolution*4)
- var lon = chunkPos.y
- while lon <= chunkPos.y + 1.0:
- cache[lat][lon] = tc.file.get_float()
- lon += 1.0/float(tc.resolution)
- lat += 1.0/float(tc.resolution)
- tc.chunkCached = true
-
- if not topoChunks.has(chunkPos.x):
- topoChunks[chunkPos.x] = {}
- topoChunks[chunkPos.x][chunkPos.y] = tc
- tc.file.close()
- Messenger.emit_signal("chunkCached", tc)
- return tc
-
- func createHeightmap(chunkPos:Vector2):
- var minLat:float = chunkPos.x
- var minLon:float = chunkPos.y
- var maxLat:float = chunkPos.x + 1.0
- var maxLon:float = chunkPos.y + 1.0
- var idxX = 0
- var idxY = 0
- var value = 0.0
- var heightmap = Image.new()
- heightmap.create(len(cache[cache.keys()[0]]), len(cache), false, Image.FORMAT_RF)
- heightmap.lock()
- for y in cache.keys():
- if not minLat:
- minLat = y
- for x in cache[y].keys():
- if not minLon:
- minLon = x
- value = inverse_lerp(minheight, maxheight, cache[y][x])
- heightmap.set_pixel(idxX, idxY, Color(value,0,0))#Color(cache[y][x],0,0))
- maxLon = x
- idxX += 1
- maxLat = y
- idxY += 1
- idxX = 0
- heightmap.unlock()
- var heightmapfilepath = "user://heightmap/%s:%s-%s:%s.png"%[minLat, minLon, maxLat, maxLon]
- heightmap.save_png(heightmapfilepath)
- return heightmap
- func read(lat,lon):
- if cache.has(lat) and cache[lat].has(lon):
- return cache[lat][lon]
- else:
- print("out of scope!")
- #func _validate(lat,lon):
- # var condition = true
- # if abs(lat) > latMax:
- # condition = false
- # if abs(lat) < latMin:
- # condition = false
- # if lon > lonMax:
- # condition = false
- # if lon < lonMin:
- # condition = false
- #
- # return condition
-
- #if abs(lat) <= latMax and abs(lat) >= latMin and lon <= lonMax and lon >= lonMin:
- # return true
- #return false
- # Called every frame. 'delta' is the elapsed time since the previous frame.
- #func _process(delta):
- # pass
|