Как получить информацию из вашего protobuf в C ++? - PullRequest
0 голосов
/ 05 апреля 2020

В основном я пытаюсь получить координаты x и y из сообщения ProtoBuf, которое похоже на тип SHPObject. Я знаю, что с SHPObject я могу делать такие вещи, как double* x = obj->padfX и double* y = obj->padfY. Однако я не совсем уверен, как извлечь эту же информацию из моего ProtoBuf (код показан ниже). Спасибо за вашу помощь!

Это то, что я пробовал до сих пор:

myProject::protobuf::NewShape _NewShape;

auto obj = _NewShape.shape(0);

double* x = obj.polygon(0).point(0); 

Выдает ошибку:

не может инициализировать переменную типа ' double 'с r-значением типа' unsigned int '

И затем я попробовал это, которое компилируется, но ничего не делает (не дает мне желаемый вывод):

double x_coordinate = obj.polygon(0).point(0);
double *x_ptr = &x_coordinate;

Вот мой файл ProtoBuf:

newShape.proto

syntax = "proto2";

package myProject.protobuf;

message NewShape {

  message Polygon 
  {
    enum PolygonType {
      POLY_TYPE_OUTER = 1;
      POLY_TYPE_INNER = 2;
    };

    optional PolygonType type = 1 [default = POLY_TYPE_OUTER];

    // x, y coordinates 
    repeated uint32 point     = 2 [packed = true];
  }

  message Shape
  {
    repeated Polygon polygon  = 1;
  }

  repeated Shape shape = 2;
}

1 Ответ

1 голос
/ 08 апреля 2020

Учитывая ваш формат, вы можете получить доступ к точкам из правильно заполненного и десериализованного объекта, например:

// newShape is the deserialized object here

const auto s0p0p0 = newShape.shape(0).polygon(0).point(0);
const auto s0p0p1 = newShape.shape(0).polygon(0).point(1);

Аналогично, shape(1) даст вам вторую форму для доступа к точкам в объекте многоугольника. Вы должны проверить методы *_size() перед доступом к индексу, чтобы убедиться в правильности доступа, например newShape.shape_size(), shape.polygon_size() и polygon.point_size().

Если вы намереваетесь изменить сообщение, вы можете использовать методы mutable_* чтобы получить указатели на соответствующие объекты, а затем вы можете изменить их.

Например (точки изменения первого многоугольника первой фигуры):

auto p = newShape2.mutable_shape(0);
p->mutable_polygon(0)->set_point(0, 123);
p->mutable_polygon(0)->set_point(1, 345);

Вот полный рабочий пример сериализации и десериализация:

#include <iostream>
#include "newShape.pb.h"

int main()
{
    // Serailization

    ::myProject::protobuf::NewShape newShape1;

    auto shape1 = newShape1.add_shape();
    auto polygon1 = shape1->add_polygon();
    polygon1->add_point(1);
    polygon1->add_point(2);

    auto shape2 = newShape1.add_shape();
    auto polygon2 = shape2->add_polygon();
    polygon2->add_point(3);
    polygon2->add_point(4);

    const auto serializedData = newShape1.SerializeAsString();

    std::cout << "Serialized Data Size: " << serializedData.size() << "\n\n";

    // Send/Store Serialized Data

    // Deserialization

    ::myProject::protobuf::NewShape newShape2;

    if ( !newShape2.ParseFromString( serializedData ) )
    {
        std::cerr << "Deserialization failed!\n";
        return -1;
    }

    std::cout << "Deserialized Data Size: " << newShape2.ByteSize() << "\n\n";

    std::cout << "NewShape [Shapes: " << newShape2.shape_size() << "]\n";

    for ( int i {0}; i < newShape2.shape_size(); ++i )
    {
        std::cout << " Shape # " << i << '\n';

        const auto& shape = newShape2.shape( i );
        for ( int j {0}; j < shape.polygon_size(); ++j )
        {
            std::cout << "  Polygon # " << j << '\n';

            const auto& polygon = shape.polygon( j );
            for ( int k {0}; k < polygon.point_size(); ++k )
            {
                const auto& point = polygon.point( k );
                std::cout << "   Point # " << k << ": " << point << '\n';
            }
        }
    }

    return 0;
}

Выход:

Serialized Data Size: 16

Deserialized Data Size: 16

NewShape [Shapes: 2]
 Shape # 0
  Polygon # 0
   Point # 0: 1
   Point # 1: 2
 Shape # 1
  Polygon # 0
   Point # 0: 3
   Point # 1: 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...