Shapefile格式说明及读写代码示例
shape文件的操作

shape⽂件的操作⼀、maven依赖引⼊<dependency><groupId>org.geotools</groupId><artifactId>gt-api</artifactId><exclusions><exclusion><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId></exclusion><exclusion><groupId>jgridshift</groupId><artifactId>jgridshift</artifactId></exclusion><exclusion><groupId>Javax.media</groupId><artifactId>jai_core</artifactId></exclusion></exclusions></dependency><dependency><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId></dependency><dependency><groupId>jgridshift</groupId><artifactId>jgridshift</artifactId></dependency><dependency><groupId>Javax.media</groupId><artifactId>jai_core</artifactId></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-geojson</artifactId></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-epsg-hsql</artifactId><exclusions><exclusion><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId></exclusion></exclusions></dependency><!-- https:///artifact/org.hsqldb/hsqldb --><dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId><scope>test</scope></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId></dependency><dependency><groupId>com.googlecode.json-simple</groupId><artifactId>json-simple</artifactId></dependency>备注:需要配置下载org.geotools的私有仓库<repositories><repository><id>osgeo</id><name>OSGeo Release Repository</name><url>https:///repository/release/</url><snapshots><enabled>false</enabled></snapshots><releases><enabled>true</enabled></releases></repository></repositories>⼆、读取shape⽂件,并转换为对象Tpublic static List<T>readShape(URL url) throws IOException {ShapefileDataStore store = new ShapefileDataStore(url);//设置编码Charset charset = Charset.forName("GBK");store.setCharset(charset);SimpleFeatureSource sfSource = store.getFeatureSource();SimpleFeatureIterator sfIter = sfSource.getFeatures().features();// 从ShapeFile⽂件中遍历每⼀个Feature,然后将Feature转为GeoJSON字符串List<T> list = new ArrayList<>();while (sfIter.hasNext()) {SimpleFeature feature = sfIter.next();// Feature转GeoJSONFeatureJSON fjson = new FeatureJSON();StringWriter writer = new StringWriter();fjson.writeFeature(feature, writer);JSONObject jsonObject = new JSONObject(writer.toString());String type = jsonObject.getStr("type").toLowerCase();if (type.equals("multipolygon")){LOGGER.error("该数据不是图斑:【{}】",writer);continue;}String properties = jsonObject.remove("properties").toString();jsonObject.remove("id");//其他属性T t = JSONUtil.toBean(properties, T.class);if (JudgeUtil.isDBNull(t.getObjectid())){LOGGER.error("该图斑每页objectid:【{}】",writer.toString());continue;}//geojsont.setGeojson(jsonObject.toString());list.add(gisWarnQrstbhhx);}return list;}三、shape⽂件写⼊1、写⼊shape⽂件⼊⼝/*** 写shape⽂件* @param rootFile* @param shapeName shape⽂件名包含后缀名.shp* @param list*/public static void writeShape(File rootFile,String shapeName,List<T>list) throws IOException {if (JudgeUtil.isEmpty(list)){throw new WrongDataException("数据不能为空");}String type = new JSONObject(list.get(0).getGeojson()).getStr("type").toLowerCase();//将list转换为geoJson字符串String geoJson = getGsoJson(list);if (!rootFile.exists() || rootFile.isFile()){rootFile.mkdirs();}File file = new File(rootFile,shapeName);Map<String, Serializable> params = new HashMap<>();params.put(ShapefileDataStoreFactory.URLP.key,file.toURI().toURL());ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);//定义图形信息和属性信息SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();tb.setCRS(DefaultGeographicCRS.WGS84);tb.setName("shapefile");tb.setDefaultGeometry("the_geom");//添加属性addProperties(type,tb);ds.createSchema(tb.buildFeatureType());//设置编码Charset charset = Charset.forName("GBK");ds.setCharset(charset);FeatureJSON featureJson = new FeatureJSON();SimpleFeatureCollection featureCollection = (SimpleFeatureCollection) featureJson.readFeatureCollection(geoJson);FeatureIterator<SimpleFeature> iterator = featureCollection.features();//设置WriterFeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);//写下⼀条SimpleFeature srcFeature;Iterator<Property> properties;while (iterator.hasNext()){srcFeature = iterator.next();properties = srcFeature.getProperties().iterator();SimpleFeature destFeature = writer.next();while (properties.hasNext()){Name name = properties.next().getName();Object attribute = srcFeature.getAttribute(name);if (!(attribute instanceof Geometry)){destFeature.setAttribute(name, attribute);}}destFeature.setDefaultGeometryProperty(srcFeature.getDefaultGeometryProperty());}writer.write();writer.close();ds.dispose();}2、将List<T>转换为geojson/*** T转geojson* @param list* @return*/private static String getGsoJson(List<T>list){JSONObject jsonObject = new JSONObject();jsonObject.putOnce("type","FeatureCollection");JSONArray jsonArray = new JSONArray();jsonObject.putOnce("features",jsonArray);for (T t : list) {JSONObject feature = new JSONObject();feature.putOnce("type","Feature");feature.putOnce("geometry",new JSONObject(t.getGeojson()));t.setGeojson(null);t.setGeom(null);t.setGid(null);feature.putOnce("properties",JSONUtil.parseObj(t));jsonArray.add(feature);}return jsonObject.toString();}3、通过反射添加properties/*** 通过反射添加properties* @param tb*/private static void addProperties(String type, SimpleFeatureTypeBuilder tb){Field[] declaredFields = T.class.getDeclaredFields();setType(tb,type.toLowerCase());for (Field declaredField : declaredFields) {String name = declaredField.getName();if (!name.equals("serialVersionUID") && !name.equals("geojson") && !name.equals("geom")){ tb.add(name,declaredField.getType());}}}4、设置类型private static void setType(SimpleFeatureTypeBuilder tb,String type){if (type.equals("point")) {tb.add("the_geom", Point.class);} else if (type.equals("line")) {tb.add("the_geom", LineString.class);} else if (type.equals("polygon")) {tb.add("the_geom", Polygon.class);} else if (type.equals("multipoint")) {tb.add("the_geom", MultiPoint.class);} else if (type.equals("multiline")) {tb.add("the_geom", MultiLineString.class);} else if (type.equals("multipolygon")) {tb.add("the_geom", MultiPolygon.class);}}。
结合C++和GDAL实现shapefile(shp)文件的读取

结果显示:
登录后才能查看或发表评论立即登录或者逛逛博客园首页
结合 C++和 GDAL实现 shapefile( shp)文件的读取
工具:vs2012+GDAL 2.0
数据:中国省界SHP文件bou2_4p.shp 可
包含头文件:
#include ""
代码:
int main() {
GDALAllRegister(); GDALDataset *poDS; CPLSetConfigOption("SHAPE_ENCODING",""); //解决中文乱码问题 //读取shp文件 poDS = (GDALDataset*) GDALOpenEx("d:/shapefile/bou2_4p.shp", GDAL_OF_VECTOR, NULL, NULL, NULL );
if(poFeature->GetFieldAsDouble("AREA")<1) continue; //去掉面积过小的polygon i=i++; cout<<i<<" "; OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); int iField; int n=poFDefn->GetFieldCount(); //获得字段的数目,不包括前两个字段(FID,Shape); for( iField = 0; iField <n; iField++ ) {
ogr2ogr 转换shapefile 编码

ogr2ogr 转换shapefile 编码(原创版)目录1.引言2.ogr2ogr 转换器的概述3.Shapefile 格式的概述4.编码的选择与转换5.示例与实践6.结论正文【引言】地理信息系统 (GIS) 是一种通过将空间数据与属性数据相结合来捕捉、存储、分析和管理地理信息的技术。
GIS 数据格式的标准化对于数据共享和互操作性至关重要。
Shapefile 是一种常见的 GIS 数据格式,而ogr2ogr 是一个开源的 GIS 数据转换器,可以将 Shapefile 转换为其他格式。
本文将介绍如何使用 ogr2ogr 转换器对 Shapefile 进行编码转换。
【ogr2ogr 转换器的概述】ogr2ogr 是一个命令行工具,可以将 GIS 数据从一个格式转换为另一个格式。
它支持许多不同的数据源和目标格式,包括 Shapefile、GeoJSON、KML 等。
ogr2ogr 转换器还可以处理地理坐标系和投影。
它由OGR(Open Geospatial Reference) 项目开发,是一个开源的 GIS 软件库。
【Shapefile 格式的概述】Shapefile 是一种常见的 GIS 数据格式,可以存储点、线和面等空间几何数据。
Shapefile 文件由多个文件组成,包括.shp(几何图形)、.shx(索引) 和.dbf(属性数据) 等文件。
Shapefile 文件通常使用dbf 文件存储属性数据,这些数据可以是任何类型的数据,包括字符串、数字、日期等。
【编码的选择与转换】在将 Shapefile 转换为其他格式时,需要选择目标格式的编码。
常见的编码包括 UTF-8、UTF-16、ISO-8859-1 等。
选择正确的编码可以确保数据在转换过程中不会丢失或损坏。
例如,如果将 Shapefile 转换为GeoJSON,则应该选择 UTF-8 编码,因为 GeoJSON 是一种基于 JSON 的格式,它使用 UTF-8 编码来存储字符串数据。
shapefile的使用和地理信息的获得

shapefile的使⽤和地理信息的获得Shapefile⽂件是美国ESRI公司发布的⽂件格式,因其ArcGIS软件的推⼴⽽得到了普遍的使⽤,是现在GIS领域使⽤最为⼴泛的⽮量数据格式。
官⽅称Shapefile是⼀种⽤于存储地理要素的⼏何位置和属性信息的⾮拓扑简单格式。
⼀般地,Shapefile⽂件是多个⽂件的集合,⾄少包括⼀个shp,shx以及dbf⽂件。
shp主⽂件使⽤变长记录存储空间⼏何数据,⽀持点,线,⾯等多种⼏何类型。
shx索引⽂件⽤于存储⼏何数据的索引信息,包含对主⽂件中每个记录长度的描述(注意不是空间索引)dbf表⽂件是使⽤dBase数据库表⽂件进⾏空间属性数据存储的⽂件所以,我们如果要⾃⼰完全从底层写代码解析Shapefile⽂件的话,需要根据shx⽂件中的信息读取shp中的⼆进制数据并转化为⼏何对象,然后再读取dbf表格,将属性添加到⼏何对象上就完成了对⼀个Shapefile⽂件的解析.其实现在,如果给定⼀个地点的经度和维度,现在让你想判断⼀下,这个地点是算什么区域,正常做法是,我们调⽤百度地图或者⾕歌地图的API⾥⾯的接⼝就可以了。
但是其实,如果当这些接⼝不能调⽤的时候,我们该怎么办呢。
这⾥我们可以考虑下⽤shapefile来完成这个任务。
1. ⾸先在shapefile⾥⾯,⽂件数据提供了信息,这个信息可以帮助我们绘制⼀个地区区域的多边形。
2. 接着我们需要把我们的⽬标点绘制成⼀个点3. 剩下的任务就是,我们来判断,⽬标区域的点是不是在地形绘制的多边形⾥⾯。
判断任务3的时候,我们可以⽤⼀个景点的 point in ploygon 理论,⼤概是这个样⼦判断的算法我就直接引⽤了:1) Draw a horizontal line to the right of each point and extend it to infinity1) Count the number of times the line intersects with polygon edges.2) A point is inside the polygon if either count of intersections is odd orpoint lies on an edge of polygon. If none of the conditions is true, thenpoint lies outside.那这样,我们有我们⽬标点的坐标,我们⼜有我们区域的⼤概的形状,那这样我们就可以确定,我们的⽬标点的所在区域了下⾯是代码,⽤python实现的# Library# 这个是⽤来判断点在不在多边形⾥⾯的库,同时绘制点和多边形from shapely.geometry import Pointfrom shapely.geometry.polygon import Polygon# 这⾥是⽤这个来读取shapefile⽂件import shapefile接着我们读⼊数据1# Load the shapefile information2 sf = shapefile.Reader("./vic_suburb_boundary/VIC_LOCALITY_POLYGON_shp") # note, no suffix, all3 files are used3 recs = sf.records()4 shapes = sf.shapes()这时候我们先看下,shapefile⾥⾯有哪些信息recs[0]这⾥我们发现,基本上可能是与这个区域有关的⼀些⽂字信息,我们看到第7个元素是我们这次需要的,是这个区域的名字,接着我们看下shapes⾥⾯的内容shapes[0].points这⾥我们发现是⼀系列坐标点,这些坐标点可以帮助我们来绘制这个区域的的多边形# Build a list to hold the name of the suburbsubsurb_name = []for item in recs:# Extract the 7th element:subsurb namesubsurb_name.append(item[6])# Check the extraction resultprint(subsurb_name[:5])# Build a list to hold the ploygon represent the subsurbsub_plon = []for item in shapes:# Using the points information to draw the ploygonpolygon = Polygon(item.points)sub_plon.append(polygon)# Drow one of the subsurbsub_plon[0]在上⾯两步,我们把shape中的区域名字信息以及区域性质信息都提取了出来,接着,我们就可以⽤这个信息,来判断,我们的⽬标点,相应都在哪⾥了# Combine name and ploygon list togethersub_info = list(zip(subsurb_name,sub_plon))# lat information for all the latslat_list = list(df_t)# lng informationlng_list = list(df_house.lng)# Zip them in the list of tuplesposition_list = zip(lng_list, lat_list)# A list for holding the subsurb information for each house propertysub_for_house = []# Loop through all the housefor item in position_list:# Build a point to represent the house propertypoint = Point(item[0],item[1])# Check where the point is locatedfor sub in sub_info:# Return true if the point is in the ploygonif sub[1].contains(point):# Collect the resultsub_for_house.append(sub[0])# Check the resultsub_for_house[:5]根据我们之前的算法,我们把每个我们的⽬标地址都便利了⼀遍,并且计算出相应的位置点。
Shapefile文件修改_Python地理空间分析指南(第2版)_[共2页]
![Shapefile文件修改_Python地理空间分析指南(第2版)_[共2页]](https://img.taocdn.com/s3/m/433e4b2e0242a8956bece4ee.png)
5.5 Shapefile文件编辑 155也可能包含一个名为m的测量值。
该测量测值可能是和上述形状有关的用户自定义信息。
例如一个给定位置的温度信息,这是另外一种形状类型,它允许为每个形状添加一个m值而非z值。
这种形状数据大家一般叫它M型几何图形。
和z值类似,如果存在该类型数据,就会生成m属性,如果没有那么它们就不是上述类型的数据。
你一般不会遇到包含z值的Shapefile文件,碰到需要设置m值的数据的几率就更小了。
但是如果有机会遇到它们,那么也不必大惊小怪。
只需将dbf文件中的看到的字段和记录一视同仁即可。
如果你不喜欢将z和m值分开存放在List对象中,那么可以使用zip()方法通过点集List对它们进行组合。
zip()方法可以接受多个List对象作为参数,只需要用逗号对它们分隔即可。
5.5.4 Shapefile文件修改当你使用PyShp库创建了一个读取器对象后,它是只读的。
你可以在该读取器对象中修改记录的值,但是它们不会对原Shapefile文件中的记录产生影响。
为了创建一个Shapefile 文件,你也需要创建一个写者对象。
你可以在写入和读取对象中随意修改数据记录的值,因为它们都是Python的动态数据类型。
但是与此同时,你必须将需要修改的值从读取器对象拷贝到写入对象中。
PyShp库能自动处理所有头文件信息,例如边框和记录总数。
你唯一需要关注的是几何图形和属性。
你会发现这个方法比在之前OGR示例中使用的方法容易的多。
不过它的缺点是只适用于UTM投影。
为了演示这一概念,将会读取一个使用度做计量单位的点Shapefile文件,然后在写者对象保存它之前将其参照系统转换为UTM投影。
我们将会用到本章前面提到过的PyShp 和UTM库。
本示例中用到的Shapefile文件是之前重投影为WGS84坐标系统的纽约市博物馆Shapefile文件。
你还可以通过如下地址下载该文件的ZIP压缩格式:http://git.io/vLd8Y请看下列代码:>>> import shapefile>>> import utm>>> r = shapefile.Reader("NYC_MUSEUMS_GEO")>>> w = shapefile.Writer(r.shapeType)>>> w.fields = list(r.fields)>>> w.records.extend(r.records())>>> for s in r.iterShapes():... lon,lat = s.points[0]... y,x,zone,band = utm.from_latlon(lat,lon)... w.point(x,y)>>> w.save("NYC_MUSEUMS_UTM")。
shapefile翻译

表1.shp文件的头文件结构注:最后4个加星号特别标示的四个数据只有当这个Shapefile文件包含Z方向坐标或者具有Measrue值时才有值,否则为0.0。
所谓Measrue值,是用于存储需要的附加数据,可以用来记录各种数据,例如权值、道路长度等信息。
文件长度是文件的所有长度,用16位字表示(即包括50个16位字长度的文件头)。
编号几何类型0Null Shape(表示这个Shapefile文件不含坐标)1Point(表示Shapefile文件记录的是点状目标,但不是多点)3PolyLine(表示Shapefile文件记录的是线状目标)5Polygon(表示Shapefile文件记录的是面状目标)8MultiPoint(表示Shapefile文件记录的是多点,即点集合)11PointZ(表示Shapefile文件记录的是三维点状目标)13PolyLineZ(表示Shapefile文件记录的是三维线状目标)15PolygonZ(表示Shapefile文件记录的是三维面状目标)18MultiPointZ(表示Shapefile文件记录的是三维点集合目标)21PointM(表示含有Measrue值的点状目标)23PolyLineM(表示含有Measrue值的线状目标)25PolygonM(表示含有Measrue值的面状目标)28MultiPointM(表示含有Measrue值的多点目标)31MultiPatch(表示复合目标)(5)Polygon -X,Y空间的面状目标:一个面状目标包含一个或多个环。
环是一个首尾连接的由4个或4个以上的点组成的一个封闭的,非自交的环路。
一个面状目标可能包含多重外环路。
一个环的顶点顺序或方向显示了环是否位于面状目标的内部。
内部环是逆时针的,而简单的环状面状目标通常是顺时针的。
和线类似,面状目标也包括边界框、部分数、点表14 PolygonZ的记录内容一个MultiPatch 包括许多表面部分(parts)。
资料:shapefile(中文版)
ESRI shapefile 技术手册本技术手册规定了shapefile空间数据格式,阐述了为什么是一种比较重要的数据格式。
同时本技术手册还列出了直接创建shapefile数据的ESRI工具和从其它数据格式向shapefile 格式转换的软件。
对一些希望通过自己开发程序来完成数据转换或者创建shapefile格式的数据的组织来说,这份技术说明同样提供了所需的所有技术支持。
什么是shapefile?Shapefile把空间对象的非拓扑地理数据和属性信息存储在一个数据集里面。
由于其不包含拓扑结构数据结构,因此相比于其它的数据格式,具有更易于图形输出与编辑的能力。
Shapefile更易于处理单要素图形,此外shapefile还具有需要较少的磁盘储存空间与易于读写的优点。
Shapefile支持点、线、面状要素;面状要素以闭合的多线,即多边形的边界存储。
属性要素以dBASE格式记录。
且每一个属性值与相关的形记录有一对一的关系。
如何创建shapefile?可以通过以下方式创建shapefile:导入---使用ARC/INFO、PC ARC/INFO,、Spatial Database Engine(SDE)、Arc View GIS,或者是Business MAP等软件,由已有的数据源创建。
数字化---由ArcView的地理信息要素创建工具直接数字化得到。
编程---使用Avenue™ (ArcView GIS), MapObjects™, ARC Macro Language (AML™)(ARC/INFO),或者简单的宏命令,自行创建shapefile.直接生成----通过特定的程序直接生成shapefile文件。
SDE、ARC/INFO、PC ARC/INFO、Data Automation Kit (DAK), 和Arc CAD这些软件可以把shapefile格式的文件转化为coverage的文件格式,ARC/INFO还可以把coverage格式转化为shapefile 文件格式,在这份文件中详细地说明了shapefile数据与其他形式数据的转化过程。
一种Shapefile文件的剖析及读写方法
一种Shapefile文件的剖析及读写方法马文涛;陈宜金;王淼淼;张雪;张凯旋【摘要】为加深对 Shapefile文件结构的理解,培养将一定格式的数据文件转换成Shapefile图形文件的能力.详细探讨了Shapefile文件的底层结构,并以此为出发点,在.Net环境下利用 Microsoft Visual Stu-dio2015 设计出可对 Shapefile图形文件进行交互式读写的 GIS程序.结果表明通过一定的编程手段,可以将一定格式的图形文件按照我们所期望的方式展现出来,且能够创造出我们所需要的图形文件.可见特定格式的数据图形文件与Shapefile图形文件可以通过编程技术进行互相转换.【期刊名称】《北京测绘》【年(卷),期】2018(032)012【总页数】5页(P1517-1521)【关键词】Shapefile;地理信息系统(GIS)程序;网络;数据结构【作者】马文涛;陈宜金;王淼淼;张雪;张凯旋【作者单位】中国矿业大学(北京)地球科学与测绘工程学院,北京 100083;中国矿业大学(北京)地球科学与测绘工程学院,北京 100083;中国矿业大学(北京)地球科学与测绘工程学院,北京 100083;中国矿业大学(北京)地球科学与测绘工程学院,北京100083;中国矿业大学(北京)地球科学与测绘工程学院,北京 100083【正文语种】中文【中图分类】P2080 引言ArcGIS作为 ESRI(Environmental Systems Research Institute)公司推出的一套具有完善体系的 GIS平台产品,是目前使用最广泛的地理信息系统平台软件,主要用来创建和绘制地图,空间数据编辑与管理,分析,共享和显示地理要素信息,并在一系列应用中使用地图和地理信息[1]。
然而这些功能都是在数据的基础上进行的,Shapefile图形文件格式作为 ArcGIS使用的最主要的几种数据图形格式之一,与其它图形数据文件相对比,该图形文件只占用少量的磁盘存储空间,并且没有拓扑数据结构,具有更快的制图和编辑速度,更易于读写,是 ESRI公司独立发布的用来描述空间图形数据的几何和属性特征的非拓扑实体矢量数据结构的一种格式,旨在用来培养系统开发人员和软件用户具备将不同数据格式进行互相转换的能力,使得能够在更广泛的应用情况下读取或建立 Shapefile文件,从而将不同的矢量格式转换成ArcGIS能够接受的数据格式,增强地理空间数据的共享性,普遍性和互操作性[2]。
matlab中shaperead函数
matlab中shaperead函数Matlab中的shaperead函数是一个非常有用的工具,它可以帮助我们读取和处理地理信息系统(GIS)中的矢量数据。
这些数据通常以shapefile格式存储,包含了地图上的各种要素,如道路、河流、建筑物等等。
在本文中,我们将详细介绍shaperead函数的用法和功能。
首先,让我们看一下shaperead函数的基本语法:```matlabS = shaperead(filename)```其中,filename是shapefile文件的名称,S是一个结构体数组,包含了shapefile中的所有要素。
每个结构体都包含了该要素的几何形状和属性信息。
例如,我们可以使用以下代码读取一个名为“myshapefile.shp”的shapefile文件:```matlabS = shaperead('myshapefile.shp');```读取完成后,我们可以使用S(1)、S(2)等方式访问结构体数组中的每个要素。
每个结构体包含的字段可能会有所不同,但通常包括以下几个:- Geometry:要素的几何形状,可以是点、线或面。
- BoundingBox:要素的边界框,即最小外接矩形。
- X、Y:要素的中心点坐标。
- Attributes:要素的属性信息,可以是任意类型的数据,如字符串、数值等等。
下面是一个简单的示例,演示如何读取shapefile文件并显示其中的要素:```matlabS = shaperead('myshapefile.shp');for i = 1:length(S)plot(S(i).X, S(i).Y);hold on;end```这段代码将读取“myshapefile.shp”文件中的所有要素,并将它们显示在一个图形窗口中。
我们可以使用plot函数绘制要素的几何形状,使用hold on命令保持图形窗口的状态,以便在同一张图中显示多个要素。
C#读取shapefile文件
C#读取shapefile文件C#读取shapefile文件using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Data.Odbc; //add by hand,which is needed when load the layer attribute informationusing System.Data.OleDb;using System.Collections;using System.Data;using System.Xml;namespace CGCL.CGFiles{public class CGShapeFileParser{public class ESRI_ShxHeader{int FileCode; //9994int[] Unused2 = new int[5];int FileLength;int Version; //1000int ShapeType; // 0- Null shape// 1- Point// 3-Arc// 5-Polygon// 8-MultiPointdouble XMin;double YMin;double XMax;double YMax;int[] Unused3 = new int[8];}class ESRI_ShapeFile{int FileCode; //9994int[] Unused = new int[5];int FileLength;int Version; //1000int ShapeType; // 0- Null shape // 1- Point// 3-Arc// 5-Polygon// 8-MultiPointdouble XMin;double YMin;double XMax;double YMax;int[] Unused1 = new int[8];}class ESRI_RecordHeader {int RecNumber;int ContentLength;}class ESRI_PointContent {int ShapeType;double X;double Y;}class ESRI_IndexRec//索引文件{int Offset;int ContentLen;}class ESRI_ArcContent{int ShapeType;double xmin;double ymin;double xmax;double ymax;int NumParts;int NumPoints;}class ESRI_PolygonContent{int ShapeType;double xmin;double ymin;double xmax;double ymax;int NumParts;int NumPoints;}public bool LoadShapeFile(CGDataAdapter.CGLocalGeoDataAdapter adapter) {string connectionString;OdbcConnection connection;OdbcDataAdapter OdbcAdapter;CGMap.CGGeoLayer geolayer = adapter.getMasterGeoLayer();string shpfilepath = adapter.getPath();string shpfilename = adapter.getFileName();string shxfilepath = shpfilepath.Substring(0, stIndexOf("\\") + 1) + adapter.getFileName() + ".shx";//read out the layer attribute infomationconnectionString = "Dsn=Visual FoxProDatabase;sourcedb=" + shpfilepath + ";sourcetype=DBF;exclusive=No;backgroundfetch=Yes;collate= Machine";connection = new OdbcConnection(connectionString);connection.Open();OdbcAdapter = new OdbcDataAdapter("select * from " + shpfilename, connectionString);// Create new DataTable and DataSource objects.DataSet ds = new DataSet();OdbcAdapter.Fill(ds);connection.Close();if (geolayer == null) return false;try{//先读取.shx文件,得到文件的总字节长度FileStream fs = new FileStream(shxfilepath, FileMode.Open, FileAccess.Read); //文件流形式BinaryReader BinaryFile = new BinaryReader(fs); //二进制读取文件的对象long BytesSum = fs.Length; //得到文件的字节总长int shapecount = (int)(BytesSum - 100) / 8; //得以总记录数目BinaryFile.Close();fs.Close();//打开shp文件if (shxfilepath == ""){// MessageBox.Show("索引文件打开出错");return false;}//打开.shp文件,读取x,y坐标的信息fs = new FileStream(shpfilepath, FileMode.Open, FileAccess.Read); //文件流形式BinaryFile = new BinaryReader(fs); //打开二进制文件BinaryFile.ReadBytes(32); //先读出36个字节,紧接着是Box边界合int shapetype = BinaryFile.ReadInt32();geolayer.envlope.left = BinaryFile.ReadDouble(); //读出整个shp图层的边界合geolayer.envlope.bottom = BinaryFile.ReadDouble();geolayer.envlope.right = BinaryFile.ReadDouble();geolayer.envlope.top = BinaryFile.ReadDouble();BinaryFile.ReadBytes(32); // shp中尚未使用的边界盒//Get Shape Data From Here Onint stype;double x, y;double left, right, top, bottom;int partcount;int pointcount;switch (shapetype){case 1://single pointgeolayer.shapeType = CGConstants.CGShapeType.SHAPE_POINT;for (int i = 0; i < shapecount; i++){CGGeoShape.CGGeoPoint gps = new CGGeoShape.CGGeoPoint();BinaryFile.ReadBytes(12); //记录头8个字节和一个int(4个字节)的shapetype/* stype = BinaryFile.ReadInt32();if (stype != shapetype)continue;*/x = BinaryFile.ReadDouble();y = BinaryFile.ReadDouble();gps.objectID = i;gps.objectUID = i;gps.x = x;gps.y = y;gps.z = 0;gps.envlope.left = gps.x;gps.envlope.right = gps.x;gps.envlope.top = gps.y;gps.envlope.bottom = gps.y;geolayer.getDataContainer().Add(gps);}break;case 8://multi points layerbreak;case 3://Polyline layergeolayer.shapeType = CGConstants.CGShapeType.SHAPE_LINE;for (int i = 0; i < shapecount; i++){geolayer.getAttributeContainer().Add(ds.Tables[0].Rows[i][0] ); //read out the attribute step by stepBinaryFile.ReadBytes(12);// int pos = indexRecs[i].Offset+8;// bb0.position(pos);// stype = bb0.getInt();// if (stype!=nshapetype){// continue;// }left = BinaryFile.ReadDouble();bottom = BinaryFile.ReadDouble();right = BinaryFile.ReadDouble();top = BinaryFile.ReadDouble();partcount = BinaryFile.ReadInt32(); pointcount = BinaryFile.ReadInt32();int[] parts = new int[partcount];int[] partspos = new int[partcount];double[] xpoints = new double[pointcount]; double[] ypoints = new double[pointcount]; double[] zpoints = new double[pointcount];//firstly read out parts begin pos in filefor (int j = 0; j < partcount; j++){parts[j] = BinaryFile.ReadInt32();}//shift them to be points count included in parts if (partcount > 0)partspos[0] = 0;int newpos = 0;for (int j = 0; j <= partcount - 2; j++){parts[j] = parts[j + 1] - parts[j];newpos += parts[j];partspos[j + 1] = newpos;}parts[partcount - 1] = pointcount - parts[partcount - 1];//read out coordinatesfor (int j = 0; j < pointcount; j++){x = BinaryFile.ReadDouble();y = BinaryFile.ReadDouble();xpoints[j] = x;ypoints[j] = y;zpoints[j] = 0;}if (pointcount > 1){CGGeoShape.CGGeoLine gl = new CGGeoShape.CGGeoLine(xpoints, ypoints, zpoints, parts, partspos, pointcount, partcount);gl.envlope.left = left;gl.envlope.right = right;gl.envlope.top = top;gl.envlope.bottom = bottom;gl.objectID = i;gl.objectUID = i;geolayer.getDataContainer().Add(gl);}}break;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Shapefile格式说明及读写代码示例 Shape files 数据说明 Shape files 是 ESRI 提供的一种矢量数据格式,它没有拓扑信息,一个 Shape files 由一组文件组成,其中必要的基本文件包括坐标文件( .shp )、索引文件( .shx )和属性文件( .dbf )三个文件。 坐标文件的结构说明 坐标文件 (.shp) 用于记录空间坐标信息。它由头文件和实体信息两部分构成(如图 2.1 所示)。 坐标文件的文件头 坐标文件的文件头是一个长度固定 (100 bytes) 的记录段,一共有 9 个 int 型和 7 个 double 型数据,主要记录内容见表 2.2 。 文件头 记录头 记录内容 记录头 记录内容 记录头 记录内容 记录头 记录内容
图 2.1 坐标文件的结构 起始位置 名称 数值 类型 位序 0 File Code 9994 Integer big 4 Unused 0 Integer big 8 Unused 0 Integer big 12 Unused 0 Integer big 16 Unused 0 Integer big 20 Unused 0 Integer big 24 文件长度 文件的实际长度 Integer big
28 版本号 1000 Integer Little 32 几何类型 表示这个 Shapefile 文件所记录的空间数据的几何类型 Integer Little
36 Xmin 空间数据所占空间范围的 X 方向最小值 Double Little 44 Ymin 空间数据所占空间范围的 Y 方向最小值 Double Little 52 Xmax 空间数据所占空间范围的 X 方向最大值 Double Little 60 Ymax 空间数据所占空间范围的 Y 方向最大值 Double Little 68* Zmin 空间数据所占空间范围的 Z Double Little 方向最小值 76* Zmax 空间数据所占空间范围的 Z 方向最大值 Double Little
84* Mmin 最小 Measure 值 Double Little 92* Mmax 最大 Measure 值 Double Little 表 2.2shapefiles 头文件表 注:最后 4 个加星号特别标示的四个数据只有当这个 Shapefile 文件包含 Z 方向 坐标或者具有 Measure 值时才有值,否则为 0.0 。所谓 Measure 值,是用于存储需要的 附加数据,可以用来记录各种数据,例如权值、道路长度等信息。 位序 细心的读者会注意到表 2.2 中的数值的位序有 Little 和 big 的区别,对于位序是 big 的数据我们在读取时要小心。通常,数据的位序都是 Little ,但在有些情况下可能会是 big ,二者的区别在于它们位序的顺序相反。一个位序为 big 的数据,如果我们想得到它的真实数值,需要将它的位序转换成 Little 即可。转换原理非常简单,就是交换字节顺序,下面是作者实现的在两者间进行转换的程序,代码如下: // 位序转换程序 unsigned long OnChangeByteOrder (int indata) { char ss[8]; char ee[8]; unsigned long val = unsigned long(indata); _ultoa( val, ss, 16 );// 将十六进制的数 (val) 转到一个字符串 (ss) 中 int i; int length=strlen(ss); if(length!=8) { for(i=0;i<8-length;i++) ee[i]='0'; for(i=0;i ee[i+8-length]=ss[i]; for(i=0;i<8;i++) ss[i]=ee[i]; } ////****** 进行倒序 int t; t =ss[0]; ss[0] =ss[6]; ss[6] =t; t =ss[1]; ss[1] =ss[7]; ss[7] =t; t =ss[2]; ss[2] =ss[4]; ss[4] =t; t =ss[3]; ss[3] =ss[5]; ss[5] =t; ////****** //****** 将存有十六进制数 (val) 的字符串 (ss) 中的十六进制数转成十进制数 int value=0; for(i=0;i<8;i++) { int k; CString mass; mass=ss[i]; if(ss[i]=='a' || ss[i]=='b' || ss[i]=='c' || ss[i]=='d' || ss[i]=='e' || ss[i]=='f') k=10+ss[i]-'a'; else sscanf(mass,"%d",&k); value=value+int(k*pow(16,7-i)); } return (value); }
Shapefile 文件支持的几何类型( ShapeType ) Shapefile 文件所支持的几何类型如表 2.3 所示: 编号 几何类型 0 Null Shape (表示这个 Shapefile 文件不含坐标) 1 Point (表示 Shapefile 文件记录的是点状目标,但不是多点) 3 PolyLine (表示 Shapefile 文件记录的是线状目标) 5 Polygon (表示 Shapefile 文件记录的是面状目标) 8 MultiPoint (表示 Shapefile 文件记录的是多点,即点集合) 11 PointZ (表示 Shapefile 文件记录的是三维点状目标) 13 PolyLineZ (表示 Shapefile 文件记录的是三维线状目标) 15 PolygonZ (表示 Shapefile 文件记录的是三维面状目标) 18 MultiPointZ (表示 Shapefile 文件记录的是三维点集合目标) 21 PointM (表示含有 Measure 值的点状目标) 23 PolyLineM (表示含有 Measure 值的线状目标) 25 PolygonM (表示含有 Measure 值的面状目标) 28 MultiPointM (表示含有 Measure 值的多点目标) 31 MultiPatch (表示复合目标) 表 2.3shapefiles 文件支持的几何类型 对于一个不是记录 Null Shape 类型的 Shapefile 文件,它所记录的空间目标的几何类型必须一致,不能在一个 Shapefile 文件中同时记录两种不同类型的几何目标。 读取坐标文件( .shp )的文件头的代码 如下: void OnReadShp ( CString ShpFileName ) { FILE* m_ShpFile_fp; //****Shp 文件指针 // 打开坐标文件 if((m_ShpFile_fp=fopen(ShpFileName,"rb"))==NULL) { return; } // 读取坐标文件头的内容开始 int FileCode; int Unused; int FileLength; int Version; int ShapeType; double Xmin; double Ymin; double Xmax; double Ymax; double Zmin; double Zmax; double Mmin; double Mmax; fread(&FileCode, sizeof(int), 1,m_ShpFile_fp); FileCode = OnChangeByteOrder(FileCode); for(i=0;i<5;i++) fread(&Unused,sizeof(int), 1,m_ShpFile_fp); fread(&FileLength, sizeof(int), 1,m_ShpFile_fp); FileLength = OnChangeByteOrder(FileLength); fread(&Version, sizeof(int), 1,m_ShpFile_fp); fread(&ShapeType, sizeof(int), 1,m_ShpFile_fp); fread(&Xmin, sizeof(double),1,m_ShpFile_fp); fread(&Ymin, sizeof(double),1,m_ShpFile_fp); fread(&Xmax, sizeof(double),1,m_ShpFile_fp); fread(&Ymax, sizeof(double),1,m_ShpFile_fp); fread(&Zmin, sizeof(double),1,m_ShpFile_fp); fread(&Zmax, sizeof(double),1,m_ShpFile_fp); fread(&Mmin, sizeof(double),1,m_ShpFile_fp); fread(&Mmax, sizeof(double),1,m_ShpFile_fp); // 读取坐标文件头的内容结束 // 根据几何类型读取实体信息 } 实体信息的内容