shp地图解析(不用AE)
AE太重型,还收费,如果只是加载地图作为底图,可以用纯C#实现。线类型用得最多,以下是线类型的数据结构:
总体架构
文件头 |
记录头 记录内容 |
记录头 记录内容 |
。。。。。。。。。。。。 |
记录头 记录内容 |
文件头
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | File Code | 文件代码 |
Byte 4 | int | 无用 | |
Byte 8 | int | 无用 | |
Byte 12 | int | 无用 | |
Byte 16 | int | 无用 | |
Byte 20 | int | 无用 | |
Byte 24 | int | File Length | 文件长度 |
Byte 28 | int | Version | 版本 |
Byte 32 | int | Shape Type |
图形类型 1:Point,点类型 3:PolyLine,线类型 5:Polygon,面类型 |
Byte 36 | double | Xmin | 整图的X轴坐标最小值 |
Byte 44 | double | Ymin | 整图的Y轴坐标最小值 |
Byte 52 | double | Xmax | 整图的X轴坐标最大值 |
Byte 60 | double | Ymax | 整图的Y轴坐标最大值 |
Byte 68* | double | Zmin | |
Byte 76* | double | Zmax | |
Byte 84* | double | Mmin | |
Byte 92* | double | Mmax |
记录头
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | Record Number | 记录号,从1开始 |
Byte 4 | int | Content Length | 内容长度,内容的16位字数,不包括记录号。 |
记录内容
点类型:
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | ShapeType | Shape类型=1 |
Byte 4 | double | X | 点的X坐标 |
Byte 12 | double | Y | 点的Y坐标 |
线类型:
位置 | 类型 | 字段 | 说明 |
Byte 0 | int | ShapeType | Shape类型=3 |
Byte 4 | double [4] | Box | 该线条的边界盒,以Xmin,Ymin,Xmax,Ymax的顺序存储 |
Byte 36 | int | NumParts | 是PolyLine中部分的数目 |
Byte 40 | int | NumPoints | 是PolyLine中点的数目 |
Byte 44 | int [NumParts] | Parts | 每条PolyLine存储它在点数列中的第一个点的索引。数列索引是从0开始的。Parts[NumParts]数组是Points[NumPoints]数组的目录 |
X | Point[NumPoints] | Points | 本条记录的所有点。Struct Point {Double X;Double Y;} |
Parts和Points之间的关系: 如果Parts [0]=0Parts [1]=3Parts [2]=11Parts [3]=15…那么 第0条线:(Points[0], Points[1] , Points[2])三个点依次连结 第1条线:(Points[3], Points[4] , Points[5] , Points[6] , Points[7] , Points[8] , Points[9] , Points[10])这几个点依次连结 第3条线:(Points[11], Points[12] , Points[13] , Points[14])四个点依次连结 … |
ClassShp类:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO; namespace SDD
{
struct StructShapePoint
{
public double X;
public double Y;
} struct StructShapePolyline
{
public int RecordNumber;//记录号
public int ContentLength;//内容长度
public int ShapeType;
public double[] Box;//长度为4
public int PartsCount;
public int PointsCount;
public List<int> Parts;//在部分中第一个点的索引
public List<StructShapePoint> Points;//所有部分的点
public List<StructShapePoint[]> Lines;//把点按线组织好
} class ClassShp
{
public string FileName;
public int FileLength;
public int FileVersion;
public int ShapeType;//绘图类型:1-点,3-线,5-面
public double Xmin, Ymin, Xmax, Ymax;//地图边界尺寸
public double RawWidth, RawHeight;//地图大小,原始值
public double RawCenterX, RawCenterY;//shp原始坐标系的中心点
public List<StructShapePoint> ListPoints = new List<StructShapePoint>();//点集合
public List<StructShapePolyline> ListPolylines = new List<StructShapePolyline>();//线集合 public double Scale = ;//放大倍数,原始数据中1表示的像素数
public double CenterX, CenterY;//地图缩放后的中心点在控件坐标系中的位置 public double WindowWidth;//显示控件大小
public double WindowHeight; public Bitmap Bmp = null;//用于显示的画布,大小等于显示控件
public Pen ThePen = new Pen(Color.White, ); public ClassShp()
{ } public ClassShp(string pmtShpPathName, double pmtVisibleWidth, double pmtVisibleHeight)
{
if (File.Exists(pmtShpPathName) == false) return;
if (Init(pmtShpPathName, pmtVisibleWidth, pmtVisibleHeight))
{
SaveAsTxt(); //把数据保存成文本文档
}
} //################################################################################
// 由Xmin等四个值计算出基本成员参数
//################################################################################
public void SetBaseParameter(double pmtXmin,double pmtYmin,double pmtXmax,double pmtYmax)
{
Xmin = pmtXmin;
Ymin = pmtYmin;
Xmax = pmtXmax;
Ymax = pmtYmax; RawWidth = Xmax - Xmin;
RawHeight = Ymax - Ymin;
RawCenterX = (Xmin + Xmax) / ;
RawCenterY = (Ymin + Ymax) / ; CenterX = WindowWidth / ;
CenterY = WindowHeight / ; SetRelativityScale(, WindowWidth, WindowHeight); Console.WriteLine("绘图类型:{0}", ShapeType);
Console.WriteLine("地图边界:({0}, {1}), ({2}, {3})", Xmin, Ymin, Xmax, Ymax);
Console.WriteLine("地图大小:{0} * {1}", RawWidth, RawHeight);
Console.WriteLine("地图中心:({0}, {1})", RawCenterX, RawCenterY);
} //################################################################################
// 初始化
//################################################################################
public bool Init(string pmtShpPathName, double pmtVisibleWidth, double pmtVisibleHeight)
{
if (File.Exists(pmtShpPathName) == false) return false; int nameIndex = pmtShpPathName.LastIndexOf("\\")+;
int nameLenght = pmtShpPathName.Length--pmtShpPathName.LastIndexOf("\\"); FileName = pmtShpPathName.Substring(nameIndex, nameLenght); WindowWidth = pmtVisibleWidth;
WindowHeight = pmtVisibleHeight; try
{
FileStream fs = new FileStream(pmtShpPathName, FileMode.Open);
BinaryReader br = new BinaryReader(fs, Encoding.Default); br.ReadBytes();
FileLength = br.ReadInt32();
FileVersion = br.ReadInt32();
ShapeType = br.ReadInt32(); Xmin = br.ReadDouble();
Ymin = br.ReadDouble();
Xmax = br.ReadDouble();
Ymax = br.ReadDouble(); br.ReadBytes(); if (ShapeType == )
{
ListPoints.Clear();
while (br.PeekChar() != -)
{
StructShapePoint shapePoint = new StructShapePoint();
uint recordNum = br.ReadUInt32();
int dataLength = br.ReadInt32();
br.ReadInt32();
shapePoint.X = br.ReadDouble();
shapePoint.Y = br.ReadDouble();
ListPoints.Add(shapePoint);
}
}//end of : if (ShpType==1)
else if (ShapeType == || ShapeType == )
{
ListPolylines.Clear();
while (br.PeekChar() != -)
{
StructShapePolyline shapePolyline = new StructShapePolyline();
shapePolyline.Box = new double[];
shapePolyline.Parts = new List<int>();
shapePolyline.Points = new List<StructShapePoint>();
shapePolyline.Lines = new List<StructShapePoint[]>();
shapePolyline.RecordNumber = br.ReadInt32();
shapePolyline.ContentLength = br.ReadInt32();
shapePolyline.ShapeType = br.ReadInt32();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.Box[] = br.ReadDouble();
shapePolyline.PartsCount = br.ReadInt32();
shapePolyline.PointsCount = br.ReadInt32(); //把每一段线的开始点偏移读进Parts队列
for (int i = ; i < shapePolyline.PartsCount; i++)
{
int tmpPart = br.ReadInt32();
shapePolyline.Parts.Add(tmpPart);
}
//把所有点读进Points队列
for (int i = ; i < shapePolyline.PointsCount; i++)
{
StructShapePoint tmpPoint = new StructShapePoint();
tmpPoint.X = br.ReadDouble();
tmpPoint.Y = br.ReadDouble();
shapePolyline.Points.Add(tmpPoint);
}
//把该线的点读进Lines队列
for (int i = ; i < shapePolyline.PartsCount; i++)
{
int startpoint;
int endpoint; if (i == shapePolyline.PartsCount - )
{
startpoint = (int)shapePolyline.Parts[i];
endpoint = shapePolyline.PointsCount;
}
else
{
startpoint = (int)shapePolyline.Parts[i];
endpoint = (int)shapePolyline.Parts[i + ];
}
StructShapePoint[] shpPointArray = new StructShapePoint[endpoint - startpoint];
for (int j = , k = startpoint; k < endpoint; j++, k++)
{
shpPointArray[j].X = shapePolyline.Points[k].X;
shpPointArray[j].Y = shapePolyline.Points[k].Y;
}
shapePolyline.Lines.Add(shpPointArray);
}
//把该线条加进m_polylines队列
ListPolylines.Add(shapePolyline);
}
}//end of : else if (ShpType == 3)
SetBaseParameter(Xmin, Ymin, Xmax, Ymax);
return true;
}
catch (System.Exception ex)
{
Console.WriteLine("异常:ClassShp.Init()" + ex.ToString());
return false;
}
} //################################################################################
// 把数据写成txt文本
//################################################################################
public void SaveAsTxt()
{
StreamWriter swLine = new StreamWriter(FileName+".txt");
swLine.WriteLine("绘图类型:{0}", ShapeType);
swLine.WriteLine("地图边界:({0}, {1}), ({2}, {3})", Xmin, Ymin, Xmax, Ymax);
swLine.WriteLine("地图大小:{0} * {1}", RawWidth, RawHeight);
swLine.WriteLine("地图中心:({0}, {1})", RawCenterX, RawCenterY); int recordCount = ;
if (ShapeType==)
{
foreach (StructShapePoint p in ListPoints)
{
swLine.WriteLine("点{0}: ({1}, {2})", recordCount, p.X, p.Y);
recordCount++;
}
}
else if (ShapeType== || ShapeType==)
{
foreach (StructShapePolyline p in ListPolylines)
{
for (int i = ; i < p.Lines.Count; i++)
{
swLine.WriteLine("记录内容{0}:########################################################", recordCount, i);
for (int j = ; j < p.Lines[i].Length; j++)
{
StructShapePoint ps = p.Lines[i][j];
swLine.WriteLine("线{0}: ({1}, {2})", j, ps.X, ps.Y);
}
}
recordCount++;
}//end of :foreach
}
swLine.Close();
} //################################################################################
// 把图绘进Bmp中
//################################################################################
public bool DrawBmp(int pmtWidth, int pmtHeight)
{
double screenWidth = RawWidth * Scale;
double screenHeight = RawHeight * Scale; try
{
Bmp = new Bitmap(pmtWidth, pmtHeight);//创建画布
Graphics g = Graphics.FromImage(Bmp); g.TranslateTransform((float), (float)pmtHeight);//变换坐标系,把左下角置为原点
g.ScaleTransform((float), (float)-); if (ShapeType == ) //点类型
{
foreach (StructShapePoint p in ListPoints)
{
PointF pf = new PointF();
double offsetX = CenterX - screenWidth / 2.0;
double offsetY = CenterY - screenHeight / 2.0;
pf.X = (float)((p.X - Xmin) * Scale + offsetX);
pf.Y = (float)((p.Y - Ymin) * Scale + offsetY);
float r = ;
//g.DrawEllipse(ThePen, pf.X - r / 2, pf.Y + r / 2, r * 2, r * 2);//画点
Brush bs = new SolidBrush(Color.Green);//填充的颜色
g.FillEllipse(bs, pf.X - r / , pf.Y + r / , r * , r * );
}
}
else if (ShapeType == 3 || ShapeType == 5) //线类型和面类型是一样的
{
//Console.WriteLine("线类型");
foreach (StructShapePolyline p in ListPolylines)
{
for (int i = ; i < p.Lines.Count; i++)
{
PointF[] pfArray = new PointF[p.Lines[i].Length];
for (int j = ; j < p.Lines[i].Length; j++)
{
StructShapePoint ps = p.Lines[i][j];
double offsetX = CenterX - screenWidth / 2.0;
double offsetY = CenterY - screenHeight / 2.0;
pfArray[j].X = (float)((ps.X - Xmin) * Scale + offsetX);
pfArray[j].Y = (float)((ps.Y - Ymin) * Scale + offsetY);
}
g.DrawLines(ThePen, pfArray);
}
}
} return true;
}
catch (System.Exception ex)
{
Console.WriteLine("异常:ClassShp.drawBmp" + ex.ToString());
return false;
}
}
}
}
在主窗口放置一个pictureBox控件,名为pictureBoxMap.
主函数:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging; namespace SDD
{
public partial class FormMain : Form
{
ClassShp ShapeChina; public FormMain()
{
InitializeComponent(); string mapChinaPathName = new ClassShp(@"D:\map\地图\国界.shp", pictureBoxMap.Width, pictureBoxMap.Height);
pictureBoxMap.Refresh();
}
private void pictureBoxMap_Paint(object sender, PaintEventArgs e)
{
Bitmap bmp = new Bitmap(pictureBoxMap.Width, pictureBoxMap.Height);//创建画布
ShapeChina.DrawBmp(pictureBoxMap.Width, pictureBoxMap.Height);
e.Graphics.DrawImage(ShapeChina.Bmp, , );
}
}
}
shp地图解析(不用AE)的更多相关文章
- 全国SHP地图数据赠送
百度搜索:GIS之家获取全国SHP图层数据的方式:收藏(ArcGIS地图全国电子地图shp格式版本GIS地图数据.GIS开发顺德政府GIS公共服务共享平台),并且截图验证,验证通过后,收下邮箱,我把下 ...
- arcgis将图片转成shp地图
打开arcMap 1.右键[图层]-[属性]-[坐标系]-[地理坐标系]-双击"WGS 1984" 2.右键[图层]-[添加数据],打开图片文件-Band_2 3.右键图片-[属性 ...
- C#读取shapefile文件(不用AE)
1.创建工程文件,选窗体应用程序,命名为:EsriShpReader 2.添加SplitContainer控件到窗体 3.在SplitContainer.panel1中添加两个按钮Button,tex ...
- LocationCoder 地图经纬度解析
LocationCoder 地图经纬度解析 其实,在地图里面将地图解析成有意义的地址,或者把地址转换成有意义的经纬度都是很容易的事情,只是我将其封装了支持KVO,通知中心,block取结果,代理取结果 ...
- 如何使用highmaps制作中国地图
如何使用highmaps制作中国地图 文章目录 Highmaps 所需文件 地图初始化代码 highmaps 渲染讲解 highmaps 中国各城市坐标的json文件 highmaps 线上DEMO ...
- 将AE开发的专题图制作功能发布为WPS
AE开发可以定制化实现ArcGIS的地理处理功能,并实际运用于其他方面的工作,有时候我们还希望将AE开发的功能发布为网络地理信息处理服务(WPS),从而能在Web端更自由便利地调用所需要的地学处理算法 ...
- 使用highmaps制作中国地图
Highmaps 所需文件 http://code.highcharts.com/maps/highmaps.js(地图渲染的核心文件 必须引用)http://code.highcharts.com/ ...
- 使用R画地图数据
用R画地图数据 首先,从这里下载中国地图的GIS数据,这是一个压缩包,完全解压后包含三个文件(bou2_4p.dbf.bou2_4p.shp和bou2_4p.shx),将这三个文件解压到同一个目录下. ...
- 只写104行代码!在nopCommerce中如何实现自动生成网站地图
表告诉我说你不知道nopCommerce是什么.它是目前.NET中最流行的完全开源网上商城,由俄罗斯的团队在2008年开始立项一直开发到现在已经是3.3版本了.代码目前托管在codeplex上,有兴趣 ...
随机推荐
- block的传值简单示例仅供参考,大牛勿喷
#import "ViewController.h" typedef void(^sumBlock)(int s);//声明为一个类型; /** * 用声明的block类型 su ...
- RunJS - 在线编辑、展示、分享、交流你的 JavaScript 代码
发现一个很好玩,很强大的网站 RunJS - 在线编辑.展示.分享.交流你的 JavaScript 代码 http://runjs.cn/ 比如: http://runjs.cn/detail/l ...
- SQL Server 2005中的分区表(二):如何添加、查询、修改分区表中的数据(转)
在创建完分区表后,可以向分区表中直接插入数据,而不用去管它这些数据放在哪个物理上的数据表中.接上篇文章,我们在创建好的分区表中插入几条数据 insert Sale ([Name],[SaleTime] ...
- POJ 2352 【树状数组】
题意: 给了很多星星的坐标,星星的特征值是不比他自己本身高而且不在它右边的星星数. 给定的输入数据是按照y升序排序的,y相同的情况下按照x排列,x和y都是介于0和32000之间的整数.每个坐标最多有一 ...
- Storm实时计算框架的编程模式
storm分布式流式计算框架. nimbus:主进程服务(职责就是任务的分配的,程序的分发) supervisor:工作进程服务(职责就是启动线程池,接受任务,运行任务,报告任务的运行状态) 注意容错 ...
- Ubuntu - Grub2.0修改默认启动项
1. 我的环境: Ubuntu 10.04 2. 关键位置和文件: /boot/grub/grub.cfg 文件: /etc/grub.d/ 目录: /etc/default/grub 文件: ...
- java的String类(一)
final类,无子类. 类内定义了char数组value[],私有,不可修改. String的长度,length(). 判空,isEmpty(). 索引index处的字符,charAt(index). ...
- IIS错误代码表
当用户试图通过 HTTP 或文件传输协议 (FTP) 访问一台正在运行 Internet 信息服务 (IIS) 的服务器上的内容时,IIS 返回一个表示该请求的状态的数字代码.该状态代码记录在 IIS ...
- silverlight,动态数据集合中,移除动态集合自身的内容
在xaml的页面上创建一个x:Name为_list1的ListBox,其中ListBox里面的每一项是ListBoxItem if (_list1.SelectedItem == null)//如果_ ...
- OC基础(7)
封装 继承基本概念 继承相关特性 多态基本概念 多态的实现 *:first-child { margin-top: 0 !important; } body > *:last-child { m ...