The following .proto files are required for BigGeo GRPC API.

//    Copyright 2024 BigGeo Inc.
//
//    Permission is hereby granted, free of charge, to any person obtaining a copy of
//    this software and associated documentation files (the “Software”), to deal in
//    the Software without restriction, including without limitation the rights to
//    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
//    of the Software, and to permit persons to whom the Software is furnished to do
//    so, subject to the following conditions:
//
//    The above copyright notice and this permission notice shall be included in all
//    copies or substantial portions of the Software.
//
//    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
//    INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//    PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

syntax = "proto3";

package biggeo.protobuf;

import "bgsearch_types.proto";
import "google/protobuf/empty.proto";

service BGSearch {
  rpc CreateCollection  (CreateCollectionArgs)  returns (google.protobuf.Empty) {}
  rpc RemoveCollection  (RemoveCollectionArgs)  returns (google.protobuf.Empty) {}
  rpc GetCollectionInfo (GetCollectionInfoArgs) returns (GetCollectionInfoResult) {}
  rpc SwapCollections   (SwapCollectionsArgs)   returns (google.protobuf.Empty) {}
  rpc RenameCollection  (RenameCollectionArgs)  returns (google.protobuf.Empty) {}

  rpc Insert (InsertArgs) returns (InsertResult) {}
  rpc Remove (RemoveArgs) returns (RemoveResult) {}
  rpc Update (UpdateArgs) returns (UpdateResult) {}
  rpc Upsert (UpsertArgs) returns (UpsertResult) {}

  rpc WriteToCollection (stream WriteToCollectionArgs) returns (stream WriteToCollectionResult) {}

  rpc SearchIntersects (SearchIntersectsArgs) returns (stream SearchResult) {}
  rpc SearchDistWithin (SearchDistWithinArgs) returns (stream SearchResult) {}

  // Data persistence endpoint
  rpc SaveCollectionToFile   (SaveCollectionToFileArgs)   returns (SaveCollectionResult) {}
  rpc LoadCollectionFromFile (LoadCollectionFromFileArgs) returns (google.protobuf.Empty) {}
}

// **************
// Argument Types
// **************

message CreateCollectionArgs {
  string name = 1;
  IndexType index_type = 2;
  IDType id_type = 3;
  reserved 4;
  reserved "payload_type";
}

message RemoveCollectionArgs {
  string collection = 1;
}

message GetCollectionInfoArgs {
  string collection = 1;
}

message SwapCollectionsArgs {
  string collection1 = 1;
  string collection2 = 2;
}

message RenameCollectionArgs {
  string collection = 1;
  string new_name = 2;
}

message InsertArgs {
  string collection = 1;
  repeated IndexedGeometry geometries = 2;
}

message RemoveArgs {
  string collection = 1;
  repeated GeometryID ids = 2;
}

message UpdateArgs {
  string collection = 1;
  repeated IndexedGeometry geometries = 2;
}

message UpsertArgs {
  string collection = 1;
  repeated IndexedGeometry geometries = 2;
}

message WriteToCollectionArgs {
  message SetCollection {
    string collection = 1;
  }
  message Insert {
    IndexedGeometry geometry = 1;
  }
  message Remove {
    GeometryID id = 1;
  }
  message Update {
    IndexedGeometry geometry = 1;
  }
  message Upsert {
    IndexedGeometry geometry = 1;
  }
  message Request {
    oneof request {
      SetCollection set_collection = 1;
      Insert insert = 2;
      Remove remove = 3;
      Update update = 4;
      Upsert upsert = 5;
    }
  }
  repeated Request requests = 1;
}

message SaveCollectionToFileArgs {
  string collection = 1;
  string path = 2;
  string filename = 3;
}

message LoadCollectionFromFileArgs {
  string collection = 1;
  string location = 2;
}

message SearchControls {
  bool return_geometries = 1;
  bool return_payloads = 2;
  uint64 chunk_size = 3;
};

message SearchIntersectsArgs {
  string collection = 1;
  oneof search_geometry {
    // LatLng point = 2;
    // LineStrip line_strip = 3;
    Polygon polygon = 4;
    LatLngBBox lat_lng_bbox = 5;
  };
  reserved 2, 3, 6 to 14;
  reserved "point", "line_strip";
  SearchControls controls = 15;
}

message SearchDistWithinArgs {
  string collection = 1;
  double distance_m = 2;
  oneof search_geometry {
    LatLng point = 3;
    // LineStrip line_strip = 4;
    // Polygon polygon = 5;
  };
  reserved 4 to 14;
  reserved "line_strip", "polygon";
  SearchControls controls = 15;
}

// ************
// Result Types
// ************

message GetCollectionInfoResult {
  string name = 1;
  uint64 size = 2;
  IndexType index_type = 3;
  IDType id_type = 4;
  reserved 5;
  reserved "payload_type";
}

message InsertResult {
  repeated GeometryID inserted_ids = 1;
}

message RemoveResult {
  uint64 num_removed = 1;
}

message UpdateResult {
  uint64 num_updated = 1;
}

message UpsertResult {
  uint64 num_inserted = 1;
  uint64 num_updated = 2;
  uint64 num_noops = 3;
  reserved 4 to 6; // for list of IDs for each case
}

enum UpsertStatus {
  UPSERT_STATUS_UNSPECIFIED = 0;
  UPSERT_STATUS_INSERTED = 1;
  UPSERT_STATUS_UPDATED = 2;
}

message WriteToCollectionResult {
  message CollectionSet {
  }
  message Insert {
    GeometryID id = 1;
  }
  message Remove {
    bool removed = 1;
  }
  message Update {
    bool updated = 1;
  }
  message Upsert {
    UpsertStatus status = 1;
  }
  message Result {
    oneof result {
      CollectionSet set_collection = 1;
      Insert insert = 2;
      Remove remove = 3;
      Update update = 4;
      Upsert upsert = 5;
    }
  }
  repeated Result results = 1;
}

message SearchResult {
  message Geometry {
    GeometryID id = 1;
    optional IndexableGeometry geometry = 2;
    optional Payload payload = 3;
  }
  message Aggregate {
    // TODO this: This is done in Beta API
  }

  repeated Geometry geometries = 1;
  //repeated Aggregate aggregates = 2;

  reserved 2;
  reserved "aggregates";
}

message SaveCollectionResult {
  string full_path = 1;
}
//    Copyright 2024 BigGeo Inc.
//
//    Permission is hereby granted, free of charge, to any person obtaining a copy of
//    this software and associated documentation files (the “Software”), to deal in
//    the Software without restriction, including without limitation the rights to
//    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
//    of the Software, and to permit persons to whom the Software is furnished to do
//    so, subject to the following conditions:
//
//    The above copyright notice and this permission notice shall be included in all
//    copies or substantial portions of the Software.
//
//    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
//    INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//    PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

syntax = "proto3";

package biggeo.protobuf;

import "google/protobuf/any.proto";

// **************
// Geometry types
// **************

message LatLng {
  double latitude = 1;
  double longitude = 2;
}

// LineStrips can't have fewer than 2 points
message LineStrip {
  repeated LatLng points = 1;
}

// Rings can't be self-intersecting
// Rings are implicitly closed (the first and last point are implicitly connected)
// Rings can't have fewer than 3 points
// Rings can't have duplicate points
message Ring {
  repeated LatLng points = 1;
}

// Vertices should be specified in an order such that the
// left of the edge denotes the inside. For small polygons,
// this means the exterior ring should be specified in
// counter-clockwise order, and holes should be clockwise.
//
// Inner rings must be contained by the outer ring
// Inner rings can't intersect each other
message Polygon {
  Ring outer = 1; // polygon outer ring - must be counter-clockwise
  repeated Ring inners = 2; // polygons holes - they have to be clockwise
}

message MultiPolygon {
  repeated Polygon polygons = 1;
}

message LatLngBBox {
  LatLng top_left = 1;
  LatLng bottom_right = 2;
}

message IndexableGeometry {
  oneof geometry {
    LatLng point = 1;
    LineStrip line_strip = 2;
    Polygon polygon = 3;
    // MultiPoint multi_point = 4;
    // MultiLine multi_line = 5;
    MultiPolygon multi_polygon = 6;
    // MultiGeometry multi_geometry = 7;
  }
  reserved 4, 5, 7;
  reserved "multi_point", "multi_line", "multi_geometry";
}

// ******************
// Non-geometry types
// ******************

message GeometryID {
  oneof id {
    uint64 uint64 = 1;
    //string uuid = 2;
  }
  reserved 2;
  reserved "uuid";
}

// TODO is this the best way to do this?
message Payload {
  bytes data = 1;
}

message IndexedGeometry {
  GeometryID id = 1;
  IndexableGeometry geometry = 2;
  optional Payload payload = 3;
}

message DGGSIndex {
    string index = 1;
}

enum IndexType {
  INDEX_TYPE_UNSPECIFIED = 0;
  INDEX_TYPE_PER_NODE    = 1;
  INDEX_TYPE_ULL         = 2;
}

enum IDType {
  ID_TYPE_UNSPECIFIED = 0;
  ID_TYPE_PROVIDED_U64 = 1;
  // ID_TYPE_PROVIDED_UUID = 2;
  // ID_TYPE_ASSIGNED_UUID = 3;
  ID_TYPE_AUTO_INC = 4;
  reserved 2, 3;
  reserved "ID_TYPE_PROVIDED_UUID", "ID_TYPE_ASSIGNED_UUID";
}