Fuyi Atlas

I have a dream too !

  • 开源技术赋予我们站在巨人的肩膀上做到更高更强的可能,我想通过开源技术来构建一个地理信息的世界,愿给地理信息数据带来更多的使用价值。

  • 既然都说人类活动所接触、产生的信息80%以上都与地理空间位置有关,那么这些空间数据就应该很容易的被使用,而不是仅被围困在专业领域内,不是吗?


  • 如果你想要拥有从未有过的东西,那就去做你从未做过的事!

微天气 终篇

起源 天气小程序产生于2022年年初,目的是用于验证自己是否有进入全栈开发(仅前后端)的能力。 受新冠疫情影响,2022年的春节是在杭州过的。还记得当时附近好几个地方都被划为了高风险,对整个区进行了管控。如果选择回家的话,得到将是14天的隔离,还不确定能否回来上班。因此便没有回去了。好在所在的区域情况并没有那么的严重,还是可以去买菜的。领了消费券,再加上公司发的年货,也没有想象中的那么糟糕。 所以,既然没有回去,又有十来天的时间,总得做点什么东西才行,对吧 🙄! 2022年,是我工作的第四个年头。受多方面的信息影响,我也想看看验证自己是否有进入全栈开发(仅前后端)的能力。 历程 拂衣天气,又名微天气。 一个集地理信息与天气预报为一体的天气预报类小程序,界面精美,使用便捷。【致敬:和风天气】! 💡 主要是有人给我说拂衣天气,听着还以为是卖衣服的。so,我就想着换个名字,就有了微天气。但是由于微信认证的原因,所以有些地方还是拂衣天气。现在细细想来,好像也没有什么关系,那就先这样吧 🙄 该项目从2022年1月12号正式启动,于2022年3月19日发布一阶段最终版本(1.1.9),总体耗时2个月零7天。从内容完整度以及界面友好程度来说,我给自己70分。 此前实在是没有经验,也没有相关的习惯,天气小程序开发过程中并没有编写相关的文档。所以在小程序开发完成之后,本来计划是将拂衣天气完整的开发过程通过文章的方式记录下来,并将该项目开源出去,甚至还想将该项目提交给和风天气。但最后的结果就是:文章就完成了四篇,也就是一个开头,没啥实际内容。@time 2022年8月16日 好的,现在时间来到2023年12月,我又有点时间了,因为我离职了(不是被裁)。这次的目标是完善文档,修复发现的一些BUG,然后新增一些内容,最终将该小程序开源,并贡献给和风天气。 接下来,让我来回忆一下每个阶段的详细内容 🤔 项目初始 为什么会想到做一个天气小程序呢? 嗯,首先我是一个做服务端开发的GIS开发工程师。在当时刚结束一个小程序的开发工作,觉得小程序这个东西还挺有意思。同时受到周边各种信息的影响,也想试一试写点前端的内容,最好是可以方便发布的那种,也算是自己的作品不是。为什么会选择天气类别,好像是当时刷网页还是什么,看到一个人分享自己做了一个天气机器人,然后给女朋友推天气信息。so, 🫣 所以,我当时就想做一个天气类别的小程序,以此进行全栈开发能力的试炼。我想这会是一个微信小程序、是一个可以正常使用的小程序,以Java进行服务端开发,以Mapbox实现天气数据可视化。 本阶段事务分为了三个阶段,分别是:调研、学习、实现 调研 天气小程序什么最重要?当然是天气数据最为重要,所以首要内容便是确定天气数据的来源。其次便是确定本次天气小程序的技术实现构成。 天气数据 天气数据需要是真实的、可用的。那么可以通过网络中提供的天气API进行获取。 通过一定的检索后,我选定了两个天气平台,分别是:和风天气、心知天气。 高德天气:大平台,但是目前服务类目比较少 彩云天气:免费接口几乎没有,收费又太贵 心知天气 心知天气试用版与开发者版开发产品几乎等同,且开发者版收费也不贵。最为关键的是,支持以经纬度方式进行天气查询。 和风天气 几乎可以免费使用其提供的所有 API,且同样支持经纬度方式进行天气查询。 对比了这两者,发现至少都需要注册为开发者之后,才可以较好的使用其服务。且两者的开发者认证均需要实名。 关于天气API的选择,我最终选择了和风天气,倒不是因为它可以免费使用。其实,刚开始的时候我更倾向于使用心知天气,因为它还可以直接查昨天的天气(和风对于历史天气的查询比较麻烦)。但是和风天气首页结合了地图进行可视化,而且还提供有APP可以使用(方便参考)。再加上,我想了想,其实我并没有迫切的需要知道昨天的天气情况。 🙄 💡 其实最重要的原因在于:我先注册了心知天气(需要审核),过了半天后再去注册了和风天气(需要审核),但是最先通过审核的是和风天气(耗时大概也就半天左右,我是在春节期间注册的啊)。 技术实现构成 这里存在一个遗憾,小程序原生并不支持使用如mapbox这样的第三方地图框架,初始想法是通过webview的方式使用mapbox,但是遗憾的是,webview并不对个人类型的小程序开放使用。 所以,退而求其次,选择腾讯地图(及其提供的样式)实现地图浏览。 服务端程序则使用Java语言开发,天气数据是经过服务端代理的方式形成内部的数据接口,并非是小程序直接调用和风的接口 最终将服务端程序部署到阿里云 学习 我是一个后端开发工程师,我不怎么会写页面,我特别的讨厌写CSS。我也没有接触过前端开发和微信小程序开发,所以需要提前储备一下相关知识。 前端知识 我并没有想要精通前端技术,但是我需要比较体系的了解一下前端技术,方便进行小程序开发。所以我在B站找了两门前端视频学习(粗略的刷了一遍) 尚硅谷Web前端零基础入门HTML5+CSS3基础教程丨初学者从入门到精通 千锋web前端开发项目教程_1000集完全零基础入门HTML5+CSS3+JS到精通 微信小程序知识 其实就看官方文档就足够了,不过心虚的我还是在极客时间找了门课。最终发现:就官方文档就足够了,因为我并不需要很深入的东西 实现 在有一定准备后,就开始进入实现环节了。 在这里有一个大问题就是UI设计问题,我看和风天气APP就挺好看的,有天气有地图,身为GIS开发的我就很喜欢。又发现无论是和风天气官方,还是其他天气小程序应用,基本都没有携带地图的。 所以,我当即决定参考和风天气官方APP界面,做一个类似的天气小程序。当然,我做的这个小程序就是奔着开源,同时将作为作品分享给和风天气,才想着如此操作的。请务必慎重 🤔 在经过简单的设计过后,于2022年1月18日正式进行开发,2022年3月19日发布一阶段最终版本1.1.9。 文档补充 今天偷的懒,明天都会让你加倍还回来。此前一是没意识,二是认为没必要,三还是太懒,所以并没有同步编写文档。 现在计划将拂衣天气开发的完整过程通过文章的方式记录下来,下面是我对该整体内容的编写计划: 但是,我又要开始说但是了。打工人还是打工人! 天气小程序于2022年4月前就已经完成了开发,直至到今天(2022年8月16日)也就才完成了三篇文章,不得不说拖延症是真的严重。天气小程序只是一个应用,就目前的投入收益来说,不应该把过多的时间放在小程序上面。在加上距离开发已经过去了4个月,开发之时并没有进行文档产出,所以现在才进行复盘则是相当于重新实现了一遍。就目前来看,核心的行政区划数据合并已基本完成,所以,后面将暂停小程序相关内容,变更为GIS基础与计算机基础的学习。 💡 对的,停更说明。 死灰复燃 打工是不可能打工的,只要我不打工,我就有时间了 🙄...

March 14, 2024 · 1 min · Fuyi

微天气 小程序发布记录

前言 服务端部署:由于并没有建立全链路的自动化部署,目前还需要到云服务器上进行环境制作(数据库,Nginx),并拉取后端服务进行部署 小程序发布:需要先完成服务端部署,保证应用正常可用 服务端部署 数据库安装与数据初始化 最开始的时候,我是直接将在操作系统上面安装数据库,后面发现迁移的时候还是不方便,即使我可以放弃数据库中的数据,但是还是需要重新创建数据表结构。 所以,在这一次中,我编写了一个Dockerfile脚本,使用一个空数据库作为模板,构建了postgis镜像。基于此,我可以实现快速的迁移与部署。由于这是一个实验性质的小程序,所以数据资产并不是十分重要(并不是说不安全,而是我可以丢弃),所以我可以安心的使用docker技术。在初始化postgis容器的时候,会同步释放模板以创建数据库。这将会带来一个问题是:如果重新创建容器,那么将会得到一个全新的数据库。当然你可以把数据库的data目录映射到宿主机上,应该可以解决这个问题。 docker build -t registry.cn-hangzhou.aliyuncs.com/fuyi-atlas/micro-weather-postgis:12-3.4 . 最后,我在本地完成该镜像的制作后,将其推送到我的阿里云镜像仓库中,便于后续使用。你可以注册一个阿里云账户去免费启用个人版的镜像仓库,也可以直接使用dockerhub。 docker push registry.cn-hangzhou.aliyuncs.com/fuyi-atlas/micro-weather-postgis:latest 应用部署 于本地完成镜像制作,并推送到阿里云镜像仓库中。 为了更方便的进行部署,我编写了docker compose脚本,用于将数据库与应用服务端程序一并启动。目前程序中有一个海报分享的功能,该功能实现中需要一些额外的中文字体的支持,所以需要将此部分中文字体放置到宿主机的某个目录下,并在环境变量中指定该目录,脚本中会将该目录映射该到容器内的/usr/share/fonts目录下 对于图片访问,还是延续此前的实现,即在服务器端生成分享海报,存储到本地(指服务器磁盘),而后通过Nginx代理访问。由于目前的服务器我是与他人共用,同时还需要配置域名证书,所以暂时没有将Nginx的部署同步放置到docker compose脚本中。 💡 由于部署中需要提供部分敏感信息,比如:小程序的密钥、天气应用的key、docker镜像仓库地址。我将所有信息以环境变量的方式进行占位,通过docker compose的环境变量进行替换,即.env文件 小程序发布 小程序端的发布就比较简单了 先将base_url更换为正式环境的地址(我没有提交此部分代码,你可以自己更改) 本次调试没有问题后,就可以上传代码,即提交为体验版本 而后使用体验版本测试没有问题,就可以提交审核 审核通过后,就可以发布了 总体来看,本次发布很顺利,审核在十分钟就通过了。

March 13, 2024 · 1 min · Fuyi

微天气 Github Action镜像自动构建与推送

前言 这里暂不作过多的操作,还是保持与此前一致。即通过Github Action完成Docker Image的build与push,目标仓库为阿里云容器镜像服务实例(个人版)registry.cn-hangzhou.aliyuncs.com 那么一共分为三个部分: Dockerfile编写 阿里云容器镜像服务配置 Github Action Dockerfile编写 jdk17 gradle FROM gradle:jdk17-alpine AS build # 设置语言,支持中文 ENV LANG C.UTF-8 COPY --chown=gradle:gradle . /opt/gradle/src WORKDIR /opt/gradle/src RUN gradle clean build -x test --no-daemon FROM eclipse-temurin:17-jdk-jammy COPY --from=build /opt/gradle/src/build/libs/*.jar /usr/app/ WORKDIR /usr/app/ RUN sh -c 'touch micro-weather-backend-1.0.0-RELEASE.jar' ENTRYPOINT ["java", "-jar", "micro-weather-backend-1.0.0-RELEASE.jar"] Github Action 先在阿里云镜像服务中创建命名空间 创建仓库(可选,因为可以自动创建) 编写Github Action脚本 name: Micro Weather Service Image Build And Push CI on: push: branches: - 'main' jobs: docker: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 # setup-qemu 如果您想使用 QEMU 添加仿真支持以便能够针对更多平台进行构建,则 action 会很有用 - name: Set up QEMU uses: docker/setup-qemu-action@v1 # setup-buildx-action 将默认使用docker-container 构建器驱动程序创建和引导构建器。非必需 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to Aliyun DockerHub uses: docker/login-action@v1 with: registry: ${{secrets....

March 13, 2024 · 1 min · Fuyi

微天气—行政区划数据(二)

前言 此前提到微天气应用程序需要使用到行政区划数据,不过上一章所使用的数据来源于网络,或多或少都可以考虑一下是否还有其他获取的方式,所以也就有了本文的内容。 在这里,将基于全国1:100万基础地理信息数据进行行政区划数据的提取。本文用于记录使用程序实现全国1:100万基础地理信息数据合并的全过程。 当然,本文产生的最重要原因其实并不是受到微天气的启发,更多的是个人想试一试能不能用。 数据说明 全国1:100万公众版基础地理信息数据(2021)覆盖全国陆地范围和包括台湾岛、海南岛、钓鱼岛、南海诸岛在内的主要岛屿及其临近海域,共77幅1:100万图幅,该数据集整体现势性为2019年。数据采用2000国家大地坐标系,1985国家高程基准,经纬度坐标。 为满足广大社会群众对地理信息数据资源的需求,经自然资源部授权,全国地理信息资源目录服务系统提供全国1:100万全图层要素免费下载的服务。下载数据采用1:100万标准图幅分发,内容包括水系、居民地及设施、交通、管线、境界与政区、地貌与土质、植被、地名及注记9个数据集,且保存要素间空间关系和相关属性信息。 💡 提供下载的是矢量数据,不是最终地图,与符号化后的地图再可视化表达上存在一定差异。用户利用此数据编制地图,应当严格执行《地图管理条例》有关规定;编制的地图如需向社会公开的,还应当依法履行地图审核程序。 成果规格 分幅编号及范围 1:100万公众版基础地理信息数据(2021)的图幅总数为77幅,分幅数据按照GB/T 13989-2012《国家基本比例尺地形图分幅和编号》执行。空间存储单元为6°(经差)×4°(纬差)。 坐标系统 平面坐标系: 2000国家大地坐标系。 高程基准:1985国家高程基准。 地图投影:分幅数据采用地理坐标,坐标单位为度。 几何精度 更新后地物点对于附近野外控制点的平面位置和高程中误差符合下表的要求,以两倍中误差值为最大误差。 地物点误差 最小 最大 平面位置 100 500 高程 50 200 现势性 1:100万地形数据现势性与更新使用的数据源的现势性一致,数据整体现势性达到2019年。 成果数据组织 全国1:100万公众版地形数据(2021)内容包括水系、居民地及设施、交通、管线、境界与政区、地貌与土质、植被、地名及注记9个数据集。 数据分层的命名采用四个字符,第一个字符代表数据分类,第二三个字符是数据内容的缩写,第四个字符代表几何类型。 目标 实现分图层合并(处理图幅合并时接边问题) 水系(暂缓) 交通(暂缓) 境界与政区(国、省、市、县) 地名及注记 根据合并后的行政区划与地名注记,制作行政区划数据库 数据库使用PostgreSQL(PostGIS) 设计 图层解析程序 Java程序, 使用GDAL 读取GDB 逻辑 根据《国家基本比例尺地形图分幅和编号》规定可知网格范围,通过网格范围动态生成对应网格的分幅编号,并以该编号进行数据检索。如果命中则根据成果数据组织规格以及相关标准对数据进行解析,如果未命中则跳过,直至网格扫描完毕。 经度:72~138(E),43~53(11) 纬度:0~56(N),A~N(14) 即,网格范围:[43,53] x [A,N] 数据的处理流程可使用责任链模式进行,后续也方便加入其他的处理流程。即,整体的执行框架为策略模式+责任链模式。为统一策略选择模型,在此提出图层定义(LayerDefinition)的概念。 LayerDefinition由如下几个关键要素组成: 图层数据源(LayerSource) driver:驱动,参考java.sql.UnWrapper实现 instance name catalog: schema: table: commonDefinitionKey :常规定义缓存的key fieldDefinitionKey :字段定义缓存的key featureCarrierKey :要素载体缓存的key origin:数据来源(分幅文件路径) scale:比例尺(如:1000000,表示1:1000000) sourceSpatialRef:源坐标系(表现形式可为标准ID、PROJ Text、WKT Text) sinkSpatialRef:目标坐标系(表现形式可为标准ID、PROJ Text、WKT Text) featureCode:要素分类码,对应成果数据组织中的要素分类(如:C、B) name:图层命名,也是图层分类码 layerCode:图层分类码 release:释放格式(比如:WMTS、Shapefile、GDB…) 描述字符为:比例尺:源坐标系:目标坐标系:要素分类码:图层名称:释放格式,在描述字符串中,坐标系仅使用标准ID表示...

October 16, 2023 · 2 min · Fuyi

微天气—行政区划数据(一)

前言 微天气程序中存在如下几个功能需要使用到行政区划数据: 城市列表,需要支持城市搜索 根据经纬度获区域(城市)的天气数据 地图坐标拾取并获取所处区域(城市)信息,同时获取天气数据 对于城市的天气数据,不使用和风天气的城市列表,而是自行维护,通过空间位置(经纬度)进行关联。对于城市位置的定义,本可以选择如行政中心或市中心,但我没有这样的数据,就直接用城市区划范围的中心点代替。不准确不重要,过程已经满足了,且后续是可以替换的。 其实完全可以使用官方提供的城市数据和GeoAPI覆盖这些功能,但既然我是做GIS开发的,而且手里也有可以用作研究学习的数据,为啥不用呢。 今天突然发现,其实我可以爬一下和风的数据,这样就可以拿到城市选择的经纬度数据了 @time 2023.10.10 About 行政区划解析程序,输入shape文件,写入Postgresql. 大体完整的四级行政区划数据组织 github link: fuyi-district-parse 数据情况 数据原源于网络,由于时间久远,我已经忘记了是如何获取到的 名词解释 省级行政区 中国的一级行政区,或称国家一级行政区或省级行政区,是指直属中央政府管辖的行政区划,在历史上曾有不同的称呼。如:省、自治区、直辖市、特别行政区。 地级行政区 地级行政区即“地区级别行政区”,是现行中华人民共和国行政区划中常规的第二级行政区划单位,包括地级市、地区、盟、自治州等。地级行政区隶属于省、自治区、直辖市等省级行政区之下;下辖若干个县、区、县级市、旗等县级行政区。作为特例,东莞市、中山市、嘉峪关市、儋州市等四个地级市下辖街道办事处与乡镇,不辖县、区,因此也称作“直筒子(地级)市”。地级行政区的级别为正厅级,所以非正厅级的省直辖的行政区划不算作地级行政区,例如:湖北省辖的仙桃市、天门市、潜江市;河南省辖的济源市等等。直辖市下辖的区,虽然是正厅级,但未列入地级行政区的统计。 县级行政区 县为中华人民共和国行政区划单位之一,县级行政区指行政地位与“县”相同的行政区划单位的总称,其管辖乡级行政区。为乡、镇的上一级行政区划单位。中华人民共和国成立后,随着行政督察区名称的变更,除各直辖市均隶属于专区(行政督察专区)、地区或地级行政区,现除各直辖市、海南省直管县外均为地级行政区的下一级行政区。 按省、县、乡三级行政区划制度划分,县级行政区属于第二级行政区,为直辖市的下级行政区划单位。 按省、地、县、乡四级行政区划制度划分,县级行政区属于第三级行政区,属于省、自治区所辖地级行政区的下级行政区划单位。 乡级行政区 乡,中华人民共和国现行基层行政区划单位,区划层次介于县与村之间。“乡”为县、县级市下的主要行政区划类型之一。中国行政区划史上,“乡”一直为县的行政区划单元,因此现行处同一层次的区划单位归入乡级行政区。中国自改革开放以来,由于城市的快速扩张,行政区划制度出现了大的变革。1980年代以后“乡改镇”、“乡改街道”的现象越来越普遍。 在乡级行政区划中,乡(包括镇)设有一级人民政府,属于基层政权;乡的行政区划单位为村(含民族村)。但很多乡设有社区,乡的区划单位设置与镇、街道看不出实质性差异。 目的 解析所有数据文件,实现最终入库 使用GeoTools实现 数据库表结构: 行政区划信息(district_info) id:自增Id(bigserial) name:行政区划名称 grade:行政区划等级(省级行政区:1, 地级行政区:2, 县级行政区:3,) code:行政区代码 center_point:中心点(geometry::point) bounds:行政区边界(geometry) 注: 数据入库前审查,保证行政区代码唯一 使用grade区分省、市、县、乡镇 对于省、市、县code列,统一进行前6位截取(不满6位字符所在数据,直接丢弃),对于乡镇则统一进行前9位进行截取(不满9位字符所在数据,直接丢弃) 省级行政区 存在错乱数据,可以使用行政区代码识别(adcode) 地级行政区 存在错乱数据,可以使用行政区代码识别(code),需要截取前6位 县级行政区 存在错乱数据,可以使用行政区代码识别(code),需要截取前6位 乡级行政区 成果 记录数:46652 点数据为各个行政区中心点 数据表 PostGIS CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA public; 行政区划 -- -- Name: district_info_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres -- CREATE SEQUENCE public....

October 10, 2023 · 6 min · Fuyi

如何构建一个矢量瓦片服务

前言 关于矢量瓦片(节选) 地图瓦片技术是在线地图服务常用的瓦片技术,瓦片就是地图瓦片的具体存储形态,提前切好的瓦片可以大大提高在线地图的访问效率。 栅格瓦片 以图片为介质的栅格瓦片使得在线地图得以迅速普及,优势在于显示效率高、方便传输。但是,随着地图的移动化和应用的逐渐深入,栅格瓦片占用带宽和存储都较大,不利于地图在移动设备的应用。 矢量瓦片 矢量瓦片的产生弥补了栅格瓦片的不足。矢量瓦片数据以矢量形式存在。矢量瓦片体积下,可高度压缩,占用的存储空间比栅格瓦片要小上千倍。数据传输体量小,地图更新的代价小 常见的矢量瓦片制作工具(节选) 目前开源的矢量切片工具还是非常多的,列出一些主流的阐述下: 基于GeoServer的矢量切片插件,适合熟悉GeoServer的用户,操作还比较简单,缺点是切片的行列号与一般的XYZ编号不同不容易单独部署。 基于tippecanoe的矢量切片工具方案,该工具提供了很多高级功能在数据定制化上有很强的优势,但只能部署在Linux,并不是跨平台,只能读取geojson文件,不能直连数据库,不是很好,如果有幸您是c++开发大神,可以改下库的编译绑定平台,使其支持windows,再更改下数据源底层,使其能支持空间数据库,那么该工具会有更多的应用空间。 基于PostGIS的矢量切片方案,该方案在熟悉PostGIS的用户中应该很受欢迎,优势是支持动态矢量切片,有PG社区的系统级加成。 总的来说,工具虽然很多,但是没有一款可以说覆盖一切场景的,具体应用还是看场景的,比如前两个方案都是做底图数据时比较有用,都是静态矢量切片方案,geoserver能直连数据库,tippecanoe有强数据定制性要求,那么如果用户侧重点是简单点的话geoserver够了,用户侧重点是希望对数据做很多高级过滤什么的操作用tippecanoe,但步骤麻烦点。这些矢量切片工具仅仅在处理很久不变的数据,就是切一次用很久的数据,如果数据频繁变化,这种静态数据切片工具就很不好用了。 与其他方案相比,PostGIS方案的好处主要有两大点: 资源开销低:空间数据一般存空间数据库中,传统工具会先从数据库中捞数据,这个数据通常很大,网络开销和服务器端内存都要很大,查询慢计算慢是肯定的。而PostGIS是在数据库中把数据处理完,只把结果传给后台转前台,可以很方便的使用数据库的索引,并行计算等,优化查询和处理速度。 动态矢量切片,数据时效性高:每当根据xyz请求时,数据库会动态查询范围内数据,裁剪简化并输出pbf格式的二进制数据出去,在数据变化频繁的场景下,可以保证用户看到的是最新的数据。 💡 GeoServer、Tippecanoe 皆为静态矢量切片方案,需提前准备切片数据,并进行持久化(GeoServer也可以在使用时进行切片,同时进行持久化)。PostGIS支持动态矢量切片方案,即实时计算生成切片,且不进行切片的持久化。 为什么要自己写一个服务 于我个人而言,我目前仅接触和使用到了GeoServer,且对其中的实现细节并不太清楚,所以想通过参考模仿的方式实现一个示例服务。其次,还想测试在没有如GeoWebcache此类的瓦片缓存的情况下,服务的性能如何。综上所述,其实也就是为了如下这几方面的目的: 学习,了解其中的实现细节 更好的适配 比如说,WMTS服务很明确存在缓存,WMS性能又不够好。如果使用WMTS服务确实可以提升服务的性能,但是对于源数据存在编辑的场景下,缓存问题还是会让人头疼。 那么是否存在动态的矢量瓦片服务?既能解决缓存的问题,同时还没有太大的性能问题。 你或许会提到基于PostGIS的动态矢量瓦片服务,但是有些历史的原因,短时间内没有变法变更数据库。当然也可以基于类如CDC这样的功能进行缓存的更新,但其实还是会存在缓存的问题,只是说可以通过一些手段降低缓存问题出现的概率,并无法从根本上解决问题 所以,基于此,既然PostGIS可以实现动态矢量瓦片服务,我们自然也可以。公瑾大佬曾发文说过,当下地图服务去服务化、数据不切片基本上已经是必然的趋势,那么我为什么还要去做一个服务化的东西。大概就是下面这几个原因了: 数据库技术,在某些特定的因素下,短时间内无法切换到PostGIS 数据量级 性能容忍度 小厂,我不思进取 🙄 后续知识储备 矢量瓦片标准 参见:矢量瓦片标准 在这里贴几个关键点(对于目前使用上来说): 文件格式 矢量瓦片文件采用Google Protocol Buffers进行编码。Google Protocol Buffers是一种兼容多语言、多平台、易扩展的数据序列化格式。 投影和范围 矢量瓦片表示的是投影在正方形区块上的数据。矢量瓦片不应该包含范围和投影信息。解码方被假定知道矢量瓦片的范围和投影信息。 Web Mercator是默认的投影方式,Google tile scheme是默认的瓦片编号方式。两者一起完成了与任意范围、任意精度的地理区域的一一对应,例如https://example.com/17/65535/43602.mvt。 矢量瓦片可以用来表示任意投影方式、任意瓦片编号方案的数据。 内部结构 图层 每块矢量瓦片应该至少包含一个图层。每个图层应该至少包含一个要素。 几何图形编码 矢量瓦片中的几何数据被定义为屏幕坐标系。瓦片的左上角(显示默认如此)是坐标系的原点。X轴向右为正,Y轴向下为正。几何图形中的坐标必须为整数。 矢量瓦片服务构建 在这里,我选择抄GeoServer的作业。众所周知,PostGIS是开源的,那为什么没有选择抄PostGIS的作业呢? 当下水平不够 想快速验证想法 想基于GeoServer做二次开发,或者说是基于现存的地图服务相关的实现,集各家之大成,合并成一个组在功能上可自由搭配的、较高性能服务端组件 接着说当前的事情。要实现一个动态矢量瓦片服务,我们需要先分析一下实现内容,在此先做出如下拆解: 动态矢量瓦片服务可以理解为没有瓦片缓存的,实时生成的矢量瓦片服务,所以核心还是矢量瓦片服务 矢量瓦片服务也就是根据调用端传递的参数,从数据源获取对应的数据,并将其转换为矢量瓦片格式,最终返回给调用端 这里选择瓦片坐标作为检索参数,可以便于服务降级(缓存)和性能优化(瓦片坐标值相对来说更加准确和可固定,且便于降维) 需要实现瓦片坐标系到数据源坐标系下数据范围的相互转换 需要实现数据源的范围查询 需要实现矢量数据到矢量瓦片的编解码 那么大体的实现路径可归结于如下所示: 其中的核心要点总结如下: 瓦片金字塔模型构建 瓦片坐标系与空间坐标系的映射关系 切片方案确定 瓦片大小 分辨率 … 矢量瓦片的编解码 矢量数据查询 下面将对以上几点作详细描述,本次内容基本上全部参考GeoServer实现完成。...

May 23, 2023 · 5 min · Fuyi

GeoServer开发环境搭建

前言 本文用于记录GeoServer开发环境的搭建过程 通过GeoServer发布计划可以看到,在2.23.x版本开始,会移除对jdk1.8的支持。那么当前我们会选择2.22.x版本进行研究 环境 JAVA:1.8或11 Maven Git Action 获取源码 git clone git://github.com/geoserver/geoserver.git geoserver # or git clone https://github.com/geoserver/geoserver.git geoserver 代码库结构 Each branch has the following structure: build - release and continuous integration scripts doc - sources for the user and developer guides src - java sources for GeoServer itself data - a variety of GeoServer data directories / configurations 切换到2.22.x分支 # 查看分支 git branch -av # 切换分支 git checkout -b 2....

March 9, 2023 · 2 min · Fuyi

深入研究GeoServer—开篇

为什么需要深入研究GeoServer GeoServer是一个开源的、流行的、Java实现的可发布和共享地理信息数据的软件服务器,是WMS、WCS、WFS的标准实现,含WMTS GeoServer功能强大,但是我可能只会用到其中的一两个部分,比如坐标转换与WMTS服务。可以通过研究将其进行提取和重组,形成符合我要求的,更加精简方便的软件服务器 GIS后端开发绕不过去的知识点 如何进行研究 开发环境搭建 通过WMTS请求链接到源码 通过源码进行研究学习 … 未完待续…

March 9, 2023 · 1 min · Fuyi

Computer System Roaming

前言 此为深入理解计算机系统(csapp)第一章的笔记,也算是一个开始了。 Hello程序 #include <studio.h> int main() { printf("hello world\n"); return 0; } 基本思想 系统中所有的信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传输的数据,都是由一串比特(bit)表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。 要点 源程序实际上就是一个由0和1组成的位(或称为比特:bit)序列,8个位为一组,称为字节(byte)。 大部分的现代计算机系统都使用ASCII标准来表示文本字符,这种方式实际上就是用一个唯一的单字节大小的整数值来表示每个字符 hello.c程序是以字节序列的方式存储在文件中。每个字节都有一个整数值,对应于某些字符(注意:每个文本行都是以一个看不见的换行符“/n”来结束的) 只由ASCII字符构成的文件称为文本文件,所有其他文件都称为二进制文件 编译系统(compilation system):编译的四个阶段 gcc -o hello hello.c hello.c(文本) —> 预处理器[cpp] —> hello.i(文本) —> 编译器[ccl] —> hello.s(文本) —> 汇编器[as] —> hello.o(二进制) —> 链接器[ld] —> hello(二进制) 预处理:预处理器处理#开头的命令,修改原始的C程序 编译:编译器将hello.i翻译为hello.s,即将源文件翻译为汇编语言。汇编语言是非常有用的,因为它为不同高级语言的不同编译器提供了通用的输出语言。例如,C编译器和Fortran编译器产生的输出文件用的都是一样的汇编语言 汇编:汇编器将hello.s翻译为机器语言指令,把这些指令打包成一种叫做可重定位目标程序(relocation object program)的格式,并将结果保存在目标文件hello.o中。hello.o是一个二进制文件(即将汇编内容翻译为机器语言指令,并将这些指令打包成一种叫做可重定位目标程序的格式) 链接:链接器用于处理合并。比如在hello程序中调用了printf函数,它是每个C编译器都提供的标准C库中的一个函数。printf函数存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到hello.o程序中。链接器就负责处理这种合并。最终得到hello文件,它是一个可执行目标文件(或简称为可执行文件),可以被加载到内存中,由系统执行 shell是一个命令行解释器,它输出一个提示符,等待输入一个命令行,然后执行这个命令。如果该命令行的单词不是一个内置的命令,那么shell就会u假设这是一个可执行文件的名字,它将加载并运行这个文件。 系统的硬件组成 CPU:中央处理单元; ALU:算术/逻辑单元; PC:程序计数器; USB:通用串行总线 总线 贯穿整个系统的是一组电子管道,称做总线,它携带信息字节并负责在各个部件间传递。硬件之间进行信息交流需要有一个统一的标准,也就是二进制信息传递规则,为了高效考虑,通常总线被设计成传送定长的字节块,也就是字(word)。字中的字节数(即字长)是一个基本的系统参数,在各个系统中的情况都不尽相同。现在的大多数机器字长要么是4个字节(32位),要么是8个字节(64位)。 I/O设备 输入 / 输出(I/O)设备是系统与外部世界的联系通道。每个 I/O 设备都通过一个控制器或适配器与 I/O 总线相连。控制器与适配器之间的区别主要在于它们的封装方式。控制器是 I/O 设备本身或者系统的主印制电路板(通常称为主板)上的芯片组。而适配器则是一块插在主板插槽上的卡。无论如何,它们的功能都是在 I/O 总线和 I/O 设备之间传递信息。...

March 2, 2023 · 2 min · Fuyi

Fuyi Atlas Init

前言 I have a dream too! 开源技术赋予我们站在巨人的肩膀上做到更高更强的可能,我想通过开源技术来构建一个地理信息的世界(such as: one personal cloud gis),愿给地理信息数据带来更多的使用价值。当前主要关注空间数据库、数据处理与应用以及数据渲染,由内到外,逐步构建。既然都说人类活动所接触、产生的信息80%以上都与地理空间位置有关,那么这些空间数据就应该很容易的被使用,而不是仅被围困在专业领域内,不是吗? Fuyi Atlas(拂衣志),取自 《侠客行》、Cloud Atlas以及Discovery Atlas。愿自己也能行此间小事,而非蹉跎岁月。 Fuyi Atlas Website将会使用Hugo + Github Pages进行构建,本文用于记录Fuyi Atlas的初始构建过程。 HUGO是什么 Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again. Hugo是一个使用GO语言编写的,开源的,静态站点生成器。 也就是说,你可以使用Hugo来快速构建你自己的静态站点。比如个人博客、知识库、产品介绍、文档等等。 我此前使用vuepress来构建我的个人站点,接触Hugo之后,更愿意使用Hugo。那么我将使用Hugo代替vuepress来构建我的个人站点。理由有那么几个: Hugo是一个纯粹的生成器 Hugo没有过多的生态依赖 Hugo更轻 据说更快,其LiveReload可以实现近实时的内容刷新 挺多可选的开源主题 使用更加简单 我也不是很喜欢node_modules Fuyi Atlas Site Build Hugo Install Hugo is available in two editions: standard and extended....

February 19, 2023 · 3 min · Fuyi