Shp2osm:shp转换为osm格式文件

参考文档主要是Shp2osm:https://wiki.openstreetmap.org/wiki/Shp2osm
最主要部分是:
在这里插入图片描述

FOR /R .\ %G IN (*_out.shp) DO shp2osm.pl "%~dpnG" > "%~dpnG.osm"

但是想要执行这个命令没想象中的那么简单,比较麻烦,需要经过好多步骤!!而且网上也没有这个Shp2osm转换教程,我这算是首篇教程了吧!!下面来听我慢慢讲解吧。
1、shp2osm.pl这个是.pl文件,perl语言文件的源程序的扩展名,所以首先要安装perl,我用的是Win7系统!
安装Perl教程很多,可以百度搜索。https://jingyan.baidu.com/article/4b52d702e3b86afc5c774ba4.html
2、然后用cmd命令行cd到shp所在文件夹路径,执行FOR /R .\ %G IN (*_out.shp) DO shp2osm.pl "%~dpnG" > "%~dpnG.osm"命令,还需要shp2osm.pl文件!
在这里插入图片描述
shp2osm.pl:

# Copyright (c) 2006 Gabriel Ebner <ge@gabrielebner.at>
# updated in 2008 by Tobias Wendorff <tobias.wendorff@uni-dortmund.de>
# HTML-Entities based on ideas of Hermann Schwärzler
# Gauß-Krüger implementation based on gauss.pl by Andreas Achtzehn
# version 1.3 (17. September 2008)

use Geo::ShapeFile;
use HTML::Entities qw(encode_entities_numeric);
use Math::Trig;

if(@ARGV == 0) {
   print "usage:\n";
   print "with transformation from GK to WGS84: 'shp2osm.pl shapefile GK'\n";
   print "without transformation: 'shp2osm.pl shapefile'";
   exit;
}

print <<'END';
<?xml version='1.0'?>
<osm version='0.5' generator='shp2osm.pl'>
END

#BEGIN { our %default_tags = ( natural => 'water', source => 'SWDB' ); }
BEGIN { our %default_tags = (  ); }

my $file = @ARGV[0];
$file =~ s/\.shp$//;
my $shpf = Geo::ShapeFile->new($file);
proc_shpf($shpf);

{
     BEGIN { our $i = -1; }

     sub tags_out {
         my ($tags) = @_;
         my %tags = $tags ? %$tags : ();
         #$tags{'created_by'} ||= 'shp2osm.pl';
         delete $tags{'_deleted'} unless $tags{'_deleted'};
         while ( my ( $k, $v ) = each %tags ) {
             my $key = encode_entities_numeric($k);
             my $val = encode_entities_numeric($v);
             print '    <tag k="'. $key .'" v="'. $val ."\"/>\n" if $val;
         }
     }

     sub node_out {
         my ( $lon, $lat, $tags ) = @_;
         my $id = $i--;
         if(@ARGV[1] eq 'GK') {
             my ($wgs84lon, $wgs84lat) = gk2geo($lon, $lat);
             print "  <node id='$id' visible='true' lat='$wgs84lat' lon='$wgs84lon' />\n";
         } else {
            print "  <node id='$id' visible='true' lat='$lat' lon='$lon' />\n";         
         }
         $id;
     }

     sub seg_out {
         my $id = $i+1;
         $id;
     }

     sub way_out {
         my ( $segs, $tags ) = @_;
         my $id = $i--;
         print "  <way id='$id' visible='true'>\n";
         print "    <nd ref='$_' />\n" for @$segs;
         tags_out $tags;
         print "  </way>\n";
         $id;
     }
}


print <<'END';
</osm>
END

sub polyline_out {
    my ( $pts, $tags, $connect_last_seg ) = @_;

    my ( $first_node, $last_node, @segs );
    for my $pt (@$pts) {
        my $node = node_out @$pt;
        push @segs, seg_out $last_node, $node;
        $last_node = $node;
        $first_node ||= $last_node;
    }
    push @segs, seg_out $last_node, $first_node
      if $first_node && $connect_last_seg;
    way_out \@segs, $tags;
}

sub proc_obj {
    my ( $shp, $dbf, $type ) = @_;
    my $tags = { %default_tags, %$dbf };
    my $is_polygon = $type % 10 == 5;
    for ( 1 .. $shp->num_parts ) {
        polyline_out [ map( [ $_->X(), $_->Y() ], $shp->get_part($_) ) ], $tags,
          $is_polygon;
    }
 }

sub proc_shpf {
    my ($shpf) = @_;
    my $type = $shpf->shape_type;
    for ( 1 .. $shpf->shapes() ) {
        my $shp = $shpf->get_shp_record($_);
        my %dbf = $shpf->get_dbf_record($_);
        proc_obj $shp, \%dbf, $type;
    }
}

sub gk2geo {
  my $sr  = $_[0];
  my $sx  = $_[1];

  my $bm  = int($sr/1000000);
  my $y   = $sr-($bm*1000000+500000);
  my $si  = $sx/111120.6196;
  my $px  = $si+0.143885358*sin(2*$si*0.017453292)+0.00021079*sin(4*$si*0.017453292)+0.000000423*sin(6*$si*0.017453292);
  my $t   = (sin($px*0.017453292))/(cos($px*0.017453292));
  my $v   = sqrt(1+0.006719219*cos($px*0.017453292)*cos($px*0.017453292));
  my $ys  = ($y*$v)/6398786.85;
  my $lat = $px-$ys*$ys*57.29577*$t*$v*$v*(0.5-$ys*$ys*(4.97-3*$t*$t)/24);
  my $dl  = $ys*57.29577/cos($px*0.017453292) * (1-$ys*$ys/6*($v*$v+2*$t*$t-$ys*$ys*(0.6+1.1*$t*$t)*(0.6+1.1*$t*$t)));
  my $lon = $bm*3+$dl;

  my $potsd_a  = 6377397.155;
  my $wgs84_a  = 6378137.0;
  my $potsd_f  = 1/299.152812838;
  my $wgs84_f  = 1/298.257223563;

  my $potsd_es = 2*$potsd_f - $potsd_f*$potsd_f;

  my $potsd_dx = 606.0;
  my $potsd_dy = 23.0;
  my $potsd_dz = 413.0;
  my $pi = 3.141592654;
  my $latr = $lat/180*$pi;
  my $lonr = $lon/180*$pi;

  my $sa = sin($latr);
  my $ca = cos($latr);
  my $so = sin($lonr);
  my $co = cos($lonr);

  my $bda  = 1-$potsd_f;

  my $delta_a = $wgs84_a - $potsd_a;
  my $delta_f = $wgs84_f - $potsd_f;

  my $rn = $potsd_a / sqrt(1-$potsd_es*sin($latr)*sin($latr));
  my $rm = $potsd_a * ((1-$potsd_es)/sqrt(1-$potsd_es*sin($latr)*sin($latr)*1-$potsd_es*sin($latr)*sin($latr)*1-$potsd_es*sin($latr)*sin($latr)));

  my $ta = (-$potsd_dx*$sa*$co - $potsd_dy*$sa*$so)+$potsd_dz*$ca;
  my $tb = $delta_a*(($rn*$potsd_es*$sa*$ca)/$potsd_a);
  my $tc = $delta_f*($rm/$bda+$rn*$bda)*$sa*$ca;
  my $dlat = ($ta+$tb+$tc)/$rm;

  my $dlon = (-$potsd_dx*$so + $potsd_dy*$co)/($rn*$ca);

  my $wgs84lat = ($latr + $dlat)*180/$pi;
  my $wgs84lon = ($lonr + $dlon)*180/$pi;

  return( $wgs84lon, $wgs84lat);
}

这个文件在https://svn.openstreetmap.org/applications/utils/import/shp2osm/有。
3、运行报错
perl缺失模块
需要perl安装模块,在网上搜索资料。
安装模块方法参考:https://blog.csdn.net/czz1141979570/article/details/78697219
第一种方法是从CPAN上下载您需要的模块,手工编译、安装。
第二种方法是联上internet,使用一个叫做CPAN的模块自动完成下载、编译、安装的全过程。
可是安装了两三个模块之后再安装autovivification模块就报错了,c不是内部或外部命令还有link不是内部或外部命令,用这两种方法安装都安装不了!结果又找资料发现了一个神器!perl package manager,在这个软件可以直接安装模块!早知道就不用那么费劲用命令行安装了。
package manager
操作步骤:
1、鼠标右键点击选择安装或者卸载;
在这里插入图片描述
2、File→Run Marked Actions Ctrl+Enter,然后就执行安装,安装成功就行了!
在这里插入图片描述
写到最后:最后执行命令不报错了,需要的模块也安装好了,OSM格式文件便转换成功了。
在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值