好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C# 中SharpMap的简单使用实例详解

本文是利用shapmap实现gis的简单应用的小例子,以供学习分享使用。关于sharpmap的说明,网上大多是以shapefile为例进行简单的说明,就连官网上的例子也不多。本文是自己参考了源代码进行整理的,主要是winform的例子。原理方面本文也不过多论述,主要是实例演示,需要的朋友还是以sharpmap源码进行深入研究。

什么是sharpmap ?

sharpmap是一个基于.net 2.0使用c#开发的map渲染类库,可以渲染各类gis数据(目前支持esri shape和postgis格式),可应用于桌面和web程序。代码行数近10000行,可以算是一个实现了最基本功能的gis系统,有利于研究学习使用。

涉及知识点:

sharpmap的基本概念:layer(图层,常用图层:vectorlayer,labellayer) , iprovider(数据提供者,常用数据源:ogr(对应mapinfo),shapfile,datatablepoint(对应dataset)) 坐标转换:主要用于经纬度和地图坐标的转换。

sharpmap知识结构图:

效果图如下:

(一)车辆轨迹图:数据源:excel数据

(二)定点数据(数据源:excel)将河南省十七个城市,全部插上小红旗

(三)使用mapinfo做背景文件(此处通过程序调整了比例尺)

(四)使用shapfile做背景图

核心代码

?

using brutile.predefined;

using geoapi.coordinatesystems.transformations;

using projnet.coordinatesystems;

using projnet.coordinatesystems.transformations;

using sharpmap;

using sharpmap.data.providers;

using sharpmap.layers;

using sharpmap.rendering;

using sharpmap.rendering.thematics;

using sharpmap.styles;

using system;

using system.collections.generic;

using system.data;

using system.data.oledb;

using system.drawing;

using system.drawing.drawing2d;

using system.drawing.text;

using system.linq;

using system.text;

using point = geoapi.geometries.coordinate;

namespace demosharpmap

{

  public class sharpmaphelper

  {

  private const string xlsconnectionstring = "provider={2};data source={0}\\{1};extended properties=\"excel 8.0;hdr=yes;imex=1\"" ;

  public static map initializemap(maptype tt,float angle)

  {

   map map = null;

   switch (tt)

   {

   case maptype.runline:

    map = initializemaposmwithxls(angle);

    break ;

   case maptype.mapinfo:

    map = initializemapinfo(angle);

    break ;

   case maptype.shapefile:

    map = initializemaporig(angle);

    break ;

   case maptype.static:

    map = initializemaposmwithxls2(angle);

    break ;

   default:

    map = initializemaposmwithxls(angle);

    break ;

   }

   return map;

  }

  /// <summary>

  /// mapinfo格式的地图文件

  /// < /summary >

  /// <param name= "angle" >< /param >

  /// <returns>< /returns >

  private static map initializemapinfo(float angle)

  {

   //initialize a new map of size 'imagesize'

   map map = new map();

   //set up the countries layer

   vectorlayer laycountries = new vectorlayer( "countries" );

   //set the datasource to a shapefile in the app_data folder

   try

   {

   laycountries.datasource = new ogr( "geodata/mapinfo/countriesmapinfo.tab" );

   }

   catch (typeinitializationexception ex)

   {

   if (ex.message == "the type initializer for 'osgeo.ogr.ogr' threw an exception." )

   {

    throw new exception(

    string. format (

     "the application threw a pinvoke exception. you probably need to copy the unmanaged dll's to your bin directory. they are a part of fwtools {0}. you can download it from: http://home.gdal.org/fwtools/" ,

     gdalrasterlayer.fwtoolsversion));

   }

   throw;

   }

   //set fill-style to green

   laycountries.style.fill = new solidbrush(color.green);

   //set the polygons to have a black outline

   laycountries.style.outline = pens.black;

   laycountries.style.enableoutline = true ;

   laycountries.srid = 4326;

   //set up a river layer

   vectorlayer layrivers = new vectorlayer( "rivers" );

   //set the datasource to a shapefile in the app_data folder

   layrivers.datasource = new ogr( "geodata/mapinfo/riversmapinfo.tab" );

   //define a blue 1px wide pen

   layrivers.style.line = new pen(color.blue, 1);

   layrivers.srid = 4326;

   //set up a river layer

   vectorlayer laycities = new vectorlayer( "cities" );

   //set the datasource to a shapefile in the app_data folder

   laycities.datasource = new ogr( "geodata/mapinfo/citiesmapinfo.tab" );

   laycities.style.symbolscale = 0.8f;

   laycities.maxvisible = 40;

   laycities.srid = 4326;

   //set up a country label layer

   labellayer laylabel = new labellayer( "country labels" );

   laylabel.datasource = laycountries.datasource;

   laylabel.enabled = true ;

   laylabel.labelcolumn = "name" ;

   laylabel.style = new labelstyle();

   laylabel.style.forecolor = color.white;

   laylabel.style.font = new font(fontfamily.genericserif, 12);

   laylabel.style.backcolor = new solidbrush(color.fromargb(128, 255, 0, 0));

   laylabel.maxvisible = 90;

   laylabel.minvisible = 30;

   laylabel.style.horizontalalignment = labelstyle.horizontalalignmentenum.center;

   laylabel.srid = 4326;

   laylabel.multipartgeometrybehaviour = labellayer.multipartgeometrybehaviourenum.largest;

   //set up a city label layer

   labellayer laycitylabel = new labellayer( "city labels" );

   laycitylabel.datasource = laycities.datasource;

   laycitylabel.enabled = true ;

   laycitylabel.labelcolumn = "name" ;

   laycitylabel.style = new labelstyle();

   laycitylabel.style.forecolor = color.black;

   laycitylabel.style.font = new font(fontfamily.genericserif, 11);

   laycitylabel.maxvisible = laylabel.minvisible;

   laycitylabel.style.horizontalalignment = labelstyle.horizontalalignmentenum.left;

   laycitylabel.style.verticalalignment = labelstyle.verticalalignmentenum.bottom;

   laycitylabel.style.offset = new pointf(3, 3);

   laycitylabel.style.halo = new pen(color.yellow, 2);

   laycitylabel.textrenderinghint = textrenderinghint.antialias;

   laycitylabel.smoothingmode = smoothingmode.antialias;

   laycitylabel.srid = 4326;

   laycitylabel.labelfilter = labelcollisiondetection.thoroughcollisiondetection;

   laycitylabel.style.collisiondetection = true ;

   //add the layers to the map object.

   //the order we add them in are the order they are drawn, so we add the rivers last to put them on top

   map.layers.add(laycountries);

   map.layers.add(layrivers);

   map.layers.add(laycities);

   map.layers.add(laylabel);

   map.layers.add(laycitylabel);

   // 增加layers

   var xlspath = string. format (xlsconnectionstring, system.io.directory.getcurrentdirectory(), "geodata\\henan.xls" , properties.settings.default.oledbprovider);

   var ds = getdatafromexcel(xlspath, "cities" );

   //var ct = getcoordinatetransformation();

   //transcoordinate (ds, ct);

   string columename = "rotation" ;

   //add rotation column

   addcolumetodataset(ds, columename, -angle);

   var xlslayer = getlayerfromdataset2(ds, color.greenyellow); //set up provider

   map.layers.add(xlslayer); //add layer to map

   map.center = xlslayer.envelope.centre; // new point(0, 0);

   map.mapscale = 350;

   //map .center = new point(0, 0);

   //_ogrsampledataset = "mapinfo" ;

   //matrix mat = new matrix();

   //mat .rotateat(angle, map.worldtoimage(map.center));

   //map .maptransform = mat;

   //map .zoomtobox(xlslayer.envelope);

   return map;

  }

  /// <summary>

  /// shapefile

  /// < /summary >

  /// <param name= "angle" >< /param >

  /// <returns>< /returns >

  private static map initializemaporig(float angle)

  {

   //initialize a new map of size 'imagesize'

   map map = new map();

   //set up the countries layer

   vectorlayer laycountries = new vectorlayer( "countries" );

   //set the datasource to a shapefile in the app_data folder

   laycountries.datasource = new shapefile( "geodata/world/countries.shp" , true );

   //set fill-style to green

   laycountries.style.fill = new solidbrush(color.fromargb(64, color.green));

   //set the polygons to have a black outline

   laycountries.style.outline = pens.black;

   laycountries.style.enableoutline = true ;

   laycountries.srid = 4326;

   //set up a river layer

   vectorlayer layrivers = new vectorlayer( "rivers" );

   //set the datasource to a shapefile in the app_data folder

   layrivers.datasource = new shapefile( "geodata/world/rivers.shp" , true );

   //define a blue 1px wide pen

   layrivers.style.line = new pen(color.blue, 1);

   layrivers.srid = 4326;

   //set up a cities layer

   vectorlayer laycities = new vectorlayer( "cities" );

   //set the datasource to a shapefile in the app_data folder

   laycities.datasource = new shapefile( "geodata/world/cities.shp" , true );

   laycities.style.symbolscale = 0.8f;

   laycities.maxvisible = 40;

   laycities.srid = 4326;

   //set up a country label layer

   labellayer laylabel = new labellayer( "country labels" );

   laylabel.datasource = laycountries.datasource;

   laylabel.enabled = true ;

   laylabel.labelcolumn = "name" ;

   laylabel.style = new labelstyle();

   laylabel.style.forecolor = color.white;

   laylabel.style.font = new font(fontfamily.genericserif, 12);

   laylabel.style.backcolor = new solidbrush(color.fromargb(128, 255, 0, 0));

   laylabel.maxvisible = 90;

   laylabel.minvisible = 30;

   laylabel.style.horizontalalignment = labelstyle.horizontalalignmentenum.center;

   laylabel.srid = 4326;

   laylabel.multipartgeometrybehaviour = labellayer.multipartgeometrybehaviourenum.largest;

   laylabel.labelfilter = labelcollisiondetection.thoroughcollisiondetection;

   laylabel.style.collisiondetection = true ;

   laylabel.labelpositiondelegate = fdr => fdr.geometry.interiorpoint.coordinate;

   laylabel.prioritycolumn = "popdens" ;

   //set up a city label layer

   labellayer laycitylabel = new labellayer( "city labels" );

   laycitylabel.datasource = laycities.datasource;

   laycitylabel.enabled = true ;

   laycitylabel.labelcolumn = "name" ;

   laycitylabel.style = new labelstyle();

   laycitylabel.style.forecolor = color.black;

   laycitylabel.style.font = new font(fontfamily.genericserif, 11);

   laycitylabel.maxvisible = laylabel.minvisible;

   laycitylabel.style.horizontalalignment = labelstyle.horizontalalignmentenum.left;

   laycitylabel.style.verticalalignment = labelstyle.verticalalignmentenum.bottom;

   laycitylabel.style.offset = new pointf(3, 3);

   laycitylabel.style.halo = new pen(color.yellow, 2);

   laycitylabel.textrenderinghint = textrenderinghint.antialias;

   laycitylabel.smoothingmode = smoothingmode.antialias;

   laycitylabel.srid = 4326;

   laycitylabel.labelfilter = labelcollisiondetection.thoroughcollisiondetection;

   laycitylabel.style.collisiondetection = true ;

   laycitylabel.prioritycolumn = "population" ;

   laycitylabel.theme = new gradienttheme(laycitylabel.prioritycolumn, 250000, 5000000,

   new labelstyle

   {

    maxvisible = 10,

    collisionbuffer = new size(0, 0),

    collisiondetection = true ,

    enabled = true ,

    forecolor = color.lightslategray,

    halo = new pen(color.silver, 1),

    horizontalalignment = labelstyle.horizontalalignmentenum.center,

    verticalalignment = labelstyle.verticalalignmentenum.middle,

    font = new font(genericfontfamilies.sansserif.tostring(), 8f, fontstyle.regular)

   },

   new labelstyle

   {

    maxvisible = laylabel.minvisible,

    collisionbuffer = new size(3, 3),

    collisiondetection = true ,

    enabled = true ,

    forecolor = color.lightslategray,

    halo = new pen(color.silver, 5),

    horizontalalignment = labelstyle.horizontalalignmentenum.center,

    verticalalignment = labelstyle.verticalalignmentenum.middle,

    font = new font(genericfontfamilies.sansserif.tostring(), 16f, fontstyle.bold)

   });

   bool ignorelength = false ;

   var layriverlabel = new labellayer( "river labels" )

   {

   datasource = layrivers.datasource,

   enabled = true ,

   labelcolumn = "name" ,

   textrenderinghint = textrenderinghint.antialias,

   smoothingmode = smoothingmode.antialias,

   srid = 4326,

   labelfilter = labelcollisiondetection.thoroughcollisiondetection,

   multipartgeometrybehaviour = labellayer.multipartgeometrybehaviourenum测试数据moncenter,

   style =

       new labelstyle

       {

       forecolor = color.darkblue,

       font = new font(fontfamily.genericsansserif, 11),

       horizontalalignment = labelstyle.horizontalalignmentenum.center,

       verticalalignment = labelstyle.verticalalignmentenum.middle,

       //collisiondetection = true ,

       halo = new pen(color.azure, 2),

       ignorelength = ignorelength,

       offset = new pointf(0, -10)

       },

   };

   //add the layers to the map object.

   //the order we add them in are the order they are drawn, so we add the rivers last to put them on top

   //map .backgroundlayer.add(asynclayerproxylayer.create(laycountries));

   map.layers.add(laycountries);

   map.layers.add(layrivers);

   map.layers.add(laycities);

   map.layers.add(laylabel);

   map.layers.add(laycitylabel);

   map.layers.add(layriverlabel);

   // 增加layers

   var xlspath = string. format (xlsconnectionstring, system.io.directory.getcurrentdirectory(), "geodata\\henan.xls" , properties.settings.default.oledbprovider);

   var ds = getdatafromexcel(xlspath, "cities" );

   //var ct = getcoordinatetransformation();

   //transcoordinate (ds, ct);

   string columename = "rotation" ;

   //add rotation column

   addcolumetodataset(ds, columename, -angle);

   var xlslayer = getlayerfromdataset2(ds, color.greenyellow); //set up provider

   map.layers.add(xlslayer); //add layer to map

      //limit the zoom to 360 degrees width

      //map .maximumzoom = 360;

      //map .backcolor = color.lightblue;

   //map .zoom = 360;

   map.center = xlslayer.envelope.centre; // new point(0, 0);

   map.mapscale = 350;

   //matrix mat = new matrix();

   //mat .rotateat(angle, map.worldtoimage(map.center));

   //map .maptransform = mat;

   //map .zoomtobox(xlslayer.envelope);

   return map;

  }

  /// <summary>

  /// 在线显示,圆点显示轨迹

  /// < /summary >

  /// <param name= "angle" >< /param >

  /// <returns>< /returns >

  private static map initializemaposmwithxls(float angle)

  {

   var map = new map();

   var tilelayer = new tileasynclayer(

   knowntilesources.create(knowntilesource.openstreetmap), "tilelayer - osm with xls" );

   tilelayer.srid = 4326;

   map.backgroundlayer.add(tilelayer);

   //get data from excel

   var xlspath = string. format (xlsconnectionstring, system.io.directory.getcurrentdirectory(), "geodata\\cities.xls" , properties.settings.default.oledbprovider);

   var ds = getdatafromexcel(xlspath, "cities" );

   var ds1 = getdatafromexcel(xlspath, "cities2" );

   var ct = getcoordinatetransformation();

   transcoordinate(ds, ct);

   transcoordinate(ds1, ct);

   string columename = "rotation" ;

   //add rotation column

   addcolumetodataset(ds, columename, -angle);

   addcolumetodataset(ds1, columename, -angle);

   var xlslayer = getlayerfromdataset(ds, color.greenyellow); //set up provider

   map.layers.add(xlslayer); //add layer to map

   var xlslayer1 = getlayerfromdataset(ds1, color.red);

   map.layers.add(xlslayer1);

   var xlslabellayer = getlabellayerbyvectorlayer(xlslayer, "xlslabel" );

   xlslabellayer.theme = new sharpmap.rendering.thematics.fontsizetheme(xlslabellayer, map) { fontsizescale = 1000f };

   map.layers.add(xlslabellayer);

   map.zoomtobox(xlslayer.envelope.expandedby(xlslayer1.envelope));

   return map;

  }

  /// <summary>

  /// 在线显示,图标显示轨迹

  /// < /summary >

  /// <param name= "angle" >< /param >

  /// <returns>< /returns >

  private static map initializemaposmwithxls2(float angle)

  {

   var map = new map();

   var tilelayer = new tileasynclayer(

   knowntilesources.create(knowntilesource.openstreetmap), "tilelayer - osm with xls" );

   tilelayer.srid = 4326;

   map.backgroundlayer.add(tilelayer);

   //get data from excel

   var xlspath = string. format (xlsconnectionstring, system.io.directory.getcurrentdirectory(), "geodata\\henan.xls" , properties.settings.default.oledbprovider);

   var ds = getdatafromexcel(xlspath, "cities" );

   var ct = getcoordinatetransformation();

   transcoordinate(ds, ct);

   string columename = "rotation" ;

   //add rotation column

   addcolumetodataset(ds, columename, -angle);

   var xlslayer = getlayerfromdataset2(ds, color.greenyellow); //set up provider

   map.layers.add(xlslayer); //add layer to map

   var xlslabellayer = getlabellayerbyvectorlayer(xlslayer, "xlslabel" );

   xlslabellayer.theme = new fontsizetheme(xlslabellayer, map) { fontsizescale = 1000f };

   map.layers.add(xlslabellayer);

   map.zoomtobox(xlslayer.envelope);

   return map;

  }

  /// <summary>

  /// 从excel中读取数据

  /// < /summary >

  private static dataset getdatafromexcel(string xlspath, string sheetname)

  {

   dataset ds = new dataset( "xls" );

   string sql = string. format ( "select * from [{0}$];" , sheetname);

   using (var cn = new oledbconnection(xlspath))

   {

   cn. open ();

   using (var da = new oledbdataadapter(new oledbcommand(sql, cn)))

   {

    da.fill(ds);

   }

   }

   return ds;

  }

  /// <summary>

  /// 获取坐标转换对象

  /// < /summary >

  /// <returns>< /returns >

  private static icoordinatetransformation getcoordinatetransformation()

  {

   //the srs for this datasource is epsg:4326, therefore we need to transfrom it to osm projection

   var ctf = new coordinatetransformationfactory();

   var cf = new coordinatesystemfactory();

   var epsg4326 = cf.createfromwkt( "geogcs[\"wgs 84\",datum[\"wgs_1984\",spheroid[\"wgs 84\",6378137,298.257223563,authority[\"epsg\",\"7030\"]],authority[\"epsg\",\"6326\"]],primem[\"greenwich\",0,authority[\"epsg\",\"8901\"]],unit[\"degree\",0.01745329251994328,authority[\"epsg\",\"9122\"]],authority[\"epsg\",\"4326\"]]" );

   var epsg3857 = cf.createfromwkt( "projcs[\"popular visualisation crs / mercator\", geogcs[\"popular visualisation crs\", datum[\"popular visualisation datum\", spheroid[\"popular visualisation sphere\", 6378137, 0, authority[\"epsg\",\"7059\"]], towgs84[0, 0, 0, 0, 0, 0, 0], authority[\"epsg\",\"6055\"]],primem[\"greenwich\", 0, authority[\"epsg\", \"8901\"]], unit[\"degree\", 0.0174532925199433, authority[\"epsg\", \"9102\"]], axis[\"e\", east], axis[\"n\", north], authority[\"epsg\",\"4055\"]], projection[\"mercator\"], parameter[\"false_easting\", 0], parameter[\"false_northing\", 0], parameter[\"central_meridian\", 0], parameter[\"latitude_of_origin\", 0], unit[\"metre\", 1, authority[\"epsg\", \"9001\"]], axis[\"east\", east], axis[\"north\", north], authority[\"epsg\",\"3857\"]]" );

   var ct = ctf.createfromcoordinatesystems(epsg4326, epsg3857);

   return ct;

  }

  /// <summary>

  /// 转换地球经纬度到坐标

  /// < /summary >

  /// <param name= "ds" >< /param >

  /// <param name= "ct" >< /param >

  private static void transcoordinate(dataset ds, icoordinatetransformation ct)

  {

   foreach (system.data.datarow row in ds.tables[0].rows)

   {

   if (row[ "x" ] == dbnull.value || row[ "y" ] == dbnull.value) continue ;

   var coords = new[] { convert.todouble(row[ "x" ]), convert.todouble(row[ "y" ]) };

   coords = ct.mathtransform.transform(coords);

   row[ "x" ] = coords[0];

   row[ "y" ] = coords[1];

   }

  }

  /// <summary>

  /// 增加列

  /// < /summary >

  /// <param name= "ds" >< /param >

  /// <param name= "columename" >< /param >

  /// <param name= "columevalue" >< /param >

  private static void addcolumetodataset(dataset ds, string columename, float columevalue)

  {

   ds.tables[0].columns.add(columename, typeof(float));

   foreach (system.data.datarow row in ds.tables[0].rows)

   {

   row[ "rotation" ] = -columevalue;

   }

  }

  /// <summary>

  /// 轨迹用点表示

  /// < /summary >

  /// <param name= "ds" >< /param >

  /// <param name= "c" >< /param >

  /// <returns>< /returns >

  private static vectorlayer getlayerfromdataset(dataset ds, color c)

  {

   var xlsprovider = new datatablepoint(ds.tables[0], "oid" , "x" , "y" );

   var xlslayer = new vectorlayer( "xls" , xlsprovider)

   { style = new vectorstyle() { pointcolor = new solidbrush(c) } };

   return xlslayer;

  }

  /// <summary>

  /// 获取带图标的图层

  /// < /summary >

  /// <param name= "ds" >< /param >

  /// <param name= "c" >< /param >

  /// <returns>< /returns >

  private static vectorlayer getlayerfromdataset2(dataset ds, color c)

  {

   var xlsprovider = new datatablepoint(ds.tables[0], "oid" , "x" , "y" );

   var xlslayer = new vectorlayer( "xls" , xlsprovider)

   { style = { symbol=properties.resources.redflag} };

   return xlslayer;

  }

  private static labellayer getlabellayerbyvectorlayer(vectorlayer xlslayer, string layername)

  {

   var xlslabellayer = new labellayer(layername)

   {

   datasource = xlslayer.datasource,

   labelcolumn = "name" ,

   //prioritycolumn = "population" ,

   style =

    {

    collisionbuffer = new system.drawing.sizef(2f, 2f),

    collisiondetection = true

    },

   labelfilter = labelcollisiondetection.thoroughcollisiondetection

   };

   return xlslabellayer;

  }

  }

  public enum maptype {

  shapefile = 0,

  mapinfo = 1,

  runline = 2, // 运行轨迹

  static = 3 // 定点数据

  }

}

 

备注:

1. 因用的mapinfo和shape源文件为源码里面的,所有为英文显示。

源码下载: demosharpmap.rar

总结

以上所述是小编给大家介绍的c# 中sharpmap的简单使用实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!

原文链接:http://HdhCmsTestcnblogs测试数据/hsiang/archive/2017/08/27/7440950.html

dy("nrwz");

查看更多关于C# 中SharpMap的简单使用实例详解的详细内容...

  阅读:64次