Accessing and creating content

Your GIS can host a variety of maps, web layers, analytical tools, apps and individual files. Using the gis module, you can search for, access and manage all your folders, contents and automate such maintenance workflows as scripts.

Import libraries

import os
import datetime as dt

import pandas 

from arcgis.gis import GIS
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\numpy\_distributor_init.py:30: UserWarning: loaded more than 1 DLL from .libs:
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\numpy\.libs\libopenblas64__v0.3.23-246-g3d31191b-gcc_10_3_0.dll
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\numpy\.libs\libopenblas64__v0.3.23-gcc_10_3_0.dll
  warnings.warn("loaded more than 1 DLL from .libs:"
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\scipy\__init__.py:138: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.25.2)
  warnings.warn(f"A NumPy version >={np_minversion} and <{np_maxversion} is required for this version of "

As mentioned in the gis module guide, the Python API uses Resource Manager classes to manage Web GIS users, groups, datastores, and content. You access the UserManager, GroupManager and ContentManager classes as the users, groups, and content properties of the GIS, respectively. (See Helper objects for details.)

Each resource manager implements the ArcGIS REST API search operation as a method. For example, gis.content.search(). It's important to understand that the search mechanism uses many different inputs to find possible matches, ranks them and returns appropriate results. The search becomes ideal for human interaction, but fuzzy when looking for specific records programmatically. The search results are non-deterministic. Using search may not necessarily be the best approach for finding specific items, but more a group of items from which to further filter.

It's also important to know that using search programmatically, like with the Python API, does not correspond identically to searching with an application written in a different language. The various search options in the ArcGIS Online or Portal for ArcGIS Enterprise interfaces work differently than the Python API resource managers' search. Different applications may use different inputs. The relationship between a content search in one application, like a Portal or ArcGIS Online viewer, is not one-to-one with a content search using the Python API even when logged in as the same user.

Let's look at an example to clarify:

# Log into ArcGIS Online
gis = GIS(profile='your_online_profile')
# Search for Feature Layers owned by the logged-in user
my_content = gis.content.search(query="owner:" + gis.users.me.username, 
                                item_type="Feature Layer", 
                                max_items=15)

my_content
[<Item title:"0ff721b591bb4526a0877b4708488db1" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"UnemploymentRateHotspots245326" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"6f0e42f4e35540b180f92263da913dba" type:Table Layer owner:arcgis_python>,
 <Item title:"6cf4c07182ef44c3b8d0f64f28a8fd7e" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"DissolveBoundaries18992" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"9b5bddb9555442f0b7420ba63aa4db40" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"DissolveBoundaries425210" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"test dffgvrdfbdffbg483152" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"c8b9af28c4164d6b8aeda68c95dfb2e5" type:Table Layer owner:arcgis_python>,
 <Item title:"api-downloads-1yr" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"5128c4b217154f6183e9313abc2baf04" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"0201001c228f41f38e5bb105146bca15" type:Table Layer owner:arcgis_python>,
 <Item title:"DissolveBoundaries803956" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"derive_new_loactions700970" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"CensusTract" type:Feature Layer Collection owner:arcgis_python>]

Using Fiddler to examine the REST API query made to the server, it looks like this:

https://geosaurus.maps.arcgis.com/sharing/rest/search?
    f=json
    &q=owner:arcgis_python AND (type:"feature service") accountid:xxxxxxxxxxxxxxxx
    &start=1
    &num=100
    &sortFields=avgRating
    &sortOrder=desc
    &token=<my_web_gis_token>   

Logging into the same ArcGIS Online Organization in a web browser as the same user, navigate to My Content, and then select All My Content in the Folders panel. Then navigate to the Filters panel, choose Layers and then further filter on Feature Layers. Using the Developer Tools of the web browser, examine the REST API Query and see it looks like this:

https://geosaurus.maps.arcgis.com/sharing/rest/search?
    num=20
    &start=1
    &sortField=modified
    &sortOrder=desc
    &q= owner:"arcgis_python" orgid:xxxxxxxxxxxxxxxx 
            (type:("Feature Collection" OR "Feature Service" OR "Stream Service" OR "WFS") 
            -typekeywords:"Table")  -type:("Code Attachment") -typekeywords:("MapAreaPackage") 
            -type:("Map Area")
    &f=json
    &token=<my_arcgis_online_token>
    
https://geosaurus.maps.arcgis.com/sharing/rest/search?
    num=6
    &start=0
    &sortField=title
    &sortOrder=asc
    &q=(group:"group_id1" AND 
        id:("item_id1" OR "item_id2" 
        OR "item_id3" OR "item_id4" 
        OR "item_id5" OR "item_id6"))
    &f=json
    &token=<my_arcgis_online_token>

The REST API queries differ between the applications written in different languages. You can expect different results between seemingly similiar queries to the same server when using different applications to search. The Python API search may return different results than the ArcGIS Enterprise or ArcGIS Online map viewers and other applications.

Search Tip

Python list comprehensions can augment the resource managers search functionality to allow for more precise queries.

NOTE: List comprehension processing is performed on the client side.

To return a list of items owned by the logged in user published on a specific day, create a datetime object to represent midnight as the start of the day, and a second datetime object representing the end of the day. Convert each to millisecond integers since that is how an ArcGIS portal stores date values.

day_start = dt.datetime(2019, 5, 30, 0, 0, 0, 0)
day_end = dt.datetime(2019, 5, 30, 23, 59, 59, 999999)

start_timestamp = int(day_start.timestamp() * 1000)
end_timestamp = int(day_end.timestamp() * 1000)

Use the timestamps in a list comprehension:

content_published_53019 = [item
                        for item in gis.content.search(query="* AND \
                                                owner:" + gis.users.me.username,
                                                max_items=50)
                        if item.created > start_timestamp 
                        and item.created < end_timestamp]

Write a function to return a human-readable date string and print the list

def readable_date(portal_stamp):
    return dt.datetime.fromtimestamp(portal_stamp/1000).strftime('%B %d %Y at %I:%M.%S %p')
title = "Item Title"
item_type = "Item Type"
publish = "Published"
print(f"{title:40}{item_type:25}{publish:40}")

for content in content_published_53019:
    print(f" {content.title:<40} {content.type:25} {readable_date(content.created):40}")
Item Title                              Item Type                Published                               

Searching for content

Accessing the content property of your gis object returns you an instance of ContentManager class. You can use the search() method of the ContentManager object to search for items on your GIS. You can use the search() even if you are connected as an anonymous user, in which case you get to search for public content on ArcGIS Online.

The first step is to import the API and connect to your GIS

from arcgis.gis import GIS
gis = GIS(profile="your_enterprise_profile")

Lets see what you get when you access content property

type(gis.content)
arcgis.gis.ContentManager

As explained earlier, we don't recommend creating an instance of the ContentManager directly, but instead recommend accessing it through the content property of your GIS object as shown below:

search_result = gis.content.search(query="title:Ports along US West Coast", item_type="Feature Layer")
search_result
[<Item title:"Ports in the Western US" type:Feature Layer Collection owner:api_data_owner>]

The search() method returned us a list of Item objects that matched the search criteria and that the logged in user had permissions to access. The query parameter supports a variety of inputs. Refer to the search reference for more ideas on what is supported. Some typical examples are shown below:

# search and list all feature layers in my contents
search_result = gis.content.search(query="", item_type="Feature Layer")
search_result
[<Item title:"Target_Parcels_with_Join_Pools_in_Redlands" type:Feature Layer Collection owner:rohitgeo>,
 <Item title:"wp_subset_urban_dist" type:Feature Layer Collection owner:arcgispyapibot>,
 <Item title:"SwimmingPools180605b" type:Feature Layer Collection owner:portaladmin>,
 <Item title:"68141df3a1a34243acd9466b35ea7c91" type:Feature Layer Collection owner:playground_test>,
 <Item title:"wp_clean_061722" type:Feature Layer Collection owner:arcgispyapibot>,
 <Item title:"Chennai_precipitation_1" type:Feature Layer Collection owner:arcgispyapibot>,
 <Item title:"FGDBEmpty" type:Feature Layer Collection owner:andrew>,
 <Item title:"be343ca6ccff47a5a100a5ecc358c3de" type:Feature Layer Collection owner:playground_test>,
 <Item title:"db7a39387c4b4f4ea138b7007dd6ebe4" type:Feature Layer Collection owner:jroebuck>,
 <Item title:"uganda_wp_buffer" type:Feature Layer Collection owner:arcgispyapibot>]

Notice how the search result includes items owned by other users that are shared across the organization. You can limit the search to only your content by specifying that in the query string as shown below:

search_my_contents = gis.content.search(query="owner:arcgis_python", 
                                        item_type="Feature *")
search_my_contents
[<Item title:"LT" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"Test CSV BRITISH CITIES2" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"test666" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"arun excel" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"LT" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"Flight Paths Polyline 1613812364" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"USA Capitals spreadsheet 1609855019" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"USA Capitals spreadsheet 1611799454" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"USA Capitals spreadsheet_1609936075" type:Feature Layer Collection owner:arcgis_python>,
 <Item title:"TEMPORAIRE" type:Feature Layer Collection owner:arcgis_python>]

Search supports usage of wild cards. You can use one asterisk * for multiple character wild card search and one question mark ? for single character.

search_result_USA = gis.content.search(query="title:USA*")                  
search_result_USA
[<Item title:"USA median age map" type:Web Map owner:arcgis_python>,
 <Item title:"USA median age map" type:Web Map owner:arcgis_python>,
 <Item title:"USA median age map" type:Web Map owner:arcgis_python>,
 <Item title:"USA Capitals spreadsheet 1613717378" type:CSV owner:arcgis_python>,
 <Item title:"USA median age map" type:Web Map owner:arcgis_python>,
 <Item title:"USA " type:Web Map owner:arcgis_python>,
 <Item title:"USA " type:Web Map owner:arcgis_python>,
 <Item title:"USA Capitals spreadsheet_1602810416" type:CSV owner:arcgis_python>,
 <Item title:"USA median age map" type:Web Map owner:arcgis_python>,
 <Item title:"USA median age map" type:Web Map owner:arcgis_python>]

Searching for content outside your portal

So far, we searched for content that belonged to the logged in user, as well as items shared within the portal and published by built-in accounts and other named users in the same portal. When connected to ArcGIS Online or connected to ArcGIS Enterprise configured to access ArcGIS Online, you can also search for content published and shared publicly even if the named users are in other portals. You can do so by turning the outside_org flag to True.

# search for content that begin with a prefix - say 'USA'
search_result_USA = gis.content.search(query="title:USA*", outside_org=True)                  
search_result_USA
[<Item title:"USA Major Cities" type:Web Map owner:esri_livingatlas>,
 <Item title:"USA Protected Areas - Public Access" type:Vector Tile Layer owner:esri_livingatlas>,
 <Item title:"USA Official Protraction Diagrams" type:Feature Layer Collection owner:esri_livingatlas>,
 <Item title:"USA SSURGO - Nonirrigated Capability Class" type:Imagery Layer owner:esri_livingatlas>,
 <Item title:"USA Forest Service Lands" type:Imagery Layer owner:esri_livingatlas>,
 <Item title:"USA Protected Areas - Protection Mechanism Category" type:Vector Tile Layer owner:esri_livingatlas>,
 <Item title:"2020 USA Per Capita Income" type:Map Image Layer owner:esri_livingatlas>,
 <Item title:"USA Protected Areas - GAP Status 2" type:Imagery Layer owner:esri_livingatlas>,
 <Item title:"2021 USA Child Care Spending" type:Map Image Layer owner:esri_livingatlas>,
 <Item title:"2020 USA Unemployment Rate" type:Map Image Layer owner:esri_livingatlas>]

Notice the Living Atlas content returned in the results. The portal administrator configured the portal to access Living Atlas centent.

When using the Jupyter notebook environment, you can utilize the rich representation of items for your query results.

from IPython.display import display
for item in search_result_USA:
    display(item)
USA Major Cities
This layer presents the locations of cities within United States with populations of 10,000 or greater (based on Census 2000 figures), all state capitals, and the national capital.Web Map by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA Protected Areas - Public Access
This vector tile layer displays public access from the USGS Protected Areas Database of the United States version 3.0.Vector Tile Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA Official Protraction Diagrams
USA Protraction Polygons based on the OCS Marine Survey Group Official Protraction Diagram.Feature Layer Collection by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA SSURGO - Nonirrigated Capability Class
Suitability of soil for practical use (such as agriculture) when irrigation is not used.Imagery Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA Forest Service Lands
Lands managed by the United States Forest Service including National Forests and National Grasslands.Imagery Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA Protected Areas - Protection Mechanism Category
This vector tile layer displays protection mechanism category from the USGS Protected Areas Database of the United States version 3.0.Vector Tile Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
2020 USA Per Capita Income
This layer shows per capita income (income per person) in the U.S. in 2020 in a multiscale map by country, state, county, ZIP Code, tract, and block group. ArcGIS Online subscription required.Map Image Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
USA Protected Areas - GAP Status 2
This imagery layer displays lands managed for biodiversity in the United States. Natural disturbances on these lands are suppressed.Imagery Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
2021 USA Child Care Spending
This layer shows the average amount spent on child care per household in the U.S. in 2021, by country, state, county, ZIP Code, tract, and block group. ArcGIS Online subscription required.Map Image Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views
2020 USA Unemployment Rate
This layer shows unemployment rates in the United States in 2020 in a multiscale map by country, state, county, ZIP Code, tract, and block group. ArcGIS Online subscription required.Map Image Layer by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views

Once you know an item's id (called itemId), you can access it using the get() method instead of searching for it.

# lets get the itemid of first item from previous query
first_item = search_result_USA[0]
known_item_id = first_item.id
print(known_item_id)
c7a0023f7c0a424e8bdff6d77c877f20
# lets use the get() to access this item
online_historic_item = gis.content.get(known_item_id)
online_historic_item
USA Major Cities
This layer presents the locations of cities within United States with populations of 10,000 or greater (based on Census 2000 figures), all state capitals, and the national capital.Web Map by esri_livingatlas
Last Modified: December 02, 2022
0 comments, 0 views

Searching for content in ArcGIS Online

So far, we searched for content accessible to a user logged into ArcGIS Enterprise. Let's connect directly to an ArcGIS Online Organization and futher explore ways to search for web GIS content.

# connect to ArcGIS Online
gis2 = GIS(profile="your_online_profile")

Let us search for public web scenes visualizing 3D cities. Note, I want to see content that is most popular by number of views to be returned on the top. I am also concerned that if too many items show up, the query might be running slow, hence restrict the results to 15 items.

public_3d_city_scenes = gis2.content.search(query="3d cities", item_type = "web scene",
                                           sort_field="numViews" ,sort_order="desc",
                                           max_items = 15, outside_org=True)
for item in public_3d_city_scenes:
    display(item)
Invozone_Catalyst_Cities_5bba6
Invozone_Catalyst_CitiesWeb Scene by viewproguest
Last Modified: June 28, 2021
0 comments, 854704 views
Capital City 3D (Web 2.0)
Web Scene by mat.sedgwick
Last Modified: October 24, 2022
0 comments, 550828 views
Visualize New Developments
Understand proposed changes in the context of your 3D City. Communicate changes with stakeholders and solicit public feedback.Web Scene by esri_3d
Last Modified: July 20, 2022
8 comments, 524723 views
Maa-amet 3D
Maa-ameti 3D kaardirakenduse stseen. Estonian Land Board 3D Web Scene.Web Scene by AndresKasekampMA
Last Modified: September 22, 2023
0 comments, 478363 views
CARTE 3D DE GENEVE
Web Scene by sitg
Last Modified: April 25, 2023
0 comments, 458768 views
Satellite Maps 3D Scene 2023 - for website
Satellite Maps 3D global with satellite imagery from GOES East, GOES West and NOAA-20 NOAA's two operational geostationary environmental satellites cover the western Pacific Ocean to the eastern Atlantic Ocean, while the operational polar-orbiting satellite circles the earth, providing coverage of the entire globe each day. The web map opens with GOES GeoColor day and night imagery. Select also infrared, water vapor, or the latest JPSS VIIRS daytime global map.Web Scene by rafael.deameller_noaa
Last Modified: July 24, 2023
0 comments, 163368 views
Winter Sun Exposure
Scene of shadows cast by mountains on the Winter Solstice from the hours of 10:00 to 11:00 at 15 minute intervals.Web Scene by jsapi_team
Last Modified: April 05, 2019
0 comments, 158568 views
Capital City (Web 3D)
Web Scene by msedgwick_Latitudegeo
Last Modified: July 06, 2020
0 comments, 130718 views
Human Reach - City Populations
Web Scene by whackney
Last Modified: June 19, 2020
0 comments, 122768 views
Boston development visualizations
Scene with development projects in the city of Boston.Web Scene by scene_viewer
Last Modified: October 26, 2018
0 comments, 111244 views
Berlin, Germany Scene
This scene highlights layers for Berlin, Germany available in ArcGIS to support your work in 3D. Use these layers in conjunction with your own layers to create new scenes focused on a specific topic or area of interest to you.Web Scene by esri_3d
Last Modified: May 01, 2020
0 comments, 89468 views
GeoZone_webscene
3D Map Portal for City of AubreyWeb Scene by viewpro_cityofaubrey
Last Modified: March 29, 2023
0 comments, 83349 views
Rotterdam, the Netherlands Scene
This scene highlights layers for Rotterdam, The Netherlands available in ArcGIS to support your work in 3D. Use these layers in conjunction with your own layers to create new scenes focused on a specific topic or area of interest to you.Web Scene by esri_3d
Last Modified: May 01, 2020
0 comments, 68416 views
City 3D
City of Bayswater 3D - innovationWeb Scene by Bayswater53
Last Modified: June 25, 2022
0 comments, 67476 views
Webscene Saving Sample
Basic web scene used in the Save a web scene sample in the JavaScript API Samples.Web Scene by jsapi_team
Last Modified: March 23, 2021
0 comments, 55291 views

Searching for content with multiple filtering clauses

So far, we searched for content with single condition listed in the query string. Let's further explore how to search with multiple filter clauses which refines the returned results in the web GIS content.

items = gis.content.search(query='owner:' + gis.users.me.username + ' type:map',
                           max_items=1000)
len(items)
475
items = gis.content.search(query='type:map AND owner:' + gis.users.me.username,
                           max_items=1000)
len(items)
475

When the search filters contain two or more clauses, the recommended schema is to have clauses separated by blank, or AND. The order of filters does not affect the search results if filters are separated by a space or with AND operator instead of a comma. The queries shown above return the same number of items.

However, when comma is used to separate search filters in a query string, then the order of filters affects the search results. For instance, the first cell below returns expected number of results, while the second cell returns no items in search results.

NOTE: When multiple filtering clauses separated by comma in the query parameter, the filtering condition for owner cannot be placed at the first position. For more, please check Search Reference.

items = gis.content.search(query='type:map, owner:' + gis.users.me.username,
                           max_items=1000)
len(items)
475
items = gis.content.search(query='owner:' + gis.users.me.username + ', type:map',
                           max_items=1000)
len(items)
0

You applied filters and optional parameters to search for content from other users in different organizations. This collaborative aspect of GIS is quite powerful. You can quickly scale up your projects by leveraging the maps and GIS data shared by other users. You can also get ideas on how to visualize or render a particular phenomenon through the experience of others who have shared how they completed it. You can do all of this using the API, easily writing scripts to automate tasks such as notifying you whenever someone shares an item in a particulare topic of interest.

So far, you observed how existing items can be searched and accessed using the gis module. Next, let us observe how new content can be created.

Creating new content

To create new items on your GIS, you use the add() method on a ContentManager instance. Again, rather than creating an instance of the ContentManager directly, the Python API implements the class as the content property of your GIS object.

The add() method accepts a dictionary containing the properties of the item to be created. The optional data parameter accepts a string path to a file. You can use the optional metadata parameter to specify an XML file containing metadata information.

All content you add this way is added to the authenticated user's contents. Let us connect to our Enterprise instance, add a csv file as an item and then publish a feature layer from it.

For example, set up a path to the data: data_path = os.path.join(r"<your_drive>:\\", "path", "to", "data")

data_path = (r".\data")

We are going to create an item titled "Earthquakes around the world from 1800s to early 1900s", but first let's see if there is any item already created with the same title by the current user, if it is then we'll delete it so that there are no duplicate items

username = gis.users.me.username
for earthquakes_csv_item in gis.content.search(query="title:Earthquakes around the world from 1800s to early 1900s AND owner:"+username):
    earthquakes_csv_item.delete()
csv_path = os.path.join(data_path, "earthquakes.csv")
csv_properties={'title':'Earthquakes around the world from 1800s to early 1900s',
                'description':'Measurements from globally distributed seismometers',
                'tags':'arcgis, python, earthquake, natural disaster, emergency'}
thumbnail_path = os.path.join(data_path, "earthquake.png")

earthquake_csv_item = gis.content.add(item_properties=csv_properties, data=csv_path,
                                     thumbnail = thumbnail_path)

The add() method returns an object of type arcgis.gis.Item representing the added item. In Jupyter notebook environment, you can visualize it by querying the item

earthquake_csv_item
Earthquakes around the world from 1800s to early 1900s
CSV by arcgis_python
Last Modified: October 12, 2023
0 comments, 0 views

Note: You can specify most properties of an item as a dictionary to the item_properties parameter. Refer to the API ref doc of this method for a definitive list. You could also specify an empty dictionary to this parameter, the downside is search cannot index these items efficiently if it does not have sufficient metadata information, hence that is not a good programming practice.

Publishing an item as a web layer

In the example above you added a csv Item to the portal. Items such as csv files, service definitions, file geodatabases, shapefiles and packages such as tile, scene and vector tile packages can be published into hosted web layers. You call the publish() method on the Item object to create the web layer.

Optionally, The publish() method accepts an optional publish_parameters dictionary where you can specify certain parameters. See the publish REST API documentation for detailed descriptions on these parameters. For instance, the address_fields parameter allows you to specify which field in your csv or dataset contains address fields suitable for geocoding.

Let us publish the csv into a web feature layer. This csv contains latitude and longitude coordinates of each point, hence the address_fields parameter can be ignored. The publish() method returns an Item object corresponding to the web layer created.

earthquake_feature_layer_item = earthquake_csv_item.publish()
earthquake_feature_layer_item
Earthquakes around the world from 1800s to early 1900s
Feature Layer Collection by arcgis_python
Last Modified: October 12, 2023
0 comments, 0 views

Notice that the GIS used the same metadata (thumbnail, title, description) of the source item used for publishing. This helps provide context on what the new item is and also as a good starting point for the metadata which you can edit later.

Importing data from a pandas data frame

Pandas is a popular data analysis library for Python. The data frame object of pandas allows you to store and analyze tabular information with ease. Using the Python API, you can import such data frames as an arcgis.features.FeatureCollection object using the import_data() method. You can then add that feature collection as an item to your GIS.

Let us create a new pandas data frame representing locations of a few coastal cities read from a csv file. Note, in the example below, you could publish the csv as an item as shown earlier, but we will observe how you can filter that data through pandas and add it as a feature collection instead.

# read csv as a pandas dataframe
ports_df = pandas.read_csv(os.path.join(data_path, "ports.csv"))
ports_df
countryglobalidharborsizelabel_positionlatitudelongitudeport_nameshort_formgeometry.xgeometry.y
0US{14FB62C9-1CEA-4F12-ACA4-14BB72F042BF}LSW37.816667-122.416667SAN FRANCISCOSFO-136273604553559
1US{6EE30C76-399D-42F5-B6ED-403C94DFFCD4}SSW37.783333-122.266667ALAMEDANGZ-136106604548863
2US{A6A21CC3-DE52-4B8A-A5B2-1CAA726E7F02}LSW37.816667-122.333333OAKLANDOAK-1361808045535590
3US{265AD7A6-4F59-4181-88DE-194F23F64E92}SSW37.916667-122.366667POINT RICHMONDRIC-136218004567660
4US{B15D545F-83DD-4D3E-9051-6D9F290A8E9E}SSW38.100000-122.266667MARE ISLANDNaN-136106604593562
5US{A97E8B59-1E25-416E-9206-4B59A869E2F4}SSW38.083333-122.250000SOUTH VALLEJONaN-136088104591205
6US{8EB57C5B-100B-4C50-B6B1-4D6B9B1C7545}SSW37.950000-121.300000STOCKTONSCK-135030504572365
7US{3B7B126E-0B60-49AF-89AA-4AC05402CFEA}SSW38.583333-121.500000SACRAMENTOSMF-135253204662162
8US{20378B4B-3E9E-47D2-AF42-4F0A31D5CA66}SSW40.800000-124.183333EUREKAACV-138240304982886
9US{782C11E0-B02D-45AB-8BAD-97C1B5817812}MSW43.400000-124.283333EMPIRENaN-138351605373055
10US{888593DC-D385-4A7C-A1F0-C9D46AB91353}SSW43.366667-124.216667COOS BAYNaN-138277405367950
11US{A04935D7-314D-43D3-AA39-99E91FE93BD5}MSW32.716667-117.183333SAN DIEGOSAN-130447903857756
12US{45CCFAFA-CE13-4EEE-907A-5C53A486C434}MSW33.766667-118.183333LONG BEACHLGH-131561103997514
13US{ECA58B5E-ADBB-4392-A6F2-1F5476E69375}SSW36.616667-121.883333MONTEREYMRY-135679904385809
14US{9B472045-E648-4371-906A-FCC35A7CB0B1}LSW45.516667-122.666667PORTLANDNaN-136551905703230
15US{B8AC37F8-5AA6-4D27-A401-7B35A8E4B9D3}SSW21.950000-159.350000NAWILIWILI BAYNaN-177387602505523
16US{6D718925-1CF2-4A45-9E3D-B4FBE215BA71}SSW21.900000-159.583333PORT ALLENNaN-177647402499523
17US{50ECBCE3-137E-45BF-A42E-F0D423434067}MSW21.300000-157.866667HONOLULUHNL-175736402427687
18US{9168C51F-28FF-4885-AFD5-18A1607E3808}SSW20.033333-155.833333KAWAIHAENaN-173472902276980
19US{A2A35C01-C1D4-4FD0-B74E-424E1A9DE20F}MSW19.733333-155.066667HILOITO-172619402241467
20US{BC904585-28E5-4995-9F6F-BCBDEE4D00C2}MSW45.633333-122.683333VANCOUVERNaN-136570505721784
# find latitude of SFO
lat = ports_df.loc[ports_df.port_name == 'SAN FRANCISCO']['latitude']
lat
0    37.816667
Name: latitude, dtype: float64
# only select ports that are to the south of SFO
ports_south_of_SFO = ports_df.loc[ports_df.latitude < lat[0]]
ports_south_of_SFO
countryglobalidharborsizelabel_positionlatitudelongitudeport_nameshort_formgeometry.xgeometry.y
1US{6EE30C76-399D-42F5-B6ED-403C94DFFCD4}SSW37.783333-122.266667ALAMEDANGZ-136106604548863
11US{A04935D7-314D-43D3-AA39-99E91FE93BD5}MSW32.716667-117.183333SAN DIEGOSAN-130447903857756
12US{45CCFAFA-CE13-4EEE-907A-5C53A486C434}MSW33.766667-118.183333LONG BEACHLGH-131561103997514
13US{ECA58B5E-ADBB-4392-A6F2-1F5476E69375}SSW36.616667-121.883333MONTEREYMRY-135679904385809
15US{B8AC37F8-5AA6-4D27-A401-7B35A8E4B9D3}SSW21.950000-159.350000NAWILIWILI BAYNaN-177387602505523
16US{6D718925-1CF2-4A45-9E3D-B4FBE215BA71}SSW21.900000-159.583333PORT ALLENNaN-177647402499523
17US{50ECBCE3-137E-45BF-A42E-F0D423434067}MSW21.300000-157.866667HONOLULUHNL-175736402427687
18US{9168C51F-28FF-4885-AFD5-18A1607E3808}SSW20.033333-155.833333KAWAIHAENaN-173472902276980
19US{A2A35C01-C1D4-4FD0-B74E-424E1A9DE20F}MSW19.733333-155.066667HILOITO-172619402241467

Now that we have the desired data frame, let us import that as a feature collection

ports_fc = gis.content.import_data(ports_south_of_SFO)
ports_fc
<FeatureCollection>

Next step is to convert the feature collection to a JSON and add it as a text based item to the GIS. The feature collection properties provides the layer definition and feature set for a layer. Construct a python dictionary from these properties, and then use the dictionary in a list as the layers property of a json featureCollection to add the item to the portal.

import json
ports_fc_dict = dict(ports_fc.properties)
ports_json = json.dumps({"featureCollection": {"layers": [ports_fc_dict]}})

We are going to create an item titled "Ports to the south of SFO along west coast of USA", but first let's see if there is any item already created with the same title by the current user, if it is then we'll delete it so that there are no duplicate items

for ports_item in gis.content.search(query="title:Ports to the south of SFO along west coast of USA AND owner:"+username):
    ports_item.delete()
ports_item_properties = {'title': 'Ports to the south of SFO along west coast of USA',
                        'description':'Example demonstrating conversion of pandas ' + \
                         'dataframe object to a GIS item',
                        'tags': 'arcgis python api, pandas, csv',
                        'text':ports_json,
                        'type':'Feature Collection'}
ports_item = gis.content.add(ports_item_properties)
ports_item
Ports to the south of SFO along west coast of USA
Feature Collection by arcgis_python
Last Modified: October 16, 2023
0 comments, 0 views

Note: here, we used the add() method to add the FeatureCollection object in memory as an item on the GIS. Notice we used the text property to pass the JSON representation of the feature collection and the type property to indicate the item type. You can use the same method to publish web maps and web scenes.

The sample notebooks for content publishers show how the concepts discussed here can be used to publish web maps and scenes to your GIS

Publishing an empty service

So far, we observed how an existing item can be used to publish a service. The ContentManager class allows you to publish a new service without any content using the create_service() method. This capability is useful when you want to create an empty service first then add content to it by editing it from client applications - Collector for ArcGIS for instance.

Before you create a service, you would want to ensure your desired service name is available. Since service name is part of the URL for a service, they need to be unique for a service type in an organization. For this purpose, you would use is_service_name_available() method.

Below, let us publish an empty feature service. If successful, the API would return a feature layer item.

# check if service name is available
gis.content.is_service_name_available(service_name= "awesome_python", service_type = 'featureService')
True
# let us publish an empty service
empty_service_item = gis.content.create_service(name='awesome_python', service_type='featureService')
empty_service_item
awesome_python
Feature Layer Collection by arcgis_python
Last Modified: October 16, 2023
0 comments, 0 views
# access the layers property of the item
empty_service_item.layers
[]

Notice that, there are no layers in this service. The first step when you edit such a service would be to update its service definition and enable the editing related capabilities.

Organizing content

Over time, your GIS can get filled with content. You can create folders on your GIS, just like in your file system, and use it to organize.

Using folders to organize your content

The create_folder() and delete_folder() methods available on the ContentManager class can be used to manage your folders. Once created, you can use the move() method to move content into and out of folders.

Let us create a folder called 'ports' and move the ports_item into it

# create new folder
gis.content.create_folder(folder='ports')
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\IPython\core\interactiveshell.py:3553: DeprecatedWarning: create_folder is deprecated as of 2.3.0 and has be removed in 3.0.0. Use `gis.content.folders.create` instead.
  exec(code_obj, self.user_global_ns, self.user_ns)
{'username': 'arcgis_python',
 'id': 'a2e4bca479bb4c1da0c5160f8c596e2b',
 'title': 'ports'}
# move the ports_item into this folder
ports_item.move(folder='ports')
{'success': True,
 'itemId': '5f85dc7bb8eb44d6b29fc142aa830ccd',
 'owner': 'arcgis_python',
 'folder': 'a2e4bca479bb4c1da0c5160f8c596e2b'}

You can move content out of folders to root by calling the move() method and specifying / as folder name

# move back to root
ports_item.move(folder='/')
{'success': True,
 'itemId': '5f85dc7bb8eb44d6b29fc142aa830ccd',
 'owner': 'arcgis_python',
 'folder': 'null'}
gis.content.delete_folder(folder='ports')
C:\Users\tar12555\AppData\Local\ESRI\conda\envs\pyapi-dev\lib\site-packages\IPython\core\interactiveshell.py:3553: DeprecatedWarning: delete_folder is deprecated as of 2.3.0 and has be removed in 3.0.0. Use `Folder.delete()` instead.
  exec(code_obj, self.user_global_ns, self.user_ns)
True

Summary

Thus, in this guide you observed how the gis module can be used to create new content and search for existing ones. Head over to the guide on managing-your-content next. When combined into a script, the ArcGIS API for Python becomes a powerful tool to automate your GIS content creation and management tasks.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.