Visualize geospatial analytics data using a Colab notebook Stay organized with collections Save and categorize content based on your preferences.
In this tutorial, you visualize geospatial analytics data fromBigQuery by using a Colab notebook.
This tutorial uses the following BigQuerypublic datasets:
- San Francisco Ford GoBike Share
- San Francisco Neighborhoods
- San Francisco Police Department (SFPD) Reports
For information on accessing these public datasets, seeAccess public datasetsin the Google Cloud console.
You use the public datasets to create the following visualizations:
- Ascatter plot of all bike share stations from the Ford GoBike Sharedataset
- Polygons in the San Francisco Neighborhoods dataset
- Achoropleth map of the number of bike share stations by neighborhood
- Aheatmap of incidents from the San Francisco Police Department Reportsdataset
Objectives
- Set up authentication with Google Cloud and, optionally, Google Maps.
- Query data in BigQuery and download the results intoColab.
- Use Python data science tools to perform transformations and analyses.
- Create visualizations, including scatter plots, polygons, choropleths,and heatmaps.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage, use thepricing calculator.
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
- Create a project: To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission.Learn how to grant roles.
Verify that billing is enabled for your Google Cloud project.
Enable the BigQuery and Google Maps JavaScript APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
- Create a project: To create a project, you need the Project Creator role (
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission.Learn how to grant roles.
Verify that billing is enabled for your Google Cloud project.
Enable the BigQuery and Google Maps JavaScript APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.- Ensure that you have thenecessary permissions to perform the tasks in this document.
Required roles
If you create a new project, you are the project owner, and you are granted allof the required IAM permissions that you need to complete thistutorial.
If you are using an existing project you need the following project-level rolein order to run query jobs.
Make sure that you have the following role or roles on the project:
- BigQuery User (
roles/bigquery.user)
Check for the roles
In the Google Cloud console, go to theIAM page.
Go to IAM- Select the project.
In thePrincipal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check theRole column to see whether the list of roles includes the required roles.
Grant the roles
In the Google Cloud console, go to theIAM page.
Go to IAM- Select the project.
- ClickGrant access.
In theNew principals field, enter your user identifier. This is typically the email address for a Google Account.
- ClickSelect a role, then search for the role.
- To grant additional roles, clickAdd another role and add each additional role.
- ClickSave.
For more information about roles in BigQuery, seePredefinedIAM roles.
Create a Colab notebook
This tutorial builds a Colab notebook to visualizegeospatial analytics data. You can open a prebuilt version of thenotebook in Colab, Colab Enterprise, orBigQuery Studio by clicking the links at the top of the GitHub version ofthe tutorial—BigQuery Geospatial Visualization in Colab.
Open Colab.
In theOpen notebook dialog, clickNew notebook.
Click
Untitled0.ipynband change the name of the notebook tobigquery-geo.ipynb.SelectFile> Save.
Authenticate with Google Cloud and Google Maps
This tutorial queries BigQuery datasets and uses the Google MapsJavaScript API. To use these resources, you authenticate theColab runtime with Google Cloud and the Maps API.
Note: Using the Maps API is optional. You can run the code in this tutorialwithout using the Google Maps JavaScript API.Authenticate with Google Cloud
To insert a code cell, clickCode.
To authenticate with your project, enter the following code:
# REQUIRED: Authenticate with your project.GCP_PROJECT_ID="PROJECT_ID"#@param {type:"string"}fromgoogle.colabimportauthfromgoogle.colabimportuserdataauth.authenticate_user(project_id=GCP_PROJECT_ID)# Set GMP_API_KEY to noneGMP_API_KEY=None
ReplacePROJECT_ID with your project ID.
Click Runcell.
When prompted, clickAllow to give Colab access toyour credentials, if you agree.
On theSign in with Google page, choose your account.
On theSign in to Third-party authored notebook code page, clickContinue.
On theSelect what third-party authored notebook code can access, clickSelect all and then clickContinue.
After you complete the authorization flow, no output is generated in yourColab notebook. The check mark beside the cell indicates thatthe code ran successfully.
Optional: Authenticate with Google Maps
If you use Google Maps Platform as the map provider for base maps, you mustprovide a Google Maps Platform API key. The notebook retrieves the key fromyour Colab Secrets.
This step is necessary only if you're using the Maps API. If you don'tauthenticate with Google Maps Platform,pydeck uses thecarto map instead.
Get your Google Maps API key by following the instructions on theUse APIkeys page inthe Google Maps documentation.
Switch to your Colab notebook and then click Secrets.
ClickAdd new secret.
ForName, enter
GMP_API_KEY.ForValue, enter the Maps API key value you generated previously.
Close theSecrets panel.
To insert a code cell, clickCode.
To authenticate with the Maps API, enter the following code:
# Authenticate with the Google Maps JavaScript API.GMP_API_SECRET_KEY_NAME="GMP_API_KEY"#@param {type:"string"}ifGMP_API_SECRET_KEY_NAME:GMP_API_KEY=userdata.get(GMP_API_SECRET_KEY_NAME)ifGMP_API_SECRET_KEY_NAMEelseNoneelse:GMP_API_KEY=None
When prompted, clickGrant access to give the notebook access to yourkey, if you agree.
Click Runcell.
After you complete the authorization flow, no output is generated in yourColab notebook. The check mark beside the cell indicates thatthe code ran successfully.
Install Python packages and import data science libraries
In addition to thecolabtools (google.colab)Python modules, this tutorial uses several other Python packages and datascience libraries.
In this section, you install thepydeck andh3 packages.pydeckprovides high-scale spatial rendering in Python, powered bydeck.gl.h3-py provides Uber's H3 HexagonalHierarchical Geospatial Indexing System in Python.
You then import theh3 andpydeck libraries and the following Pythongeospatial libraries:
geopandasto extend thedatatypes used bypandasto allow spatialoperations on geometric types.shapelyformanipulation and analysis of individual planar geometric objects.brancato generate HTMLand JavaScript colormaps.geemap.deckfor visualization withpydeckandearthengine-api.
After importing the libraries, you enable interactive tables forpandasDataFrames in Colab.
Install thepydeck andh3 packages
To insert a code cell, clickCode.
To install the
pydeckandh3packages, enter the following code:# Install pydeck and h3.!pip install pydeck>=0.9 h3>=4.2
Click Runcell.
After you complete the installation, no output is generated in yourColab notebook. The check mark beside the cell indicates thatthe code ran successfully.
Import the Python libraries
To insert a code cell, clickCode.
To import the Python libraries, enter the following code:
# Import data science libraries.importbrancaimportgeemap.deckasgmdkimporth3importpydeckaspdkimportgeopandasasgpdimportshapely
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
Enable interactive tables for pandas DataFrames
To insert a code cell, clickCode.
To enable
pandasDataFrames, enter the following code:# Enable displaying pandas data frames as interactive tables by default.fromgoogle.colabimportdata_tabledata_table.enable_dataframe_formatter()
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
Create a shared routine
In this section, you create a shared routine that renders layers on a base map.
To insert a code cell, clickCode.
To create a shared routine for rendering layers on a map, enter thefollowing code:
# Set Google Maps as the base map provider.MAP_PROVIDER_GOOGLE=pdk.bindings.base_map_provider.BaseMapProvider.GOOGLE_MAPS.value# Shared routine for rendering layers on a map using geemap.deck.defdisplay_pydeck_map(layers,view_state,**kwargs):deck_kwargs=kwargs.copy()# Use Google Maps as the base map only if the API key is provided.ifGMP_API_KEY:deck_kwargs.update({"map_provider":MAP_PROVIDER_GOOGLE,"map_style":pdk.bindings.map_styles.GOOGLE_ROAD,"api_keys":{MAP_PROVIDER_GOOGLE:GMP_API_KEY},})m=gmdk.Map(initial_view_state=view_state,ee_initialize=False,**deck_kwargs)forlayerinlayers:m.add_layer(layer)returnm
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
Create a scatter plot
In this section, you create a scatter plot of all bike share stations in theSan Francisco Ford GoBike Share public dataset by retrieving data from thebigquery-public-data.san_francisco_bikeshare.bikeshare_station_info table. Thescatter plot is created using alayerand ascatterplot layerfrom thedeck.gl framework.
Scatter plots are useful when you need to review a subset of individual points(also known asspot checking).
The following example demonstrates how to use a layer and a scatterplot layerto render individual points as circles.
To insert a code cell, clickCode.
To query the San Francisco Ford GoBike Share public dataset, enter thefollowing code. This code uses the
%%bigquerymagic functionto run the query and return the results in a DataFrame:# Query the station ID, station name, station short name, and station# geometry from the bike share dataset.# NOTE: In this tutorial, the denormalized 'lat' and 'lon' columns are# ignored. They are decomposed components of the geometry.%%bigquerygdf_sf_bikestations--project{GCP_PROJECT_ID}--use_geodataframestation_geomSELECTstation_id,name,short_name,station_geomFROM`bigquery-public-data.san_francisco_bikeshare.bikeshare_station_info`
Click Runcell.
The output is similar to the following:
Job ID 12345-1234-5678-1234-123456789 successfully executed: 100%To insert a code cell, clickCode.
To get a summary of the DataFrame, including columns and data types,enter the following code:
# Get a summary of the DataFramegdf_sf_bikestations.info()
Click Runcell.
The output should look like the following:
<class 'geopandas.geodataframe.GeoDataFrame'>RangeIndex: 472 entries, 0 to 471Data columns (total 4 columns):# Column Non-Null Count Dtype--- ------ -------------- -----0 station_id 472 non-null object1 name 472 non-null object2 short_name 472 non-null object3 station_geom 472 non-null geometrydtypes: geometry(1), object(3)memory usage: 14.9+ KBTo insert a code cell, clickCode.
To preview the first five rows of the DataFrame, enter the following code:
# Preview the first five rowsgdf_sf_bikestations.head()
Click Runcell.
The output is similar to the following:

Rendering the points requires you to extract the longitude and latitude as x and y coordinates from thestation_geom column in the bike share dataset.
Sincegdf_sf_bikestations is ageopandas.GeoDataFrame, coordinates are accessed directly from itsstation_geom geometry column. You can retrieve the longitude using the column's.x attribute and the latitude using its.y attribute. Then, you can store them in new longitude and latitude columns.
To insert a code cell, clickCode.
To extract the longitude and latitude values from the
station_geomcolumn,enter the following code:# Extract the longitude (x) and latitude (y) from station_geom.gdf_sf_bikestations["longitude"]=gdf_sf_bikestations["station_geom"].xgdf_sf_bikestations["latitude"]=gdf_sf_bikestations["station_geom"].y
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
To insert a code cell, clickCode.
To render the scatter plot of bike share stations based on the longitude andlatitude values you extracted previously, enter the following code:
# Render a scatter plot using pydeck with the extracted longitude and# latitude columns in the gdf_sf_bikestations geopandas.GeoDataFrame.scatterplot_layer=pdk.Layer("ScatterplotLayer",id="bike_stations_scatterplot",data=gdf_sf_bikestations,get_position=['longitude','latitude'],get_radius=100,get_fill_color=[255,0,0,140],# Adjust color as desiredpickable=True,)view_state=pdk.ViewState(latitude=37.77613,longitude=-122.42284,zoom=12)display_pydeck_map([scatterplot_layer],view_state)
Click Runcell.
The output is similar to the following:

Visualize polygons
Geospatial analytics lets you analyze and visualize geospatial data inBigQuery by usingGEOGRAPHY data types and GoogleSQLgeography functions.
TheGEOGRAPHY data typein geospatial analytics is a collection of points, linestrings, andpolygons, which is represented as a point set, or a subset of the surface of theEarth. AGEOGRAPHY type can contain objects such as the following:
- Points
- Lines
- Polygons
- Multipolygons
For a list of all supported objects, see theGEOGRAPHY typedocumentation.
If you are provided geospatial data without knowing the expected shapes, you canvisualize the data to discover the shapes. You can visualize shapes byconverting the geographic data toGeoJSON format. Youcan then visualize theGeoJSON data using aGeoJSON layerfrom thedeck.gl framework.
In this section, you query geographic data in the San Francisco Neighborhoodsdataset and then visualize the polygons.
To insert a code cell, clickCode.
To query the geographic data from the
bigquery-public-data.san_francisco_neighborhoods.boundariestable in theSan Francisco Neighborhoods dataset, enter the following code. This codeuses the%%bigquerymagic functionto run the query and return the results in a DataFrame:# Query the neighborhood name and geometry from the San Francisco# neighborhoods dataset.%%bigquerygdf_sanfrancisco_neighborhoods--project{GCP_PROJECT_ID}--use_geodataframegeometrySELECTneighborhood,neighborhood_geomASgeometryFROM`bigquery-public-data.san_francisco_neighborhoods.boundaries`
Click Runcell.
The output is similar to the following:
Job ID 12345-1234-5678-1234-123456789 successfully executed: 100%To insert a code cell, clickCode.
To get a summary of the DataFrame, enter the following code:
# Get a summary of the DataFramegdf_sanfrancisco_neighborhoods.info()
Click Runcell.
The results should look like the following:
<class 'geopandas.geodataframe.GeoDataFrame'>RangeIndex: 117 entries, 0 to 116Data columns (total 2 columns):# Column Non-Null Count Dtype--- ------ -------------- -----0 neighborhood 117 non-null object1 geometry 117 non-null geometrydtypes: geometry(1), object(1)memory usage: 2.0+ KBTo preview the first row of the DataFrame, enter the following code:
# Preview the first rowgdf_sanfrancisco_neighborhoods.head(1)
Click Runcell.
The output is similar to the following:

In the results, notice that the data is a polygon.
To insert a code cell, clickCode.
To visualize the polygons, enter the following code.
pydeckis used toconvert eachshapelyobject instance in the geometry column intoGeoJSONformat:# Visualize the polygons.geojson_layer=pdk.Layer('GeoJsonLayer',id="sf_neighborhoods",data=gdf_sanfrancisco_neighborhoods,get_line_color=[127,0,127,255],get_fill_color=[60,60,60,50],get_line_width=100,pickable=True,stroked=True,filled=True,)view_state=pdk.ViewState(latitude=37.77613,longitude=-122.42284,zoom=12)display_pydeck_map([geojson_layer],view_state)
Click Runcell.
The output is similar to the following:

Create a choropleth map
If you are exploring data with polgyons that are difficult to convert toGeoJSON format, you can use apolygon layerfrom thedeck.gl framework instead. A polygon layer can process input data ofspecific types such as an array of points.
In this section, you use a polygon layer to render an array of points and usethe results to render a choropleth map. The choropleth map shows the density ofbike share stations by neighborhood by joining data from the San FranciscoNeighborhoods dataset with the San Francisco Ford GoBike Share dataset.
To insert a code cell, clickCode.
To aggregate and count the number of stations per neighborhood and to createa
polygoncolumn that contains an array of points, enter the followingcode:# Aggregate and count the number of stations per neighborhood.gdf_count_stations=gdf_sanfrancisco_neighborhoods.sjoin(gdf_sf_bikestations,how='left',predicate='contains')gdf_count_stations=gdf_count_stations.groupby(by='neighborhood')['station_id'].count().rename('num_stations')gdf_stations_x_neighborhood=gdf_sanfrancisco_neighborhoods.join(gdf_count_stations,on='neighborhood',how='inner')# To simulate non-GeoJSON input data, create a polygon column that contains# an array of points by using the pandas.Series.map method.gdf_stations_x_neighborhood['polygon']=gdf_stations_x_neighborhood['geometry'].map(lambdag:list(g.exterior.coords))
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
To insert a code cell, clickCode.
To add a
fill_colorcolumn for each of the polygons, enter the followingcode:# Create a color map gradient using the branch library, and add a fill_color# column for each of the polygons.colormap=branca.colormap.LinearColormap(colors=["lightblue","darkred"],vmin=0,vmax=gdf_stations_x_neighborhood['num_stations'].max(),)gdf_stations_x_neighborhood['fill_color']=gdf_stations_x_neighborhood['num_stations'] \.map(lambdac:list(colormap.rgba_bytes_tuple(c)[:3])+[0.7*255])# force opacity of 0.7
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
To insert a code cell, clickCode.
To render the polygon layer, enter the following code:
# Render the polygon layer.polygon_layer=pdk.Layer('PolygonLayer',id="bike_stations_choropleth",data=gdf_stations_x_neighborhood,get_polygon='polygon',get_fill_color='fill_color',get_line_color=[0,0,0,255],get_line_width=50,pickable=True,stroked=True,filled=True,)view_state=pdk.ViewState(latitude=37.77613,longitude=-122.42284,zoom=12)display_pydeck_map([polygon_layer],view_state)
Click Runcell.
The output is similar to the following:

Create a heatmap
Choropleths are useful when you have meaningful boundaries that are known. Ifyou have data with no known meaningful boundaries, you can use a heatmap layerto render its continuous density.
In the following example, you query data in thebigquery-public-data.san_francisco_sfpd_incidents.sfpd_incidents table in theSan Francisco Police Department (SFPD) Reports dataset. The data is used tovisualize the distribution of incidents in 2015.
For heatmaps, it is recommended that you quantize and aggregate the data beforerendering. In this example, the data is quantized and aggregated usingCartoH3 spatial indexing.The heatmap is created using aheatmap layerfrom thedeck.gl framework.
In this example, quantizing is done using theh3 Python library to aggregatethe incident points into hexagons. Theh3.latlng_to_cell function is used tomap the incident's position (latitude and longitude) to an H3 cell index. An H3resolution of nine provides sufficient aggregated hexagons for the heatmap.Theh3.cell_to_latlng function is used to determine the center of eachhexagon.
To insert a code cell, clickCode.
To query the data in the San Francisco Police Department (SFPD) Reportsdataset, enter the following code. This code uses the
%%bigquerymagicfunction to run thequery and return the results in a DataFrame:# Query the incident key and location data from the SFPD reports dataset.%%bigquerygdf_incidents--project{GCP_PROJECT_ID}--use_geodataframelocation_geographySELECTunique_key,location_geographyFROM(SELECTunique_key,SAFE.ST_GEOGFROMTEXT(location)ASlocation_geography,# WKT string to GEOMETRYEXTRACT(YEARFROMtimestamp)ASyear,FROM`bigquery-public-data.san_francisco_sfpd_incidents.sfpd_incidents`incidents)WHEREyear=2015
Click Runcell.
The output is similar to the following:
Job ID 12345-1234-5678-1234-123456789 successfully executed: 100%To insert a code cell, clickCode.
To compute the cell for each incident's latitude and longitude, aggregatethe incidents for each cell, construct a
geopandasDataFrame, and add thecenter of each hexagon for the heatmap layer, enter the following code:# Compute the cell for each incident's latitude and longitude.H3_RESOLUTION=9gdf_incidents['h3_cell']=gdf_incidents.geometry.apply(lambdageom:h3.latlng_to_cell(geom.y,geom.x,H3_RESOLUTION))# Aggregate the incidents for each hexagon cell.count_incidents=gdf_incidents.groupby(by='h3_cell')['unique_key'].count().rename('num_incidents')# Construct a new geopandas.GeoDataFrame with the aggregate results.# Add the center of each hexagon for the HeatmapLayer to render.gdf_incidents_x_cell=gpd.GeoDataFrame(data=count_incidents).reset_index()gdf_incidents_x_cell['h3_center']=gdf_incidents_x_cell['h3_cell'].apply(h3.cell_to_latlng)gdf_incidents_x_cell.info()
Click Runcell.
The output is similar to the following:
<class 'geopandas.geodataframe.GeoDataFrame'>RangeIndex: 969 entries, 0 to 968Data columns (total 3 columns):# Column Non-Null Count Dtype-- ------ -------------- -----0 h3_cell 969 non-null object1 num_incidents 969 non-null Int642 h3_center 969 non-null objectdtypes: Int64(1), object(2)memory usage: 23.8+ KBTo insert a code cell, clickCode.
To preview the first five rows of the DataFrame, enter the following code:
# Preview the first five rows.gdf_incidents_x_cell.head()
Click Runcell.
The output is similar to the following:

To insert a code cell, clickCode.
To convert the data into a JSON format that can be used by
HeatmapLayer,enter the following code:# Convert to a JSON format recognized by the HeatmapLayer.def_make_heatmap_datum(row)->dict:return{"latitude":row['h3_center'][0],"longitude":row['h3_center'][1],"weight":float(row['num_incidents']),}heatmap_data=gdf_incidents_x_cell.apply(_make_heatmap_datum,axis='columns').values.tolist()
Click Runcell.
After you run the code, no output is generated in your Colabnotebook. The check mark beside the cell indicates that the code ransuccessfully.
To insert a code cell, clickCode.
To render the heatmap, enter the following code:
# Render the heatmap.heatmap_layer=pdk.Layer("HeatmapLayer",id="sfpd_heatmap",data=heatmap_data,get_position=['longitude','latitude'],get_weight='weight',opacity=0.7,radius_pixels=99,# this limitation can introduce artifacts (see above)aggregation='MEAN',)view_state=pdk.ViewState(latitude=37.77613,longitude=-122.42284,zoom=12)display_pydeck_map([heatmap_layer],view_state)
Click Runcell.
The output is similar to the following:

Clean up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Delete the project
Console
gcloud
Delete your Google Maps API key and notebook
After you delete the Google Cloud project, if you used the Google MapsAPI, delete the Google Maps API key from your Colab Secrets andthen optionally delete the notebook.
In your Colab, click Secrets.
At the end of the
GMP_API_KEYrow, click Delete.Optional: To delete the notebook, clickFile> Move totrash.
What's next
- For more information on geospatial analytics in BigQuery, seeIntroduction to geospatial analytics in BigQuery.
- For an introduction to visualizing geospatial data in BigQuery,seeVisualize geospatial data.
- To learn more about
pydeckand otherdeck.glchart types, you can findexamples in thepydeckGallery,thedeck.glLayer Catalog,and thedeck.glGitHub source. - For more information on working with geospatial data in data frames, see theGeoPandas Getting started pageand theGeoPandas User guide.
- For more information on geometric object manipulation, see theShapely user manual.
- To explore using Google Earth Engine data in BigQuery, seeExporting to BigQueryin the Google Earth Engine documentation.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-18 UTC.