NumPy Geometry

Working with geometry using numpy.

Maintained by Dan-Patterson

Geo array basics

Import npg and take a subsample of some featureclass (in_fc) geometry objects (g).

IFT refers to the feature id value, the from and to points.

To reduce numeric problems, the value of the lower left corner is subtracted from all coordinates moving coordinate space into quadrant I. You could also subtract the mean value of the points which would center the shapes about the x-y axis origin.

test2(g, kind=2)  # a polygon featureclass with 3 shapes

Listing of Geo array properties and functions

npg.dirr(g)

----------------------------------------------------------------------
| dir(npg) ...
|    <class 'npg.Geo'>
-------... Geo class ...

  (001)  Bit                            CL                             FT                             
  (002)  Fr                             H                              IDs                            
  (003)  IFT                            IFT_str                        IP                             
  (004)  Info                           K                              LL                             
  (005)  N                              PID                            SR                             
  (006)  SVG                            To                             U                              
  (007)  UR                             X                              XT                             
  (008)  XY                             Y                              Z                              
  (009)  __author__                     __dict__                       __module__                     
  (010)  __name__                       all_parts                      all_shapes                     
  (011)  aoi_extent                     aoi_rectangle                  areas                          
  (012)  as_arrays                      as_lists                       bit_IFT                        
  (013)  bit_ids                        bit_pnt_cnt                    bit_seq                        
  (014)  bits                           boundary                       bounding_circles               
  (015)  centers                        centroids                      change_indices                 
  (016)  close_polylines                common_segments                convex_hulls                   
  (017)  densify_by_distance            densify_by_factor              densify_by_percent             
  (018)  dupl_pnts                      extent_centers                 extent_corner                  
  (019)  extent_pnts                    extent_rectangles              extents                        
  (020)  facts                          fill_holes                     first_bit                      
  (021)  first_part                     fr_to_pnts                     geo_props                      
  (022)  geom_check                     get_shapes                     holes_to_shape                 
  (023)  inner_IFT                      inner_rings                    is_clockwise                   
  (024)  is_convex                      is_in                          is_multipart                   
  (025)  is_multipart_report            lengths                        maxs                           
  (026)  means                          min_area_rect                  mins                           
  (027)  moveto                         multipart_to_singlepart        od_pairs                       
  (028)  outer_IFT                      outer_rings                    part_IFT                       
  (029)  part_ids                       parts                          pnt_counts                     
  (030)  pnt_ids                        pnt_indices                    pnt_on_poly                    
  (031)  polygon_angles                 polygons_to_polylines          polyline_angles                
  (032)  polylines_to_polygons          polys_to_points                prn                            
  (033)  prn_arr                        prn_obj                        radial_sort                    
  (034)  roll_shapes                    rotate                         segment_angles                 
  (035)  segment_pnt_ids                segment_polys                  shapes                         
  (036)  shift                          shp_IFT                        shp_ids                        
  (037)  shp_part_cnt                   shp_pnt_cnt                    shp_pnt_ids                    
  (038)  singleton_pnts                 sort_by_area                   sort_by_extent                 
  (039)  sort_by_length                 sort_coords                    split_by                       
  (040)  structure                      svg                            to_segments                    
  (041)  translate                      triangulate                    uniq_pnts                      
  (042)  unique_segments                xy_id                          

Functions from modules ...
npg_geom ...
  (043)  CH                             Delaunay                       bin_pnts                       
  (044)  common_extent                  densify_by_distance            densify_by_factor              
  (045)  eucl_dist                      extent_to_poly                 find_closest                   
  (046)  in_hole_check                  mabr                           npGeo                          
  (047)  np_wn                          offset_buffer                  pnts_in_pnts                   
  (048)  pnts_on_poly                   pnts_to_extent                 polys_to_segments              
  (049)  polys_to_unique_pnts           repack_fields                  scale_by_area                  
  (050)  script                         segments_to_polys              simplify_lines                 
  (051)  stu                            triangulate_pnts               uts                            
npg_geom  helpers ...
  (052)  _add_pnts_on_line_             _angles_3pnt_                  _bit_area_                     
  (053)  _bit_min_max_                  _ch_                           _ch_scipy_                     
  (054)  _ch_simple_                    _closest_pnt_on_poly_          _dist_along_                   
  (055)  _e_2d_                         _get_base_                     _in_extent_                    
  (056)  _is_pnt_on_line_               _percent_along_                _pnt_on_segment_               
npg_helpers ...
  (057)  a_eq_b                         cartesian_product              coerce2array                   
  (058)  common_pnts                    compare_geom                   del_seq_dups                   
  (059)  dist_angle_sort                flat                           interweave                     
  (060)  keep_geom                      polyline_angles                project_pnt_to_line            
  (061)  radial_sort                    reclass_ids                    remove_geom                    
  (062)  segment_angles                 shape_finder                   sort_xy                        
  (063)  stride_2d                      uniq_1d                        uniq_2d                        
npg_helpers helpers ...
  (064)  _angles_3pnt_                  _area_centroid_                _bit_area_                     
  (065)  _bit_check_                    _bit_crossproduct_             _bit_length_                   
  (066)  _bit_min_max_                  _bit_segment_angles_           _from_north_                   
  (067)  _from_to_pnts_                 _get_base_                     _in_LBRT_                      
  (068)  _in_extent_                    _is_ccw_                       _is_clockwise_                 
  (069)  _is_convex_                    _is_right_side                 _isin_2d_                      
  (070)  _od_angles_dist_               _perp_                         _pnts_in_extent_               
  (071)  _rotate_                       _scale_                        _to_lists_                     
  (072)  _trans_rot_                    _translate_                    prn_tbl                        
npg_io ...
  (073)  dtype_info                     load_geo                       save_geo                       
  (074)  load_txt                       save_txt                       load_geojson                   
  (075)  geojson_Geo                    
npg_prn ...
  (076)  _svg                           prn_                           prn_Geo_shapes                 
  (077)  prn_arrays                     prn_as_obj                     prn_geo                        
  (078)  prn_lists                      prn_q                          prn_tbl                        

  

Geo array creation

new(cls, g=None, IFT=None, Kind=2, Info="Geo array")

g : array_like

IFT : array_like

Kind : integer

Info : text (optional)


Properties

g      the ndarray of xy coordinates
g.T  # ---- g.T shown
# ---- Geo[[Xs], [Ys]]

Geo([[ 10.0,  10.0,  1.5,  0.0,  10.0,  3.0,  3.0,  9.0,  9.0,  3.0,  2.0,
       1.0,  2.0,  2.0,  2.0,  1.0,  1.0,  2.0,  8.0,  8.0,  4.0,  5.0,  8.0,
       6.0,  5.0,  7.0,  6.0,  25.0,  25.0,  15.0,  15.0,  23.0,  23.0,  15.0,
       15.0,  25.0,  20.0,  20.0,  12.0,  12.0,  20.0,  20.0,  10.0,  10.0,
       14.0,  20.0,  11.0,  12.0,  12.0,  11.0,  10.5,  10.5,  11.5,  10.5,
       10.5,  10.5,  11.5,  10.5,  14.0,  10.0,  15.0,  14.0],
     [ 10.0,  0.0,  1.5,  10.0,  10.0,  9.0,  3.0,  3.0,  9.0,  9.0,  7.0,
       7.0,  5.0,  7.0,  8.0,  9.0,  8.0,  8.0,  8.0,  4.0,  4.0,  7.0,  8.0,
       7.0,  5.0,  5.0,  7.0,  14.0,  4.0,  4.0,  6.0,  6.0,  12.0,  12.0,
       14.0,  14.0,  10.0,  8.0,  8.0,  2.0,  2.0,  0.0,  0.0,  10.0,  10.0,
       10.0,  9.0,  8.5,  9.0,  9.0,  8.5,  7.0,  7.0,  8.5,  2.0,  0.5,  0.5,
       2.0,  10.0,  10.0,  18.0,  10.0]])

The structure and relationships between the array elements is given in the IFT property.

g.IFT ==> Id, From, To - shape ID, from-to points in the shape

g.IFT
array([[ 1,  0,  5,  1,  1,  0],
       [ 1,  5, 10,  0,  1,  1],
       [ 1, 10, 14,  0,  1,  2],
       [ 1, 14, 18,  0,  1,  3],
       [ 1, 18, 23,  1,  2,  0],
       [ 1, 23, 27,  0,  2,  1],
       [ 2, 27, 36,  1,  1,  0],
       [ 2, 36, 46,  1,  2,  0],
       [ 2, 46, 50,  0,  2,  1],
       [ 2, 50, 54,  0,  2,  2],
       [ 2, 54, 58,  0,  2,  3],
       [ 3, 58, 62,  1,  1,  0]], dtype=int64)

Geo array ==>

g.IDs  IFT[:, 0]   shape identifier
[1 1 1 ... 2 2 3]

g.Fr   IFT[:, 1]   shape from point
[ 0  5 10 ... 50 54 58]

g.To   IFT[:, 2]         to point
[ 5 10 14 ... 54 58 62]

g.CW   IFT[:, 3]   shape orientation (C)lock(W)ise boolean result
[1 0 0 ... 0 0 1]

g.PID  IFT[:, 4]   part identifier within a shape
[1 1 1 ... 2 2 1]

g.Bit  IFT[:, 5]   bit identifier with a shape
[0 1 2 ... 2 3 0]

g.FT   IFT[:, 1:3] from-to point pairs
[[ 0  5]
 [ 5 10]
 [10 14]
 ...
 [50 54]
 [54 58]
 [58 62]]

g.K ... 2 ...  shape kind 1, 2, 3 for points, polylines, polygons
g.Info ... test ... extra information string

g.H ... Help on Geo arrays

**Geo class**
-------------

Construction from an ndarray, IFT, Kind and optional Info.

Parameters
----------
**Required**

arr : array-like
    A 2D array sequence of points with shape (N, 2).
IFT : array-like
    Defines, the I(d)F(rom)T(o) and other structural elements that are
    present in polyline or polygon geometry that `arr` represents .
    Shape (N, 6) required.
Kind : integer
    Points (0), polylines/lines (1) and polygons (2).
Info : string (optional)
    Optional information if needed.

**Derived**

IDs : IFT[:, 0]
    Shape ids, the id number will be repeated for each part and hole in
    the shape
Fr : IFT[:, 1]
    The ``from`` point in the point sequence.
To : IFT[:, 2]
    The ``to`` point in the point sequence.
CW : IFT[:, 3]
    A value of ``1`` for exterior rings, ``0`` for interior/holes.
PID : IFT[:, 4]
    Part ids sequence by shape.  A singlepart shape will have one (1) part.
    Subsequent parts are numbered incrementally.
Bit : IFT[:, 5]
    The bit sequence in a singlepart feature with holes and/or multipart
    features with or without holes
FT : IFT[:, 1:3]
    The from-to ids together (Fr, To).
IP : IFT[:, [0, 4]]
    Shape and part ids together (IDs, PID)
N : integer
    The number of unique shapes.
U : integer(s)
    A sequence of integers indicating the feature ID value.  There is no
    requirement for these to be sequential.
SR : text
    Spatial reference name.
X, Y, XY, Z: Derived from columns in the point array.
    X = arr[:, 0], Y = arr[:, 0], XY = arr[:, :2],
    Z = arr[:, 2] if defined
XT : array
    An array/list of points identifying the lower-left and upper-right,
    of full extent of all the geometry objects.
LL, UR : array
    The extent points as defined in XT.
hlp : this
    self.H or self.docs where self is a Geo array will recall this information.

A featureclass with 3 shapes. The first two are multipart with holes.

arr.IFT  # ---- annotated ----
#      IDs, Fr, To, CW, PID, Bit
array([[ 1,  0,  5,  1,   1,  0],  # first shape, first part, outer ring
       [ 1,  5, 10,  0,   1,  1],  # hole 1
       [ 1, 10, 14,  0,   1,  2],  # hole 2
       [ 1, 14, 18,  0,   1,  3],  # hole 3
       [ 1, 18, 23,  1,   2,  0],  # first shape, second part, outer ring
       [ 1, 23, 27,  0,   2,  1],  # hole 1
       [ 2, 27, 36,  1,   1,  0],  # second shape, first part, outer ring
       [ 2, 36, 46,  1,   2,  0],  # second shape, second part, outer ring
       [ 2, 46, 50,  0,   2,  1],  # hole 1
       [ 2, 50, 54,  0,   2,  2],  # hole 2
       [ 2, 54, 58,  0,   2,  3],  # hole 3
       [ 3, 58, 62,  1,   1,  0]], # third shape, first part, outer ring
                     dtype=int64)

Derived Properties


shape, part, and bit : N, part_cnt, bit_cnt

shape, part and bit ids : shp_ids, part_ids, bit_ids

shape, part and bit counts : shp_IFT, part_IFT, bit_IFT

x, y and XY coordinates : X, Y, XY)

- sample size, unique shapes
g.N ... 3 ...  len(uni)   #  uni, idx = np.unique(arr.IDs, True)
g.U ... [1 2 3] ...  g.IDs[idx]

- coordinate values
g.X    g[:, 0]
[ 10.00  10.00  1.50 ...  10.00  15.00  14.00]

g.Y    g[:, 1]
[ 10.00  0.00  1.50 ...  10.00  18.00  10.00]

g.XY   g[:, :2]
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

g.g[    not implemented yet
- identifiers by shape, part, bit

g.shp_IFT
[[ 1  0 27 -1 -1 -1]
 [ 2 27 58 -1 -1 -1]
 [ 3 58 62 -1 -1 -1]]

g.part_IFT
[[ 1  0 18  1  1  0]
 [ 1 18 27  1  2  0]
 [ 2 27 36  1  1  0]
 [ 2 36 58  1  2  0]
 [ 3 58 62  1  1  0]]

g.bit_IFT
[[ 1  0  5  1  1  0]
 [ 1  5 10  0  1  1]
 [ 1 10 14  0  1  2]
 ...
 [ 2 50 54  0  2  2]
 [ 2 54 58  0  2  3]
 [ 3 58 62  1  1  0]]

g.shp_ids  :[1 2 3]
g.part_ids :[1 1 2 2 3]
g.bit_ids  :[1 1 1 ... 2 2 3]
g.bit_seq  :[0 1 2 ... 2 3 0]
g.pnt_ids  :[1 1 1 ... 3 3 3]
g.shp_pnt_cnt
[[ 1 27]
 [ 2 31]
 [ 3  4]]

g.shp_part_cnt
[[1 2]
 [2 2]
 [3 1]]

g.bit_pnt_cnt
[[1 0 5]
 [1 1 5]
 [1 2 4]
 ...
 [2 2 4]
 [2 3 4]
 [3 0 4]]

g.shapes
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 5.00  5.00]
 [ 7.00  5.00]
 [ 6.00  7.00]] ... snip
[[ 14.00  10.00]
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

g.parts
[ 10.00  10.00] ... snip
[[ 14.00  10.00]
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

g.bits
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 [ 0.00  10.00]
 [ 10.00  10.00]] ... snip
[[ 14.00  10.00]
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

Methods.....


(1) g.first_bit(True) ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(2) g.first_bit(True).IFT ...
[[ 1  0  5  1  1  0]
 [ 1  5 10  1  2  0]
 [ 2 10 19  1  1  0]
 [ 2 19 29  1  2  0]
 [ 3 29 33  1  1  0]]

(3) g.first_part(True) ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(4) g.first_part(True).IFT ...
[[ 1  0  5  1  1  0]
 [ 1  5 10  0  1  1]
 [ 1 10 14  0  1  2]
 [ 1 14 18  0  1  3]
 [ 2 18 27  1  1  0]
 [ 3 27 31  1  1  0]]

(5) g.get_shape(ID=3, asGeo=True) ...
[[ 14.00  10.00]
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(6) g.get_shape(ID=3, asGeo=True).IFT ...
[[3 0 4 1 1 0]]

(7) g.outer_rings(asGeo=True) ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(8) g.outer_rings(asGeo=True).IFT ...
[[ 1  0  5  1  1  0]
 [ 1  5 10  1  2  0]
 [ 2 10 19  1  1  0]
 [ 2 19 29  1  2  0]
 [ 3 29 33  1  1  0]]

(9) g.areas(True) ...
[ 57.50  102.25  16.00]

(10) g.areas(False) ...
[85.0, -36.0, -1.0, -0.5, 12.0, -2.0, 52.0, 52.0, -0.25, -0.75, -0.75, 16.0]

(11) g.lengths(True) ...
[ 90.71  123.22  21.50]

(12) g.lengths(False) ...
[37.26267650163207, 24.0, 5.23606797749979,... snip ..., 21.49623888035515]

(13) g.cent_shapes() ...
[[ 4.71  6.60]
 [ 15.35  7.18]
 [ 13.00  12.67]]

(14) g.cent_parts() ...
[[ 5.38  5.38]
 [ 6.25  5.75]
 [ 19.50  9.00]
 [ 15.33  5.56]
 [ 13.00  12.67]]

(15) g.centroids() ...
[[ 7.65  3.56]
 [ 16.51  6.09]
 [ 13.00  12.67]]

(16) g.aoi_extent() ...
[ 0.00  0.00  25.00  18.00]

(17) g.aoi_rectangle() ...
[[ 0.00  0.00]
 [ 0.00  18.00]
 [ 25.00  18.00]
 [ 25.00  0.00]
 [ 0.00  0.00]]

(18) g.extents(splitter="part") ...
[[ 0.00  0.00  10.00  10.00]
 [ 4.00  4.00  8.00  8.00]
 [ 15.00  4.00  25.00  14.00]
 [ 10.00  0.00  20.00  10.00]
 [ 10.00  10.00  15.00  18.00]]

(19) g.extents(splitter="shape") ...
[[ 0.00  0.00  10.00  10.00]
 [ 10.00  0.00  25.00  14.00]
 [ 10.00  10.00  15.00  18.00]]

(20) g.extent_centers(splitter="part") ...
[[ 5.00  5.00]
 [ 6.00  6.00]
 [ 20.00  9.00]
 [ 15.00  5.00]
 [ 12.50  14.00]]

(21) g.extent_centers(splitter="shape") ...
[[ 5.00  5.00]
 [ 17.50  7.00]
 [ 12.50  14.00]]

(22) g.extent_rectangles(splitter="shape") ...
[array([[ 300000.00,  5000000.00],
       [ 300000.00,  5000010.00],
       [ 300010.00,  5000010.00],
       [ 300010.00,  5000000.00],
       [ 300000.00,  5000000.00]]), array([[ 300010.00,  5000000.00],
       [ 300010.00,  5000014.00],
       [ 300025.00,  5000014.00],
       [ 300025.00,  5000000.00],
       [ 300010.00,  5000000.00]]), array([[ 300010.00,  5000010.00],
       [ 300010.00,  5000018.00],
       [ 300015.00,  5000018.00],
       [ 300015.00,  5000010.00],
       [ 300010.00,  5000010.00]])]

(23) g.extent_rectangles(splitter="part") ...
[array([[ 300000.00,  5000000.00],
       [ 300000.00,  5000010.00],
       [ 300010.00,  5000010.00],
       [ 300010.00,  5000000.00],
       [ 300000.00,  5000000.00]]), array([[ 300004.00,  5000004.00],
       [ 300004.00,  5000008.00],
       [ 300008.00,  5000008.00],
       [ 300008.00,  5000004.00],
       [ 300004.00,  5000004.00]]), array([[ 300015.00,  5000004.00],
       [ 300015.00,  5000014.00],
       [ 300025.00,  5000014.00],
       [ 300025.00,  5000004.00],
       [ 300015.00,  5000004.00]])]

(24) g.maxs(by_bit=False) ...
[[ 10.00  10.00]
 [ 25.00  14.00]
 [ 15.00  18.00]]

(25) g.maxs(by_bit=True) ...
[[ 10.00  10.00]
 [ 8.00  8.00]
 [ 25.00  14.00]
 [ 20.00  10.00]
 [ 15.00  18.00]]

(26) g.is_clockwise(is_closed_polyline=False) ...
[(1, 1) (1, 0) (1, 0) ... (2, 0) (2, 0) (3, 1)]

(27) g.is_convex() ...
[1 1 0 0 1]

(28) g.is_multipart(as_structured=False) ...
[[1 1]
 [2 1]
 [3 0]]

(29) g.polygon_angles(inside=True, in_deg=True) ...
[array([ 90.00,  79.99,  110.02,  79.99]),
 array([ 71.57,  90.00,  71.57,  126.87]),
 array([ 90.00,  90.00,  90.00,  90.00,  270.00,  270.00,  90.00,  90.00]),
 array([ 90.00,  90.00,  270.00,  270.00,  90.00,  90.00,  90.00,  90.00, 180.00]),
 array([ 97.13,  57.99,  24.88])
 ]

(30) g.bounding_circles(angle=5, return_xyr=False) ...
[[ 0.00  8.26]
 [ 0.03  8.88]
 [ 0.11  9.49]
 ...
 [ 9.93  16.44]
 [ 9.87  16.85]
 [ 9.85  17.26]]

(31) g.min_area_rect(as_structured=False) ...
[[ 139.67 -1.41 -1.41  9.49  11.41]
 [ 23.52  3.20  4.60  8.80  8.80]
 [ 100.00  15.00  4.00  25.00  14.00]
 [ 100.00  10.00  0.00  20.00  10.00]
 [ 54.02  8.55  9.74  16.45  16.58]]

(32) g.triangulate(by_bit=False, as_polygon=True) ...
[[ 3.00  9.00]
 [ 0.00  10.00]
 [ 10.00  10.00]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(33) g.fill_holes() ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(34) g.holes_to_shape() ...
[[ 3.00  9.00]
 [ 9.00  9.00]
 [ 9.00  3.00]
 ...
 [ 11.50  0.50]
 [ 10.50  0.50]
 [ 10.50  2.00]]

(35) g.multipart_to_singlepart(info="") ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(36) g.od_pairs() ...
[[ 10.00  10.00  10.00  0.00]
 [ 10.00  0.00  1.50  1.50]
 [ 1.50  1.50  0.00  10.00]
 [ 0.00  10.00  10.00  10.00]]

(37) g.polygons_to_polylines() ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(38) g.boundary() ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.00  10.00]
 [ 15.00  18.00]
 [ 14.00  10.00]]

(39) g.polys_to_points(keep_order=True, as_structured=False) ...
[[ 10.00  10.00]
 [ 10.00  0.00]
 [ 1.50  1.50]
 ...
 [ 10.50  0.50]
 [ 11.50  0.50]
 [ 15.00  18.00]]

(40) g.densify_by_distance(spacing=1)n ...
[[ 10.00  10.00]
 [ 10.00  9.00]
 [ 10.00  8.00]
 ...
 [ 14.13  11.05]
 [ 14.01  10.06]
 [ 14.00  10.00]]

(41) g.densify_by_percent(percent=50) ...
[[ 10.00  10.00]
 [ 10.00  4.63]
 [ 10.00  0.00]
 ...
 [ 15.00  18.00]
 [ 14.25  12.00]
 [ 14.00  10.00]]


Others of interest


A simplified informational table of a Geo array's IFT array with annotations. Useful for documentation purposes.

sq2.structure()

Geo array structure
-------------------
OID_    : self.Id   shape id
Fr_pnt  : self.Fr   from point id
To_pnt  : self.To   to point id for a shape
CW_CCW  : self.CW   outer (1) inner/hole (0)
Part_ID : self.PID  part id for each shape
Bit_ID  : self.Bit  sequence order of each part in a shape
----

...    OID_    Fr_pnt    To_pnt    CW_CCW    Part_ID    Bit_ID  
--------------------------------------------------------------
 000      1         0         7         1          1         0
 001      1         7        11         0          1         1
 002      2        11        19         1          1         0
 003      3        19        25         1          1         0
 004      4        25        30         1          1         0