基于geojson

编程入门 行业动态 更新时间:2024-10-26 15:14:29

基于<a href=https://www.elefans.com/category/jswz/34/1747280.html style=geojson"/>

基于geojson

概述

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

效果

实现

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);

6. 前端调用

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

更多推荐

基于geojson

本文发布于:2023-12-08 03:33:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1672233.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:geojson

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!