[fpc-pascal] UBER H3 API working/partially converted

Skybuck Flying skybuck2000 at hotmail.com
Sun Jul 31 15:55:36 CEST 2022


(I mainly write this second e-mail to prevent you from wasting time on the previous e-mail, cause the conversion was already quite successfull with a different tool, read below)

The in Delphi written tool CHET was used to convert the C api for UBER H3 library.

https://github.com/neslib/Chet
[https://opengraph.githubassets.com/b39cf935c557cba4185d6776c2195f5790769b08f096256d01ca89b5ab57a40c/neslib/Chet]<https://github.com/neslib/Chet>
GitHub - neslib/Chet: C Header Translator for Delphi<https://github.com/neslib/Chet>
Chet - C Header Translator for Delphi. Chet is a .h-to-.pas translator powered by libclang for Delphi.. Features. Unlike some other header translators, Chet uses the Clang compiler to parse header files, resulting in more accurate translations that require fewer manual adjustments.
github.com


CHET uses LIBClang for Delphi. Which can be found at: https://github.com/neslib/Neslib.Clang
[https://opengraph.githubassets.com/fc65d8cd6fa05f844e7d52fe10a26ddaa1814241a437d1e8c101db34bce19f7b/neslib/Neslib.Clang]<https://github.com/neslib/Neslib.Clang>
GitHub - neslib/Neslib.Clang: libclang for Delphi<https://github.com/neslib/Neslib.Clang>
Neslib.Clang - libclang for Delphi. Libclang is the C Interface to Clang's C family of compilers. It provides a relatively small API that exposes facilities for parsing source code into an abstract syntax tree (AST), loading already-parsed ASTs, traversing the AST, associating physical source locations with elements within the AST, and other facilities that support Clang-based development tools.
github.com


I don't know if LIBClang for Free Pascal Exist.

But this chet tool in combination with this LibClang was pretty awesome !

Especially cause this was quite a complex/bitch of an api, with crazy painfull macros, but the tool performed pretty well and did it's best and produced something useable.
I had to only disable/comments 5 lines of code.

The api was briefly tested and it seems to work !

Some improvements can be made by using properties to access H3Indexes directly etc.

This will be done/attempted in the near future.

For now for what it's worth here is the unit code, ofcourse it kinda sucks to have it in e-mail format.

Maybe later I uploaded it somewhere...

unit UBER_H3_API;
{ This unit is automatically generated by Chet:
  https://github.com/neslib/Chet }

{$MINENUMSIZE 4}

interface

const
  {$IF Defined(WIN64)}
  UBER_H3 = 'h3_release_64_bit.dll';
  _PU = '';
  {$ELSE}
    {$MESSAGE Error 'Unsupported platform'}
  {$ENDIF}

const
  M_PI = 3.14159265358979323846;
  M_PI_2 = 1.5707963267948966;
  M_2PI = 6.28318530717958647692528676655900576839433;
  M_PI_180 = 0.0174532925199432957692369076848861271111;
  M_180_PI = 57.29577951308232087679815481410517033240547;
  EPSILON = 0.0000000000000001;
  M_SQRT3_2 = 0.8660254037844386467637231707529361834714;
  M_SIN60 = M_SQRT3_2;
  M_AP7_ROT_RADS = 0.333473172251832115336090755351601070065900389;
  M_SIN_AP7_ROT = 0.3273268353539885718950318;
  M_COS_AP7_ROT = 0.9449111825230680680167902;
  EARTH_RADIUS_KM = 6371.007180918475;
  RES0_U_GNOMONIC = 0.38196601125010500003;
  MAX_H3_RES = 15;
  NUM_ICOSA_FACES = 20;
  NUM_BASE_CELLS = 122;
  NUM_HEX_VERTS = 6;
  NUM_PENT_VERTS = 5;
  NUM_PENTAGONS = 12;
  H3_CELL_MODE = 1;
  H3_DIRECTEDEDGE_MODE = 2;
  H3_EDGE_MODE = 3;
  H3_VERTEX_MODE = 4;
  { TODO : Unable to convert function-like macro: }
  (* H3_EXPORT ( name ) name *)
  H3_NULL = 0;
  H3_VERSION_MAJOR = 4;
  H3_VERSION_MINOR = 0;
  H3_VERSION_PATCH = 0;
  MAX_CELL_BNDRY_VERTS = 10;
  EPSILON_DEG = 0.000000001;
  EPSILON_RAD = (EPSILON_DEG*M_PI_180);
  NORMALIZATION_SUCCESS = 0;
  NORMALIZATION_ERR_MULTIPLE_POLYGONS = 1;
  NORMALIZATION_ERR_UNASSIGNED_HOLES = 2;
  { TODO : Macro probably uses invalid symbol "currentCoord": }
  (* INIT_ITERATION_LINKED_LOOP LinkedLatLng * currentCoord = NULL ; LinkedLatLng * nextCoord = NULL *)
  { TODO : Unable to convert function-like macro: }
  (* GET_NEXT_COORD ( loop , coordToCheck ) coordToCheck == NULL ? loop -> first : currentCoord -> next *)
  { TODO : Unable to convert function-like macro: }
  (* ITERATE_LINKED_LOOP ( loop , vertexA , vertexB ) currentCoord = GET_NEXT_COORD ( loop , currentCoord ) ; if ( currentCoord == NULL ) break ; vertexA = currentCoord -> vertex ; nextCoord = GET_NEXT_COORD ( loop , currentCoord -> next ) ; vertexB = nextCoord -> vertex *)
  { TODO : Unable to convert function-like macro: }
  (* IS_EMPTY_LINKED_LOOP ( loop ) loop -> first == NULL *)
  { TODO : Unable to convert function-like macro: }
  (* H3_MEMORY ( name ) name *)
  IJ = 1;
  KI = 2;
  JK = 3;
  INVALID_FACE = -1;
  INVALID_BASE_CELL = 127;
  MAX_FACE_COORD = 2;
  INVALID_ROTATIONS = -1;
  H3_NUM_BITS = 64;
  H3_MAX_OFFSET = 63;
  H3_MODE_OFFSET = 59;
  H3_BC_OFFSET = 45;
  H3_RES_OFFSET = 52;
  H3_RESERVED_OFFSET = 56;
  H3_PER_DIGIT_OFFSET = 3;
  { TODO : Macro probably uses invalid symbol "uint64_t": }
  (* H3_HIGH_BIT_MASK ( ( uint64_t ) ( 1 ) << H3_MAX_OFFSET ) *)
  { TODO : Macro uses commented-out symbol "H3_HIGH_BIT_MASK": }
  (* H3_HIGH_BIT_MASK_NEGATIVE ( ~ H3_HIGH_BIT_MASK ) *)
  { TODO : Macro probably uses invalid symbol "uint64_t": }
  (* H3_MODE_MASK ( ( uint64_t ) ( 15 ) << H3_MODE_OFFSET ) *)
  { TODO : Macro uses commented-out symbol "H3_MODE_MASK": }
  (* H3_MODE_MASK_NEGATIVE ( ~ H3_MODE_MASK ) *)
  { TODO : Macro probably uses invalid symbol "uint64_t": }
  (* H3_BC_MASK ( ( uint64_t ) ( 127 ) << H3_BC_OFFSET ) *)
  { TODO : Macro uses commented-out symbol "H3_BC_MASK": }
  (* H3_BC_MASK_NEGATIVE ( ~ H3_BC_MASK ) *)
  { TODO : Unable to convert function-like macro: }
  (* UINT64_C ( x ) ( x ## ULL ) *)
  H3_RES_MASK = (UINT64_C(15) shl H3_RES_OFFSET);
  H3_RES_MASK_NEGATIVE = ( not H3_RES_MASK);
  { TODO : Macro probably uses invalid symbol "uint64_t": }
  (* H3_RESERVED_MASK ( ( uint64_t ) ( 7 ) << H3_RESERVED_OFFSET ) *)
  { TODO : Macro uses commented-out symbol "H3_RESERVED_MASK": }
  (* H3_RESERVED_MASK_NEGATIVE ( ~ H3_RESERVED_MASK ) *)
  { TODO : Macro probably uses invalid symbol "uint64_t": }
  (* H3_DIGIT_MASK ( ( uint64_t ) ( 7 ) ) *)
  { TODO : Macro uses commented-out symbol "H3_DIGIT_MASK": }
  (* H3_DIGIT_MASK_NEGATIVE ( ~ H3_DIGIT_MASK ) *)
  { TODO : Macro uses commented-out symbol "UINT64_C": }
  (* H3_INIT ( UINT64_C ( 35184372088831 ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_HIGH_BIT ( h3 ) ( ( int ) ( ( ( ( h3 ) & H3_HIGH_BIT_MASK ) >> H3_MAX_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_HIGH_BIT ( h3 , v ) ( h3 ) = ( ( ( h3 ) & H3_HIGH_BIT_MASK_NEGATIVE ) | ( ( ( uint64_t ) ( v ) ) << H3_MAX_OFFSET ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_MODE ( h3 ) ( ( int ) ( ( ( ( h3 ) & H3_MODE_MASK ) >> H3_MODE_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_MODE ( h3 , v ) ( h3 ) = ( ( ( h3 ) & H3_MODE_MASK_NEGATIVE ) | ( ( ( uint64_t ) ( v ) ) << H3_MODE_OFFSET ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_BASE_CELL ( h3 ) ( ( int ) ( ( ( ( h3 ) & H3_BC_MASK ) >> H3_BC_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_BASE_CELL ( h3 , bc ) ( h3 ) = ( ( ( h3 ) & H3_BC_MASK_NEGATIVE ) | ( ( ( uint64_t ) ( bc ) ) << H3_BC_OFFSET ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_RESOLUTION ( h3 ) ( ( int ) ( ( ( ( h3 ) & H3_RES_MASK ) >> H3_RES_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_RESOLUTION ( h3 , res ) ( h3 ) = ( ( ( h3 ) & H3_RES_MASK_NEGATIVE ) | ( ( ( uint64_t ) ( res ) ) << H3_RES_OFFSET ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_INDEX_DIGIT ( h3 , res ) ( ( Direction ) ( ( ( ( h3 ) >> ( ( MAX_H3_RES - ( res ) ) * H3_PER_DIGIT_OFFSET ) ) & H3_DIGIT_MASK ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_RESERVED_BITS ( h3 , v ) ( h3 ) = ( ( ( h3 ) & H3_RESERVED_MASK_NEGATIVE ) | ( ( ( uint64_t ) ( v ) ) << H3_RESERVED_OFFSET ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_GET_RESERVED_BITS ( h3 ) ( ( int ) ( ( ( ( h3 ) & H3_RESERVED_MASK ) >> H3_RESERVED_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* H3_SET_INDEX_DIGIT ( h3 , res , digit ) ( h3 ) = ( ( ( h3 ) & ~ ( ( H3_DIGIT_MASK << ( ( MAX_H3_RES - ( res ) ) * H3_PER_DIGIT_OFFSET ) ) ) ) | ( ( ( uint64_t ) ( digit ) ) << ( ( MAX_H3_RES - ( res ) ) * H3_PER_DIGIT_OFFSET ) ) ) *)
  { TODO : Unable to convert function-like macro: }
  (* MAX ( a , b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) *)
  { TODO : Macro probably uses invalid symbol "int": }
  (* INIT_ITERATION_GEOFENCE int loopIndex = - 1 *)
  { TODO : Unable to convert function-like macro: }
  (* ITERATE_GEOFENCE ( geoloop , vertexA , vertexB ) if ( ++ loopIndex >= geoloop -> numVerts ) break ; vertexA = geoloop -> verts [ loopIndex ] ; vertexB = geoloop -> verts [ ( loopIndex + 1 ) % geoloop -> numVerts ] *)
  { TODO : Unable to convert function-like macro: }
  (* IS_EMPTY_GEOFENCE ( geoloop ) geoloop -> numVerts == 0 *)
  INVALID_VERTEX_NUM = -1;
  MAX_BASE_CELL_FACES = 5;

type
  // Forward declarations
  PInt64 = ^Int64;
  PLatLng = ^LatLng;
  PCellBoundary = ^CellBoundary;
  PGeoLoop = ^GeoLoop;
  PGeoPolygon = ^GeoPolygon;
  PGeoMultiPolygon = ^GeoMultiPolygon;
  PLinkedLatLng = ^LinkedLatLng;
  PLinkedGeoLoop = ^LinkedGeoLoop;
  PLinkedGeoPolygon = ^LinkedGeoPolygon;
  PCoordIJ = ^CoordIJ;
  PBBox = ^BBox;
  PVec2d = ^Vec2d;
  PCoordIJK = ^CoordIJK;
  PVertexNode = ^VertexNode;
  PPVertexNode = ^PVertexNode;
  PVertexGraph = ^VertexGraph;
  PFaceIJK = ^FaceIJK;
  PFaceOrientIJK = ^FaceOrientIJK;
  PBaseCellData = ^BaseCellData;
  PIterCellsChildren = ^IterCellsChildren;
  PIterCellsResolution = ^IterCellsResolution;
  PVec3d = ^Vec3d;
  PPentagonDirectionFaces = ^PentagonDirectionFaces;

  (** @brief Identifier for an object (cell, edge, etc) in the H3 system.
   *
   * The H3Index fits within a 64-bit unsigned integer.
   *)
  H3Index = UInt64;
  PH3Index = ^H3Index;
  (** @brief Result code (success or specific error) from an H3 operation *)
  H3Error = UInt32;

  H3ErrorCodes = (
    E_SUCCESS = 0,
    E_FAILED = 1,
    E_DOMAIN = 2,
    E_LATLNG_DOMAIN = 3,
    E_RES_DOMAIN = 4,
    E_CELL_INVALID = 5,
    E_DIR_EDGE_INVALID = 6,
    E_UNDIR_EDGE_INVALID = 7,
    E_VERTEX_INVALID = 8,
    E_PENTAGON = 9,
    E_DUPLICATE_INPUT = 10,
    E_NOT_NEIGHBORS = 11,
    E_RES_MISMATCH = 12,
    E_MEMORY_ALLOC = 13,
    E_MEMORY_BOUNDS = 14,
    E_OPTION_INVALID = 15);
  PH3ErrorCodes = ^H3ErrorCodes;

  (** @struct LatLng
      @brief latitude/longitude in radians
   *)
  LatLng = record
    /// latitude in radians
    lat: Double;
    /// longitude in radians
    lng: Double;
  end;

  (** @struct CellBoundary
      @brief cell boundary in latitude/longitude
   *)
  CellBoundary = record
    /// number of vertices
    numVerts: Integer;
    /// vertices in ccw order
    verts: array [0..9] of LatLng;
  end;

  (** @struct GeoLoop
   *  @brief similar to CellBoundary, but requires more alloc work
   *)
  GeoLoop = record
    numVerts: Integer;
    verts: PLatLng;
  end;

  (** @struct GeoPolygon
   *  @brief Simplified core of GeoJSON Polygon coordinates definition
   *)
  GeoPolygon = record
    /// exterior boundary of the polygon
    geoloop: GeoLoop;
    /// number of elements in the array pointed to by holes
    numHoles: Integer;
    /// interior boundaries (holes) in the polygon
    holes: PGeoLoop;
  end;

  (** @struct GeoMultiPolygon
   *  @brief Simplified core of GeoJSON MultiPolygon coordinates definition
   *)
  GeoMultiPolygon = record
    numPolygons: Integer;
    polygons: PGeoPolygon;
  end;

  LinkedLatLng = record
    vertex: LatLng;
    next: PLinkedLatLng;
  end;

  LinkedGeoLoop = record
    first: PLinkedLatLng;
    last: PLinkedLatLng;
    next: PLinkedGeoLoop;
  end;

  LinkedGeoPolygon = record
    first: PLinkedGeoLoop;
    last: PLinkedGeoLoop;
    next: PLinkedGeoPolygon;
  end;

  (** @struct CoordIJ
   * @brief IJ hexagon coordinates
   *
   * Each axis is spaced 120 degrees apart.
   *)
  CoordIJ = record
    /// i component
    i: Integer;
    /// j component
    j: Integer;
  end;

  (** @struct BBox
   *  @brief  Geographic bounding box with coordinates defined in radians
   *)
  BBox = record
    /// north latitude
    north: Double;
    /// south latitude
    south: Double;
    /// east longitude
    east: Double;
    /// west longitude
    west: Double;
  end;

  (** @struct Vec2d
   *  @brief 2D floating-point vector
   *)
  Vec2d = record
    /// x component
    x: Double;
    /// y component
    y: Double;
  end;

  (** @struct CoordIJK
   * @brief IJK hexagon coordinates
   *
   * Each axis is spaced 120 degrees apart.
   *)
  CoordIJK = record
    /// i component
    i: Integer;
    /// j component
    j: Integer;
    /// k component
    k: Integer;
  end;

  (** @brief H3 digit representing ijk+ axes direction.
   * Values will be within the lowest 3 bits of an integer.
   *)
  Direction = (
    (** H3 digit in center *)
    CENTER_DIGIT = 0,
    (** H3 digit in k-axes direction *)
    K_AXES_DIGIT = 1,
    (** H3 digit in j-axes direction *)
    J_AXES_DIGIT = 2,
    (** H3 digit in j == k direction *)
    JK_AXES_DIGIT = 3,
    (** H3 digit in i-axes direction *)
    I_AXES_DIGIT = 4,
    (** H3 digit in i == k direction *)
    IK_AXES_DIGIT = 5,
    (** H3 digit in i == j direction *)
    IJ_AXES_DIGIT = 6,
    (** H3 digit in the invalid direction *)
    INVALID_DIGIT = 7,
    (** Valid digits will be less than this value. Same value as INVALID_DIGIT.
     *)
    NUM_DIGITS = 7,
    (** Child digit which is skipped for pentagons *)
    PENTAGON_SKIPPED_DIGIT = 1);
  PDirection = ^Direction;

  VertexNode = record
    from: LatLng;
    &to: LatLng;
    next: PVertexNode;
  end;

  (** @struct VertexGraph
   *  @brief A data structure to store a graph of vertices
   *)
  VertexGraph = record
    buckets: PPVertexNode;
    numBuckets: Integer;
    size: Integer;
    res: Integer;
  end;

  (** @struct FaceIJK
   * @brief Face number and ijk coordinates on that face-centered coordinate
   * system
   *)
  FaceIJK = record
    /// face number
    face: Integer;
    /// ijk coordinates on that face
    coord: CoordIJK;
  end;

  (** @struct FaceOrientIJK
   * @brief Information to transform into an adjacent face IJK system
   *)
  FaceOrientIJK = record
    /// face number
    face: Integer;
    /// res 0 translation relative to primary face
    translate: CoordIJK;
    /// number of 60 degree ccw rotations relative to primary
    ccwRot60: Integer;
  end;

  (** Digit representing overage type *)
  Overage = (
    (** No overage (on original face) *)
    NO_OVERAGE = 0,
    (** On face edge (only occurs on substrate grids) *)
    FACE_EDGE = 1,
    (** Overage on new face interior *)
    NEW_FACE = 2);
  POverage = ^Overage;

  (** @struct BaseCellData
   * @brief information on a single base cell
   *)
  BaseCellData = record
    /// "home" face and normalized ijk coordinates on that face
    homeFijk: FaceIJK;
    /// is this base cell a pentagon?
    isPentagon: Integer;
    /// if a pentagon, what are its two clockwise offset
    cwOffsetPent: array [0..1] of Integer;
  end;

  (**
   * IterCellsChildren: struct for iterating through the descendants of
   * a given cell.
   *
   * Constructors:
   *
   * Initialize with either `iterInitParent` or `iterInitBaseCellNum`.
   * `iterInitParent` sets up an iterator for all the children of a given
   * parent cell at a given resolution.
   *
   * `iterInitBaseCellNum` sets up an iterator for children cells, given
   * a base cell number (0--121).
   *
   * Iteration:
   *
   * Step iterator with `iterStepChild`.
   * During the lifetime of the `IterCellsChildren`, the current iterate
   * is accessed via the `IterCellsChildren.h` member.
   * When the iterator is exhausted or if there was an error in initialization,
   * `IterCellsChildren.h` will be `H3_NULL` even after calling `iterStepChild`.
   *)
  IterCellsChildren = record
    h: H3Index;
    _parentRes: Integer;
    _skipDigit: Integer;
  end;

  (**
   * IterCellsResolution: struct for iterating through all cells at a given
   * resolution
   *
   * Constructor:
   *
   * Initialize with `IterCellsResolution`.
   *
   * Iteration:
   *
   * Step iterator with `iterStepRes`.
   * During the lifetime of the iterator the current iterate
   * is accessed via the `IterCellsResolution.h` member.
   * When the iterator is exhausted or if there was an error in initialization,
   * `IterCellsResolution.h` will be `H3_NULL` even after calling `iterStepRes`.
   *)
  IterCellsResolution = record
    h: H3Index;
    _baseCellNum: Integer;
    _res: Integer;
    _itC: IterCellsChildren;
  end;

  (** @struct Vec3D
   *  @brief 3D floating point structure
   *)
  Vec3d = record
    /// x component
    x: Double;
    /// y component
    y: Double;
    /// z component
    z: Double;
  end;

  (** @struct PentagonDirectionFaces
   *  @brief  The faces in each axial direction of a given pentagon base cell
   *)
  PentagonDirectionFaces = record
    /// base cell number
    baseCell: Integer;
    /// face numbers for each axial direction,
    faces: array [0..4] of Integer;
  end;

const
  (** @brief CoordIJK unit vectors corresponding to the 7 H3 digits.
   *)
  ] : CoordIJK UNIT_VECS [{ TODO : unrecognized type "ConstantArray" }
   = {{0,0,0},// direction 0{0,0,1},// direction 1{0,1,0},// direction 2{0,1,1},// direction 3{1,0,0},// direction 4{1,0,1},// direction 5{1,1,0}// direction 6};

function latLngToCell(const g: PLatLng; res: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'latLngToCell';

function cellToLatLng(h3: H3Index; g: PLatLng): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToLatLng';

function cellToBoundary(h3: H3Index; gp: PCellBoundary): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToBoundary';

function maxGridDiskSize(k: Integer; &out: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'maxGridDiskSize';

function gridDiskUnsafe(origin: H3Index; k: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDiskUnsafe';

function gridDiskDistancesUnsafe(origin: H3Index; k: Integer; &out: PH3Index; distances: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDiskDistancesUnsafe';

function gridDiskDistancesSafe(origin: H3Index; k: Integer; &out: PH3Index; distances: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDiskDistancesSafe';

function gridDisksUnsafe(h3Set: PH3Index; length: Integer; k: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDisksUnsafe';

function gridDisk(origin: H3Index; k: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDisk';

function gridDiskDistances(origin: H3Index; k: Integer; &out: PH3Index; distances: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDiskDistances';

function gridRingUnsafe(origin: H3Index; k: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridRingUnsafe';

function maxPolygonToCellsSize(const geoPolygon: PGeoPolygon; res: Integer; flags: UInt32; &out: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'maxPolygonToCellsSize';

function polygonToCells(const geoPolygon: PGeoPolygon; res: Integer; flags: UInt32; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'polygonToCells';

function cellsToLinkedMultiPolygon(const h3Set: PH3Index; const numHexes: Integer; &out: PLinkedGeoPolygon): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellsToLinkedMultiPolygon';

procedure destroyLinkedMultiPolygon(polygon: PLinkedGeoPolygon); cdecl;
  external UBER_H3 name _PU + 'destroyLinkedMultiPolygon';

function degsToRads(degrees: Double): Double; cdecl;
  external UBER_H3 name _PU + 'degsToRads';

function radsToDegs(radians: Double): Double; cdecl;
  external UBER_H3 name _PU + 'radsToDegs';

function greatCircleDistanceRads(const a: PLatLng; const b: PLatLng): Double; cdecl;
  external UBER_H3 name _PU + 'greatCircleDistanceRads';

function greatCircleDistanceKm(const a: PLatLng; const b: PLatLng): Double; cdecl;
  external UBER_H3 name _PU + 'greatCircleDistanceKm';

function greatCircleDistanceM(const a: PLatLng; const b: PLatLng): Double; cdecl;
  external UBER_H3 name _PU + 'greatCircleDistanceM';

function getHexagonAreaAvgKm2(res: Integer; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'getHexagonAreaAvgKm2';

function getHexagonAreaAvgM2(res: Integer; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'getHexagonAreaAvgM2';

function cellAreaRads2(h: H3Index; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellAreaRads2';

function cellAreaKm2(h: H3Index; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellAreaKm2';

function cellAreaM2(h: H3Index; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellAreaM2';

function getHexagonEdgeLengthAvgKm(res: Integer; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'getHexagonEdgeLengthAvgKm';

function getHexagonEdgeLengthAvgM(res: Integer; &out: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'getHexagonEdgeLengthAvgM';

function exactEdgeLengthRads(edge: H3Index; length: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'exactEdgeLengthRads';

function exactEdgeLengthKm(edge: H3Index; length: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'exactEdgeLengthKm';

function exactEdgeLengthM(edge: H3Index; length: PDouble): H3Error; cdecl;
  external UBER_H3 name _PU + 'exactEdgeLengthM';

function getNumCells(res: Integer; &out: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'getNumCells';

function res0CellCount(): Integer; cdecl;
  external UBER_H3 name _PU + 'res0CellCount';

function getRes0Cells(&out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'getRes0Cells';

function pentagonCount(): Integer; cdecl;
  external UBER_H3 name _PU + 'pentagonCount';

function getPentagons(res: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'getPentagons';

function getResolution(h: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'getResolution';

function getBaseCellNumber(h: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'getBaseCellNumber';

function stringToH3(const str: PUTF8Char; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'stringToH3';

function h3ToString(h: H3Index; str: PUTF8Char; sz: NativeUInt): H3Error; cdecl;
  external UBER_H3 name _PU + 'h3ToString';

function isValidCell(h: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'isValidCell';

function cellToParent(h: H3Index; parentRes: Integer; parent: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToParent';

function cellToChildrenSize(h: H3Index; childRes: Integer; &out: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToChildrenSize';

function cellToChildren(h: H3Index; childRes: Integer; children: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToChildren';

function cellToCenterChild(h: H3Index; childRes: Integer; child: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToCenterChild';

function compactCells(const h3Set: PH3Index; compactedSet: PH3Index; const numHexes: Int64): H3Error; cdecl;
  external UBER_H3 name _PU + 'compactCells';

function uncompactCellsSize(const compactedSet: PH3Index; const numCompacted: Int64; const res: Integer; &out: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'uncompactCellsSize';

function uncompactCells(const compactedSet: PH3Index; const numCompacted: Int64; outSet: PH3Index; const numOut: Int64; const res: Integer): H3Error; cdecl;
  external UBER_H3 name _PU + 'uncompactCells';

function isResClassIII(h: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'isResClassIII';

function isPentagon(h: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'isPentagon';

function maxFaceCount(h3: H3Index; &out: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'maxFaceCount';

function getIcosahedronFaces(h3: H3Index; &out: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'getIcosahedronFaces';

function areNeighborCells(origin: H3Index; destination: H3Index; &out: PInteger): H3Error; cdecl;
  external UBER_H3 name _PU + 'areNeighborCells';

function cellsToDirectedEdge(origin: H3Index; destination: H3Index; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellsToDirectedEdge';

function isValidDirectedEdge(edge: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'isValidDirectedEdge';

function getDirectedEdgeOrigin(edge: H3Index; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'getDirectedEdgeOrigin';

function getDirectedEdgeDestination(edge: H3Index; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'getDirectedEdgeDestination';

function directedEdgeToCells(edge: H3Index; originDestination: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'directedEdgeToCells';

function originToDirectedEdges(origin: H3Index; edges: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'originToDirectedEdges';

function directedEdgeToBoundary(edge: H3Index; gb: PCellBoundary): H3Error; cdecl;
  external UBER_H3 name _PU + 'directedEdgeToBoundary';

function cellToVertex(origin: H3Index; vertexNum: Integer; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToVertex';

function cellToVertexes(origin: H3Index; vertexes: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToVertexes';

function vertexToLatLng(vertex: H3Index; point: PLatLng): H3Error; cdecl;
  external UBER_H3 name _PU + 'vertexToLatLng';

function isValidVertex(vertex: H3Index): Integer; cdecl;
  external UBER_H3 name _PU + 'isValidVertex';

function gridDistance(origin: H3Index; h3: H3Index; distance: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridDistance';

function gridPathCellsSize(start: H3Index; &end: H3Index; size: PInt64): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridPathCellsSize';

function gridPathCells(start: H3Index; &end: H3Index; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'gridPathCells';

function cellToLocalIj(origin: H3Index; h3: H3Index; mode: UInt32; &out: PCoordIJ): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToLocalIj';

function localIjToCell(origin: H3Index; const ij: PCoordIJ; mode: UInt32; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'localIjToCell';

procedure setGeoDegs(p: PLatLng; latDegs: Double; lngDegs: Double); cdecl;
  external UBER_H3 name _PU + 'setGeoDegs';

function constrainLat(lat: Double): Double; cdecl;
  external UBER_H3 name _PU + 'constrainLat';

function constrainLng(lng: Double): Double; cdecl;
  external UBER_H3 name _PU + 'constrainLng';

function geoAlmostEqual(const p1: PLatLng; const p2: PLatLng): Boolean; cdecl;
  external UBER_H3 name _PU + 'geoAlmostEqual';

function geoAlmostEqualThreshold(const p1: PLatLng; const p2: PLatLng; threshold: Double): Boolean; cdecl;
  external UBER_H3 name _PU + 'geoAlmostEqualThreshold';

function _posAngleRads(rads: Double): Double; cdecl;
  external UBER_H3 name _PU + '_posAngleRads';

procedure _setGeoRads(p: PLatLng; latRads: Double; lngRads: Double); cdecl;
  external UBER_H3 name _PU + '_setGeoRads';

function _geoAzimuthRads(const p1: PLatLng; const p2: PLatLng): Double; cdecl;
  external UBER_H3 name _PU + '_geoAzimuthRads';

procedure _geoAzDistanceRads(const p1: PLatLng; az: Double; distance: Double; p2: PLatLng); cdecl;
  external UBER_H3 name _PU + '_geoAzDistanceRads';

function bboxIsTransmeridian(const bbox: PBBox): Boolean; cdecl;
  external UBER_H3 name _PU + 'bboxIsTransmeridian';

procedure bboxCenter(const bbox: PBBox; center: PLatLng); cdecl;
  external UBER_H3 name _PU + 'bboxCenter';

function bboxContains(const bbox: PBBox; const point: PLatLng): Boolean; cdecl;
  external UBER_H3 name _PU + 'bboxContains';

function bboxEquals(const b1: PBBox; const b2: PBBox): Boolean; cdecl;
  external UBER_H3 name _PU + 'bboxEquals';

function bboxHexEstimate(const bbox: PBBox; res: Integer): Int64; cdecl;
  external UBER_H3 name _PU + 'bboxHexEstimate';

function lineHexEstimate(const origin: PLatLng; const destination: PLatLng; res: Integer): Int64; cdecl;
  external UBER_H3 name _PU + 'lineHexEstimate';

function _v2dMag(const v: PVec2d): Double; cdecl;
  external UBER_H3 name _PU + '_v2dMag';

procedure _v2dIntersect(const p0: PVec2d; const p1: PVec2d; const p2: PVec2d; const p3: PVec2d; inter: PVec2d); cdecl;
  external UBER_H3 name _PU + '_v2dIntersect';

function _v2dEquals(const p0: PVec2d; const p1: PVec2d): Boolean; cdecl;
  external UBER_H3 name _PU + '_v2dEquals';

procedure _setIJK(ijk: PCoordIJK; i: Integer; j: Integer; k: Integer); cdecl;
  external UBER_H3 name _PU + '_setIJK';

procedure _hex2dToCoordIJK(const v: PVec2d; h: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_hex2dToCoordIJK';

procedure _ijkToHex2d(const h: PCoordIJK; v: PVec2d); cdecl;
  external UBER_H3 name _PU + '_ijkToHex2d';

function _ijkMatches(const c1: PCoordIJK; const c2: PCoordIJK): Integer; cdecl;
  external UBER_H3 name _PU + '_ijkMatches';

procedure _ijkAdd(const h1: PCoordIJK; const h2: PCoordIJK; sum: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_ijkAdd';

procedure _ijkSub(const h1: PCoordIJK; const h2: PCoordIJK; diff: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_ijkSub';

procedure _ijkScale(c: PCoordIJK; factor: Integer); cdecl;
  external UBER_H3 name _PU + '_ijkScale';

procedure _ijkNormalize(c: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_ijkNormalize';

function _unitIjkToDigit(const ijk: PCoordIJK): Direction; cdecl;
  external UBER_H3 name _PU + '_unitIjkToDigit';

procedure _upAp7(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_upAp7';

procedure _upAp7r(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_upAp7r';

procedure _downAp7(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_downAp7';

procedure _downAp7r(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_downAp7r';

procedure _downAp3(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_downAp3';

procedure _downAp3r(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_downAp3r';

procedure _neighbor(ijk: PCoordIJK; digit: Direction); cdecl;
  external UBER_H3 name _PU + '_neighbor';

procedure _ijkRotate60ccw(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_ijkRotate60ccw';

procedure _ijkRotate60cw(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + '_ijkRotate60cw';

function _rotate60ccw(digit: Direction): Direction; cdecl;
  external UBER_H3 name _PU + '_rotate60ccw';

function _rotate60cw(digit: Direction): Direction; cdecl;
  external UBER_H3 name _PU + '_rotate60cw';

function ijkDistance(const a: PCoordIJK; const b: PCoordIJK): Integer; cdecl;
  external UBER_H3 name _PU + 'ijkDistance';

procedure ijkToIj(const ijk: PCoordIJK; ij: PCoordIJ); cdecl;
  external UBER_H3 name _PU + 'ijkToIj';

procedure ijToIjk(const ij: PCoordIJ; ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + 'ijToIjk';

procedure ijkToCube(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + 'ijkToCube';

procedure cubeToIjk(ijk: PCoordIJK); cdecl;
  external UBER_H3 name _PU + 'cubeToIjk';

function normalizeMultiPolygon(root: PLinkedGeoPolygon): Integer; cdecl;
  external UBER_H3 name _PU + 'normalizeMultiPolygon';

function addNewLinkedPolygon(polygon: PLinkedGeoPolygon): PLinkedGeoPolygon; cdecl;
  external UBER_H3 name _PU + 'addNewLinkedPolygon';

function addNewLinkedLoop(polygon: PLinkedGeoPolygon): PLinkedGeoLoop; cdecl;
  external UBER_H3 name _PU + 'addNewLinkedLoop';

function addLinkedLoop(polygon: PLinkedGeoPolygon; loop: PLinkedGeoLoop): PLinkedGeoLoop; cdecl;
  external UBER_H3 name _PU + 'addLinkedLoop';

function addLinkedCoord(loop: PLinkedGeoLoop; const vertex: PLatLng): PLinkedLatLng; cdecl;
  external UBER_H3 name _PU + 'addLinkedCoord';

function countLinkedPolygons(polygon: PLinkedGeoPolygon): Integer; cdecl;
  external UBER_H3 name _PU + 'countLinkedPolygons';

function countLinkedLoops(polygon: PLinkedGeoPolygon): Integer; cdecl;
  external UBER_H3 name _PU + 'countLinkedLoops';

function countLinkedCoords(loop: PLinkedGeoLoop): Integer; cdecl;
  external UBER_H3 name _PU + 'countLinkedCoords';

procedure destroyLinkedGeoLoop(loop: PLinkedGeoLoop); cdecl;
  external UBER_H3 name _PU + 'destroyLinkedGeoLoop';

(**
 * Create a bounding box from a LinkedGeoLoop
 * @param geoloop Input GeoLoop
 * @param bbox     Output bbox
 *)
procedure bboxFromLinkedGeoLoop(const loop: PLinkedGeoLoop; bbox: PBBox); cdecl;
  external UBER_H3 name _PU + 'bboxFromLinkedGeoLoop';

(**
 * Take a given LinkedGeoLoop data structure and check if it
 * contains a given geo coordinate.
 * @param loop          The linked loop
 * @param bbox          The bbox for the loop
 * @param coord         The coordinate to check
 * @return              Whether the point is contained
 *)
function pointInsideLinkedGeoLoop(const loop: PLinkedGeoLoop; const bbox: PBBox; const coord: PLatLng): Boolean; cdecl;
  external UBER_H3 name _PU + 'pointInsideLinkedGeoLoop';

(**
 * Whether the winding order of a given LinkedGeoLoop is clockwise
 * @param loop  The loop to check
 * @return      Whether the loop is clockwise
 *)
function isClockwiseLinkedGeoLoop(const loop: PLinkedGeoLoop): Boolean; cdecl;
  external UBER_H3 name _PU + 'isClockwiseLinkedGeoLoop';

procedure initVertexGraph(graph: PVertexGraph; numBuckets: Integer; res: Integer); cdecl;
  external UBER_H3 name _PU + 'initVertexGraph';

procedure destroyVertexGraph(graph: PVertexGraph); cdecl;
  external UBER_H3 name _PU + 'destroyVertexGraph';

function addVertexNode(graph: PVertexGraph; const fromVtx: PLatLng; const toVtx: PLatLng): PVertexNode; cdecl;
  external UBER_H3 name _PU + 'addVertexNode';

function removeVertexNode(graph: PVertexGraph; node: PVertexNode): Integer; cdecl;
  external UBER_H3 name _PU + 'removeVertexNode';

function findNodeForEdge(const graph: PVertexGraph; const fromVtx: PLatLng; const toVtx: PLatLng): PVertexNode; cdecl;
  external UBER_H3 name _PU + 'findNodeForEdge';

function findNodeForVertex(const graph: PVertexGraph; const fromVtx: PLatLng): PVertexNode; cdecl;
  external UBER_H3 name _PU + 'findNodeForVertex';

function firstVertexNode(const graph: PVertexGraph): PVertexNode; cdecl;
  external UBER_H3 name _PU + 'firstVertexNode';

function _hashVertex(const vertex: PLatLng; res: Integer; numBuckets: Integer): UInt32; cdecl;
  external UBER_H3 name _PU + '_hashVertex';

procedure _initVertexNode(node: PVertexNode; const fromVtx: PLatLng; const toVtx: PLatLng); cdecl;
  external UBER_H3 name _PU + '_initVertexNode';

function h3NeighborRotations(origin: H3Index; dir: Direction; rotations: PInteger; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'h3NeighborRotations';

function directionForNeighbor(origin: H3Index; destination: H3Index): Direction; cdecl;
  external UBER_H3 name _PU + 'directionForNeighbor';

procedure _kRingInternal(origin: H3Index; k: Integer; &out: PH3Index; distances: PInteger; maxIdx: Integer; curK: Integer); cdecl;
  external UBER_H3 name _PU + '_kRingInternal';

function h3SetToVertexGraph(const h3Set: PH3Index; const numHexes: Integer; &out: PVertexGraph): H3Error; cdecl;
  external UBER_H3 name _PU + 'h3SetToVertexGraph';

procedure _vertexGraphToLinkedGeo(graph: PVertexGraph; &out: PLinkedGeoPolygon); cdecl;
  external UBER_H3 name _PU + '_vertexGraphToLinkedGeo';

function _getEdgeHexagons(const geoloop: PGeoLoop; numHexagons: Int64; res: Integer; numSearchHexes: PInt64; search: PH3Index; found: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + '_getEdgeHexagons';

function _gridDiskDistancesInternal(origin: H3Index; k: Integer; &out: PH3Index; distances: PInteger; maxIdx: Int64; curK: Integer): H3Error; cdecl;
  external UBER_H3 name _PU + '_gridDiskDistancesInternal';

procedure _geoToFaceIjk(const g: PLatLng; res: Integer; h: PFaceIJK); cdecl;
  external UBER_H3 name _PU + '_geoToFaceIjk';

procedure _geoToHex2d(const g: PLatLng; res: Integer; face: PInteger; v: PVec2d); cdecl;
  external UBER_H3 name _PU + '_geoToHex2d';

procedure _faceIjkToGeo(const h: PFaceIJK; res: Integer; g: PLatLng); cdecl;
  external UBER_H3 name _PU + '_faceIjkToGeo';

procedure _faceIjkToCellBoundary(const h: PFaceIJK; res: Integer; start: Integer; length: Integer; g: PCellBoundary); cdecl;
  external UBER_H3 name _PU + '_faceIjkToCellBoundary';

procedure _faceIjkPentToCellBoundary(const h: PFaceIJK; res: Integer; start: Integer; length: Integer; g: PCellBoundary); cdecl;
  external UBER_H3 name _PU + '_faceIjkPentToCellBoundary';

procedure _faceIjkToVerts(fijk: PFaceIJK; res: PInteger; fijkVerts: PFaceIJK); cdecl;
  external UBER_H3 name _PU + '_faceIjkToVerts';

procedure _faceIjkPentToVerts(fijk: PFaceIJK; res: PInteger; fijkVerts: PFaceIJK); cdecl;
  external UBER_H3 name _PU + '_faceIjkPentToVerts';

procedure _hex2dToGeo(const v: PVec2d; face: Integer; res: Integer; substrate: Integer; g: PLatLng); cdecl;
  external UBER_H3 name _PU + '_hex2dToGeo';

function _adjustOverageClassII(fijk: PFaceIJK; res: Integer; pentLeading4: Integer; substrate: Integer): Overage; cdecl;
  external UBER_H3 name _PU + '_adjustOverageClassII';

function _adjustPentVertOverage(fijk: PFaceIJK; res: Integer): Overage; cdecl;
  external UBER_H3 name _PU + '_adjustPentVertOverage';

procedure _geoToClosestFace(const g: PLatLng; face: PInteger; sqd: PDouble); cdecl;
  external UBER_H3 name _PU + '_geoToClosestFace';

function _isBaseCellPentagon(baseCell: Integer): Integer; cdecl;
  external UBER_H3 name _PU + '_isBaseCellPentagon';

function _isBaseCellPolarPentagon(baseCell: Integer): Boolean; cdecl;
  external UBER_H3 name _PU + '_isBaseCellPolarPentagon';

function _faceIjkToBaseCell(const h: PFaceIJK): Integer; cdecl;
  external UBER_H3 name _PU + '_faceIjkToBaseCell';

function _faceIjkToBaseCellCCWrot60(const h: PFaceIJK): Integer; cdecl;
  external UBER_H3 name _PU + '_faceIjkToBaseCellCCWrot60';

function _baseCellToCCWrot60(baseCell: Integer; face: Integer): Integer; cdecl;
  external UBER_H3 name _PU + '_baseCellToCCWrot60';

procedure _baseCellToFaceIjk(baseCell: Integer; h: PFaceIJK); cdecl;
  external UBER_H3 name _PU + '_baseCellToFaceIjk';

function _baseCellIsCwOffset(baseCell: Integer; testFace: Integer): Boolean; cdecl;
  external UBER_H3 name _PU + '_baseCellIsCwOffset';

function _getBaseCellNeighbor(baseCell: Integer; dir: Direction): Integer; cdecl;
  external UBER_H3 name _PU + '_getBaseCellNeighbor';

function _getBaseCellDirection(originBaseCell: Integer; destinationBaseCell: Integer): Direction; cdecl;
  external UBER_H3 name _PU + '_getBaseCellDirection';

procedure setH3Index(h: PH3Index; res: Integer; baseCell: Integer; initDigit: Direction); cdecl;
  external UBER_H3 name _PU + 'setH3Index';

function isResolutionClassIII(r: Integer): Integer; cdecl;
  external UBER_H3 name _PU + 'isResolutionClassIII';

function _h3ToFaceIjkWithInitializedFijk(h: H3Index; fijk: PFaceIJK): Integer; cdecl;
  external UBER_H3 name _PU + '_h3ToFaceIjkWithInitializedFijk';

function _h3ToFaceIjk(h: H3Index; fijk: PFaceIJK): H3Error; cdecl;
  external UBER_H3 name _PU + '_h3ToFaceIjk';

function _faceIjkToH3(const fijk: PFaceIJK; res: Integer): H3Index; cdecl;
  external UBER_H3 name _PU + '_faceIjkToH3';

function _h3LeadingNonZeroDigit(h: H3Index): Direction; cdecl;
  external UBER_H3 name _PU + '_h3LeadingNonZeroDigit';

function _h3RotatePent60ccw(h: H3Index): H3Index; cdecl;
  external UBER_H3 name _PU + '_h3RotatePent60ccw';

function _h3RotatePent60cw(h: H3Index): H3Index; cdecl;
  external UBER_H3 name _PU + '_h3RotatePent60cw';

function _h3Rotate60ccw(h: H3Index): H3Index; cdecl;
  external UBER_H3 name _PU + '_h3Rotate60ccw';

function _h3Rotate60cw(h: H3Index): H3Index; cdecl;
  external UBER_H3 name _PU + '_h3Rotate60cw';

function _zeroIndexDigits(h: H3Index; start: Integer; &end: Integer): H3Index; cdecl;
  external UBER_H3 name _PU + '_zeroIndexDigits';

function iterInitParent(h: H3Index; childRes: Integer): IterCellsChildren; cdecl;
  external UBER_H3 name _PU + 'iterInitParent';

function iterInitBaseCellNum(baseCellNum: Integer; childRes: Integer): IterCellsChildren; cdecl;
  external UBER_H3 name _PU + 'iterInitBaseCellNum';

procedure iterStepChild(iter: PIterCellsChildren); cdecl;
  external UBER_H3 name _PU + 'iterStepChild';

function iterInitRes(res: Integer): IterCellsResolution; cdecl;
  external UBER_H3 name _PU + 'iterInitRes';

procedure iterStepRes(iter: PIterCellsResolution); cdecl;
  external UBER_H3 name _PU + 'iterStepRes';

function cellToLocalIjk(origin: H3Index; h3: H3Index; &out: PCoordIJK): H3Error; cdecl;
  external UBER_H3 name _PU + 'cellToLocalIjk';

function localIjkToCell(origin: H3Index; const ijk: PCoordIJK; &out: PH3Index): H3Error; cdecl;
  external UBER_H3 name _PU + 'localIjkToCell';

function _ipow(base: Int64; exp: Int64): Int64; cdecl;
  external UBER_H3 name _PU + '_ipow';

procedure bboxesFromGeoPolygon(const polygon: PGeoPolygon; bboxes: PBBox); cdecl;
  external UBER_H3 name _PU + 'bboxesFromGeoPolygon';

function pointInsidePolygon(const geoPolygon: PGeoPolygon; const bboxes: PBBox; const coord: PLatLng): Boolean; cdecl;
  external UBER_H3 name _PU + 'pointInsidePolygon';

(**
 * Create a bounding box from a GeoLoop
 * @param geoloop Input GeoLoop
 * @param bbox     Output bbox
 *)
procedure bboxFromGeoLoop(const loop: PGeoLoop; bbox: PBBox); cdecl;
  external UBER_H3 name _PU + 'bboxFromGeoLoop';

(**
 * Take a given GeoLoop data structure and check if it
 * contains a given geo coordinate.
 * @param loop          The geoloop
 * @param bbox          The bbox for the loop
 * @param coord         The coordinate to check
 * @return              Whether the point is contained
 *)
function pointInsideGeoLoop(const loop: PGeoLoop; const bbox: PBBox; const coord: PLatLng): Boolean; cdecl;
  external UBER_H3 name _PU + 'pointInsideGeoLoop';

(**
 * Whether the winding order of a given GeoLoop is clockwise
 * @param loop  The loop to check
 * @return      Whether the loop is clockwise
 *)
function isClockwiseGeoLoop(const geoloop: PGeoLoop): Boolean; cdecl;
  external UBER_H3 name _PU + 'isClockwiseGeoLoop';

procedure _geoToVec3d(const geo: PLatLng; point: PVec3d); cdecl;
  external UBER_H3 name _PU + '_geoToVec3d';

function _pointSquareDist(const p1: PVec3d; const p2: PVec3d): Double; cdecl;
  external UBER_H3 name _PU + '_pointSquareDist';

function vertexNumForDirection(const origin: H3Index; const direction: Direction): Integer; cdecl;
  external UBER_H3 name _PU + 'vertexNumForDirection';

function directionForVertexNum(const origin: H3Index; const vertexNum: Integer): Direction; cdecl;
  external UBER_H3 name _PU + 'directionForVertexNum';

implementation

end.

Bye for now,
  Skybuck.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20220731/8d8271c1/attachment-0001.htm>


More information about the fpc-pascal mailing list