GIS基础(转)

1. GIS:你能帮我做什么样

  “GIS是什么样,能干什么?”,我想以此题材或者是疑惑大多数GIS专业学生的题目,现在本来好过多,但在大家上学那会儿,完全是混混沌沌,不了然将来毕业了去干嘛,当人家很诧异地问起协调的业内时,也很难用只言片语跟人家描述清楚,那种学了n年还说不清自己专业的羞愧呐。。。直到后来GoogleMap、GoogleEarth横空出世,当大家发现这玩意儿能在处理器上来看自己家房顶,找到玩转世界这种“君临天下”的觉得的时候,大家到底可以傲娇地说,俺的标准就是做这么些的lol(其实您精通)。

  当大家去查询GIS的定义,一般都会如此介绍——“在电脑软硬件的支撑下,对地理数据举行获取、存储、分析、展现、输出的音信序列。”

  “这GIS不就是用微机做地图呢?”

  “GIS比统计机制图高级,因为咱们有数据库支撑,我们还是可以做空间分析……”

  听起来无所无法的GIS,但在很长日子里其实也只是停留在做出专题图的级差,像图1中的渐变色就很分明的来得出各省的男同胞的平均身高,各位可以很高效地在心底得出自己有木有拖后腿的下结论,再或者可以跟地图交互查询一下属性,压根儿用不到复杂的上空分析。

                                     
  图片 1

                                                                       
   图1 华夏各省男性平均身高

        
这GIS究竟能做怎么着吗?首先就是采访地理音信,人类活动75%都与地理地点有关,比如想和男朋友找个电影院看视频,出差到一个来路不明的城市找旅社,这多少个都是地理消息,通过GIS能使得地把这多少个都存储起来,怎么存呢?excel吗?这怎么和地图关联起来?这是后话,当然那多少个题目不太用大家用户担心,业界大佬们早已定义好了地理信息的各样存储情势,文件或者数据库都得以,我们只要按要求把信息录入就可以了。

        
收集到的地理音信,现在也只是统计机中的一堆表格,这怎么为人们所见到啊?这就是所谓的“可视化”了,各个图片是音讯可视化的产物,这地理音信可视化的产物就是“地图”,当然地图远比GIS出现的要早,这位长辈是GIS首要的喉舌,GIS可以方便地将募集到的新闻在地形图上显得,如图1用深浅变化的水彩表明身材的轻重,假使收集到的音信还有女性的身高,分分钟就可以再做出一幅类似的女性身高图来。而即便你是一个绘制高手,能够在CorelDraw、Illustrator甚至Photoshop中绘制出图1,但却很难再此基础上登时绘制出另一幅女性身高图来。

        
而上空分析其实离大家也并不深切,像群众点评这样的采取已经十分普及,我可以很便宜地找到周边的餐饮店,还有地图导航,都是透过GPS装置收集的你的地理地点然后,在地形图上找到科学的职位展现,再进一步的实现诸如查询检索等职能。

通过近一个半月的上学我们曾经渡过了python基础的级差,前天我们开端上学python网络编程,没有为难知晓的逻辑,更注重的是回忆。

2. 数量:有料才是王道

  大体知道了GIS是何等,大家再来探究下图1是咋做出来的,身高之类的数码很好采访得到,不过地图呢?让我们追根溯源地想一想地图到底是怎么画出来的,在尚未测绘,没有RS,没有GPS的年份,大家的老祖先们就是靠脚步来丈量土地,靠眼睛看来的来手绘地图,而现在RS可以因而卫星来给地球拍照,GPS可以实时定位,即使曾经摆脱了“数据大旨靠走”的时日,可是想赢得数码依旧要花费些代价,大多数地理数据还没有开放需要购买,当然像图1中如此比例尺级别(第4有些我们会研商到)的地图,依旧很容易从网上得到,这大家下载后,就可以在GIS软件中打开,将身高数据录入,从而急迅的做出一幅地图来。

  所谓“巧妇难为无米之炊”,数据才是王道,否则GIS系统就是一个空架子。对于数据而言,GIS有两大基本存储模型,一种是矢量数据模型,一种是栅格数据模型。如图2所示,同样音信的抒发,在左手的矢量数据中,大家看出的是显著的点、线、面的实体,来发挥河流、湖泊、地块这样的消息;而左边的栅格数据中,我们看看的则是一个个的格子,相平等的像元值在地图上显示出相同的颜料,从而也显示出河流、湖泊、地块的造型。虽然都能发挥出同样的信息,可是这二种存储模型是一心两样的,矢量是以目标为单位,我们可以把一个湖泊的面积等性能都存储在该对象中;而用栅格表明的话,湖泊是由一组像元组成的,我们不容许将总体湖泊的面积分别予以每个像元。

                                                       
  图片 2

                                                                     图2
矢量数据模型与栅格数据模型

       
网上公开免费的数目何地可以下到呢?在美利坚同盟国数码的绽开程度仍旧一定高的,像人口普查之类的详实数据完全能够拿走到(http://thistract.com/),另外还有一些网站可以获取数据:

五洲90m分辨率的DEM(高程数据)下载:

http://srtm.csi.cgiar.org/index.asp

Natural Earth提供了举世1:10 000 000、1:50 000 000、1:110 000
000比例尺的矢量和栅格数据下载,格式为ESRI的shp、Geodatabase以及tiff:

http://www.naturalearthdata.com

Bathymetry是大海深度的测量数据,在 British Oceanographic Data Centre
的网站上得以下到全球海洋深度数据:

https://www.bodc.ac.uk/data

Globe land cover facility提供免费卫星图像,如Landsat、 Modis、 Ikonos、
Quickbird等,下载地址:

http://glcf.umiacs.umd.edu/

   对于中国用户,开放的免费数据得到途径有限,国家基础地理新闻主旨揭橥过全国1:400万比例尺的矢量图,详细到县级行政数据。此外,虽然咱们只是需要背景地图展现的话,可以不要获取原始数据,而采纳叠加地形图服务的方法。中国的ArcGIS
Online(http://www.arcgisonline.cn)为中国用户提供了免费的地图服务,我们只需要将其与我们的数据叠加,就能够快速做出一幅地图来,当然这里的地形图服务无法直接举行查询,它的效果类似于背景图片。

 

3. 比例尺:地图的知心爱人

  早在东晋制图学家裴秀就指出“制图六体”的概念:分率、准望、道里、高下、方邪、迂直,首当其冲的分率指的就是比例尺。无论是我们购买的山势图,仍旧我们在软件中出图,都要涉及到比例尺,对于地图而言,比例尺是必不可少的相亲朋友。就像上节中大家关系Natural
Earth提供了举世1:10 000 000的矢量数据下载,这里的1:10 000
000就是比例尺,它的意思是:地图上任意线段长度与它表示的可靠水平距离之比,也就是说尽管地图上两点之间测量的离开为1mm,那么可靠的离开则是10km。

  简单的说,地图都是对具体世界的纸上谈兵缩短,比例尺就表示了抽象的档次。比例尺越小,抽象程度越高,表明的地物就少而简易;比例尺越大,抽象程度低,表明的地物就越详细。如图3所示,同一个湖泊在较大比例地图上以面来代表,能够看看湖泊的大概,而在较小比例尺地形图上就只是以线来代表。这几个对地物举行抽象的过程存在于数据搜集那个环节,对于采集到的数码,在软件中我们是可以兑现比例尺的无极缩放的,这时候改变的就不再是空泛程度,而是显示的地理范围了。

                                               
 图片 3

                                                                    图3
不同比例尺对于地物的虚幻程度

   我国规定1:5千、1:1万、1:2.5万、1:5万、1:10万、1:25万、1:50万、1:100万八种比例尺地形图为国家骨干比例尺地形图。编制那么些地图要么通过全站仪、经纬仪等大地测量的措施,要么通过航摄的措施。因此这里又要引入多少个概念:测图比例尺和航摄比例尺。由于人眼在地图上的分辨率平日为0.1mm,不同比例尺图上0.1mm所表示的可靠距离,称为地形图比例尺的精度,该精度决定了测图比例尺。例如,某工程测量要可以在图上发挥出10cm的精度,则选用的测图比例尺应不低于0.1mm/10cm=1/1000。航摄比例尺与成图比例尺的关联见下表(影像分辨率指的是形象所能识别出的矮小地物单元的轻重)

                                                                       
  表1  成图比例尺与航摄比例尺及印象分辨率关系

成图比例尺

航摄比例尺

影像分辨率(m)

1:500

1:2000-1:3000

0.05

1:1000

1:3500-1:4000

0.1

1:2000

1:6000-1:8000

0.2

1:5000

1:10000-1:20000

0.4-0.8

   通过上表中的相比,大家可以发现成图比例尺基本是航摄比例尺的4倍,为何是4倍,原因是精度决定,4倍内的留影照片就够了,刚好不会冒出罗利(Raleign)克,假若将录像比例尺确定得过小,造成图像模糊不清,甚至出现“苏州克”图案,影响成图质料;反之,将拍摄比例尺确定得太大,“大材小用”造成不必要的资源浪费。

本篇导航:

4.  坐标:究竟有多首要

  很多时候遭逢学员拿来这样的数额,坐标值不得法或者没有坐标系,不可以和另外数据科学的叠加在一起展现,无法设置比例尺,也无从做拓扑检查之类的做事。坐标不得法的由来重要有:在用CAD等软件绘图的时候从不举办好正确的地理坐标系,或者数字化纸质量形图或影象的时候没有留神是否由此配准这一手续;坐标系缺失的事态就更多了,导入数据的时候只导入了坐标值音信,或者数额格式转换的时候忘记了点名坐标系。

  而一个地物怎么样才能正确定位在地球上?答案是没错的坐标值加上坐标单位。让大家暂时丢掉地球是个三维球体,先来成功在平面图上画出一栋房屋的任务,现在晓得房子的多少个拐点坐标(1,1)(3,1)(3,4)(1,4)。首先大家务必要先认同的是坐标原点在什么地方?其次还要有横轴和纵轴以及单位刻度(房子的长宽是米,现在坐标轴的刻度单位也是米),这图4中所示的就是房子应该在的岗位。而地理数据一定也是平等的法则,只但是大地坐标系的定义则是:以参考椭球体(用来模拟地球的细腻球体)中央为原点,本初子午面(大英帝国格林尼治天文台所在位置为本初子午线,即0度经线)为纵轴方向,赤道平面为横轴方向,如图5所示,绿色点的坐标就活该是(50,40),单位为度。

                           
 图片 4

                                                    图4 二维笛卡尔坐标系

                                       
  图片 5

                                                    图5 大地坐标系

  获取科学的地理坐标究竟有多么首要?是不是本身做一幅地图所需的数据必须要明了正确的地理坐标呢?我们通晓获取坐标并不是一件分外容易的业务,草根的法子一般是在GoogleEarth上助长地标,通过KML这种格式导入GIS软件生成矢量图,官方的门径就是通过买进了。但实际某些时候,坐标并不是我们所认为的那么首要,比如我要做景色分析,商讨一个村庄的布局,在此基础上做一些地形图,我想说,其实您真的不必为地理坐标烦扰,找一个航拍图片,没有的话纸质料图也可以,直接在下面描图得到多少,就像时辰候大家大概都撕过课本封面上的晶莹薄膜叠在任何图上描图,原理是相同的,只是你这时获取的坐标是相持坐标罢了,既然自己不需要和此外地图叠加在一起定位,我又何须要关爱地球坐标原点在哪儿吗? 
  

5.  阴影:神马不是浮云

  大家精通地球是一个形态不规则的椭球体,这如若为地球画一张平面画像,这该怎么尽量真实地复发地球的忠实面目呢?前面我们了然到地理坐标系的定义:以球心为坐标原点,东西方向按经度划分为360度,南北方向按纬度划分为180度,也就是大家所说的WGS(大地坐标系)将地物进行复苏,如图6即是按经纬度直接描绘出的世界地图。

                           
  图片 6

                                                             图6
未投影的世界

        
一切看起来都很正规,正如有本书所写“世界是平的”,但我们仔细一看就会发现问题,A1A2期间的相距和B1B2之间的相距在图上看起来是分外的,然则实际,位于不同纬度的如出一辙经度差相对是不等于的,位于赤道上的偏离远比位于两极的要大过多,因而用地点提到的写真格局来做平面地图是不可能很好地发挥距离,方向之间的相对地点关系的,所以大家在制图的时候才要引入投影,即将三维球面显示到平面地图上,对于地图来讲,投影绝对不是浮云。

                           
 图片 7

                                                                图7
Albers投影

  这里我们选用了Albers(等积圆锥投影),世界地图立马显示出不相同的形制,这里A1A2和B1B2之间的距离也发出了变形,因为影子是三维向二维的映照,所以一定会生出变形,大家可以为不同用途的地形图采取相应的黑影情势来保证面积,方向或角度的变形最小。

 

对网络协议和根基没有概念的可以在阅读本文前预习统计机基础3、网络协议:http://www.cnblogs.com/liluning/p/7170799.html

一、客户端/服务器架设

1、C/S结构,即Client/Server(客户端/服务器)结构

2、我们在互联网中处处可见c/s架构比如说浏览器,qq,lol,视频软件。。。

3、我们学习socket就是为着c/s架构的支付


 

二、scoket与网络协议

第一我们需要贯彻网络通信必然需要多网络协议有着深厚的打听。而我们做开发尽管把每一点都搞通晓太过分耗费精力,所以我们才有了scoket

socket是应用层与TCP/IP协议族通信的中档软件抽象层,它是一组接口。在设计形式中,Socket其实就是一个外衣情势,它把纷繁的TCP/IP协议族隐藏在socket接口前面,对用户来说,一组简单的接口就是任何,让Socket去协会数据,以符合指定的商谈。

因而,大家无需深切了然tcp/udp协议,socket已经为我们封装好了,大家只需要遵循socket的规定去编程,写出的次序自然就是遵照tcp/udp标准的

图片 8


 

三、套接字

 套接字起点于 20 世纪 70
年代内布拉斯加大学Berkeley分校版本的 Unix,即人们所说的 BSD
Unix。一初叶,套接字被设计用在同
一台主机上三个应用程序之间的简报。套接字有二种(或者叫做有三个种族),分别是依据文件型的和依据网络型的。

1、基于文件类型的套接字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,四个套接字进程运行在同一机器,可以因此访问同一个文件系统直接完成通信

2、基于网络项目的套接字:AF_INET

还有AF_INET6被用于ipv6,还有部分其它的地方家族,AF_INET是利用最广泛的一个,python襄助很多种地方家族,不过出于咱们只关心网络编程,所以大部分时候我么只行使AF_INET

3、套接字函数的认识

第一我们要了然所有的函数使用都亟待导入socket模块

1)socket()模块

import socket
获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

2)服务端套接字函数

bind()    绑定(主机,端口号)到套接字
listen()  开始TCP监听
accept()  被动接受TCP客户的连接,(阻塞式)等待连接的到来

3)客户端套接字函数

connect()     主动初始化TCP服务器连接
connect_ex()  connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

4)公共用途的套接字函数

recv()            接收TCP数据
send()            发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
sendall()         发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
recvfrom()        接收UDP数据
sendto()          发送UDP数据
getpeername()     连接到当前套接字的远端的地址
getsockname()     当前套接字的地址
getsockopt()      返回指定套接字的参数
setsockopt()      设置指定套接字的参数
close()           关闭套接字

5)面向锁的套接字函数

setblocking()     设置套接字的阻塞与非阻塞模式
settimeout()      设置阻塞套接字操作的超时时间
gettimeout()      得到阻塞套接字操作的超时时间

6)面向文件的套接字函数

fileno()          套接字的文件描述符
makefile()        创建一个与该套接字相关的文件

 

四、基于tcp的套接字代码实现

前方两遍性近二十个函数是不是看蒙蔽了
来看看实际利用其实采用很简单

tcp是基于链接的,必须先启动服务端,然后再开行客户端去链接服务端

tcp服务端

ss = socket()      #创建服务器套接字
ss.bind()      #把地址绑定到套接字
ss.listen()      #监听链接
while True :      #服务器无限循环
    conn,client_addr=ss.accept()      #接受客户端链接
    while True :      #通讯循环
        conn.recv()/cs.send()      #对话(接收与发送)
    conn.close()      #关闭客户端套接字
ss.close()      #关闭服务器套接字(可选)

tcp客户端

cs = socket()    # 创建客户套接字
cs.connect()    # 尝试连接服务器
while True :        # 通讯循环
    cs.send()/cs.recv()    # 对话(发送/接收)
cs.close()            # 关闭客户套接字

1、socket通信流程与打电话流程类似以此为例:

服务端:

import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #买手机
s.bind('127.0.0.1',8080)  #手机插卡
s.listen(5)  #开机

#print('starting...')
conn,addr=s.accept()  #等电话 (链接,客户的的ip和端口组成的元组)
#print(conn,addr)

data=conn.recv(1024)  #接收
print('client data: <%s>' %data)
conn.send(data.upper())  #发送

conn.close()  #挂电话
s.close()  #关机

客户端:

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1',8080)) #绑定手机卡

#发,收消息
phone.send('hello'.encode('utf-8'))
data=phone.recv(1024)
print('server back res:<%s>' %data)

phone.close()

2、加上链接循环与通信循环

服务端:

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.bind(('127.0.0.1',8081)) #绑定手机卡
phone.listen(5) #开机 最多挂起5个服务

print('starting...')
while True: #链接循环
    conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
    print('-------->',conn,client_addr)

    #收,发消息
    while True:#通信循环
        try:
            data=conn.recv(1024)
            if not data:break #针对linux
            print('client data: <%s>' %data)
            conn.send(data.upper())
        except Exception:
            break
    conn.close() #挂电话
phone.close() #关机

客户端(可以有多少个客户端一起链接前边的被挂起前一个断开后立马链接):

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.connect(('127.0.0.1',8081)) #绑定手机卡

#发,收消息
while True:
    msg=input('>>: ').strip()
    if not msg:continue
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)
    print('server back res:<%s>' %data)

phone.close()

3、模拟ssh远程模拟命令

服务端:

import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8082))
phone.listen(5)

print('starting...')
while True:
    conn,client_addr=phone.accept()
    print('-------->',conn,client_addr)

    while True:
        try:
            cmd=conn.recv(1024)
            #if not cmd:break #针对linux
            #执行cmd命令,拿到cmd的结果,结果应该是bytes类型
            #。。。。
            res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            stdout=res.stdout.read()
            stderr=res.stderr.read()

            #发送命令的结果
            conn.send(stdout+stderr)
        except Exception:
            break
    conn.close() #挂电话
phone.close() #关机

客户端:

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
phone.connect(('127.0.0.1',8082))

while True:
    cmd=input('>>: ').strip()
    if not cmd:continue
    phone.send(cmd.encode('utf-8'))
    cmd_res=phone.recv(1024)
    print(cmd_res.decode('gbk'))
phone.close()

 

五、非凡解决(理解)

图片 9

化解措施:

#加入一条socket配置,重用ip和端口

phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))

图片 10图片 11

发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

linux系统方法


 

六、subprocess模块(简单介绍)

同意你去创立一个新的历程让其举行其余的次第,并与它举行通信,获取标准的输入、标准输出、标准错误以及重回码等

Popen类

subprocess模块中定义了一个波普(Pope)n类,通过它可以来创制过程,并与其开展复杂的互相。查看一下它的构造函数:

__init__(self, args, bufsize=0, executable=None, 
stdin=None, stdout=None, stderr=None, preexec_fn=None, 
close_fds=False, shell=False, cwd=None, env=None, 
universal_newlines=False, startupinfo=None, 
creationflags=0)

紧要参数表达: 
args:args should be a string, or a
sequence of program
arguments.也就是说必须是一个字符串或者体系类型(如:字符串、list、元组),用于指定进程的可执行文件及其参数。假使是一个行列类型参数,则连串的率先个要素平时都必须是一个可执行文件的路线。当然也足以使用executeable参数来指定可执行文件的路子。

stdin,stdout,stderr:分别代表程序的专业输入、标准输出、标准错误。有效的值可以是PIPE,存在的文书描述符,存在的文书对象或None,虽然为None需从父进程继续过来,stdout可以是PIPE,表示对子进程创设一个管道,stderr可以是STDOUT,表示专业错误数据应该从应用程序中抓获并视作规范输出流stdout的文书句柄。

shell:一经那个参数被设置为True,程序将经过shell来推行。 
env:它描述的是子进程的环境变量。假如为None,子进程的环境变量将从父进程继续而来。

实例化:

res = subprocess.Popen(r'dir', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website