Beispiel #1
0
def create_new_webmap(project_name, layer_names, *args):
    """
    creates a web map, adds feature layers to web map,
    and defines properties for layers and the web map

    Args:
        project_name (str): name of project
        layer_names (list): list of layer names to be added to web map

    Raises:
        TypeError: if project name is not type of string
        TypeError: if layer names is not type of list
        TypeError: if layer name is not type of string
    """
    if not isinstance(project_name, str):
        raise TypeError('expected project name to be type of str')

    if not isinstance(layer_names, list):
        raise TypeError('expected layer names to be type of list')

    for layer_name in layer_names:
        if not isinstance(layer_name, str):
            raise TypeError('expected layer name to be type of str')

    # get feature layers collection and update its properties
    feature_layers = get_feature_layers_collection(project_name)
    feature_layers_properties = get_properties_from_project(
        project_name=project_name,
        content_type='Feature Layer',
        project_additional_info=list(args))
    feature_layers.update(item_properties=feature_layers_properties)
    protect_share_item(feature_layers)

    # create a new web map
    new_web_map = WebMap()
    print('creating a new web map')

    # add feature layers to the web map
    for feature_layer in feature_layers.layers:
        new_web_map.add_layer(layer=feature_layer)
    print('adding', feature_layers.title, 'to web map')

    # define properties for the web map
    web_map_properties = get_properties_from_project(
        project_name=project_name,
        content_type='WebMap',
        project_additional_info=list(args))

    # create popups for map layers
    create_popups(web_map=new_web_map,
                  project_name=project_name,
                  layer_names=layer_names)

    # save the web map
    new_web_map.save(item_properties=web_map_properties)
    print('saving web map in portal')
Beispiel #2
0
def processMap(processOrg, fldr, mapTitle, mpNum, mpLayerTags, termsOfUse):

    #Flatten and get the unique Tags

    mpTags = reduce(operator.concat, mpLayerTags)
    uniqueMpTags = set(mpTags)

    # Accesses the map metadata to understand the layers that are used in the map
    # Creates a list of the layers found
    styleFrontUrl = "http://worldmap.harvard.edu/geoserver/styles/"

    folderProcess = fldr  #"HarvardForestDataMap"
    mTitle = mapTitle  #'Harvard Forest Data Map'
    mapNum = mpNum  #17305

    procSpace = r'C:\projects\HarvardMap\Data\{}'.format(folderProcess)

    # Dictionary lookup for sld styles
    sldGeomLookup = {}
    sldGeomLookup['MultiPolygon'] = "Polygon"
    sldGeomLookup['MultiLineString'] = "Polyline"
    sldGeomLookup['Point'] = "Point"

    # log into the org
    #gis = GIS(profile='harvardworldmap')
    gis = processOrg  #(profile="myorg")

    # Access the map inventory Excel file and load into a dataframe for later access
    #mapDF = pd.read_csv(r"C:\projects\HarvardMap\Data\maps_tab\maps_tab_excelExport.csv",sep=',')
    #seaMP = mapDF[mapDF.id == '{}'.format(mapNum)]

    # read in the Published map data layers from conversion script
    # Add to a dataframe for later access

    # Connect to the log table to determine
    tbIT = gis.content.get('5ca2378ea96e48e7b5739b6121557c3e')
    # c2169b562b4f407e8acf2e2b73b11a4a
    # 5ca2378ea96e48e7b5739b6121557c3e
    tbl = tbIT.tables[0]
    tbDF = tbl.query(where="mapname='{}'".format(mapTitle), as_df=True)

    lyrlgPubPath = '{}\{}PubLyrLog.txt'.format(procSpace, mTitle)

    #pubLyrDataFrame = pd.read_csv(lyrlgPubPath,index_col='indxCol')

    browser = webdriver.Chrome(
        executable_path=r"C:\projects\chromedriver_win32\chromedriver.exe")

    #url = "https://worldmap.harvard.edu/maps/17305/info/"
    url = "https://worldmap.harvard.edu/maps/{}".format(mapNum)
    # url = "http://trainingapps.esri.com/osiris/TrainingEvents/Search?PageSize=20&OrderBy=StartDate&Direction=asc&InstructorName={0}+{1}&StartDate=09%2F12%2F2016&EndDate=12%2F31%2F2016".format(firstName,lastName)

    browser.implicitly_wait(60)
    a = browser.get(url)

    # FireFox
    # browser = webdriver.Firefox(executable_path=r"C:\Software\geckodriver-v0.20.0-win64\geckodriver.exe")
    # browser.get(url)

    # opnFile = open(r"C:\Dev\Python\OsirisTools\pythclass.html",'r')
    # pgSource = BeautifulSoup(opnFile,'html.parser')
    pgSource = BeautifulSoup(browser.page_source, 'html.parser')

    # Create an empty webmap
    empty_webmap = WebMap()

    s = pgSource.head.find_all('script')
    jj = s[18]
    regex = re.compile('\n^(.*?){(.*?)$|,', re.MULTILINE)
    js_text = re.findall(
        regex, jj.string)  #Change jj.text to jj.string based on error
    mapJsonpre = js_text[76][1]
    mapJson = '{0}{1}'.format('{', mapJsonpre[:-2])
    mpJ = json.loads(mapJson)

    # Map Description from the JSON
    if mpJ['about']['introtext']:
        mapDesc = mpJ['about']['introtext']
    else:
        mapDesc = mTitle

    # Map scale
    #if mpJ['map']['maxResolution']:
    #mapScale = ['map']['maxResolution']

    grpDict = {}

    # Pull the group names into a list to reverse their order to preserve layer order from the map
    grpNames = [grp['group'] for grp in mpJ['map']['groups']]
    grpNames.reverse()

    for grp in grpNames:  #mpJ['map']['groups']:
        grpName = grp  #['group']
        print('GroupName :: {} '.format(grpName))
        grpLyrs = []
        for lyr in mpJ['map']['layers']:
            if lyr['group'] == grpName:
                print(lyr['title'])

                #if lyr['visibility']:
                #if lyr['visibility']:

                #visibile layer start
                if lyr['title'] == 'Population Density (2010)km2':
                    print('need to stop')

                # # use the name to link over to the item ID
                # if not 'geonode:' in lyr['name']:
                #     llkUP = lyr['detail_url'].split("/")[-1]
                #     print(llkUP)
                # else:
                #     llkUP = lyr['name']

                # isolate and test if the current layer is published vectordata
                #publyrLookupID = tbDF.query("geonodeSRC == '{}'".format(llkUP))

                # search for the published Layer by snippet
                addLayer = gis.content.search(query='snippet:"{}"'.format(
                    lyr['name']),
                                              item_type="Feature Layer")

                if len(addLayer) == 1:

                    # Check for styles in layer
                    if 'styles' in lyr and lyr['styles'] != '':

                        lyrStylesUrl = styleFrontUrl
                        sldFileURLTest = "{}{}".format(styleFrontUrl,
                                                       lyr['styles'])

                        if ".sld" in sldFileURLTest:
                            sldFileURL = sldFileURLTest
                        else:
                            sldFileURL = "{}.sld".format(sldFileURLTest)

                    else:
                        #Check the layer info page
                        lyrInfo = urllib.request.urlopen(
                            'http://worldmap.harvard.edu/data/{}'.format(
                                lyr['name']))
                        lyrInfoRD = lyrInfo.read()
                        lyrInfoRDDC = lyrInfoRD.decode('utf-8')

                        lyrInfoSoup = BeautifulSoup(lyrInfoRDDC)

                        spnTyle = lyrInfoSoup.find(
                            'span', attrs={'class': 'styles-list'})

                        if spnTyle:
                            styles = spnTyle.find_all('a')

                            if len(styles) > 0:
                                sldFileURL = styles[0].attrs['href']

                                # Need to write in how to distinguish renderer type
                                #simple_renderer = {"renderer": "autocast", "type": "simple"}
                                # Check the style Geometry

                    #test the url for a valid connectiono
                    try:
                        stylOpen = urllib.request.urlopen(sldFileURL).read()
                        stylOpenDecode = stylOpen.decode('utf-8')

                        if 'PolygonSymbolizer' in stylOpenDecode:
                            sldGeom = 'Polygon'
                        elif 'LineSymbolizer' in stylOpenDecode:
                            sldGeom = 'Polyline'
                        elif 'PointSymbolizer' in stylOpenDecode:
                            sldGeom = 'Point'

                        # Find the geometry type and pass it to the right render Geometry
                        #sldGeom = sldGeomLookup[publyrLookupID.geometryType.values[0]]
                        renren = ""
                        if sldGeom == 'Point':
                            pntRenderer = symbolsPoints.processPointSymbol(
                                sldFileURL)

                            renren = pntRenderer
                        if sldGeom == 'Polygon':
                            polyRenderer = symbolsPolygon.processPolygonSymbol(
                                sldFileURL)

                            if polyRenderer[1] == 'classbreaks':
                                sdf = pd.DataFrame.spatial.from_layer(
                                    addLayer[0].layers[0])

                                if polyRenderer[0]['field'][0] == '_':
                                    sdfRenFLD = 'F{}'.format(
                                        polyRenderer[0]['field'])
                                else:
                                    sdfRenFLD = polyRenderer[0]['field']

                                genRen = generate_renderer('Polygon',
                                                           sdf,
                                                           render_type='c',
                                                           field=sdfRenFLD)

                                brks = polyRenderer[0]['classBreakInfos']
                                genRen['classBreakInfos'] = brks

                                polyRenderer.pop(0)
                                polyRenderer.insert(0, genRen)

                            renren = polyRenderer

                        if sldGeom == 'Polyline':
                            lnRenderer = symbolsLines.processLineSymbol(
                                sldFileURL)

                            if lnRenderer[1] == 'classbreaks':
                                sdf = pd.DataFrame.spatial.from_layer(
                                    addLayer[0].layers[0])

                                if lnRenderer[0]['field'][0] == '_':
                                    sdfRenFLD = 'F{}'.format(
                                        lnRenderer[0]['field'])
                                else:
                                    sdfRenFLD = lnRenderer[0]['field']

                                genRen = generate_renderer('Polyline',
                                                           sdf,
                                                           render_type='c',
                                                           field=sdfRenFLD)

                                brks = lnRenderer[0]['classBreakInfos']
                                genRen['classBreakInfos'] = brks

                                lnRenderer.pop(0)
                                lnRenderer.insert(0, genRen)

                            renren = lnRenderer

                    #renren[0]["renderer"] = "autocast"

                    # Get the item from the org
                    #addLayer = gis.content.search(query='snippet:"{}"')
                    #addLayer = gis.content.get(publyrLookupID.itemID.values[0])
                        if renren != "":

                            empty_webmap.add_layer(
                                addLayer[0].layers[0], {
                                    "type": "FeatureLayer",
                                    "renderer": renren[0],
                                    'visibility': lyr['visibility']
                                })
                        else:
                            empty_webmap.add_layer(
                                addLayer[0].layers[0], {
                                    "type": "FeatureLayer",
                                    'visibility': lyr['visibility']
                                })

                    except:
                        empty_webmap.add_layer(
                            addLayer[0].layers[0], {
                                "type": "FeatureLayer",
                                'visibility': lyr['visibility']
                            })
                        pass

                        # Add an item update to remove the tracking snippet
                        # addLayer.update(item_properties={'snippet': "{}".format(lyr['title'])})
                    grpLyrs.append(lyr)

                else:
                    print('Current Layer {} does not have a featurelayer')
                    grpLyrs.append(lyr)
                    # # use the name to link over to the item ID
                # if not 'geonode:' in lyr['name']:
                #     llkUP = lyr['detail_url'].split("/")[-1]
                #     print(llkUP)
                # else:
                #     llkUP = lyr['name']
                #
                #
                # publyrLookupID = pubLyrDataFrame.query("geonodeSRC == '{}'".format(llkUP))

        grpDict[grpName] = grpLyrs

    webmapprops = {
        'title': '{}'.format(mTitle),
        'description': mapDesc,
        'licenseInfo': termsOfUse,
        'snippet': ' ',
        'tags': uniqueMpTags
    }

    empty_webmap.save(item_properties=webmapprops)
for layer in wm.definition['operationalLayers']:
    if layer['title'] in LayerDict:
        # Keep Original Title for Updating Content if Changing Title (Key Will Change)
        orig_title = layer['title']

        # Get List Index of Item (Updating Content Based on Index in OperationalLayers List in AGO)
        index = wm.definition['operationalLayers'].index(layer)

        # Change Dictionary/JSON values (Visiblity/Title Below) **Not Working Right Now***
        if LayerDict[layer['title']][2] is False:
            layer['visibility'] = False
        else:
            layer['visibility'] = True

        if LayerDict[layer['title']][1]:
            layer['title'] = LayerDict[layer['title']][1]

        # Grab JSON File Content and Use to Update AGO JSON (Using Layer Index in Operational Layers List)
        with open(LayerDict[orig_title][0]) as json_file:
            data = json.load(json_file)
            wm.definition['operationalLayers'][index] = data

# Set New Item Properties and Save Map
web_map_properties = {
    'title': 'AGRI Base Template',
    'snippet': 'Base Template for BC Ministry of Agriculture Web Maps',
    'tags': 'AGRI'
}
web_map_item = wm.save(item_properties=web_map_properties)

print("Done")
#Set the Title of the web map#
name = webmap_result.title

print ("The title of the map is " + name)
print("\n")

#Place the search result into the WebMap class#
webmap = WebMap(webmap_result)

#Collect and display a list of the layers within the web map#
layersList = webmap.layers

print ("Layers: \n")

for item in layersList:
    print (item.title)
    
print("\n")

#Establish the required Item Properties#
itemProperties = {'title':'Knoxville_QC_Map_Live_BACKUP_' + today, 
                   'snippet':'Backup Knoxville_QC_Map_Live map created using Python API', 
                   'tags':['automation', 'Backup']}

#Save the web map as a copy into the desired folder#
webmap.save(item_properties = itemProperties, folder = "Backup Web Maps")

print ("Backup Complete")

Beispiel #5
0
def create_map_add_views(views_dict,
                         web_map_title='web map title',
                         web_map_snippet='web map snippet',
                         web_map_tags='web map tags'):
    # create a map and add the views to it and then set the visibility of all them to false

    # create empty map
    web_map = WebMap()

    # add views to the map
    for key, value in views_dict.items():
        print(key)
        map_renderer = {
            "renderer": "autocast",  #This tells python to use JS autocasting
            "type": "classBreaks",
            "field": key,
            "minValue": 1
        }

        map_renderer["visualVariables"] = [{
            "type":
            "sizeInfo",
            "expression":
            "view.scale",
            "field":
            key,
            "stops": [{
                "size": 1.5,
                "value": 50921
            }, {
                "size": 0.75,
                "value": 159129
            }, {
                "size": 0.375,
                "value": 636517
            }, {
                "size": 0,
                "value": 1273034
            }]
        }]

        map_renderer["classBreakInfos"] = [{
            "symbol": {
                "color": [90, 106, 56, 255],
                "outline": {
                    "color": [194, 194, 194, 64],
                    "width": 0.75,
                    "type": "esriSLS",
                    "style": "esriSLSSolid"
                },
                "type": "esriSFS",
                "style": "esriSFSSolid"
            },
            "label": "1",
            "classMaxValue": 1
        }, {
            "symbol": {
                "color": [117, 144, 67, 255],
                "outline": {
                    "color": [194, 194, 194, 64],
                    "width": 0.75,
                    "type": "esriSLS",
                    "style": "esriSLSSolid"
                },
                "type": "esriSFS",
                "style": "esriSFSSolid"
            },
            "label": "2",
            "classMaxValue": 2
        }, {
            "symbol": {
                "color": [143, 178, 77, 255],
                "outline": {
                    "color": [194, 194, 194, 64],
                    "width": 0.75,
                    "type": "esriSLS",
                    "style": "esriSLSSolid"
                },
                "type": "esriSFS",
                "style": "esriSFSSolid"
            },
            "label": "3",
            "classMaxValue": 3
        }, {
            "symbol": {
                "color": [200, 223, 158, 255],
                "outline": {
                    "color": [194, 194, 194, 64],
                    "width": 0.75,
                    "type": "esriSLS",
                    "style": "esriSLSSolid"
                },
                "type": "esriSFS",
                "style": "esriSFSSolid"
            },
            "label": "4",
            "classMaxValue": 4
        }]
        web_map.add_layer(
            gis.content.get(views_dict[key]), {
                "type": "FeatureLayer",
                "renderer": map_renderer,
                "field_name": key,
                "minValue": 1
            })

    # save the map
    web_map_properties = {
        'title': web_map_title,
        'snippet': web_map_snippet,
        'tags': web_map_tags
    }

    web_map_item = web_map.save(item_properties=web_map_properties)

    # get json data of the web map
    map_search = gis.content.search(web_map_title)
    map_item = map_search[0]
    map_json = map_item.get_data()

    # set visibility to false
    for layer in map_json['operationalLayers']:
        layer['visibility'] = False

    # update the json file of the web map
    item_properties = {"text": json.dumps(map_json)}
    item = gis.content.get(map_item.id)
    item.update(item_properties=item_properties)

    return web_map_item
Beispiel #6
0
if len(existing_webmap) > 0:
    answer = input(
        '"{}" webmap exists, delete it? (y/n): '.format(webmap_name))
    for i in existing_webmap:
        delete_map(answer, i, webmap_name)

# Set the webmap properties and tags, then save it to my gis. If one already exists with the same name,
# it will create another one
webmap_item_properties = {
    'title': webmap_name,
    'snippet': webmap_name,
    'tags': ['webmap', 'epa', 'python']
}

print('saving webmap')
my_webmap.save(webmap_item_properties)

# wait until webmap exists before doing anything with it
my_webmap = my_gis.content.search(webmap_name, item_type="Web Map")

while len(my_webmap) == 0:
    my_webmap = my_gis.content.search(webmap_name, item_type="Web Map")
    if len(my_webmap) == 1:
        break

# to make changes to the initial map, need to share it publicly
my_webmap = my_webmap[0]
my_webmap.share(everyone=True)

# update extent of webmap- this one is Manhattan
update_parameters = {'extent': '-74.227,40.537,-73.601,40.862'}
        "width": 1,
        "type": "esriSLS",
        "style": "esriSLSSolid"
    },
    "type": "esriSFS",
    "style": "esriSFSDiagonalCross"
}
i = 0
while i < len(wm.layers):
    if wm.definition.operationalLayers[i].title == "Historic counties":
        print("Layer found in index: ", i)
        wm.definition.operationalLayers[
            i].title = "Historic counties (renamed)"
        wm.definition.operationalLayers[
            i].popupInfo.title = "Historic counties (also renamed)"
        wm.definition.operationalLayers[
            i].layerDefinition.drawingInfo.renderer.symbol = fillSymbolDiagonal
    i = i + 1

properties = {
    "title": "Webmap from the API",  # string.
    "snippet":
    "Short description",  # string. Provide a short summary (limit to max 250 characters) of the what the item is.
    "description":
    "Demo <b>webmap</b>",  # string. Provide a lists all sub-types, see URL 1 below for valid values.
    "tags": "webmap,python,api",
    "access": "public"
}
public_wm = wm.save(properties)

print("New webmap created: ", public_wm.itemid)