User:Ewmjc/PGS 2 OSM Conversion Script
Jump to navigation
Jump to search
#!/usr/bin/perl use strict; use Geo::ShapeFile; =pod =head1 NAME Prototype Global Shoreline Data (PGS) Shapefile to OSM XML conversion script. =head1 DESCRIPTION Converts specified lat/lon windows of National Geospatial-Intelligence Agency (US) Prototype Global Shoreline Data (Satellite Derived High Water Line Data) file to OpenStreetMap (OSM) Nodes and Segments file suitable for editing in JOSM. Author: Based on "Shapefile upload script" by OJW http://wiki.openstreetmap.org/index.php/Shapefile_upload_script and adapted by Mike Collinson, Aug 2006 =head1 TO RUN 1) Download and install Geo::ShapeFile package from CPAN or ppm. 1) Download appropriate PGS file from http://www.nga.mil/portal/site/nga01/index.jsp?epi-content=GENERIC&itemID=9328fbd8dcc4a010VgnVCMServer3c02010aRCRD&beanID=1629630080&viewID=Article 2) Unzip the file 3) Enter your local configuration parameters below 4) perl coastline.pl =cut ## YOUR CONFIGURATION # Where you want your output file to be written open (OSMFILE,'>c:/temp/coastline.osm'); # Change the following for the location you want to process # Name and relative location of your downloaded, uzipped PGS file (don't # specify any root file type # Min Lon (decimal) # Min Lat (decimal) # Max Lon (decimal) # Max Lat (decimal) &createCoasts("coastline/NGA_GlobalShoreline_cd5", 150.40, -34.20, 151.35, -33.75); ## -- END OF YOUR CONFIGURATION print "Done\n"; sub createCoasts(){ my ($Filename, $X1, $Y1, $X2, $Y2) = @_; open(LOG, ">coastline_log.txt"); print LOG "Area $X1 to $X2, $Y1 to $Y2\n"; my $shapefile = new Geo::ShapeFile($Filename); printf "%d shapes in input file\n", $shapefile->shapes(); print OSMFILE "<?xml version=\"1.0\"?>\n<osm version=\"0.3\">"; my $CountA = my $CountB = my $Node = my $SegmentID = 0; for(1 .. $shapefile->shapes()) { my $shape = $shapefile->get_shp_record($_); my $LastValid = 0; #debug print LOG "Shape\n"; my $firstshape = 1; my $LastNode = ''; foreach my $Point($shape->points()){ my $Long = $Point->X(); my $Lat = $Point->Y(); my $InArea = ($Lat > $Y1 && $Lat < $Y2 && $Long > $X1 && $Long < $X2); if($InArea){ $Node--; writeNode($Lat, $Long, $Node); if ($firstshape) { print LOG "Shape\n"; $firstshape = 0; } printf LOG "Node #%d: %f, %f\n", $Node, $Lat, $Long; if($LastValid){ $SegmentID--; my $Segment = writeSegment($LastNode, $Node, $SegmentID); printf LOG "Segment #%d: %d, %d\n", $Segment, $LastNode, $Node; } $LastNode = $Node; $CountB++; $LastValid = 1; } else { $LastValid = 0; } $CountA++; } } print OSMFILE "</osm>"; print "Writing $CountB points out of $CountA in input file\n"; print LOG "Complete\n"; close LOG; print "Complete\n"; } sub writeSegment(){ my ($NodeID_1,$NodeID_2, $SegmentID) = @_; my $Tags = "<tag k=\"created_by\" v=\"almien_coastlines\"/>"; $Tags .= "<tag k=\"natural\" v=\"coastline\"/>"; $Tags .= "<tag k=\"source\" v=\"PGS\"/>"; my $Segment = sprintf("<segment id=\"%d\" from=\"%d\" to=\"%d\">$Tags</segment>\n", $SegmentID, $NodeID_1,$NodeID_2); print OSMFILE $Segment; return; } sub writeNode(){ my ($Lat, $Long, $Node) = @_; my $Tags = "<tag k=\"created_by\" v=\"almien_coastlines\"/>"; $Tags .= "<tag k=\"source\" v=\"PGS\"/>"; my $NodeTag = sprintf("<node id=\"%d\" lon=\"%f\" lat=\"%f\">$Tags</node>", $Node, $Long, $Lat); print OSMFILE $NodeTag; return; }