Skip to content

Commit ce42d29

Browse files
author
liurh
committed
增加等高程渲染功能
1 parent 37d94fd commit ce42d29

File tree

7 files changed

+633
-48
lines changed

7 files changed

+633
-48
lines changed

README.MD

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
#运行环境
1+
##运行环境
22
nodejs
3-
#依赖
3+
##依赖
44
node-canvas\
55
d3\
66
express
7-
#配置
7+
##配置
88
通过配置bin/www 配置服务端口号
9-
#启动
9+
##启动
1010
>node hot.js
11-
#接口
12-
##渲染服务:
11+
##接口
12+
###渲染服务:
1313
url: /render/spa\
1414
说明:返回渲染后的png图片\
1515
方式:get\

data/china.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

painter/spatial-painter.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ function SpatialPainter() {
44
/**
55
* 初始化颜色版
66
*/
7-
this.init = function () {
7+
this.init = function (conrec) {
88
try {
99
let _paleCanvas = createCanvas(1, 256);
1010
let ctx = _paleCanvas.getContext("2d");
1111
let grad = ctx.createLinearGradient(0, 0, 1, 256);
12-
let gradient = this._getGradientDict();
12+
let gradient;
13+
if(conrec) {
14+
gradient = this._getContecGradientDict();
15+
}else {
16+
gradient = this._getGradientDict();
17+
}
1318
for (let x in gradient) {
1419
grad.addColorStop(parseFloat(x), gradient[x]);
1520
}
@@ -21,9 +26,9 @@ function SpatialPainter() {
2126
}
2227
};
2328

24-
this.paintSpatial = function (canvas, data, projection, polygons,alpha=0.5) {
29+
this.paintSpatial = function (canvas, data, projection, polygons,alpha=0.5,conrec=false) {
2530
try {
26-
this.init();
31+
this.init(conrec);
2732
//插值
2833
//按照画布逐像素点着色
2934
if(data.min && data.max) {
@@ -120,6 +125,10 @@ function SpatialPainter() {
120125
console.log('paint spatial error'+e);
121126
}
122127
};
128+
129+
this.paintContour = function (canvas, data, projection, polygons,alpha=0.5) {
130+
131+
};
123132
/**
124133
* 将地理坐标数据转换成画布坐标数据
125134
* @param data
@@ -306,6 +315,25 @@ function SpatialPainter() {
306315
}
307316
};
308317

318+
this._getContecGradientDict = function () {
319+
return {
320+
0: "#00deff", //蓝色 0
321+
0.099:"#00deff",
322+
0.1: "#00ff32", //绿色 50
323+
0.199: "#00ff32", //绿色 50
324+
0.2: "#ffdc00", //黄色 100
325+
0.299: "#ffdc00", //黄色 100
326+
0.3: "#F06C19", //橙色 150
327+
0.399: "#F06C19", //橙色 150
328+
0.4: "#FF0000", //红色 200
329+
0.599: "#FF0000", //红色 200
330+
0.6: "#87004C", //紫色 300
331+
0.799: "#87004C", //紫色 300
332+
0.8: "#7E0023", //褐红 400
333+
0.999: "#7E0023", //褐红 400
334+
1.0: "rgb(111,4,116)"
335+
};
336+
};
309337
this._getGradientDict = function () {
310338
//AQI颜色标记字典(依据IAQI比例分级)
311339
/*

routes/render.js

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ router.get('/spa', function(req, res) {
2424
let scale = req.query.scale;
2525
let size = req.query.size;
2626
let sectorName = req.query.sectorName;
27+
let conrec = req.query.conrec;
2728
let renderService = new RenderService();
2829
center = [parseFloat(center[0]), parseFloat(center[1])];
2930
size = [parseFloat(size[0]), parseFloat(size[1])];
@@ -60,7 +61,7 @@ router.get('/spa', function(req, res) {
6061
'Content-Type': 'image/png',
6162
"Access-Control-Allow-Origin": "*"
6263
});
63-
let stream = renderService.paintSpatial(data, size, projection, poly).pngStream();
64+
let stream = renderService.paintSpatial(data, size, projection, poly,conrec).pngStream();
6465
map.set(hash, hash);
6566
stream.pipe(fileStream);
6667
stream.pipe(res);
@@ -82,7 +83,7 @@ router.get('/spa', function(req, res) {
8283
'Content-Type': 'image/png',
8384
"Access-Control-Allow-Origin": "*"
8485
});
85-
let stream = renderService.paintSpatial(data, size, projection, polygon).pngStream();
86+
let stream = renderService.paintSpatial(data, size, projection, polygon,conrec).pngStream();
8687
map.set(hash, hash);
8788
stream.pipe(fileStream);
8889
stream.pipe(res);
@@ -110,8 +111,8 @@ router.get('/getimg',function (req,res) {
110111
'Content-Type': 'image/png',
111112
"Access-Control-Allow-Origin": "*"
112113
});
113-
fs.createReadStream('pngCache/' + hash + '.png').pipe(res);
114-
return res.end();
114+
fs.createReadStream('./pngCache/' + hash + '.png').pipe(res);
115+
return;
115116
}
116117
});
117118

@@ -120,80 +121,87 @@ router.post('/postspa',function (req,res) {
120121
console.log('render/statial');
121122
log.info('render/statial');
122123
let fnv = require('fnv-plus');
123-
let hash = fnv.hash(req.body, 64).str();
124+
let body = req.body;
125+
//计算请求hash值
126+
let hash = fnv.hash(body, 64).str();
127+
//查询图片是否缓存,已缓存时直接返回hash
124128
if (map.get(hash)) {
125129
writeHead(res);
126130
return res.end(JSON.stringify({hash:hash}));
127131
}
128-
let data = req.body.data;
129-
let center = req.body.center;
130-
let scale = req.body.scale;
131-
let size = req.body.size;
132-
let sectorName = req.body.sectorName;
132+
let data = body.data;
133+
let center = body.center;
134+
let scale = body.scale;
135+
let size = body.size;
136+
let conrec = body.conrec;
137+
let sectorName = body.sectorName;
133138
let renderService = new RenderService();
134139
center = [parseFloat(center[0]), parseFloat(center[1])];
135140
size = [parseFloat(size[0]), parseFloat(size[1])];
136-
console.log("center %s", center);
137-
console.log("size %s", size);
138141
let floatData = [];
142+
//数据处理成指定格式
139143
for (let i = 0; i < data.datas.length; i++) {
140144
let d = {
141145
lng: parseFloat(data.datas[i].lng),
142146
lat: parseFloat(data.datas[i].lat),
143147
value: parseFloat(data.datas[i].value)
144148
};
149+
//不符合要求的数据跳过
145150
if (!isNaN(d.lng) && !isNaN(d.lat) && !isNaN(d.value)) {
146151
floatData.push(d);
147152
}
148153
}
149154
data.datas = floatData;
155+
//获取投影
150156
let projection = getProjection(center, scale, size);
151157
let polygon;
152158
let fs = require('fs');
153-
let fileStream = fs.createWriteStream('pngCache/' + hash + '.png');
159+
//通过行政区切边
154160
if (sectorName) {
155161
//中国边界
156162
if (sectorName === '中国') {
157163
fs.readFile('./data/chinaborder.json', function (err, geodata) {
164+
//国界地图由多边形数组组成
158165
let geojson = JSON.parse(geodata);
159166
polygon = geojson.data;
160167
let poly = [];
161168
for (let i = 0; i < polygon.length; i++) {
162169
poly.push(polygon[i]);
163170
}
164-
writeHead(res);
165-
let stream = renderService.paintSpatial(data, size, projection, poly).pngStream();
166-
map.set(hash, hash);
167-
stream.pipe(fileStream);
168-
return res.end(JSON.stringify({hash:hash}));
169-
//stream.pipe(res);
171+
let stream = renderService.paintSpatial(data, size, projection, poly,conrec).pngStream();
172+
return cacheAndRes(hash,stream,res);
170173
});
171174
}
172175
//中国地图各省市
173176
else {
174177
fs.readFile('./data/china.json', 'utf-8', function (err, geodata) {
175178
let geojson = JSON.parse(geodata);
176179
for (let i = 0; i < geojson.features.length; i++) {
177-
if (geojson.features[i].properties.name === sectorName) {
178-
polygon = geojson.features[i].geometry.coordinates;
179-
break;
180+
var feature = geojson.features[i];
181+
if (feature.properties.name === sectorName) {
182+
if(feature.geometry.type=="Polygon"){
183+
polygon = feature.geometry.coordinates;
184+
break;
185+
}else if(feature.geometry.type=="MultiPolygon"){
186+
polygon = [];
187+
feature.geometry.coordinates.forEach(element => {
188+
element.forEach(poly=>{
189+
polygon.push(poly);
190+
})
191+
});
192+
break;
193+
}
180194
}
181195
}
182196
console.dir(polygon);
183-
writeHead(res);
184-
let stream = renderService.paintSpatial(data, size, projection, polygon).pngStream();
185-
map.set(hash, hash);
186-
stream.pipe(fileStream);
187-
return res.end(JSON.stringify({hash:hash}));
188-
//stream.pipe(res);
197+
let stream = renderService.paintSpatial(data, size, projection, polygon,conrec).pngStream();
198+
return cacheAndRes(hash,stream,res);
189199
})
190200
}
191-
} else {
192-
writeHead(res);
201+
}
202+
else {//不切边
193203
let stream = renderService.paintSpatial(data, size, projection, polygon).pngStream();
194-
map.set(hash, hash);
195-
stream.pipe(fileStream);
196-
return res.end(JSON.stringify({hash:hash}));
204+
return cacheAndRes(hash,stream,res);
197205
}
198206
}catch(e)
199207
{
@@ -202,6 +210,13 @@ router.post('/postspa',function (req,res) {
202210
}
203211
});
204212

213+
router.post('/spacontour',function (req,res) {
214+
215+
});
216+
217+
/**
218+
* 带文字图片
219+
*/
205220
router.get('/spatext', function(req, res) {
206221
console.log('render/statial');
207222
let fnv = require('fnv-plus');
@@ -257,6 +272,7 @@ router.get('/spatext', function(req, res) {
257272
}
258273
});
259274

275+
260276
/***
261277
* 返回图片边界坐标
262278
*/
@@ -292,6 +308,32 @@ router.get('/utm2lng',function (req,res) {
292308
res.end(lat);
293309
});
294310

311+
312+
let getCache = function(body){
313+
//计算请求hash值
314+
let hash = fnv.hash(body, 64).str();
315+
//查询图片是否缓存,已缓存时直接返回hash
316+
if (map.get(hash)) {
317+
writeHead(res);
318+
return res.end(JSON.stringify({hash:hash}));
319+
}
320+
}
321+
322+
/**
323+
* 写入本地并返回hash
324+
*/
325+
let cacheAndRes = function(hash,stream,res){
326+
let fs = require('fs');
327+
let fileStream = fs.createWriteStream('pngCache/' + hash + '.png');
328+
stream.pipe(fileStream);
329+
map.set(hash, hash);
330+
writeHead(res);
331+
return res.end(JSON.stringify({hash:hash}));
332+
}
333+
334+
/**
335+
* 通过中心点、缩放值、图片大小获取投影
336+
*/
295337
let getProjection = function (center,scale,size) {
296338
let d3 = require('d3-geo');
297339

service/RenderService.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ function RenderService() {
3838
return canvas.pngStream();
3939
};
4040

41-
this.paintSpatial = function (data,size,projection,polygon) {
41+
this.paintSpatial = function (data,size,projection,polygon,conrec=false) {
4242
var canvas = createCanvas(size[0],size[1]);
4343
var SpatialPainter = require('../painter/spatial-painter');
4444
var painter = new SpatialPainter();
45-
painter.paintSpatial(canvas,data,projection,polygon);
45+
painter.paintSpatial(canvas,data,projection,polygon,0.5,conrec);
4646
console.log('return canvas');
4747
return canvas;
4848
};

0 commit comments

Comments
 (0)