[GRASS-SVN] r72259 - grass/trunk/vector/v.in.ogr

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Feb 21 01:03:22 PST 2018


Author: mmetz
Date: 2018-02-21 01:03:22 -0800 (Wed, 21 Feb 2018)
New Revision: 72259

Added:
   grass/trunk/vector/v.in.ogr/clean.c
Modified:
   grass/trunk/vector/v.in.ogr/main.c
   grass/trunk/vector/v.in.ogr/v.in.ogr.html
Log:
v.in.ogr: convert OSM line topology to GRASS topology for line crossings

Added: grass/trunk/vector/v.in.ogr/clean.c
===================================================================
--- grass/trunk/vector/v.in.ogr/clean.c	                        (rev 0)
+++ grass/trunk/vector/v.in.ogr/clean.c	2018-02-21 09:03:22 UTC (rev 72259)
@@ -0,0 +1,71 @@
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+
+/* The OSM topological model differs from the GRASS topological model. 
+ * OSM topologically correct connections of lines can be on all vertices of the line.
+ * -> split lines at all vertices where another line has the same vertex */
+void convert_osm_lines(struct Map_info *Map, double snap)
+{
+    int line, nlines;
+    struct line_pnts *Points = Vect_new_line_struct();
+    struct line_pnts *NPoints = Vect_new_line_struct();
+    struct line_cats *Cats = Vect_new_cats_struct();
+    double x, y, z, nx, ny;
+    int with_z = Vect_is_3d(Map);
+    int i, last_i, j, nline;
+    int line_split, n_splits;
+
+    G_message(_("Converting OSM lines..."));
+    
+    n_splits = 0;
+    if (snap < 0)
+	snap = 0;
+
+    nlines = Vect_get_num_lines(Map);
+    G_percent(0, nlines, 5);
+    for (line = 1; line <= nlines; line++) {
+	G_percent(line, nlines, 5);
+	if (Vect_get_line_type(Map, line) != GV_LINE)
+	    continue;
+	
+	Vect_read_line(Map, Points, Cats, line);
+	line_split = 0;
+	last_i = 0;
+	for (i = 1; i < Points->n_points - 1; i++) {
+	    x = Points->x[i];
+	    y = Points->y[i];
+	    z = Points->z[i];
+	    nline = Vect_find_line(Map, x, y, z, GV_LINE, snap, with_z, line);
+	    if (nline > 0) {
+		Vect_line_distance(Points, x, y, z, with_z, &nx, &ny,
+		                   NULL, NULL, NULL, NULL);
+
+		if (line_split == 0)
+		    Vect_delete_line(Map, line);
+		line_split++;
+		Points->x[i] = nx;
+		Points->y[i] = ny;
+		Vect_reset_line(NPoints);
+		for (j = last_i; j <= i; j++)
+		    Vect_append_point(NPoints, Points->x[j], Points->y[j], Points->z[j]);
+		Vect_write_line(Map, GV_LINE, NPoints, Cats);
+		last_i = i;
+		n_splits++;
+	    }
+	}
+	if (line_split) {
+	    Vect_reset_line(NPoints);
+	    for (j = last_i; j < Points->n_points; j++)
+		Vect_append_point(NPoints, Points->x[j], Points->y[j], Points->z[j]);
+	    Vect_write_line(Map, GV_LINE, NPoints, Cats);
+	}
+    }
+    if (n_splits)
+	G_verbose_message(_("Number of OSM line splits: %d"), n_splits);
+    G_message(_("Merging lines..."));
+    Vect_merge_lines(Map, GV_LINE, NULL, NULL);
+    Vect_destroy_cats_struct(Cats);
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_line_struct(NPoints);
+}


Property changes on: grass/trunk/vector/v.in.ogr/clean.c
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/x-csrc
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c	2018-02-21 08:40:03 UTC (rev 72258)
+++ grass/trunk/vector/v.in.ogr/main.c	2018-02-21 09:03:22 UTC (rev 72259)
@@ -26,7 +26,6 @@
 #include <grass/gis.h>
 #include <grass/dbmi.h>
 #include <grass/vector.h>
-#include <grass/gprojects.h>
 #include <grass/glocale.h>
 #include <gdal_version.h>	/* needed for OFTDate */
 #include <cpl_conv.h>
@@ -49,6 +48,8 @@
 
 char *get_datasource_name(const char *, int);
 
+void convert_osm_lines(struct Map_info *Map, double snap);
+
 int cmp_layer_srs(ds_t, int, int *, char **, char *);
 void check_projection(struct Cell_head *cellhd, ds_t hDS, int layer, char *geom_col,
                       char *outloc, int create_only, int override,
@@ -828,7 +829,7 @@
     }
     /* <-- estimate distance for boundary splitting */
 
-    use_tmp_vect = n_polygon_boundaries > 0;
+    use_tmp_vect = (n_polygon_boundaries > 0) || (strcmp(ogr_driver_name, "OSM") == 0);
 
     G_debug(1, "Input is 3D ? %s", (input3d == 0 ? "yes" : "no"));
     with_z = input3d;
@@ -947,7 +948,7 @@
 	    
 	    col_info = G_malloc(ncols_out * sizeof(struct grass_col_info));
 
-	    /* Create table */
+	    /* Collect column names and types */
 	    i_out = 0;
 	    col_info[i_out].idx = i_out;
 	    col_info[i_out].name = key_column[layer];
@@ -1109,7 +1110,7 @@
 	    qsort(col_info, ncols_out, sizeof(struct grass_col_info),
 		  cmp_col_idx);
 
-	    /* construct sql from column names and types */
+	    /* Create table */
 	    i = 0;
 	    sprintf(buf, "create table %s (%s %s", Fi->table,
 		    col_info[i].name, col_info[i].type);
@@ -1382,6 +1383,12 @@
 	Vect_build_partial(&Tmp, GV_BUILD_BASE);
     }
 
+    if (use_tmp_vect && !flag.no_clean->answer &&
+        strcmp(ogr_driver_name, "OSM") == 0 &&
+	Vect_get_num_primitives(Out, GV_LINE) > 0) {
+	convert_osm_lines(Out, snap);
+    }
+
     /* make this a separate function ?
      * no, too many arguments */
     if (use_tmp_vect && !flag.no_clean->answer &&
@@ -1920,11 +1927,11 @@
 
     if (OGR_iter->ogr_interleaved_reading) {
 #if GDAL_VERSION_NUM >= 2020000
-	G_verbose_message(_("Using GDAL 2.2+ style interleaved reading for GDAL version %d"),
-			  GDAL_VERSION_NUM); 
+	G_verbose_message(_("Using GDAL 2.2+ style interleaved reading for GDAL version %d.%d.%d"),
+			  GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR, GDAL_VERSION_REV); 
 #else
-	G_verbose_message(_("Using GDAL 1.x style interleaved reading for GDAL version %d"),
-			  GDAL_VERSION_NUM); 
+	G_verbose_message(_("Using GDAL 1.x style interleaved reading for GDAL version %d.%d.%d"),
+			  GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR, GDAL_VERSION_REV); 
 #endif
     }
 }

Modified: grass/trunk/vector/v.in.ogr/v.in.ogr.html
===================================================================
--- grass/trunk/vector/v.in.ogr/v.in.ogr.html	2018-02-21 08:40:03 UTC (rev 72258)
+++ grass/trunk/vector/v.in.ogr/v.in.ogr.html	2018-02-21 09:03:22 UTC (rev 72259)
@@ -318,9 +318,30 @@
 not belong to any of the above layers.
 </ul>
 
-It is recommended to import one layer at a time.
+It is recommended to import one layer at a time, and to select features 
+with the <b>where</b> option, e.g. to import roads, use 
 
+<div class="code"><pre>
+v.in.ogr where="highway <> ''"
+</pre></div>
+i.e. the OSM tag <em>highway</em> must be set.
+
 <p>
+When importing administrative boundaries from OSM, it is important to 
+not only select administrative boundaries, but also the admin level to 
+be imported (valid range is 1 - 11), e.g. with
+
+<div class="code"><pre>
+v.in.ogr where="boundary = 'administrative' and admin_level = '1'"
+</pre></div>
+
+<p>
+The OSM topological model differs from the GRASS topological model. OSM 
+topologically correct connections of lines can be on all vertices of a 
+line. During import, lines are automatically split at those vertices 
+where an OSM connection to another line exists.
+
+<p>
 Import of OSM data requires a configuration file, defined with the 
 OSM_CONFIG_FILE configuration option. In the data folder of the GDAL 
 distribution, you can find a <a href="https://svn.osgeo.org/gdal/trunk/gdal/data/osmconf.ini">osmconf.ini file</a>



More information about the grass-commit mailing list