def testWatermaskOnlyReader(self): z = 9 x = 769 y = 319 geodetic = GlobalGeodetic(True) ter = TerrainTile() [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z) ter.fromFile('forge/data/quantized-mesh/%s_%s_%s_watermask.terrain' % (z, x, y), minx, miny, maxx, maxy, hasWatermask=True) self.assertEqual(len(ter.watermask), 256) for row in ter.watermask: self.assertEqual(len(row), 256) for val in row: self.assertTrue(val >= 0) self.assertTrue(val <= 255) ter.toFile(self.tmpfile) ter2 = TerrainTile() ter2.fromFile(self.tmpfile, minx, miny, maxx, maxy, hasWatermask=True) self.assertEqual(len(ter2.watermask), 256) for i in range(0, len(ter.watermask)): for j in range(0, len(ter.watermask[i])): self.assertEqual(ter.watermask[i][j], ter2.watermask[i][j])
def testExtensionsReader(self): z = 10 x = 1563 y = 590 geodetic = GlobalGeodetic(True) ter = TerrainTile() [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z) ter.fromFile( 'forge/data/quantized-mesh/%s_%s_%s_light_watermask.terrain' % (z, x, y), minx, miny, maxx, maxy, hasLighting=True, hasWatermask=True) # check indices self.assertTrue(len(ter.indices) > 0) # check edges self.assertTrue(len(ter.westI) > 0) self.assertTrue(len(ter.southI) > 0) self.assertTrue(len(ter.eastI) > 0) self.assertTrue(len(ter.northI) > 0) # check extensions self.assertEqual(len(ter.watermask), 1) self.assertEqual(len(ter.watermask[0]), 1) # Water only -> 255 self.assertEqual(ter.watermask[0][0], 255) ter.toFile(self.tmpfile) ter2 = TerrainTile() ter2.fromFile(self.tmpfile, minx, miny, maxx, maxy, hasLighting=True, hasWatermask=True) self.assertEqual(len(ter.watermask), len(ter2.watermask)) self.assertEqual(len(ter.watermask[0]), len(ter2.watermask[0])) sign = lambda a: 1 if a > 0 else -1 if a < 0 else 0 for i in range(0, len(ter.vLight)): for j in range(0, 3): # We cannot have an exact equality with successive # oct encoding and decoding # Thus we only check the sign self.assertEqual(sign(ter.vLight[i][j]), sign(ter2.vLight[i][j]))
def testBoundingSpherePrecision(self): tilePath = 'forge/data/quantized-mesh/raron.flat.1.terrain' ter = TerrainTile() ter.fromFile(tilePath, 7.80938, 7.81773, 46.30261, 46.30799) coords = ter.getVerticesCoordinates() llh2ecef = lambda x: LLH2ECEF(x[0], x[1], x[2]) coords = map(llh2ecef, coords) sphere = BoundingSphere() sphere.fromPoints(coords) for coord in coords: distance = c3d.distance(sphere.center, coord) self.failUnless(distance <= sphere.radius)
def testExtensionsReader(self): z = 10 x = 1563 y = 590 geodetic = GlobalGeodetic(True) ter = TerrainTile() [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z) ter.fromFile( 'forge/data/quantized-mesh/%s_%s_%s_light_watermask.terrain' % (z, x, y), minx, miny, maxx, maxy, hasLighting=True, hasWatermask=True ) # check indices self.assertTrue(len(ter.indices) > 0) # check edges self.assertTrue(len(ter.westI) > 0) self.assertTrue(len(ter.southI) > 0) self.assertTrue(len(ter.eastI) > 0) self.assertTrue(len(ter.northI) > 0) # check extensions self.assertEqual(len(ter.watermask), 1) self.assertEqual(len(ter.watermask[0]), 1) # Water only -> 255 self.assertEqual(ter.watermask[0][0], 255) ter.toFile(self.tmpfile) ter2 = TerrainTile() ter2.fromFile(self.tmpfile, minx, miny, maxx, maxy, hasLighting=True, hasWatermask=True) self.assertEqual(len(ter.watermask), len(ter2.watermask)) self.assertEqual(len(ter.watermask[0]), len(ter2.watermask[0])) sign = lambda a: 1 if a > 0 else -1 if a < 0 else 0 for i in range(0, len(ter.vLight)): for j in range(0, 3): # We cannot have an exact equality with successive # oct encoding and decoding # Thus we only check the sign self.assertEqual(sign(ter.vLight[i][j]), sign(ter2.vLight[i][j]))
def testReaderWriter(self): ''' Circle jerk testing. We read the file with our reader We write this data with our writer to a temporary file We read this temporary file We compare the results ''' ter = TerrainTile() # ter.fromFile( # 'forge/data/quantized-mesh/0.terrain', 7.80938, 7.81773, 46.30261, 46.3079) # ter.fromFile( # 'forge/data/quantized-mesh/raron.flat.1.terrain', # 7.80938, 7.81773, 46.30261, 46.30790) ter.fromFile( 'forge/data/quantized-mesh/goms.mountains.1.terrain', 7.80938, 7.81773, 46.30261, 46.30799 ) ter.toFile(self.tmpfile) ter2 = TerrainTile() ter2.fromFile(self.tmpfile, 7.80938, 7.81773, 46.30261, 46.30799) # check headers self.assertTrue(len(ter.header) > 0) self.assertEqual(len(ter.header), len(ter2.header)) self.assertEqual(len(ter.header), len(TerrainTile.quantizedMeshHeader)) for k, v in ter.header.iteritems(): self.assertEqual(v, ter2.header[k], 'For k = ' + k) # check vertices self.assertTrue(len(ter.u) > 0) self.assertTrue(len(ter.v) > 0) self.assertTrue(len(ter.h) > 0) self.assertEqual(len(ter.u), len(ter2.u)) self.assertEqual(len(ter.v), len(ter2.v)) self.assertEqual(len(ter.h), len(ter2.h)) for i, v in enumerate(ter.u): self.assertEqual(v, ter2.u[i]) for i, v in enumerate(ter.v): self.assertEqual(v, ter2.v[i]) for i, v in enumerate(ter.h): self.assertEqual(v, ter2.h[i]) # check indices self.assertTrue(len(ter.indices) > 0) self.assertEqual(len(ter.indices), len(ter2.indices)) for i, v in enumerate(ter.indices): self.assertEqual(v, ter2.indices[i], i) # check edges self.assertTrue(len(ter.westI) > 0) self.assertEqual(len(ter.westI), len(ter2.westI)) for i, v in enumerate(ter.westI): self.assertEqual(v, ter2.westI[i], i) self.assertTrue(len(ter.southI) > 0) self.assertEqual(len(ter.southI), len(ter2.southI)) for i, v in enumerate(ter.southI): self.assertEqual(v, ter2.southI[i], i) self.assertTrue(len(ter.eastI) > 0) self.assertEqual(len(ter.eastI), len(ter2.eastI)) for i, v in enumerate(ter.eastI): self.assertEqual(v, ter2.eastI[i], i) self.assertTrue(len(ter.northI) > 0) self.assertEqual(len(ter.northI), len(ter2.northI)) for i, v in enumerate(ter.northI): self.assertEqual(v, ter2.northI[i], i)
# -*- coding: utf-8 -*- from forge.terrain import TerrainTile ter = TerrainTile() # ter.fromFile('forge/data/quantized-mesh/0.terrain') ter.fromFile('forge/data/quantized-mesh/raron.flat.1.terrain', 7.80938, 7.81773, 46.30261, 46.30799) # ter.fromFile('forge/data/quantized-mesh/goms.mountains.1.terrain') ter.computeVerticesCoordinates(epsg=21781) print ter
from forge.terrain.topology import TerrainTopology from forge.lib.shapefile_utils import ShpToGDALFeatures from forge.lib.global_geodetic import GlobalGeodetic basename = '7_133_98' directory = '.tmp' extension = '.terrain' curDir = os.getcwd() filePathSource = '%s/forge/data/shapefile-features/%s.shp' % (curDir, basename) filePathTarget = '%s/%s%s' % (directory, basename, extension) shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() geodetic = GlobalGeodetic(True) zxy = basename.split('_') bounds = geodetic.TileBounds(float(zxy[1]), float(zxy[2]), float(zxy[0])) terrainFormat.fromTerrainTopology(terrainTopo, bounds) terrainFormat.toFile(filePathTarget) # Display SwissCoordinates terrainFormat.computeVerticesCoordinates(epsg=21781) print terrainFormat
i = 0 t0 = time.time() getShapefiles = lambda x: x.endswith('.shp') shapefilesNames = filter(getShapefiles, os.listdir(basePath)) bucket = getBucket() bucketBasePath = tmsConfig.get('General', 'bucketpath') for f in shapefilesNames: filePathSource = basePath + f shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() terrainFormat.fromTerrainTopology(terrainTopo) fileObject = terrainFormat.toStringIO() compressedFile = gzipFileObject(fileObject) # Hardcoded scheme because we don't have any separators in the names # for now keyPath = f[1:3] + '/' + f[3:9] + '/' + f[9:14] + extension print 'Writing %s to S3' % keyPath writeToS3(bucket, keyPath, compressedFile, basePath, bucketBasePath, contentType=terrainFormat.getContentType()) i += 1 t1 = time.time() ti = t1 - t0 print 'It took %s secs to write %s/%s tiles' % (
def testReaderWriter(self): ''' Circle jerk testing. We read the file with our reader We write this data with our writer to a temporary file We read this temporary file We compare the results ''' ter = TerrainTile() # ter.fromFile( # 'forge/data/quantized-mesh/0.terrain', 7.80938, 7.81773, 46.30261, 46.3079) # ter.fromFile( # 'forge/data/quantized-mesh/raron.flat.1.terrain', # 7.80938, 7.81773, 46.30261, 46.30790) ter.fromFile('forge/data/quantized-mesh/goms.mountains.1.terrain', 7.80938, 7.81773, 46.30261, 46.30799) ter.toFile(self.tmpfile) ter2 = TerrainTile() ter2.fromFile(self.tmpfile, 7.80938, 7.81773, 46.30261, 46.30799) # check headers self.assertTrue(len(ter.header) > 0) self.assertEqual(len(ter.header), len(ter2.header)) self.assertEqual(len(ter.header), len(TerrainTile.quantizedMeshHeader)) for k, v in ter.header.iteritems(): self.assertEqual(v, ter2.header[k], 'For k = ' + k) # check vertices self.assertTrue(len(ter.u) > 0) self.assertTrue(len(ter.v) > 0) self.assertTrue(len(ter.h) > 0) self.assertEqual(len(ter.u), len(ter2.u)) self.assertEqual(len(ter.v), len(ter2.v)) self.assertEqual(len(ter.h), len(ter2.h)) for i, v in enumerate(ter.u): self.assertEqual(v, ter2.u[i]) for i, v in enumerate(ter.v): self.assertEqual(v, ter2.v[i]) for i, v in enumerate(ter.h): self.assertEqual(v, ter2.h[i]) # check indices self.assertTrue(len(ter.indices) > 0) self.assertEqual(len(ter.indices), len(ter2.indices)) for i, v in enumerate(ter.indices): self.assertEqual(v, ter2.indices[i], i) # check edges self.assertTrue(len(ter.westI) > 0) self.assertEqual(len(ter.westI), len(ter2.westI)) for i, v in enumerate(ter.westI): self.assertEqual(v, ter2.westI[i], i) self.assertTrue(len(ter.southI) > 0) self.assertEqual(len(ter.southI), len(ter2.southI)) for i, v in enumerate(ter.southI): self.assertEqual(v, ter2.southI[i], i) self.assertTrue(len(ter.eastI) > 0) self.assertEqual(len(ter.eastI), len(ter2.eastI)) for i, v in enumerate(ter.eastI): self.assertEqual(v, ter2.eastI[i], i) self.assertTrue(len(ter.northI) > 0) self.assertEqual(len(ter.northI), len(ter2.northI)) for i, v in enumerate(ter.northI): self.assertEqual(v, ter2.northI[i], i)
# -*- coding: utf-8 -*- from forge.terrain import TerrainTile from forge.lib.global_geodetic import GlobalGeodetic basename = '7_133_98' directory = '.tmp' extension = '.shp' # Read terrain file filePathSource = 'forge/data/quantized-mesh/%s.terrain' % basename filePathTarget = '%s/%s%s' % (directory, basename, extension) ter = TerrainTile() geodetic = GlobalGeodetic(True) zxy = basename.split('_') bounds = geodetic.TileBounds(float(zxy[1]), float(zxy[2]), float(zxy[0])) print bounds ter.fromFile(filePathSource, bounds[0], bounds[2], bounds[1], bounds[3]) ter.toShapefile(filePathTarget) # In order to display swiss coordinates ter.computeVerticesCoordinates(epsg=21781) print ter
extension = '.terrain' i = 0 t0 = time.time() getShapefiles = lambda x: x.endswith('.shp') shapefilesNames = filter(getShapefiles, os.listdir(basePath)) bucket = getBucket() for f in shapefilesNames: filePathSource = basePath + f shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() terrainFormat.fromTerrainTopology(terrainTopo) fileObject = terrainFormat.toStringIO() compressedFile = gzipFileObject(fileObject) # Hardcoded scheme because we don't have any separators in the names # for now keyPath = f[1:3] + '/' + f[3:9] + '/' + f[9:14] + extension print 'Writing %s to S3' % keyPath writeToS3(bucket, keyPath, compressedFile, basePath) i += 1 t1 = time.time() ti = t1 - t0 print 'It took %s secs to write %s/%s tiles' % (str(datetime.timedelta(seconds=ti)), i, len(shapefilesNames))
i = 0 t0 = time.time() getShapefiles = lambda x: x.endswith('.shp') shapefilesNames = filter(getShapefiles, os.listdir(basePath)) bucket = getBucket() bucketBasePath = tmsConfig.get('General', 'bucketpath') for f in shapefilesNames: filePathSource = basePath + f shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() terrainFormat.fromTerrainTopology(terrainTopo) fileObject = terrainFormat.toStringIO() compressedFile = gzipFileObject(fileObject) # Hardcoded scheme because we don't have any separators in the names # for now keyPath = f[1:3] + '/' + f[3:9] + '/' + f[9:14] + extension print 'Writing %s to S3' % keyPath writeToS3(bucket, keyPath, compressedFile, basePath, bucketBasePath, contentType=terrainFormat.getContentType())
# -*- coding: utf-8 -*- from forge.terrain import TerrainTile from forge.lib.global_geodetic import GlobalGeodetic basename = '15_58391_23482' directory = '.tmp' extension = '.shp' # Read terrain file filePathSource = '%s/%s.terrain' % (directory, basename) filePathTarget = '%s/%s%s' % (directory, basename, extension) ter = TerrainTile() geodetic = GlobalGeodetic(True) zxy = basename.split('_') bounds = geodetic.TileBounds(float(zxy[1]), float(zxy[2]), float(zxy[0])) print bounds ter.fromFile(filePathSource, bounds[0], bounds[2], bounds[1], bounds[3]) ter.toShapefile(filePathTarget) # In order to display swiss coordinates #ter.computeVerticesCoordinates(epsg=4326) #print ter
# -*- coding: utf-8 -*- import os from forge.terrain import TerrainTile from forge.terrain.topology import TerrainTopology from forge.lib.shapefile_utils import ShpToGDALFeatures basename = 'single_wgs84' directory = '.tmp' extension = '.terrain' curDir = os.getcwd() filePathSource = '/Users/liberostelios/Downloads/test_area/%s.shp' % (basename) filePathTarget = '%s/%s%s' % (directory, basename, extension) shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() terrainFormat.fromTerrainTopology(terrainTopo) terrainFormat.toFile(filePathTarget) # Display SwissCoordinates terrainFormat.computeVerticesCoordinates(epsg=7415) print terrainFormat
def createTile(tile): session = None pid = os.getpid() try: (bounds, tileXYZ, t0, dbConfigFile, bucketBasePath, hasLighting, hasWatermask) = tile db = DB(dbConfigFile) with db.userSession() as session: bucket = getBucket() # Get the model according to the zoom level model = modelsPyramid.getModelByZoom(tileXYZ[2]) watermask = [] if hasWatermask: lakeModel = modelsPyramid.getLakeModelByZoom(tileXYZ[2]) query = session.query( lakeModel.watermaskRasterize(bounds).label('watermask') ) for q in query: watermask = q.watermask # Get the interpolated point at the 4 corners # 0: (minX, minY), 1: (minX, maxY), 2: (maxX, maxY), 3: (maxX, minY) pts = [ (bounds[0], bounds[1], 0), (bounds[0], bounds[3], 0), (bounds[2], bounds[3], 0), (bounds[2], bounds[1], 0) ] def toSubQuery(x): return session.query( model.id, model.interpolateHeightOnPlane(pts[x]) ).filter( and_( model.bboxIntersects(createBBox(pts[x], 0.01)), model.pointIntersects(pts[x]) ) ).subquery('p%s' % x) subqueries = [toSubQuery(i) for i in range(0, len(pts))] # Get the height of the corner points as postgis cannot properly # clip a polygon cornerPts = {} step = 2 j = step query = session.query(*subqueries) for q in query: for i in range(0, len(q), step): sub = q[i:j] j += step cornerPts[sub[0]] = list( to_shape(WKBElement(sub[1])).coords ) # Clip using the bounds clippedGeometry = model.bboxClippedGeom(bounds) query = session.query( model.id, clippedGeometry.label('clip') ).filter(model.bboxIntersects(bounds)) terrainTopo = TerrainTopology(hasLighting=hasLighting) for q in query: coords = list(to_shape(q.clip).exterior.coords) if q.id in cornerPts: pt = cornerPts[q.id][0] for i in range(0, len(coords)): c = coords[i] if c[0] == pt[0] and c[1] == pt[1]: coords[i] = [c[0], c[1], pt[2]] try: rings = processRingCoordinates(coords) except Exception as e: msg = '[%s] --------- ERROR ------- occured while ' \ 'collapsing non triangular shapes\n' % pid msg += '[%s]: %s' % (pid, e) logger.error(msg, exc_info=True) raise Exception(e) # Redundant coord has been remove already for vertices in rings: terrainTopo.addVertices(vertices) bucketKey = '%s/%s/%s.terrain' % ( tileXYZ[2], tileXYZ[0], tileXYZ[1]) verticesLength = len(terrainTopo.vertices) if verticesLength > 0: terrainTopo.create() # Prepare terrain tile terrainFormat = TerrainTile(watermask=watermask) terrainFormat.fromTerrainTopology(terrainTopo, bounds=bounds) # Bytes manipulation and compression fileObject = terrainFormat.toStringIO() compressedFile = gzipFileObject(fileObject) writeToS3( bucket, bucketKey, compressedFile, model.__tablename__, bucketBasePath, contentType=terrainFormat.getContentType() ) tend = time.time() tilecount.value += 1 val = tilecount.value total = val + skipcount.value if val % 10 == 0: logger.info('[%s] Last tile %s (%s rings). ' '%s to write %s tiles. (total processed: %s)' % ( pid, bucketKey, verticesLength, str(datetime.timedelta(seconds=tend - t0)), val, total ) ) else: skipcount.value += 1 val = skipcount.value total = val + tilecount.value # One should write an empyt tile logger.info('[%s] Skipping %s %s because no features found ' 'for this tile (%s skipped from %s total)' % ( pid, bucketKey, bounds, val, total ) ) except Exception as e: logger.error(e, exc_info=True) raise Exception(e) finally: db.userEngine.dispose() return 0
def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'f:t:', ['from=', 'to=']) except getopt.GetoptError as err: error(str(err), 2, usage=usage) ffrom = None to = None ffile = None for o, a in opts: if o in ('-f', '--from'): ffrom = a if o in ('-t', '--to'): to = a if ffrom is None or to is None: if len(args) != 1: error("Please specify a file.", 4, usage=usage) ffile = args[0] tiles = [] # We have file, so we get the tiles from the file if ffile is not None: with open(ffile) as f: for line in f: line = line.rstrip() if len(line) > 2: tiles.append(map(int, line.split('/'))) # If we have from to, we catch layers.json from poc and use from to for levels if ffrom is not None and to is not None: req = urlopen(poc_base_url + 'layer.json') layers = {} for line in req: layers = json.loads(line) for zoom in range(int(ffrom), int(to) + 1): level = layers['available'][zoom][0] for x in range(int(level['startX']), int(level['endX']) + 1): for y in range(int(level['startY']), int(level['endY']) + 1): tiles.append([zoom, x, y]) bucket = getBucket() g = GlobalGeodetic(tmscompatible=True) if not os.path.isdir('tmp'): os.mkdir('tmp') for tile in tiles: req = None tilebounds = g.TileBounds(tile[1], tile[2], tile[0]) tilestring = str(tile[0]) + "/" + str(tile[1]) + "/" + str(tile[2]) try: url = poc_base_url + tilestring + ".terrain?v=2.0.0" req = urlopen(url) with open(gzip_file_name, 'wb') as fp: fp.write(req.read()) ff = gzip.open(gzip_file_name) with open(temp_file_name, 'wb') as fp: fp.write(ff.read()) ter = TerrainTile() ter.fromFile( temp_file_name, tilebounds[0], tilebounds[2], tilebounds[1], tilebounds[3] ) ''' if os.path.isfile(tms_file_name): os.remove(tms_file_name) if os.path.isfile(shape_file_name): os.remove(shape_file_name) if os.path.isfile(tms_from_shape_file_name): os.remove(tms_from_shape_file_name) ter.toFile(tms_file_name) ter.toShapefile(shape_file_name) shapefile = ShpToGDALFeatures(shpFilePath=shape_file_name) features = shapefile.__read__() topology = TerrainTopology(features=features) topology.fromGDALFeatures() terFromPoc = TerrainTile() terFromPoc.fromFile( tms_file_name, tilebounds[0], tilebounds[2], tilebounds[1], tilebounds[3] ) terFromShape = TerrainTile() terFromShape.fromTerrainTopology(topology) terFromShape.toFile(tms_from_shape_file_name) # Use this to select what is written to s3 ter2 = terFromShape ''' ter2 = ter fileObject = ter2.toStringIO() compressedFile = gzipFileObject(fileObject) bucketKey = tilestring + '.terrain' print 'Uploading %s to S3' % bucketKey writeToS3(bucket, bucketKey, compressedFile, 'POC Tiles copy', contentType=ter.getContentType()) except Exception as e: print "error with " + line + " " + str(e) finally: if req: req.close() return 0
# -*- coding: utf-8 -*- from forge.terrain import TerrainTile from forge.lib.global_geodetic import GlobalGeodetic ter = TerrainTile() path = 'forge/data/quantized-mesh/' basename = '9_533_383' extension = '.terrain' fullPath = '%s%s%s' % (path, basename, extension) geodetic = GlobalGeodetic(True) zxy = basename.split('_') bounds = geodetic.TileBounds(float(zxy[1]), float(zxy[2]), float(zxy[0])) ter.fromFile(fullPath, bounds[1], bounds[3], bounds[0], bounds[2]) ter.computeVerticesCoordinates(epsg=21781) print ter
from forge.terrain import TerrainTile from forge.terrain.topology import TerrainTopology from forge.lib.shapefile_utils import ShpToGDALFeatures from forge.lib.global_geodetic import GlobalGeodetic basename = '7_133_98' directory = '.tmp' extension = '.terrain' curDir = os.getcwd() filePathSource = '%s/forge/data/shapefile-features/%s.shp' % (curDir, basename) filePathTarget = '%s/%s%s' % (directory, basename, extension) shapefile = ShpToGDALFeatures(shpFilePath=filePathSource) features = shapefile.__read__() terrainTopo = TerrainTopology(features=features) terrainTopo.fromGDALFeatures() terrainFormat = TerrainTile() geodetic = GlobalGeodetic(True) zxy = basename.split('_') bounds = geodetic.TileBounds(float(zxy[1]), float(zxy[2]), float(zxy[0])) terrainFormat.fromTerrainTopology(terrainTopo, bounds) terrainFormat.toFile(filePathTarget) # Display SwissCoordinates terrainFormat.computeVerticesCoordinates(epsg=21781) print terrainFormat
def createTile(tile): session = None pid = os.getpid() try: (bounds, tileXYZ, t0, dbConfigFile, bucketBasePath, hasLighting, hasWatermask) = tile db = DB(dbConfigFile) with db.userSession() as session: # bucket = getBucket() # Get the model according to the zoom level model = modelsPyramid.getModelByZoom(tileXYZ[2]) watermask = [] if hasWatermask: lakeModel = modelsPyramid.getLakeModelByZoom(tileXYZ[2]) query = session.query( lakeModel.watermaskRasterize(bounds).label('watermask')) for q in query: watermask = q.watermask # Get the interpolated point at the 4 corners # 0: (minX, minY), 1: (minX, maxY), 2: (maxX, maxY), 3: (maxX, minY) pts = [(bounds[0], bounds[1], 0), (bounds[0], bounds[3], 0), (bounds[2], bounds[3], 0), (bounds[2], bounds[1], 0)] def toSubQuery(x): return session.query( model.id, model.interpolateHeightOnPlane(pts[x])).filter( and_(model.bboxIntersects(createBBox(pts[x], 0.01)), model.pointIntersects(pts[x]))).subquery('p%s' % x) subqueries = [toSubQuery(i) for i in range(0, len(pts))] # Get the height of the corner points as postgis cannot properly # clip a polygon cornerPts = {} step = 2 j = step query = session.query(*subqueries) for q in query: for i in range(0, len(q), step): sub = q[i:j] j += step cornerPts[sub[0]] = list( to_shape(WKBElement(sub[1])).coords) # Clip using the bounds clippedGeometry = model.bboxClippedGeom(bounds) query = session.query(model.id, clippedGeometry.label('clip')).filter( model.bboxIntersects(bounds)) terrainTopo = TerrainTopology(hasLighting=hasLighting) for q in query: if to_shape(q.clip).geom_type == "GeometryCollection": continue if to_shape(q.clip).geom_type == "LineString" or to_shape( q.clip).geom_type == "Point": continue coords = list(to_shape(q.clip).exterior.coords) if q.id in cornerPts: pt = cornerPts[q.id][0] for i in range(0, len(coords)): c = coords[i] if c[0] == pt[0] and c[1] == pt[1]: coords[i] = [c[0], c[1], pt[2]] try: rings = processRingCoordinates(coords) except Exception as e: msg = '[%s] --------- ERROR ------- occured while ' \ 'collapsing non triangular shapes\n' % pid msg += '[%s]: %s' % (pid, e) logger.error(msg, exc_info=True) raise Exception(e) # Redundant coord has been remove already for vertices in rings: terrainTopo.addVertices(vertices) baseDir = '/Users/liberostelios/3d_forge_geodata/output' terrainDir = '%s/%s/%s' % (baseDir, tileXYZ[2], tileXYZ[0]) bucketKey = '%s/%s.terrain' % (terrainDir, tileXYZ[1]) verticesLength = len(terrainTopo.vertices) if verticesLength > 0: terrainTopo.create() # Prepare terrain tile terrainFormat = TerrainTile(watermask=watermask) terrainFormat.fromTerrainTopology(terrainTopo, bounds=bounds) # STELIOS: We want this in a file, instead if not os.path.isdir(terrainDir): os.makedirs(terrainDir) terrainFormat.toFile(bucketKey) logger.info('[%s] Just did %s %s' % (pid, bucketKey, bounds)) # Bytes manipulation and compression # fileObject = terrainFormat.toStringIO() # compressedFile = gzipFileObject(fileObject) # writeToS3( # bucket, bucketKey, compressedFile, model.__tablename__, # bucketBasePath, contentType=terrainFormat.getContentType() # ) tend = time.time() tilecount.value += 1 val = tilecount.value total = val + skipcount.value if val % 10 == 0: logger.info('[%s] Last tile %s (%s rings). ' '%s to write %s tiles. (total processed: %s)' % (pid, bucketKey, verticesLength, str(datetime.timedelta(seconds=tend - t0)), val, total)) else: skipcount.value += 1 val = skipcount.value total = val + tilecount.value # One should write an empyt tile logger.info('[%s] Skipping %s %s because no features found ' 'for this tile (%s skipped from %s total)' % (pid, bucketKey, bounds, val, total)) except Exception as e: logger.error(e, exc_info=True) raise Exception(e) finally: db.userEngine.dispose() return 0