Trace vector contours from a scanned map: Difference between revisions

From GRASS-Wiki
Jump to navigation Jump to search
No edit summary
mNo edit summary
 
(25 intermediate revisions by 3 users not shown)
Line 1: Line 1:
* Import a scanned map image. To save processing later you might want to mask out obvious text and other noise in a paint program first.
== Import ==
 
'''Import a scanned map image'''
 
=== Preprocessing ===
* To save processing later you might want to mask out obvious text and other noise in a paint program first.
: For example, load the image into [http://www.gimp.org the GIMP] and cut away boxes of text, etc. If you are interested in a specific feature (such as solid black contour lines) you might try to isolate those by "Select -> By color" to pick out everything black, then "Select -> Invert" to pick everything that isn't black, and then "Edit -> Cut" to remove those parts of the image that we are not interested in. It helps if the original image starts with an indexed color palette. You also have the option of using GRASS's r.mapcalc module and other raster analysis modules to simplify the image after import. ''(see below)''
: The Magic Wand select tool may be of great help here as well.
: If the orignal file was a GeoTIFF, the paint program will typically strip off any geocoding metadata upon re-save. You can read those off with ''gdalinfo'' and reapply with ''gdal_translate'', or use the original image+''gdal_translate'' to create a TFW world file which can be used on the new image. Another option is to dump the metadata to a file with the ''listgeo'' program and reapply to the new image with the ''geotifcp'' program. Both these come with the [http://download.osgeo.org/geotiff/libgeotiff/ libgeotiff] software distribution. If using these tools it is important not to alter the dimensions of the image. See the [http://www.remotesensing.org/geotiff/faq.html#preserve_metadata GeoTIFF FAQ] for more information.
 
=== Import into GIS ===
 
* Import image into GRASS (probably into a simple XY location)
  r.in.gdal
  r.in.gdal


* georectify map using GUI georectifier or i.points + i.rectify
* [[Georeferencing | Georectify]] map using GUI georectifier or i.points + i.rectify
* switch to in target location
* Switch to target location
* we now have a registered raster map containing a 300 dpi scan of our A0 sized map
* We now have a registered raster map containing a 300 dpi scan of our A0 sized paper map
 
== Convert to vector map ==
 
=== Isolate contour lines ===
''(see also pre-processing hints above)''


* check how many categories
* Check how many categories (map colors)
  r.info chart
  r.info chart
* 8 colors (categories)
: ''8 colors''


* zoom to the map's bounds
* Zoom to the map's bounds
  g.region rast=chart
  g.region rast=chart


* display map
* Display map (command line version)
  d.mon x0
  d.mon x0
  d.rast chart
  d.rast chart


* query map values
* Query map values (command line version)
  d.what.rast
  d.what.rast
* black is category 1
: ''black is category 1''


* make a reclass map, with just the black lines
* Create a reclass map, with just the black lines
  r.reclass in=chart out=chart_black << EOF
  r.reclass in=chart out=chart_black << EOF
  1 = 1 black
  1 = 1 black
  EOF
  EOF


* thin the lines to be 1 pixel wide
=== Prepare raster for conversion ===
 
* Thin the lines to be 1 raster cell wide
  r.thin in=chart_black out=chart_black.thinned
  r.thin in=chart_black out=chart_black.thinned


* convert raster lines to vector lines
* Sometimes it helps to "grow" the contours before thinning, especially when the scan is not of high quality and contours have "breaks" in them. Note that you may have to repeatedly try different radius values to get the desired effect.
r.grow in=chart out=chart_grown radius=n_cells
 
=== Run the conversion ===
 
* Convert raster lines to vector lines
  r.to.vect -s in=chart_black.thinned out=chart_lines
  r.to.vect -s in=chart_black.thinned out=chart_lines


* remove any dangles smaller than 1km
== Clean vector map ==
 
* Remove any dangles smaller than 1km
  v.clean in=chart_lines out=chart_lines_cleaned tool=rmdangle thresh=1000
  v.clean in=chart_lines out=chart_lines_cleaned tool=rmdangle thresh=1000


* connect broken lines
* Remove known grid lines
v.mkgrid
v.buffer
v.overlay ain=scanned_lines bin=buffered_grid operator=not
 
* Clean by hand in with the digitizing tool
v.digit
:or the [http://qgis.org QGIS] GRASS vector editor
 
* Connect lines which were broken at dangles
  v.build.polylines -q in=chart_lines_cleaned out=chart_polyline
  v.build.polylines -q in=chart_lines_cleaned out=chart_polyline


* add category numbers to lines
== Remove short line segments ==
 
* Add category numbers to lines
  v.category in=chart_polyline out=chart_polyline_cat type=line
  v.category in=chart_polyline out=chart_polyline_cat type=line


* create a DB table to hold line length values
* Create a DB table to hold line length values
  v.db.addtable chart_polyline_cat columns="length_km DOUBLE PRECISION"
  v.db.addtable chart_polyline_cat columns="length_km DOUBLE PRECISION"


* upload line lengths to DB table
* Upload line lengths to DB table
  v.to.db chart_polyline_cat type=line option=length units=k column=length_km
  v.to.db chart_polyline_cat type=line option=length units=k column=length_km


* extract line features longer than 5km (cleans out the noise)
* Extract line features longer than 5km (cleans out the noise)
  v.extract in=chart_polyline_cat out=chart_lines_5km type=line where="length_km > 5"
  v.extract in=chart_polyline_cat out=chart_lines_5km type=line where="length_km > 5"


* display result over raster chart
== View ==
 
* Display result over raster chart (command line version)
  d.vect chart_lines_5km color=red width=2
  d.vect chart_lines_5km color=red width=2


* export as a shapefile
* Export as a shapefile
  v.out.ogr in=chart_lines_5km dsn=chart_lines_gt5km
  v.out.ogr in=chart_lines_5km dsn=chart_lines_gt5km


* view shape file in [http://qgis.org QuantumGIS]
* View shapefile in [http://qgis.org QuantumGIS]
  qgis chart_lines_gt5km/chart_lines_5km_crop.shp
  qgis chart_lines_gt5km/chart_lines_5km_crop.shp
== Convert to DEM ==
* See the [[Contour lines to DEM]] wiki page.
''Done!''
== Other ideas ==
* [http://autotrace.sourceforge.net/ Autotrace]
* [http://potrace.sourceforge.net/ Potrace] [http://wiki.inkscape.org/wiki/index.php/Potrace from within Inkscape]
* [http://delineate.sourceforge.net/download.html Delineate]
* Newer versions of [http://www.inkscape.org Inkscape] can be used to extract vector features from a PDF into a format that can be loaded into the GIS, such as DXF (pehaps with a SVG->DXF tool)
[[Category:Documentation]]
[[Category:FAQ]]
[[Category:Vector]]

Latest revision as of 00:35, 7 December 2011

Import

Import a scanned map image

Preprocessing

  • To save processing later you might want to mask out obvious text and other noise in a paint program first.
For example, load the image into the GIMP and cut away boxes of text, etc. If you are interested in a specific feature (such as solid black contour lines) you might try to isolate those by "Select -> By color" to pick out everything black, then "Select -> Invert" to pick everything that isn't black, and then "Edit -> Cut" to remove those parts of the image that we are not interested in. It helps if the original image starts with an indexed color palette. You also have the option of using GRASS's r.mapcalc module and other raster analysis modules to simplify the image after import. (see below)
The Magic Wand select tool may be of great help here as well.
If the orignal file was a GeoTIFF, the paint program will typically strip off any geocoding metadata upon re-save. You can read those off with gdalinfo and reapply with gdal_translate, or use the original image+gdal_translate to create a TFW world file which can be used on the new image. Another option is to dump the metadata to a file with the listgeo program and reapply to the new image with the geotifcp program. Both these come with the libgeotiff software distribution. If using these tools it is important not to alter the dimensions of the image. See the GeoTIFF FAQ for more information.

Import into GIS

  • Import image into GRASS (probably into a simple XY location)
r.in.gdal
  • Georectify map using GUI georectifier or i.points + i.rectify
  • Switch to target location
  • We now have a registered raster map containing a 300 dpi scan of our A0 sized paper map

Convert to vector map

Isolate contour lines

(see also pre-processing hints above)

  • Check how many categories (map colors)
r.info chart
8 colors
  • Zoom to the map's bounds
g.region rast=chart
  • Display map (command line version)
d.mon x0
d.rast chart
  • Query map values (command line version)
d.what.rast
black is category 1
  • Create a reclass map, with just the black lines
r.reclass in=chart out=chart_black << EOF
1 = 1 black
EOF

Prepare raster for conversion

  • Thin the lines to be 1 raster cell wide
r.thin in=chart_black out=chart_black.thinned
  • Sometimes it helps to "grow" the contours before thinning, especially when the scan is not of high quality and contours have "breaks" in them. Note that you may have to repeatedly try different radius values to get the desired effect.
r.grow in=chart out=chart_grown radius=n_cells

Run the conversion

  • Convert raster lines to vector lines
r.to.vect -s in=chart_black.thinned out=chart_lines

Clean vector map

  • Remove any dangles smaller than 1km
v.clean in=chart_lines out=chart_lines_cleaned tool=rmdangle thresh=1000
  • Remove known grid lines
v.mkgrid
v.buffer
v.overlay ain=scanned_lines bin=buffered_grid operator=not
  • Clean by hand in with the digitizing tool
v.digit
or the QGIS GRASS vector editor
  • Connect lines which were broken at dangles
v.build.polylines -q in=chart_lines_cleaned out=chart_polyline

Remove short line segments

  • Add category numbers to lines
v.category in=chart_polyline out=chart_polyline_cat type=line
  • Create a DB table to hold line length values
v.db.addtable chart_polyline_cat columns="length_km DOUBLE PRECISION"
  • Upload line lengths to DB table
v.to.db chart_polyline_cat type=line option=length units=k column=length_km
  • Extract line features longer than 5km (cleans out the noise)
v.extract in=chart_polyline_cat out=chart_lines_5km type=line where="length_km > 5"

View

  • Display result over raster chart (command line version)
d.vect chart_lines_5km color=red width=2
  • Export as a shapefile
v.out.ogr in=chart_lines_5km dsn=chart_lines_gt5km
qgis chart_lines_gt5km/chart_lines_5km_crop.shp


Convert to DEM


Done!

Other ideas