[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