Sfoglia il codice sorgente

bugfix for https://trac.osgeo.org/grass/ticket/111 by Benjamin Ducke; (non?)fix for calc'ing cell neighbourhoods in combination with raster masks by Mark Lake

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@36161 15284696-431f-4ddb-bdfa-cd5b030d7da7
Hamish Bowman 16 anni fa
parent
commit
45870744c6
4 ha cambiato i file con 72 aggiunte e 3 eliminazioni
  1. 45 2
      raster/r.los/delete.c
  2. 7 0
      raster/r.los/main.c
  3. 6 0
      raster/r.los/point.h
  4. 14 1
      raster/r.los/pts_elim.c

+ 45 - 2
raster/r.los/delete.c

@@ -33,18 +33,61 @@ struct point *delete(struct point *PT_TO_DELETE, struct point *head,
     segment_put(seg_out_p, value,
 		row_viewpt - PT_TO_DELETE_Y, PT_TO_DELETE_X + col_viewpt);
 
-    if (PT_TO_DELETE == head) {	/*  first one ?  */
+    /* If first and last point. This fixes a bug in r.los. See pts_elim.c for details */
+    if ((PT_TO_DELETE == head) && (PT_NEXT_TO_DELETED == NULL)) {
 	NEXT_PT_BACK_PTR = NULL;
 	head = PT_NEXT_TO_DELETED;
 	G_free(PT_TO_DELETE);
 	return (head);
     }
 
+    if (PT_TO_DELETE == head) { /*  first one ?  */
+	NEXT_PT_BACK_PTR = NULL;
+	head = PT_NEXT_TO_DELETED;
+	/* 
+	   We cannot delete this point right now, as pts_elim.c might still
+	   reference it. Thus, we only mark it for deletion now by pointing
+	   the global DELAYED_DELETE to it and free it the next time we
+	   get here! 
+	*/
+	if ( DELAYED_DELETE != NULL ) {
+	    G_free ( DELAYED_DELETE );
+	    DELAYED_DELETE = NULL;
+	} else {
+	    if ( PT_TO_DELETE != NULL ) {
+	        DELAYED_DELETE = PT_TO_DELETE;
+	    }
+	}
+	
+	return (head);
+    }
+
+    /* If last point. This fixes a bug in r.los. See pts_elim.c for details */
+    if (PT_NEXT_TO_DELETED == NULL) {
+        PREVIOUS_PT_NEXT_PTR = PT_NEXT_TO_DELETED;
+	G_free(PT_TO_DELETE);
+	return (head);
+    }
+
     /*  otherwise  */
 
     NEXT_PT_BACK_PTR = PT_PREVIOUS_TO_DELETED;
     PREVIOUS_PT_NEXT_PTR = PT_NEXT_TO_DELETED;
-    G_free(PT_TO_DELETE);
+	
+    /* 
+        We cannot delete this point right now, as pts_elim.c might still
+	reference it. Thus, we only mark it for deletion now by pointing
+	the global DELAYED_DELETE to it and free it the next time we
+	get here! 
+    */
+    if ( DELAYED_DELETE != NULL ) {
+        G_free ( DELAYED_DELETE );
+        DELAYED_DELETE = NULL;
+    } else {
+        if ( PT_TO_DELETE != NULL ) {
+	    DELAYED_DELETE = PT_TO_DELETE;
+	}
+    }
 
     return (head);
 

+ 7 - 0
raster/r.los/main.c

@@ -133,6 +133,8 @@ int main(int argc, char *argv[])
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
+    /* initialize delayed point deletion */
+    DELAYED_DELETE =  NULL;
 
     G_scan_easting(opt3->answers[0], &east, G_projection());
     G_scan_northing(opt3->answers[1], &north, G_projection());
@@ -414,5 +416,10 @@ int main(int argc, char *argv[])
     G_command_history(&history);
     G_write_history(out_layer, &history);
 
+    /* release that last tiny bit of memory ... */
+    if ( DELAYED_DELETE != NULL ) {
+        G_free ( DELAYED_DELETE );
+    }
+
     exit(EXIT_SUCCESS);
 }

+ 6 - 0
raster/r.los/point.h

@@ -48,6 +48,12 @@ struct point *hidden_point_elimination(struct point *, int, SEGMENT *,
 struct point *segment(int, int, int, double, double,
 		      int, int, int, int, SEGMENT *, SEGMENT *, SEGMENT *,
 		      int, int, int, int, double);
+/* 	
+	For delayed deletion of points (see delete3.c).
+	Initially set to NULL in main.c.
+*/
+struct point *DELAYED_DELETE;
+
 #endif
 
 /****************************************************************/

+ 14 - 1
raster/r.los/pts_elim.c

@@ -201,7 +201,20 @@ struct point *hidden_point_elimination(struct point *head, int viewpt_elev,
 	    segment_get(seg_patt_p, &mask, row_viewpt - BLOCKING_PT_Y,
 			col_viewpt + BLOCKING_PT_X);
 	    if (mask == 0 || G_is_null_value(&mask, CELL_TYPE)) {
-		if (NEXT_BLOCKING_PT != NULL)
+	    
+	      /* Commenting out the following fixes a bug in r.los.
+		 In that program the 8 cells around the viewpoint
+		 are marked as visible (when visible)
+		 even if they fall outside the area of interest 
+		 specified by the patt_map.  This occurs because
+		 these cells are always the last blocking points
+		 on the segment lists, and therefore don't get 
+		 deleted when they should.  This fix allows them
+		 to be deleted, but it required modifications
+		 to delete.c.  MWL 25/6/99 */	    
+	    
+		/* if (NEXT_BLOCKING_PT != NULL) */
+		
 		    head = delete(BLOCKING_PT, head, seg_out_p,
 				  row_viewpt, col_viewpt);
 	    }