<s> import bson . json_util <EOL> import six <EOL> from geojson import GeoJSON <EOL> from pymongo import GEOSPHERE <EOL> from pymongo . errors import OperationFailure <EOL> from girder . api import access <EOL> from girder . api . describe import Description , describeRoute <EOL> from girder . api . rest import loadmodel , Resource , RestException <EOL> from girder . constants import AccessType <EOL> GEOSPATIAL_FIELD = '<STR_LIT>' <EOL> class GeospatialItem ( Resource ) : <EOL> """<STR_LIT>""" <EOL> @ access . user <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = True , <EOL> paramType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' <EOL> '<STR_LIT>' , required = True , <EOL> paramType = '<STR_LIT>' ) <EOL> . errorResponse ( ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> . errorResponse ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' , <NUM_LIT> ) <EOL> . notes ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> ) <EOL> def create ( self , params ) : <EOL> """<STR_LIT>""" <EOL> self . requireParams ( ( '<STR_LIT>' , '<STR_LIT>' ) , params ) <EOL> try : <EOL> geospatial = bson . json_util . loads ( params [ '<STR_LIT>' ] ) <EOL> GeoJSON . to_instance ( geospatial , strict = True ) <EOL> except ValueError : <EOL> raise RestException ( '<STR_LIT>' ) <EOL> if geospatial [ '<STR_LIT:type>' ] == '<STR_LIT>' : <EOL> features = [ geospatial ] <EOL> elif geospatial [ '<STR_LIT:type>' ] == '<STR_LIT>' : <EOL> features = geospatial [ '<STR_LIT>' ] <EOL> else : <EOL> raise RestException ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> data = [ ] <EOL> for feature in features : <EOL> properties = feature [ '<STR_LIT>' ] <EOL> if '<STR_LIT:name>' not in properties : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> name = properties [ '<STR_LIT:name>' ] <EOL> del properties [ '<STR_LIT:name>' ] <EOL> if '<STR_LIT:description>' in properties : <EOL> description = properties [ '<STR_LIT:description>' ] <EOL> del properties [ '<STR_LIT:description>' ] <EOL> else : <EOL> description = '<STR_LIT>' <EOL> for key in properties : <EOL> if not len ( key ) : <EOL> raise RestException ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if '<STR_LIT:.>' in key or key [ <NUM_LIT:0> ] == '<STR_LIT:$>' : <EOL> raise RestException ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % key ) <EOL> data . append ( { '<STR_LIT:name>' : name , <EOL> '<STR_LIT:description>' : description , <EOL> '<STR_LIT>' : properties , <EOL> '<STR_LIT>' : feature [ '<STR_LIT>' ] } ) <EOL> user = self . getCurrentUser ( ) <EOL> folder = self . model ( '<STR_LIT>' ) . load ( <EOL> id = params [ '<STR_LIT>' ] , user = user , level = AccessType . WRITE , exc = True ) <EOL> items = [ ] <EOL> for datum in data : <EOL> newItem = self . model ( '<STR_LIT>' ) . createItem ( <EOL> folder = folder , name = datum [ '<STR_LIT:name>' ] , creator = user , <EOL> description = datum [ '<STR_LIT:description>' ] ) <EOL> self . model ( '<STR_LIT>' ) . setMetadata ( newItem , datum [ '<STR_LIT>' ] ) <EOL> newItem [ GEOSPATIAL_FIELD ] = { '<STR_LIT>' : datum [ '<STR_LIT>' ] } <EOL> newItem = self . model ( '<STR_LIT>' ) . updateItem ( newItem ) <EOL> items . append ( newItem ) <EOL> return [ self . _filter ( item ) for item in items ] <EOL> @ access . public <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' ) <EOL> . param ( '<STR_LIT:q>' , '<STR_LIT>' , required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . errorResponse ( ) <EOL> ) <EOL> def find ( self , params ) : <EOL> """<STR_LIT>""" <EOL> self . requireParams ( ( '<STR_LIT:q>' , ) , params ) <EOL> try : <EOL> query = bson . json_util . loads ( params [ '<STR_LIT:q>' ] ) <EOL> except ValueError : <EOL> raise RestException ( "<STR_LIT>" ) <EOL> limit , offset , sort = self . getPagingParameters ( params , '<STR_LIT>' ) <EOL> return self . _find ( query , limit , offset , sort ) <EOL> @ access . public <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . errorResponse ( ) <EOL> ) <EOL> def intersects ( self , params ) : <EOL> """<STR_LIT>""" <EOL> self . requireParams ( ( '<STR_LIT>' , '<STR_LIT>' ) , params ) <EOL> try : <EOL> geometry = bson . json_util . loads ( params [ '<STR_LIT>' ] ) <EOL> GeoJSON . to_instance ( geometry , strict = True ) <EOL> except ( TypeError , ValueError ) : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if params [ '<STR_LIT>' ] [ : <NUM_LIT:3> ] == '<STR_LIT>' % GEOSPATIAL_FIELD : <EOL> field = params [ '<STR_LIT>' ] . strip ( ) <EOL> else : <EOL> field = '<STR_LIT>' % ( GEOSPATIAL_FIELD , params [ '<STR_LIT>' ] . strip ( ) ) <EOL> query = { <EOL> field : { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : geometry <EOL> } <EOL> } <EOL> } <EOL> limit , offset , sort = self . getPagingParameters ( params , '<STR_LIT>' ) <EOL> return self . _find ( query , limit , offset , sort ) <EOL> def _getGeometry ( self , params ) : <EOL> try : <EOL> geometry = bson . json_util . loads ( params [ '<STR_LIT>' ] ) <EOL> GeoJSON . to_instance ( geometry , strict = True ) <EOL> if geometry [ '<STR_LIT:type>' ] != '<STR_LIT>' : <EOL> raise ValueError <EOL> return geometry <EOL> except ( TypeError , ValueError ) : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> @ access . public <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> required = False , dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> required = False , dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' <EOL> '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . errorResponse ( ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' , <NUM_LIT> ) <EOL> . notes ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> ) <EOL> def near ( self , params ) : <EOL> """<STR_LIT>""" <EOL> self . requireParams ( ( '<STR_LIT>' , '<STR_LIT>' ) , params ) <EOL> condition = { <EOL> '<STR_LIT>' : self . _getGeometry ( params ) <EOL> } <EOL> for param in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if param in params : <EOL> try : <EOL> distance = float ( params [ param ] ) <EOL> if distance < <NUM_LIT:0.0> : <EOL> raise ValueError <EOL> except ValueError : <EOL> raise RestException ( "<STR_LIT>" % <EOL> param ) <EOL> condition [ '<STR_LIT:$>' + param ] = distance <EOL> if params [ '<STR_LIT>' ] [ : <NUM_LIT:3> ] == '<STR_LIT>' % GEOSPATIAL_FIELD : <EOL> field = params [ '<STR_LIT>' ] . strip ( ) <EOL> else : <EOL> field = '<STR_LIT>' % ( GEOSPATIAL_FIELD , params [ '<STR_LIT>' ] . strip ( ) ) <EOL> if params . get ( '<STR_LIT>' , False ) : <EOL> user = self . getCurrentUser ( ) <EOL> if not user : <EOL> raise RestException ( '<STR_LIT>' , <NUM_LIT> ) <EOL> self . model ( '<STR_LIT>' ) . collection . create_index ( [ ( field , GEOSPHERE ) ] ) <EOL> query = { <EOL> field : { <EOL> '<STR_LIT>' : condition <EOL> } <EOL> } <EOL> limit , offset , sort = self . getPagingParameters ( params , '<STR_LIT>' ) <EOL> try : <EOL> items = self . _find ( query , limit , offset , sort ) <EOL> except OperationFailure : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" % field ) <EOL> return items <EOL> _RADIUS_OF_EARTH = <NUM_LIT> <EOL> @ access . public <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = True ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = False ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , <EOL> required = False ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . param ( '<STR_LIT>' , '<STR_LIT>' , required = False , <EOL> dataType = '<STR_LIT>' ) <EOL> . errorResponse ( ) <EOL> . notes ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> ) <EOL> def within ( self , params ) : <EOL> """<STR_LIT>""" <EOL> self . requireParams ( ( '<STR_LIT>' , ) , params ) <EOL> if '<STR_LIT>' in params : <EOL> try : <EOL> geometry = bson . json_util . loads ( params [ '<STR_LIT>' ] ) <EOL> GeoJSON . to_instance ( geometry , strict = True ) <EOL> if geometry [ '<STR_LIT:type>' ] != '<STR_LIT>' : <EOL> raise ValueError <EOL> except ( TypeError , ValueError ) : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> condition = { <EOL> '<STR_LIT>' : geometry <EOL> } <EOL> elif '<STR_LIT>' in params and '<STR_LIT>' in params : <EOL> try : <EOL> radius = float ( params [ '<STR_LIT>' ] ) / self . _RADIUS_OF_EARTH <EOL> if radius < <NUM_LIT:0.0> : <EOL> raise ValueError <EOL> except ValueError : <EOL> raise RestException ( "<STR_LIT>" ) <EOL> try : <EOL> center = bson . json_util . loads ( params [ '<STR_LIT>' ] ) <EOL> GeoJSON . to_instance ( center , strict = True ) <EOL> if center [ '<STR_LIT:type>' ] != '<STR_LIT>' : <EOL> raise ValueError <EOL> except ( TypeError , ValueError ) : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> condition = { <EOL> '<STR_LIT>' : [ center [ '<STR_LIT>' ] , radius ] <EOL> } <EOL> else : <EOL> raise RestException ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if params [ '<STR_LIT>' ] [ : <NUM_LIT:3> ] == '<STR_LIT>' % GEOSPATIAL_FIELD : <EOL> field = params [ '<STR_LIT>' ] . strip ( ) <EOL> else : <EOL> field = '<STR_LIT>' % ( GEOSPATIAL_FIELD , params [ '<STR_LIT>' ] . strip ( ) ) <EOL> limit , offset , sort = self . getPagingParameters ( params , '<STR_LIT>' ) <EOL> query = { <EOL> field : { <EOL> '<STR_LIT>' : condition <EOL> } <EOL> } <EOL> return self . _find ( query , limit , offset , sort ) <EOL> @ access . public <EOL> @ loadmodel ( model = '<STR_LIT>' , level = AccessType . READ ) <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' ) <EOL> . param ( '<STR_LIT:id>' , '<STR_LIT>' , paramType = '<STR_LIT:path>' ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' , <NUM_LIT> ) <EOL> ) <EOL> def getGeospatial ( self , item , params ) : <EOL> """<STR_LIT>""" <EOL> return self . _filter ( item ) <EOL> @ access . user <EOL> @ loadmodel ( model = '<STR_LIT>' , level = AccessType . WRITE ) <EOL> @ describeRoute ( <EOL> Description ( '<STR_LIT>' ) <EOL> . notes ( '<STR_LIT>' ) <EOL> . param ( '<STR_LIT:id>' , '<STR_LIT>' , paramType = '<STR_LIT:path>' ) <EOL> . param ( '<STR_LIT:body>' , '<STR_LIT>' , <EOL> paramType = '<STR_LIT:body>' ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' ) <EOL> . errorResponse ( '<STR_LIT>' , <NUM_LIT> ) <EOL> ) <EOL> def setGeospatial ( self , item , params ) : <EOL> """<STR_LIT>""" <EOL> geospatial = self . getBodyJson ( ) <EOL> for k , v in six . viewitems ( geospatial ) : <EOL> if '<STR_LIT:.>' in k or k [ <NUM_LIT:0> ] == '<STR_LIT:$>' : <EOL> raise RestException ( '<STR_LIT>' <EOL> '<STR_LIT>' % k ) <EOL> if v : <EOL> try : <EOL> GeoJSON . to_instance ( v , strict = True ) <EOL> except ValueError : <EOL> raise RestException ( '<STR_LIT>' <EOL> '<STR_LIT>' % ( k , v ) ) <EOL> if GEOSPATIAL_FIELD not in item : <EOL> item [ GEOSPATIAL_FIELD ] = dict ( ) <EOL> item [ GEOSPATIAL_FIELD ] . update ( six . viewitems ( geospatial ) ) <EOL> keys = [ k for k , v in six . viewitems ( item [ GEOSPATIAL_FIELD ] ) <EOL> if v is None ] <EOL> for key in keys : <EOL> del item [ GEOSPATIAL_FIELD ] [ key ] <EOL> item = self . model ( '<STR_LIT>' ) . updateItem ( item ) <EOL> return self . _filter ( item ) <EOL> def _filter ( self , item ) : <EOL> """<STR_LIT>""" <EOL> filtered = self . model ( '<STR_LIT>' ) . filter ( item ) <EOL> if GEOSPATIAL_FIELD in item : <EOL> filtered [ GEOSPATIAL_FIELD ] = item [ GEOSPATIAL_FIELD ] <EOL> else : <EOL> filtered [ GEOSPATIAL_FIELD ] = { } <EOL> return filtered <EOL> def _find ( self , query , limit , offset , sort ) : <EOL> """<STR_LIT>""" <EOL> user = self . getCurrentUser ( ) <EOL> cursor = self . model ( '<STR_LIT>' ) . find ( query , sort = sort ) <EOL> return [ self . _filter ( result ) for result in <EOL> self . model ( '<STR_LIT>' ) <EOL> . filterResultsByPermission ( cursor , user , AccessType . READ , <EOL> limit , offset ) ] </s>
