예제 #1
0
def runChild(procIndex, itemsQueue, resultsQueue, lasFolder, dbname, dbuser, dbpass, dbhost, dbport):
    connection, cursor = utils.connectToDB(dbname, dbuser, dbpass, dbhost, dbport) 
    kill_received = False
    while not kill_received:
        itemId = None
        try:
            # This call will patiently wait until new job is available
            itemId = itemsQueue.get()
        except:
            # if there is an error we will quit the generation
            kill_received = True
        if itemId == None:
            # If we receive a None job, it means we can stop this workers 
            # (all the create-image jobs are done)
            kill_received = True
        else:            
            logging.info('PROC%d: Getting minimum and maximum Z for item %d' % (procIndex,itemId))
            outputFile = 'temp_%03d.las' % itemId 
            try:
                (returnOk, vertices, minZ, maxZ, avgZ, numpoints) = GetItemLAS.create_cut_out(cursor, lasFolder, outputFile, itemId, BUFFER, CONCAVE)
            
                # We do not need the cutout
                if os.path.isfile(outputFile):
                    os.remove(outputFile)
            
                if returnOk:
                    logging.info('PROC%d: Updating DB minimum and maximum Z for item %d' % (procIndex,itemId))
                    utils.dbExecute(cursor, "UPDATE ITEM SET (min_z,max_z) = (%s,%s) WHERE item_id = %s", 
                                    [minZ, maxZ, itemId])
            except Exception, e:
                connection.rollback()
                logging.error('PROC%d: Can not update minimum and maximum Z for item %d' % (procIndex,itemId))
                logging.error(e)
            resultsQueue.put((procIndex, itemId))   
예제 #2
0
def updateOSGLocation(cursor, osgLocationId, xml_element, bgSRID, bgOffset):
    """ Update an OSG location by its osgLocationId"""
    (names, values) = parseLocation(cursor, xml_element, bgSRID, bgOffset)
    auxs = []
    for i in range(len(values)):
        auxs.append('%s')
    utils.dbExecute(cursor, 'UPDATE OSG_LOCATION SET (' + ','.join(names) + ') = (' + ','.join(auxs) + ') WHERE osg_location_id = %s', values + [osgLocationId,]) 
def clean_temp_table(args):

    drop_table_sql = "DROP TABLE IF EXISTS sites_geoms_temp"
    utils.dbExecute(cursor, drop_table_sql)

    msg = 'Removed table sites_geoms_temp (if existed).'
    #    print msg
    logger.info(msg)
예제 #4
0
def runChild(procIndex, itemsQueue, resultsQueue, lasFolder, dbname, dbuser,
             dbpass, dbhost, dbport):
    connection, cursor = utils.connectToDB(dbname, dbuser, dbpass, dbhost,
                                           dbport)
    kill_received = False
    while not kill_received:
        itemId = None
        try:
            # This call will patiently wait until new job is available
            itemId = itemsQueue.get()
        except:
            # if there is an error we will quit the generation
            kill_received = True
        if itemId == None:
            # If we receive a None job, it means we can stop this workers
            # (all the create-image jobs are done)
            kill_received = True
        else:
            logging.info('PROC%d: Getting minimum and maximum Z for item %d' %
                         (procIndex, itemId))
            outputFile = 'temp_%03d.las' % itemId
            try:
                (returnOk, vertices, minZ, maxZ, avgZ,
                 numpoints) = GetItemLAS.create_cut_out(
                     cursor, lasFolder, outputFile, itemId, BUFFER, CONCAVE)

                # We do not need the cutout
                if os.path.isfile(outputFile):
                    os.remove(outputFile)

                if returnOk:
                    logging.info(
                        'PROC%d: Updating DB minimum and maximum Z for item %d'
                        % (procIndex, itemId))
                    utils.dbExecute(
                        cursor,
                        "UPDATE ITEM SET (min_z,max_z) = (%s,%s) WHERE item_id = %s",
                        [minZ, maxZ, itemId])
            except Exception, e:
                connection.rollback()
                logging.error(
                    'PROC%d: Can not update minimum and maximum Z for item %d'
                    % (procIndex, itemId))
                logging.error(e)
            resultsQueue.put((procIndex, itemId))
def update_geom_col_type(cursor):
    """ function to update the initial geometries column type """
    num_items = utils.countElementsTable(cursor, 'item')
    msg = "Number of elements in item table: %s" % num_items
    logger.debug(msg)

    col_type = utils.typeColumnTable(cursor, 'geom', 'item')
    msg = "Current geom column type is %s." % col_type
    logger.debug(msg)

    if (num_items == 0) or (col_type == 'polygon'):
        # alter the geometry field type
        alter_type_sql = "ALTER TABLE item ALTER COLUMN geom TYPE geometry(MultiPolygon, " + str(
            utils.SRID) + ") USING geom:: geometry(MultiPolygon, " + str(
                utils.SRID) + ")"
        utils.dbExecute(cursor, alter_type_sql)

        msg = "Current geom column type is MultiPolygon, " + str(utils.SRID)
        logger.debug(msg)
예제 #6
0
def insertDB(cursor, tableName, names, values, returnColumn = None):
    """ Generic method to insert a row in a table"""
    try:
        auxs = []
        for i in range(len(names)):
            auxs.append('%s')
        insertStatement = 'INSERT INTO ' + tableName + ' (' + ','.join(names) +') VALUES (' + ','.join(auxs) + ')'
        insertValues = values[:]
        if returnColumn != None:
            insertStatement += ' RETURNING ' + returnColumn
        utils.dbExecute(cursor, insertStatement, insertValues)
        if returnColumn != None:
            return cursor.fetchone()[0]
        else:
            return None
    except Exception as e:
        cursor.connection.rollback()
        msg = 'Could not do insert in table ' + tableName + ' ' + str(names) + ' = ' + str(values)
        print msg
        logging.error(msg)
        return None
예제 #7
0
def deleteOSG(cursor, aoType, labelName = None, itemId = None, objectId = None, rawDataItemId = None):
    ''' Function to delete a and OSG item objects or an OSG label (and their related OSG location entries) '''
    if aoType == utils.AO_TYPE_OBJ:
        if (itemId == None) or (objectId == None):
            raise Exception ('Item Object operations require not null itemId and objectId')
        # extract osg_location_id of the object
        data,rows = utils.fetchDataFromDB(cursor, 'SELECT osg_location_id FROM OSG_ITEM_OBJECT WHERE item_id = %s AND object_number = %s', [itemId, objectId])
        utils.dbExecute(cursor, 'DELETE FROM OSG_ITEM_OBJECT WHERE item_id = %s AND object_number = %s', [itemId, objectId])
        # delete from OSG_LOCATION
        utils.dbExecute(cursor, 'DELETE FROM OSG_LOCATION WHERE osg_location_id = %s', [data[0][0],])
    elif aoType == utils.AO_TYPE_LAB:
        if labelName == None:
            raise Exception ('Label operations require not null labelName')
        # extract osg_location_id of the label
        data, rows = utils.fetchDataFromDB(cursor, 'SELECT osg_location_id FROM OSG_LABEL WHERE osg_label_name = %s', [labelName,])
        # delete from OSG_LABEL
        utils.dbExecute(cursor,'DELETE FROM OSG_LABEL WHERE osg_label_name = %s', [labelName,])
        # delete from OSG_LOCATION
        utils.dbExecute(cursor, 'DELETE FROM OSG_LOCATION WHERE osg_location_id = %s', [data[0][0],])
    else:
        raise Exception('Not possible to delete object ' + labelName)
def update_geometries(list_ids, new):
    """ function to update/insert the footprint geometries into the item table
        got a given list of IDs. the new flag indicated weather INSERT or UPDATE
        is needed """
    number = 1
    for (sid, ) in list_ids:

        msg = "Processing %s site from %s sites in total" % (number,
                                                             len(list_ids))
        #        print msg
        logger.debug(msg)

        fetch_geom_sql = "SELECT site_id AS item_id, ST_Multi(ST_Transform( ST_Union(geom), %s)) AS geom FROM sites_geoms_temp WHERE site_id = %s GROUP BY site_id"
        data, num = utils.fetchDataFromDB(cursor, fetch_geom_sql,
                                          [utils.SRID, sid], [], False)

        item_id = data[0][0]
        background = False
        geometry = data[0][1]

        if new:
            insert_geom_sql = "INSERT INTO item VALUES (%s,%s,%s)"
            utils.dbExecute(cursor, insert_geom_sql,
                            [item_id, background, geometry])
            # We also insert for the new item an entry in item_object
            utils.dbExecute(
                cursor,
                "INSERT INTO ITEM_OBJECT (item_id, object_number) VALUES (%s,%s)",
                [item_id, utils.ITEM_OBJECT_NUMBER_ITEM])
        else:
            update_geom_sql = "UPDATE item SET background=%s,geom=%s WHERE item_id=%s"
            utils.dbExecute(cursor, update_geom_sql,
                            [background, geometry, item_id])

        number = number + 1

    msg = "The geometries have been updated!"
    logger.debug(msg)
예제 #9
0
def run(opts):
    global logger
    # Define logger and start logging
    #logname = os.path.basename(opts.output) + '.log'
    logname = os.path.splitext(os.path.basename(__file__))[0] + '.log'
    logger = utils.start_logging(filename=logname, level=opts.log)
    localtime = utils.getCurrentTimeAsAscii()
    t0 = time.time()
    msg = os.path.basename(__file__) + ' script starts at %s.' % localtime
    print msg
    logger.info(msg)

    if not opts.output.endswith(".conf.xml"):
        logger.error('The output file must end with .conf.xml')
        raise IOError('The output file must end with .conf.xml')

    # Create python postgres connection
    global cursor
    connection, cursor = utils.connectToDB(opts.dbname, opts.dbuser,
                                           opts.dbpass, opts.dbhost,
                                           opts.dbport)

    # Check that provided background is in DB
    query = """
SELECT OSG_DATA_ITEM_PC_BACKGROUND.abs_path,srid 
FROM OSG_DATA_ITEM_PC_BACKGROUND JOIN RAW_DATA_ITEM USING (raw_data_item_id)"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    backGroundAbsPath = None
    backgroundSRID = None
    for (bgAbsPath, bgSRID) in rows:
        if opts.background == os.path.basename(bgAbsPath):
            backGroundAbsPath = bgAbsPath
            backgroundSRID = bgSRID
    if backGroundAbsPath == None:
        errorMsg = 'Background ' + opts.background + ' is not found'
        logger.error(errorMsg)
        raise Exception(errorMsg)

    # Get the root object: the OSG configuration
    rootObject = viewer_conf_api.osgRCconfiguration()
    # set version
    rootObject.set_version("0.2")

    # Add all the different XML of the active objects
    # (we add distinct since the boundings will share XMLs)
    query = """
SELECT DISTINCT xml_abs_path 
FROM OSG_DATA_ITEM ORDER BY xml_abs_path"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    for (xmlPath, ) in rows:
        if xmlPath.count(opts.osg) == 0:
            logger.error('Mismatch between given OSG data directory ' +
                         'and DB content')
        rootObject.add_objectLibrary(
            viewer_conf_api.objectLibrary(
                url=os.path.relpath(xmlPath, opts.osg)))

    # Add the object library with the boundings
    rootObject.add_objectLibrary(
        viewer_conf_api.objectLibrary(url=utils.BOUNDINGS_XML_RELATIVE))

    # Add the cameras that are in the DB
    cameras = viewer_conf_api.cameras()
    query = """
SELECT osg_camera_name, srid, x, y, z, h, p, r 
FROM OSG_CAMERA JOIN OSG_LOCATION USING (osg_location_id)"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    for (name, srid, x, y, z, h, p, r) in rows:
        if (srid is not None) and (srid == bgSRID):
            x, y, z = getOSGPosition(x, y, z, srid)
        else:
            x, y, z = getOSGPosition(x, y, z)
        cameras.add_camera(
            viewer_conf_api.camera(name=name, x=x, y=y, z=z, h=h, p=p, r=r))
    # Add Default cameras for the items that have no camera in the DB
    query = """
SELECT 
    item_id, ST_SRID(geom), st_x(st_centroid(geom)), st_y(st_centroid(geom)), min_z + ((max_z - min_z) / 2) 
FROM ITEM WHERE NOT background AND geom IS NOT null AND item_id NOT IN (
    SELECT DISTINCT item_id FROM OSG_ITEM_CAMERA
) ORDER BY item_id"""
    rows, numitems = utils.fetchDataFromDB(cursor, query)
    for (itemId, srid, x, y, z) in rows:
        # only call getOSGPosition if [x,y,z] are not None
        # should item_id = -1 be added?
        if all(position is not None for position in [x, y, z]) and itemId > 0:
            if (srid is not None) and (srid == bgSRID):
                x, y, z = getOSGPosition(x, y, z, srid)
            else:
                x, y, z = getOSGPosition(x, y, z)
            cameras.add_camera(
                viewer_conf_api.camera(name=utils.DEFAULT_CAMERA_PREFIX +
                                       str(itemId),
                                       x=x,
                                       y=y,
                                       z=z))
    rootObject.set_cameras(cameras)

    # Add the XML content of the preferences
    rootObject.set_preferences(viewer_conf_api.parseString(DEFAULT_PREFENCES))

    attributes = viewer_conf_api.attributes()
    # Use generic method to fill all properties.
    # We need the name in the XML, the column name in the DB and
    # the table name in the DB
    for property in utils.ATTRIBUTES_ORDER:
        (cName, tName) = utils.ATTRIBUTES[property]
        elements = getattr(viewer_conf_api, property + 's')()
        # We need to call the columns and tables with extra "" because
        # they were created from the Access DB
        #        utils.dbExecute(cursor, 'SELECT "' + cName + '" FROM "' + tName + '"')
        utils.dbExecute(cursor, 'SELECT ' + cName + ' FROM ' + tName)

        for (element, ) in cursor:
            getattr(elements,
                    'add_' + property)(getattr(viewer_conf_api,
                                               property)(name=element))
        getattr(attributes, 'set_' + property + 's')(elements)
    rootObject.set_attributes(attributes)
    # Add all the static objects, i.e. the OSG from the background

    # Add the static object for the background
    staticObjects = viewer_conf_api.staticObjects()
    staticObjects.add_staticObject(
        viewer_conf_api.staticObject(url=os.path.relpath(
            glob.glob(backGroundAbsPath + '/' + utils.OSG_DATA_PREFIX +
                      '.osgb')[0], opts.osg)))
    # Add hardcode DOME
    staticObjects.add_staticObject(
        viewer_conf_api.staticObject(url=utils.DOMES_OSG_RELATIVE))
    rootObject.set_staticObjects(staticObjects)

    # Add the 5 different layers of active objects
    activeObjects = viewer_conf_api.activeObjects()
    # First we add points, meshes and pcitures which are related to
    # the active_objects_sites
    layersData = [('points', 'OSG_DATA_ITEM_PC_SITE', utils.AO_TYPE_PC),
                  ('photos', 'OSG_DATA_ITEM_PICTURE', utils.AO_TYPE_PIC),
                  ('meshes', 'OSG_DATA_ITEM_MESH', utils.AO_TYPE_MESH)]

    for (layerName, tableName, inType) in layersData:
        layer = viewer_conf_api.layer(name=layerName)

        query = """
SELECT item_id, raw_data_item_id, OSG_LOCATION.srid, x, y, z, xs, ys, zs, h, p, r, cast_shadow 
FROM """ + tableName + """ JOIN OSG_DATA_ITEM USING (osg_data_item_id) 
                           JOIN OSG_LOCATION  USING (osg_location_id) 
                           JOIN RAW_DATA_ITEM USING (raw_data_item_id) 
ORDER BY item_id"""
        rows, numitems = utils.fetchDataFromDB(cursor, query)
        for (itemId, rawDataItemId, srid, x, y, z, xs, ys, zs, h, p, r,
             castShadow) in rows:
            # only call getOSGPosition if [x,y,z] are not None
            if all(position is not None for position in [x, y, z]):
                if (srid is not None) and (srid == bgSRID):
                    x, y, z = getOSGPosition(x, y, z, srid)
                else:
                    x, y, z = getOSGPosition(x, y, z)
            uniqueName = utils.codeOSGActiveObjectUniqueName(
                cursor, inType, rawDataItemId)
            activeObject = viewer_conf_api.activeObject(prototype=uniqueName,
                                                        uniqueName=uniqueName)
            setting = viewer_conf_api.setting(
                x=x,
                y=y,
                z=z,
                xs=xs,
                ys=ys,
                zs=zs,
                h=h,
                p=p,
                r=r,
                castShadow=(1 if castShadow else 0))
            activeObject.set_setting(setting)
            layer.add_activeObject(activeObject)
        activeObjects.add_layer(layer)

    # Add the boundings
    layer = viewer_conf_api.layer(name='boundings')
    # We first add the boundings that are currently in the DB
    query = """
SELECT item_id, object_number, x, y, z, xs, ys, zs, h, p, r, OSG_LOCATION.cast_shadow, srid 
FROM OSG_ITEM_OBJECT JOIN OSG_LOCATION USING (osg_location_id) 
ORDER BY item_id,object_number"""
    osgItemObjects, numOsgItemObjects = utils.fetchDataFromDB(cursor, query)
    # osgItemObjects is (itemId, objectNumber, x, y, z, xs, ys, zs, h, p, r, castShadow, srid)
    # Now we add Default OSG data items for the objects that are not in OSG_ITEM_OBJECT table
    query = """
SELECT item_id,object_number 
FROM item_object 
WHERE (item_id,object_number) NOT IN (SELECT item_id,object_number FROM OSG_ITEM_OBJECT)
ORDER BY item_id,object_number"""
    objects, num_objects = utils.fetchDataFromDB(cursor, query)
    for (itemId, objectNumber) in objects:
        srid = None
        (x, y, z) = (0, 0, 0)
        (xs, ys, zs) = (1, 1, 1)
        query = """
SELECT ST_SRID(geom), st_x(st_centroid(geom)), st_y(st_centroid(geom)), min_z + ((max_z - min_z) / 2), 
       st_xmax(geom)-st_xmin(geom) as dx, st_ymax(geom)-st_ymin(geom) as dy, (max_z - min_z) as dz 
FROM ITEM 
WHERE item_id = %s and geom is not %s"""
        queryArgs = [itemId, None]
        footprints, num_footprints = utils.fetchDataFromDB(
            cursor, query, queryArgs)
        if num_footprints:
            (srid, x, y, z, xs, ys, zs) = footprints[0]
            if xs == 0: xs = 1
            if ys == 0: ys = 1
            if zs == 0: zs = 1
        osgItemObjects.append(
            [itemId, objectNumber, x, y, z, xs, ys, zs, 0, 0, 0, False, srid])
    # Now let's add them to the XML
    for (itemId, objectNumber, x, y, z, xs, ys, zs, h, p, r, castShadow,
         srid) in osgItemObjects:
        # only call getOSGPosition if [x,y,z] are not None
        if all(position is not None for position in [x, y, z]) and itemId > 0:
            if (srid is not None) and (srid == bgSRID):
                x, y, z = getOSGPosition(x, y, z, srid)
            else:
                x, y, z = getOSGPosition(x, y, z)
            uniqueName = utils.codeOSGActiveObjectUniqueName(
                cursor,
                utils.AO_TYPE_OBJ,
                itemId=itemId,
                objectId=objectNumber)
            proto = "Bounding Box"
            activeObject = viewer_conf_api.activeObject(prototype=proto,
                                                        uniqueName=uniqueName)
            setting = viewer_conf_api.setting(
                x=x,
                y=y,
                z=z,
                xs=xs,
                ys=ys,
                zs=zs,
                h=h,
                p=p,
                r=r,
                castShadow=(1 if castShadow else 0))
            activeObject.set_setting(setting)
            layer.add_activeObject(activeObject)
    activeObjects.add_layer(layer)

    # Add the labels
    layer = viewer_conf_api.layer(name='labels')
    utils.dbExecute(
        cursor, 'SELECT osg_label_name, text, red, green, blue, ' +
        'rotate_screen, outline, font, srid, x, y, z, xs, ys, zs, h, ' +
        'p, r, cast_shadow FROM OSG_LABEL INNER JOIN ' +
        'OSG_LOCATION ON OSG_LABEL.osg_location_id=' +
        'OSG_LOCATION.osg_location_id')
    rows = cursor.fetchall()
    for (name, text, red, green, blue, rotatescreen, outline, font, srid, x, y,
         z, xs, ys, zs, h, p, r, castShadow) in rows:
        proto = "labelPrototype"
        uniqueName = utils.codeOSGActiveObjectUniqueName(cursor,
                                                         utils.AO_TYPE_LAB,
                                                         labelName=name)
        if (srid is not None) and (srid == bgSRID):
            x, y, z = getOSGPosition(x, y, z, srid)
        else:
            x, y, z = getOSGPosition(x, y, z)
        activeObject = viewer_conf_api.activeObject(
            prototype=proto,
            uniqueName=uniqueName,
            labelText=text,
            labelColorRed=red,
            labelColorGreen=green,
            labelColorBlue=blue,
            labelRotateScreen=rotatescreen,
            outline=outline,
            Font=font)
        setting = viewer_conf_api.setting(x=x,
                                          y=y,
                                          z=z,
                                          xs=xs,
                                          ys=ys,
                                          zs=zs,
                                          h=h,
                                          p=p,
                                          r=r,
                                          castShadow=(1 if castShadow else 0))
        activeObject.set_setting(setting)
        layer.add_activeObject(activeObject)
    activeObjects.add_layer(layer)

    rootObject.set_activeObjects(activeObjects)

    # Create the XML
    rootObject.export(open(opts.output, 'w'), 0)

    elapsed_time = time.time() - t0
    msg = 'Finished. Total elapsed time: %.02f seconds. See %s' % (
        elapsed_time, logname)
    print(msg)
    logger.info(msg)
예제 #10
0
def deleteCameras(cursor):
    utils.dbExecute(cursor, 'DELETE FROM OSG_ITEM_CAMERA CASCADE')
    utils.dbExecute(cursor, 'DELETE FROM OSG_CAMERA CASCADE')
예제 #11
0
def run(args):
    logname = os.path.basename(args.input) + '.log'
    utils.start_logging(filename=logname, level=args.log)

    localtime = utils.getCurrentTimeAsAscii()
    t0 = time.time()
    msg = os.path.basename(__file__) + ' script starts at %s.' % localtime
    print msg
    logging.info(msg)

    logging.info('Checking validity of SQL file')
    # Check that beginning of the file does not contain a create database statement
    if os.popen('head -500 ' + args.input +
                ' | grep "CREATE DATABASE"').read().count("CREATE DATABASE"):
        msg = "You must remove CREATE DATABASE statement from the SQL file"
        print msg
        logging.error(msg)
        return
    # Check that ther are not defaults in TIMESTAMPS that would cause errors
    if os.popen('grep "TIMESTAMP DEFAULT" ' +
                args.input).read().count("TIMESTAMP DEFAULT"):
        msg = "You must remove any DEFAULT value of any TIMESTAMP column"
        print msg
        logging.error(msg)
        return
    # Check that ther are not index creations
    if os.popen('grep "INDEX" ' + args.input).read().count("INDEX"):
        msg = "You must remove any INDEX creation"
        print msg
        logging.error(msg)
        return
    if os.popen("""grep '"' """ + args.input).read().count('"'):
        msg = 'You must remove any double quote (")'
        print msg
        logging.error(msg)
        dangerousWords = []
        for line in open(args.input, 'r').read().split('\n'):
            if not line.startswith('--'):
                for word in line.split():
                    if word.count('"') == 1:
                        dangerousWords.append(word)
        if len(dangerousWords):
            msg = 'Also, before removing all ", take care of table and column names that would be incorrect when removing ".\n If any of the following is a table or column name please be sure that it does not have white spaces: ' + ','.join(
                dangerousWords)
            print msg
            logging.error(msg)
            return
        return

    # Establish connection with DB
    connection, cursor = utils.connectToDB(args.dbname, args.dbuser,
                                           args.dbpass, args.dbhost,
                                           args.dbport)

    # First we drop all tables in attribute
    logging.info("Dropping all previous attribute tables")
    for tablename in ('tbl2_site_relation', 'tbl2_object_depression',
                      'tbl2_object_decoration', 'tbl2_object_material',
                      'tbl1_object', 'tbl1_site'):
        cursor.execute('DROP TABLE IF EXISTS ' + tablename + ' CASCADE')
        connection.commit()
    # First we need to drop the previous constraints in tbl1_site and tbl1_object


#    logging.info("Dropping constraints in tbl1_site and tbl1_object tables")
#    for tablename in ('tbl1_site','tbl1_object'):
#        cursor.execute("select constraint_name from information_schema.table_constraints where table_name=%s", [tablename,])
#        constraintNames = cursor.fetchall()
#        for (constraintName, ) in constraintNames:
#            cursor.execute('ALTER TABLE ' + tablename + ' DROP CONSTRAINT %s CASCADE', [constraintName,])
#            connection.commit()

# This script will drop all attribute tables and create them again
    logging.info('Executing SQL file %s' % args.input)
    #utils.load_sql_file(cursor, args.input)
    connParams = utils.postgresConnectString(args.dbname, args.dbuser,
                                             args.dbpass, args.dbhost,
                                             args.dbport, True)
    logFile = os.path.basename(args.input) + '.log'
    command = 'psql ' + connParams + ' -f ' + args.input + ' &> ' + logFile
    logging.info(command)
    os.system(command)

    #Check errors
    if os.popen('cat ' + logFile + ' | grep ERROR').read().count("ERROR"):
        msg = 'There was some errors in the data loading. Please see log ' + logFile
        print msg
        logging.error(msg)
        return

    # Set select permissions to all new tables
    logging.info('Granting select permissions to all tables')
    cursor.execute(
        "select tablename from  pg_tables where schemaname = 'public'")
    tablesNames = cursor.fetchall()
    for (tableName, ) in tablesNames:
        cursor.execute('GRANT SELECT ON ' + tableName + ' TO public')

    # We check that the added Sites and Objects are also in Data Management part of the DB
    # All sites in tbl1_site must have an entry in ITEM
    logging.info(
        'Adding items in attribute data that are missing in ITEM table')
    query = 'SELECT site_id from tbl1_site WHERE site_id NOT IN (SELECT item_id FROM item)'
    sites, num_sites = utils.fetchDataFromDB(cursor, query)
    for (siteId, ) in sites:
        utils.dbExecute(
            cursor, "INSERT INTO ITEM (item_id, background) VALUES (%s,%s)",
            [siteId, False])
        utils.dbExecute(
            cursor,
            "INSERT INTO ITEM_OBJECT (item_id, object_number) VALUES (%s,%s)",
            [siteId, utils.ITEM_OBJECT_NUMBER_ITEM])

    # All objects in tbl1_object must also be in ITEM_OBJECT
    logging.info(
        'Adding items objects in attribute data that are missing in ITEM_OBJECT table'
    )
    query = 'SELECT site_id,object_id from tbl1_object WHERE (site_id,object_id) NOT IN (SELECT item_id,object_number FROM item_object)'
    sites_objects, num_sites_objects = utils.fetchDataFromDB(cursor, query)
    for (siteId, objectId) in sites_objects:
        utils.dbExecute(
            cursor,
            "INSERT INTO ITEM_OBJECT (item_id, object_number) VALUES (%s,%s)",
            [siteId, objectId])

    #We add again the constraints that link management and attribute data
    logging.info('Adding constraints between attribute and items')
    cursor.execute("""ALTER TABLE tbl1_object
ADD FOREIGN KEY (site_id, object_id)
REFERENCES ITEM_OBJECT (item_id, object_number)
ON UPDATE NO ACTION
ON DELETE NO ACTION""")
    connection.commit()
    cursor.execute("""ALTER TABLE tbl1_site
ADD FOREIGN KEY (site_id)
REFERENCES ITEM (item_id)
ON UPDATE NO ACTION
ON DELETE NO ACTION""")
    connection.commit()

    elapsed_time = time.time() - t0
    msg = 'Finished. Total elapsed time: %.02f seconds. See %s' % (
        elapsed_time, logname)
    print(msg)
    logging.info(msg)
예제 #12
0
def run(opts):
    global logger
    # Define logger and start logging
    #logname = os.path.basename(opts.output) + '.log'
    logname = os.path.splitext(os.path.basename(__file__))[0] + '.log'
    logger = utils.start_logging(filename=logname, level=opts.log)
    localtime = utils.getCurrentTimeAsAscii()
    t0 = time.time()
    msg = os.path.basename(__file__) + ' script starts at %s.' % localtime
    print msg
    logger.info(msg)

    if not opts.output.endswith(".conf.xml"):
        logger.error('The output file must end with .conf.xml')
        raise IOError('The output file must end with .conf.xml')

    # Create python postgres connection
    global cursor
    connection, cursor = utils.connectToDB(opts.dbname, opts.dbuser,
                                           opts.dbpass, opts.dbhost,
                                           opts.dbport)
    
    # Check that provided background is in DB
    query = """
SELECT OSG_DATA_ITEM_PC_BACKGROUND.abs_path,srid 
FROM OSG_DATA_ITEM_PC_BACKGROUND JOIN RAW_DATA_ITEM USING (raw_data_item_id)"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    backGroundAbsPath = None
    backgroundSRID = None
    for (bgAbsPath,bgSRID) in rows:
        if opts.background == os.path.basename(bgAbsPath):
            backGroundAbsPath = bgAbsPath
            backgroundSRID = bgSRID
    if backGroundAbsPath == None:
        errorMsg = 'Background ' + opts.background + ' is not found'
        logger.error(errorMsg)
        raise Exception(errorMsg)
    
    # Get the root object: the OSG configuration
    rootObject = viewer_conf_api.osgRCconfiguration()
    # set version
    rootObject.set_version("0.2")

    # Add all the different XML of the active objects
    # (we add distinct since the boundings will share XMLs)
    query = """
SELECT DISTINCT xml_abs_path 
FROM OSG_DATA_ITEM ORDER BY xml_abs_path"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    for (xmlPath,) in rows:
        if xmlPath.count(opts.osg) == 0:
            logger.error('Mismatch between given OSG data directory ' +
                         'and DB content')
        rootObject.add_objectLibrary(viewer_conf_api.objectLibrary
                                     (url=os.path.relpath(xmlPath, opts.osg)))

    # Add the object library with the boundings
    rootObject.add_objectLibrary(viewer_conf_api.objectLibrary
                                 (url=utils.BOUNDINGS_XML_RELATIVE))

    # Add the cameras that are in the DB
    cameras = viewer_conf_api.cameras()
    query = """
SELECT osg_camera_name, srid, x, y, z, h, p, r 
FROM OSG_CAMERA JOIN OSG_LOCATION USING (osg_location_id)"""
    rows, num_rows = utils.fetchDataFromDB(cursor, query)
    for (name, srid, x, y, z, h, p, r) in rows:
        if (srid is not None) and (srid == bgSRID):
            x, y, z = getOSGPosition(x, y, z, srid)
        else:
            x, y, z = getOSGPosition(x, y, z)
        cameras.add_camera(viewer_conf_api.camera
                           (name=name, x=x, y=y, z=z, h=h, p=p, r=r))
    # Add Default cameras for the items that have no camera in the DB
    query = """
SELECT 
    item_id, ST_SRID(geom), st_x(st_centroid(geom)), st_y(st_centroid(geom)), min_z + ((max_z - min_z) / 2) 
FROM ITEM WHERE NOT background AND geom IS NOT null AND item_id NOT IN (
    SELECT DISTINCT item_id FROM OSG_ITEM_CAMERA
) ORDER BY item_id"""
    rows, numitems = utils.fetchDataFromDB(cursor, query)
    for (itemId, srid, x, y, z) in rows:
        # only call getOSGPosition if [x,y,z] are not None
        # should item_id = -1 be added? 
        if all(position is not None for position in [x,y,z]) and itemId>0:
            if (srid is not None) and (srid == bgSRID):
                x, y, z = getOSGPosition(x, y, z, srid)
            else:
                x, y, z = getOSGPosition(x, y, z)
            cameras.add_camera(viewer_conf_api.camera
                               (name=utils.DEFAULT_CAMERA_PREFIX + str(itemId),
                                x=x, y=y, z=z))
    rootObject.set_cameras(cameras)
    
    # Add the XML content of the preferences
    rootObject.set_preferences(viewer_conf_api.parseString(DEFAULT_PREFENCES))
    
    attributes = viewer_conf_api.attributes()
    # Use generic method to fill all properties.
    # We need the name in the XML, the column name in the DB and
    # the table name in the DB
    for property in utils.ATTRIBUTES_ORDER:
        (cName, tName) = utils.ATTRIBUTES[property]
        elements = getattr(viewer_conf_api, property + 's')()
        # We need to call the columns and tables with extra "" because
        # they were created from the Access DB
#        utils.dbExecute(cursor, 'SELECT "' + cName + '" FROM "' + tName + '"')
        utils.dbExecute(cursor, 'SELECT ' + cName + ' FROM ' + tName)

        for (element,) in cursor:
            getattr(elements, 'add_' + property)(getattr(
                viewer_conf_api, property)(name=element))
        getattr(attributes, 'set_' + property + 's')(elements)
    rootObject.set_attributes(attributes)
    # Add all the static objects, i.e. the OSG from the background

    # Add the static object for the background
    staticObjects = viewer_conf_api.staticObjects()
    staticObjects.add_staticObject(viewer_conf_api.staticObject
                                           (url=os.path.relpath(
                                           glob.glob(backGroundAbsPath + '/' + utils.OSG_DATA_PREFIX + '.osgb')[0],
                                           opts.osg)))
    # Add hardcode DOME
    staticObjects.add_staticObject(viewer_conf_api.staticObject
                                   (url=utils.DOMES_OSG_RELATIVE))
    rootObject.set_staticObjects(staticObjects)

    # Add the 5 different layers of active objects
    activeObjects = viewer_conf_api.activeObjects()
    # First we add points, meshes and pcitures which are related to
    # the active_objects_sites
    layersData = [('points', 'OSG_DATA_ITEM_PC_SITE', utils.AO_TYPE_PC),
                  ('photos', 'OSG_DATA_ITEM_PICTURE', utils.AO_TYPE_PIC),
                  ('meshes', 'OSG_DATA_ITEM_MESH', utils.AO_TYPE_MESH)]
    
    for (layerName, tableName, inType) in layersData:
        layer = viewer_conf_api.layer(name=layerName)
        
        query = """
SELECT item_id, raw_data_item_id, OSG_LOCATION.srid, x, y, z, xs, ys, zs, h, p, r, cast_shadow 
FROM """ + tableName + """ JOIN OSG_DATA_ITEM USING (osg_data_item_id) 
                           JOIN OSG_LOCATION  USING (osg_location_id) 
                           JOIN RAW_DATA_ITEM USING (raw_data_item_id) 
ORDER BY item_id"""
        rows, numitems = utils.fetchDataFromDB(cursor, query)
        for (itemId, rawDataItemId, srid, x, y, z, xs, ys, zs, h, p, r, castShadow) in rows:
            # only call getOSGPosition if [x,y,z] are not None            
            if all(position is not None for position in [x,y,z]):
                if (srid is not None) and (srid == bgSRID):
                    x, y, z  = getOSGPosition(x, y, z, srid)
                else:
                    x, y, z = getOSGPosition(x, y, z)
            uniqueName = utils.codeOSGActiveObjectUniqueName(cursor, inType, rawDataItemId)
            activeObject = viewer_conf_api.activeObject(prototype=uniqueName,
                                                        uniqueName=uniqueName)
            setting = viewer_conf_api.setting(
                x=x, y=y, z=z, xs=xs, ys=ys, zs=zs, h=h, p=p, r=r,
                castShadow=(1 if castShadow else 0))
            activeObject.set_setting(setting)
            layer.add_activeObject(activeObject)
        activeObjects.add_layer(layer)

    # Add the boundings
    layer = viewer_conf_api.layer(name='boundings')
    # We first add the boundings that are currently in the DB
    query = """
SELECT item_id, object_number, x, y, z, xs, ys, zs, h, p, r, OSG_LOCATION.cast_shadow, srid 
FROM OSG_ITEM_OBJECT JOIN OSG_LOCATION USING (osg_location_id) 
ORDER BY item_id,object_number"""
    osgItemObjects, numOsgItemObjects = utils.fetchDataFromDB(cursor, query)
    # osgItemObjects is (itemId, objectNumber, x, y, z, xs, ys, zs, h, p, r, castShadow, srid)
    # Now we add Default OSG data items for the objects that are not in OSG_ITEM_OBJECT table
    query = """
SELECT item_id,object_number 
FROM item_object 
WHERE (item_id,object_number) NOT IN (SELECT item_id,object_number FROM OSG_ITEM_OBJECT)
ORDER BY item_id,object_number"""
    objects, num_objects = utils.fetchDataFromDB(cursor, query)
    for (itemId, objectNumber) in objects:
        srid = None
        (x,y,z) = (0,0,0)
        (xs,ys,zs) = (1,1,1)
        query = """
SELECT ST_SRID(geom), st_x(st_centroid(geom)), st_y(st_centroid(geom)), min_z + ((max_z - min_z) / 2), 
       st_xmax(geom)-st_xmin(geom) as dx, st_ymax(geom)-st_ymin(geom) as dy, (max_z - min_z) as dz 
FROM ITEM 
WHERE item_id = %s and geom is not %s"""
        queryArgs = [itemId, None]
        footprints, num_footprints = utils.fetchDataFromDB(cursor, query, queryArgs)
        if num_footprints:
            (srid, x, y, z, xs, ys, zs) = footprints[0]
            if xs == 0: xs = 1
            if ys == 0: ys = 1
            if zs == 0: zs = 1
        osgItemObjects.append([itemId, objectNumber, x, y, z, xs, ys, zs, 0, 0, 0, False, srid])
    # Now let's add them to the XML
    for (itemId, objectNumber, x, y, z, xs, ys, zs, h, p, r, castShadow, srid) in osgItemObjects:
        # only call getOSGPosition if [x,y,z] are not None
        if all(position is not None for position in [x,y,z]) and itemId>0:        
            if (srid is not None) and (srid == bgSRID):
                x, y, z  = getOSGPosition(x, y, z, srid)
            else:
                x, y, z = getOSGPosition(x, y, z)                
            uniqueName = utils.codeOSGActiveObjectUniqueName(cursor, utils.AO_TYPE_OBJ, itemId = itemId, objectId = objectNumber)
            proto = "Bounding Box"
            activeObject = viewer_conf_api.activeObject(prototype=proto,
                                                        uniqueName=uniqueName)
            setting = viewer_conf_api.setting(
                x=x, y=y, z=z, xs=xs, ys=ys, zs=zs, h=h, p=p, r=r,
            castShadow=(1 if castShadow else 0))
            activeObject.set_setting(setting)
            layer.add_activeObject(activeObject)
    activeObjects.add_layer(layer)

    # Add the labels
    layer = viewer_conf_api.layer(name='labels')
    utils.dbExecute(cursor, 'SELECT osg_label_name, text, red, green, blue, ' +
                    'rotate_screen, outline, font, srid, x, y, z, xs, ys, zs, h, ' +
                    'p, r, cast_shadow FROM OSG_LABEL INNER JOIN ' +
                    'OSG_LOCATION ON OSG_LABEL.osg_location_id=' +
                    'OSG_LOCATION.osg_location_id')
    rows = cursor.fetchall()
    for (name, text, red, green, blue, rotatescreen, outline, font, srid, x, y, z, xs, ys, zs, h, p, r, castShadow) in rows:
        proto = "labelPrototype"
        uniqueName = utils.codeOSGActiveObjectUniqueName(cursor, utils.AO_TYPE_LAB, labelName = name)
        if (srid is not None) and (srid == bgSRID):
            x, y, z = getOSGPosition(x, y, z, srid)
        else:
            x, y, z = getOSGPosition(x, y, z)
        activeObject = viewer_conf_api.activeObject(
            prototype=proto, uniqueName=uniqueName, labelText=text,
            labelColorRed=red, labelColorGreen=green, labelColorBlue=blue,
            labelRotateScreen=rotatescreen, outline=outline, Font=font)
        setting = viewer_conf_api.setting(
            x=x, y=y, z=z, xs=xs, ys=ys, zs=zs, h=h, p=p, r=r,
            castShadow=(1 if castShadow else 0))
        activeObject.set_setting(setting)
        layer.add_activeObject(activeObject)
    activeObjects.add_layer(layer)

    rootObject.set_activeObjects(activeObjects)

    # Create the XML
    rootObject.export(open(opts.output, 'w'), 0)
    
    elapsed_time = time.time() - t0
    msg = 'Finished. Total elapsed time: %.02f seconds. See %s' % (elapsed_time, logname)
    print(msg)
    logger.info(msg)