[ gpsdrive ] Nautical maps
Hamish
hamish_b at yahoo.com
Sat Mar 1 18:22:32 AKST 2008
Hamish wrote:
> > 1) get NOAA S-57 (EMC) data
> > http://nauticalcharts.noaa.gov/mcd/enc/download.htm
> > nice preview:
> > http://www.oceangrafix.com/o.g/search-nautical-charts.html
> > 2) install GDAL/OGR from www.gdal.org
> > 3) test for S-57 support with 'ogrinfo --formats | grep S57'
> > 4) Try to load it with a nice viewer like Quantum GIS
> > (www.qgis.org)
> > 5) Import S-57 data into GRASS GIS (grass.osgeo.org) with v.in.ogr
tartifola:
> got lost at this point. How can I import S-57 maps in GRASS? I need
> to create a new location, right? Where are the info needed to
> create it?
Yes, select "create new location from georeferenced file", using the
ENC *.000 file. It's just lat/lon WGS84, so you could create a new
location by EPSG code (4326) or by custom entry too. Another automatic
way (from within grass) is to use v.in.ogr's location= option.
Hamish:
> > 6) Set zoom, dispaly layers, colors, line widths, labels, etc. in
> > GRASS
> > 7) Export & register the GpsDrive tile with d.out.gpsdrive
> > 8) create GpsDrive waypoints at bouy lat/lons and verify that tile
> > lines up
> >
> > I am downloading a couple of NOAA ENCs now, I'll give it a try and
> > post the results.
I have had some good success today with this!
See instructions below, and script+screenshot at:
http://hamish.bowman.googlepages.com/gpsdrivefiles#tiles
Also on that page is new version of gdal_slice.sh script which now
works with degree and foot based input maps. (foot is untested)
I had mentioned earlier that newer BSB charts may be encrypted. The
ones you can download for free from NOAA are not, and they serve their
>1000 charts for free.
NOAA Electronic Nautical Chart Raster & Vectors to GpsDrive tiles
-----------------------------------------------------------------
[aka spend your money on nice food for the crew]
0) I found a quick & dirty way, a bit simpler than fighting with S-57.
For the US, you can download rasterized BSB charts from NOAA.
These include georeferencing information ("ground control points"),
but those GCPs need to be applied and the image warped to fit them.
For lat/lon maps this squashes them a bit, but they are still
readable. We can then chop the rectified GeoTIFF up into tiles for
GpsDrive with the gdal_slice.sh script.
Raster Navigational Charts ("RNCs", BSB format)
http://nauticalcharts.noaa.gov/mcd/Raster/download.htm
nice previews:
http://www.oceangrafix.com/o.g/search-nautical-charts.html
gdal_slice.sh:
http://hamish.bowman.googlepages.com/gpsdrivefiles#tiles
GDAL method: fast & simple but not as pretty
gdalwarp -t_srs "EPSG:4326" -order 2 -rn -co 'COMPRESS=DEFLATE' \
BSB_ROOT/12300/12300_1.KAP noaa_12300_2ndO.tif
It would be prettier to use cubic splice resampling (-rcs) than
nearest neighbor (-rn), but the image is a few color indexed
palette not a 24bit RGB so that doesn't work directly. If you
really want anti-aliased-like results you can use GIMP or some
NetPBM tool to convert it to RGB & resave but then I think you
have to reattach the GCPs using gdal_translate as GIMP etc don't
know about them.
Maybe a GDAL wiz knows a smarter way?
GRASS's i.rectify nearest neighbor mode is much much slower but
does a nicer job and uses much less RAM.
Maybe just oversample with gdalwarp's "-ts width height" function?
Get original size with "gdalinfo 12300_1.KAP | grep Size"
(I've just tried, this makes a nicer looking GeoTIFF but because
GpsDrive doesn't deal with anything but fixed aspect ratios
the resulting tiles would be scaled incorrectly :( )
# gdal_slice.sh calls "gdal_translate" in a loop to chop it up
# edit file names etc at the top of gdal_slice.sh, then
./gdal_slice.sh
One issue with gdal_slice is that GpsDrive (AFAIK) doesn't provide
a way to zoom-out, only zoom-in. So you have to use a more
regional
scaled map to get an overview of the area.
GRASS method: more control, less memory intensive
# make a XY GRASS location and a lat/lon WGS84 location
# (the EPSG code for LL/WGS84 is 4326)
# start GRASS in the simple XY location
r.in.gdal in=BSB_ROOT/12300/12300_1.KAP out=noaa_12300
g.region rast=noaa_12300.palette
d.mon x0; d.rast noaa_12300.palette
# need to rectify it.. gdalwarp?
i.target group=noaa_12300 location=ll_wgs84 mapset=ny_harbor
# if you like to check GCPs (including RMS error) run i.points
# but it's not necessary
#i.points group=noaa_12300
i.rectify group=noaa_12300 input=noaa_12300 ext=_2ndO order=2
# restart GRASS in lat/lon WGS84 location
g.rename noaa_12300.palette_2ndO,noaa_12300
g.region rast=noaa_12300
d.mon x0; d.rast noaa_12300
# check alignment by overlaying a grid
#d.grid 0:30 color=red
d.out.gpsdrive output=noaa_12300_full
1) S-57 vector data (hopefully one day rendered like OpenStreetMap)
get NOAA S-57 vector data (Electronic Navigation Chart "ENC")
http://nauticalcharts.noaa.gov/mcd/enc/download.htm
nice previews:
http://www.oceangrafix.com/o.g/search-nautical-charts.html
I picked charts #12326 and #12300, approaches to NY Harbor
The checkout page produced a file for download called
NOAA_ENCs440569.zip. Then:
unzip NOAA_ENCs440569.zip
2) install GDAL/OGR from www.gdal.org
OGR's S-57 page: http://www.gdal.org/ogr/drv_s57.html
3) test for S-57 support
ogrinfo --formats | grep S57
ogrinfo ENC_ROOT/US3NY01M/US3NY01M.000 # lists 53 internal layers
4) Try to load it with a nice viewer like Quantum GIS (www.qgis.org)
qgis
Layer -> Add a vector layer choose ENC_ROOT/US3NY01M/US3NY01.000
# which feature to display?
QGIS would load it, but I couldn't see how to do anything with it.
(??)
Perhaps OpenEV can display S-57 simply?
http://openev.sourceforge.net
; "symbology of the presentation library (IHO S52). Sylvain Duclos
; did extensive developmental work on an S57 display interpreter
; for OpenEV. It is in the OpenEV cvs under /contrib."
-- John Craddock on QGIS Mailing list Jan 2007
http://openev.sourceforge.net
(I'll try this soon)
S-57 Layer guide: http://www.s-57.com
5) Import S-57 data into GRASS GIS (grass.osgeo.org) with v.in.ogr
### in GRASS
Create new location from EPSG code 4326 (LL/WGS84)
[or chose "new location from data file", or create via manually
entry]
# change default database from DBF to SQLite as it is less lossy
db.connect driver=sqlite \
database='$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite.db'
# import data (ignore the many string warnings)
v.in.ogr dsn=ENC_ROOT/US3NY01M/US3NY01M.000 out=noaa_12300
# have a look
v.info noaa_12300
g.region vect=noaa_12300
d.mon x0; d.vect noaa_12300
# e.g. land Layer: LNDARE
ogrinfo -ro ENC_ROOT/US3NY01M/US3NY01M.000 | grep LNDARE
20: LNDARE
d.vect noaa_12300 layer=20 type=area disp=shape,attr attrcol=objnam
\
llayer=20 fcolor=255:200:80
# e.g. soundings Layer: SOUNDG (automated layer by name)
LAYER=SOUNDG
LAYER_ID=`ogrinfo -ro ENC_ROOT/US3NY01M/US3NY01M.000 | \
grep "$LAYER" | cut -f1 -d':'`
38: SOUNDG (Multi Point)
d.vect noaa_12300 layer=$LAYER_ID type=point icon=basic/diamond \
fcolor=yellow size=6
# e.g. buoys Layer: BOYSPP
ogrinfo -ro ENC_ROOT/US3NY01M/US3NY01M.000 | grep BOY
7: BOYLAT (Point)
8: BOYSAW (Point)
9: BOYSPP (Point)
d.vect noaa_12300 layer=7 type=point icon=basic/circle \
fcolor=orange size=8
d.vect noaa_12300 layer=8 type=point icon=basic/circle \
fcolor=magenta size=8
d.vect noaa_12300 layer=9 type=point icon=basic/circle \
fcolor=blue size=8
6) Set zoom, display layers, colors, line widths, labels, etc. in GRASS
(this will take some work)
# show everything
NUMLAYERS=`v.db.connect -g noaa_12326 | wc -l`
for layer in `seq 1 $NUMLAYERS` ; do
echo "layer=$layer"
d.vect noaa_12326 layer=$layer \
color=$((layer*4)):$((layer*4)):$((layer*4)) \
fcolor=$((layer*4)):$((layer*4)):$((layer*4))
done
# Color and symbology standards:
http://www.iho.shom.fr/ECDIS/s52intro.htm
http://www.iho.shom.fr/publicat/free/files/PresLib_3.3_Addendum_2007.pdf
e.g. fill color for land is 255:200:80
d.vect noaa_12326 attrcol=objnam llayer=24 disp=attr \
layer=24 fcolor=255:200:80
7) Export & register the GpsDrive tile with d.out.gpsdrive
(see the d.out.gpsdrive help page for doing a large image in a loop)
8) create GpsDrive waypoints (way_*.txt) at buoy lat/lons + grid
overlay
to verify that raster tiles line up with buoy locations.
ogrinfo -ro ENC_ROOT/US3NY01M/US3NY01M.000 | grep BOY
7: BOYLAT (Point)
8: BOYSAW (Point)
9: BOYSPP (Point)
v.extract in=noaa_12300 out=noaa_12300_BOYLAT type=point layer=7
v.extract in=noaa_12300 out=noaa_12300_BOYSAW type=point layer=8
v.extract in=noaa_12300 out=noaa_12300_BOYSPP type=point layer=9
d.vect noaa_12300_BOYLAT layer=-1
# write out waypoint files
# v.out.ascii.db is from GRASS's wiki-addons page
for BOY in BOYLAT BOYSAW BOYSPP ; do
v.out.ascii.db in=noaa_12300_$BOY column=OBJNAM | \
awk -F'|' '{print $4 "\t" $3 "\t" $2 "\tSpeedtrap"}' | \
tr ' ' '_' > way_${BOY}.txt
done
cat way_BOY* > ~/.gpsdrive/way_BOY.txt
For the 12326 map (printed 1:80,000) the S-57 buoy waypoints I
measured were around 20-125m away from the site on the raster
tile. Some of this can be explained by poor workmanship on behalf
of the NOAA employee setting up the ground control points in the
BSB map (Zooming in on them in GRASS's i.points show them off by
a few pixels here and there). If you overlay the S-57 buoys over
the raster image in GRASS they mostly line up very well. Also to
consider is the different age of the vector vs raster maps? ie
sometimes buoys are shifted.
fair winds and happy hacking,
Hamish
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
More information about the GPSdrive
mailing list