<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: proto/gtfs.proto

namespace Gtfs;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;

/**
 * Generated from protobuf message <code>gtfs.Shape</code>
 */
class Shape extends \Google\Protobuf\Internal\Message
{
    /**
     * Generated from protobuf field <code>string shape_id = 1;</code>
     */
    protected $shape_id = '';
    /**
     * Generated from protobuf field <code>float shape_pt_lat = 2;</code>
     */
    protected $shape_pt_lat = 0.0;
    /**
     * Generated from protobuf field <code>float shape_pt_lon = 3;</code>
     */
    protected $shape_pt_lon = 0.0;
    /**
     * Generated from protobuf field <code>int32 shape_pt_sequence = 4;</code>
     */
    protected $shape_pt_sequence = 0;
    /**
     * Generated from protobuf field <code>float shape_dist_traveled = 5;</code>
     */
    protected $shape_dist_traveled = 0.0;
    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     */
    protected $extension = null;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type string $shape_id
     *     @type float $shape_pt_lat
     *     @type float $shape_pt_lon
     *     @type int $shape_pt_sequence
     *     @type float $shape_dist_traveled
     *     @type \Google\Protobuf\Any $extension
     *           The extensions namespace allows 3rd-party developers to extend the
     *           GTFS specification in order to add and evaluate new features and
     *           modifications to the spec.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Proto\Gtfs::initOnce();
        parent::__construct($data);
    }

    /**
     * Generated from protobuf field <code>string shape_id = 1;</code>
     * @return string
     */
    public function getShapeId()
    {
        return $this->shape_id;
    }

    /**
     * Generated from protobuf field <code>string shape_id = 1;</code>
     * @param string $var
     * @return $this
     */
    public function setShapeId($var)
    {
        GPBUtil::checkString($var, True);
        $this->shape_id = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>float shape_pt_lat = 2;</code>
     * @return float
     */
    public function getShapePtLat()
    {
        return $this->shape_pt_lat;
    }

    /**
     * Generated from protobuf field <code>float shape_pt_lat = 2;</code>
     * @param float $var
     * @return $this
     */
    public function setShapePtLat($var)
    {
        GPBUtil::checkFloat($var);
        $this->shape_pt_lat = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>float shape_pt_lon = 3;</code>
     * @return float
     */
    public function getShapePtLon()
    {
        return $this->shape_pt_lon;
    }

    /**
     * Generated from protobuf field <code>float shape_pt_lon = 3;</code>
     * @param float $var
     * @return $this
     */
    public function setShapePtLon($var)
    {
        GPBUtil::checkFloat($var);
        $this->shape_pt_lon = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>int32 shape_pt_sequence = 4;</code>
     * @return int
     */
    public function getShapePtSequence()
    {
        return $this->shape_pt_sequence;
    }

    /**
     * Generated from protobuf field <code>int32 shape_pt_sequence = 4;</code>
     * @param int $var
     * @return $this
     */
    public function setShapePtSequence($var)
    {
        GPBUtil::checkInt32($var);
        $this->shape_pt_sequence = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>float shape_dist_traveled = 5;</code>
     * @return float
     */
    public function getShapeDistTraveled()
    {
        return $this->shape_dist_traveled;
    }

    /**
     * Generated from protobuf field <code>float shape_dist_traveled = 5;</code>
     * @param float $var
     * @return $this
     */
    public function setShapeDistTraveled($var)
    {
        GPBUtil::checkFloat($var);
        $this->shape_dist_traveled = $var;

        return $this;
    }

    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     * @return \Google\Protobuf\Any
     */
    public function getExtension()
    {
        return $this->extension;
    }

    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     * @param \Google\Protobuf\Any $var
     * @return $this
     */
    public function setExtension($var)
    {
        GPBUtil::checkMessage($var, \Google\Protobuf\Any::class);
        $this->extension = $var;

        return $this;
    }

}

