部署server
[root@ /]# docker-compose up ... Starting server_1 ... Starting server_1 ... done ... server_1 exited with code 0 docker容器执行任务完成后就会处于exited状态
加上 stdin_open: true , tty: true 这两行参数,代码如下,其中 stdin_open 相当于 run 命令中的 -d, 其中 tty 相当于 run 命令中的 -i
# server server: image: mycentos ports: - 8080:8080 links: - mysql:mysql networks: - backend stdin_open: true tty: true
描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
数据范围: 2≤n,m≤10 , 输入的内容只包含 0≤val≤1 输入描述: 输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述: 左上角到右下角的最短路径,格式如样例所示。
示例1 输入:
5 5 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 输出:
一、问题起因 最近做项目时遇到了需要多用户之间通信的问题,涉及到了WebSocket握手请求,以及集群中WebSocket Session共享的问题。
期间我经过了几天的研究,总结出了几个实现分布式WebSocket集群的办法,从zuul到spring cloud gateway的不同尝试。
以下是我的场景描述:
资源 :4台服务器。其中只有一台服务器具备ssl认证域名,一台redis+mysql服务器,两台应用服务器(集群)应用发布限制条件 :由于场景需要,应用场所需要ssl认证的域名才能发布。因此ssl认证的域名服务器用来当api网关,负责https请求与wss(安全认证的ws)连接。俗称https卸载,用户请求https域名服务器(eg:https://oiscircle.com/xxx),但真实访问到的是http+ip地址的形式。只要网关配置高,能handle多个应用需求 :用户登录应用,需要与服务器建立wss连接,不同角色之间可以单发消息,也可以群发消息集群中的应用服务类型 :每个集群实例都负责http无状态请求服务与ws长连接服务 二、系统架构图 在我的实现里,每个应用服务器都负责http and ws请求,其实也可以将ws请求建立的聊天模型单独成立为一个模块。从分布式的角度来看,这两种实现类型差不多,但从实现方便性来说,一个应用服务http+ws请求的方式更为方便,下文会有解释。本文涉及的技术栈:
Eureka 服务发现与注册Redis Session共享Redis 消息订阅Spring BootZuul 网关Spring Cloud Gateway 网关Spring WebSocket 处理长连接Ribbon 负载均衡Netty 多协议NIO网络通信框架Consistent Hash 一致性哈希算法 三、技术可行性分析 下面我将描述session特性,以及根据这些特性列举出n个解决分布式架构中处理ws请求的集群方案:WebSocketSession与HttpSession
在Spring所集成的WebSocket里面,每个ws连接都有一个对应的session:WebSocketSession,在Spring WebSocket中,我们建立ws连接之后可以通过类似这样的方式进行与客户端的通信:
protected void handleTextMessage(WebSocketSession session, TextMessage message) { System.out.println("服务器接收到的消息: "+ message ); //send message to client session.sendMessage(new TextMessage("message")); } 那么问题来了:ws的session无法序列化到redis,因此在集群中,我们无法将所有WebSocketSession都缓存到redis进行session共享。每台服务器都有各自的session。于此相反的是HttpSession,redis可以支持httpsession共享,但是目前没有websocket session共享的方案,因此走redis websocket session共享这条路是行不通的。
有的人可能会想:我可不可以将sessin关键信息缓存到redis,集群中的服务器从redis拿取session关键信息然后重新构建websocket session...我只想说这种方法如果有人能试出来,请告诉我一声... 以上便是websocket session与http session共享的区别:总的来说就是http session共享已经有解决方案了,而且很简单,只要引入相关依赖:spring-session-data-redis和spring-boot-starter-redis。而websocket session共享的方案由于websocket底层实现的方式,我们无法做到真正的websocket session共享。
四、解决方案的演变 Netty与Spring WebSocket 刚开始的时候,我尝试着用netty实现了websocket服务端的搭建。在netty里面,并没有websocket session这样的概念,与其类似的是channel,每一个客户端连接都代表一个channel。前端的ws请求通过netty监听的端口,走websocket协议进行ws握手连接之后,通过一些列的handler(责链模式)进行消息处理。与websocket session类似地,服务端在连接建立后有一个channel,我们可以通过channel进行与客户端的通信。
学习内容: 分别用递归和非递归实现二叉树的先序,中序,后序遍历。 以及层序遍历。
二叉树的创建
先序:头左右
中序:左头右
后序:左右头
层序:按层遍历
要点: 递归方式遍历时,先序是第一次进入函数就打印,先打印的是头结点然后再打印左节点和右节点。中序是第一次回到函数时打印,此时左节点已经打印,当前打印的是头结点,之后再打印右节点。后序是第二次回到函数时打印,此时左右节点都已打印,当前打印的是头结点。
层序遍历用队列实现,先将头结点压入队列,然后出队时打印,先压左再压右。
1 / \ 2 3 / \ / 4 5 6 此树的递归序为:1,2,4,4,4,2,5,5,5,2,1,3,6,6,6,3,3,1
先序:1,2,4,5,3,6
中序:4,2,5,1,6,3
后序:4,5,2,6,3,1
层序:1,2,3,4,5,6
代码: #include <iostream> #include <stack> #include <queue> using namespace std; struct Node { int value; Node *left; Node *right; Node() : value(0), left(nullptr), right(nullptr) {} Node(int x) : value(x), left(nullptr), right(nullptr) {} Node(int x, Node *left, Node *right) : value(x), left(left), right(right) {} }; /* 1 / \ 2 3 / \ / 4 5 6 */ void creatBitree(Node *&node) //传入指针的引用(根节点) { int in; cout << "
前言 在生产环境中,一般一个域名对应一个前端项目,但如果域名紧张,不想浪费二级域名,或者自己的测试项目,完全可以一个域名对应多个前端项目、
以 vue 为例,要实现这一点,需要 vue-router 中的 base 选项助力
2. base 简介 base 选项设置应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"
base 选项的默认值为 “/”,这个代表什么意思呢?
我们知道,无论是开发模式下,还是生产模式下,我们都需要启动一个服务来运行我们的前端项目,如
开发模式下,可能是 http://127.0.0.1:8080生产环境下,可能是 http://www.xxxx.com 这两个服务都映射到了前端项目的根目录,比如此时路由规则中有这么几个规则
const routes = [ { path: '/hot', name: 'hot', component: Hot }, { path: '/local', name: 'local', component: Local }, { path: '/money', name: 'money', component: Money }, { path: '/detail/:id', name: 'detail', component: Detail }, ] 此时,base 选项的值设置为 “/”
那么在地址栏中的路径就是这样的
http://localhost:8080/hot http://localhost:8080/local http://localhost:8080/money http://localhost:8080/detail/5 也就是域名(http://127.
这个错误可能有以下两个原因:
和云端硬盘连接出现了问题,重启一下colab笔记本,并重新装载一下云端硬盘即可解决。有些依赖没有安装 具体步骤
请先确认依赖是否安装完毕,在笔记本中创建一个代码块,并运行以下代码:
(关于Colab的依赖项,可以参考:Colab库及依赖项)
!pip install matplotlib-venn !apt-get -qq install -y libfluidsynth1 # https://pypi.python.org/pypi/libarchive !apt-get -qq install -y libarchive-dev && pip install -U libarchive import libarchive # https://pypi.python.org/pypi/pydot !apt-get -qq install -y graphviz && pip install pydot import pydot !pip install cartopy import cartopy 如果依赖项安装完毕,请参照如下步骤:
重启Colab笔记本添加一个代码块,并运行以下代码: from google.colab import drive drive.mount('/content/drive') 在弹出的页面允许访问(也可能是需要访问系统给出的网址,并复制页面验证码到输入框)运行完毕后即可在笔记本中使用代码直接访问云端硬盘中的文件,在文件树中也会出现自己云端硬盘的文件夹(drive)。如下图:
ps:需要注意的是,云端笔记本中的路径表达式的根路径都是/content/drive, 如果仍然出现错误,需检查路径表达式是否正确。
可以参考以下链接:(对Colab不熟悉的同学可以重点看看第一个官方教程)
5. Colab使用手册
6. Stack Overflow上的解答
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 一、新建项目与保存项目【注意:切勿双击打开样板文件夹作为项目文件使用】 二、创建标高**标高**是用来定义楼层层高及我们生成平面视图;**轴网**是用于我们一个构建的定位,在定位当中轴网确定了一个不可见的一个工作平面;第一步第二步第三步第四步第五步第六步 三、阵列命令:比如注意: 一、新建项目与保存项目 `
【注意:切勿双击打开样板文件夹作为项目文件使用】 选项有一个备份的作用,
备份就是说文件中00010002等等就是一个备份的作用,通常10个就够了。
二、创建标高 标高是用来定义楼层层高及我们生成平面视图; 标高不是说必须作为楼层的一个层高也可以作为一个辅助作用;
轴网是用于我们一个构建的定位,在定位当中轴网确定了一个不可见的一个工作平面; 1.添加标高(标高命令,复制,阵列等修改命令的应用);
2.修改标高(标头,临时尺寸,影响范围);
3.标高属性(实例属性,类型属性);
思考:Revit中为何建议先创建标高再创建轴网?
第一步 标高在立面当中建立的,先去到东立面,在其中我们会发现在原有的基础上它已经在样板当中建立了相应的标高,当选中一个标高之后我们会发现出现一条虚线;
这条虚线作用是标头的对齐线以及一个选择框(鼠标移过去就显示编号,显示两端标高的一个作用);
第二步 当我们选中一个标高后它也会出现临时尺寸,这个尺寸可以直接输入数值进行编辑,这里也可以点生成永久性尺寸标注,那么此时再去点它是无法修改的,如果想要更改需要选中它之后再选中标高才会又变成一个临时尺;
第三步 点中标高之后也会出现一个3D的字样,也就是东南西北是个3D的同时可以看更改之后的效果,当3D关掉之后只更改当前方位立面,其他不同时改变;
第四步 同时图面上有一个锁头图形,这个图形的作用就是锁上是全部标头对其,解锁之后只单独标头移动;复制快捷键与在建筑中创建的标高与原有标高颜色不同;
第五步 我们发现在左边我们在建筑中创建的标高8自动生成楼层平面视图,而标高7因为采用复制的方式属于临时创建所以没有,如果也想要标高7的视图,我们可以去视图工具栏有一个平面视图,单击平面视图我们会发现有一个楼层平面按钮,这个就是用于将复制而来的标高创建成楼层平面的按钮;
第六步 那么,为什么标高2后面直接就是标高7标高8?这其实就是一种排序,你可以人为更改标高数(也可以是英文字母也可以是中文一二等汉字)并且之后再加的标高都会按照你新改的之后由小到大增加标高;
三、阵列命令: 点击标高右键选择重复阵列》修改相应的数值,要再添加几层就在项目数写几》
比如 添加三层每层300米则直接拉到最后一层的高度-900米的位置即可
注意: 此处是不会自动将新加的楼层添加到楼层平面中去的需要自己去视图里面手动添加。
本文主要详细讲述常见的八种排序算法的思想、实现以及复杂度。包括冒泡排序、快速排序、插入排序、希尔排序等等,文章讲解非常详细!
冒泡排序 要点 冒泡排序是一种交换排序。
什么是交换排序呢?
交换排序:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。
算法思想 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢 “浮” 到数列的顶端,故名。
假设有一个大小为 N 的无序序列。冒泡排序就是要每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。
以上图为例,演示一下冒泡排序的实际流程:
假设有一个无序序列 {4. 3. 1. 2, 5}
第一趟排序:通过两两比较,找到第一小的数值 1 ,将其放在序列的第一位。第二趟排序:通过两两比较,找到第二小的数值 2 ,将其放在序列的第二位。第三趟排序:通过两两比较,找到第三小的数值 3 ,将其放在序列的第三位。 至此,所有元素已经有序,排序结束。
要将以上流程转化为代码,我们需要像机器一样去思考,不然编译器可看不懂。
假设要对一个大小为 N 的无序序列进行升序排序(即从小到大)。 每趟排序过程中需要通过比较找到第 i 个小的元素。所以,我们需要一个外部循环,从数组首端 (下标 0) 开始,一直扫描到倒数第二个元素(即下标 N - 2) ,剩下最后一个元素,必然为最大。假设是第 i 趟排序,可知,前 i-1 个元素已经有序。现在要找第 i 个元素,只需从数组末端开始,扫描到第 i 个元素,将它们两两比较即可。 所以,需要一个内部循环,从数组末端开始(下标 N - 1),扫描到 (下标 i + 1)。 核心代码
public void bubbleSort(int[] list) { int temp = 0; // 用来交换的临时数 // 要遍历的次数 for (int i = 0; i < list.
小滴课堂工业级pass云平台项目
lt:less than 小于
le:less than or equal to 小于等于
eq:equal to 等于
ne:not equal to 不等于
ge:greater than or equal to 大于等于
gt:greater than 大于
lq: 是小于等于
Maybatis-Plus lambdaQuery和mapper中EQ、NE、GT、LT、GE、LE的用法及详解
1.等于当前时间
//EQ 就是 EQUAL等于
taskFlowService.lambdaQuery().eq(TaskFlow::getCreateTime,DateUtil.now()) 1
2
2.不等于当前时间
//NE就是 NOT EQUAL不等于
taskFlowService.lambdaQuery().ne(TaskFlow::getCreateTime,DateUtil.now()); 1 2
3.大于当前时间
//GT 就是 GREATER THAN大于
taskFlowService.lambdaQuery().gt(TaskFlow::getCreateTime,DateUtil.now()); 1
2
4.小于当前时间
//LT 就是 LESS THAN小于
taskFlowService.lambdaQuery().lt(TaskFlow::getCreateTime,DateUtil.now()); 1
2
5.大于等于当前时间
//GE 就是 GREATER THAN OR EQUAL 大于等于
taskFlowService.lambdaQuery().ge(TaskFlow::getCreateTime,DateUtil.now()); 1
创建 创建网络
docker network create cassandra 启动一个临时的cassandra(注意,只是测试,关闭docker后cassandra容器会删除)
docker run --rm -d --name cassandra --hostname cassandra --network cassandra cassandra 连接cassandra
# 直接进docker连接 docker exec -it cassandra sh # 无用户名 docker run -it --network cassandra --rm cassandra cqlsh cassandra # 使用用户名 docker run -it --network cassandra --rm cassandra cqlsh -u cassandra -pcassandra cassandra 使用 cassandra语法与sql很像
# 查看keyspaces(相当于数据库) describe keyspaces; # 创建keyspaces CREATE KEYSPACE IF NOT EXISTS mycasdb WITH REPLICATION = {'class': 'SimpleStrategy','replication_factor':3}; # ---- 注意class,replication_factor参数 # 使用数据库 use mycasdb ; #创建表 CREATE TABLE user (id int,user_name varchar,PRIMARY KEY (id)); #查看所有表 DESCRIBE TABLES ; #插入数据 INSERT INTO user (id,user_name) VALUES (1,'sxj'); #查看数据 SELECT * FROM user ; #删除数据 delete from user where id=1; 参考:
根据商品的父类目id查询子类目id信息,通常用获取各级类目对应关系,以便将推广商品归类。业务参数parentId、grade都输入0可查询所有一级类目ID,之后再用其作为parentId查询其子类目。
1、注册共京荣开放平台账号
http://interface.mkstone.club/#/
2、获取接口秘钥apikey
appkey是注册我们平台获得的,注册就可以用了。
提示appkey未通过验证的,仔细看接口说明的请求参数类型!!
全站接口都支持https, 自行切换即可
|基本信息
接口状态:已完成
接口URL: http://api, mkstone. club/api/v1/open/jd/getShopType?content=3645133&appkey=的appkey
*请求方式: GET
|响应示例
正确响应示例
“Code”: 1, “Data”: “1”,“Msg”: “获取成功”,
“Remain”: “13277”
参数说明
参数说明
参数名
示例值
参数描述
Code
1
Data
1
// 0自营。1拼购。2专营店。3旗舰店。4专卖店 5.馆类 6 .其他
Msg
获取成功
Remain
13277
1、QT中debug变为release,点击运行 2、exe文件为点击运行生成的运行代码(生成路径如下图),可自己修改路径 3、新建一个文件夹,把exe文件拷贝到文件夹下(*exe文件如上图) 4、在电脑上搜索QT 5.9.9(winGW)打开进入新建文件夹下
5、运行windeployqt 代码文件名 ,就会在新建文件夹下生成环境,如下图
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言一、Revit功能特点概述:二、Revit基础术语:三、Revit划分:【重点:实例属性和类型属性】: 四、Revit常用的四种文件格式:五、基本页面展示:菜单栏自定义快速访问工具简单工具栏应用 前言 传统工作方式:点到点,分段,信息重叠;BIM工作方式:点到中心,连续,信息唯一;BIM在设计中的价值:提供更深设计视野,更多附加设计功能;
提示:以下是本篇文章正文内容,可供参考
一、Revit功能特点概述: Revit是一款三维信息化参数化设计软件,是有效创建信息化建筑模型BIM的设计工具。
1.各构件之间的关联平,立,剖面明细表双向关联,一处修改,处处更新;
2.自动统计:门窗表,建筑面积,容积率等经济指标;
3.自动生成各立面,各角度剖面视图,精准迅速;
4.异型墙体,幕墙轻松创建;
5.与AutoCAD无缝衔接,二维三维完美过度;
6.轻松布图,随意修改;
7.设计变更,一步到位,无需交付;
8.集成优异渲染,漫游功能,全方位展示您的设计;
9.体量功能让您的初步设计随心所欲;
10.轻松提高您的设计质量和设计效率;
11.自动避免低级错误;
二、Revit基础术语: 1.Revit图元,是Revit中的基本对象,是包含数据模型和行为模型的复合结构;
2.数据模型:几何数据信息和数据;
3.行为模型:变更管理;
4.图元包含三种类型的图元:模型图元-主体+模型构件,基准图元,视图专有图元;
三、Revit划分: Revit是按照类别,族,类型和实例对图元进行划分的;
1.类别:是用于建筑设计建模或归档的一组图元,描述不同的建筑结构;
2.族(类别的子类别):是类别中具有相同参数(属性)定义的图元;
3.类型:是特定尺寸的族或是样式;
4.实例:是放置在项目中的具体图元。
【重点:实例属性和类型属性】: 1.实例属性:仅影响选定的图元或要放置的图元;
2.类型属性:是族中许多图元的公共属性。
四、Revit常用的四种文件格式: 1.rvt格式:项目文件格式;
2.rte格式:样板文件格式;
3.rfa格式:外部族文件格式;
4.rft外部族样板文件格式;
五、基本页面展示: 菜单栏 自定义快速访问工具 简单工具栏应用
前言 想要学习好安全知识的话,就需要各种各样的实战。而Vulhub里就有许多已经搭好的靶场,通过Docker容器就可以进行快速的搭建练习。下面我就通过CentOS 7来演示如何搭建Vulhub靶场。
如果你是在其它的Linux系统(如Ubuntu),则将下面的yum命令改成相应的apt(或apt-get)来进行安装。同样也是可以完成安装的。
开始搭建 由于我的CentOS 7是最小化安装的,直接在虚拟机里打命令会很麻烦。所以这里我先用物理机SSH远程链接一下(这里你可以用其它的SSH链接工具,比如XShell等)
1. 更新软件:
这一步可能会有点慢,但最好还是更新一下。以免后面会遇到奇奇怪怪的BUG
yum -y update 2. 安装一些必要的包
yum install -y yum-utils device-mapper-persistent-data lvm2 --skip-broken 3. 首次安装设置 Docker 仓库:
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo yum makecache fast 4. 安装Docker
yum install -y docker-ce 5. 查看版本,是否安装成功。
docker -v 6. 启动并设置为开机自启
systemctl start docker # 启动docker容器 systemctl enable docker # 设置为开机自启动容器 systemctl status docker # 查看容器状态 7. 开发所有端口(关闭防火墙)
systemctl stop firewalld # 关闭防火墙 systemctl disable firewalld # 禁止开机启动防火墙 systemctl status firewalld # 查看防火墙状态 8.
hive优化: 一、需要调优的几个方面 1.HIVE语句执行不了
2.HIVE查询语句,在集群中执行时,数据无法落地
HIVE执行时,一开始语句检查没有问题,生成了多个JOB,
并且一开JOB中的Map 及 Reduce 正常运行,之后便报异常包括 OOM 异常等
3.HIVE查询语句,执行时,Map或者Reduce端数据处理异常慢,导致整个执行效率低
二、调优方式: 1.分区、分桶 (1)分区的好处,在扫描表时,会根据查询语句中的过滤条件,将固定分区中的数据加载至内存中避免了表的全表扫描。
(2)分桶好处? 在获取数据时,根据查询的数据,进行做hash操作,将需要获取的数据指定到具体的桶中,这样只获取固定部分桶数据,减小了数据的加载量
2.使用外部表 外部表和普通表的区别? 删除数据时,外部表不会将HDFS中对应表路径中的数据删除
3.选择适当的文件压缩格式 (1)对于刚采集过的源数据,需要用TextFile格式进行保存,需要保证源数据的格式及内容和原先一致
(2)对于处理过的数据,一般对数据进行压缩保存(需要考虑实际情况)
4.命名要规范 创建表时,需要遵守:
如果数据存储在dwd中那么建表时需要将 dwd 放至 表的开端
同时后面的业务名称需要和库名用 _ 进行分隔
5.数据分层,表分离,但是也不要分的太散 (1)数据分层:
将不同类型的数据,应当存储在不同库中,
比如 维度表 应当存储在 维度库 、原始数据应当存储在ODS库中专门做管理
(2)表分离:
在实际业务过程中,有一些表的维度比较大,单个表的存储压力大
同时数据读取时,拉去的数据内容比较多,但是所需要的字段较少,浪费计算资源
可以将表中相同类型的信息切分至多个表中,根据实际业务需要进行读取数据
如果分的太散,那么也会造成数据冗余,并且加载表过多,计算慢
6.分区裁剪 where过滤,先过滤,后join (1)针对分区表数据,可以通过where条件进行过滤数据,之后再进行其他操作
(2)适当的使用一些子查询,将子查询中的数据进行初步过滤,然后再与其他表数据进行关联
7.mapjoin(1.2以后自动默认启动mapjoin) (1)MapJoin顾名思义,就是在Map阶段进行表之间的连接,map阶段直接拿另外一个表的数据和内存中表数据做匹配。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。通常用于一个很小的表和一个大表进行join的场景。
(2)MaP JOIN 相关设置:
1)设置自动选择Mapjoin
set hive.auto.convert.join = true; 默认为true
2)大表小表的阈值设置(默认25M以下认为是小表):
set hive.mapjoin.smalltable.filesize = 25000000;
8.分区分桶,合并小文件 (1)为什么小文件需要合并?
小文件过多,MR处理数据时,会产生多个MapTask,然而每个MapTask处理的数据量很少,
那么导致MapTask启动时间大于执行时间,整体任务时间消耗较大
准备数据: 对已经反演出地表温度的tif影像数据,利用自然断点法对其进行分级,得到具有不同地温等级分类的栅格影像数据。
一、计算各个地温等级的重心坐标 ArcToolbox——Spatial Analyst——区域分析——以表格显示分区几何统计
利用该工具获得各个地温等级的几何数据:面积、周长、重心的XY坐标等数据。
二、将XY坐标导入到地图中 首先将获得的XY坐标数据处理到excel表格中,不同年份同一地温等级数据放在同一张表格中。如图所示:
然后将.xlsx文件另存为.csv文件。
将.csv文件添加到地图中:
添加进地图之后,就会在地图中显示出来,可以将其导出为shp文件:
此时就可以在地图中看到不同年份同一温度等级的重心转移轨迹。
链表的概念和结构 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
结构:实际中链表的结构非常多样,以下情况组合起来就有8种链表结构。
(1)单向、双向
(2)带头、不带头
(3)循环、非循环
本篇主要详解带头双向循环链表,结构如图:
带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。
链表的实现 首先在头文件中定义结构体和提供接口:
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> typedef int LTDataType; typedef struct ListNode { struct ListNode* next; struct ListNode* prev; LTDataType data; }ListNode; void ListPrint(ListNode* phead);//打印链表 ListNode* BuyListNode(LTDataType x);//开辟新节点 ListNode* ListInit();//初始化哨兵位 void ListPushBack(ListNode* phead, LTDataType x);//尾插,只要不改变头指针的内容,就不用传二级指针 void ListPushFront(ListNode* phead, LTDataType x);//头插 void ListPopBack(ListNode* phead);//尾删 void ListPopFront(ListNode* phead);//头删 ListNode* ListFind(ListNode* phead, LTDataType x);//查找 void ListInsert(ListNode* pos, LTDataType x);//pos位置前插 void ListErase(ListNode* pos);//pos位置删除 其次在源文件中实现接口功能:
根据报错信息,问题显示为空指针异常,问题出现在GetAllUser类中
package controller; import bean.User; import service.UserService; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class GetAllUser extends HttpServlet { private UserService userService; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<User> list=userService.getAllUsers(); if(list!=null){ request.setAttribute("users",list); request.getRequestDispatcher("/user/users.jsp").forward(request,response); }else { System.out.println("查询用户失败"); } } } 观察到16行使用了userService对象,但是在创建对象那里,对象还是显示灰的。
这里发现是与后面学习到的注解发生了混淆。
解决办法:
1、在创建对象时添加注解
2、在对象向后添加new UserService()
重新运行,完美解决!!!!
提前安装好虚拟机软件,我用的是VM workstations pro 16,网上自行下载安装,ubuntu版本是18.04.6 LTS,网上教程很多
一、更换清华镜像源提升下载速度 如何查找对应系统版本的清华镜像源并修改镜像源
提示:如果source.list文本是only read 无法修改,可以通过将修改镜像源前的所有指令加上sudo提升权限。版本错误的镜像源有可能导致链接失败,所以一定要找到系统版本的镜像源。
#找到/etc/apt/sources.list,先备份source.list 再进行指令操作 sudo gedit /etc/apt/sources.list #删掉原来的,增加新的且保存后在进行更新源 sudo apt-get update 二、下载并安装GNU radio 直接使用指令安装,无需下载安装包压缩文件,此时默认安装的是3.7.11版本的,无需再安装其他依赖,一般不会报错,如果因为网速问题失败可以重新输入指令下载
sudo apt-get install gnuradio 三、安装Python 默认安装2.7.17,后续安装过程中不知道为什么也会安装Python3的版本,暂且不用管他
sudo apt-get install python 四、安装pip 默认是pip2,后续可通过pip install xxx 安装一些组件
sudo apt-get install python-pip 五、安装cmake sudo apt-get install cmake 六、安装gr-mediatools和gr-mapper GitHub上下载
gr-mediatools
gr-mapper
或者
git clone https://github.com/osh/gr-mediatools.git git clone https://github.com/gr-vt/gr-mapper.git #该方法需要提前安装好git组件,不然无法通过git安装 解压到home后分别是
在gr-mediatools的lib文件夹中找到mediatools_audiosource_impl.cc文件中91行
找到d_frame = avcodec_alloc_frame();
改成d_frame = av_frame_alloc();
并执行指令sudo apt-get install libavcodec-dev libavformat-dev
本篇推文将为大家介绍如何基于空间句法分析城市道路的可达性,相信大家已经看过小编之前的一篇推文《ArcGIS交通可达性分析》,那一篇文章主要基于OD成本矩阵来分析道路可达性。而本文介绍的空间句法更强调空间关系,将人的行为与空间组合模式紧密结合起来,这也是为什么空间句法能够成为空间结构分析、城市形态学等最重要的分析理论与方法之一的原因。
知识课堂
要运用空间句法来分析城市道路的可达性,首先需要理解几个名词:
(1)空间句法:空间句法是20世纪70年代由英国学者比尔·希列尔提出的,用于描述和分析空间关系的数学方法。基本原理是对空间进行尺度划分和空间分割,以数学拓扑关系来描述空间之间的定量关系,并以此探究人类活动行为与空间形态之间的联系,解读城市空间形态对人类空间行为的影响方式与程度。
(2)整合度:整合度( Integration ),亦叫集成度,是指空间系统中某一元素与其他元素之间的集聚或离散程度,衡量了一个空间作为目的地吸引到达交通的能力,反映了该空间在整个系统中的中心性。整合度越高的空间,可达性越高,中心性越强,越容易集聚人流。整合度可分为全局整合度和局部整合度。
(3)选择度:选择度( Choice )是指空间系统中某一元素作为两个节点之间最短拓扑距离的频率,考察空间单元作为出行最短路径所具备的优势,反映了空间被穿行的可能性,选择度越高的空间,则更有可能被人流穿行,所以选择度也叫穿行度。
(4)连接值:连接值(Connectivity),表示系统中某个空间相交的空间数。
(5)控制值:控制值(Control),表示某一空间与之相交的空间的控制程度,数值上等于与之相邻的空间的连接值的倒数之和
(6)深度值:深度值(Depth),表示某一空间到达其它空间所需经过的最小连接数。
操作步骤
准备数据:osm路网数据
涉及软件:depthmap、ArcGIS或CAD
Depthmap安装包:
百度云链接:https://pan.baidu.com/s/15eamb4u_-bKZeytF2ctEsg?pwd=njra
提取码:njra
>>1. 路网数据预处理
在ArcGIS中对osm路网数据进行预处理,如果有CAD道路文件也行。具体步骤参考往期推文《osm道路网络构建》。
处理好后,将路网图层另存为DXF格式的文件(depthmap支持格式),CAD中也是同理另存为DXF文件就行。
>>2. 构建轴线模型
打开depthmap软件,新建一个工作空间,点击Map下的import将我们处理好的道路DXF文件加载进工作空间。小编提前在ArcGIS中将路网已处理好,注意,一定要删除一些零星的道路,否则对结果影响会非常大。
加载好数据后,选择Map下的Convert Drawing Map功能,在弹出的对话框中,将新地图类型设置为Axial Map,点击OK后会自动生成轴线模型。其中Connectivity表示的是每条道路的连通性,也就是连接值。
>>3. 轴线分析
选择Tool下的Axial/Convex/Pesh,点击Run Graph Analysis,打开参数设置对话框,首先要设置的是搜索半径,这里的搜索半径是一种抽象的表达,对于不同的出行方式(步行、车行),不同搜索半径下的分析结果可以抽象反映出人们对不同出行方式下城市空间形态的认知。即当搜索半径为n时,即所有空间都纳入计算,得到的空间参数可表达车行状态下的空间认知,如全局整合度,这时反映出的是整体的道路可达性;相应的,不同搜索半径下的道路可达性在空间分布上也有所差异。其他的可以默认,当然也可以对计算进行加权,就在最后一个勾选框中可以选择连接度、线长度等参数作为权重。设置好后点击OK,稍等片刻即可看见分析结果。
>>4. 结果分析
运行完后,如果结果中Node Count是这个熊样子(一片红色,其中有零星几条蓝色线),说明这几条蓝色线与整个路网不通,这是我们需要返回到数据处理的步骤将这几条蓝色线删掉或者将它们与路网连通。
如果Node Count是绿油油的一片,说明整个路网都是连通的,这时可以对结果进行解读。
integration[HH]结果中,越接近红色表示整合度越高,越接近蓝色表示整合度越低,整合度越高的地方道路可达性越高,因此从图中可以看出,全局整合度下,路网中间的可达性明显高于周边。
而在r=3的情况下,可反映出局部可达性的情况。
选择度则反映了空间被穿行的可能性,选择度越高的空间,则更有可能被人流穿行,图中可以看出,城市中的主干道、中轴线、环线等道路更容易被人们选择。
深度值反映了某一空间到达其它空间所需经过的最小连接数,可以看出越是道路复杂的地方深度值越高,当然这也有可能是我们没有剔除一些影响分析结果的道路,比如人行道、小径等,导致不同尺度的道路都有。
其他指标小伙伴们可以尝试着解读一下,基本上顾名思义,仔细瞅一瞅基本上能看懂
结 语
感谢观看,多多支持,下期再见,点个赞呗!
往期精彩推荐
地形图制作
常用标注技巧
交通可达性分析
设施服务区分析
人口重心迁移地图
ArcGIS制图之桂林山水
扫描二维码获取
更多精彩
凌晨GIS