예제 #1
0
def _handle_response(res, stype, gis, as_dict):
    """
    Handles returning the data in the proper format

    ================    ===============================================================
    **Argument**        **Description**
    ----------------    ---------------------------------------------------------------
    res                 Required Dict.  The response dictionary from the query call.
    ----------------    ---------------------------------------------------------------
    stype               Required String. The search type to find. This tells the
                        internal method what type of return object should be used.
    ----------------    ---------------------------------------------------------------
    gis                 Required GIS. The connection object.
    ----------------    ---------------------------------------------------------------
    as_dict             Required Boolean. If True, the response comes back as a dictionary.
    ================    ===============================================================

    :returns: List

    """
    if as_dict:
        return res['results']
    elif str(stype).lower() in {"content", "item", "items", "group_content"}:
        return [Item(itemid=r['id'], itemdict=r, gis=gis) for r in res['results']]
    elif str(stype).lower() in ["user", "users", "accounts", "account"]:
        return [User(gis=gis, username=r['username'], userdict=res) for r in res['results']]
    elif str(stype).lower() in ["groups", 'group']:
        return [Group(groupdict=r, groupid=r['id'], gis=gis) for r in res['results']]
    return res['results']
예제 #2
0
 def __init__(self, workbook: Item) -> None:
     self._item_data = workbook.get_data()
     self._url = workbook.url
     self._owner = workbook.owner
     self._id = workbook.name
     self._workbook = workbook
     print(self._item_data.keys())
예제 #3
0
def get_project(project_id, gis):
    """ Loads and returns a workforce project.
        :param gis: An authenticated arcigs.gis.GIS object.
        :param project_id: The project's id.
        :returns: workforce.Project
    """
    item = Item(gis, project_id)
    return workforce.Project(item)
예제 #4
0
    def __init__(self, gis, itemid, itemdict=None, userdict=None):
        """Does not acount for cases where their are more than one search result"""

        self.item = Item(gis, itemid, itemdict=itemdict)
        if self.item.layers:
            self.lyr = self.item.layers[0]
            self.properties = self.lyr.properties
            self.fields = self.properties.fields
예제 #5
0
    def result(self):
        """
        Return the value returned by the call. If the call hasn't yet completed
        then this method will wait.

        :returns: object
        """
        from arcgis.gis import Item
        if self.cancelled():
            return None
        res = self._future.result()
        if 'result' in res:
            if 'itemId' in res['result']:
                from arcgis.gis import Item
                return Item(gis=self._gis, itemid=res['result']['itemId'])
            elif 'itemsImported' in res['result']:
                return_result = {}
                return_result['itemsImported'] = [
                    Item(itemid=i['itemId'], gis=self._gis)
                    for i in res['result']['itemsImported'] if 'itemId' in i
                ]
                return_result['itemsSkipped'] = [
                    Item(i['itemId'], gis=self._gis)
                    for i in res['result']['itemsSkipped'] if 'itemId' in i
                ]
                return_result['itemsFailedImport'] = [
                    Item(i['itemId'], gis=self._gis)
                    for i in res['result']['itemsFailedImport']
                    if 'itemId' in i
                ]
                return return_result
            elif 'services' in res['result']:
                return [
                    Item(self._gis, t['serviceItemId'])
                    for t in res['result']['services'] if 'serviceItemId' in t
                ]
            else:
                return res

        return res
예제 #6
0
def update_picklists(item_id, sql_schema, table_name, field_map):
    """Updates hosted csv file which is used by Survey123 in select_from_file questions.

    Updates the csv file hosted in ArcGIS Online / Portal. CSV linking must be used for
    'select_x_from_file' question types in the form, and content linking must be enabled on these
    forms. The field map dictionary shoould be constructed using the format {input_field: output_field}.
    Output tables must contain 'name' and 'label' fields at a minimum. Additional optional
    fields may be included to drive cascading select type questions. ArGIS Online or Portal
    login credentials must be saved in the Window Credential Manager as 'Generic Credentials'.
    Note: linked content csvs are currently only supported by the field application. Any changes
    made to picklists contained in linked content csv files will not be reflected in a Survey123 web
    form.

    Parameters
    ----------
    item_id : str
        The item id of the target hosted .csv
    sql_schema : str
        String which represents the name of the schema which owns the SQL table
    table_name : str
        String which represents the name of the SQL table
    field_map : dict
        Dictionary of input SQL field names and their corresponding output csv field names
    """

    portal_url = r'https://nps.maps.arcgis.com'  # Change to portal URL once migrated
    # Windows credentials will need to be updated as well. Maybe make variable?
    agol_credentials = get_credential(portal_url, 'GRCA_GIS')

    # Code to initiate connection to SQL server
    # Update to correct windows credentials. Maybe make variable?
    sql_credential = get_credential('sql_login', 'postgres')
    conn_dict = {
        'drivername': 'postgresql',  # Change drivername to correct driver for target platform
        'username': sql_credential.username,
        'password': sql_credential.password,
        'host': '127.0.0.1',  # set to host IP or path
        'port': '5432'
    }
    conn_url = URL.create(**conn_dict)
    engine = create_engine(conn_url)

    # Fetch item from AGOL/portal
    gis = GIS(url=portal_url,
              username=agol_credentials.username,
              password=agol_credentials.password)
    item = Item(gis, item_id)

    # Construct query string
    field_qry_list = []
    for key, value in field_map.items():
        field_qry_list.append(f'{key} AS {value}')
    field_string = ', '.join(field_qry_list)

    # Query SQL table
    sql_query = f'''SELECT {field_string} FROM {sql_schema}.{table_name};'''
    updated_table = read_sql_query(sql_query, engine)
    # Save to disk. Potential optimization is to use in-memory csv serialization, but I can't get it to work
    output = 'temp_csv.csv'
    updated_table.to_csv(output, index=False)
    # Push table to AGOL
    item.update(data=output)
    # Delete temporary csv file
    remove(output)
def main(req: func.HttpRequest) -> func.HttpResponse:

    try:

        # if the invocation method is OPTION, just respond with 200 to let the client know the endpoint is working
        if req.method == 'OPTIONS':
            return func.HttpResponse(headers={
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
                'Access-Control-Allow-Headers': 'Content-Type',
                'Access-Control-Max-Age': '3600'
            },
                                     status_code=200)

        # otherwise, if the request method is POST, get to work!
        elif req.method == 'POST':

            # extract the Object ID from the submitted feature
            req_str = req.get_body().decode('utf-8')
            req_dict = json.loads(req_str)
            feature_oid = req_dict['feature']['result']['objectId']

            logging.info(f'Feature Object ID: {feature_oid}')

            # retrieve values from environment file
            gis_url = os.getenv('GIS_URL')
            gis_username = os.getenv('GIS_USERNAME')
            gis_password = os.getenv('GIS_PASSWORD')
            feature_service_item_id = os.getenv('SURVEY_LAYER_ITEM_ID')
            feature_service_detection_field = os.getenv(
                'FEATURE_SERVICE_DETECTION_FIELD')
            feature_service_tags_field = os.getenv(
                'FEATURE_SERVICE_TAGS_FIELD')
            azure_key = os.getenv('AZURE_KEY')
            azure_region_code = os.getenv('AZURE_REGION_CODE')
            tag_search_lst = ast.literal_eval(os.getenv('OBJECT_TAGS'))

            # connect to the web gis, and create a layer using the item ID
            gis = GIS(gis_url, username=gis_username, password=gis_password)
            lyr_pt = Item(gis, feature_service_item_id).layers[0]

            logging.info(f'Using layer {lyr_pt.url}')

            # get the image from the attachment list and create a url to access it
            attachment_lst = lyr_pt.attachments.get_list(feature_oid)
            attachment_id = attachment_lst[0]['id']
            image_url = f'{lyr_pt.url}/{feature_oid}/attachments/{attachment_id}?token={gis._con.token}'

            logging.info(
                'Successfully processed JSON, now sending to computer vision.')
            logging.info(f'Image url: {image_url}')

            # determine if a weapon exists using computer vision, and format the responses
            vision = ComputerVision(azure_key, azure_region_code)
            tag_match_dict = vision.get_image_tag_match(
                image_url, tag_search_lst)
            detection_status = tag_match_dict['match_status']
            tags_assigned = ', '.join(tag_match_dict['tag_list'])

            logging.info(
                f'Tags assigned by Azure Computer Vision: {tags_assigned}')
            logging.info(f'Object Detection Status: {detection_status}')

            # geat a feature object, modify the attribute to reflect the status, and push the results to ArcGIS Online
            feat = lyr_pt.query(object_ids=f'{feature_oid}').features[0]
            feat.attributes[feature_service_detection_field] = detection_status
            feat.attributes[feature_service_tags_field] = tags_assigned
            update_resp = lyr_pt.edit_features(updates=[feat])

            # if the process was successful, return success code
            if update_resp['updateResults'][0]['success']:

                logging.info(
                    'Successfully processed image and updated feature service.'
                )

                return func.HttpResponse(
                    'Successfully processed image and updated feature service.',
                    status_code=202)

            # otherwise, let the user know not so great
            else:

                logging.warning(
                    'Although the image was successfully categorized, updating the feature service failed.'
                )

                return func.HttpResponse(
                    'Although the image was successfully categorized, updating the feature service failed.',
                    status_code=400)

        # if it isn't an OPTIONS or POST request, homie don't play 'dat.
        else:
            return func.HttpResponse(
                f'Request must be either a OPTIONS or POST. You submitted a {req.method}, which is unacceptable.',
                status_code=404)

    except ValueError as err:

        logging.error(err)

        return func.HttpResponse(
            f'Request Data Type - {type(req)}\n' +
            f'Request Body Type - {type(req.get_body())}\n' +
            f'Request Body Decoded - {req_body}\n' +
            f'Request Body - {req.get_body()}\n' +
            f'Headers:\n {req.headers.__dict__["__http_headers__"]}\n' +
            f'Request Parameters - {req.params}\n' +
            f'Request Route Params - {req.route_params}\n' +
            f'\nError Message:\n\n{err}',
            status_code=404)
예제 #8
0
def get_item_usage(gis_object, item_id, date_range='24H', as_df=False):
    item = Item(gis=gis_object, itemid=item_id)
    return item.usage(date_range=date_range, as_df=as_df)
예제 #9
0
def update_maps(q, old_id, new_layer):
    # for each map on the server,
    # Find a reference to the new layer
    # In the map,
    #   Find the old layer
    #   Remove it
    #   Insert the new layer in the same place

    count = 0
    msg = ''
    maps = gis.content.search(q,
                              max_items=1000,
                              sort_field="title",
                              sort_order="asc",
                              outside_org=False,
                              item_type="Web Map")
    print("Found %d maps." % len(maps))

    for map in maps:
        i_did_update = False

        map_info = "%s (%s) %s" % (map.title, map.owner, map.type)
        #display(web_map)
        count += 1

        web_map = WEBMAP(map)
        for layer in web_map.layers:

            # I dont care about labels right now because i use a different workflow.
            # They can be directly replaced in Portal.
            #        if layer.layerType == 'VectorTileLayer' and layer.title == old_label_name:
            #           # I see you, old labels.
            #           print("county labels updated")
            #          i_did_update = True
            #           web_map.remove_layer(layer)
            #web_map.add_layer(new_label)

            try:
                layerId = layer.itemId
                layerType = layer.layerType
            except AttributeError:
                layerId = ''
                layerType = ''

            if layerType == 'ArcGISTiledMapServiceLayer' and layerId == old_id:
                msg += map_info + "\n"
                msg += "\ttitle:\"%s\" id:%s itemId:%s\n" % (layer.title,
                                                             layer.id, layerId)

                print("new layer", new_id)

                # ALAS ALAS
                # this puts the "added" layer at the TOP of the layer list.
                # making this script, well, useless

                web_map.remove_layer(layer)
                web_map.add_layer(new_layer,
                                  options={"title": "Clatsop County"})
                i_did_update = True
            else:
                print("32%s \"%s\" %s" % (layerId, layer.title, layerType))
            pass

        if i_did_update:

            # "update" will save changes made to the web map
            # alternatively "save" will create a new copy of the map.
            # Thumbnail can be a local file (to upload) or a URL.

            # UPDATE
            web_map.update()
            comment = "%s updated by \"%s\"" % (datestamp, myname)
            item = ITEM(gis, web_map.item.id)
            item.add_comment(comment)
            """
            # SAVE
            old_title = web_map.item.title

            # I need to grab the existing thumbnail from Portal
            #watermarked_thumbnail = "thumbnail_" + datestring + ".jpg" 
            #watermark("thumbnail.jpg", watermarked_thumbnail, old_title, (0,200,200,128))
            
            # comment indicates new map created
            comment = "%s created from \"%s\" by \"%s\"" % (datestamp, web_map.item.title, myname)

            item = web_map.save(item_properties={
                # These are REQUIRED
                    "title":   "CHANGED " +  old_title + ' ' + datestamp, 
                    "snippet": web_map.item.snippet, 
                    "tags":    web_map.item.tags
                },
                #thumbnail = watermarked_thumbnail,
#                folder = "TESTING_Brian"
            )
            item.add_comment(comment)
            """

    print(msg)
    return count
예제 #10
0
resultSorted = sorted(result)
print(resultSorted)

# Create break values and labels
break0 = int(resultSorted[1])
label0 = "0 - " + str(break0)
break1 = int(resultSorted[2])
label1 = str(break0) + " - " + str(break1)
break2 = int(resultSorted[3])
label2 = str(break1) + " - " + str(break2)
break3 = int(resultSorted[4])
label3 = str(break2) + " - " + str(break3)

# bring webmap
webmapItem = '6ed1633b7839452fbd81455c411d22ab'
item = Item(gisuser, webmapItem, itemdict=None)
totalActionsMap = WebMap(item)

# modify webmap
# breaks
totalActionsMap['operationalLayers'][0]['layerDefinition']['drawingInfo'][
    'renderer']['classBreakInfos'][0]['classMaxValue'] = break0
totalActionsMap['operationalLayers'][0]['layerDefinition']['drawingInfo'][
    'renderer']['classBreakInfos'][1]['classMaxValue'] = break1
totalActionsMap['operationalLayers'][0]['layerDefinition']['drawingInfo'][
    'renderer']['classBreakInfos'][2]['classMaxValue'] = break2
totalActionsMap['operationalLayers'][0]['layerDefinition']['drawingInfo'][
    'renderer']['classBreakInfos'][3]['classMaxValue'] = break3

# labels
totalActionsMap['operationalLayers'][0]['layerDefinition']['drawingInfo'][
예제 #11
0
    opsLayers = src.get_data()['operationalLayers']
    mapDestObj = arcgis.mapping.WebMap(des)
    mapDestObj.definition['operationalLayers'] = opsLayers
    mapDestObj.update()


##BS BEGINS
portal = GIS("https://" + src, src_admin, src_admin_pwd, verify_cert=False)
print(portal)

#loop through dictionary
for i in rollBackList:
    #define variables
    srcId = rollBackList[i]['source']
    desId = rollBackList[i]['destination']
    srcMap = Item(portal, srcId)
    destMap = Item(portal, desId)

    #print actions to check, if destination and source titels are different... you'll be fired
    print("-------------------------")
    print(rollBackList[i]['name'])
    print("-------------------------")
    print(" Source item title:      " + srcMap.title)
    print(" Destination item title: " + destMap.title)
    print("    SOURCE:      " + srcId)
    print("    DESTINATION: " + desId)

    #transfer begins
    if readOnly == False:
        transfer(srcMap, destMap)
        print("    Transfer Complete for this item")