def testEncodeDecodeNoBounds(self): ter = encode(geometries) ter.toFile(self.tmpfile) bounds = ter.bounds ter2 = decode(self.tmpfile, bounds) self.assert_tile(ter, ter2) # Bounds computed dynamically from partial tile # east edge now has data self.assertGreater(len(ter.eastI), 0) self.assertEqual(len(ter.eastI), len(ter2.eastI))
def testEncodeDecode(self): z = 0 x = 0 y = 0 globalGeodetic = GlobalGeodetic(True) bounds = globalGeodetic.TileBounds(x, y, z) ter = encode(geometries, bounds=bounds) ter.toFile(self.tmpfile) ter2 = decode(self.tmpfile, bounds) self.assert_tile(ter, ter2) # Partial tile nothing on the east edge self.assertEqual(len(ter.eastI), 0) self.assertEqual(len(ter.eastI), len(ter2.eastI))
def testEncodeDecode(self): z = 0 x = 0 y = 0 globalGeodetic = GlobalGeodetic(True) bounds = globalGeodetic.TileBounds(x, y, z) ter = encode(geometries, bounds=bounds) ter.toFile(self.tmpfile) ter2 = decode(self.tmpfile, bounds) self.assertIsInstance(ter.__repr__(), str) self.assertIsInstance(ter2.__repr__(), str) # check headers self.assertGreater(len(ter.header), 0) self.assertEqual(len(ter.header), len(ter2.header)) # check vertices self.assertGreater(len(ter.u), 0) self.assertGreater(len(ter.v), 0) self.assertGreater(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]) self.assertEqual( len(ter.getVerticesCoordinates()), len(ter2.getVerticesCoordinates()) ) # check indices self.assertGreater(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.assertGreater(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.assertEqual(len(ter.eastI), 0) self.assertEqual(len(ter.eastI), len(ter2.eastI))
def createTile(tile): session = None pid = os.getpid() try: (bounds, tileXYZ, t0, dbConfigFile, bucketBasePath, hasLighting, hasWatermask) = tile db = DB(dbConfigFile) bucketKey = '%s/%s/%s.terrain' % (tileXYZ[2], tileXYZ[0], tileXYZ[1]) 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)) geomCoords = [] 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]] geomCoords.append(coords) nbGeoms = len(geomCoords) if nbGeoms > 0: try: terrainTile = encode(geomCoords, bounds=bounds, autocorrectGeometries=True, hasLighting=hasLighting, watermask=watermask) except Exception as e: msg = '[%s] --------- ERROR ------- occured while ' % pid msg += 'encoding terrain tile\n' msg += '[%s]: %s' % (pid, e) logger.error(msg, exc_info=True) raise Exception(e) writeToS3(bucket, bucketKey, terrainTile.toBytesIO(gzipped=True), model.__tablename__, bucketBasePath, contentType=terrainTile.getContentType()) tend = time.time() tilecount.value += 1 tilesCreated = tilecount.value total = tilesCreated + skipcount.value if tilesCreated % 1000 == 0: logger.info('[%s] Last tile %s (%s rings). ' '%s to write %s tiles. (total processed: %s)' % (pid, bucketKey, nbGeoms, str(datetime.timedelta(seconds=tend - t0)), tilesCreated, 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