QGis二次开发 -- 源码编译终极篇

2023-11-19

由于是开源软件,QGis版本迭代比较快,在保持long term release版本的基础上,每个月都会有一个monthly release的新版本发布。源码工程变化快速,给想要上手编译开发的新人朋友带来了一些困惑。

我之前分别写过QGis1.8版本和QGis2.9版本的源码编译指南,我相信还是帮助到了一部分人。但是现在回过头来看,文章中用到的QGis版本又过时了。

显然,我写博客的速度赶不及QGis大大小小的版本发布速度,也没有必要每一个版本,都来写一遍编译指南,这是很笨拙的做法。况且,我发现,有很大一部分朋友在向我提问题的时候,他们是并没有仔仔细细地把博客内容学习过的,大多数是走马观花。还有一部分朋友确实是学习过博客内容了,并且一步一步依照准则进行,但是一旦遇到点错误,就不知所措,急病乱投医。

俗话说,授人以鱼不如授人以渔。这次我想抛开QGis的任何一个特定版本,跟大家谈谈源码编译的根本方法,结合我之前写的两篇QGis的编译指南,希望能够就此终结源码编译的噩梦。

注意:
本文只讲工程组织的一些原理,如果需要具体的编译操作,请移步关于QGis1.8二次开发的环境配置 以及 QGis2.9在windows下的编译以及二次开发包下载

写在前面的一点忠告

1. 不要轻易尝试用最新版本的Qt进行编译

截止本文撰写的时间,QGis3.0还未正式发布,到那以前,QGis对于Qt5.x的支持都不会非常好。即使支持,也并没有真正用到Qt5的新特性。目前Qt5.5以下的版本,都有成功编译的例子,但更新的版本就很难了。所以,新版本,有风险。
当你想要用最新版本的Qt进行QGis编译时,先想一想,你是否真的需要最新版的功能?举个最简单的例子,你真的需要Qt Quick吗?或者,你知道Qt Quick吗?

2. 不要低估C++的难度,但也不要过分高估C++带来的阻碍

我在这里必须要单独说明这一点,很多朋友误以为C++如同C#、Python那般上手就能看懂,熟悉一下就能运用自如,这是非常错误的,尤其是你现在要自己去研究QGis这般庞大的C++源码工程的时候。记住这句话,当你看不懂编译器出错信息,不知道是哪里出问题的时候,只是因为你不懂C++。
C++是一门博大精深的语言,它的困难在于自身的灵活性,想要精通它并非一朝一夕的功夫。
然而,就我们编译QGis源码,并用它进行二次开发而言,你需要越过的C++门槛其实并不高。你只需要把基本的概念、编译链接流程等理解清楚,就足够了。

3.多在自己身上找原因

这个不用细说,只是作为提醒,不要抱怨别人的方法不行,不要责怪自己的电脑不行,更不要去怀疑自己的操作系统出了故障,大多数时候编译不成功,都是你自己的原因。

原理

源码工程的编译过程,实际上,就是将依赖库与源代码连接起来的过程。

从github下载到QGis的源码后,我们会看到如下图的文件结构:

这里写图片描述

我们来解释一下这里面的文件夹的用途。

文件名 说明
ci
cmake 工程组织说明文件,主要是依赖库的配置说明
cmake_templates cmake模板文件
debian Linux操作系统所需
doc 帮助文档
!18n 翻译所需文件
images 图片资源文件
mac 苹果Mac操作系统所需
ms-windows 微软Windows操作系统所需
postinstall 软件安装完成之后执行的脚本操作
python python脚本支持
resources 各种资源、配置文件
rpm 默认配置文件
scripts 各种脚本
src 源代码,这个是我们关注的重点
tests 各种测试代码
tools 目前这里面只有一个Qt3迁移到Qt4的工具

并且,在这一级目录下面,有一个非常重要的文件“CMakeLists.txt”,它定义了源码工程如何进行编译。这个文件代码很长,梳理一下,删掉不必要的部分,结构大致可以表示为下面这样。(请务必读一下下面的代码,关键地方我都注释在了代码里面

##############################################################
# 编译版本设置
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
……

# Note the version no is Mmmpp for Major/minor/patch, 0-padded, thus '10100' for 1.1.0
MATH(EXPR QGIS_VERSION_INT "${CPACK_PACKAGE_VERSION_MAJOR}*10000+${CPACK_PACKAGE_VERSION_MINOR}*100+${CPACK_PACKAGE_VERSION_PATCH}")
MESSAGE(STATUS "QGIS version: ${COMPLETE_VERSION} ${RELEASE_NAME} (${QGIS_VERSION_INT})")

#############################################################
# CMake设置
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6) # CMake最低要求
……

# 配置GRASS插件
FOREACH (GRASS_SEARCH_VERSION 6 7)
  ……

# 下面是各种编译选项
SET (WITH_DESKTOP TRUE CACHE BOOL "Determines whether QGIS desktop should be built")
SET (WITH_SERVER FALSE CACHE BOOL "Determines whether QGIS server should be built")
……

SET (WITH_CUSTOM_WIDGETS FALSE CACHE BOOL "Determines whether QGIS custom widgets for Qt Designer should be built")

SET (WITH_ASTYLE FALSE CACHE BOOL "If you plan to contribute you should reindent with scripts/prepare-commit.sh (using 'our' astyle)")

SET (WITH_POSTGRESQL TRUE CACHE BOOL "Determines whether POSTGRESQL support should be built")
……

SET (WITH_INTERNAL_QEXTSERIALPORT TRUE CACHE BOOL "Use internal build of Qextserialport")

SET (WITH_QSPATIALITE FALSE CACHE BOOL "Determines whether QSPATIALITE sql driver should be built")

SET (WITH_ORACLE FALSE CACHE BOOL "Determines whether Oracle support should be built")
……

# 如果你需要Python支持,关注这一块
SET (WITH_BINDINGS TRUE CACHE BOOL "Determines whether python bindings should be built")
IF (WITH_BINDINGS)
  ……
ENDIF (WITH_BINDINGS)

# Android移动端支持
IF (ANDROID)
    SET (DEFAULT_WITH_QTMOBILITY TRUE)
ELSE (ANDROID)
    SET (DEFAULT_WITH_QTMOBILITY FALSE)
ENDIF (ANDROID)
SET (WITH_QTMOBILITY ${DEFAULT_WITH_QTMOBILITY} CACHE BOOL "Determines if QtMobility related code should be build (for example internal GPS)")

# globe三维支持
SET (WITH_GLOBE FALSE CACHE BOOL "Determines whether Globe plugin should be built")
……

SET (PEDANTIC TRUE CACHE BOOL "Determines if we should compile in pedantic mode.")
SET (ENABLE_TESTS TRUE CACHE BOOL "Build unit tests?")
SET (ENABLE_COVERAGE FALSE CACHE BOOL "Perform coverage tests?")
SET (GENERATE_COVERAGE_DOCS FALSE CACHE BOOL "Generate coverage docs (requires lcov)?")

# hide this variable because building of python bindings might fail
# if set to other directory than expected
MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH)

# 这里是指定编译器类型
IF (MSVC AND CMAKE_GENERATOR MATCHES "NMake")
  # following variable is also used in qgsconfig.h
  SET (USING_NMAKE TRUE)
ENDIF (MSVC AND CMAKE_GENERATOR MATCHES "NMake")

#############################################################
# 这里是Flex和Bison

INCLUDE(Flex)

FIND_FLEX()

IF (NOT FLEX_EXECUTABLE)
  MESSAGE(FATAL_ERROR "Couldn't find Flex")
ENDIF (NOT FLEX_EXECUTABLE)

INCLUDE(Bison)

FIND_BISON()

IF (NOT BISON_EXECUTABLE)
  MESSAGE(FATAL_ERROR "Couldn't find Bison")
ENDIF (NOT BISON_EXECUTABLE)

#############################################################
# 下面就开始找依赖库了

IF(NOT WIN32 AND NOT ANDROID)
  ……

# 必须要的依赖库
FIND_PACKAGE(Proj)
FIND_PACKAGE(GEOS)
FIND_PACKAGE(GDAL)
FIND_PACKAGE(Expat REQUIRED)
FIND_PACKAGE(Spatialindex REQUIRED)
FIND_PACKAGE(Qwt REQUIRED)

IF (WITH_INTERNAL_QEXTSERIALPORT)
  SET(QEXTSERIALPORT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/core/gps/qextserialport)
ELSE (WITH_INTERNAL_QEXTSERIALPORT)
  FIND_PACKAGE(Qextserialport REQUIRED)
ENDIF(WITH_INTERNAL_QEXTSERIALPORT)

FIND_PACKAGE(Sqlite3)
IF (NOT SQLITE3_FOUND)
  MESSAGE (SEND_ERROR "sqlite3 dependency was not found!")
ENDIF (NOT SQLITE3_FOUND)

# 可选的依赖库
IF (WITH_POSTGRESQL)
  FIND_PACKAGE(Postgres) # PostgreSQL provider
ENDIF (WITH_POSTGRESQL)

FIND_PACKAGE(SpatiaLite REQUIRED)

# spatialite的版本处理
IF(SPATIALITE_VERSION_GE_4_0_0)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_VERSION_GE_4_0_0")
ENDIF(SPATIALITE_VERSION_GE_4_0_0)
IF(SPATIALITE_VERSION_G_4_1_1)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_VERSION_G_4_1_1")
ENDIF(SPATIALITE_VERSION_G_4_1_1)
IF(SPATIALITE_HAS_INIT_EX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSPATIALITE_HAS_INIT_EX")
ENDIF(SPATIALITE_HAS_INIT_EX)

IF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)
  MESSAGE (SEND_ERROR "Some dependencies were not found! Proj: ${PROJ_FOUND}, Geos: ${GEOS_FOUND}, GDAL: ${GDAL_FOUND}")
ENDIF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND)

IF (POSTGRES_FOUND)
  # following variable is used in qgsconfig.h
  SET (HAVE_POSTGRESQL TRUE)
ENDIF (POSTGRES_FOUND)

SET (WITH_QTWEBKIT TRUE CACHE INTERNAL "Enable QtWebkit support")
IF (WITH_QTWEBKIT)
  ADD_DEFINITIONS(-DWITH_QTWEBKIT)
ENDIF(WITH_QTWEBKIT)
#############################################################
# 找Qt4,如果设置了ENABLE_QT5会尝试去找Qt5,需要用Qt5编译的,关注这里的详细代码
SET(QT_MIN_VERSION 4.8.0)
SET (ENABLE_QT5 FALSE CACHE BOOL "If enabled will try to find Qt5 before looking for Qt4")
IF (ENABLE_QT5)
  ……

# 下面是模型测试
SET(ENABLE_MODELTEST FALSE CACHE BOOL "Enable QT ModelTest (not for production)")

IF (ENABLE_TESTS)
  ……

#############################################################
# C++11的支持
# enable use of c++11 features where available
# full c++11 support in clang 3.3+: http://clang.llvm.org/cxx_status.html
# for Mac, this is probably Apple LLVM 4.2 (based on LLVM 3.2svn, in XCode 4.6+)
#   or definitely Apple LLVM 5.0 (based on LLVM 3.3svn, in Xcode 5+):
#   https://gist.github.com/yamaya/2924292

IF (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
  IF (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
    SET(USE_CXX_11 TRUE)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  ENDIF()
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  IF ((NOT APPLE AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "3.2")
       OR (APPLE AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.1"))
    SET(USE_CXX_11 TRUE)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-error=c++11-narrowing")
  ENDIF()
ELSEIF (MSVC AND MSVC_VERSION GREATER 1600)
  SET(USE_CXX_11 TRUE)
ELSE()
  SET(USE_CXX_11 FALSE)
ENDIF()

#allow override keyword if available
IF (NOT USE_CXX_11)
  ADD_DEFINITIONS("-Doverride=")
  ADD_DEFINITIONS("-Dnoexcept=")
  ADD_DEFINITIONS("-Dnullptr=0")
ENDIF()


#############################################################
# 设置警告信息可用

IF (PEDANTIC)
  MESSAGE (STATUS "Pedantic compiler settings enabled")
  IF(MSVC)
    ……

    # disable warnings
    SET(_warnings "${_warnings} /wd4100 ")  # unused formal parameters
   ……

ENDIF (PEDANTIC)

IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  ……

IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
 ……

IF (CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
  ……

IF(MSVC)
  ……

IF(ENABLE_COVERAGE)
  ……

#############################################################
# 操作系统环境指定的一些配置

IF (WIN32)
  ……

  IF (MSVC)
    ……

  IF (APPLE)
    ……

ENDIF (WIN32)

IF (ANDROID)
    ……

# 看一看这里,是配置预编译器选项需要的设置
ADD_DEFINITIONS("-DCORE_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DGUI_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DPYTHON_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DANALYSIS_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DAPP_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DCUSTOMWIDGETS_EXPORT=${DLLIMPORT}")
ADD_DEFINITIONS("-DSERVER_EXPORT=${DLLIMPORT}")

#############################################################
# 用户可以指定的一些QGIS配置,主要针对安装好的应用程序
# user-changeable settings which can be used to customize
# layout of QGIS installation
# (default values are platform-specific)

SET (QGIS_BIN_SUBDIR     ${DEFAULT_BIN_SUBDIR}     CACHE STRING "Subdirectory where executables will be installed")
……


#############################################################
# Python的一些依赖

SET (ENABLE_PYTHON3 ${ENABLE_QT5} CACHE BOOL "If enabled will try to find Python 3 before looking for Python 2")
IF(ENABLE_PYTHON3)
  SET(PYTHON_VER 3 CACHE STRING "Python version")
ELSE(ENABLE_PYTHON3)
  SET(PYTHON_VER 2.7 CACHE STRING "Python version")
ENDIF(ENABLE_PYTHON3)

FIND_PACKAGE(PythonInterp ${PYTHON_VER} REQUIRED)

#############################################################
# Python bindings

IF (WITH_BINDINGS)
  ……

#############################################################
# create qgsconfig.h
# installed with app target

CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake_templates/qgsconfig.h.in ${CMAKE_BINARY_DIR}/qgsconfig.h)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})

# Added by Jef to prevent python core and gui libs linking to other qgisCore and qgisGui libs
# that may be in the same install prefix
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/src/core ${CMAKE_BINARY_DIR}/src/gui)

#############################################################
# create qgsversion.h
IF (EXISTS ${CMAKE_SOURCE_DIR}/.git/index)
  ……

#############################################################
# 在输出目录中添加一些子文件夹

#create a variable to specify where our test data is
#so that unit tests can use TEST_DATA_DIR to locate
#the test data. See CMakeLists in test dirs for more info
#TEST_DATA_DIR is also used by QgsRenderChecker currently in core
SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata")

ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(doc)
ADD_SUBDIRECTORY(images)
ADD_SUBDIRECTORY(resources)
ADD_SUBDIRECTORY(i18n)

IF (WITH_BINDINGS)
  ADD_SUBDIRECTORY(python)
ENDIF (WITH_BINDINGS)

IF (ENABLE_TESTS)
  ADD_SUBDIRECTORY(tests)
  SET (CTEST_BINARY_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/output/bin" )
  MESSAGE (STATUS "Ctest Binary Directory set to: ${CTEST_BINARY_DIRECTORY}")
ENDIF (ENABLE_TESTS)

IF (APPLE)
  ……

INSTALL(FILES cmake/FindQGIS.cmake DESTINATION ${QGIS_DATA_DIR})

#############################################################
# Post-install commands
ADD_SUBDIRECTORY(postinstall)

#############################################################
# Uninstall stuff see: http://www.vtk.org/Wiki/CMake_FAQ
CONFIGURE_FILE(
  ……

#############################################################
# Enable packaging
……

如果你把上面的代码认真读了一遍,相信你对QGis工程的组织有一些基本的认识了。

我自己将QGis的不同模块对应的编译选项列在这里了,可以参考。(如果有遗漏请告诉我,谢谢)

这里写图片描述

针对每个不同的模块编译,可以去找不同模块子文件夹下的CMakeList.txt文件,看看自己是否在生成工程的时候哪里有缺失。

总结

通过上面的整体介绍,希望大家能够对QGis工程的编译有一点感觉,这里面的组织非常复杂,但只要细心,你一定会找到自己编译不成功的原因。

谢谢阅读,如有错误,请不吝指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QGis二次开发 -- 源码编译终极篇 的相关文章

  • mybatis 动态sql 源码解析

    mybatis 动态sql 测试例子 java程序 xml文件 调试 直接进入到解析select语句的地方 进入 解析xml 进入buildStatementFromContext 依然是交给XMLStatementBuilder解析 核心
  • 创建一个QGIS plugin

    创建一个QGIS plugin 1 plugins gt Plugin Builder 2 4 6 选择自己创建的插件存储的地方 最好换一个地方 默认的插件存储地方比较深 我放的地方为D coding mygistest 点击generat
  • PACS系统源码 PACS源码 基于VC + MSSQL开发

    基于VC MSSQL开发的一套大型医院医学影像PACS系统源码 有演示 文末获取联系 PACS系统可以覆盖医院现有放射 CT MR 核医学 超声 内镜 病理 心电等绝大部分DICOM和非DICOM检查设备 支持从科室级 全院级 集团医院级乃
  • oschina源码分析之侧滑菜单界面之可以拖动的ScrollView

    先上源码 package net oschina app widget import android annotation SuppressLint import android content Context import android
  • 解决,worldGeo.db中有geom数据的x1表无法在QGIS中成图像

    原因 缺少geom数据对应的坐标geometry columns文件 如下图所示 STEP 1 在navicat for SQLite中将目标表x1中字段geom中blob改成 POINT 或者MULTIPOLYGON等对应的格式 注意 f
  • 基于java springboot vue仓库管理系统源码(毕设)

    开发环境及工具 大于Jdk1 8 大于mysql5 5 idea eclipse vscode webstorm 技术说明 Springboot mybatis vue elementui 代码注释齐全 没有多余代码 适合学习 毕设 二次开
  • 浅析muduo库中的定时器设施

    一个设计良好的定时器在服务端的应用程序上至关重要 muduo定时器的实现陈硕大牛在书中已经详细的谈过 笔者尝试从源码的角度解读定时器的实现 如果理解不对 欢迎指正 在muduo的定时器系统中 一共由四个类 Timestamp Timer T
  • SonarQube白盒静态代码专家解决方案

    中国区官网 http www safetesting cn 西安青穗 http www safetesting cn 是瑞士SonarSource公司正式授权的中国渠道商和技术服务提供商 技术服务团队有多年行业经验的业界专家 咨询顾问组成
  • 技术宅学会几招FFmpeg

    有些时候 我需要对某个视频文件做一些简单的处理 也或者是受亲戚朋友的委托吧 又不好意思推辞 因为人家觉得你是搞技术的 这点小事应该能轻松搞定 但是 我犯不着为这点事去安装一个笨重的多媒体软件 我也不想去网上随便找个免费的小工具 怕它不干净
  • Android中如何重新启动应用APP或重启系统

    重新启动应 程序 有两种 法 分别是 1 通过ActivityManager来重新启动应 程序 java 代码 ActivityManager manager ActivityManager this getSystemService Co
  • QGis二次开发基础 -- 构建图层管理器

    为了回应有些同学对上一篇博文的建议 这篇文章主要关注于QGis二次开发中的 图层管理器 的实现 使用QGis构建独立应用系统 我相信大部分同学应该还是关注于GIS基本功能框架构建上 也就是一些基本的GIS功能 例如 数据的显示 漫游浏览等
  • ASP.NET Core3.1 跨平台智能云管理系统源码

    ASP NET Core3 1 跨平台智能云管理系统源码 一个相当不错的系统框架 ASP NET Core3 1 跨平台智能云管理系统 什么是 ASP NET Core ASP NET Core 是一个由微软创建的 用于构建 web 应用
  • 如何在多线程异步的情况下保证事务?

    在Spring环境下 如果使用了 Transactional 注解 那么当你的 inert 操作时异步的话 则会不在当前事务里面 那么后续的回滚操作 不会将这次异步操作的插入进行回滚 那么我们有方式来保证多线程异步场景下的事务吗 Servi
  • Caffe源码(十一):io.cpp 分析

    目录 目录 简单介绍 主要函数 ReadProtoFromTextFile 函数 WriteProtoToTextFile 函数 ReadProtoFromBinaryFile 函数 WriteProtoToBinaryFile 函数 Re
  • [pytest源码4]-pluggy之Plugin注册逻辑分析

    前言 本篇将详细对plugin的注册逻辑进行分析 个人拙见 有错请各位指出 如果的我的文章对您有帮助 不符动动您的金手指给个Star 予人玫瑰 手有余香 不胜感激 GitHub pluggy注册逻辑分析性 我们来详细分析一下plugin的注
  • 13 openEuler用户组管理

    文章目录 13 1 创建用户组 13 1 1 groupadd命令 13 1 2 用户组信息文件 13 1 3 创建用户组实例 13 2 修改用户组 13 2 1 修改GID 13 2 2 修改用户组名 13 3 删除用户组 13 4 将用
  • 开源Cloudreve云盘系统源码/ 支持本地储存+对接各大对象储存/带云盘系统安装教程/公私兼备网盘系统

    源码介绍 Cloudreve云盘系统源码 它不仅支持本地储存 而且还对接各大对象储存 附带云盘系统安装教程 轻松搭建个人网盘 拥有美观界面 云盘系统安装教程 公私兼备网盘系统 多功能仿百度网盘源码 测试环境 PHP7 1 MYSQL5 6
  • 开源Cloudreve云盘系统源码/ 支持本地储存+对接各大对象储存/带云盘系统安装教程/公私兼备网盘系统

    源码介绍 Cloudreve云盘系统源码 它不仅支持本地储存 而且还对接各大对象储存 附带云盘系统安装教程 轻松搭建个人网盘 拥有美观界面 云盘系统安装教程 公私兼备网盘系统 多功能仿百度网盘源码 测试环境 PHP7 1 MYSQL5 6
  • 病案管理的定义、流程及应用分析

    病案管理是指针对病人的基本信息 病历 就诊记录等进行收集 整理 存储 分析和应用的一项管理工作 它在医院 医疗机构和医疗行业中具有重要的作用 能够提高医疗服务的质量 效率和安全性 本文将就病案管理的定义 流程以及其在医疗健康领域中的应用进行
  • 我无法安装包 spatstat.data。是否可以下载 zip 文件并复制并粘贴到 R 文件夹库中?

    新的错误消息 https i stack imgur com gy84q png我更新了spatstat包 它分为各个包 除了 spatstat data 之外 所有这些都已更新 我努力了install packages spatstat

随机推荐

  • 【Ant Design】Form.Item创建自定义表单

    一 概述 Antd是一个非常强大的UI组件库 里面的Form表单组件也基本能满足我们大多数场景 但是也有需要自定义表单的场景 Vue2里我们使用v model 结合子组件的model属性 来实现自定义组件的双向绑定 Vue3里我们使用v m
  • 【Jboss】热部署

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net inforstack article details 47681803
  • 蓝桥杯:斐波那契数列最大公约数

    题目表示的很明确 要用两个算法 斐波那契数列是很经典的dp问题 最大公约数是很经典的辗转相除法 从而我理所应当的就定义一个数组存放斐波那契数列 long long int F 2021 0 F 1 1 F 2 1 for int i 3 i
  • 解决SQL Server占用服务器内存过高问题

    最近发现个问题 数据库服务器内存居高不下 64G的内存 几乎被占用100 结果差点把服务器给拖垮了 第一步 打开SQL Server Management Studio 在连接上右键 属性 第二步 内存选项卡 修改最大服务器内存的大小 如下
  • Android Killer的安装和配置 -安卓逆向的必备神器

    图文并茂 详细的不能再详细了 这你总不能学不会吧 都给我学会 安装包我已经放在了文章末尾 需要可以自取哟 1 下载安卓Android killer 首先 我们先下载打包好的Android killer 解压缩后可以得到一大堆没啥用的 文件
  • 用WinHex软件解析FAT32文件系统

    一 工欲善其事 1 准备工作 将一个U盘格式化为FAT32格式 在U盘内创建几个文件 最好是TXT文档 其中至少有一个是长文件 命名较长 2 补充知识 短文件名表示 长文件名表示 Note 当一个文件名为长文件名时 会由几个长文件名表示法和
  • Linux查看当前目录下各文件所占空间

    要查看当前目录下各文件所占空间 可以使用du命令 磁盘使用情况 配合sort命令来实现 以下是在Linux系统中执行的命令 du sh sort hr 解释一下这个命令 du sh 计算当前目录下每个文件和目录的总大小 并以易读的方式显示
  • 给定一个无重复元素的有序整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 n

    class Solution public List
  • 让dapper支持Oracle

    之前的项目数据使用mssql和mysql ORM使用一个轻量级的dapper 感觉很方便 性能也比EF强 关键是语法灵活 上手容易 用这种框架开发了几个网站 感觉非常好 但新项目要使用oracle 就出问题了 dapper里的关键字 在or
  • 史上最全量化交易资源整理

    有些国外的平台 社区 博客如果连接无法打开 那说明可能需要 科学 上网 国内在线量化平台 BigQuant 你的人工智能量化平台 可以无门槛地使用机器学习 人工智能开发量化策略 基于python 提供策略自动生成器 镭矿 基于量化回测平台
  • PCL 大窗口可视化两个点云

    一 主要参数 viewer gt setFullScreen true 设置点云为全屏显示的2D俯视图 二 代码实现 1 一个大窗口可视化两个点云 include
  • 清除history内容

    history记录是记录在 bash history中的 history c 清除的是当前会话的记录 原来的记录是不会被清除的 可以直接删除 bash history 清空这个文件cat dev null gt bash history
  • c++ - 抽象类 和 多态当中一些问题

    抽象类 纯虚函数 在虚函数的后面写上 0 则这个函数为纯虚函数 class A public virtual void func 0 纯虚函数不需要写函数的定义 他有类似声明一样的结构 抽象类概念 我们把具有纯虚函数的类 叫做抽象类 所谓抽
  • C++ 惯用法之 CRTP

    背景 CRTP 是 一种 C 的设计方法 其巧妙的结合了继承和模板编程技术 可以用来给类提供额外的功能 CRTP 概述 CRTP 的基本特征表现为 基类是一个模板类 派生类在继承该基类时 将派生类自身作为模板参数传递给基类 实现示例 tem
  • ACE命令参数解析

    ACE提供了ACE Get Opt类来处理命令行参数选项 这个类是一个迭代器 用于解析按照自然数方式计数的参数向量 它包装了POSIX的getotp 函数的功能 但是与getopt 函数不同 ACE Get Opt类的每个实例都维护有自己的
  • 【Vue】终极笔记:面试必胜宝典,大厂面试题源码级详解 (持续更新!!!)

    Vue经典面试题源码级详解 1 Vue组件之间通信方式有哪些 分析 思路分析 回答范例 1 组件通信常用方式有以下8种 2 根据组件之间关系讨论组件通信最为清晰有效 2 v if 和 v for哪个优先级更高 分析 思路分析 回答范例 3
  • mysql运行语句时出现 FUNCTION *** does not exist

    我在运行MYSQL时 经常出现这种问题 一阵搜索后 原来问题出现在函数与括号之间的空格上 比如 写成 concat 这样就出错了 需要去掉空格 concat 就好了 资料来源 在这个网址找到方法 http blog 152 org 2009
  • [Spring Boot]08 IDEA接入MyBatisCodeHelper代码自动生成器

    目录 前言 一 插件市场安装插件 二 使用插件自动生成代码 前言 上次介绍了 原生mybatis的方法 06 Spring Boot接入mybatis通用mapper插件自动生成器 这次 再介绍下插件MyBatisCodeHelper Pr
  • P4wnP1 USB与赛门铁克反病毒绕过

    最近 我使用P4wnP1 image把我手头的Raspberry Pi Zero W转换成了一个bad USB 我的最终目标是运行远程命令shell 同时绕过已启用完全保护的最新版Symantec SEP 我通过创建自己的有效负载paylo
  • QGis二次开发 -- 源码编译终极篇

    由于是开源软件 QGis版本迭代比较快 在保持long term release版本的基础上 每个月都会有一个monthly release的新版本发布 源码工程变化快速 给想要上手编译开发的新人朋友带来了一些困惑 我之前分别写过QGis1