示例#1
0
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)
    )
示例#2
0
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
示例#3
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
示例#4
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