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 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)
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 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 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)
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 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 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 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)