def testWatermaskOnlyReader(self):
        z = 9
        x = 769
        y = 319
        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)

        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter.fromFile('tests/data/%s_%s_%s_watermask.terrain' % (z, x, y),
            hasWatermask=True)

        self.assertEqual(len(ter.watermask), 256)
        for row in ter.watermask:
            self.assertEqual(len(row), 256)
            for val in row:
                self.assertGreaterEqual(val, 0)
                self.assertLessEqual(val, 255)

        ter.toFile(self.tmpfile)

        ter2 = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter2.fromFile(self.tmpfile, 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])

        self.assertEqual(ter2.getContentType(),
            'application/vnd.quantized-mesh;extensions=watermask')
    def testFromStringIO(self):
        z = 10
        x = 1563
        y = 590
        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)

        # Regular file not gzip compressed
        ter = TerrainTile()
        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        with open('tests/data/%s_%s_%s_light_watermask.terrain' % (z, x, y)) as f:
            content = cStringIO.StringIO(f.read())

        ter.fromStringIO(content, hasLighting=True, hasWatermask=True)

        # check indices
        self.assertGreater(len(ter.indices), 0)

        # check edges
        self.assertGreater(len(ter.westI), 0)
        self.assertGreater(len(ter.southI), 0)
        self.assertGreater(len(ter.eastI), 0)
        self.assertGreater(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)
Exemple #3
0
    def populateLakes(self):
        self.setupDatabase()
        logger.info('Action: populateLakes()')

        # For now we never reproject lakes
        with self.userSession() as session:
            shpFile = self.config.get('Data', 'lakes')

            if not os.path.exists(shpFile):
                logger.error('Shapefile %s does not exists' % (shpFile))
                sys.exit(1)

            count = 1
            shp = ShpToGDALFeatures(shpFile)
            logger.info('Processing %s' % (shpFile))
            bulk = BulkInsert(Lakes, session, withAutoCommit=1000)

            for feature in shp.getFeatures():
                polygon = feature.GetGeometryRef()
                # Force 2D for lakes
                polygon.FlattenTo2D()
                # add shapefile path to dict
                # self.shpFilePath
                bulk.add(dict(the_geom='SRID=4326;' + polygon.ExportToWkt()))
                count += 1
            bulk.commit()
            logger.info('Commit %s features for %s.' % (count, shpFile))
            # Once all features have been commited, start creating all
            # the simplified versions of the lakes
            logger.info('Simplifying lakes')
            tiles = TerrainTiles(self.dbConfigFile, tmsConfig, time.time())
            geodetic = GlobalGeodetic(True)
            bounds = (tiles.minLon, tiles.minLat, tiles.maxLon, tiles.maxLat)
            zooms = range(tiles.tileMinZ, tiles.tileMaxZ + 1)
            for i in xrange(0, len(zooms)):
                zoom = zooms[i]
                tablename = 'lakes_%s' % zoom
                tileMinX, tileMinY = geodetic.LonLatToTile(
                    bounds[0], bounds[1], zoom)
                tileMaxX, tileMaxY = geodetic.LonLatToTile(
                    bounds[2], bounds[3], zoom)
                tileBounds = geodetic.TileBounds(tileMinX, tileMinY, zoom)
                pointA = transformCoordinate(
                    'POINT(%s %s)' % (tileBounds[0], tileBounds[1]), 4326,
                    21781).GetPoints()[0]
                pointB = transformCoordinate(
                    'POINT(%s %s)' % (tileBounds[2], tileBounds[3]), 4326,
                    21781).GetPoints()[0]
                length = c2d.distance(pointA, pointB)
                pixelArea = pow(length, 2) / pow(256.0, 2)
                pixelLength = math.sqrt(pixelArea)
                session.execute(
                    create_simplified_geom_table(tablename, pixelLength))
                session.commit()
                logger.info('Commit table public.%s with %s meters '
                            'tolerance' % (tablename, pixelLength))
Exemple #4
0
def load_tile(terrain_path, x, y, z):
    """

    :rtype: EditableTerrainTile
    """
    geodetic = GlobalGeodetic(True)
    [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)
    tile = EditableTerrainTile(west=minx, south=miny, east=maxx, north=maxy)
    tile.fromFile(terrain_path, has_lighting=True)
    return tile
 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))
Exemple #6
0
 def _initPyramidMetadata(self):
     # It keeps track of the starting and ending tiles
     # and the missing tiles in between
     self.metadata = {}
     self.ranges = {}
     geodetic = GlobalGeodetic(True)
     bounds = self.meta['bounds']
     # Assume the whole extent is available
     for z in range(self.tileMinZoom, self.tileMaxZoom + 1):
         tileMinX, tileMinY = geodetic.LonLatToTile(bounds[0], bounds[1], z)
         tileMaxX, tileMaxY = geodetic.LonLatToTile(bounds[2], bounds[3], z)
         self.metadata[z] = dict(x=[tileMinX, tileMaxX],
                                 y=[tileMinY, tileMaxY])
         self.ranges[z] = {}
Exemple #7
0
    def testExtensionsReader(self):
        z = 10
        x = 1563
        y = 590
        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)

        ter = TerrainTile()
        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter.fromFile(
            'tests/data/%s_%s_%s_light_watermask.terrain' % (z, x, y),
            hasLighting=True, hasWatermask=True
        )

        # check indices
        self.assertGreater(len(ter.indices), 0)

        # check edges
        self.assertGreater(len(ter.westI), 0)
        self.assertGreater(len(ter.southI), 0)
        self.assertGreater(len(ter.eastI), 0)
        self.assertGreater(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(west=minx, south=miny, east=maxx, north=maxy)
        ter2.fromFile(self.tmpfile,
                      hasLighting=True, hasWatermask=True)

        self.assertEqual(len(ter.watermask), len(ter2.watermask))
        self.assertEqual(len(ter.watermask[0]), len(ter2.watermask[0]))

        def sign(a):
            return 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]))

        self.assertEqual(ter2.getContentType(),
                         'application/vnd.quantized-mesh;' +
                         'extensions=octvertexnormals-watermask')
Exemple #8
0
    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 testBoundingSpherePrecision(self):
        x = 533
        y = 383
        z = 9

        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)
        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter.fromFile('tests/data/%s_%s_%s.terrain' % (z, x, y))

        coords = [LLH2ECEF(*coord) for coord in ter.getVerticesCoordinates()]
        sphere = BoundingSphere()
        sphere.fromPoints(coords)
        for coord in coords:
            distance = c3d.distance(sphere.center, coord)
            self.assertLessEqual(distance, sphere.radius)
Exemple #10
0
def tileNotExists(tile):
    h = {'Referer': 'http://geo.admin.ch'}
    (bounds, tileXYZ, t0, basePath, tFormat, gridOrigin, tilesURLs) = tile
    # Only native tiles for now
    entryPoint = 'http:%s' % (random.choice(tilesURLs))

    # Account for a different origin
    if gridOrigin == 'topLeft':
        geodetic = GlobalGeodetic(True)
        nbYTiles = geodetic.GetNumberOfYTilesAtZoom(tileXYZ[2])
        tilexyz = (tileXYZ[0], nbYTiles - tileXYZ[1] - 1, tileXYZ[2])
        tileAdress = '/'.join(
            (str(tilexyz[2]), str(tilexyz[1]), str(tilexyz[0])))
    else:
        tileAdress = '/'.join(
            (str(tileXYZ[2]), str(tileXYZ[1]), str(tileXYZ[0])))

    url = '%s%s%s.%s' % (entryPoint, basePath, tileAdress, tFormat)
    tilecount.value += 1

    try:
        exists = resourceExists(url, headers=h)
    except Exception as e:
        logger.error('Connection Error', exc_info=True)
        logger.error('%s was skipped' % url, exc_info=True)
        raise Exception(e)

    if not exists:
        tileskipped.value += 1
    if tilecount.value % 1000 == 0:
        tend = time.time()
        logger.info('It took %s to (HEAD) request %s tiles. %s skipped' % (
            str(datetime.timedelta(seconds=tend - t0)),
            tilecount.value, tileskipped.value)
        )
        logger.info('Last tile checked:')
        logger.info(url)
    if not exists:
        # Return everything in terrain coordinates
        # e.g. starting at the bottom left
        # (Transformation is performed in Cesium)
        # https://github.com/camptocamp/cesium/blob/c2c_patches/Source/
        #     Scene/UrlTemplateImageryProvider.js#L500
        return tileXYZ
    def testExtentionsReaderWriterGzipped(self):
        z = 10
        x = 1563
        y = 590
        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)

        # Regular file not gzip compressed
        ter = TerrainTile()
        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter.fromFile(
            'tests/data/%s_%s_%s_light_watermask.terrain' % (z, x, y),
            hasLighting=True, hasWatermask=True
        )

        # Same file but gzipped this time
        terG = TerrainTile()
        terG = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        terG.fromFile(
            'tests/data/%s_%s_%s_light_watermask.terrain.gz' % (z, x, y),
            hasLighting=True, hasWatermask=True, gzipped=True
        )

        # check indices
        self.assertEqual(len(terG.indices), len(ter.indices))
        self.assertEqual(terG.indices[0], ter.indices[0])

        # check edges
        self.assertEqual(len(terG.westI), len(ter.westI))
        self.assertEqual(len(terG.southI), len(ter.southI))
        self.assertEqual(len(terG.eastI), len(ter.eastI))
        self.assertEqual(len(terG.northI), len(ter.northI))

        self.assertEqual(terG.westI[0], ter.westI[0])
        self.assertEqual(terG.southI[0], ter.southI[0])
        self.assertEqual(terG.eastI[0], ter.eastI[0])
        self.assertEqual(terG.northI[0], ter.northI[0])

        self.assertEqual(len(terG.watermask), len(ter.watermask))
        self.assertEqual(len(terG.watermask[0]), len(ter.watermask[0]))
        # Water only -> 255
        self.assertEqual(terG.watermask[0][0], 255)
        # To gzipped file
        terG.toFile(self.tmpfile, gzipped=True)
Exemple #12
0
def createTerrainBasedTileJSON(params):
    baseUrls = getBaseUrls(params)
    with open('configs/terrain/layer.json') as f:
        terrainConfig = json.loads(f.read())

    # Delete unrelevant fields
    if 'extensions' in terrainConfig:
        del terrainConfig['extensions']
    # Overwrite
    terrainConfig['minzoom'] = params.minZoom
    terrainConfig['maxzoom'] = params.maxZoom
    terrainConfig['name'] = params.name
    terrainConfig['format'] = params.format
    terrainConfig['description'] = params.description
    terrainConfig['attribution'] = params.attribution
    terrainConfig['tiles'] = baseUrls

    geodetic = GlobalGeodetic(True)
    # Fix with empty ranges if we start with a biggeer min zoom
    for i in range(0, params.maxZoom + 1):
        if i < params.minZoom:
            terrainConfig['available'][i] = []
        # Max zoom is heigher than max terrain zoom level
        # In that case we include the full range within the bounds
        if i >= len(terrainConfig['available']):
            tileMinX, tileMinY = geodetic.LonLatToTile(
                params.bounds[0], params.bounds[1], i
            )
            tileMaxX, tileMaxY = geodetic.LonLatToTile(
                params.bounds[2], params.bounds[3], i
            )
            terrainConfig['available'].append(dict(
                startX=tileMinX,
                endX=tileMaxX,
                startY=tileMinY,
                endY=tileMaxY
            ))
    return json.dumps(terrainConfig)
Exemple #13
0
# import cStringIO
# import requests
# from quantized_mesh_tile.terrain import TerrainTile
# from quantized_mesh_tile.global_geodetic import GlobalGeodetic
# [z, x, y] = [14, 24297, 10735]
# geodetic = GlobalGeodetic(True)
# [west, south, east, north] = bounds = geodetic.TileBounds(x, y, z)
# url = 'http://assets.agi.com/stk-terrain/world/%s/%s/%s.terrain?v=1.16389.0' % (z, x, y)
# response = requests.get(url)
# content = cStringIO.StringIO(response.content)
# print west, south, east, north
# ter = TerrainTile(west=west, south=south, east=east, north=north)
# ter.fromStringIO(content)
# print ter.header
# print ter.getVerticesCoordinates()

# path = "9_533_383.terrain"
from quantized_mesh_tile.global_geodetic import GlobalGeodetic
from quantized_mesh_tile.terrain import TerrainTile
geodetic = GlobalGeodetic(True)
# [z, x, y] = [16,67465,51617]
[z, x, y] = [0, 0, 0]
[minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)
ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
print geodetic.TileBounds(0, 0, 0)
# ter.fromFile('ahn_416656.terrain')
ter.fromFile('51617.terrain')

print ter.getTrianglesCoordinates()
Exemple #14
0
def createModelBasedTileJSON(params):
    tilecount = 0
    t0 = time.time()
    baseUrls = getBaseUrls(params)

    engine = getEngine(params)
    metadata = sqlalchemy.MetaData(bind=engine, schema=params.dbSchema)
    metadata.reflect()
    try:
        table = metadata.tables[params.dbSchema + '.' + params.tableName]
    except KeyError:
        raise ValueError(
            'Table %s in schema %s could not be found' % (
                params.tableName, params.dbSchema))
    # We assume a pkey is defined by only one column for now.
    pkColumn = table.primary_key.columns.items()[0]
    pkColumnName = pkColumn[0].__str__()
    pkColumnType = pkColumn[1].type.__class__
    model = getOrmModel(pkColumnName, pkColumnType, params)
    # Bounds generated from DB
    try:
        conn = engine.connect()
        bounds = conn.execute(
            tableExtentLiteral(
                params.dbSchema, params.tableName, params.sridFrom)
        ).fetchone()
        strBounds = tuple(['{:2f}'.format(i) for i in bounds])
        # Tuple to list for json converison
        bounds = [b for b in bounds]
        logger.info('Bounds are %s, %s, %s, %s' % strBounds)
    except Exception as e:
        logger.error(
            'An error occured while determining the bounds', exc_info=True)
        raise Exception(e)
    finally:
        conn.close()

    # pre-calculate the maximazed buffers in degrees
    if params.pxTolerance:
        geodetic = GlobalGeodetic(True)
        buffers = {}
        for z in range(params.minZoom, params.maxZoom):
            buffers[z] = degreesToMeters(
                geodetic.Resolution(z) * float(params.pxTolerance)
            )

    try:
        session = scoped_session(sessionmaker(bind=engine))
        # We usually don't scan the last levels
        tiles = Tiles(
            bounds, params.minZoom, params.maxScanZoom, t0
        )
        tMeta = LayerMetadata(
            bounds=bounds, minzoom=params.minZoom,
            maxzoom=params.maxZoom, baseUrls=baseUrls,
            description=params.description, attribution=params.attribution,
            name=params.name
        )
        for tile in tiles:
            metaBuffer = 0.
            tilecount += 1
            if params.pxTolerance:
                xyz = tile[1]
                metaBuffer = buffers[xyz[2]]

            noGeom = scanLayer(
                tile, session, model, params.sridFrom,
                params.sridTo, metaBuffer, tilecount
            )
            if noGeom:
                tMeta.removeTile(noGeom[0], noGeom[1], noGeom[2])
    finally:
        session.close()
        engine.dispose()
    return (tMeta.toJSON(), tilecount)
    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
        '''
        x = 533
        y = 383
        z = 9
        geodetic = GlobalGeodetic(True)
        [minx, miny, maxx, maxy] = geodetic.TileBounds(x, y, z)

        ter = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter.fromFile('tests/data/%s_%s_%s.terrain' % (z, x, y))
        ter.toFile(self.tmpfile)
        self.assertIsInstance(ter.__repr__(), str)

        ter2 = TerrainTile(west=minx, south=miny, east=maxx, north=maxy)
        ter2.fromFile(self.tmpfile)
        self.assertIsInstance(ter2.__repr__(), str)

        # check headers
        self.assertGreater(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.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.assertGreater(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.assertGreater(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.assertGreater(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)

        self.assertEqual(ter2.getContentType(),
            'application/vnd.quantized-mesh')
Exemple #16
0
minWKT = 'POINT (%f %f)' % (MINX, MINY)
maxWKT = 'POINT (%f %f)' % (MAXX, MAXY)

minPoint = transformCoordinate(minWKT, 21781, 4326)
maxPoint = transformCoordinate(maxWKT, 21781, 4326)

MINX = minPoint.GetX()
MINY = minPoint.GetY()
MAXX = maxPoint.GetX()
MAXY = maxPoint.GetY()
print 'Extent :'
print[MINX, MINY, MAXX, MAXY]
MINZOOM = 3
MAXZOOM = 17

geodetic = GlobalGeodetic(True)
drv = ogr.GetDriverByName('ESRI Shapefile')
directory = '.tmp/'
extension = '.shp'

# Generate table with min max tile coordinates for all zoomlevels
for tz in range(MINZOOM, MAXZOOM + 1):
    filePathTarget = '%s%s%s' % (directory, tz, extension)
    tminx, tminy = geodetic.LonLatToTile(MINX, MINY, tz)
    tmaxx, tmaxy = geodetic.LonLatToTile(MAXX, MAXY, tz)

    dataSource = drv.CreateDataSource(filePathTarget)
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)
    layer = dataSource.CreateLayer('%s' % tz, srs, ogr.wkbPolygon)
    fieldKey = ogr.FieldDefn('Key', ogr.OFTString)