ArcGIS Enterprise中Portal发布场景服务后无法查看

大家都知道ArcGIS现在整个产品体系特别庞大,以我来看,个人是不能将所有的产品学到精通的,毕竟整个产品已经年近五旬,积累沉淀的东西非一人所能穷尽的。
现在就说一下ArcGIS Enterprise,俗称”ArcGIS 全家桶“套餐,为什么这么叫呢,因为之前这个系统有多个组件。ArcGIS Enterprise 在是在10.5版本以后才叫这个名字的,算是一个统称,包括了Portal Server Datastore Webadaptor,所以需要一个个组件安装,并且有一定的部署顺序,如果不太熟悉这个流程,好不容易在漫长的安装过程之后,出现令人崩溃的不能用,排查问题的时候又很困难,所以,目前这套系统再生产环境中需要Esri官方技术人员现场部署,以保证系统的安全。

点击继续阅读

无人机(UAV)影像处理最佳实践

1、前言

数字孪生(Data Twins)概念已经在报端见诸多年,但是在制造业、能源化工、流域治理等还是最底层的搭建和展示。

回头看看,当初热火朝天炒的那波人和政策理论已经烟消云散,如今激不起半点涟漪,传统还是传统,并没有被数字信息革了命。

不说经济的下行原因,每个参与过其中的在思考:是什么让我们龃龉不前!!!

是技术跟不上理论?亦或是从来没有共识?

点击继续阅读

什么是texture函数

在着色器语言中,如GLSL(OpenGL Shading Language),texture2D 是用于在纹理上进行采样的函数。它的参数通常包括两个:

1
vec4 texture2D(sampler2D sampler, vec2 textureCoordinates);

其中:

  • sampler2D sampler:表示纹理采样器,它是一个指向纹理对象的引用。这个参数告诉着色器在哪个纹理上进行采样。

  • vec2 textureCoordinates:表示纹理坐标,用于指定在纹理上的位置。纹理坐标通常是二维的,范围在 [0.0, 1.0] 之间。通常 (0, 0) 表示纹理的左下角,(1, 1) 表示右上角。

texture2D 函数返回一个 vec4 类型的颜色值,其中包含了在指定纹理坐标位置处采样得到的颜色信息。这个颜色值通常包括红色(R)、绿色(G)、蓝色(B)和 alpha 通道(A)的分量。

例如,在一个简单的片元着色器中,你可能会使用 texture2D 函数来获取纹理上某个位置的颜色:

1
2
3
4
5
6
7
8
9
uniform sampler2D myTexture;  // 纹理采样器
varying vec2 vTextureCoord; // 从顶点着色器传递过来的纹理坐标

void main() {
vec4 color = texture2D(myTexture, vTextureCoord);
// 使用 color 进行进一步的处理
// ...
gl_FragColor = color;
}

在这个例子中,myTexture 是一个纹理采样器,vTextureCoord 是从顶点着色器传递过来的纹理坐标。texture2D(myTexture, vTextureCoord) 用于在这个纹理坐标处采样纹理,返回颜色值,然后可以在着色器中进行后续处理。

完美geoserver跨域解决方式(2024版)

因为tomcat容器本身或者geoserver的安全策略,在tomcat中部署geoserver,导致在其他应用使用geoserver地图服务会出现跨域现象。
通常会通过nginx的反向代理解决这个问题。

但是安装nginx反过来又会让流程变得繁琐,将大象装到冰箱里就不止三部了。

我们知道,GeoServer的项目是一个完整的JavaJ2EE)系统。

所以,基于geoserver本身配置可以来解决这个问题。

但是百度搜索的结果不是过时,就是毫无责任的、误导人的遍地复制粘贴,也说明现在搜索引擎的尴尬局面:blog论坛贴吧的时代一去不复返,robot协议更加苛刻,搜索爬虫处于严重饥饿状态。 所以我们拿到的结果显得匮乏,难以命中问题。

好在chatgpt解决了一些问题,但是使用成本和难以预料的胡说八道,又让我们不得不审视其专业性。

废话不再多说

简要说下就是在tomcat中部署完geoserver,能正常访问后,通过修改geoserverweb.xml文件,将两个jar包添加到geoserverlib目录,就能完美解决跨域问题,重点是找到不同geoserver所对应的jar版本

点击继续阅读

航班数据分享

近期抓取了一些航班数据,分享一下。

1
2
3
数据范围:全国(境内,不包括港澳台)
日期范围:20230320-20230327
航班数量:58987条

数据预览
关注右侧公众号zyouzz回复”航班”获取下载,

有偿提供近期或者其他日期航班数据(全国、世界均可)

如有需要,请于公众号zyouzz留言

WebGL若干原理摘抄

Shader

shader,即着色器,分为顶点着色器(Vertex Shader)片元着色器(Fragment Shader)几何着色器(Geometry shader)计算着色器(Compute shader)细分曲面着色器(Tessellation or hull shader),其中可编程的是顶点着色器和片元着色器。至于它们的定义网上可以找到很多,但对于小白来讲看完还是一脸懵逼,我们需要一种通俗易懂的解释,这才符合深入浅出的精髓。

在知乎上找到一段解释,感觉还不错:

1
2
3
4
5
6
7
8
9
10
11
12
13
当我们在屏幕上绘制或显示一些物体时,
这些物体的显示形式是图元(Primitive)或者网格(Mesh),
比如游戏中一个几何模型角色或一个贴在网格上的纹理角色,
比如我们做阴影效果时先绘制网格再计算阴影,
比如一个发射物体发射前需要先绘制该物体外形网格。
这些物体都可归结为网格,它可被分解为图元,即图元是网格的基本单位。
图元有三角形、直线或点。
当我们在屏幕上画一个三角形时,首先要绘制顶点,
因为网格由顶点组成,此时就要用到顶点着色器(Vertex shader),
将需要到顶点信息给顶点着色器,以显示顶点信息;
其次是在这些顶点组成的区域之间填充颜色,
此时用到像素着色器(Pixel shader)或片元着色器(Fragment shader),
片段(Fragment)有助于定义像素的最终颜色。

shader

简单来说渲染流程如下:
顶点数据(Vertices) > 顶点着色器(Vertex Shader) > 图元装配(Assembly) > 几何着色器(Geometry Shader) > 光栅化(Rasterization) > 片元着色器(Fragment Shader) > 逐片元处理(Per-Fragment Operations) > 帧缓冲(FrameBuffer)

最后经过双缓冲的交换(SwapBuffer),渲染内容就显示到了屏幕上。从流程中我们可以看到,顶点着色器之后是图元装配, 图元装配通俗讲就是把图形放置到坐标系中。在片元着色器之前是 光栅化,光栅化是将图形投影到屏幕上,把图形栅格化成一个个的像素点,一个像素点也就是一个片元。在片元着色器之后是逐片元处理, 逐片元处理即填充颜色。再说白一点,顶点着色器负责坐标位置,片元着色器负责填充颜色。好吧,这个说法不一定很严谨,但一定足够浅显,如果我说的不对也欢迎拍砖。

域名包括二级路径,配置VUE中vite

通常情况下我们将vue打包后,直接放置nginx或者tomcat等容器里,配置下相关路径文件就可以访问了。
但是当我们使用域名的二级路径访问时,如https://abc.com/cesium/,会报404错误,这是因为一些静态文件路径为域名+文件形式,导致找不到文件,例如index.html中的文件为/assets/index-9a873818.js,导致直接拼接了域名。
接下来需要在工程中做相关配置
1、增加开发环境文件.env.development,添加以下内容

1
2
##开发环境
VITE_BASE_PATH='/'

2、增加生产环境文件.env.production,添加以下内容

1
2
#生产环境
VITE_BASE_PATH=/cesium/

3、修改package.json中的devbuild命令为:

1
2
"dev": "vite serve --mode development",
"build": "vite build --mode production",

4、安装dotenv模块,

1
yarn add dotenv

5、在vite.config.js中增加

1
2
3
4
5
6
import dotenv from 'dotenv';
dotenv.config({ path: `.env.${process.env.NODE_ENV}` });
//添加base
export default defineConfig({
base: process.env.VITE_BASE_PATH,
})

另外附nginx一般配置,

1
2
3
4
5
location cesium/ {
root html/cesium/;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}

注意文件夹名要和域名二级路径一致,不然需要在index.html前指定文件夹名称,如下

1
2
3
4
5
location cesium/ {
root html/test/;
try_files $uri $uri/ test/index.html;
index index.html index.htm;
}

Cesium拾取坐标三种方式(摘抄)

首先基于事件触发捕捉位置信息,一般是Cesium.ScreenSpaceEventType.MOUSE_MOVE,也可以是Cesium.ScreenSpaceEventType.LEFT_CLICK或者Cesium.ScreenSpaceEventType.RIGHT_CLICK

1
2
3
4
this.mouseHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
this.mouseHandler.setInputAction((movement) => {
// 添加方法
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)

根据场景加载数据和需求,大部分情况下,我们拾取的是模型表面位置,所以使用方法一。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 方式一: 从场景的深度缓冲区中拾取相应的位置,可以采集entity,primitive,3dtile
// 当拾取区域无entity,primitive,3dtile时,将返回一个无法预料的坐标(标准椭球面以下,无法使用,无法预料)
let cartesianPosition = viewer.scene.pickPosition(movement.position);
if (cartesian3) {
// 下面两个都行
// let cartographic3 = Cesium.Cartographic.fromCartesian(cartesianPosition);
let cartographic3 = ellipsoid.cartesianToCartographic(cartesianPosition);
this.pickInfoOption3.lng = Cesium.Math.toDegrees(cartographic3.longitude);
this.pickInfoOption3.lat = Cesium.Math.toDegrees(cartographic3.latitude);
this.pickInfoOption3.height = cartographic3.height;
}
// 方式二:获取当前点击视线与地球表面相交的坐标(有地形时候均可用,无地形时高程几乎为0)(无视entity、3dtile,不能拾取其表面坐标)
let ray = viewer.scene.camera.getPickRay(movement.position);
let cartesian1 = viewer.scene.globe.pick(ray, viewer.scene);
if (cartesian1) {
let cartographic1 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian1);
this.pickInfoOption1.lng = Cesium.Math.toDegrees(cartographic1.longitude);
this.pickInfoOption1.lat = Cesium.Math.toDegrees(cartographic1.latitude);
this.pickInfoOption1.height = cartographic1.height;
}
// 方式三:获取当前点击视线与标准椭球面相交处的坐标,无高程(恒为0)
let cartesian2 = viewer.camera.pickEllipsoid(movement.position, ellipsoid);
if (cartesian2) {
let cartographic2 = ellipsoid.cartesianToCartographic(cartesian2);
this.pickInfoOption2.lng = Cesium.Math.toDegrees(cartographic2.longitude);
this.pickInfoOption2.lat = Cesium.Math.toDegrees(cartographic2.latitude);
this.pickInfoOption2.height = cartographic2.height;
}

postman设置collection全局token

平时在postman调试接口多,如果过了一段时间后,token会失效,每个请求需要更换token,挺麻烦的,我们可以根据在postman配置collection下的全局token;
具体如下
1、打开Postman并创建一个新的Collection。
Collection
2、在Collection的”Authorization”选项卡中选择适当的授权方式(例如Bearer Token或OAuth 2.0)。
3、在”Token”字段中,使用双大括号({{}})将Token包裹起来,形成一个环境变量。例如:{{token}}。
token
4、点击右上角的“眼睛”按钮,以便在请求中查看环境变量的值。
环境变量
5、现在,您需要在Postman的环境中设置Token的值。在Postman左上角的”Manage Environments”(管理环境)按钮旁边,点击下拉菜单按钮,并选择”Add”(添加)。
6、输入环境名称,例如”Token Environment”,然后点击”Add”(添加)。
Add
7、在环境变量列表中,添加一个新的变量,键为”token”,值为您的Token值。
Add
8、点击”Save”(保存)以保存环境变量。
9、注意检查请求中Authorization是否为inherit auth from parent
inherit auth from parent