// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package vectortile provides access to the Semantic Tile API.
//
// For product documentation, see: https://developers.google.com/maps/contact-sales/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/vectortile/v1"
//   ...
//   ctx := context.Background()
//   vectortileService, err := vectortile.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   vectortileService, err := vectortile.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   vectortileService, err := vectortile.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package vectortile // import "google.golang.org/api/vectortile/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "vectortile:v1"
const apiName = "vectortile"
const apiVersion = "v1"
const basePath = "https://vectortile.googleapis.com/"
const mtlsBasePath = "https://vectortile.mtls.googleapis.com/"

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Featuretiles = NewFeaturetilesService(s)
	s.Terraintiles = NewTerraintilesService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Featuretiles *FeaturetilesService

	Terraintiles *TerraintilesService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewFeaturetilesService(s *Service) *FeaturetilesService {
	rs := &FeaturetilesService{s: s}
	return rs
}

type FeaturetilesService struct {
	s *Service
}

func NewTerraintilesService(s *Service) *TerraintilesService {
	rs := &TerraintilesService{s: s}
	return rs
}

type TerraintilesService struct {
	s *Service
}

// Area: Represents an area. Used to represent regions such as water,
// parks, etc.
type Area struct {
	// HasExternalEdges: True if the polygon is not entirely internal to the
	// feature that it belongs to: that is, some of the edges are bordering
	// another feature.
	HasExternalEdges bool `json:"hasExternalEdges,omitempty"`

	// InternalEdges: When has_external_edges is true, the polygon has some
	// edges that border another feature. This field indicates the internal
	// edges that do not border another feature. Each value is an index into
	// the vertices array, and denotes the start vertex of the internal edge
	// (the next vertex in the boundary loop is the end of the edge). If the
	// selected vertex is the last vertex in the boundary loop, then the
	// edge between that vertex and the starting vertex of the loop is
	// internal. This field may be used for styling. For example, building
	// parapets could be placed only on the external edges of a building
	// polygon, or water could be lighter colored near the external edges of
	// a body of water. If has_external_edges is false, all edges are
	// internal and this field will be empty.
	InternalEdges []int64 `json:"internalEdges,omitempty"`

	// LoopBreaks: Identifies the boundary loops of the polygon. Only set
	// for INDEXED_TRIANGLE polygons. Each value is an index into the
	// vertices array indicating the beginning of a loop. For instance,
	// values of [2, 5] would indicate loop_data contained 3 loops with
	// indices 0-1, 2-4, and 5-end. This may be used in conjunction with the
	// internal_edges field for styling polygon boundaries. Note that an
	// edge may be on a polygon boundary but still internal to the feature.
	// For example, a feature split across multiple tiles will have an
	// internal polygon boundary edge along the edge of the tile.
	LoopBreaks []int64 `json:"loopBreaks,omitempty"`

	// TriangleIndices: When the polygon encoding is of type
	// INDEXED_TRIANGLES, this contains the indices of the triangle vertices
	// in the vertex_offsets field. There are 3 vertex indices per triangle.
	TriangleIndices []int64 `json:"triangleIndices,omitempty"`

	// Type: The polygon encoding type used for this area.
	//
	// Possible values:
	//   "TRIANGLE_FAN" - The first vertex in vertex_offset is the center of
	// a triangle fan. The other vertices are arranged around this vertex in
	// a fan shape. The following diagram showes a triangle fan polygon with
	// the vertices labelled with their indices in the vertex_offset list.
	// Triangle fan polygons always have a single boundary loop. Vertices
	// may be in either a clockwise or counterclockwise order. (1) / \ / \ /
	// \ (0)-----(2) / \ / / \ / / \ / (4)-----(3)
	//   "INDEXED_TRIANGLES" - The polygon is a set of triangles with three
	// vertex indices per triangle. The vertex indices can be found in the
	// triangle_indices field. Indexed triangle polygons also contain
	// information about boundary loops. These identify the loops at the
	// boundary of the polygon and may be used in conjunction with the
	// internal_edges field for styling. Boundary loops may represent either
	// a hole or a disconnected component of the polygon. The following
	// diagram shows an indexed triangle polygon with two boundary loops.
	// (0) (4) / \ / \ / \ / \ (1)----(2) (3)----(5)
	//   "TRIANGLE_STRIP" - A strip of triangles, where each triangle uses
	// the last edge of the previous triangle. Vertices may be in either a
	// clockwise or counterclockwise order. Only polygons without the
	// has_external_edges flag set will use triangle strips. (0) / \ / \ / \
	// (2)-----(1) / \ / / \ / / \ / (4)-----(3)
	Type string `json:"type,omitempty"`

	// VertexOffsets: The vertices present in the polygon defining the area.
	VertexOffsets *Vertex2DList `json:"vertexOffsets,omitempty"`

	// ZOrder: The z-ordering of this area. Areas with a lower z-order
	// should be rendered beneath areas with a higher z-order. This
	// z-ordering does not imply anything about the altitude of the line
	// relative to the ground, but it can be used to prevent z-fighting
	// during rendering on the client. This z-ordering can only be used to
	// compare areas, and cannot be compared with the z_order field in the
	// Line message. The z-order may be negative or zero.
	ZOrder int64 `json:"zOrder,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HasExternalEdges") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HasExternalEdges") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Area) MarshalJSON() ([]byte, error) {
	type NoMethod Area
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExtrudedArea: Represents a height-extruded area: a 3D prism with a
// constant X-Y plane cross section. Used to represent extruded
// buildings. A single building may consist of several extruded areas.
// The min_z and max_z fields are scaled to the size of the tile. An
// extruded area with a max_z value of 4096 has the same height as the
// width of the tile that it is on.
type ExtrudedArea struct {
	// Area: The area representing the footprint of the extruded area.
	Area *Area `json:"area,omitempty"`

	// MaxZ: The z-value in local tile coordinates where the extruded area
	// ends.
	MaxZ int64 `json:"maxZ,omitempty"`

	// MinZ: The z-value in local tile coordinates where the extruded area
	// begins. This is non-zero for extruded areas that begin off the
	// ground. For example, a building with a skybridge may have an extruded
	// area component with a non-zero min_z.
	MinZ int64 `json:"minZ,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Area") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Area") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ExtrudedArea) MarshalJSON() ([]byte, error) {
	type NoMethod ExtrudedArea
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Feature: A feature representing a single geographic entity.
type Feature struct {
	// DisplayName: The localized name of this feature. Currently only
	// returned for roads.
	DisplayName string `json:"displayName,omitempty"`

	// Geometry: The geometry of this feature, representing the space that
	// it occupies in the world.
	Geometry *Geometry `json:"geometry,omitempty"`

	// PlaceId: Place ID of this feature, suitable for use in Places API
	// details requests.
	PlaceId string `json:"placeId,omitempty"`

	// Relations: Relations to other features.
	Relations []*Relation `json:"relations,omitempty"`

	// SegmentInfo: Metadata for features with the SEGMENT FeatureType.
	SegmentInfo *SegmentInfo `json:"segmentInfo,omitempty"`

	// Type: The type of this feature.
	//
	// Possible values:
	//   "FEATURE_TYPE_UNSPECIFIED" - Unknown feature type.
	//   "STRUCTURE" - Structures such as buildings and bridges.
	//   "BAR" - A business serving alcoholic drinks to be consumed onsite.
	//   "BANK" - A financial institution that offers services to the
	// general public.
	//   "LODGING" - A place that provides any type of lodging for
	// travelers.
	//   "CAFE" - A business that sells coffee, tea, and sometimes small
	// meals.
	//   "RESTAURANT" - A business that prepares meals on-site for service
	// to customers.
	//   "EVENT_VENUE" - A venue for private and public events.
	//   "TOURIST_DESTINATION" - Place of interest to tourists, typically
	// for natural or cultural value.
	//   "SHOPPING" - A structure containing a business or businesses that
	// sell goods.
	//   "SCHOOL" - Institution where young people receive general (not
	// vocation or professional) education.
	//   "SEGMENT" - Segments such as roads and train lines.
	//   "ROAD" - A way leading from one place to another intended for use
	// by vehicles.
	//   "LOCAL_ROAD" - A small city street, typically for travel in a
	// residential neighborhood.
	//   "ARTERIAL_ROAD" - Major through road that's expected to carry large
	// volumes of traffic.
	//   "HIGHWAY" - A major road including freeways and state highways.
	//   "CONTROLLED_ACCESS_HIGHWAY" - A highway with grade-separated
	// crossings that is accessed exclusively by ramps. These are usually
	// called "freeways" or "motorways". The enable_detailed_highway_types
	// request flag must be set in order for this type to be returned.
	//   "FOOTPATH" - A path that's primarily intended for use by
	// pedestrians and/or cyclists.
	//   "RAIL" - Tracks intended for use by trains.
	//   "FERRY" - Services which are part of the road network but are not
	// roads.
	//   "REGION" - Non-water areas such as parks and forest.
	//   "PARK" - Outdoor areas such as parks and botanical gardens.
	//   "BEACH" - A pebbly or sandy shore along the edge of a sea or lake.
	//   "FOREST" - Area of land covered by trees.
	//   "POLITICAL" - Political entities, such as provinces and districts.
	//   "ADMINISTRATIVE_AREA1" - Top-level divisions within a country, such
	// as prefectures or states.
	//   "LOCALITY" - Cities, towns, and other municipalities.
	//   "SUBLOCALITY" - Divisions within a locality like a borough or ward.
	//   "WATER" - Water features such as rivers and lakes.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DisplayName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Feature) MarshalJSON() ([]byte, error) {
	type NoMethod Feature
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FeatureTile: A tile containing information about the map features
// located in the region it covers.
type FeatureTile struct {
	// Coordinates: The global tile coordinates that uniquely identify this
	// tile.
	Coordinates *TileCoordinates `json:"coordinates,omitempty"`

	// Features: Features present on this map tile.
	Features []*Feature `json:"features,omitempty"`

	// Name: Resource name of the tile. The tile resource name is prefixed
	// by its collection ID `tiles/` followed by the resource ID, which
	// encodes the tile's global x and y coordinates and zoom level as
	// `@,,z`. For example, `tiles/@1,2,3z`.
	Name string `json:"name,omitempty"`

	// Providers: Data providers for the data contained in this tile.
	Providers []*ProviderInfo `json:"providers,omitempty"`

	// Status: Tile response status code to support tile caching.
	//
	// Possible values:
	//   "STATUS_OK" - Everything worked out OK. The cache-control header
	// determines how long this Tile response may be cached by the client.
	// See also version_id and STATUS_OK_DATA_UNCHANGED.
	//   "STATUS_OK_DATA_UNCHANGED" - Indicates that the request was
	// processed successfully and that the tile data that would have been
	// returned are identical to the data already in the client's cache, as
	// specified by the value of client_tile_version_id contained in
	// GetFeatureTileRequest. In particular, the tile's features and
	// providers will not be populated when the tile data is identical.
	// However, the cache-control header and version_id can still change
	// even when the tile contents itself does not, so clients should always
	// use the most recent values returned by the API.
	Status string `json:"status,omitempty"`

	// VersionId: An opaque value, usually less than 30 characters, that
	// contains version info about this tile and the data that was used to
	// generate it. The client should store this value in its tile cache and
	// pass it back to the API in the client_tile_version_id field of
	// subsequent tile requests in order to enable the API to detect when
	// the new tile would be the same as the one the client already has in
	// its cache. Also see STATUS_OK_DATA_UNCHANGED.
	VersionId string `json:"versionId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Coordinates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Coordinates") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FeatureTile) MarshalJSON() ([]byte, error) {
	type NoMethod FeatureTile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirstDerivativeElevationGrid: A packed representation of a 2D grid of
// uniformly spaced points containing elevation data. Each point within
// the grid represents the altitude in meters above average sea level at
// that location within the tile. Elevations provided are (generally)
// relative to the EGM96 geoid, however some areas will be relative to
// NAVD88. EGM96 and NAVD88 are off by no more than 2 meters. The grid
// is oriented north-west to south-east, as illustrated: rows[0].a[0]
// rows[0].a[m] +-----------------+ | | | N | | ^ | | | | | W <-----> E
// | | | | | v | | S | | | +-----------------+ rows[n].a[0] rows[n].a[m]
// Rather than storing the altitudes directly, we store the diffs
// between them as integers at some requested level of precision to take
// advantage of integer packing. The actual altitude values a[] can be
// reconstructed using the scale and each row's first_altitude and
// altitude_diff fields.
type FirstDerivativeElevationGrid struct {
	// AltitudeMultiplier: A multiplier applied to the altitude fields below
	// to extract the actual altitudes in meters from the elevation grid.
	AltitudeMultiplier float64 `json:"altitudeMultiplier,omitempty"`

	// Rows: Rows of points containing altitude data making up the elevation
	// grid. Each row is the same length. Rows are ordered from north to
	// south. E.g: rows[0] is the north-most row, and rows[n] is the
	// south-most row.
	Rows []*Row `json:"rows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AltitudeMultiplier")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AltitudeMultiplier") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *FirstDerivativeElevationGrid) MarshalJSON() ([]byte, error) {
	type NoMethod FirstDerivativeElevationGrid
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *FirstDerivativeElevationGrid) UnmarshalJSON(data []byte) error {
	type NoMethod FirstDerivativeElevationGrid
	var s1 struct {
		AltitudeMultiplier gensupport.JSONFloat64 `json:"altitudeMultiplier"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.AltitudeMultiplier = float64(s1.AltitudeMultiplier)
	return nil
}

// Geometry: Represents the geometry of a feature, that is, the shape
// that it has on the map. The local tile coordinate system has the
// origin at the north-west (upper-left) corner of the tile, and is
// scaled to 4096 units across each edge. The height (Z) axis has the
// same scale factor: an extruded area with a max_z value of 4096 has
// the same height as the width of the tile that it is on. There is no
// clipping boundary, so it is possible that some coordinates will lie
// outside the tile boundaries.
type Geometry struct {
	// Areas: The areas present in this geometry.
	Areas []*Area `json:"areas,omitempty"`

	// ExtrudedAreas: The extruded areas present in this geometry.
	ExtrudedAreas []*ExtrudedArea `json:"extrudedAreas,omitempty"`

	// Lines: The lines present in this geometry.
	Lines []*Line `json:"lines,omitempty"`

	// ModeledVolumes: The modeled volumes present in this geometry.
	ModeledVolumes []*ModeledVolume `json:"modeledVolumes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Areas") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Areas") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Geometry) MarshalJSON() ([]byte, error) {
	type NoMethod Geometry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Line: Represents a 2D polyline. Used to represent segments such as
// roads, train tracks, etc.
type Line struct {
	// VertexOffsets: The vertices present in the polyline.
	VertexOffsets *Vertex2DList `json:"vertexOffsets,omitempty"`

	// ZOrder: The z-order of the line. Lines with a lower z-order should be
	// rendered beneath lines with a higher z-order. This z-ordering does
	// not imply anything about the altitude of the area relative to the
	// ground, but it can be used to prevent z-fighting during rendering on
	// the client. In general, larger and more important road features will
	// have a higher z-order line associated with them. This z-ordering can
	// only be used to compare lines, and cannot be compared with the
	// z_order field in the Area message. The z-order may be negative or
	// zero.
	ZOrder int64 `json:"zOrder,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VertexOffsets") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "VertexOffsets") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Line) MarshalJSON() ([]byte, error) {
	type NoMethod Line
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ModeledVolume: Represents a modeled volume in 3D space. Used to
// represent 3D buildings.
type ModeledVolume struct {
	// Strips: The triangle strips present in this mesh.
	Strips []*TriangleStrip `json:"strips,omitempty"`

	// VertexOffsets: The vertices present in the mesh defining the modeled
	// volume.
	VertexOffsets *Vertex3DList `json:"vertexOffsets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Strips") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Strips") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ModeledVolume) MarshalJSON() ([]byte, error) {
	type NoMethod ModeledVolume
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ProviderInfo: Information about the data providers that should be
// included in the attribution string shown by the client.
type ProviderInfo struct {
	// Description: Attribution string for this provider. This string is not
	// localized.
	Description string `json:"description,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProviderInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ProviderInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Relation: Represents a relation to another feature in the tile. For
// example, a building might be occupied by a given POI. The related
// feature can be retrieved using the related feature index.
type Relation struct {
	// RelatedFeatureIndex: Zero-based index to look up the related feature
	// from the list of features in the tile.
	RelatedFeatureIndex int64 `json:"relatedFeatureIndex,omitempty"`

	// RelationType: Relation type between the origin feature to the related
	// feature.
	//
	// Possible values:
	//   "RELATION_TYPE_UNSPECIFIED" - Unspecified relation type. Should
	// never happen.
	//   "OCCUPIES" - The origin feature occupies the related feature.
	//   "PRIMARILY_OCCUPIED_BY" - The origin feature is primarily occupied
	// by the related feature.
	RelationType string `json:"relationType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RelatedFeatureIndex")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RelatedFeatureIndex") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Relation) MarshalJSON() ([]byte, error) {
	type NoMethod Relation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RoadInfo: Extra metadata relating to roads.
type RoadInfo struct {
	// IsPrivate: Road has signage discouraging or prohibiting use by the
	// general public. E.g., roads with signs that say "Private", or "No
	// trespassing."
	IsPrivate bool `json:"isPrivate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IsPrivate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IsPrivate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoadInfo) MarshalJSON() ([]byte, error) {
	type NoMethod RoadInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Row: A row of altitude points in the elevation grid, ordered from
// west to east.
type Row struct {
	// AltitudeDiffs: The difference between each successive pair of
	// altitudes, from west to east. The first, westmost point, is just the
	// altitude rather than a diff. The units are specified by the
	// altitude_multiplier parameter above; the value in meters is given by
	// altitude_multiplier * altitude_diffs[n]. The altitude row (in metres
	// above sea level) can be reconstructed with: a[0] = altitude_diffs[0]
	// * altitude_multiplier when n > 0, a[n] = a[n-1] + altitude_diffs[n-1]
	// * altitude_multiplier.
	AltitudeDiffs []int64 `json:"altitudeDiffs,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AltitudeDiffs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AltitudeDiffs") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Row) MarshalJSON() ([]byte, error) {
	type NoMethod Row
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SecondDerivativeElevationGrid: A packed representation of a 2D grid
// of uniformly spaced points containing elevation data. Each point
// within the grid represents the altitude in meters above average sea
// level at that location within the tile. Elevations provided are
// (generally) relative to the EGM96 geoid, however some areas will be
// relative to NAVD88. EGM96 and NAVD88 are off by no more than 2
// meters. The grid is oriented north-west to south-east, as
// illustrated: rows[0].a[0] rows[0].a[m] +-----------------+ | | | N |
// | ^ | | | | | W <-----> E | | | | | v | | S | | | +-----------------+
// rows[n].a[0] rows[n].a[m] Rather than storing the altitudes directly,
// we store the diffs of the diffs between them as integers at some
// requested level of precision to take advantage of integer packing.
// Note that the data is packed in such a way that is fast to decode in
// Unity and that further optimizes wire size.
type SecondDerivativeElevationGrid struct {
	// AltitudeMultiplier: A multiplier applied to the elements in the
	// encoded data to extract the actual altitudes in meters.
	AltitudeMultiplier float64 `json:"altitudeMultiplier,omitempty"`

	// ColumnCount: The number of columns included in the encoded elevation
	// data (i.e. the horizontal resolution of the grid).
	ColumnCount int64 `json:"columnCount,omitempty"`

	// EncodedData: A stream of elements each representing a point on the
	// tile running across each row from left to right, top to bottom. There
	// will be precisely horizontal_resolution * vertical_resolution
	// elements in the stream. The elements are not the heights, rather the
	// second order derivative of the values one would expect in a stream of
	// height data. Each element is a varint with the following encoding:
	// ----------------------------------------------------------------------
	// --| | Head Nibble |
	// ----------------------------------------------------------------------
	// --| | Bit 0 | Bit 1 | Bits 2-3 | | Terminator| Sign (1=neg) | Least
	// significant 2 bits of absolute error |
	// ----------------------------------------------------------------------
	// --| | Tail Nibble #1 |
	// ----------------------------------------------------------------------
	// --| | Bit 0 | Bit 1-3 | | Terminator| Least significant 3 bits of
	// absolute error |
	// ----------------------------------------------------------------------
	// --| | ... | Tail Nibble #n |
	// ----------------------------------------------------------------------
	// --| | Bit 0 | Bit 1-3 | | Terminator| Least significant 3 bits of
	// absolute error |
	// ----------------------------------------------------------------------
	// --|
	EncodedData string `json:"encodedData,omitempty"`

	// RowCount: The number of rows included in the encoded elevation data
	// (i.e. the vertical resolution of the grid).
	RowCount int64 `json:"rowCount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AltitudeMultiplier")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AltitudeMultiplier") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SecondDerivativeElevationGrid) MarshalJSON() ([]byte, error) {
	type NoMethod SecondDerivativeElevationGrid
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *SecondDerivativeElevationGrid) UnmarshalJSON(data []byte) error {
	type NoMethod SecondDerivativeElevationGrid
	var s1 struct {
		AltitudeMultiplier gensupport.JSONFloat64 `json:"altitudeMultiplier"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.AltitudeMultiplier = float64(s1.AltitudeMultiplier)
	return nil
}

// SegmentInfo: Extra metadata relating to segments.
type SegmentInfo struct {
	// RoadInfo: Metadata for features with the ROAD FeatureType.
	RoadInfo *RoadInfo `json:"roadInfo,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RoadInfo") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RoadInfo") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SegmentInfo) MarshalJSON() ([]byte, error) {
	type NoMethod SegmentInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TerrainTile: A tile containing information about the terrain located
// in the region it covers.
type TerrainTile struct {
	// Coordinates: The global tile coordinates that uniquely identify this
	// tile.
	Coordinates *TileCoordinates `json:"coordinates,omitempty"`

	// FirstDerivative: Terrain elevation data encoded as a
	// FirstDerivativeElevationGrid.
	FirstDerivative *FirstDerivativeElevationGrid `json:"firstDerivative,omitempty"`

	// Name: Resource name of the tile. The tile resource name is prefixed
	// by its collection ID `terrain/` followed by the resource ID, which
	// encodes the tile's global x and y coordinates and zoom level as
	// `@,,z`. For example, `terrain/@1,2,3z`.
	Name string `json:"name,omitempty"`

	// SecondDerivative: Terrain elevation data encoded as a
	// SecondDerivativeElevationGrid. .
	SecondDerivative *SecondDerivativeElevationGrid `json:"secondDerivative,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Coordinates") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Coordinates") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TerrainTile) MarshalJSON() ([]byte, error) {
	type NoMethod TerrainTile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TileCoordinates: Global tile coordinates. Global tile coordinates
// reference a specific tile on the map at a specific zoom level. The
// origin of this coordinate system is always at the northwest corner of
// the map, with x values increasing from west to east and y values
// increasing from north to south. Tiles are indexed using x, y
// coordinates from that origin. The zoom level containing the entire
// world in a tile is 0, and it increases as you zoom in. Zoom level n +
// 1 will contain 4 times as many tiles as zoom level n. The zoom level
// controls the level of detail of the data that is returned. In
// particular, this affects the set of feature types returned, their
// density, and geometry simplification. The exact tile contents may
// change over time, but care will be taken to keep supporting the most
// important use cases. For example, zoom level 15 shows roads for
// orientation and planning in the local neighborhood and zoom level 17
// shows buildings to give users on foot a sense of situational
// awareness.
type TileCoordinates struct {
	// X: Required. The x coordinate.
	X int64 `json:"x,omitempty"`

	// Y: Required. The y coordinate.
	Y int64 `json:"y,omitempty"`

	// Zoom: Required. The Google Maps API zoom level.
	Zoom int64 `json:"zoom,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TileCoordinates) MarshalJSON() ([]byte, error) {
	type NoMethod TileCoordinates
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TriangleStrip: Represents a strip of triangles. Each triangle uses
// the last edge of the previous one. The following diagram shows an
// example of a triangle strip, with each vertex labeled with its index
// in the vertex_index array. (1)-----(3) / \ / \ / \ / \ / \ / \
// (0)-----(2)-----(4) Vertices may be in either clockwise or
// counter-clockwise order.
type TriangleStrip struct {
	// VertexIndices: Index into the vertex_offset array representing the
	// next vertex in the triangle strip.
	VertexIndices []int64 `json:"vertexIndices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VertexIndices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "VertexIndices") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TriangleStrip) MarshalJSON() ([]byte, error) {
	type NoMethod TriangleStrip
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Vertex2DList: 2D vertex list used for lines and areas. Each entry
// represents an offset from the previous one in local tile coordinates.
// The first entry is offset from (0, 0). For example, the list of
// vertices [(1,1), (2, 2), (1, 2)] would be encoded in vertex offsets
// as [(1, 1), (1, 1), (-1, 0)].
type Vertex2DList struct {
	// XOffsets: List of x-offsets in local tile coordinates.
	XOffsets []int64 `json:"xOffsets,omitempty"`

	// YOffsets: List of y-offsets in local tile coordinates.
	YOffsets []int64 `json:"yOffsets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "XOffsets") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "XOffsets") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Vertex2DList) MarshalJSON() ([]byte, error) {
	type NoMethod Vertex2DList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Vertex3DList: 3D vertex list used for modeled volumes. Each entry
// represents an offset from the previous one in local tile coordinates.
// The first coordinate is offset from (0, 0, 0).
type Vertex3DList struct {
	// XOffsets: List of x-offsets in local tile coordinates.
	XOffsets []int64 `json:"xOffsets,omitempty"`

	// YOffsets: List of y-offsets in local tile coordinates.
	YOffsets []int64 `json:"yOffsets,omitempty"`

	// ZOffsets: List of z-offsets in local tile coordinates.
	ZOffsets []int64 `json:"zOffsets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "XOffsets") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "XOffsets") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Vertex3DList) MarshalJSON() ([]byte, error) {
	type NoMethod Vertex3DList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "vectortile.featuretiles.get":

type FeaturetilesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a feature tile by its tile resource name.
func (r *FeaturetilesService) Get(name string) *FeaturetilesGetCall {
	c := &FeaturetilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ClientInfoApiClient sets the optional parameter
// "clientInfo.apiClient": API client name and version. For example, the
// SDK calling the API. The exact format is up to the client.
func (c *FeaturetilesGetCall) ClientInfoApiClient(clientInfoApiClient string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.apiClient", clientInfoApiClient)
	return c
}

// ClientInfoApplicationId sets the optional parameter
// "clientInfo.applicationId": Application ID, such as the package name
// on Android and the bundle identifier on iOS platforms.
func (c *FeaturetilesGetCall) ClientInfoApplicationId(clientInfoApplicationId string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.applicationId", clientInfoApplicationId)
	return c
}

// ClientInfoApplicationVersion sets the optional parameter
// "clientInfo.applicationVersion": Application version number, such as
// "1.2.3". The exact format is application-dependent.
func (c *FeaturetilesGetCall) ClientInfoApplicationVersion(clientInfoApplicationVersion string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.applicationVersion", clientInfoApplicationVersion)
	return c
}

// ClientInfoDeviceModel sets the optional parameter
// "clientInfo.deviceModel": Device model as reported by the device. The
// exact format is platform-dependent.
func (c *FeaturetilesGetCall) ClientInfoDeviceModel(clientInfoDeviceModel string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.deviceModel", clientInfoDeviceModel)
	return c
}

// ClientInfoOperatingSystem sets the optional parameter
// "clientInfo.operatingSystem": Operating system name and version as
// reported by the OS. For example, "Mac OS X 10.10.4". The exact format
// is platform-dependent.
func (c *FeaturetilesGetCall) ClientInfoOperatingSystem(clientInfoOperatingSystem string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.operatingSystem", clientInfoOperatingSystem)
	return c
}

// ClientInfoPlatform sets the optional parameter "clientInfo.platform":
// Platform where the application is running.
//
// Possible values:
//   "PLATFORM_UNSPECIFIED" - Unspecified or unknown OS.
//   "EDITOR" - Development environment.
//   "MAC_OS" - macOS.
//   "WINDOWS" - Windows.
//   "LINUX" - Linux
//   "ANDROID" - Android
//   "IOS" - iOS
//   "WEB_GL" - WebGL.
func (c *FeaturetilesGetCall) ClientInfoPlatform(clientInfoPlatform string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.platform", clientInfoPlatform)
	return c
}

// ClientInfoUserId sets the optional parameter "clientInfo.userId":
// Required. A client-generated user ID. The ID should be generated and
// persisted during the first user session or whenever a pre-existing ID
// is not found. The exact format is up to the client. This must be
// non-empty in a GetFeatureTileRequest (whether via the header or
// GetFeatureTileRequest.client_info).
func (c *FeaturetilesGetCall) ClientInfoUserId(clientInfoUserId string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientInfo.userId", clientInfoUserId)
	return c
}

// ClientTileVersionId sets the optional parameter
// "clientTileVersionId": Optional version id identifying the tile that
// is already in the client's cache. This field should be populated with
// the most recent version_id value returned by the API for the
// requested tile. If the version id is empty the server always returns
// a newly rendered tile. If it is provided the server checks if the
// tile contents would be identical to one that's already on the client,
// and if so, returns a stripped-down response tile with
// STATUS_OK_DATA_UNCHANGED instead.
func (c *FeaturetilesGetCall) ClientTileVersionId(clientTileVersionId string) *FeaturetilesGetCall {
	c.urlParams_.Set("clientTileVersionId", clientTileVersionId)
	return c
}

// EnableDetailedHighwayTypes sets the optional parameter
// "enableDetailedHighwayTypes": Flag indicating whether detailed
// highway types should be returned. If this is set, the
// CONTROLLED_ACCESS_HIGHWAY type may be returned. If not, then these
// highways will have the generic HIGHWAY type. This exists for
// backwards compatibility reasons.
func (c *FeaturetilesGetCall) EnableDetailedHighwayTypes(enableDetailedHighwayTypes bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enableDetailedHighwayTypes", fmt.Sprint(enableDetailedHighwayTypes))
	return c
}

// EnableFeatureNames sets the optional parameter "enableFeatureNames":
// Flag indicating whether human-readable names should be returned for
// features. If this is set, the display_name field on the feature will
// be filled out.
func (c *FeaturetilesGetCall) EnableFeatureNames(enableFeatureNames bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enableFeatureNames", fmt.Sprint(enableFeatureNames))
	return c
}

// EnableModeledVolumes sets the optional parameter
// "enableModeledVolumes": Flag indicating whether 3D building models
// should be enabled. If this is set structures will be returned as 3D
// modeled volumes rather than 2.5D extruded areas where possible.
func (c *FeaturetilesGetCall) EnableModeledVolumes(enableModeledVolumes bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enableModeledVolumes", fmt.Sprint(enableModeledVolumes))
	return c
}

// EnablePoliticalFeatures sets the optional parameter
// "enablePoliticalFeatures": Flag indicating whether political features
// should be returned.
func (c *FeaturetilesGetCall) EnablePoliticalFeatures(enablePoliticalFeatures bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enablePoliticalFeatures", fmt.Sprint(enablePoliticalFeatures))
	return c
}

// EnablePrivateRoads sets the optional parameter "enablePrivateRoads":
// Flag indicating whether the returned tile will contain road features
// that are marked private. Private roads are indicated by the
// Feature.segment_info.road_info.is_private field.
func (c *FeaturetilesGetCall) EnablePrivateRoads(enablePrivateRoads bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enablePrivateRoads", fmt.Sprint(enablePrivateRoads))
	return c
}

// EnableUnclippedBuildings sets the optional parameter
// "enableUnclippedBuildings": Flag indicating whether unclipped
// buildings should be returned. If this is set, building render ops
// will extend beyond the tile boundary. Buildings will only be returned
// on the tile that contains their centroid.
func (c *FeaturetilesGetCall) EnableUnclippedBuildings(enableUnclippedBuildings bool) *FeaturetilesGetCall {
	c.urlParams_.Set("enableUnclippedBuildings", fmt.Sprint(enableUnclippedBuildings))
	return c
}

// LanguageCode sets the optional parameter "languageCode": Required.
// The BCP-47 language code corresponding to the language in which the
// name was requested, such as "en-US" or "sr-Latn". For more
// information, see
// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
func (c *FeaturetilesGetCall) LanguageCode(languageCode string) *FeaturetilesGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// RegionCode sets the optional parameter "regionCode": Required. The
// Unicode country/region code (CLDR) of the location from which the
// request is coming from, such as "US" and "419". For more information,
// see http://www.unicode.org/reports/tr35/#unicode_region_subtag.
func (c *FeaturetilesGetCall) RegionCode(regionCode string) *FeaturetilesGetCall {
	c.urlParams_.Set("regionCode", regionCode)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FeaturetilesGetCall) Fields(s ...googleapi.Field) *FeaturetilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FeaturetilesGetCall) IfNoneMatch(entityTag string) *FeaturetilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FeaturetilesGetCall) Context(ctx context.Context) *FeaturetilesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FeaturetilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FeaturetilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "vectortile.featuretiles.get" call.
// Exactly one of *FeatureTile or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *FeatureTile.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FeaturetilesGetCall) Do(opts ...googleapi.CallOption) (*FeatureTile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FeatureTile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a feature tile by its tile resource name.",
	//   "flatPath": "v1/featuretiles/{featuretilesId}",
	//   "httpMethod": "GET",
	//   "id": "vectortile.featuretiles.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "clientInfo.apiClient": {
	//       "description": "API client name and version. For example, the SDK calling the API. The exact format is up to the client.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.applicationId": {
	//       "description": "Application ID, such as the package name on Android and the bundle identifier on iOS platforms.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.applicationVersion": {
	//       "description": "Application version number, such as \"1.2.3\". The exact format is application-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.deviceModel": {
	//       "description": "Device model as reported by the device. The exact format is platform-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.operatingSystem": {
	//       "description": "Operating system name and version as reported by the OS. For example, \"Mac OS X 10.10.4\". The exact format is platform-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.platform": {
	//       "description": "Platform where the application is running.",
	//       "enum": [
	//         "PLATFORM_UNSPECIFIED",
	//         "EDITOR",
	//         "MAC_OS",
	//         "WINDOWS",
	//         "LINUX",
	//         "ANDROID",
	//         "IOS",
	//         "WEB_GL"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified or unknown OS.",
	//         "Development environment.",
	//         "macOS.",
	//         "Windows.",
	//         "Linux",
	//         "Android",
	//         "iOS",
	//         "WebGL."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.userId": {
	//       "description": "Required. A client-generated user ID. The ID should be generated and persisted during the first user session or whenever a pre-existing ID is not found. The exact format is up to the client. This must be non-empty in a GetFeatureTileRequest (whether via the header or GetFeatureTileRequest.client_info).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientTileVersionId": {
	//       "description": "Optional version id identifying the tile that is already in the client's cache. This field should be populated with the most recent version_id value returned by the API for the requested tile. If the version id is empty the server always returns a newly rendered tile. If it is provided the server checks if the tile contents would be identical to one that's already on the client, and if so, returns a stripped-down response tile with STATUS_OK_DATA_UNCHANGED instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "enableDetailedHighwayTypes": {
	//       "description": "Flag indicating whether detailed highway types should be returned. If this is set, the CONTROLLED_ACCESS_HIGHWAY type may be returned. If not, then these highways will have the generic HIGHWAY type. This exists for backwards compatibility reasons.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enableFeatureNames": {
	//       "description": "Flag indicating whether human-readable names should be returned for features. If this is set, the display_name field on the feature will be filled out.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enableModeledVolumes": {
	//       "description": "Flag indicating whether 3D building models should be enabled. If this is set structures will be returned as 3D modeled volumes rather than 2.5D extruded areas where possible.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enablePoliticalFeatures": {
	//       "description": "Flag indicating whether political features should be returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enablePrivateRoads": {
	//       "description": "Flag indicating whether the returned tile will contain road features that are marked private. Private roads are indicated by the Feature.segment_info.road_info.is_private field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enableUnclippedBuildings": {
	//       "description": "Flag indicating whether unclipped buildings should be returned. If this is set, building render ops will extend beyond the tile boundary. Buildings will only be returned on the tile that contains their centroid.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "languageCode": {
	//       "description": "Required. The BCP-47 language code corresponding to the language in which the name was requested, such as \"en-US\" or \"sr-Latn\". For more information, see http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Resource name of the tile. The tile resource name is prefixed by its collection ID `tiles/` followed by the resource ID, which encodes the tile's global x and y coordinates and zoom level as `@,,z`. For example, `tiles/@1,2,3z`.",
	//       "location": "path",
	//       "pattern": "^featuretiles/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "regionCode": {
	//       "description": "Required. The Unicode country/region code (CLDR) of the location from which the request is coming from, such as \"US\" and \"419\". For more information, see http://www.unicode.org/reports/tr35/#unicode_region_subtag.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "FeatureTile"
	//   }
	// }

}

// method id "vectortile.terraintiles.get":

type TerraintilesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a terrain tile by its tile resource name.
func (r *TerraintilesService) Get(name string) *TerraintilesGetCall {
	c := &TerraintilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// AltitudePrecisionCentimeters sets the optional parameter
// "altitudePrecisionCentimeters": The precision of terrain altitudes in
// centimeters. Possible values: between 1 (cm level precision) and
// 1,000,000 (10-kilometer level precision).
func (c *TerraintilesGetCall) AltitudePrecisionCentimeters(altitudePrecisionCentimeters int64) *TerraintilesGetCall {
	c.urlParams_.Set("altitudePrecisionCentimeters", fmt.Sprint(altitudePrecisionCentimeters))
	return c
}

// ClientInfoApiClient sets the optional parameter
// "clientInfo.apiClient": API client name and version. For example, the
// SDK calling the API. The exact format is up to the client.
func (c *TerraintilesGetCall) ClientInfoApiClient(clientInfoApiClient string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.apiClient", clientInfoApiClient)
	return c
}

// ClientInfoApplicationId sets the optional parameter
// "clientInfo.applicationId": Application ID, such as the package name
// on Android and the bundle identifier on iOS platforms.
func (c *TerraintilesGetCall) ClientInfoApplicationId(clientInfoApplicationId string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.applicationId", clientInfoApplicationId)
	return c
}

// ClientInfoApplicationVersion sets the optional parameter
// "clientInfo.applicationVersion": Application version number, such as
// "1.2.3". The exact format is application-dependent.
func (c *TerraintilesGetCall) ClientInfoApplicationVersion(clientInfoApplicationVersion string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.applicationVersion", clientInfoApplicationVersion)
	return c
}

// ClientInfoDeviceModel sets the optional parameter
// "clientInfo.deviceModel": Device model as reported by the device. The
// exact format is platform-dependent.
func (c *TerraintilesGetCall) ClientInfoDeviceModel(clientInfoDeviceModel string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.deviceModel", clientInfoDeviceModel)
	return c
}

// ClientInfoOperatingSystem sets the optional parameter
// "clientInfo.operatingSystem": Operating system name and version as
// reported by the OS. For example, "Mac OS X 10.10.4". The exact format
// is platform-dependent.
func (c *TerraintilesGetCall) ClientInfoOperatingSystem(clientInfoOperatingSystem string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.operatingSystem", clientInfoOperatingSystem)
	return c
}

// ClientInfoPlatform sets the optional parameter "clientInfo.platform":
// Platform where the application is running.
//
// Possible values:
//   "PLATFORM_UNSPECIFIED" - Unspecified or unknown OS.
//   "EDITOR" - Development environment.
//   "MAC_OS" - macOS.
//   "WINDOWS" - Windows.
//   "LINUX" - Linux
//   "ANDROID" - Android
//   "IOS" - iOS
//   "WEB_GL" - WebGL.
func (c *TerraintilesGetCall) ClientInfoPlatform(clientInfoPlatform string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.platform", clientInfoPlatform)
	return c
}

// ClientInfoUserId sets the optional parameter "clientInfo.userId":
// Required. A client-generated user ID. The ID should be generated and
// persisted during the first user session or whenever a pre-existing ID
// is not found. The exact format is up to the client. This must be
// non-empty in a GetFeatureTileRequest (whether via the header or
// GetFeatureTileRequest.client_info).
func (c *TerraintilesGetCall) ClientInfoUserId(clientInfoUserId string) *TerraintilesGetCall {
	c.urlParams_.Set("clientInfo.userId", clientInfoUserId)
	return c
}

// MaxElevationResolutionCells sets the optional parameter
// "maxElevationResolutionCells": The maximum allowed resolution for the
// returned elevation heightmap. Possible values: between 1 and 1024
// (and not less than min_elevation_resolution_cells). Over-sized
// heightmaps will be non-uniformly down-sampled such that each edge is
// no longer than this value. Non-uniformity is chosen to maximise the
// amount of preserved data. For example: Original resolution: 100px
// (width) * 30px (height) max_elevation_resolution: 30 New resolution:
// 30px (width) * 30px (height)
func (c *TerraintilesGetCall) MaxElevationResolutionCells(maxElevationResolutionCells int64) *TerraintilesGetCall {
	c.urlParams_.Set("maxElevationResolutionCells", fmt.Sprint(maxElevationResolutionCells))
	return c
}

// MinElevationResolutionCells sets the optional parameter
// "minElevationResolutionCells": The minimum allowed resolution for the
// returned elevation heightmap. Possible values: between 0 and 1024
// (and not more than max_elevation_resolution_cells). Zero is supported
// for backward compatibility. Under-sized heightmaps will be
// non-uniformly up-sampled such that each edge is no shorter than this
// value. Non-uniformity is chosen to maximise the amount of preserved
// data. For example: Original resolution: 30px (width) * 10px (height)
// min_elevation_resolution: 30 New resolution: 30px (width) * 30px
// (height)
func (c *TerraintilesGetCall) MinElevationResolutionCells(minElevationResolutionCells int64) *TerraintilesGetCall {
	c.urlParams_.Set("minElevationResolutionCells", fmt.Sprint(minElevationResolutionCells))
	return c
}

// TerrainFormats sets the optional parameter "terrainFormats": Terrain
// formats that the client understands.
//
// Possible values:
//   "TERRAIN_FORMAT_UNKNOWN" - An unknown or unspecified terrain
// format.
//   "FIRST_DERIVATIVE" - Terrain elevation data encoded as a
// FirstDerivativeElevationGrid. .
//   "SECOND_DERIVATIVE" - Terrain elevation data encoded as a
// SecondDerivativeElevationGrid.
func (c *TerraintilesGetCall) TerrainFormats(terrainFormats ...string) *TerraintilesGetCall {
	c.urlParams_.SetMulti("terrainFormats", append([]string{}, terrainFormats...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TerraintilesGetCall) Fields(s ...googleapi.Field) *TerraintilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TerraintilesGetCall) IfNoneMatch(entityTag string) *TerraintilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TerraintilesGetCall) Context(ctx context.Context) *TerraintilesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TerraintilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TerraintilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "vectortile.terraintiles.get" call.
// Exactly one of *TerrainTile or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TerrainTile.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TerraintilesGetCall) Do(opts ...googleapi.CallOption) (*TerrainTile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TerrainTile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a terrain tile by its tile resource name.",
	//   "flatPath": "v1/terraintiles/{terraintilesId}",
	//   "httpMethod": "GET",
	//   "id": "vectortile.terraintiles.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "altitudePrecisionCentimeters": {
	//       "description": "The precision of terrain altitudes in centimeters. Possible values: between 1 (cm level precision) and 1,000,000 (10-kilometer level precision).",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "clientInfo.apiClient": {
	//       "description": "API client name and version. For example, the SDK calling the API. The exact format is up to the client.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.applicationId": {
	//       "description": "Application ID, such as the package name on Android and the bundle identifier on iOS platforms.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.applicationVersion": {
	//       "description": "Application version number, such as \"1.2.3\". The exact format is application-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.deviceModel": {
	//       "description": "Device model as reported by the device. The exact format is platform-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.operatingSystem": {
	//       "description": "Operating system name and version as reported by the OS. For example, \"Mac OS X 10.10.4\". The exact format is platform-dependent.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.platform": {
	//       "description": "Platform where the application is running.",
	//       "enum": [
	//         "PLATFORM_UNSPECIFIED",
	//         "EDITOR",
	//         "MAC_OS",
	//         "WINDOWS",
	//         "LINUX",
	//         "ANDROID",
	//         "IOS",
	//         "WEB_GL"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified or unknown OS.",
	//         "Development environment.",
	//         "macOS.",
	//         "Windows.",
	//         "Linux",
	//         "Android",
	//         "iOS",
	//         "WebGL."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientInfo.userId": {
	//       "description": "Required. A client-generated user ID. The ID should be generated and persisted during the first user session or whenever a pre-existing ID is not found. The exact format is up to the client. This must be non-empty in a GetFeatureTileRequest (whether via the header or GetFeatureTileRequest.client_info).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxElevationResolutionCells": {
	//       "description": "The maximum allowed resolution for the returned elevation heightmap. Possible values: between 1 and 1024 (and not less than min_elevation_resolution_cells). Over-sized heightmaps will be non-uniformly down-sampled such that each edge is no longer than this value. Non-uniformity is chosen to maximise the amount of preserved data. For example: Original resolution: 100px (width) * 30px (height) max_elevation_resolution: 30 New resolution: 30px (width) * 30px (height)",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "minElevationResolutionCells": {
	//       "description": "The minimum allowed resolution for the returned elevation heightmap. Possible values: between 0 and 1024 (and not more than max_elevation_resolution_cells). Zero is supported for backward compatibility. Under-sized heightmaps will be non-uniformly up-sampled such that each edge is no shorter than this value. Non-uniformity is chosen to maximise the amount of preserved data. For example: Original resolution: 30px (width) * 10px (height) min_elevation_resolution: 30 New resolution: 30px (width) * 30px (height)",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "Required. Resource name of the tile. The tile resource name is prefixed by its collection ID `terraintiles/` followed by the resource ID, which encodes the tile's global x and y coordinates and zoom level as `@,,z`. For example, `terraintiles/@1,2,3z`.",
	//       "location": "path",
	//       "pattern": "^terraintiles/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "terrainFormats": {
	//       "description": "Terrain formats that the client understands.",
	//       "enum": [
	//         "TERRAIN_FORMAT_UNKNOWN",
	//         "FIRST_DERIVATIVE",
	//         "SECOND_DERIVATIVE"
	//       ],
	//       "enumDescriptions": [
	//         "An unknown or unspecified terrain format.",
	//         "Terrain elevation data encoded as a FirstDerivativeElevationGrid. .",
	//         "Terrain elevation data encoded as a SecondDerivativeElevationGrid."
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "TerrainTile"
	//   }
	// }

}
