@@ -541,7 +541,6 @@ ptarray_clamp_to_ordinate_range(const POINTARRAY *ipa, char ordinate, double fro
541
541
static inline LWCOLLECTION *
542
542
lwline_clip_to_ordinate_range (const LWLINE * line , char ordinate , double from , double to )
543
543
{
544
-
545
544
POINTARRAY * pa_in = NULL ;
546
545
LWCOLLECTION * lwgeom_out = NULL ;
547
546
POINTARRAY * dp = NULL ;
@@ -551,22 +550,15 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do
551
550
double ordinate_value_p = 0.0 , ordinate_value_q = 0.0 ;
552
551
char hasz , hasm ;
553
552
char dims ;
554
- #if POSTGIS_DEBUG_LEVEL >= 4
555
- char * geom_ewkt ;
556
- #endif
557
553
558
554
/* Null input, nothing we can do. */
559
- if ( ! line )
560
- {
561
- lwerror ("Null input geometry." );
562
- return NULL ;
563
- }
555
+ assert (line );
564
556
hasz = lwgeom_has_z (lwline_as_lwgeom (line ));
565
557
hasm = lwgeom_has_m (lwline_as_lwgeom (line ));
566
558
dims = FLAGS_NDIMS (line -> flags );
567
559
568
560
/* Asking for an ordinate we don't have. Error. */
569
- if ( (ordinate == 'Z' && ! hasz ) || (ordinate == 'M' && ! hasm ) )
561
+ if ((ordinate == 'Z' && !hasz ) || (ordinate == 'M' && !hasm ))
570
562
{
571
563
lwerror ("Cannot clip on ordinate %d in a %d-d geometry." , ordinate , dims );
572
564
return NULL ;
@@ -583,93 +575,81 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do
583
575
/* Get our input point array */
584
576
pa_in = line -> points ;
585
577
586
- for ( i = 0 ; i < pa_in -> npoints ; i ++ )
578
+ for (i = 0 ; i < pa_in -> npoints ; i ++ )
587
579
{
588
- LWDEBUGF (4 , "Point #%d" , i );
589
- LWDEBUGF (4 , "added_last_point %d" , added_last_point );
590
- if ( i > 0 )
580
+ if (i > 0 )
591
581
{
592
582
* q = * p ;
593
583
ordinate_value_q = ordinate_value_p ;
594
584
}
595
585
getPoint4d_p (pa_in , i , p );
596
586
ordinate_value_p = lwpoint_get_ordinate (p , ordinate );
597
- LWDEBUGF (4 , " ordinate_value_p %g (current)" , ordinate_value_p );
598
- LWDEBUGF (4 , " ordinate_value_q %g (previous)" , ordinate_value_q );
599
587
600
588
/* Is this point inside the ordinate range? Yes. */
601
- if ( ordinate_value_p >= from && ordinate_value_p <= to )
589
+ if (ordinate_value_p >= from && ordinate_value_p <= to )
602
590
{
603
- LWDEBUGF (4 , " inside ordinate range (%g, %g)" , from , to );
604
591
605
592
if ( ! added_last_point )
606
593
{
607
- LWDEBUG (4 ," new ptarray required" );
608
594
/* We didn't add the previous point, so this is a new segment.
609
- * Make a new point array. */
595
+ * Make a new point array. */
610
596
dp = ptarray_construct_empty (hasz , hasm , 32 );
611
597
612
598
/* We're transiting into the range so add an interpolated
613
- * point at the range boundary.
614
- * If we're on a boundary and crossing from the far side,
615
- * we also need an interpolated point. */
616
- if ( i > 0 && ( /* Don't try to interpolate if this is the first point */
617
- ( ordinate_value_p > from && ordinate_value_p < to ) || /* Inside */
618
- ( ordinate_value_p == from && ordinate_value_q > to ) || /* Hopping from above */
619
- ( ordinate_value_p == to && ordinate_value_q < from ) ) ) /* Hopping from below */
599
+ * point at the range boundary.
600
+ * If we're on a boundary and crossing from the far side,
601
+ * we also need an interpolated point. */
602
+ if (i > 0 &&
603
+ (/* Don't try to interpolate if this is the first point */
604
+ (ordinate_value_p > from && ordinate_value_p < to ) || /* Inside */
605
+ (ordinate_value_p == from && ordinate_value_q > to ) || /* Hopping from above */
606
+ (ordinate_value_p == to && ordinate_value_q < from ))) /* Hopping from below */
620
607
{
621
608
double interpolation_value ;
622
- (ordinate_value_q > to ) ? (interpolation_value = to ) : (interpolation_value = from );
609
+ (ordinate_value_q > to ) ? (interpolation_value = to )
610
+ : (interpolation_value = from );
623
611
point_interpolate (q , p , r , hasz , hasm , ordinate , interpolation_value );
624
612
ptarray_append_point (dp , r , LW_FALSE );
625
- LWDEBUGF (4 , "[0] interpolating between (%g, %g) with interpolation point (%g)" , ordinate_value_q , ordinate_value_p , interpolation_value );
626
613
}
627
614
}
628
615
/* Add the current vertex to the point array. */
629
616
ptarray_append_point (dp , p , LW_FALSE );
630
- if ( ordinate_value_p == from || ordinate_value_p == to )
631
- {
617
+ if (ordinate_value_p == from || ordinate_value_p == to )
632
618
added_last_point = 2 ; /* Added on boundary. */
633
- }
634
619
else
635
- {
636
620
added_last_point = 1 ; /* Added inside range. */
637
- }
638
621
}
639
622
/* Is this point inside the ordinate range? No. */
640
623
else
641
624
{
642
- LWDEBUGF (4 , " added_last_point (%d)" , added_last_point );
643
- if ( added_last_point == 1 )
625
+ if (added_last_point == 1 )
644
626
{
645
627
/* We're transiting out of the range, so add an interpolated point
646
- * to the point array at the range boundary. */
628
+ * to the point array at the range boundary. */
647
629
double interpolation_value ;
648
630
(ordinate_value_p > to ) ? (interpolation_value = to ) : (interpolation_value = from );
649
631
point_interpolate (q , p , r , hasz , hasm , ordinate , interpolation_value );
650
632
ptarray_append_point (dp , r , LW_FALSE );
651
- LWDEBUGF (4 , " [1] interpolating between (%g, %g) with interpolation point (%g)" , ordinate_value_q , ordinate_value_p , interpolation_value );
652
633
}
653
- else if ( added_last_point == 2 )
634
+ else if (added_last_point == 2 )
654
635
{
655
636
/* We're out and the last point was on the boundary.
656
- * If the last point was the near boundary, nothing to do.
657
- * If it was the far boundary, we need an interpolated point. */
658
- if ( from != to && (
659
- (ordinate_value_q == from && ordinate_value_p > from ) ||
660
- (ordinate_value_q == to && ordinate_value_p < to ) ) )
637
+ * If the last point was the near boundary, nothing to do.
638
+ * If it was the far boundary, we need an interpolated point. */
639
+ if (from != to && ((ordinate_value_q == from && ordinate_value_p > from ) ||
640
+ (ordinate_value_q == to && ordinate_value_p < to )))
661
641
{
662
642
double interpolation_value ;
663
- (ordinate_value_p > to ) ? (interpolation_value = to ) : (interpolation_value = from );
643
+ (ordinate_value_p > to ) ? (interpolation_value = to )
644
+ : (interpolation_value = from );
664
645
point_interpolate (q , p , r , hasz , hasm , ordinate , interpolation_value );
665
646
ptarray_append_point (dp , r , LW_FALSE );
666
- LWDEBUGF (4 , " [2] interpolating between (%g, %g) with interpolation point (%g)" , ordinate_value_q , ordinate_value_p , interpolation_value );
667
647
}
668
648
}
669
- else if ( i && ordinate_value_q < from && ordinate_value_p > to )
649
+ else if (i && ordinate_value_q < from && ordinate_value_p > to )
670
650
{
671
651
/* We just hopped over the whole range, from bottom to top,
672
- * so we need to add *two* interpolated points! */
652
+ * so we need to add *two* interpolated points! */
673
653
dp = ptarray_construct (hasz , hasm , 2 );
674
654
/* Interpolate lower point. */
675
655
point_interpolate (p , q , r , hasz , hasm , ordinate , from );
@@ -678,10 +658,10 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do
678
658
point_interpolate (p , q , r , hasz , hasm , ordinate , to );
679
659
ptarray_set_point4d (dp , 1 , r );
680
660
}
681
- else if ( i && ordinate_value_q > to && ordinate_value_p < from )
661
+ else if (i && ordinate_value_q > to && ordinate_value_p < from )
682
662
{
683
663
/* We just hopped over the whole range, from top to bottom,
684
- * so we need to add *two* interpolated points! */
664
+ * so we need to add *two* interpolated points! */
685
665
dp = ptarray_construct (hasz , hasm , 2 );
686
666
/* Interpolate upper point. */
687
667
point_interpolate (p , q , r , hasz , hasm , ordinate , to );
@@ -691,18 +671,15 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do
691
671
ptarray_set_point4d (dp , 1 , r );
692
672
}
693
673
/* We have an extant point-array, save it out to a multi-line. */
694
- if ( dp )
674
+ if (dp )
695
675
{
696
- LWDEBUG (4 , "saving pointarray to multi-line (1)" );
697
-
698
676
/* Only one point, so we have to make an lwpoint to hold this
699
- * and set the overall output type to a generic collection. */
700
- if ( dp -> npoints == 1 )
677
+ * and set the overall output type to a generic collection. */
678
+ if (dp -> npoints == 1 )
701
679
{
702
680
LWPOINT * opoint = lwpoint_construct (line -> srid , NULL , dp );
703
681
lwgeom_out -> type = COLLECTIONTYPE ;
704
682
lwgeom_out = lwcollection_add_lwgeom (lwgeom_out , lwpoint_as_lwgeom (opoint ));
705
-
706
683
}
707
684
else
708
685
{
@@ -714,39 +691,33 @@ lwline_clip_to_ordinate_range(const LWLINE *line, char ordinate, double from, do
714
691
dp = NULL ;
715
692
}
716
693
added_last_point = 0 ;
717
-
718
694
}
719
695
}
720
696
721
697
/* Still some points left to be saved out. */
722
- if ( dp && dp -> npoints > 0 )
698
+ if (dp )
723
699
{
724
- LWDEBUG (4 , "saving pointarray to multi-line (2)" );
725
- LWDEBUGF (4 , "dp->npoints == %d" , dp -> npoints );
726
- LWDEBUGF (4 , "lwgeom_out->ngeoms == %d" , lwgeom_out -> ngeoms );
727
-
728
- if ( dp -> npoints == 1 )
700
+ if (dp -> npoints == 1 )
729
701
{
730
702
LWPOINT * opoint = lwpoint_construct (line -> srid , NULL , dp );
731
703
lwgeom_out -> type = COLLECTIONTYPE ;
732
704
lwgeom_out = lwcollection_add_lwgeom (lwgeom_out , lwpoint_as_lwgeom (opoint ));
733
705
}
734
- else
706
+ else if ( dp -> npoints > 1 )
735
707
{
736
708
LWLINE * oline = lwline_construct (line -> srid , NULL , dp );
737
709
lwgeom_out = lwcollection_add_lwgeom (lwgeom_out , lwline_as_lwgeom (oline ));
738
710
}
739
-
740
- /* Pointarray is now owned by lwgeom_out, so drop reference to it */
741
- dp = NULL ;
711
+ else
712
+ ptarray_free (dp );
742
713
}
743
714
744
715
lwfree (p );
745
716
lwfree (q );
746
717
lwfree (r );
747
718
748
719
if (line -> bbox && lwgeom_out -> ngeoms > 0 )
749
- lwgeom_refresh_bbox ((LWGEOM * )lwgeom_out );
720
+ lwgeom_refresh_bbox ((LWGEOM * )lwgeom_out );
750
721
751
722
return lwgeom_out ;
752
723
}
@@ -826,22 +797,9 @@ lwtriangle_clip_to_ordinate_range(const LWTRIANGLE *tri, char ordinate, double f
826
797
static inline LWCOLLECTION *
827
798
lwcollection_clip_to_ordinate_range (const LWCOLLECTION * icol , char ordinate , double from , double to )
828
799
{
829
- LWCOLLECTION * lwgeom_out = NULL ;
830
-
831
- if (!icol )
832
- {
833
- lwerror ("Null input geometry." );
834
- return NULL ;
835
- }
836
-
837
- /* Ensure 'from' is less than 'to'. */
838
- if (to < from )
839
- {
840
- double t = from ;
841
- from = to ;
842
- to = t ;
843
- }
800
+ LWCOLLECTION * lwgeom_out ;
844
801
802
+ assert (icol );
845
803
if (icol -> ngeoms == 1 )
846
804
lwgeom_out = lwgeom_clip_to_ordinate_range (icol -> geoms [0 ], ordinate , from , to , 0 );
847
805
else
@@ -861,12 +819,15 @@ lwcollection_clip_to_ordinate_range(const LWCOLLECTION *icol, char ordinate, dou
861
819
if (col -> type != icol -> type )
862
820
lwgeom_out -> type = COLLECTIONTYPE ;
863
821
lwgeom_out = lwcollection_concat_in_place (lwgeom_out , col );
822
+ lwfree (col -> geoms );
864
823
lwcollection_release (col );
865
824
}
866
825
}
867
- if (icol -> bbox )
868
- lwgeom_refresh_bbox ((LWGEOM * )lwgeom_out );
869
826
}
827
+
828
+ if (icol -> bbox )
829
+ lwgeom_refresh_bbox ((LWGEOM * )lwgeom_out );
830
+
870
831
return lwgeom_out ;
871
832
}
872
833
@@ -877,6 +838,14 @@ lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, do
877
838
LWCOLLECTION * out_offset ;
878
839
uint32_t i ;
879
840
841
+ /* Ensure 'from' is less than 'to'. */
842
+ if (to < from )
843
+ {
844
+ double t = from ;
845
+ from = to ;
846
+ to = t ;
847
+ }
848
+
880
849
if ( ! lwin )
881
850
lwerror ("lwgeom_clip_to_ordinate_range: null input geometry!" );
882
851
0 commit comments