...
 
Commits (197)
......@@ -34,7 +34,7 @@ jobs:
if [[ "${GITHUB_REF}" =~ ^refs/tags ]]; then
echo "matrix={\"branch\":[\"${GITHUB_REF##*/}\"]}" >> $GITHUB_OUTPUT
else
echo "matrix={\"branch\":[\"master\", \"release-3_30\", \"release-3_28\"]}" >> $GITHUB_OUTPUT
echo "matrix={\"branch\":[\"master\", \"release-3_32\", \"release-3_28\"]}" >> $GITHUB_OUTPUT
fi
build-docker:
......@@ -55,6 +55,14 @@ jobs:
matrix: ${{ fromJSON( needs.define-strategy.outputs.matrix ) }}
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
tool-cache: true
large-packages: true
docker-images: false
swap-storage: true
- name: Free additional space
run: |
df -h
......
......@@ -152,7 +152,7 @@ jobs:
sudo apt install -y \
expect \
silversearcher-ag
- uses: tj-actions/changed-files@v37
- uses: tj-actions/changed-files@v38
id: changed_files
with:
separator: ' '
......
......@@ -89,6 +89,7 @@ jobs:
-DWITH_INTERNAL_QWTPOLAR=OFF \
-DWITH_BINDINGS=OFF \
-DWITH_GRASS=OFF \
-DWITH_DRACO=OFF \
-DUSE_CCACHE=ON \
-S . \
-B build
......
......@@ -135,9 +135,9 @@ those formats in GDAL.
**Requires:** Ubuntu / Debian derived distro
**Note:** Refer to the section Building Debian packages for building
debian packages. Unless you plan to develop on QGIS, that is probably the
easiest option to compile and install QGIS.
**Note:** Refer to the section [Building Debian packages](#310-building-debian-packages)
for building debian packages. Unless you plan to develop on QGIS, that is
probably the easiest option to compile and install QGIS.
These notes are for Ubuntu - other versions and Debian derived distros may
require slight variations in package names.
......@@ -405,17 +405,11 @@ Instead of creating a personal installation as in the previous step you can
also create debian package. This is done from the QGIS root directory, where
you'll find a debian directory.
First you need to install the debian packaging tools once:
First you need to install the [build dependencies](#33-install-build-dependencies)
and setup a changelog entry for your distribution. For example for Debian Bookworm:
```bash
apt-get install build-essential
```
First you need to create an changelog entry for your distribution. For example
for Ubuntu Precise:
```bash
dch -l ~precise --force-distribution --distribution precise "precise build"
dch -l ~bookworm --force-distribution --distribution bookworm "bookworm build"
```
The QGIS packages will be created with:
......@@ -426,9 +420,6 @@ dpkg-buildpackage -us -uc -b
**Note:** Install `devscripts` to get `dch`.
**Note:** If `dpkg-buildpackage` complains about unmet build dependencies
you can install them using `apt-get` and re-run the command.
**Note:** If you have `libqgis1-dev` installed, you need to remove it first
using `dpkg -r libqgis1-dev`. Otherwise `dpkg-buildpackage` will complain about a
build conflict.
......
<img src="images/README-md/main_logo.png" width="300">
[![Tests](https://github.com/qgis/QGIS/workflows/QGIS%20tests/badge.svg)](https://github.com/qgis/QGIS/actions/workflows/run-tests.yml?query=branch%3Amaster+event%3Apush)
[![🧪 QGIS tests](https://github.com/qgis/QGIS/actions/workflows/run-tests.yml/badge.svg)](https://github.com/qgis/QGIS/actions/workflows/run-tests.yml?query=branch%3Amaster+event%3Apush)
[![Docker Status](https://img.shields.io/docker/automated/qgis/qgis.svg)](https://hub.docker.com/r/qgis/qgis/tags)
[![Build Status](https://dev.azure.com/qgis/QGIS/_apis/build/status/qgis.QGIS?branchName=master)](https://dev.azure.com/qgis/QGIS/_build/latest?definitionId=1&branchName=master)
[![Windows cross build](https://github.com/qgis/QGIS/workflows/MingW64%20Windows%2064bit%20Build/badge.svg)](https://github.com/qgis/QGIS/actions/workflows/mingw64.yml?query=branch%3Amaster+event%3Apush)
[![🪟 MingW64 Windows 64bit Build](https://github.com/qgis/QGIS/actions/workflows/mingw64.yml/badge.svg)](https://github.com/qgis/QGIS/actions/workflows/mingw64.yml?query=branch%3Amaster+event%3Apush)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5869837.svg)](https://doi.org/10.5281/zenodo.5869837)
QGIS is a full-featured, user-friendly, free-and-open-source (FOSS) geographical information system (GIS) that runs on Unix platforms, Windows, and MacOS.
......
......@@ -24,6 +24,12 @@ IF(QSCINTILLA_VERSION_STR)
SET(QSCINTILLA_FOUND TRUE)
ELSE(QSCINTILLA_VERSION_STR)
if(BUILD_WITH_QT6)
set(QSCINTILLA_PATH_SUFFIXES qt6)
else()
set(QSCINTILLA_PATH_SUFFIXES qt)
endif()
set(QSCINTILLA_LIBRARY_NAMES
qscintilla2-${QT_VERSION_BASE_LOWER}
qscintilla2_${QT_VERSION_BASE_LOWER}
......@@ -58,7 +64,7 @@ ELSE(QSCINTILLA_VERSION_STR)
$ENV{LIB_DIR}/include
/usr/local/include
/usr/include
PATH_SUFFIXES qt
PATH_SUFFIXES ${QSCINTILLA_PATH_SUFFIXES}
)
IF(QSCINTILLA_LIBRARY AND QSCINTILLA_INCLUDE_DIR)
......
......@@ -2041,26 +2041,41 @@ EXPAND_AS_DEFINED = "SIP_ABSTRACT" \
"SIP_CONSTRAINED" \
"SIP_CONVERT_TO_SUBCLASS_CODE" \
"SIP_DEPRECATED" \
"SIP_DOC_TEMPLATE" \
"SIP_END" \
"SIP_EXTERNAL" \
"SIP_FACTORY" \
"SIP_FEATURE" \
"SIP_FORCE" \
"SIP_GETWRAPPER" \
"SIP_HOLDGIL" \
"SIP_IF_FEATURE" \
"SIP_IF_MODULE" \
"SIP_IN" \
"SIP_INOUT" \
"SIP_KEEPREFERENCE" \
"SIP_MAKE_PRIVATE" \
"SIP_NODEFAULTCTORS" \
"SIP_NO_FILE" \
"SIP_OUT" \
"SIP_PROPERTY" \
"SIP_PYARGDEFAULT" \
"SIP_PYARGREMOVE" \
"SIP_PYARGRENAME" \
"SIP_PYNAME" \
"SIP_PYALTERNATIVETYPE" \
"SIP_PYTHON_SPECIAL_BOOL" \
"SIP_RELEASEGIL" \
"SIP_SKIP" \
"SIP_THROW" \
"SIP_TRANSFER" \
"SIP_TRANSFERBACK" \
"SIP_TRANSFERTHIS" \
"SIP_TYPEHINT" \
"SIP_VIRTUAL_CATCHER_CODE" \
"SIP_VIRTUALERRORHANDLER" \
"SIP_WHEN_FEATURE" \
"SIP_MONKEYPATCH_COMPAT_NAME" \
"SIP_MONKEYPATCH_SCOPEENUM" \
"SIP_MONKEYPATCH_SCOPEENUM_UNNEST"
......
此差异已折叠。
此差异已折叠。
......@@ -23,7 +23,7 @@ endmacro(ADD_TRANSLATION_FILES)
file(MAKE_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/i18n)
set(TS_FILES qgis_ar.ts qgis_bg.ts qgis_bs.ts qgis_ca.ts qgis_cs.ts qgis_da.ts qgis_de.ts qgis_en_US.ts qgis_es.ts qgis_et.ts qgis_eu.ts qgis_fa.ts qgis_fi.ts qgis_fr.ts qgis_gl.ts qgis_hu.ts qgis_is.ts qgis_it.ts qgis_ja.ts qgis_ko.ts qgis_ky.ts qgis_lt.ts qgis_lv.ts qgis_nb.ts qgis_nl.ts qgis_pl.ts qgis_pt_BR.ts qgis_pt_PT.ts qgis_ro.ts qgis_ru.ts qgis_sc.ts qgis_sk.ts qgis_sv.ts qgis_tr.ts qgis_uk.ts qgis_vi.ts qgis_zh-Hans.ts qgis_zh-Hant.ts)
set(TS_FILES qgis_ar.ts qgis_az.ts qgis_bg.ts qgis_bs.ts qgis_ca.ts qgis_cs.ts qgis_da.ts qgis_de.ts qgis_en_US.ts qgis_es.ts qgis_et.ts qgis_eu.ts qgis_fa.ts qgis_fi.ts qgis_fr.ts qgis_gl.ts qgis_hu.ts qgis_is.ts qgis_it.ts qgis_ja.ts qgis_ko.ts qgis_ky.ts qgis_lt.ts qgis_lv.ts qgis_nb.ts qgis_nl.ts qgis_pl.ts qgis_pt_BR.ts qgis_pt_PT.ts qgis_ro.ts qgis_ru.ts qgis_sc.ts qgis_sk.ts qgis_sv.ts qgis_tr.ts qgis_uk.ts qgis_vi.ts qgis_zh-Hans.ts qgis_zh-Hant.ts)
ADD_TRANSLATION_FILES (QM_FILES ${TS_FILES})
......
此差异已折叠。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="1200"
height="600"
viewBox="0 -300 1200 600"
id="svg2">
<defs
id="defs21" />
<rect
width="1200"
height="600"
x="0"
y="-300"
style="fill:#0092c7;fill-opacity:1"
id="blue_stripe" />
<rect
width="1200"
height="200"
x="0"
y="-100"
style="fill:#ea0437;fill-opacity:1"
id="red_stripe" />
<rect
width="1200"
height="200"
x="0"
y="100"
style="fill:#00ae68;fill-opacity:1"
id="green_stripe" />
<circle
cx="560"
cy="0"
r="84"
style="fill:#ffffff"
id="white_circle" />
<circle
cx="582"
cy="0"
r="70"
style="fill:#ea0437;fill-opacity:1"
id="red_circle" />
<path
d="M 70.255954,-339.97293 L 48.485805,-349.82516 L 40.104505,-327.4475 L 31.677263,-349.8079 L 9.9273944,-339.91098 L 19.779625,-361.68113 L -2.5980343,-370.06243 L 19.762365,-378.48967 L 9.8654446,-400.23954 L 31.635594,-390.38731 L 40.016894,-412.76497 L 48.444136,-390.40457 L 70.194004,-400.30149 L 60.341774,-378.53134 L 82.719433,-370.15004 L 60.359034,-361.7228 L 70.255954,-339.97293 z "
transform="matrix(1.0548817,1.8411178e-3,-1.8411178e-3,1.0548817,602.05929,390.34455)"
style="fill:#ffffff;fill-opacity:1"
id="path4162" />
</svg>
......@@ -2,6 +2,7 @@
<qresource prefix="/images">
<file>flags/af.svg</file>
<file>flags/ar.svg</file>
<file>flags/az.svg</file>
<file>flags/bg.svg</file>
<file>flags/cy.svg</file>
<file>flags/de.svg</file>
......@@ -985,6 +986,10 @@
<file>themes/default/mActionTextAlongLine.svg</file>
<file>themes/default/mActionNewElevationProfile.svg</file>
<file>themes/default/mIconSurfaceElevationFillAbove.svg</file>
<file>themes/default/mIconCesium3dTiles.svg</file>
<file>themes/default/mActionAddTiledSceneLayer.svg</file>
<file>themes/default/mIconTiledScene.svg</file>
<file>themes/default/mIconTiledSceneLayer.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
......
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="24" height="24"><defs><linearGradient id="c"><stop offset="0" style="stop-color:#ccdaef;stop-opacity:1"/><stop offset="1" style="stop-color:#b3c5dd;stop-opacity:1"/></linearGradient><linearGradient id="b"><stop offset="0" style="stop-color:#aec3dc;stop-opacity:1"/><stop offset="1" style="stop-color:#8babcd;stop-opacity:1"/></linearGradient><linearGradient id="a"><stop offset="0" style="stop-color:#aec5df;stop-opacity:1"/><stop offset="1" style="stop-color:#89aad1;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#a" id="e" x1="8.902" x2="16.818" y1="3.485" y2="7.418" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#b" id="f" x1="13.27" x2="19.883" y1="11.905" y2="19.25" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#c" id="d" x1="5.611" x2="11.21" y1="9.511" y2="20.659" gradientUnits="userSpaceOnUse"/></defs><path d="M4.498 7.969v10.11l8.004 4.147v-10.11Z" style="fill:url(#d);fill-opacity:1;stroke:#476280;stroke-width:.996136;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M12.568 1.55 4.5 5.695l8.068 4.145 7.933-4.144Z" style="fill:url(#e);fill-opacity:1;stroke:#476280;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M20.498 7.973v10.105l-7.996 4.144V12.117z" style="fill:url(#f);fill-opacity:1;stroke:#476280;stroke-width:1.00384;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><g style="display:inline" transform="translate(1.846 1.846) scale(.6923)"><rect width="13" height="13" x="19" y="19" fill="#5a8c5a" rx="2.615"/><g fill-rule="evenodd"><path fill="#fff" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.6" d="M21.6 25.5h7.8m-3.9 3.9v-7.8"/><path fill="#fcffff" d="M20.3 25.5h10.4v-2.6c0-2.6-.65-2.6-5.2-2.6s-5.2 0-5.2 2.6z" opacity=".3"/></g></g><path d="m8 15.312-2-1.08v2.975l2 1.048zM11 16.817l-2-1.08v2.974l2 1.048zM8 11.426l-2-1.08v2.975l2 1.047zM11 12.93l-2-1.08v2.975l2 1.048zM17.046 11.529l2-1.08v2.975l-2 1.047zM14.046 13.033l2-1.08v2.975l-2 1.047z" style="fill:#5078a3;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><linearGradient id="a"><stop offset="0" stop-color="#6e97c4"/><stop offset="1" stop-color="#aec7e2"/></linearGradient><rect width="2.16" height="2.269" x="14.736" y="-5.609" rx=".081" ry=".093" style="fill:#4a6684;fill-opacity:1;stroke-width:.485108;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="2.16" height="2.029" x="14.733" y="-2.582" rx=".081" ry=".083" style="fill:#4a6684;fill-opacity:1;stroke-width:.458778;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="2.16" height="1.781" x="12.009" y="-5.646" rx=".081" ry=".073" style="fill:#4a6684;fill-opacity:1;stroke-width:.429843;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="2.16" height="2.694" x="12.009" y="-3.236" rx=".081" ry=".11" style="fill:#4a6684;fill-opacity:1;stroke-width:.52857;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="4.612" height="4.612" x="5.972" y="-5.187" rx=".172" ry=".188" style="fill:#aec7e2;fill-opacity:1;stroke:#476280;stroke-width:.7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="4.612" height="4.612" x="5.972" y=".766" rx=".172" ry=".188" style="fill:#aec7e2;fill-opacity:1;stroke:#476280;stroke-width:.7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" transform="rotate(45)"/><rect width="4.612" height="4.612" x="12.11" y=".766" rx=".172" ry=".188" style="fill:#aec7e2;fill-opacity:1;stroke:#476280;stroke-width:.7;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" transform="rotate(45)"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="16" height="16"><defs><linearGradient id="c"><stop offset="0" style="stop-color:#ccdaef;stop-opacity:1"/><stop offset="1" style="stop-color:#b3c5dd;stop-opacity:1"/></linearGradient><linearGradient id="b"><stop offset="0" style="stop-color:#aec3dc;stop-opacity:1"/><stop offset="1" style="stop-color:#8babcd;stop-opacity:1"/></linearGradient><linearGradient id="a"><stop offset="0" style="stop-color:#aec5df;stop-opacity:1"/><stop offset="1" style="stop-color:#89aad1;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#a" id="e" x1="8.902" x2="16.818" y1="3.485" y2="7.418" gradientTransform="matrix(.65504 0 0 .65504 .038 -.13)" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#b" id="f" x1="13.27" x2="19.883" y1="11.905" y2="19.25" gradientTransform="matrix(.65504 0 0 .65504 .038 .435)" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#c" id="d" x1="5.611" x2="11.21" y1="9.511" y2="20.659" gradientTransform="matrix(.65504 0 0 .65504 .038 .435)" gradientUnits="userSpaceOnUse"/></defs><path d="M2.5 5.655v6.623l5.727 2.716V8.37Z" style="fill:url(#d);fill-opacity:1;stroke:#476280;stroke-width:1;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M8.27.886 2.5 3.6l5.77 2.715 5.197-2.721Z" style="fill:url(#e);fill-opacity:1;stroke:#476280;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M13.5 5.658v6.619l-5.273 2.714V8.372Z" style="fill:url(#f);fill-opacity:1;stroke:#476280;stroke-width:1;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><linearGradient xlink:href="#a" id="d" x1="5.611" x2="11.21" y1="9.511" y2="20.659" gradientTransform="translate(.038 .435) scale(.65504)" gradientUnits="userSpaceOnUse"/><linearGradient id="a"><stop offset="0" style="stop-color:#e1e6ef;stop-opacity:1"/><stop offset="1" style="stop-color:#b4bbc9;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#b" id="e" x1="8.902" x2="16.818" y1="3.485" y2="7.418" gradientTransform="translate(.038 -.13) scale(.65504)" gradientUnits="userSpaceOnUse"/><linearGradient id="b"><stop offset="0" style="stop-color:#e6eaec;stop-opacity:1"/><stop offset="1" style="stop-color:#bbc4d0;stop-opacity:1"/></linearGradient><linearGradient xlink:href="#c" id="f" x1="13.27" x2="19.883" y1="11.905" y2="19.25" gradientTransform="translate(.038 .435) scale(.65504)" gradientUnits="userSpaceOnUse"/><linearGradient id="c"><stop offset="0" style="stop-color:#d2d4de;stop-opacity:1"/><stop offset="1" style="stop-color:#b2c2d0;stop-opacity:1"/></linearGradient></defs><path d="m12.03 8.112.993-.472v1.987l-.992.438z" style="fill:#5078a3;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"/><path d="M2.5 5.655v6.623l5.727 2.716V8.37Z" style="fill:url(#d);fill-opacity:1;stroke:#58687f;stroke-width:.75;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M8.27.886 2.5 3.6l5.77 2.715 5.197-2.721Z" style="fill:url(#e);fill-opacity:1;stroke:#58687f;stroke-width:.75;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="M13.5 5.658v6.619l-5.273 2.714V8.372Z" style="fill:url(#f);fill-opacity:1;stroke:#58687f;stroke-width:.75;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/><path d="m5.011 8.185-.992-.472V9.7l.992.439zM7.009 9.128l-.992-.471v1.986l.992.438zM9.988 9.843l2.006-1.005-.004 3.865-2.006.972z" style="fill:#637e9d;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"/></svg>
\ No newline at end of file
......@@ -9,6 +9,7 @@
%Include auto_generated/qgscamerapose.sip
%Include auto_generated/qgslayoutitem3dmap.sip
%Include auto_generated/qgsrulebased3drenderer.sip
%Include auto_generated/qgstiledscenelayer3drenderer.sip
%Include auto_generated/qgsvectorlayer3drenderer.sip
%Include auto_generated/qgspointcloudlayer3drenderer.sip
%Include auto_generated/lights/qgsdirectionallightsettings.sip
......
/************************************************************************
* This file has been generated automatically from *
* *
* src/3d/qgstiledscenelayer3drenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsTiledSceneLayer3DRendererMetadata : Qgs3DRendererAbstractMetadata
{
%Docstring(signature="appended")
Metadata for tiled scene layer 3D renderer to allow creation of its instances from XML
.. versionadded:: 3.34
%End
%TypeHeaderCode
#include "qgstiledscenelayer3drenderer.h"
%End
public:
QgsTiledSceneLayer3DRendererMetadata();
virtual QgsAbstract3DRenderer *createRenderer( QDomElement &elem, const QgsReadWriteContext &context ) /Factory/;
%Docstring
Creates an instance of a 3D renderer based on a DOM element with renderer configuration
%End
};
class QgsTiledSceneLayer3DRenderer : QgsAbstract3DRenderer
{
%Docstring(signature="appended")
3D renderer that renders content of a tiled scene layer
.. versionadded:: 3.34
%End
%TypeHeaderCode
#include "qgstiledscenelayer3drenderer.h"
%End
%ConvertToSubClassCode
if ( sipCpp->type() == QLatin1String( "tiledscene" ) )
{
sipType = sipType_QgsTiledSceneLayer3DRenderer;
}
else
{
sipType = 0;
}
%End
public:
QgsTiledSceneLayer3DRenderer();
void setLayer( QgsTiledSceneLayer *layer );
%Docstring
Sets tiled scene layer associated with the renderer
%End
QgsTiledSceneLayer *layer() const;
%Docstring
Returns tiled scene layer associated with the renderer
%End
double maximumScreenError() const;
%Docstring
Returns the maximum screen error allowed when rendering the tiled scene.
Larger values result in a faster render with less content rendered.
.. seealso:: :py:func:`setMaximumScreenError`
%End
void setMaximumScreenError( double error );
%Docstring
Sets the maximum screen ``error`` allowed when rendering the tiled scene.
Larger values result in a faster render with less content rendered.
.. seealso:: :py:func:`maximumScreenError`
%End
bool showBoundingBoxes() const;
%Docstring
Returns whether bounding boxes will be visible when rendering the tiled scene.
.. seealso:: :py:func:`setShowBoundingBoxes`
%End
void setShowBoundingBoxes( bool showBoundingBoxes );
%Docstring
Sets whether bounding boxes will be visible when rendering the tiled scene.
.. seealso:: :py:func:`showBoundingBoxes`
%End
virtual QString type() const;
virtual QgsAbstract3DRenderer *clone() const /Factory/;
virtual void writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const;
virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
virtual void resolveReferences( const QgsProject &project );
private:
QgsTiledSceneLayer3DRenderer( const QgsTiledSceneLayer3DRenderer & );
QgsTiledSceneLayer3DRenderer &operator=( const QgsTiledSceneLayer3DRenderer & );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/3d/qgstiledscenelayer3drenderer.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
......@@ -1569,6 +1569,13 @@ Qgis.MapLayerProperty.baseClass = Qgis
Qgis.MapLayerProperties.baseClass = Qgis
MapLayerProperties = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.AutoRefreshMode.Disabled.__doc__ = "Automatic refreshing is disabled"
Qgis.AutoRefreshMode.ReloadData.__doc__ = "Reload data (and draw the new data)"
Qgis.AutoRefreshMode.RedrawOnly.__doc__ = "Redraw current data only"
Qgis.AutoRefreshMode.__doc__ = "Map layer automatic refresh modes.\n\n.. versionadded:: 3.34\n\n" + '* ``Disabled``: ' + Qgis.AutoRefreshMode.Disabled.__doc__ + '\n' + '* ``ReloadData``: ' + Qgis.AutoRefreshMode.ReloadData.__doc__ + '\n' + '* ``RedrawOnly``: ' + Qgis.AutoRefreshMode.RedrawOnly.__doc__
# --
Qgis.AutoRefreshMode.baseClass = Qgis
# monkey patching scoped based enum
Qgis.DataProviderFlag.IsBasemapSource.__doc__ = "Associated source should be considered a 'basemap' layer. See Qgis.MapLayerProperty.IsBasemapLayer."
Qgis.DataProviderFlag.__doc__ = "Generic data provider flags.\n\n.. versionadded:: 3.26\n\n" + '* ``IsBasemapSource``: ' + Qgis.DataProviderFlag.IsBasemapSource.__doc__
# --
......@@ -1910,6 +1917,14 @@ QgsRenderContext.Flags = Qgis.RenderContextFlags
Qgis.RenderContextFlag.baseClass = Qgis
Qgis.RenderContextFlags.baseClass = Qgis
RenderContextFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.MapLayerRendererFlag.RenderPartialOutputs.__doc__ = "The renderer benefits from rendering temporary in-progress preview renders. These are temporary results which will be used for the layer during rendering in-progress compositions, which will differ from the final layer render. They can be used for showing overlays or other information to users which help inform them about what is actually occurring during a slow layer render, but where these overlays and additional content is not wanted in the final layer renders. Another use case is rendering unsorted results as soon as they are available, before doing a final sorted render of the entire layer contents."
Qgis.MapLayerRendererFlag.RenderPartialOutputOverPreviousCachedImage.__doc__ = "When rendering temporary in-progress preview renders, these preview renders can be drawn over any previously cached layer render we have for the same region. This can allow eg a low-resolution zoomed in version of the last map render to be used as a base painting surface to overdraw with incremental preview render outputs. If not set, an empty image will be used as the starting point for the render preview image."
Qgis.MapLayerRendererFlag.__doc__ = "Flags which control how map layer renderers behave.\n\n.. versionadded:: 3.34\n\n" + '* ``RenderPartialOutputs``: ' + Qgis.MapLayerRendererFlag.RenderPartialOutputs.__doc__ + '\n' + '* ``RenderPartialOutputOverPreviousCachedImage``: ' + Qgis.MapLayerRendererFlag.RenderPartialOutputOverPreviousCachedImage.__doc__
# --
Qgis.MapLayerRendererFlag.baseClass = Qgis
Qgis.MapLayerRendererFlags.baseClass = Qgis
MapLayerRendererFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
QgsRenderContext.TextRenderFormat = Qgis.TextRenderFormat
# monkey patching scoped based enum
QgsRenderContext.TextFormatAlwaysOutlines = Qgis.TextRenderFormat.AlwaysOutlines
......@@ -2449,6 +2464,16 @@ Qgis.HistoryProviderBackend.__doc__ = "History provider backends.\n\n.. versiona
Qgis.HistoryProviderBackend.baseClass = Qgis
Qgis.HistoryProviderBackends.baseClass = Qgis
HistoryProviderBackends = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.ProcessingModelChildParameterSource.ModelParameter.__doc__ = "Parameter value is taken from a parent model parameter"
Qgis.ProcessingModelChildParameterSource.ChildOutput.__doc__ = "Parameter value is taken from an output generated by a child algorithm"
Qgis.ProcessingModelChildParameterSource.StaticValue.__doc__ = "Parameter value is a static value"
Qgis.ProcessingModelChildParameterSource.Expression.__doc__ = "Parameter value is taken from an expression, evaluated just before the algorithm runs"
Qgis.ProcessingModelChildParameterSource.ExpressionText.__doc__ = "Parameter value is taken from a text with expressions, evaluated just before the algorithm runs"
Qgis.ProcessingModelChildParameterSource.ModelOutput.__doc__ = "Parameter value is linked to an output parameter for the model"
Qgis.ProcessingModelChildParameterSource.__doc__ = "Processing model child parameter sources.\n\n.. versionadded:: 3.34\n\n" + '* ``ModelParameter``: ' + Qgis.ProcessingModelChildParameterSource.ModelParameter.__doc__ + '\n' + '* ``ChildOutput``: ' + Qgis.ProcessingModelChildParameterSource.ChildOutput.__doc__ + '\n' + '* ``StaticValue``: ' + Qgis.ProcessingModelChildParameterSource.StaticValue.__doc__ + '\n' + '* ``Expression``: ' + Qgis.ProcessingModelChildParameterSource.Expression.__doc__ + '\n' + '* ``ExpressionText``: ' + Qgis.ProcessingModelChildParameterSource.ExpressionText.__doc__ + '\n' + '* ``ModelOutput``: ' + Qgis.ProcessingModelChildParameterSource.ModelOutput.__doc__
# --
Qgis.ProcessingModelChildParameterSource.baseClass = Qgis
QgsCoordinateReferenceSystem.Format = Qgis.CrsDefinitionFormat
# monkey patching scoped based enum
QgsCoordinateReferenceSystem.FormatWkt = Qgis.CrsDefinitionFormat.Wkt
......@@ -3798,7 +3823,10 @@ Qgis.TiledSceneRequestFlags.baseClass = Qgis
TiledSceneRequestFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.TiledSceneRendererFlag.RequiresTextures.__doc__ = "Renderer requires textures"
Qgis.TiledSceneRendererFlag.__doc__ = "Flags which control how tiled scene 2D renderers behave.\n\n.. versionadded:: 3.34\n\n" + '* ``RequiresTextures``: ' + Qgis.TiledSceneRendererFlag.RequiresTextures.__doc__
Qgis.TiledSceneRendererFlag.ForceRasterRender.__doc__ = "Layer should always be rendered as a raster image"
Qgis.TiledSceneRendererFlag.RendersTriangles.__doc__ = "Renderer can render triangle primitives"
Qgis.TiledSceneRendererFlag.RendersLines.__doc__ = "Renderer can render line primitives"
Qgis.TiledSceneRendererFlag.__doc__ = "Flags which control how tiled scene 2D renderers behave.\n\n.. versionadded:: 3.34\n\n" + '* ``RequiresTextures``: ' + Qgis.TiledSceneRendererFlag.RequiresTextures.__doc__ + '\n' + '* ``ForceRasterRender``: ' + Qgis.TiledSceneRendererFlag.ForceRasterRender.__doc__ + '\n' + '* ``RendersTriangles``: ' + Qgis.TiledSceneRendererFlag.RendersTriangles.__doc__ + '\n' + '* ``RendersLines``: ' + Qgis.TiledSceneRendererFlag.RendersLines.__doc__
# --
Qgis.TiledSceneRendererFlag.baseClass = Qgis
Qgis.TiledSceneRendererFlags.baseClass = Qgis
......
......@@ -116,11 +116,18 @@ Comparator for sorting of geometry.
Clears the geometry, ie reset it to a null geometry
%End
virtual QgsRectangle boundingBox() const = 0;
virtual QgsRectangle boundingBox() const;
%Docstring
Returns the minimal bounding box for the geometry
%End
virtual QgsBox3D boundingBox3D() const = 0;
%Docstring
Returns the 3D bounding box for the geometry.
.. versionadded:: 3.34
%End
virtual int dimension() const = 0;
%Docstring
......@@ -550,6 +557,16 @@ Since this test only considers the bounding box of the geometry, is is very fast
calculate and handles invalid geometries.
.. versionadded:: 3.20
%End
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
%Docstring
Returns ``True`` if the bounding box of this geometry intersects with a ``box3d``.
Since this test only considers the bounding box of the geometry, is is very fast to
calculate and handles invalid geometries.
.. versionadded:: 3.34
%End
virtual QgsAbstractGeometry *segmentize( double tolerance = M_PI / 180., SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;
......@@ -929,6 +946,15 @@ Updates the geometry type based on whether sub geometries contain z or m values.
%Docstring
Default calculator for the minimal bounding box for the geometry. Derived classes should override this method
if a more efficient bounding box calculation is available.
%End
virtual QgsBox3D calculateBoundingBox3D() const;
%Docstring
Calculates the minimal 3D bounding box for the geometry.
.. seealso:: :py:func:`calculateBoundingBox`
.. versionadded:: 3.34
%End
virtual void clearCache() const;
......
......@@ -225,7 +225,7 @@ Appends the contents of another circular ``string`` to the end of this circular
protected:
int compareToSameClass( const QgsAbstractGeometry *other ) const final;
virtual QgsRectangle calculateBoundingBox() const;
virtual QgsBox3D calculateBoundingBox3D() const;
};
......
......@@ -83,7 +83,7 @@ of the curve.
virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
virtual const QgsAbstractGeometry *simplifiedTypeRef() const /HoldGIL/;
......@@ -222,7 +222,7 @@ Appends first point if not already closed.
protected:
int compareToSameClass( const QgsAbstractGeometry *other ) const final;
virtual QgsRectangle calculateBoundingBox() const;
virtual QgsBox3D calculateBoundingBox3D() const;
};
......
......@@ -206,7 +206,7 @@ Returns a geometry without curves. Caller takes ownership
void normalize() final /HoldGIL/;
virtual QgsRectangle boundingBox() const;
virtual QgsBox3D boundingBox3D() const;
virtual bool isValid( QString &error /Out/, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;
......
......@@ -72,7 +72,7 @@ Curve polygon geometry type
virtual bool removeDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false );
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
double roundness() const;
......@@ -342,7 +342,7 @@ Returns approximate rotation angle for a vertex. Usually average angle between a
protected:
virtual QgsRectangle calculateBoundingBox() const;
virtual QgsBox3D calculateBoundingBox3D() const;
};
......
......@@ -1103,6 +1103,13 @@ intersect the other geometry.
Returns the bounding box of the geometry.
.. seealso:: :py:func:`orientedMinimumBoundingBox`
%End
QgsBox3D boundingBox3D() const;
%Docstring
Returns the 3D bounding box of the geometry.
.. versionadded:: 3.34
%End
QgsGeometry orientedMinimumBoundingBox( double &area /Out/, double &angle /Out/, double &width /Out/, double &height /Out/ ) const;
......
......@@ -104,7 +104,7 @@ Returns a geometry from within the collection.
virtual int vertexNumberFromVertexId( QgsVertexId id ) const;
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
void reserve( int size ) /HoldGIL/;
......@@ -181,7 +181,7 @@ Removes a geometry from the collection by index.
virtual QString asKml( int precision = 17 ) const;
virtual QgsRectangle boundingBox() const;
virtual QgsBox3D boundingBox3D() const;
virtual QgsCoordinateSequence coordinateSequence() const;
......@@ -342,7 +342,7 @@ Returns whether child type names are omitted from Wkt representations of the col
Reads a collection from a WKT string.
%End
virtual QgsRectangle calculateBoundingBox() const;
virtual QgsBox3D calculateBoundingBox3D() const;
virtual void clearCache() const;
......
......@@ -605,6 +605,8 @@ segment in the line.
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
QVector< QgsVertexId > collectDuplicateNodes( double epsilon = 4 * DBL_EPSILON, bool useZValues = false ) const;
%Docstring
......@@ -840,20 +842,31 @@ corresponds to the last point in the line.
%End
QgsBox3D calculateBoundingBox3d() const;
QgsBox3D calculateBoundingBox3d() const /Deprecated/;
%Docstring
Calculates the minimal 3D bounding box for the geometry.
Deprecated: use calculateBoundingBox3D instead
.. seealso:: :py:func:`calculateBoundingBox`
.. versionadded:: 3.26
.. deprecated:: QGIS 3.34
%End
virtual QgsBox3D calculateBoundingBox3D() const;
%Docstring
Calculates the minimal 3D bounding box for the geometry.
.. seealso:: :py:func:`calculateBoundingBox`
.. versionadded:: 3.34
%End
protected:
int compareToSameClass( const QgsAbstractGeometry *other ) const final;
virtual QgsRectangle calculateBoundingBox() const;
};
......
......@@ -367,7 +367,7 @@ Example
void normalize() final /HoldGIL/;
virtual bool isEmpty() const /HoldGIL/;
virtual QgsRectangle boundingBox() const /HoldGIL/;
virtual QgsBox3D boundingBox3D() const /HoldGIL/;
virtual QString geometryType() const /HoldGIL/;
......@@ -454,6 +454,8 @@ Angle undefined. Always returns 0.0
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
virtual bool boundingBoxIntersects( const QgsBox3D &box3d ) const /HoldGIL/;
virtual bool addZValue( double zValue = 0 );
......
......@@ -27,7 +27,7 @@ Gets a polygon representation of this surface.
Ownership is transferred to the caller.
%End
virtual QgsRectangle boundingBox() const;
virtual QgsBox3D boundingBox3D() const;
virtual bool isValid( QString &error /Out/, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const;
......
......@@ -23,6 +23,9 @@ Handles rendering and exports of layouts to various formats.
%End
public:
struct PageExportDetails
{
QString directory;
......@@ -210,7 +213,6 @@ Constructor for PdfExportSettings
QStringList exportThemes;
QVector<qreal> predefinedMapScales;
};
ExportResult exportToPdf( const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings );
......
......@@ -33,6 +33,7 @@ Stores information relating to the current rendering settings for a layout.
FlagDisableTiledRasterLayerRenders,
FlagRenderLabelsByMapLayer,
FlagLosslessImageRendering,
FlagSynchronousLegendGraphics
};
typedef QFlags<QgsLayoutRenderContext::Flag> Flags;
......
......@@ -540,7 +540,7 @@ parameter ``source``, and ``description``.
QString description;
};
QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition > variablesForChildAlgorithm( const QString &childId, QgsProcessingContext &context, const QVariantMap &modelParameters = QVariantMap(),
QMap< QString, QgsProcessingModelAlgorithm::VariableDefinition > variablesForChildAlgorithm( const QString &childId, QgsProcessingContext *context = 0, const QVariantMap &modelParameters = QVariantMap(),
const QVariantMap &results = QVariantMap() ) const;
%Docstring
Returns a map of variable name to variable definition for expression context variables which are available
......
......@@ -23,16 +23,6 @@ Source for the value of a parameter for a child algorithm within a model.
%End
public:
enum Source
{
ModelParameter,
ChildOutput,
StaticValue,
Expression,
ExpressionText,
ModelOutput,
};
QgsProcessingModelChildParameterSource();
%Docstring
Constructor for QgsProcessingModelChildParameterSource. It is recommended that the static methods
......@@ -118,12 +108,12 @@ algorithms already executed by the model.
.. versionadded:: 3.2
%End
Source source() const;
Qgis::ProcessingModelChildParameterSource source() const;
%Docstring
Returns the parameter value's source.
%End
void setSource( Source source );
void setSource( Qgis::ProcessingModelChildParameterSource source );
%Docstring
Sets the parameter's source.
......
......@@ -41,6 +41,7 @@ expression context.
{
DefaultLevel,
Verbose,
ModelDebug,
};
QgsProcessingContext();
......
......@@ -10,7 +10,6 @@
class QgsProcessingOutputDefinition
{
%Docstring(signature="appended")
......@@ -53,6 +52,8 @@ as generated layers or calculated values.
sipType = sipType_QgsProcessingOutputFile;
else if ( sipCpp->type() == QgsProcessingOutputConditionalBranch::typeName() )
sipType = sipType_QgsProcessingOutputConditionalBranch;
else if ( sipCpp->type() == QgsProcessingOutputVariant::typeName() )
sipType = sipType_QgsProcessingOutputVariant;
else
sipType = nullptr;
%End
......@@ -310,6 +311,33 @@ Returns the type name for the output class.
virtual QString type() const;
};
class QgsProcessingOutputVariant : QgsProcessingOutputDefinition
{
%Docstring(signature="appended")
A variant output for processing algorithms, capable of storing any QVariant value.
.. versionadded:: 3.34
%End
%TypeHeaderCode
#include "qgsprocessingoutputs.h"
%End
public:
QgsProcessingOutputVariant( const QString &name, const QString &description = QString() );
%Docstring
Constructor for QgsProcessingOutputVariant.
%End
static QString typeName();
%Docstring
Returns the type name for the output class.
%End
virtual QString type() const;
};
class QgsProcessingOutputNumber : QgsProcessingOutputDefinition
{
%Docstring(signature="appended")
......
......@@ -1645,6 +1645,15 @@ just before a new project is read).
.. seealso:: :py:func:`clear`
.. versionadded:: 3.2
%End
void aboutToBeCleared();
%Docstring
Emitted when the project is about to be cleared.
.. seealso:: :py:func:`clear`
.. versionadded:: 3.34
%End
void readProject( const QDomDocument & );
......
......@@ -955,6 +955,13 @@ The development version
typedef QFlags<Qgis::MapLayerProperty> MapLayerProperties;
enum class AutoRefreshMode
{
Disabled,
ReloadData,
RedrawOnly,
};
enum class DataProviderFlag
{
IsBasemapSource,
......@@ -1166,6 +1173,15 @@ The development version
typedef QFlags<Qgis::RenderContextFlag> RenderContextFlags;
enum class MapLayerRendererFlag
{
RenderPartialOutputs,
RenderPartialOutputOverPreviousCachedImage,
};
typedef QFlags<Qgis::MapLayerRendererFlag> MapLayerRendererFlags;
enum class TextRenderFormat
{
......@@ -1466,6 +1482,16 @@ The development version
typedef QFlags<Qgis::HistoryProviderBackend> HistoryProviderBackends;
enum class ProcessingModelChildParameterSource
{
ModelParameter,
ChildOutput,
StaticValue,
Expression,
ExpressionText,
ModelOutput,
};
enum class CrsDefinitionFormat
{
Wkt,
......@@ -2199,6 +2225,9 @@ The development version
enum class TiledSceneRendererFlag
{
RequiresTextures,
ForceRasterRender,
RendersTriangles,
RendersLines,
};
typedef QFlags<Qgis::TiledSceneRendererFlag> TiledSceneRendererFlags;
......@@ -2303,6 +2332,8 @@ QFlags<Qgis::AnnotationItemGuiFlag> operator|(Qgis::AnnotationItemGuiFlag f1, QF
QFlags<Qgis::MapSettingsFlag> operator|(Qgis::MapSettingsFlag f1, QFlags<Qgis::MapSettingsFlag> f2);
QFlags<Qgis::MapLayerRendererFlag> operator|(Qgis::MapLayerRendererFlag f1, QFlags<Qgis::MapLayerRendererFlag> f2);
QFlags<Qgis::RenderContextFlag> operator|(Qgis::RenderContextFlag f1, QFlags<Qgis::RenderContextFlag> f2);
QFlags<Qgis::VectorLayerTypeFlag> operator|(Qgis::VectorLayerTypeFlag f1, QFlags<Qgis::VectorLayerTypeFlag> f2);
......
......@@ -30,7 +30,8 @@ Returns the icon for a vector layer whose geometry ``type`` is provided.
static QIcon iconForGeometryType( Qgis::GeometryType typeGroup );
%Docstring
Returns the icon for a vector layer whose geometry ``typeGroup`` is provided.
1since QGIS 3.28
.. versionadded:: 3.28
%End
static QIcon iconPoint();
......
......@@ -393,6 +393,24 @@ Returns the size (in millimeters) of WMS legend graphics shown in the legend.
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
.. seealso:: :py:func:`wmsLegendSize`
%End
void setSynchronousLegendRequests( bool b );
%Docstring
Sets whether to request legend graphics synchronously.
.. seealso:: :py:func:`synchronousLegendRequests`
.. versionadded:: 3.34
%End
bool synchronousLegendRequests() const;
%Docstring
Returns whether to request legend graphics synchronously.
.. seealso:: :py:func:`setSynchronousLegendRequests`
.. versionadded:: 3.34
%End
double lineSpacing() const /Deprecated/;
......
......@@ -1162,16 +1162,32 @@ Write just the symbology information for the layer into the document
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag = false );
%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
Updates the data source of the layer.
This method was defined in :py:class:`QgsVectorLayer` since 2.10 and was marked as deprecated since 3.2
The ``dataSource`` argument must specify the new data source string for the layer. The format varies depending on
the specified data ``provider`` in use. See :py:class:`QgsDataSourceUri` and the documentation for the various :py:class:`QgsMapLayer`
subclasses for further details on data source strings.
The ``baseName`` argument specifies the user-visible name to use for the layer. (See :py:func:`~QgsMapLayer.name` or :py:func:`~QgsMapLayer.setName`).
The ``provider`` argument is used to specify the unique key of the data provider to use for
the layer. This must match one of the values returned by :py:func:`QgsProviderRegistry.instance()`->:py:func:`~QgsMapLayer.providerList`.
(See :py:func:`~QgsMapLayer.providerType`).
If ``loadDefaultStyleFlag`` is set to ``True`` then the layer's existing style will be reset to the default
for the data source.
.. note::
:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param loadDefaultStyleFlag: set to ``True`` to reset the layer's style to the default for the
data source
If ``loadDefaultStyleFlag`` is ``False`` then the layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
After setting a new data source callers can test :py:func:`~QgsMapLayer.isValid` to determine whether the new source
and provider are valid and ready for use. If setting the new data source fails and the layer
returns ``False`` to :py:func:`~QgsMapLayer.isValid`, then descriptive errors relating to setting the data source can
be retrieved by calling :py:func:`~QgsMapLayer.error`.
This method was defined in :py:class:`QgsVectorLayer` since 2.10 and was marked as deprecated since 3.2
.. seealso:: :py:func:`dataSourceChanged`
......@@ -1180,15 +1196,32 @@ This method was defined in :py:class:`QgsVectorLayer` since 2.10 and was marked
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag = false );
%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
Updates the data source of the layer.
The ``dataSource`` argument must specify the new data source string for the layer. The format varies depending on
the specified data ``provider`` in use. See :py:class:`QgsDataSourceUri` and the documentation for the various :py:class:`QgsMapLayer`
subclasses for further details on data source strings.
The ``baseName`` argument specifies the user-visible name to use for the layer. (See :py:func:`~QgsMapLayer.name` or :py:func:`~QgsMapLayer.setName`).
:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param options: provider options
:param loadDefaultStyleFlag: set to ``True`` to reset the layer's style to the default for the
data source
The ``provider`` argument is used to specify the unique key of the data provider to use for
the layer. This must match one of the values returned by :py:func:`QgsProviderRegistry.instance()`->:py:func:`~QgsMapLayer.providerList`.
(See :py:func:`~QgsMapLayer.providerType`).
The ``options`` argument can be used to pass additional layer properties to the new data provider.
If ``loadDefaultStyleFlag`` is set to ``True`` then the layer's existing style will be reset to the default
for the data source.
.. note::
If ``loadDefaultStyleFlag`` is ``False`` then the layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
After setting a new data source callers can test :py:func:`~QgsMapLayer.isValid` to determine whether the new source
and provider are valid and ready for use. If setting the new data source fails and the layer
returns ``False`` to :py:func:`~QgsMapLayer.isValid`, then descriptive errors relating to setting the data source can
be retrieved by calling :py:func:`~QgsMapLayer.error`.
.. seealso:: :py:func:`dataSourceChanged`
......@@ -1197,16 +1230,32 @@ if the geometry type of the new data source matches the current geometry type of
void setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags );
%Docstring
Updates the data source of the layer. The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
Updates the data source of the layer.
The ``dataSource`` argument must specify the new data source string for the layer. The format varies depending on
the specified data ``provider`` in use. See :py:class:`QgsDataSourceUri` and the documentation for the various :py:class:`QgsMapLayer`
subclasses for further details on data source strings.
The ``baseName`` argument specifies the user-visible name to use for the layer. (See :py:func:`~QgsMapLayer.name` or :py:func:`~QgsMapLayer.setName`).
The ``provider`` argument is used to specify the unique key of the data provider to use for
the layer. This must match one of the values returned by :py:func:`QgsProviderRegistry.instance()`->:py:func:`~QgsMapLayer.providerList`.
(See :py:func:`~QgsMapLayer.providerType`).
The ``options`` argument can be used to pass additional layer properties to the new data provider.
Subclasses should override setDataSourcePrivate: default implementation does nothing.
The ``flags`` argument specifies provider read flags which control the data provider construction,
such as :py:class:`QgsDataProvider`.ReadFlag.FlagTrustDataSource, :py:class:`QgsDataProvider`.ReadFlag.FlagLoadDefaultStyle, etc.
:param dataSource: new layer data source
:param baseName: base name of the layer
:param provider: provider string
:param options: provider options
:param flags: provider read flags which control dataprovider construction like FlagTrustDataSource, FlagLoadDefaultStyle, etc
.. note::
The layer's renderer and legend will be preserved only
if the geometry type of the new data source matches the current geometry type of the layer.
After setting a new data source callers can test :py:func:`~QgsMapLayer.isValid` to determine whether the new source
and provider are valid and ready for use. If setting the new data source fails and the layer
returns ``False`` to :py:func:`~QgsMapLayer.isValid`, then descriptive errors relating to setting the data source can
be retrieved by calling :py:func:`~QgsMapLayer.error`.
.. seealso:: :py:func:`dataSourceChanged`
......@@ -1356,7 +1405,7 @@ Returns whether scale based visibility is enabled for the layer.
.. seealso:: :py:func:`isInScaleRange`
%End
bool hasAutoRefreshEnabled() const;
bool hasAutoRefreshEnabled() const /Deprecated/;
%Docstring
Returns ``True`` if auto refresh is enabled for the layer.
......@@ -1364,7 +1413,19 @@ Returns ``True`` if auto refresh is enabled for the layer.
.. seealso:: :py:func:`setAutoRefreshEnabled`
.. versionadded:: 3.0
.. deprecated::
use :py:func:`~QgsMapLayer.autoRefreshMode` instead.
%End
Qgis::AutoRefreshMode autoRefreshMode() const;
%Docstring
Returns the layer's automatical refresh mode.
.. seealso:: :py:func:`autoRefreshInterval`
.. seealso:: :py:func:`setAutoRefreshMode`
.. versionadded:: 3.34
%End
int autoRefreshInterval() const;
......@@ -1383,7 +1444,7 @@ auto refresh is only active when :py:func:`~QgsMapLayer.hasAutoRefreshEnabled` i
%Docstring
Sets the auto refresh interval (in milliseconds) for the layer. This
will cause the layer to be automatically redrawn on a matching interval.
Note that auto refresh must be enabled by calling :py:func:`~QgsMapLayer.setAutoRefreshEnabled`.
Note that auto refresh must be enabled by calling :py:func:`~QgsMapLayer.setAutoRefreshMode`.
Note that auto refresh triggers deferred repaints of the layer. Any map
canvas must be refreshed separately in order to view the refreshed layer.
......@@ -1395,7 +1456,7 @@ canvas must be refreshed separately in order to view the refreshed layer.
.. versionadded:: 3.0
%End
void setAutoRefreshEnabled( bool enabled );
void setAutoRefreshEnabled( bool enabled ) /Deprecated/;
%Docstring
Sets whether auto refresh is enabled for the layer.
......@@ -1403,7 +1464,19 @@ Sets whether auto refresh is enabled for the layer.
.. seealso:: :py:func:`setAutoRefreshInterval`
.. versionadded:: 3.0
.. deprecated::
Use :py:func:`~QgsMapLayer.setAutoRefreshMode` instead.
%End
void setAutoRefreshMode( Qgis::AutoRefreshMode mode );
%Docstring
Sets the automatic refresh mode for the layer.
.. seealso:: :py:func:`autoRefreshMode`
.. seealso:: :py:func:`setAutoRefreshInterval`
.. versionadded:: 3.34
%End
virtual const QgsLayerMetadata &metadata() const;
......
......@@ -30,6 +30,7 @@ how an individual :py:class:`QgsMapLayer` behaves with relation to z values or e
#include "qgsrasterlayerelevationproperties.h"
#include "qgsvectorlayerelevationproperties.h"
#include "qgsmeshlayerelevationproperties.h"
#include "qgstiledscenelayerelevationproperties.h"
%End
%ConvertToSubClassCode
if ( qobject_cast<QgsPointCloudLayerElevationProperties *>( sipCpp ) )
......@@ -48,6 +49,10 @@ how an individual :py:class:`QgsMapLayer` behaves with relation to z values or e
{
sipType = sipType_QgsMeshLayerElevationProperties;
}
else if ( qobject_cast<QgsTiledSceneLayerElevationProperties *>( sipCpp ) )
{
sipType = sipType_QgsTiledSceneLayerElevationProperties;
}
else
{
sipType = 0;
......
......@@ -71,6 +71,13 @@ Subclasses should return ``True`` whenever their corresponding layer settings re
layer to always be rendered using a raster paint device.
.. versionadded:: 3.18
%End
virtual Qgis::MapLayerRendererFlags flags() const;
%Docstring
Returns flags which control how the map layer rendering behaves.
.. versionadded:: 3.34
%End
virtual QgsFeedback *feedback() const;
......
......@@ -51,6 +51,11 @@ Initializes matrix by setting all values in row-major order
QList< double > dataList() const /PyName=data,HoldGIL/;
%Docstring
Returns matrix data (in column-major order)
%End
void translate( const QgsVector3D &vector );
%Docstring
Multiplies this matrix by another that translates coordinates by the components of a ``vector``.
%End
QgsVector3D map( const QgsVector3D &vector ) const /HoldGIL/;
......
......@@ -84,6 +84,18 @@ Returns the destination QPainter for the render operation.
%End
QPainter *previewRenderPainter();
%Docstring
Returns the const destination QPainter for temporary in-progress preview renders.
May be ``None`` if temporary in-progress preview renders are not required.
.. seealso:: :py:func:`setPreviewRenderPainter`
.. versionadded:: 3.34
%End
void setPainterFlagsUsingContext( QPainter *painter = 0 ) const;
%Docstring
Sets relevant flags on a destination ``painter``, using the flags and settings
......@@ -554,6 +566,19 @@ is not transferred and the QPainter destination must stay alive for the duration
of any rendering operations.
.. seealso:: :py:func:`painter`
%End
void setPreviewRenderPainter( QPainter *painter );
%Docstring
Sets the destination ``painter`` for temporary in-progress preview renders.
Ownership of ``painter`` is not transferred and the QPainter destination must
stay alive for the duration of any rendering operations.
``painter`` may be ``None`` if temporary in-progress preview renders are not required.
.. seealso:: :py:func:`previewRenderPainter`
.. versionadded:: 3.34
%End
void setMaskPainter( QPainter *p, int id = 0 );
......
......@@ -25,7 +25,7 @@ Represents an individual category (class) from a :py:class:`QgsCategorizedSymbol
Constructor for QgsRendererCategory.
%End
QgsRendererCategory( const QVariant &value, QgsSymbol *symbol /Transfer/, const QString &label, bool render = true );
QgsRendererCategory( const QVariant &value, QgsSymbol *symbol /Transfer/, const QString &label, bool render = true, const QString &uuid = QString() );
%Docstring
Constructor for a new QgsRendererCategory, with the specified ``value`` and ``symbol``.
......@@ -36,6 +36,8 @@ The ownership of ``symbol`` is transferred to the category.
The ``label`` argument specifies the label used for this category in legends and the layer tree.
The ``render`` argument indicates whether the category should initially be rendered and appear checked in the layer tree.
The optional ``uuid`` argument manually set the UUID key identifier for the category (since QGIS 3.34).
%End
QgsRendererCategory( const QgsRendererCategory &cat );
......@@ -44,6 +46,13 @@ Copy constructor.
%End
~QgsRendererCategory();
QString uuid() const;
%Docstring
Returns the unique identifier for this category.
.. versionadded:: 3.34
%End
QVariant value() const;
%Docstring
Returns the value corresponding to this category.
......
......@@ -26,20 +26,39 @@ Constructor for QgsRendererRange.
%End
~QgsRendererRange();
QgsRendererRange( const QgsClassificationRange &range, QgsSymbol *symbol /Transfer/, bool render = true );
QgsRendererRange( const QgsClassificationRange &range, QgsSymbol *symbol /Transfer/, bool render = true, const QString &uuid = QString() );
%Docstring
Creates a renderer symbol range
:param range: The classification range
:param symbol: The symbol for this renderer range
:param render: If ``True``, it will be renderered
:param uuid: Optional parameter to manually set the UUID key identifier for the this range (since QGIS 3.34).
%End
QgsRendererRange( double lowerValue, double upperValue, QgsSymbol *symbol /Transfer/, const QString &label, bool render = true, const QString &uuid = QString() );
%Docstring
Creates a renderer symbol range
:param lowerValue: The lower bound of the range
:param upperValue: The upper bound of the range
:param symbol: The symbol for this renderer range
:param label: The label used for the range
:param render: If ``True``, it will be renderered
:param uuid: Optional parameter to manually set the UUID key identifier for the this range (since QGIS 3.34).
%End
QgsRendererRange( double lowerValue, double upperValue, QgsSymbol *symbol /Transfer/, const QString &label, bool render = true );
QgsRendererRange( const QgsRendererRange &range );
bool operator<( const QgsRendererRange &other ) const;
QString uuid() const;
%Docstring
Returns the unique identifier for this range.
.. versionadded:: 3.34
%End
double lowerValue() const;
%Docstring
Returns the lower bound of the range.
......
......@@ -47,15 +47,29 @@ Parses a ``sphere`` object from a Cesium JSON document.
Applies a ``transform`` to a sphere.
%End
static QByteArray extractGltfFromB3dm( const QByteArray &tileContent );
struct B3DMContents
{
QByteArray gltf;
QgsVector3D rtcCenter;
};
static B3DMContents extractGltfFromB3dm( const QByteArray &tileContent );
%Docstring
Extracts GLTF binary data from the legacy b3dm (Batched 3D Model) tile format.
Extracts GLTF binary data and other contents from the legacy b3dm (Batched 3D Model) tile format.
Returns empty byte array on error.
%End
static QByteArray extractGltfFromTileContent( const QByteArray &tileContent );
struct TileContents
{
QByteArray gltf;
QgsVector3D rtcCenter;
};
static TileContents extractGltfFromTileContent( const QByteArray &tileContent );
%Docstring
Extracts GLTF binary data from tile content.
Parses tile content.
Returns empty byte array on error.
.. note::
......
......@@ -88,6 +88,11 @@ implementation.
The index is thread safe and can be used safely across multiple threads or transferred between
threads.
%End
virtual QgsDoubleRange zRange() const;
%Docstring
Returns the provider's z range, or an infinite range if this is not known.
%End
};
......
......@@ -91,6 +91,8 @@ QgsTiledSceneLayer cannot be copied.
virtual QString loadDefaultMetadata( bool &resultFlag /Out/ );
virtual QgsMapLayerElevationProperties *elevationProperties();
QgsTiledSceneRenderer *renderer();
%Docstring
......
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/tiledscene/qgstiledscenelayerelevationproperties.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsTiledSceneLayerElevationProperties : QgsMapLayerElevationProperties
{
%Docstring(signature="appended")
Tiled scene layer specific subclass of :py:class:`QgsMapLayerElevationProperties`.
.. versionadded:: 3.34
%End
%TypeHeaderCode
#include "qgstiledscenelayerelevationproperties.h"
%End
public:
QgsTiledSceneLayerElevationProperties( QObject *parent /TransferThis/ );
%Docstring
Constructor for QgsTiledSceneLayerElevationProperties, with the specified ``parent`` object.
%End
virtual bool hasElevation() const;
virtual QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context );
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
virtual QgsTiledSceneLayerElevationProperties *clone() const /Factory/;
virtual QString htmlSummary() const;
virtual QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const;
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/tiledscene/qgstiledscenelayerelevationproperties.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
......@@ -245,6 +245,11 @@ Returns a list of all rule keys for legend nodes created by the renderer.
virtual void renderTriangle( QgsTiledSceneRenderContext &context, const QPolygonF &triangle ) = 0;
%Docstring
Renders a ``triangle``.
%End
virtual void renderLine( QgsTiledSceneRenderContext &context, const QPolygonF &line ) = 0;
%Docstring
Renders a ``line``.
%End
protected:
......
......@@ -9,6 +9,7 @@
class QgsTiledSceneTextureRenderer : QgsTiledSceneRenderer
{
%Docstring(signature="appended")
......@@ -26,6 +27,7 @@ Renders tiled scene layers using textures.
%Docstring
Constructor for QgsTiledSceneTextureRenderer.
%End
~QgsTiledSceneTextureRenderer();
virtual QString type() const;
......@@ -37,10 +39,39 @@ Constructor for QgsTiledSceneTextureRenderer.
virtual void renderTriangle( QgsTiledSceneRenderContext &context, const QPolygonF &triangle );
virtual void renderLine( QgsTiledSceneRenderContext &context, const QPolygonF &line );
virtual void startRender( QgsTiledSceneRenderContext &context );
virtual void stopRender( QgsTiledSceneRenderContext &context );
static QgsTiledSceneRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) /Factory/;
%Docstring
Creates a textured renderer from an XML ``element``.
%End
static QgsFillSymbol *createDefaultFillSymbol() /Factory/;
%Docstring
Returns a copy of the default fill symbol used to render triangles without textures.
.. seealso:: :py:func:`setFillSymbol`
%End
QgsFillSymbol *fillSymbol() const;
%Docstring
Returns the fill symbol used to render triangles without textures.
.. seealso:: :py:func:`setFillSymbol`
%End
void setFillSymbol( QgsFillSymbol *symbol /Transfer/ );
%Docstring
Sets the fill ``symbol`` used to render triangles without textures.
Ownership of ``symbol`` is transferred.
.. seealso:: :py:func:`fillSymbol`
%End
};
......
......@@ -37,6 +37,8 @@ Constructor for QgsTiledSceneWireframeRenderer.
virtual void renderTriangle( QgsTiledSceneRenderContext &context, const QPolygonF &triangle );
virtual void renderLine( QgsTiledSceneRenderContext &context, const QPolygonF &line );
virtual void startRender( QgsTiledSceneRenderContext &context );
virtual void stopRender( QgsTiledSceneRenderContext &context );
......@@ -49,7 +51,7 @@ Constructor for QgsTiledSceneWireframeRenderer.
Creates a textured renderer from an XML ``element``.
%End
static QgsFillSymbol *createDefaultfillSymbol() /Factory/;
static QgsFillSymbol *createDefaultFillSymbol() /Factory/;
%Docstring
Returns a copy of the default fill symbol used to render triangles in the wireframe.
......@@ -70,6 +72,29 @@ Sets the fill ``symbol`` used to render triangles in the wireframe.
Ownership of ``symbol`` is transferred.
.. seealso:: :py:func:`fillSymbol`
%End
static QgsLineSymbol *createDefaultLineSymbol() /Factory/;
%Docstring
Returns a copy of the default line symbol used to render lines in the wireframe.
.. seealso:: :py:func:`setLineSymbol`
%End
QgsLineSymbol *lineSymbol() const;
%Docstring
Returns the line symbol used to render lines in the wireframe.
.. seealso:: :py:func:`setLineSymbol`
%End
void setLineSymbol( QgsLineSymbol *symbol /Transfer/ );
%Docstring
Sets the line ``symbol`` used to render lines in the wireframe.
Ownership of ``symbol`` is transferred.
.. seealso:: :py:func:`lineSymbol`
%End
bool useTextureColors() const;
......
......@@ -717,6 +717,7 @@
%Include auto_generated/tiledscene/qgstiledscenedataprovider.sip
%Include auto_generated/tiledscene/qgstiledsceneindex.sip
%Include auto_generated/tiledscene/qgstiledscenelayer.sip
%Include auto_generated/tiledscene/qgstiledscenelayerelevationproperties.sip
%Include auto_generated/tiledscene/qgstiledscenerenderer.sip
%Include auto_generated/tiledscene/qgstiledscenerendererregistry.sip
%Include auto_generated/tiledscene/qgstiledscenerequest.sip
......
......@@ -123,6 +123,15 @@ to :py:func:`QgsApplication.nullRepresentation()`.
.. seealso:: :py:func:`nullRepresentation`
.. versionadded:: 3.14
%End
virtual bool event( QEvent *event );
%Docstring
Reimplemented to enable/disable the clear action
depending on read-only status
.. versionadded:: 3.34
%End
signals:
......
......@@ -173,7 +173,7 @@ Sets the parent ``dialog`` in which the widget is shown.
virtual QgsExpressionContext createExpressionContext() const;
void setSourceType( QgsProcessingModelChildParameterSource::Source type );
void setSourceType( Qgis::ProcessingModelChildParameterSource type );
%Docstring
Sets the current source ``type`` for the parameter.
......
......@@ -602,7 +602,7 @@ and should give helpful text to users to indicate the expected results from the
This is purely a text format and no expression validation is made against it.
%End
virtual QgsProcessingModelChildParameterSource::Source defaultModelSource( const QgsProcessingParameterDefinition *parameter ) const;
virtual Qgis::ProcessingModelChildParameterSource defaultModelSource( const QgsProcessingParameterDefinition *parameter ) const;
%Docstring
Returns the default source type to use for the widget for the specified ``parameter``.
......
......@@ -39,7 +39,7 @@ from qgis.PyQt.QtGui import QColor
from qgis.core import (Qgis, QgsApplication, QgsCoordinateReferenceSystem,
QgsCoordinateTransform, QgsGeometry, QgsPointXY,
QgsProviderRegistry, QgsSettings, QgsProject,
QgsRectangle)
QgsRectangle, QgsSettingsTree)
from qgis.gui import QgsRubberBand, QgsGui
from qgis.utils import OverrideCursor
......@@ -718,35 +718,38 @@ class MetaSearchDialog(QDialog, BASE_CLASS):
caller = self.sender().objectName()
# stype = human name,/qgis/connections-%s,providername
if caller == 'mActionAddWms':
stype = ['OGC:WMS/OGC:WMTS', 'wms', 'wms']
service_type = 'OGC:WMS/OGC:WMTS'
sname = 'WMS'
dyn_param = ['wms']
provider_name = 'wms'
setting_node = QgsSettingsTree.node('connections').childNode('ows').childNode('connections')
data_url = item_data['wms']
elif caller == 'mActionAddWfs':
stype = ['OGC:WFS', 'wfs', 'WFS']
service_type = 'OGC:WFS'
sname = 'WFS'
dyn_param = ['wfs']
provider_name = 'WFS'
setting_node = QgsSettingsTree.node('connections').childNode('ows').childNode('connections')
data_url = item_data['wfs']
elif caller == 'mActionAddWcs':
stype = ['OGC:WCS', 'wcs', 'wcs']
service_type = 'OGC:WCS'
sname = 'WCS'
dyn_param = ['wcs']
provider_name = 'wcs'
setting_node = QgsSettingsTree.node('connections').childNode('ows').childNode('connections')
data_url = item_data['wcs']
elif caller == 'mActionAddAms':
stype = ['ESRI:ArcGIS:MapServer', 'ams', 'arcgismapserver']
data_url = item_data['ams'].split('MapServer')[0] + 'MapServer'
elif caller == 'mActionAddAfs':
stype = ['ESRI:ArcGIS:FeatureServer', 'afs', 'arcgisfeatureserver']
data_url = (item_data['afs'].split('FeatureServer')[0] +
'FeatureServer')
service_type = 'ESRI:ArcGIS:FeatureServer'
sname = 'AFS'
dyn_param = []
provider_name = 'arcgisfeatureserver'
setting_node = QgsSettingsTree.node('connections').childNode('arcgisfeatureserver')
data_url = (item_data['afs'].split('FeatureServer')[0] + 'FeatureServer')
sname = '%s from MetaSearch' % stype[1]
# store connection
# check if there is a connection with same name
if caller in ['mActionAddAms', 'mActionAddAfs']:
self.settings.beginGroup('/qgis/connections-%s' % stype[2])
else:
self.settings.beginGroup('/qgis/connections-%s' % stype[1])
keys = self.settings.childGroups()
self.settings.endGroup()
keys = setting_node.items(dyn_param)
sname = '%s from MetaSearch' % sname
for key in keys:
if key.startswith(sname):
conn_name_matches.append(key)
......@@ -765,19 +768,14 @@ class MetaSearchDialog(QDialog, BASE_CLASS):
return
# no dups detected or overwrite is allowed
if caller in ['mActionAddAms', 'mActionAddAfs']:
self.settings.beginGroup('/qgis/connections-%s' % stype[2])
else:
self.settings.beginGroup('/qgis/connections-%s' % stype[1])
self.settings.setValue('/%s/url' % sname, clean_ows_url(data_url))
self.settings.endGroup()
dyn_param.append(sname)
setting_node.childSetting('url').setValue(clean_ows_url(data_url), dyn_param)
# open provider window
ows_provider = QgsGui.sourceSelectProviderRegistry().\
createSelectionWidget(
stype[2], self, Qt.Widget,
provider_name, self, Qt.Widget,
QgsProviderRegistry.WidgetMode.Embedded)
service_type = stype[0]
# connect dialog signals to iface slots
if service_type == 'OGC:WMS/OGC:WMTS':
......@@ -795,10 +793,6 @@ class MetaSearchDialog(QDialog, BASE_CLASS):
ows_provider.addRasterLayer.connect(self.iface.addRasterLayer)
conn_cmb = ows_provider.findChild(QWidget, 'mConnectionsComboBox')
connect = 'mConnectButton_clicked'
elif service_type == 'ESRI:ArcGIS:MapServer':
ows_provider.addRasterLayer.connect(self.iface.addRasterLayer)
conn_cmb = ows_provider.findChild(QComboBox)
connect = 'connectToServer'
elif service_type == 'ESRI:ArcGIS:FeatureServer':
def addAfsLayer(path, name):
self.iface.addVectorLayer(path, name, 'afs')
......@@ -817,7 +811,7 @@ class MetaSearchDialog(QDialog, BASE_CLASS):
# only for wfs
if service_type == 'OGC:WFS':
ows_provider.cmbConnections_activated(index)
elif service_type in ['ESRI:ArcGIS:MapServer', 'ESRI:ArcGIS:FeatureServer']: # noqa
elif service_type == 'ESRI:ArcGIS:FeatureServer':
ows_provider.cmbConnections_activated(index)
getattr(ows_provider, connect)()
......
......@@ -348,6 +348,13 @@ class PostGisDBConnector(DBConnector):
self._close_cursor(c)
return res
def getPsqlVersion(self):
regex = r"^PostgreSQL\s([0-9]{1,2})"
match = re.match(regex, self.getInfo()[0])
if match:
return int(match.group(1))
raise DbError(f"Unknown PostgreSQL version: {self.getInfo()[0]}")
def getSpatialInfo(self):
""" returns tuple about PostGIS support:
- lib version
......@@ -644,7 +651,7 @@ class PostGisDBConnector(DBConnector):
schema, tablename = self.getSchemaTableName(table)
schema_where = " AND nspname=%s " % self.quoteString(schema) if schema is not None else ""
version_number = int(self.getInfo()[0].split(' ')[1].split('.')[0])
version_number = self.getPsqlVersion()
ad_col_name = 'adsrc' if version_number < 12 else 'adbin'
sql = """SELECT a.attnum AS ordinal_position,
......@@ -692,7 +699,7 @@ class PostGisDBConnector(DBConnector):
schema, tablename = self.getSchemaTableName(table)
schema_where = " AND nspname=%s " % self.quoteString(schema) if schema is not None else ""
version_number = int(self.getInfo()[0].split(' ')[1].split('.')[0])
version_number = self.getPsqlVersion()
con_col_name = 'consrc' if version_number < 12 else 'conbin'
# In the query below, we exclude rows where pg_constraint.contype whose values are equal to 't'
......
......@@ -23,11 +23,14 @@ import os
from qgis.PyQt import uic
from qgis.core import (QgsExpressionContextScope,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsExpression,
QgsProcessingModelChildParameterSource)
from qgis.core import (
Qgis,
QgsExpressionContextScope,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsExpression,
QgsProcessingModelChildParameterSource
)
from qgis.gui import QgsFieldExpressionWidget
......@@ -78,7 +81,7 @@ class ExecuteSQLWidget(BASE, WIDGET):
if isinstance(value, list):
for v in value:
if isinstance(v, QgsProcessingModelChildParameterSource) \
and v.source() == QgsProcessingModelChildParameterSource.ExpressionText:
and v.source() == Qgis.ProcessingModelChildParameterSource.ExpressionText:
text = v.expressionText()
# replace parameter's name by expression (diverging after model save)
......
......@@ -36,6 +36,7 @@ from qgis.core import (QgsMapLayer,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterMeshLayer,
QgsProcessingParameterPointCloudLayer,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterMapLayer)
......@@ -112,6 +113,10 @@ class BatchInputSelectionPanel(QWidget):
or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and
self.param.layerType() == QgsProcessing.TypeMesh)):
layers = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance())
elif (isinstance(self.param, QgsProcessingParameterPointCloudLayer)
or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and
self.param.layerType() == QgsProcessing.TypePointCloud)):
layers = QgsProcessingUtils.compatiblePointCloudLayers(QgsProject.instance())
else:
datatypes = [QgsProcessing.TypeVectorAnyGeometry]
if isinstance(self.param, QgsProcessingParameterFeatureSource):
......
......@@ -68,6 +68,7 @@ from qgis.core import (
QgsProcessingParameterMapLayer,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterMeshLayer,
QgsProcessingParameterPointCloudLayer,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterRasterDestination,
......@@ -315,6 +316,11 @@ class BatchPanelFillWidget(QToolButton):
elif isinstance(self.parameterDefinition,
QgsProcessingParameterMultipleLayers) and self.parameterDefinition.layerType() == QgsProcessing.TypeMesh:
layers = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance())
elif isinstance(self.parameterDefinition, QgsProcessingParameterPointCloudLayer):
layers = QgsProcessingUtils.compatiblePointCloudLayers(QgsProject.instance())
elif isinstance(self.parameterDefinition,
QgsProcessingParameterMultipleLayers) and self.parameterDefinition.layerType() == QgsProcessing.TypePointCloud:
layers = QgsProcessingUtils.compatiblePointCloudLayers(QgsProject.instance())
else:
datatypes = [QgsProcessing.TypeVectorAnyGeometry]
if isinstance(self.parameterDefinition, QgsProcessingParameterFeatureSource):
......
......@@ -28,18 +28,21 @@ from qgis.PyQt import sip
from qgis.PyQt.QtCore import pyqtSignal, QSize
from qgis.PyQt.QtWidgets import QDialog, QLabel, QComboBox
from qgis.core import (QgsApplication,
QgsExpression,
QgsProperty,
QgsUnitTypes,
QgsMapLayer,
QgsCoordinateReferenceSystem,
QgsProcessingParameterNumber,
QgsProcessingOutputNumber,
QgsProcessingParameterDefinition,
QgsProcessingModelChildParameterSource,
QgsProcessingFeatureSourceDefinition,
QgsProcessingUtils)
from qgis.core import (
Qgis,
QgsApplication,
QgsExpression,
QgsProperty,
QgsUnitTypes,
QgsMapLayer,
QgsCoordinateReferenceSystem,
QgsProcessingParameterNumber,
QgsProcessingOutputNumber,
QgsProcessingParameterDefinition,
QgsProcessingModelChildParameterSource,
QgsProcessingFeatureSourceDefinition,
QgsProcessingUtils
)
from qgis.gui import QgsExpressionBuilderDialog
from processing.tools.dataobjects import createExpressionContext, createContext
......@@ -110,12 +113,12 @@ class ModelerNumberInputPanel(BASE, WIDGET):
def setValue(self, value):
if isinstance(value, QgsProcessingModelChildParameterSource):
if value.source() == QgsProcessingModelChildParameterSource.ModelParameter:
if value.source() == Qgis.ProcessingModelChildParameterSource.ModelParameter:
self.leText.setText('@' + value.parameterName())
elif value.source() == QgsProcessingModelChildParameterSource.ChildOutput:
elif value.source() == Qgis.ProcessingModelChildParameterSource.ChildOutput:
name = f"{value.outputChildId()}_{value.outputName()}"
self.leText.setText(name)
elif value.source() == QgsProcessingModelChildParameterSource.Expression:
elif value.source() == Qgis.ProcessingModelChildParameterSource.Expression:
self.leText.setText(value.expression())
else:
self.leText.setText(str(value.staticValue()))
......
......@@ -146,7 +146,7 @@ class ModelerDialog(QgsModelDesignerDialog):
self.setLastRunChildAlgorithmInputs(dlg.results().get('CHILD_INPUTS', {}))
dlg = AlgorithmDialog(self.model().create(), parent=self)
dlg.setLogLevel(QgsProcessingContext.Verbose)
dlg.setLogLevel(QgsProcessingContext.ModelDebug)
dlg.setParameters(self.model().designerParameterValues())
dlg.algorithmFinished.connect(on_finished)
dlg.exec_()
......
......@@ -126,11 +126,11 @@ class ModelerParametersDialog(QDialog):
def resolveValueDescription(self, value):
if isinstance(value, QgsProcessingModelChildParameterSource):
if value.source() == QgsProcessingModelChildParameterSource.StaticValue:
if value.source() == Qgis.ProcessingModelChildParameterSource.StaticValue:
return value.staticValue()
elif value.source() == QgsProcessingModelChildParameterSource.ModelParameter:
elif value.source() == Qgis.ProcessingModelChildParameterSource.ModelParameter:
return self.model.parameterDefinition(value.parameterName()).description()
elif value.source() == QgsProcessingModelChildParameterSource.ChildOutput:
elif value.source() == Qgis.ProcessingModelChildParameterSource.ChildOutput:
alg = self.model.childAlgorithm(value.outputChildId())
output_name = alg.algorithm().outputDefinition(value.outputName()).description()
......@@ -373,7 +373,7 @@ class ModelerParametersPanelWidget(QgsPanelWidget):
value = param.defaultValue()
if isinstance(value,
QgsProcessingModelChildParameterSource) and value.source() == QgsProcessingModelChildParameterSource.StaticValue:
QgsProcessingModelChildParameterSource) and value.source() == Qgis.ProcessingModelChildParameterSource.StaticValue:
value = value.staticValue()
wrapper.setValue(value)
......@@ -442,7 +442,7 @@ class ModelerParametersPanelWidget(QgsPanelWidget):
valid = True
for subval in val:
if (isinstance(subval, QgsProcessingModelChildParameterSource)
and subval.source() == QgsProcessingModelChildParameterSource.StaticValue
and subval.source() == Qgis.ProcessingModelChildParameterSource.StaticValue
and not param.checkValueIsAcceptable(subval.staticValue())) \
or (subval is None and not param.flags() & QgsProcessingParameterDefinition.FlagOptional):
valid = False
......
......@@ -2542,7 +2542,7 @@ class TestGdalRasterAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsT
'SKIP_NODATA': False,
'OUTPUT': outsource}, context, feedback),
['gdal2xyz.py',
'-band 1 -srcnodata -999 ' +
'-band 1 -srcnodata -999.0 ' +
source + ' ' +
outsource])
......@@ -2555,7 +2555,7 @@ class TestGdalRasterAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsT
'SKIP_NODATA': False,
'OUTPUT': outsource}, context, feedback),
['gdal2xyz.py',
'-band 1 -dstnodata -999 ' +
'-band 1 -dstnodata -999.0 ' +
source + ' ' +
outsource])
......
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ clip_lines_by_multipolygon.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>2</gml:X><gml:Y>-1</gml:Y></gml:coord>
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ogr:lines fid="lines.0">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>7,2 8,2</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:lines>
</gml:featureMember>
<gml:featureMember>
<ogr:lines fid="lines.2">
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>3,2 3,3</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>2,1 2,2</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>2,2 3,2</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
</ogr:lines>
</gml:featureMember>
<gml:featureMember>
<ogr:lines fid="lines.3">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>4,1 3,1</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:lines>
</gml:featureMember>
<gml:featureMember>
<ogr:lines fid="lines.6">
</ogr:lines>
</gml:featureMember>
</ogr:FeatureCollection>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="lines" type="ogr:lines_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="lines_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
gml:id="aFeatureCollection"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ offset_lines.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml/3.2">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-3.5 -1</gml:lowerCorner><gml:upperCorner>4.64644660940673 11.3535533905933</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.0">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>1.5 6.0</gml:lowerCorner><gml:upperCorner>4.64644660940673 11.3535533905933</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.0"><gml:posList>1.5 6.0 1.5 9.0 1.5024076366639 9.04900857016478 1.50960735979838 9.09754516100806 1.5215298321339 9.14514233862723 1.53806023374436 9.19134171618255 1.55903936782582 9.235698368413 1.58426519384873 9.2777851165098 1.61349477331863 9.31719664208182 1.64644660940673 9.35355339059327 1.68280335791818 9.38650522668137 1.7222148834902 9.41573480615127 1.764301631587 9.44096063217418 1.80865828381746 9.46193976625564 1.85485766137277 9.4784701678661 1.90245483899194 9.49039264020162 1.95099142983522 9.4975923633361 2.0 9.5 2.79289321881345 9.5 4.64644660940673 11.3535533905933</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.0</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.1">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-1.5 -1</gml:lowerCorner><gml:upperCorner>-1.5 1.0</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.1"><gml:posList>-1.5 -1 -1.5 1.0</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.1</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.2">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0.0 2.5</gml:lowerCorner><gml:upperCorner>3.0 3.5</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.2"><gml:posList>0.0 2.5 1.5 2.5 1.5 3.0 1.5024076366639 3.04900857016478 1.50960735979838 3.09754516100806 1.5215298321339 3.14514233862723 1.53806023374436 3.19134171618254 1.55903936782582 3.235698368413 1.58426519384873 3.2777851165098 1.61349477331863 3.31719664208182 1.64644660940673 3.35355339059327 1.68280335791818 3.38650522668137 1.7222148834902 3.41573480615127 1.764301631587 3.44096063217418 1.80865828381746 3.46193976625564 1.85485766137277 3.4784701678661 1.90245483899194 3.49039264020162 1.95099142983522 3.4975923633361 2.0 3.5 3.0 3.5</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.2</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.3">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>0.5 3.0</gml:lowerCorner><gml:upperCorner>0.5 5.0</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.3"><gml:posList>0.5 3.0 0.5 5.0</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.3</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.4">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-3.5 7.0</gml:lowerCorner><gml:upperCorner>-3.5 10.0</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.4"><gml:posList>-3.5 7.0 -3.5 10.0</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.4</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
<ogr:featureMember>
<ogr:SELECT gml:id="SELECT.5">
<gml:boundedBy><gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326"><gml:lowerCorner>-3.35355339059327 6.35355339059327</gml:lowerCorner><gml:upperCorner>0.64644660940673 10.3535533905933</gml:upperCorner></gml:Envelope></gml:boundedBy>
<ogr:geometryProperty><gml:LineString srsName="urn:ogc:def:crs:EPSG::4326" gml:id="SELECT.geom.5"><gml:posList>-3.35355339059327 6.35355339059327 0.64644660940673 10.3535533905933</gml:posList></gml:LineString></ogr:geometryProperty>
<ogr:fid>lines.5</ogr:fid>
</ogr:SELECT>
</ogr:featureMember>
</ogr:FeatureCollection>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
targetNamespace="http://ogr.maptools.org/"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:gmlsf="http://www.opengis.net/gmlsf/2.0"
elementFormDefault="qualified"
version="1.0">
<xs:annotation>
<xs:appinfo source="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd">
<gmlsf:ComplianceLevel>0</gmlsf:ComplianceLevel>
</xs:appinfo>
</xs:annotation>
<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="http://schemas.opengis.net/gml/3.2.1/gml.xsd"/>
<xs:import namespace="http://www.opengis.net/gmlsf/2.0" schemaLocation="http://schemas.opengis.net/gmlsfProfile/2.0/gmlsfLevels.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="featureMember">
<xs:complexType>
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureMemberType">
<xs:sequence>
<xs:element ref="gml:AbstractFeature"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="SELECT" type="ogr:SELECT_Type" substitutionGroup="gml:AbstractFeature"/>
<xs:complexType name="SELECT_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:CurvePropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> <!-- restricted to LineString --><!-- srsName="urn:ogc:def:crs:EPSG::4326" -->
<xs:element name="fid" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
......@@ -211,7 +211,9 @@ tests:
RADIUS_2: 5.0
results:
OUTPUT:
hash: 1c3adf57a7e319582736a1a222211e2360115fc930d6a12415dbdec3
hash:
- 1c3adf57a7e319582736a1a222211e2360115fc930d6a12415dbdec3
- 362fe6834eab26e44e65c0af786cc2a6d82c99d468f365afb1434796
type: rasterhash
- algorithm: gdal:griddatametrics
......@@ -230,7 +232,9 @@ tests:
RADIUS_2: 5.0
results:
OUTPUT:
hash: 11075786ce1a8f5875c203a881f39bb49e7d9f9adcb83c286c72b644
hash:
- 11075786ce1a8f5875c203a881f39bb49e7d9f9adcb83c286c72b644
- 066a82275eda08e0eb834e404f7f975944c7a8a46bd9f72333df4d05
type: rasterhash
- algorithm: gdal:gridinversedistance
......@@ -251,7 +255,9 @@ tests:
SMOOTHING: 0.0
results:
OUTPUT:
hash: 26658f6dd6a1dd4b576b2e71d3b31f1679d7144b8e53fb58502eff64
hash:
- 26658f6dd6a1dd4b576b2e71d3b31f1679d7144b8e53fb58502eff64
- 56fcd2cf1bc6eef4af088a161e0f190e5a1b8903d94bee6e15f56028
type: rasterhash
- algorithm: gdal:gridinversedistancenearestneighbor
......@@ -270,7 +276,9 @@ tests:
SMOOTHING: 0.0
results:
OUTPUT:
hash: 34fb2b6dc92f5f4147bf136a46dd872f4f94d3bca259d10c8c388620
hash:
- 34fb2b6dc92f5f4147bf136a46dd872f4f94d3bca259d10c8c388620
- 45c46d108d920b0ef19c5108a2829a581c2bd7c55cb3105c2814ea0a
type: rasterhash
- algorithm: gdal:gridlinear
......@@ -289,6 +297,7 @@ tests:
- aca7c839c679613f4910cbdea660359f1551c104c57fea9a61795668
- 57e2bc100ec9836e2aa7df4ccf6b5715bd3f3524a524ce47bec52f68
- e607570f34b1c61bc622751b324023b67642b657ef4b91a80d9057cb
- 31018c45cee587869c4b9693787db6974b5c92f1188c4046ddf3a307
type: rasterhash
- algorithm: gdal:gridnearestneighbor
......@@ -305,7 +314,9 @@ tests:
RADIUS_2: 0.0
results:
OUTPUT:
hash: 354f728b1dd133ad3db28a51b956bf3108615d31363f3a55b2ce04b9
hash:
- 354f728b1dd133ad3db28a51b956bf3108615d31363f3a55b2ce04b9
- 38db2a0bcdf6c8d25644545e050240f61377fddcbca471053949db35
type: rasterhash
- algorithm: gdal:hillshade
......@@ -339,7 +350,9 @@ tests:
WHITE: false
results:
OUTPUT:
hash: fff4a08498e93494f3f2cf1a9074451e6fd68341849aedc9e2c45e6a
hash:
- fff4a08498e93494f3f2cf1a9074451e6fd68341849aedc9e2c45e6a
- 0a382e4268b3f18c12fe89d241846d93b87ec782e9fc585e8f090630
type: rasterhash
- algorithm: gdal:rasterize
......
......@@ -156,7 +156,28 @@ tests:
# type: vector
- algorithm: gdal:clipvectorbypolygon
name: Clip lines by multipolygons
name: Clip lines by multipolygons (GEOS >= 3.11)
condition:
geos:
at_least: 31100
params:
INPUT:
name: lines.gml
type: vector
MASK:
name: multipolys.gml
type: vector
OPTIONS: ''
results:
OUTPUT:
name: expected/gdal/geos311/clip_lines_by_multipolygon.gml
type: vector
- algorithm: gdal:clipvectorbypolygon
name: Clip lines by multipolygons (GEOS < 3.11)
condition:
geos:
less_than: 31100
params:
INPUT:
name: lines.gml
......@@ -185,7 +206,31 @@ tests:
type: vector
- algorithm: gdal:offsetcurve
name: Offset curve (right-sided)
name: Offset curve (right-sided) (GEOS >= 3.11)
condition:
geos:
at_least: 31100
params:
DISTANCE: -0.5
GEOMETRY: geometry
INPUT:
name: lines.gml
type: vector
OPTIONS: ''
results:
OUTPUT:
name: expected/gdal/geos311/offset_lines.gml
type: vector
compare:
ignore_crs_check: true
geometry:
explode_collections: true
- algorithm: gdal:offsetcurve
name: Offset curve (right-sided) (GEOS < 3.11)
condition:
geos:
less_than: 31100
params:
DISTANCE: -0.5
GEOMETRY: geometry
......@@ -313,4 +358,3 @@ tests:
compare:
fields:
fid: skip
......@@ -2334,10 +2334,17 @@ apollo-reporting-protobuf@^3.3.3:
dependencies:
"@apollo/protobufjs" "1.2.6"
apollo-reporting-protobuf@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.4.0.tgz#6edd31f09d4a3704d9e808d1db30eca2229ded26"
integrity sha512-h0u3EbC/9RpihWOmcSsvTW2O6RXVaD/mPEjfrPkxRPTEPWqncsgOoRJw+wih4OqfH3PvTJvoEIf4LwKrUaqWog==
dependencies:
"@apollo/protobufjs" "1.2.6"
apollo-server-core@^3.11.1:
version "3.11.1"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-3.11.1.tgz#89d83aeaa71a59f760ebfa35bb0cbd31e15474ca"
integrity sha512-t/eCKrRFK1lYZlc5pHD99iG7Np7CEm3SmbDiONA7fckR3EaB/pdsEdIkIwQ5QBBpT5JLp/nwvrZRVwhaWmaRvw==
version "3.12.1"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-3.12.1.tgz#ba255c37345db29c48a2e0c064c519a8d62eb5af"
integrity sha512-9SF5WAkkV0FZQ2HVUWI9Jada1U0jg7e8NCN9EklbtvaCeUlOLyXyM+KCWuZ7+dqHxjshbtcwylPHutt3uzoNkw==
dependencies:
"@apollo/utils.keyvaluecache" "^1.0.1"
"@apollo/utils.logger" "^1.0.0"
......@@ -2348,11 +2355,11 @@ apollo-server-core@^3.11.1:
"@graphql-tools/schema" "^8.0.0"
"@josephg/resolvable" "^1.0.0"
apollo-datasource "^3.3.2"
apollo-reporting-protobuf "^3.3.3"
apollo-reporting-protobuf "^3.4.0"
apollo-server-env "^4.2.1"
apollo-server-errors "^3.3.1"
apollo-server-plugin-base "^3.7.1"
apollo-server-types "^3.7.1"
apollo-server-plugin-base "^3.7.2"
apollo-server-types "^3.8.0"
async-retry "^1.2.1"
fast-json-stable-stringify "^2.1.0"
graphql-tag "^2.11.0"
......@@ -2392,12 +2399,12 @@ apollo-server-express@^3.9.0:
cors "^2.8.5"
parseurl "^1.3.3"
apollo-server-plugin-base@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.1.tgz#aa78ef49bd114e35906ca9cf7493fed2664cbde8"
integrity sha512-g3vJStmQtQvjGI289UkLMfThmOEOddpVgHLHT2bNj0sCD/bbisj4xKbBHETqaURokteqSWyyd4RDTUe0wAUDNQ==
apollo-server-plugin-base@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-3.7.2.tgz#c19cd137bc4c993ba2490ba2b571b0f3ce60a0cd"
integrity sha512-wE8dwGDvBOGehSsPTRZ8P/33Jan6/PmL0y0aN/1Z5a5GcbFhDaaJCjK5cav6npbbGL2DPKK0r6MPXi3k3N45aw==
dependencies:
apollo-server-types "^3.7.1"
apollo-server-types "^3.8.0"
apollo-server-types@^3.7.1:
version "3.7.1"
......@@ -2409,6 +2416,16 @@ apollo-server-types@^3.7.1:
apollo-reporting-protobuf "^3.3.3"
apollo-server-env "^4.2.1"
apollo-server-types@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-3.8.0.tgz#d976b6967878681f715fe2b9e4dad9ba86b1346f"
integrity sha512-ZI/8rTE4ww8BHktsVpb91Sdq7Cb71rdSkXELSwdSR0eXu600/sY+1UXhTWdiJvk+Eq5ljqoHLwLbY2+Clq2b9A==
dependencies:
"@apollo/utils.keyvaluecache" "^1.0.1"
"@apollo/utils.logger" "^1.0.0"
apollo-reporting-protobuf "^3.4.0"
apollo-server-env "^4.2.1"
arch@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
......
......@@ -74,6 +74,10 @@ QAbstractSpinBox {
color: @text;
}
QAbstractSpinBox:no-frame {
border-color: transparent;
}
QAbstractSpinBox::up-button {
subcontrol-origin: border;
subcontrol-position: top right;
......@@ -240,6 +244,11 @@ QLineEdit, QTextEdit, QPlainTextEdit
selection-color: @itemdarkbackground;
}
QLineEdit:no-frame
{
border-color: transparent;
}
QPushButton
{
padding: 0.21em;
......@@ -1064,6 +1073,10 @@ QComboBox:focus, QAbstractSpinBox:focus, QLineEdit:focus, QPlainTextEdit:focus,
border:1px solid @focus;
}
QComboBox:focus:read-only, QAbstractSpinBox:focus:read-only, QLineEdit:focus:read-only, QPlainTextEdit:focus:read-only, QTextEdit:focus:read-only {
border-color: transparent;
}
QToolButton[autoRaise=true]:focus:!pressed {
border:1px solid @focusdark;
}
......
......@@ -70,6 +70,10 @@ QAbstractSpinBox {
color: @textlight;
}
QAbstractSpinBox:no-frame {
border-color: transparent;
}
QAbstractSpinBox::up-button {
subcontrol-origin: border;
subcontrol-position: top right;
......@@ -226,6 +230,11 @@ QLineEdit
selection-color: @text;
}
QLineEdit:no-frame
{
border-color: transparent;
}
QTextEdit, QPlainTextEdit
{
padding: 0.12em;
......@@ -1091,6 +1100,10 @@ QComboBox:focus, QAbstractSpinBox:focus, QLineEdit:focus, QPlainTextEdit:focus,
border:1px solid @focusdark;
}
QComboBox:focus:read-only, QAbstractSpinBox:focus:read-only, QLineEdit:focus:read-only, QPlainTextEdit:focus:read-only, QTextEdit:focus:read-only {
border-color: transparent;
}
QToolButton[autoRaise=true]:focus:!pressed {
border:1px solid @focusdark;
}
......
......@@ -38,6 +38,7 @@ my @lang;
my $translators= {
'af' => '',
'ar' => 'Ichaouia Amine, Hosham Munier, Ammar Shaarbaf',
'az' => '',
'bg' => 'Захари Савов, Jordan Tzvetkov',
'bs' => 'Almir Karabegovic',
'ca' => 'Albert F, Pau Reguant Ridó, Xavier Roijals',
......@@ -181,6 +182,8 @@ print "<table>";
print "<tr><th colspan=\"2\" style=\"width:250px;\">Language</th><th>Finished %</th><th>Translators</th></tr>\n";
for my $l (sort { $b->{percentage} <=> $a->{percentage} } @lang) {
last if $l->{percentage} < 35;
print STDERR "WARNING: images/flags/" . $l->{svg} . ".svg MISSING.\n" unless -f "images/flags/" . $l->{svg} . ".svg";
print STDERR "WARNING: flags/" . $l->{svg} . ".svg MISSING IN RESOURCES.\n" if system("grep -Fq '<file>flags/" . $l->{svg} . ".svg</file>' images/images.qrc") != 0;
printf "\n<tr>"
. '<td align="center"><img src="qrc:/images/flags/%s.svg" height="20"></td><td>%s</td>'
. '<td><div title="finished:%d unfinished:%d untranslated:%d" class="bartodo"><div class="bardone" style="width:%dpx">%.1f</div></div></td>'
......
......@@ -51,6 +51,21 @@ static float screenSpaceError( QgsChunkNode *node, const QgsChunkedEntity::Scene
return sse;
}
static bool hasAnyActiveChildren( QgsChunkNode *node, QList<QgsChunkNode *> &activeNodes )
{
for ( int i = 0; i < node->childCount(); ++i )
{
QgsChunkNode *child = node->children()[i];
if ( child->entity() && activeNodes.contains( child ) )
return true;
if ( hasAnyActiveChildren( child, activeNodes ) )
return true;
}
return false;
}
QgsChunkedEntity::QgsChunkedEntity( float tau, QgsChunkLoaderFactory *loaderFactory, bool ownsFactory, int primitiveBudget, Qt3DCore::QNode *parent )
: Qgs3DMapSceneEntity( parent )
, mTau( tau )
......@@ -111,6 +126,7 @@ QgsChunkedEntity::~QgsChunkedEntity()
}
}
void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
{
if ( !mIsValid )
......@@ -173,20 +189,13 @@ void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
#endif
}
double usedGpuMemory = QgsChunkedEntity::calculateEntityGpuMemorySize( this );
// unload those that are over the limit for replacement
// TODO: what to do when our cache is too small and nodes are being constantly evicted + loaded again
while ( usedGpuMemory > mGpuMemoryLimit )
{
QgsChunkListEntry *entry = mReplacementQueue->takeLast();
usedGpuMemory -= QgsChunkedEntity::calculateEntityGpuMemorySize( entry->chunk->entity() );
mActiveNodes.removeOne( entry->chunk );
entry->chunk->unloadChunk(); // also deletes the entry
// if this entity's loaded nodes are using more GPU memory than allowed,
// let's try to unload those that are not needed right now
#ifdef QGISDEBUG
++unloaded;
unloaded = unloadNodes();
#else
unloadNodes();
#endif
}
if ( mBboxesEntity )
{
......@@ -214,6 +223,51 @@ void QgsChunkedEntity::handleSceneUpdate( const SceneState &state )
.arg( t.elapsed() ), 2 );
}
int QgsChunkedEntity::unloadNodes()
{
double usedGpuMemory = QgsChunkedEntity::calculateEntityGpuMemorySize( this );
if ( usedGpuMemory <= mGpuMemoryLimit )
return 0;
QgsDebugMsgLevel( QStringLiteral( "Going to unload nodes to free GPU memory (used: %1 MB, limit: %2 MB)" ).arg( usedGpuMemory ).arg( mGpuMemoryLimit ), 2 );
int unloaded = 0;
// unload nodes starting from the back of the queue with currently loaded
// nodes - i.e. those that have been least recently used
QgsChunkListEntry *entry = mReplacementQueue->last();
while ( entry && usedGpuMemory > mGpuMemoryLimit )
{
// not all nodes are safe to unload: we do not want to unload nodes
// that are currently active, or have their descendants active or their
// siblings or their descendants are active (because in the next scene
// update, these would be very likely loaded again, making the unload worthless)
if ( entry->chunk->parent() && !hasAnyActiveChildren( entry->chunk->parent(), mActiveNodes ) )
{
QgsChunkListEntry *entryPrev = entry->prev;
mReplacementQueue->takeEntry( entry );
usedGpuMemory -= QgsChunkedEntity::calculateEntityGpuMemorySize( entry->chunk->entity() );
mActiveNodes.removeOne( entry->chunk );
entry->chunk->unloadChunk(); // also deletes the entry
++unloaded;
entry = entryPrev;
}
else
{
entry = entry->prev;
}
}
if ( usedGpuMemory > mGpuMemoryLimit )
{
QgsDebugMsgLevel( QStringLiteral( "Unable to unload enough nodes to free GPU memory (used: %1 MB, limit: %2 MB)" ).arg( usedGpuMemory ).arg( mGpuMemoryLimit ), 2 );
}
return unloaded;
}
QgsRange<float> QgsChunkedEntity::getNearFarPlaneRange( const QMatrix4x4 &viewMatrix ) const
{
QList<QgsChunkNode *> activeEntityNodes = activeNodes();
......@@ -438,7 +492,7 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
// has additive strategy. With additive strategy, child nodes should be rendered
// in addition to the parent nodes (rather than child nodes replacing parent entirely)
if ( mAdditiveStrategy )
if ( node->refinementProcess() == Qgis::TileRefinementProcess::Additive )
{
// Logic of the additive strategy:
// - children that are not loaded will get requested to be loaded
......@@ -493,7 +547,7 @@ void QgsChunkedEntity::update( QgsChunkNode *root, const SceneState &state )
{
mActiveNodes << node;
// if we are not using additive strategy we need to make sure the parent primitives are not counted
if ( !mAdditiveStrategy && node->parent() && nodes.contains( node->parent() ) )
if ( node->refinementProcess() != Qgis::TileRefinementProcess::Additive && node->parent() && nodes.contains( node->parent() ) )
{
nodes.remove( node->parent() );
renderedCount -= mChunkLoaderFactory->primitivesCount( node->parent() );
......@@ -616,11 +670,8 @@ void QgsChunkedEntity::onActiveJobFinished()
void QgsChunkedEntity::startJobs()
{
while ( mActiveJobs.count() < 4 )
while ( mActiveJobs.count() < 4 && !mChunkLoaderQueue->isEmpty() )
{
if ( mChunkLoaderQueue->isEmpty() )
return;
QgsChunkListEntry *entry = mChunkLoaderQueue->takeFirst();
Q_ASSERT( entry );
QgsChunkNode *node = entry->chunk;
......@@ -663,6 +714,7 @@ void QgsChunkedEntity::cancelActiveJob( QgsChunkQueueJob *job )
Q_ASSERT( job );
QgsChunkNode *node = job->chunk();
disconnect( job, &QgsChunkQueueJob::finished, this, &QgsChunkedEntity::onActiveJobFinished );
if ( qobject_cast<QgsChunkLoader *>( job ) )
{
......
......@@ -93,16 +93,6 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
//! Returns the root node of the whole quadtree hierarchy of nodes
QgsChunkNode *rootNode() const { return mRootNode; }
//! Sets whether additive strategy is enabled - see usingAditiveStrategy()
void setUsingAdditiveStrategy( bool additive ) { mAdditiveStrategy = additive; }
/**
* Returns whether additive strategy is enabled.
* With additive strategy enabled, also all parent nodes are added to active nodes.
* This is desired when child nodes add more detailed data rather than just replace coarser data in parents.
*/
bool usingAditiveStrategy() const { return mAdditiveStrategy; }
/**
* Sets the limit of the GPU memory used to render the entity
* \since QGIS 3.26
......@@ -147,6 +137,8 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
void startJobs();
QgsChunkQueueJob *startJob( QgsChunkNode *node );
int unloadNodes();
private slots:
void onActiveJobFinished();
......@@ -187,12 +179,6 @@ class QgsChunkedEntity : public Qgs3DMapSceneEntity
//! jobs that are currently being processed (asynchronously in worker threads)
QList<QgsChunkQueueJob *> mActiveJobs;
/**
* With additive strategy enabled, also all parent nodes are added to active nodes.
* This is desired when child nodes add more detailed data rather than just replace coarser data in parents.
*/
bool mAdditiveStrategy = false;
bool mIsValid = true;
int mPrimitivesBudget = std::numeric_limits<int>::max();
......
......@@ -257,9 +257,15 @@ void QgsChunkNode::updateParentBoundingBoxesRecursively() const
float yMax = -std::numeric_limits< float >::max();
float zMin = std::numeric_limits< float >::max();
float zMax = -std::numeric_limits< float >::max();
for ( int i = 0; i < currentNode->childCount(); ++i )
{
const QgsAABB childBBox = currentNodeChildren[i]->bbox();
// Nodes without data have an empty bbox and should be skipped
if ( childBBox.isEmpty() )
continue;
if ( childBBox.xMin < xMin )
xMin = childBBox.xMin;
if ( childBBox.yMin < yMin )
......@@ -273,7 +279,12 @@ void QgsChunkNode::updateParentBoundingBoxesRecursively() const
if ( childBBox.zMax > zMax )
zMax = childBBox.zMax;
}
currentNode->setExactBbox( QgsAABB( xMin, yMin, zMin, xMax, yMax, zMax ) );
// QgsAABB is normalized in its constructor, so that min values are always smaller than max.
// If all child bboxes were empty, we can end up with min > max, so let's have an empty bbox instead.
const QgsAABB currentNodeBbox = xMin < xMax && yMin < yMax && zMin < zMax ? QgsAABB( xMin, yMin, zMin, xMax, yMax, zMax ) : QgsAABB();
currentNode->setExactBbox( currentNodeBbox );
currentNode = currentNode->parent();
}
}
......
......@@ -29,6 +29,7 @@
#include "qgsaabb.h"
#include "qgis.h"
#include <QTime>
#define SIP_NO_FILE
......@@ -83,7 +84,7 @@ struct QgsChunkNodeId
//! Returns textual representation of the node ID in form of "Z/X/Y"
QString text() const
{
if ( uniqueId == -1 )
if ( uniqueId != -1 )
return QString::number( uniqueId );
else if ( z == -1 )
return QStringLiteral( "%1/%2/%3" ).arg( d ).arg( x ).arg( y ); // quadtree
......@@ -167,6 +168,8 @@ class QgsChunkNode
int childCount() const { return mChildren.count(); }
//! Returns array of the four children. Children may be NULLPTR if they were not created yet
QgsChunkNode *const *children() const { return mChildren.constData(); }
//! Returns how the chunked entity should behave when it is going to activate node's children
Qgis::TileRefinementProcess refinementProcess() const { return mRefinementProcess; }
//! Returns current state of the node
State state() const { return mState; }
......@@ -190,6 +193,9 @@ class QgsChunkNode
//! Sets child nodes of this node. Takes ownership of all objects. Must be only called once.
void populateChildren( const QVector<QgsChunkNode *> &children );
//! Sets how the chunked entity should behave when it is going to activate node's children
void setRefinementProcess( Qgis::TileRefinementProcess refinementProcess ) { mRefinementProcess = refinementProcess; }
//! how deep is the node in the tree (zero means root node, every level adds one)
int level() const;
......@@ -262,6 +268,8 @@ class QgsChunkNode
State mState; //!< State of the node
Qgis::TileRefinementProcess mRefinementProcess = Qgis::TileRefinementProcess::Replacement; //!< How to handle display of the node when children get activated
QgsChunkListEntry *mLoaderQueueEntry; //!< Not null <=> QueuedForLoad or QueuedForUpdate state
QgsChunkListEntry *mReplacementQueueEntry; //!< Not null <=> has non-null entity (Loaded or QueuedForUpdate or Updating state)
......
......@@ -473,7 +473,7 @@ void Qgs3DMapScene::createTerrain()
{
mSceneEntities.removeOne( mTerrain );
mTerrain->deleteLater();
delete mTerrain;
mTerrain = nullptr;
}
......
......@@ -968,7 +968,7 @@ void Qgs3DMapSettings::set3DAxisSettings( const Qgs3DAxisSettings &axisSettings,
{
if ( force )
{
// ie. refresh. We nned to disconnect and to reconnect to avoid 'dirty' project
// ie. refresh. We need to disconnect and to reconnect to avoid 'dirty' project
disconnect( this, &Qgs3DMapSettings::axisSettingsChanged, this, &Qgs3DMapSettings::settingsChanged );
emit axisSettingsChanged();
connect( this, &Qgs3DMapSettings::axisSettingsChanged, this, &Qgs3DMapSettings::settingsChanged );
......
......@@ -168,7 +168,7 @@ static Qt3DQAttribute *reprojectPositions( tinygltf::Model &model, int accessorI
{
double x = vx[i] - sceneOrigin.x();
double y = vy[i] - sceneOrigin.y();
double z = vz[i] - sceneOrigin.z();
double z = ( vz[i] * transform.zValueScale ) + transform.zValueOffset - sceneOrigin.z();
// QGIS 3D uses base plane (X,-Z) with Y up - so flip the coordinates
out[i * 3 + 0] = static_cast< float >( x );
......@@ -259,6 +259,8 @@ static QByteArray fetchUri( const QUrl &url, QStringList *errors )
if ( url.scheme().startsWith( "http" ) )
{
QNetworkRequest request = QNetworkRequest( url );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
QgsBlockingNetworkRequest networkRequest;
// TODO: setup auth, setup headers
if ( networkRequest.get( request ) != QgsBlockingNetworkRequest::NoError )
......@@ -372,7 +374,7 @@ static Qt3DRender::QMaterial *parseMaterial( tinygltf::Model &model, int materia
}
static QVector<Qt3DCore::QEntity *> parseNode( tinygltf::Model &model, int nodeIndex, const QgsGltf3DUtils::EntityTransform &transform, QgsVector3D &tileTranslationEcef, QString baseUri, QMatrix4x4 parentTransform, QStringList *errors )
static QVector<Qt3DCore::QEntity *> parseNode( tinygltf::Model &model, int nodeIndex, const QgsGltf3DUtils::EntityTransform &transform, const QgsVector3D &tileTranslationEcef, QString baseUri, QMatrix4x4 parentTransform, QStringList *errors )
{
tinygltf::Node &node = model.nodes[nodeIndex];
......@@ -495,7 +497,7 @@ static Qt3DCore::QEntity *parseModel( tinygltf::Model &model, const QgsGltf3DUti
*errors << "Scene contains multiple nodes: only loading the first one!";
}
QgsVector3D tileTranslationEcef = QgsGltfUtils::extractTileTranslation( model );
const QgsVector3D tileTranslationEcef = QgsGltfUtils::extractTileTranslation( model );
int rootNodeIndex = scene.nodes[0];
const QVector<Qt3DCore::QEntity *> entities = parseNode( model, rootNodeIndex, transform, tileTranslationEcef, baseUri, QMatrix4x4(), errors );
......
......@@ -60,6 +60,9 @@ class _3D_EXPORT QgsGltf3DUtils
QgsMatrix4x4 tileTransform;
//! Transform from ECEF (normally EPSG:4978) to the target CRS
const QgsCoordinateTransform *ecefToTargetCrs = nullptr;
double zValueScale = 1;
double zValueOffset = 0;
};
/**
......
......@@ -176,7 +176,9 @@ QgsChunkNode *QgsPointCloudLayerChunkLoaderFactory::createRootNode() const
{
const QgsAABB bbox = nodeBoundsToAABB( mPointCloudIndex->nodeBounds( IndexedPointCloudNode( 0, 0, 0, 0 ) ), mPointCloudIndex->offset(), mPointCloudIndex->scale(), mMap, mCoordinateTransform, mZValueOffset );
const float error = mPointCloudIndex->nodeError( IndexedPointCloudNode( 0, 0, 0, 0 ) );
return new QgsChunkNode( QgsChunkNodeId( 0, 0, 0, 0 ), bbox, error );
QgsChunkNode *node = new QgsChunkNode( QgsChunkNodeId( 0, 0, 0, 0 ), bbox, error );
node->setRefinementProcess( mSymbol->renderAsTriangles() ? Qgis::TileRefinementProcess::Replacement : Qgis::TileRefinementProcess::Additive );
return node;
}
QVector<QgsChunkNode *> QgsPointCloudLayerChunkLoaderFactory::createChildren( QgsChunkNode *node ) const
......@@ -208,7 +210,9 @@ QVector<QgsChunkNode *> QgsPointCloudLayerChunkLoaderFactory::createChildren( Qg
const float chZMax = !dy ? bbox.zMax : zc;
const float chYMin = dz ? yc : bbox.yMin;
const float chYMax = dz ? bbox.yMax : yc;
children << new QgsChunkNode( childId, QgsAABB( chXMin, chYMin, chZMin, chXMax, chYMax, chZMax ), childError, node );
QgsChunkNode *child = new QgsChunkNode( childId, QgsAABB( chXMin, chYMin, chZMin, chXMax, chYMax, chZMax ), childError, node );
child->setRefinementProcess( mSymbol->renderAsTriangles() ? Qgis::TileRefinementProcess::Replacement : Qgis::TileRefinementProcess::Additive );
children << child;
}
return children;
}
......@@ -247,7 +251,6 @@ QgsPointCloudLayerChunkedEntity::QgsPointCloudLayerChunkedEntity( QgsPointCloudI
: QgsChunkedEntity( maximumScreenSpaceError,
new QgsPointCloudLayerChunkLoaderFactory( map, coordinateTransform, pc, symbol, zValueScale, zValueOffset, pointBudget ), true, pointBudget )
{
setUsingAdditiveStrategy( !symbol->renderAsTriangles() );
setShowBoundingBoxes( showBoundingBoxes );
}
......
此差异已折叠。
......@@ -39,6 +39,7 @@ class QgsAABB;
namespace Qt3DRender
{
class QCamera;
class QGeometryRenderer;
}
......@@ -108,6 +109,18 @@ namespace QgsRayCastingUtils
QVector3D &uvw,
float &t );
/**
* Tests whether a triangular mesh is intersected by a ray. Returns whether an intersection
* was found. If found, it outputs the point at which the intersection happened and index
* of the intersecting triangle.
* \since QGIS 3.34
*/
bool rayMeshIntersection( Qt3DRender::QGeometryRenderer *geometryRenderer,
const QgsRayCastingUtils::Ray3D &r,
const QMatrix4x4 &worldTransform,
QVector3D &intPt,
int &triangleIndex );
/**
* Helper struct to store ray casting results.
*/
......
......@@ -388,14 +388,13 @@ Qt3DCore::QEntity *QgsRuleBased3DRenderer::createEntity( const Qgs3DMapSettings
if ( !vl )
return nullptr;
// we start with a maximal z range (based on a number similar to the radius of the Earth),
// because we can't know this upfront. There's too many
// we start with a maximal z range because we can't know this upfront. There's too many
// factors to consider eg vertex z data, terrain heights, data defined offsets and extrusion heights,...
// This range will be refined after populating the nodes to the actual z range of the generated chunks nodes.
// Assuming the vertical height is in meter, then it's extremely unlikely that a real vertical
// height will exceed this amount!
constexpr double MINIMUM_VECTOR_Z_ESTIMATE = -5000000;
constexpr double MAXIMUM_VECTOR_Z_ESTIMATE = 5000000;
constexpr double MINIMUM_VECTOR_Z_ESTIMATE = -100000;
constexpr double MAXIMUM_VECTOR_Z_ESTIMATE = 100000;
return new QgsRuleBasedChunkedEntity( vl, MINIMUM_VECTOR_Z_ESTIMATE, MAXIMUM_VECTOR_Z_ESTIMATE, tilingSettings(), mRootRule, map );
}
......
......@@ -108,12 +108,6 @@ class QgsTessellatedPolygonGeometry : public Qt3DCore::QGeometry
*/
QgsFeatureId triangleIndexToFeatureId( uint triangleIndex ) const;
/**
* Tests whether the geometry is intersected by \a ray.
* In case of success, the \a intersectionPoint and the corresponding \a fid are updated.
*/
bool rayIntersection( const QgsRayCastingUtils::Ray3D &ray, const QMatrix4x4 &worldTransform, QVector3D &intersectionPoint, QgsFeatureId &fid );
friend class Qgs3DSceneExporter;
private:
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。