Example #1
0
def createValidationResult(requestParams, gcps, gcpstargetSrs, LOGGER):
    """ Function creates a process image and creates a temporary wms.

    :type requestParams: dict
    :type gcps: List.<gdal.GCP>
    :type georefTargetSRS: int
    :type LOGGER: logging.LOGGER
    :return: str
    :raise: vkviewer.python.georef.georeferenceexceptions.ParameterException """
    LOGGER.debug('Process georeference result ...')
    tmpFile = os.path.join(GEOREFERENCE_MAPFILE_FOLDER,requestParams['mapObj'].apsdateiname+"::"+str(uuid.uuid4())+".tif")
    destPath = None
    if requestParams['georeference']['algorithm'] == 'affine':
        destPath = rectifyImageAffine(requestParams['mapObj'].originalimage, tmpFile,
                [], gcps, gcpstargetSrs, LOGGER)
    elif requestParams['georeference']['algorithm'] == 'polynom':
        destPath = rectifyPolynomWithVRT(requestParams['mapObj'].originalimage, tmpFile, gcps, gcpstargetSrs, LOGGER, TMP_DIR)
    elif requestParams['georeference']['algorithm'] == 'tps':
        destPath = rectifyTpsWithVrt(requestParams['mapObj'].originalimage, tmpFile, gcps, gcpstargetSrs, LOGGER, TMP_DIR)
    else:
        raise ParameterException('Transformation algorithm - %s - is not supported yet.'%requestParams['georeference']['algorithm'])

    LOGGER.debug('Create temporary mapfile ...')
    wmsUrl = createMapfile(requestParams['mapObj'].apsdateiname, destPath, gcpstargetSrs, GEOREFERENCE_MAPFILE_TEMPLATE, GEOREFERENCE_MAPFILE_FOLDER, GEOREFERENCE_MAPFILE_DEFAULT_PARAMS)

    LOGGER.debug('Calculate extent ...')
    dataset = gdal.Open(destPath, GA_ReadOnly)
    extent = getBoundsFromDataset(dataset)
    LOGGER.debug('Deliver results.')
    return {'wmsUrl':wmsUrl,'layerId':requestParams['mapObj'].apsdateiname, 'extent': extent}
def getByObjectId(request):
    """ The function returns the process process information for a given objectid. Supports GET/POST requests
        
        :type request: pyramid.request
        :return: dict
        :raise: HTTPBadRequest
        :raise: HTTPInternalServerError """
        
    def getObjectId(request):
        """ Parse the object id from the request.
        
        :type request: pyramid.request
        :return: int """
        objectid = None
        if request.method == 'POST' and 'objectid' in request.json_body:
            objectid = request.json_body['objectid']
        if request.method == 'GET' and 'objectid' in request.params:
            objectid = request.params['objectid']
            
        if objectid is None:
            return None
        else:
            namespace, id = objectid.rsplit('-', 1)
            
            # check if it is the correct namespace
            if namespace == OAI_ID_PATTERN.rsplit('-', 1)[0]:
                return int(id)
        return None
    
    try:
        objectid = getObjectId(request)
        if objectid is None:
            raise ParameterException("Wrong or missing objectid.")

        LOGGER.debug('Create response for objectid - %s ...'%objectid)
        return generateGeoreferenceProcessForMapObj(objectid, request, LOGGER)
    except ParameterException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(ERROR_MSG)
def setProcessToIsValide(request):
    LOGGER.info(
        'Request - Set admin evaluation of georeference process to isvalide ....'
    )
    try:
        # remove georeference process
        if 'georeferenceid' in request.params:
            georeferenceid = request.params['georeferenceid']
            comment = '' if 'comment' not in request.params else request.params[
                'comment']

            # check if georeference id exist
            georeferenceprocess = Georeferenzierungsprozess.by_id(
                georeferenceid, request.db)
            if georeferenceprocess:
                newJob = createNewAdminJob(georeferenceprocess, 'isvalide',
                                           request.params['userid'], comment)
                request.db.add(newJob)

            return {
                'message': 'The georeference process has been set to isvalide.'
            }
        else:
            raise Exception('Missing parameter (georeferenceid) ...')
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        return HTTPBadRequest(GENERAL_ERROR_MESSAGE)
def createValidationResult(requestParams, gcps, gcpstargetSrs, LOGGER):
    """ Function creates a process image and creates a temporary wms.

    :type requestParams: dict
    :type gcps: List.<gdal.GCP>
    :type georefTargetSRS: int
    :type LOGGER: logging.LOGGER
    :return: str
    :raise: vkviewer.python.georef.georeferenceexceptions.ParameterException """
    LOGGER.debug("Process georeference result ...")
    tmpFile = os.path.join(
        GEOREFERENCE_MAPFILE_FOLDER, requestParams["mapObj"].apsdateiname + "::" + str(uuid.uuid4()) + ".tif"
    )
    destPath = None
    if requestParams["georeference"]["algorithm"] == "affine":
        destPath = rectifyImageAffine(requestParams["mapObj"].originalimage, tmpFile, [], gcps, gcpstargetSrs, LOGGER)
    elif requestParams["georeference"]["algorithm"] == "polynom":
        destPath = rectifyPolynomWithVRT(
            requestParams["mapObj"].originalimage, tmpFile, gcps, gcpstargetSrs, LOGGER, TMP_DIR
        )
    elif requestParams["georeference"]["algorithm"] == "tps":
        destPath = rectifyTpsWithVrt(
            requestParams["mapObj"].originalimage, tmpFile, gcps, gcpstargetSrs, LOGGER, TMP_DIR
        )
    else:
        raise ParameterException(
            "Transformation algorithm - %s - is not supported yet." % requestParams["georeference"]["algorithm"]
        )

    LOGGER.debug("Create temporary mapfile ...")
    wmsUrl = createMapfile(
        requestParams["mapObj"].apsdateiname,
        destPath,
        gcpstargetSrs,
        GEOREFERENCE_MAPFILE_TEMPLATE,
        GEOREFERENCE_MAPFILE_FOLDER,
        GEOREFERENCE_MAPFILE_DEFAULT_PARAMS,
    )

    LOGGER.debug("Calculate extent ...")
    dataset = gdal.Open(destPath, GA_ReadOnly)
    extent = getBoundsFromDataset(dataset)
    LOGGER.debug("Deliver results.")
    return {"wmsUrl": wmsUrl, "layerId": requestParams["mapObj"].apsdateiname, "extent": extent}
def setProcessToIsValide(request):
    LOGGER.info('Request - Set admin evaluation of georeference process to isvalide ....')
    try:
        # remove georeference process
        if 'georeferenceid' in request.params:
            georeferenceid = request.params['georeferenceid']
            comment = '' if 'comment' not in request.params else request.params['comment']

            # check if georeference id exist
            georeferenceprocess = Georeferenzierungsprozess.by_id(georeferenceid, request.db)
            if georeferenceprocess:
                newJob = createNewAdminJob(georeferenceprocess, 'isvalide', request.params['userid'], comment)
                request.db.add(newJob)

            return {'message':'The georeference process has been set to isvalide.'}
        else:
            raise Exception('Missing parameter (georeferenceid) ...')
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        return HTTPBadRequest(GENERAL_ERROR_MESSAGE);
def getGeoreferencePoints(request):

    LOGGER.info('Request - Get georeference points.')
    dbsession = request.db
    try:
        LOGGER.debug('Get points per user')
        queryData = request.db.query(Georeferenzierungsprozess.nutzerid, func.count(Georeferenzierungsprozess.nutzerid))\
            .filter(Georeferenzierungsprozess.adminvalidation != 'invalide')\
            .group_by(Georeferenzierungsprozess.nutzerid)\
            .order_by(desc(func.count(Georeferenzierungsprozess.nutzerid)))\
            .limit(10)
        user_points = []
        for record in queryData:
            userid = record[0]
            count = record[1]
            user_points.append({'userid': userid, 'points': 20 * count})

        LOGGER.debug('Get georeference map count')
        queryData = request.db.query(func.count(Map.isttransformiert))\
            .filter(Map.isttransformiert == True)\
            .filter(Map.istaktiv == True)
        georeference_map_count = []
        for record in queryData:
            georeference_map_count = record[0]

        LOGGER.debug('Get missing georeference map count')
        queryData = request.db.query(func.count(Map.isttransformiert))\
            .filter(Map.isttransformiert == False)\
            .filter(Map.istaktiv == True)
        missing_georeference_map_count = []
        for record in queryData:
            missing_georeference_map_count = record[0]

        return {
            'pointoverview': user_points,
            'georeference_map_count': georeference_map_count,
            'missing_georeference_map_count': missing_georeference_map_count
        }
    except Exception as e:
        LOGGER.error(
            'Error while trying to request georeference history information')
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(GENERAL_ERROR_MESSAGE)
Example #7
0
def georeferenceValidation(request):
    """ The function generates a process validation result and publish it via a WMS instance. The
        wms references are returned.

        :type request: pyramid.request
        :return: dict
        :raise: HTTPBadRequest
        :raise: HTTPInternalServerError """
    LOGGER.info('Receive process validation request with parameters: %s'%request.json_body)

    try:
        # extract validation data
        LOGGER.debug('Parse request params ...')
        requestParams = parseGeoreferenceParamsFromRequest(request)

        LOGGER.debug('Parse and validate SRS params ...')
        georefSourceSRS = requestParams['georeference']['source']
        if str(georefSourceSRS).lower() != 'pixel':
            raise ParameterException('Only "pixel" is yet supported as source srs.')

        if ':' not in str(requestParams['georeference']['target']):
            raise ParameterException('Missing "EPSG:...." syntax for target srs.')
        georefTargetSRS = stripSRIDFromEPSG(requestParams['georeference']['target'])

        # generate a temporary process result and publish it via wms
        LOGGER.debug('Parse and validate gcps params ...')
        if len(requestParams['georeference']['gcps']) < 2:
            raise ParameterException('Not enough gcps for valid georeferencing ...')
        gcps = parseGcps(requestParams['georeference']['gcps'])

        # calculate validation result
        return createValidationResult(requestParams, gcps, georefTargetSRS, LOGGER)

    except ParameterException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPBadRequest(ERROR_MSG)
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(ERROR_MSG)
def generateGeoreferenceHistory(request):

    def getUserId(request):
        """ Parse the process id from the request.

        :type request: pyramid.request
        :return: str|None """
        if request.method == 'GET' and 'userid' in request.matchdict:
            return request.matchdict['userid']
        return None

    LOGGER.info('Request - Get georeference profile page.')
    dbsession = request.db

    try:
        userid = getUserId(request)
        if userid is None:
            raise ParameterException("Wrong or missing userid.")

        LOGGER.debug('Query georeference profile information from database for user %s'%userid)
        queryData = request.db.query(Georeferenzierungsprozess, Metadata, Map).join(Metadata, Georeferenzierungsprozess.mapid == Metadata.mapid)\
            .join(Map, Georeferenzierungsprozess.mapid == Map.id)\
            .filter(Georeferenzierungsprozess.nutzerid == userid)\
            .order_by(desc(Georeferenzierungsprozess.id))

        LOGGER.debug('Create response list')
        georef_profile = []
        points = 0
        for record in queryData:
            georef = record[0]
            metadata = record[1]
            mapObj = record[2]

            #
            # create response
            #
            responseRecord = {'georefid':georef.id, 'mapid':OAI_ID_PATTERN%georef.mapid,
                    'georefparams': georef.georefparams, 'time': str(metadata.timepublish), 'transformed': georef.processed,
                    'isvalide': georef.adminvalidation, 'title': metadata.title, 'key': mapObj.apsdateiname,
                    'georeftime':str(georef.timestamp),'type':georef.type,
                    'published':georef.processed, 'thumbnail': metadata.thumbsmid}

            # add boundingbox if exists
            if mapObj.boundingbox is not None:
                responseRecord['boundingbox'] = mapObj.getExtentAsString(dbsession, 4326)

            # calculate points
            if georef.adminvalidation is not 'invalide':
                points += 20

            georef_profile.append(responseRecord)

        LOGGER.debug('Response: %s'%georef_profile)

        return {'georef_profile':georef_profile, 'points':points}
    except Exception as e:
        LOGGER.error('Error while trying to request georeference history information');
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(GENERAL_ERROR_MESSAGE)
Example #9
0
def getGeoreferenceResource(request):
    """ The function returns the process process information for a given objectid. Supports GET/POST requests
         
        :type request: pyramid.request
        :return: dict
        :raise: HTTPBadRequest
        :raise: HTTPInternalServerError """
         
    def getGeoreferenceId(request):
        """ Parse the process id from the request.
         
        :type request: pyramid.request
        :return: int|None """
        if request.method == 'GET' and 'georeferenceid' in request.matchdict:
            return int(request.matchdict['georeferenceid'])
        return None
     
    try:
        georeferenceid = getGeoreferenceId(request) 
        if georeferenceid is None:
            raise ParameterException("Wrong or missing georeferenceid.")
 
        LOGGER.debug('Create response for georeferenceid - %s ...'%georeferenceid)
        return generateGeoreferenceProcessForSpecificGeoreferenceId(georeferenceid, request, LOGGER)
    except ParameterException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPBadRequest(ERROR_MSG) 
    except ProcessIsInvalideException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPBadRequest('This process process is blocked for further work!')
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(ERROR_MSG)
def adminEvaluationGeoreferenceProcess(request):
    try:
        LOGGER.info('Request - Get georeference processes.')

        if 'mapid' in request.params:
            LOGGER.debug('Get processes for mapid %s ...'%request.params['mapid'])
            # parse the id
            mapid = None
            if '-' in request.params['mapid']:
                namespace, mapid = request.params['mapid'].rsplit('-', 1)
                # check if it is the correct namespace
                if namespace != OAI_ID_PATTERN.rsplit('-', 1)[0]:
                    return []
            queryData = request.db.query(Georeferenzierungsprozess, Metadata).join(Metadata, Georeferenzierungsprozess.mapid == Metadata.mapid)\
                .filter(Georeferenzierungsprozess.mapid == mapid)\
                .order_by(desc(Georeferenzierungsprozess.id))
        elif 'userid' in request.params:
            LOGGER.debug('Get processes for userid %s ...'%request.params['userid'])
            queryData = request.db.query(Georeferenzierungsprozess, Metadata).join(Metadata, Georeferenzierungsprozess.mapid == Metadata.mapid)\
                .filter(Georeferenzierungsprozess.nutzerid == request.params['userid'])\
                .order_by(desc(Georeferenzierungsprozess.id))
        elif 'validation' in request.params:
            LOGGER.debug('Get processes for adminvalidation %s ...'%request.params['validation'])
            queryData = request.db.query(Georeferenzierungsprozess, Metadata).join(Metadata, Georeferenzierungsprozess.mapid == Metadata.mapid)\
                .filter(Georeferenzierungsprozess.adminvalidation == request.params['validation'])\
                .order_by(desc(Georeferenzierungsprozess.id))
        else:
            LOGGER.debug('Get all pending processes ...')
            queryData = request.db.query(Georeferenzierungsprozess, Metadata).join(Metadata, Georeferenzierungsprozess.mapid == Metadata.mapid)\
                .filter(or_(Georeferenzierungsprozess.adminvalidation == '', Georeferenzierungsprozess.adminvalidation == None))\
                .order_by(desc(Georeferenzierungsprozess.id))

        response = []
        for record in queryData:
            georef = record[0]
            metadata = record[1]
            dict = {
                    'georef_id':georef.id,
                    'mapid':georef.mapid,
                    'georef_params': georef.georefparams,
                    'time': str(metadata.timepublish),
                    'processed': georef.processed,
                    'adminvalidation': georef.adminvalidation,
                    'title': metadata.title,
                    'apsobjectid': georef.messtischblattid,
                    'georef_time':str(georef.timestamp),
                    'type':georef.type,
                    'userid': georef.nutzerid,
                    'georef_isactive':georef.isactive
                }

            if georef.clip is not None:
                dict['clippolygon'] = {
                    'source': 'EPSG:%s' % georef.getSRIDClip(request.db),
                    'polygon': convertPostgisStringToList(georef.clip)
                }

            response.append(dict)
        return response
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        return HTTPInternalServerError(GENERAL_ERROR_MESSAGE)
def georeferenceValidation(request):
    """ The function generates a process validation result and publish it via a WMS instance. The
        wms references are returned.

        :type request: pyramid.request
        :return: dict
        :raise: HTTPBadRequest
        :raise: HTTPInternalServerError """
    LOGGER.info("Receive process validation request with parameters: %s" % request.json_body)

    try:
        # extract validation data
        LOGGER.debug("Parse request params ...")
        requestParams = parseGeoreferenceParamsFromRequest(request)

        LOGGER.debug("Parse and validate SRS params ...")
        georefSourceSRS = requestParams["georeference"]["source"]
        if str(georefSourceSRS).lower() != "pixel":
            raise ParameterException('Only "pixel" is yet supported as source srs.')

        if ":" not in str(requestParams["georeference"]["target"]):
            raise ParameterException('Missing "EPSG:...." syntax for target srs.')
        georefTargetSRS = stripSRIDFromEPSG(requestParams["georeference"]["target"])

        # generate a temporary process result and publish it via wms
        LOGGER.debug("Parse and validate gcps params ...")
        if len(requestParams["georeference"]["gcps"]) < 2:
            raise ParameterException("Not enough gcps for valid georeferencing ...")
        gcps = parseGcps(requestParams["georeference"]["gcps"])

        # calculate validation result
        return createValidationResult(requestParams, gcps, georefTargetSRS, LOGGER)

    except ParameterException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPBadRequest(ERROR_MSG)
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(ERROR_MSG)
Example #12
0
def georeferenceConfirm(request):
    """ The function persistent saves a georeference confirmation request

        :type request: pyramid.request
        :return: dict
        :raise: HTTPBadRequest
        :raise: HTTPInternalServerError """
    LOGGER.info('Receive georeference validation request with parameters: %s' %
                request.json_body)

    try:
        # extract validation data
        LOGGER.debug('Parse request params ...')
        requestData = parseGeoreferenceParamsFromRequest(request)

        # in case of type new,
        # check if there already exist an actual georeference process for this object with this type
        if requestData[
                'type'] == 'new' and Georeferenzierungsprozess.isGeoreferenced(
                    requestData['mapObj'].id, request.db):
            msg = 'There exists already an active georeference process for this map id. It is therefore not possible to save a georeference process of type "new".'
            LOGGER.debug(msg)

            georeferenceid = Georeferenzierungsprozess.getActualGeoreferenceProcessForMapId(
                requestData['mapObj'].id, request.db).id
            return {'text': msg, 'georeferenceid': georeferenceid}

        LOGGER.debug('Save georeference parameter in datase ...')
        timestamp = convertTimestampToPostgisString(datetime.now())
        georefParam = str(convertUnicodeDictToUtf(requestData['georeference']))
        overwrites = requestData[
            'overwrites'] if 'overwrites' in requestData else 0
        georefProcess = Georeferenzierungsprozess(
            messtischblattid=requestData['mapObj'].apsobjectid,
            nutzerid=requestData['userid'],
            georefparams=ast.literal_eval(georefParam),
            timestamp=timestamp,
            isactive=False,
            type=requestData['type'],
            overwrites=overwrites,
            adminvalidation='',
            processed=False,
            mapid=requestData['mapObj'].id,
            algorithm=requestData['georeference']['algorithm'])

        request.db.add(georefProcess)
        request.db.flush()

        # add polygon
        if 'clip' in requestData:
            clipParam = convertUnicodeDictToUtf(requestData['clip'])
            polygonAsString = convertListToPostgisString(
                clipParam['polygon'], 'POLYGON')
            georefProcess.setClip(polygonAsString,
                                  stripSRIDFromEPSG(clipParam['source']),
                                  request.db)

        LOGGER.debug('Create response ...')
        # @TODO has to be updated
        points = int(len(requestData['georeference']['gcps']) * 5)
        return {
            'text':
            'Georeference result saved. It will soon be ready for use.',
            'georeferenceid': georefProcess.id,
            'points': points
        }
    except ParameterException as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPBadRequest(ERROR_MSG)
    except Exception as e:
        LOGGER.error(e)
        LOGGER.error(traceback.format_exc())
        raise HTTPInternalServerError(ERROR_MSG)