当前位置: 首页 > news >正文

基于geojson-vt和canvas的高性能出图

概述

本文介绍基于geojson-vtcanvas,实现node端高性能出图。

效果

动画.gif

性能

实现

1. canvas绘图

import { createCanvas } from 'canvas'const tileSize = 256;
const canvas = createCanvas(tileSize, tileSize)
const ctx = canvas.getContext('2d')

2. 处理geojson

const geojson = result.rows[0].geojson;
geojson.features = geojson.features || []
const tileIndex = geojsonvt(geojson, {maxZoom: 22,tolerance: 3, // simplification tolerance (higher means simpler)extent: 4096, // tile extent (both width and height)buffer: 64,   // tile buffer on each sidedebug: 0,     // logging level (0 to disable, 1 or 2)lineMetrics: false, // whether to enable line metrics tracking for LineString/MultiLineString featurespromoteId: null,    // name of a feature property to promote to feature.id. Cannot be used with `generateId`generateId: false,  // whether to generate feature ids. Cannot be used with `promoteId`indexMaxZoom: 5,       // max zoom in the initial tile indexindexMaxPoints: 100000 // max number of points per tile in the index
})
const features = tileIndex.getTile(Number(z), Number(x), Number(y))?.features || [];

3. 绘制features

function drawTile(features, zoom) {ctx.clearRect(0, 0, tileSize, tileSize);// 绘制边框// ctx.strokeStyle = '#fff'// ctx.lineWidth = 1// ctx.strokeRect(0, 0, tileSize, tileSize)for (let i = 0; i < features.length; i++) {const feature = features[i];const {adcode, name} = feature.tagsconst type = feature.type;ctx.beginPath();for (let j = 0; j < feature.geometry.length; j++) {const geom = feature.geometry[j];if (type === 1) { // 1点ctx.save()ctx.fillStyle = `rgba(${'255,0,0'}, 1)`;ctx.strokeStyle = '#fff'ctx.lineWidth = 2;ctx.textAlign = "center";ctx.textBaseline = "middle"ctx.font = "bold 16px 宋体";// const len = ctx.measureText(name).width / 2;// const offset = 5// if(x + len > tileSize) x = tileSize - len - offset// if(x - len < 0 ) x = len + offsetif(name && zoom >= 9) {ctx.strokeText(name, geom[0] / 16.0, geom[1] / 16.0)ctx.fillText(name, geom[0] / 16.0, geom[1] / 16.0)}// ctx.arc(geom[0] / 16.0, geom[1] / 16.0, 3, 0, 2 * Math.PI, false);ctx.restore()ctx.fill()ctx.stroke()} else { // 2线 或 3面// const color = colorDict[adcode] || '255,0,0'const color = '255,0,0'ctx.strokeStyle = `rgba(${color}, 1)`;ctx.fillStyle = `rgba(${color}, 0.1)`;ctx.lineWidth = 1;for (let k = 0; k < geom.length; k++) {const p = geom[k];if (k) ctx.lineTo(p[0] / 16.0, p[1] / 16.0);else ctx.moveTo(p[0] / 16.0, p[1] / 16.0);}// if (type === 3) ctx.fill();ctx.stroke();}}}
}

4. 设置缓存并发送到前端

app.get('/tile/:z/:x/:y', (req, res) => {const {z, x, y} = req.paramstry {getFeatures(x, y, z).then(image => {res.setHeader('Expires', new Date(Date.now() + 30 * 1000).toUTCString())res.writeHead(200, {"Content-Type": "image/png",});res.end(image);})} catch (err) {console.error(err);}   
})

5. 数据获取

数据是存在PG数据库中,可通过node连接获取,可通过如下语句直接将结果转换为geojson。

SELECT json_build_object('type', 'FeatureCollection','features', json_agg(ST_AsGeoJSON(t.*)::json)
) as geojson FROM (select adcode, name, geom from base_county where st_intersects(BBox(101, 52, 7), geom)
) as t(adcode, name, geom);

image.png

6. 前端调用

new ol.layer.Tile({source: new ol.source.XYZ({url: 'http://127.0.0.1:18089/tile/{z}/{x}/{y}'})
}),

相关文章:

基于geojson-vt和canvas的高性能出图

概述 本文介绍基于geojson-vt和canvas&#xff0c;实现node端高性能出图。 效果 实现 1. canvas绘图 import { createCanvas } from canvasconst tileSize 256; const canvas createCanvas(tileSize, tileSize) const ctx canvas.getContext(2d)2. 处理geojson const g…...

CTF是黑客大赛?新手如何入门CTF?

CTF是啥 CTF 是 Capture The Flag 的简称&#xff0c;中文咱们叫夺旗赛&#xff0c;其本意是西方的一种传统运动。在比赛上两军会互相争夺旗帜&#xff0c;当有一方的旗帜已被敌军夺取&#xff0c;就代表了那一方的战败。在信息安全领域的 CTF 是说&#xff0c;通过各种攻击手…...

电脑开不了机用U盘重装系统Win10教程

如果我们遇到了电脑开不起机的问题&#xff0c;这给我们的正常使用带来了很大的影响。这时候我们可以借助U盘重装系统的方法&#xff0c;轻松应对这一问题。下面小编给大家详细介绍关于用U盘给开不机的电脑重装Win10系统的教程步骤&#xff0c;操作后用户就能正常使用电脑了。 …...

四叉堆在GO中的应用-定时任务timer

堆作为必须掌握的数据结构之一&#xff0c;在众多场景中也得到了广泛的应用。 比较典型的&#xff0c;如java中的优先队列PriorityQueue、算法中的TOP-K问题、最短路径Dijkstra算法等&#xff0c;在这些经典应用中堆都担任着灵魂般的角色。 理论基础 binary heap 再一起回忆…...

Flow深入浅出系列之使用Kotlin Flow自动刷新Android数据的策略

Flow深入浅出系列之在ViewModels中使用Kotlin FlowsFlow深入浅出系列之更聪明的分享 Kotlin FlowsFlow深入浅出系列之使用Kotlin Flow自动刷新Android数据的策略 Flow深入浅出系列之使用Kotlin Flow自动刷新Android数据的策略 讨论在Android应用程序中使用Kotlin Flow高效加载…...

AC修炼计划(AtCoder Regular Contest 165)

传送门&#xff1a;AtCoder Regular Contest 165 - AtCoder 本次习题参考了樱雪猫大佬的题解&#xff0c;大佬的题解传送门如下&#xff1a;Atcoder Regular Contest 165 - 樱雪喵 - 博客园 (cnblogs.com) A - Sum equals LCM 第一题不算特别难 B - Sliding Window Sort 2 对…...

【Express】登录鉴权 JWT

JWT&#xff08;JSON Web Token&#xff09;是一种用于实现身份验证和授权的开放标准。它是一种基于JSON的安全传输数据的方式&#xff0c;由三部分组成&#xff1a;头部、载荷和签名。 使用jsonwebtoken模块&#xff0c;你可以在Node.js应用程序中轻松生成和验证JWT。以下是j…...

【微服务 SpringCloud】实用篇 · Ribbon负载均衡

微服务&#xff08;4&#xff09; 文章目录 微服务&#xff08;4&#xff09;1. 负载均衡原理2. 源码跟踪1&#xff09;LoadBalancerIntercepor2&#xff09;LoadBalancerClient3&#xff09;负载均衡策略IRule4&#xff09;总结 3. 负载均衡策略3.1 负载均衡策略3.2 自定义负载…...

zabbix-proxy代理服务器配置

下载zabbix源 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm 安装 yum -y install zabbix-proxy-mysql zabbix_get 查看相关文件路径 rpm -ql zabbix-proxy-mysql 创建数据库 mysq -uroot -proot mysql> create database…...

【python零基础入门学习】python进阶篇之OOP - 面向对象的程序设计

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

中国xx集团信息技术工程师面试

进入面试间&#xff0c;坐着三位面试官&#xff0c;压力扑面而来&#xff0c;三位面试官先做了自我介绍&#xff0c;介绍了一下面试的流程后才开始面试。 一、自我介绍 不多说。 二、看你学过数据挖掘这门课&#xff0c;能简单介绍一下有哪些章节&#xff0c;学了些什么&…...

Jmeter接口自动化测试 —— Jmeter下载安装及入门

jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试&#xff0c;它最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。 下载 下载地址&#xff1a;Apache JMeter - Download Apache JMeter 安装 由于Jmeter是基于Java的…...

ARM 学习笔记2 初识Cortex-M33与STM32G4

入门 ARM Cortex-M系列处理器的差异与联系&#xff1a;【ARM Cortex-M 系列 1 – Cortex-M0, M3, M4, M7, M33 差异】两本书籍的英文版和中文版 Definitive Guide to Arm Cortex-M23 and Cortex-M33 Processors Arm Cortex-M23和Cortex-M33微处理器权威指南ST的介绍页 Arm Cor…...

vue中使用coordtransform 互相转换坐标系

官方网站&#xff1a;https://www.npmjs.com/package/coordtransform 在使用高德sdk时&#xff0c;其返回的坐标在地图上显示时有几百米的偏移&#xff0c;这是由于高德用的是 火星坐标&#xff08;GCJ02&#xff09;&#xff0c;而不是wgs84坐标。为了消除偏移&#xff0c;将G…...

双线性插值详解

双线性插值的原理网上资料非常多,本文重点介绍双线性插值实现的两种方式: 角对齐(coner_align = True) 和 边对齐(coner_align = False)。两种不能的方式下去实现双线性插值,目标图像中的每个像素点,它是如何计算取值的,本文会通过原理结合代码的方式将实现细节讲清楚。 1…...

C++ “”

&加上有时候会加速 如果想该对象跟着函数变化一定要加“&” 在题目函数里面定义的 例如 vector<vector<bool>> visited(grid.size(),vector<bool>(grid[0].size(),false)); 如果自己定义的新void dfs&#xff08;vector<vector<bool>>…...

计算机三级有必要考吗?计算机三级有哪些科目?

在大学期间&#xff0c;计算机等级考试是一门很火热的考试&#xff0c;很多小伙伴通过二级考试以后在究竟是报考三级还是四级之间徘徊&#xff0c;下面肉丸子就来给大家分析一下&#xff0c;究竟有没有必要考计算机三级考试&#xff0c;以及计算机三级考试的科目有哪些&#xf…...

6.5 Elasticsearch(五)Spring Data Elasticsearch - 增删改查API

文章目录 1.Spring Data Elasticsearch2.案例准备2.1 在 Elasticsearch 中创建 students 索引2.2 案例测试说明 3.创建项目3.1 新建工程3.2 新建 springboot module&#xff0c;添加 spring data elasticsearch 依赖3.3 pom.xml 文件3.4 application.yml 配置 4.Student 实体类…...

XPS—专项文献阅读-科学指南针

XPS&#xff08;X-ray Photoelectron Spectroscopy&#xff09;&#xff0c;X射线光电子能谱&#xff0c;可以说是材料研究中必不可少的一类分析测试手段了。今天我们就来讲讲&#xff0c;什么情况下我们需要用到XPS&#xff0c;以及拿到数据之后应该怎样进行数据处理分析。 XP…...

电脑办公助手之桌面便签,助力高效率办公

在现代办公的快节奏中&#xff0c;大家有应接不暇的工作&#xff0c;每天面对着复杂的工作任务&#xff0c;总感觉时间不够用&#xff0c;而且工作无厘头。对于这种状态&#xff0c;大家可以选择在电脑上安装一款好用的办公便签软件来辅助日常办公。 敬业签是一款专为办公人士…...

【面试题】2023虹软计算机视觉一面

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 1.自我介绍 2.介绍了自己的项目&#xff0c;并提问项目&#xff0c;讲了30分钟 3.介绍centernet&#xff0c;它和其他目标检测模型有什么区别 4.介绍yolov5 5.介绍focal loss 6.双线性插值和最近邻插值的区…...

板带纠偏控制系统伺服比例阀放大器

板带纠偏控制系统是集光、机、电、液四方面有机结合在一起的全闭环电液伺服系统&#xff0c;是用途广泛的机电一体化高新技术产品。 板带纠偏控制系统可广泛地应用于机械、冶金、造纸、橡胶、织带、纺织印染、电镀、塑膜胶片等诸多行业的不同种类的带材生产线的在线纠偏。 板…...

视频I420裸流保存为文件

1、从TvCamera的ABK回调的OnImageReceived出来的是I420的数据&#xff0c;保存文件的方式如下&#xff1a; void OnImageReceived(const uint8_t* data, size_t size, uint16_t widht, uint16_t height) { .............. FILE *fp fopen("test.yuv", "wb&quo…...

IDEA中SpringBoot项目的yml多环境配置

SpringBoot的yml多环境配置 创建多个配置文件 application.yml #主配置文件 application-dev.yml #开发环境的配置 application-test.yml #测试环境的配置在application.yml中添加多环境配置属性 spring:profiles:active: profiles.active项目启动可能不会识别&#x…...

【Linux】UDP协议

文章目录 &#x1f4d6; 前言1. 再谈端口号1.1 端口号划分范围&#xff1a;1.2 端口和进程的关系&#xff1a;1.2 - 1 netstat1.2 - 2 pidof 1.3 源端口和目的端口&#xff1a; 2. UDP协议2.1 UDP协议格式&#xff1a; 3. 再谈write/read4. UDP需要接收/发送缓冲区吗5. UDP使用…...

AutoCAD 2022 for Mac/Windows升级您的设计工具,提升工作效率

Autodesk AutoCAD 2022 是设计行业最流行的计算机辅助设计 (CAD) 软件之一。这款软件由Autodesk公司开发&#xff0c;它提供了强大的功能&#xff0c;从基本的设计和修改工具&#xff0c;到复杂的3D建模和渲染&#xff0c;一切尽在掌握。通过其直观的用户界面和不断更新的功能&…...

协程,GIL全局解释器,互斥锁,线程池,Concurrent模块

进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位。每一个进程中至少有一个线程。 Python对并发编程的支持 (1)多线程&#xff1a;threading&#xff0c;利用CPU和IO可以同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成。 (2)多进程&#xff1a;multiproces…...

MAPEFFECT代码在传奇中有何作用如何运用

今天介绍一下MAPEFFECT的作用和使用方法&#xff0c;可以实现的效果比如进入游戏或者某个地图显示特效&#xff0c;或者显示地图名称&#xff0c;提示信息等等用到的命令就是MAPEFFECT。 使用方法是 在QManage.txt中找到 [Startup] 在下面增加如下代码 #if #act MAPEFFECT 11…...

Godot 官方2D C#重构(1):雪花碰撞

前言 Godot 官方 教程 Godot 2d 官方案例C#重构 专栏 Godot 2d 重构 github地址 实现效果 难点介绍 Godot GDScript和C# 对应关系大部分靠猜 文件导入 资源地址&#xff1a;默认为res://开头2D贴图导入类型&#xff1a;Texture2D public Texture2D Bullet_Image new Textu…...

计算机基础知识35

进程和线程的比较 1. 进程的开销比线程的开销大很多 2. 进程之间的数据是隔离的&#xff0c;但是&#xff0c;线程之间的数据不隔离 3. 多个进程间的线程数据不共享----->让进程通信(IPC)---->进程下的线程也通信了---->队列 GIL全局解释器锁(重要理论) # 虽然一个进程…...