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' % ( str(datetime.timedelta(seconds=ti)), i, len(shapefilesNames) )
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
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 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