Skip to content

Commit 3fae359

Browse files
committed
finetuning, more examples, support pointradius option
1 parent 90792fe commit 3fae359

5 files changed

Lines changed: 424 additions & 93 deletions

File tree

src/qlever-petrimaps/server/RenderContext.cpp

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ RenderContext::RenderContext(int w, int h, double orx, double ory, double mercW,
3636
size_t numThreads)
3737
: _points(numThreads),
3838
_areaFillPoints(numThreads),
39+
_linePoints(numThreads),
3940
_weights(numThreads),
4041
_areaFillWeights(numThreads),
42+
_lineWeights(numThreads),
4143
_rasterDims(numThreads),
4244
_image(w * h * 4),
4345
_style(style),
@@ -52,6 +54,7 @@ RenderContext::RenderContext(int w, int h, double orx, double ory, double mercW,
5254
_rasterDims[i].resize(w * h, {1, 1});
5355
_weights[i].resize(w * h, 0);
5456
_areaFillWeights[i].resize(w * h, 0);
57+
_lineWeights[i].resize(w * h, 0);
5558
}
5659
}
5760

@@ -98,22 +101,46 @@ void RenderContext::writeInteriorObjects(heatmap_t* hm) {
98101
}
99102

100103
// _____________________________________________________________________________
101-
void RenderContext::drawPointObject(size_t tid, int px, int py, double weight,
102-
double rasterW, double rasterH) {
103-
drawPoint(tid, px, py, weight, rasterW, rasterH, _ostyle.pointRadius);
104+
void RenderContext::drawLinePoint(size_t tid, int px, int py, double weight,
105+
double rasterW, double rasterH) {
106+
drawLinePoint(tid, px, py, weight, rasterW, rasterH,
107+
(_ostyle.lineWidth - 1) / 2.0);
104108
}
105109

106110
// _____________________________________________________________________________
107111
void RenderContext::drawLinePoint(size_t tid, int px, int py, double weight,
108-
double rasterW, double rasterH) {
109-
drawPoint(tid, px, py, weight, rasterW, rasterH,
110-
(_ostyle.lineWidth - 1) / 2.0);
112+
double, double, double r) {
113+
if (r < 0) return;
114+
if (_style == OBJECTS) {
115+
if (px >= 0 && py >= 0 && px < _w && py < _h) {
116+
if (abs(ceil(r) - r) > 0.1) {
117+
if (px + 1 < _w && py + 1 < _h &&
118+
_lineWeights[tid][_w * (py + 1) + px + 1] == 0) {
119+
_linePoints[tid].push_back(_w * (py + 1) + px + 1);
120+
_lineWeights[tid][_w * (py + 1) + px + 1] = 1;
121+
}
122+
if (py + 1 < _h && _lineWeights[tid][_w * (py + 1) + px] == 0) {
123+
_linePoints[tid].push_back(_w * (py + 1) + px);
124+
_lineWeights[tid][_w * (py + 1) + px] = 1;
125+
}
126+
}
127+
if (_lineWeights[tid][_w * py + px] == 0) {
128+
_linePoints[tid].push_back(_w * py + px);
129+
_lineWeights[tid][_w * py + px] = 1;
130+
}
131+
}
132+
} else {
133+
if (px >= 0 && py >= 0 && px < _w && py < _h) {
134+
if (_lineWeights[tid][_w * py + px] == 0)
135+
_linePoints[tid].push_back(_w * py + px);
136+
_lineWeights[tid][_w * py + px] += weight;
137+
}
138+
}
111139
}
112140

113141
// _____________________________________________________________________________
114142
void RenderContext::drawPoint(size_t tid, int px, int py, double weight,
115-
double rasterW, double rasterH, double r) {
116-
if (r < 0) return;
143+
double rasterW, double rasterH) {
117144
if (_style == RASTER) {
118145
if (px >= 0 && py >= 0 && px < _w && py < _h) {
119146
_rasterDims[tid][_w * py + px] = {rasterW, rasterH};
@@ -129,20 +156,9 @@ void RenderContext::drawPoint(size_t tid, int px, int py, double weight,
129156
}
130157
} else if (_style == OBJECTS) {
131158
if (px >= 0 && py >= 0 && px < _w && py < _h) {
132-
if (abs(ceil(r) - r) > 0.1) {
133-
if (px + 1 < _w && _weights[tid][_w * py + px + 1] == 0) {
134-
_points[tid].push_back(_w * py + px + 1);
135-
_weights[tid][_w * py + px + 1] = 1;
136-
}
137-
if (py >= 1 && _weights[tid][_w * (py - 1) + px] == 0) {
138-
_points[tid].push_back(_w * (py - 1) + px);
139-
_weights[tid][_w * (py - 1) + px] = 1;
140-
}
141-
}
142-
if (_weights[tid][_w * py + px] == 0) {
159+
if (_weights[tid][_w * py + px] == 0)
143160
_points[tid].push_back(_w * py + px);
144-
_weights[tid][_w * py + px] = 1;
145-
}
161+
_weights[tid][_w * py + px] = 1;
146162
}
147163
} else {
148164
if (px >= 0 && py >= 0 && px < _w && py < _h) {
@@ -176,8 +192,10 @@ void RenderContext::drawArea(size_t tid, const util::geo::DLine& line,
176192
}
177193

178194
if (border) {
179-
const auto& denseline = util::geo::densify(
180-
pxPoly.getOuter(), std::max(0.5, (_ostyle.lineWidth * 1.0) / 2.0));
195+
const auto& denseline = util::geo::sparseify(
196+
util::geo::densify(pxPoly.getOuter(),
197+
std::max(0.5, (_ostyle.lineWidth * 1.0) / 4.0)),
198+
(_ostyle.lineWidth * 1.0) / 10.0);
181199
for (const auto& p : denseline) {
182200
drawLinePoint(tid, p.getX(), p.getY(), val, 1, 1);
183201
}
@@ -283,15 +301,26 @@ void RenderContext::writeHeatmap(heatmap_t* hm) {
283301
} else if (_style == OBJECTS) {
284302
if ((_ostyle.lineWidth - 1.0) / 2.0 >= 0) {
285303
int r = (_ostyle.lineWidth - 1.0) / 2.0;
304+
286305
auto stamp = heatmap_stamp_gen(r);
287306
for (size_t i = 0; i < NUM_THREADS; i++) {
288-
for (const auto& p : _points[i]) {
307+
for (const auto& p : _linePoints[i]) {
289308
size_t y = p / _w;
290309
size_t x = p - (y * _w);
291310
heatmap_add_weighted_point_with_stamp(hm, x, y, 1, stamp);
292311
}
293312
}
294313
heatmap_stamp_free(stamp);
314+
315+
// points
316+
stamp = heatmap_stamp_gen(_ostyle.pointRadius);
317+
for (size_t i = 0; i < NUM_THREADS; i++) {
318+
for (const auto& p : _points[i]) {
319+
size_t y = p / _w;
320+
size_t x = p - (y * _w);
321+
heatmap_add_weighted_point_with_stamp(hm, x, y, 1, stamp);
322+
}
323+
}
295324
}
296325
} else {
297326
// HEATMAP
@@ -304,6 +333,15 @@ void RenderContext::writeHeatmap(heatmap_t* hm) {
304333
}
305334
}
306335

336+
for (size_t i = 0; i < NUM_THREADS; i++) {
337+
for (const auto& p : _linePoints[i]) {
338+
size_t y = p / _w;
339+
size_t x = p - (y * _w);
340+
if (_lineWeights[i][p] > 0)
341+
heatmap_add_weighted_point(hm, x, y, _lineWeights[i][p]);
342+
}
343+
}
344+
307345
auto fillStamp = heatmap_stamp_gen(1);
308346
for (size_t i = 0; i < NUM_THREADS; i++) {
309347
for (const auto& p : _areaFillPoints[i]) {

src/qlever-petrimaps/server/RenderContext.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,21 @@ enum MapStyle { HEATMAP, OBJECTS, RASTER };
1919

2020
struct ObjectStyle {
2121
double pointRadius = 3;
22-
double lineWidth = 2;
22+
double lineWidth = 3;
2323
double fillOpacity = .5;
2424
double lineOpacity = 1;
2525
};
2626

2727
class RenderContext {
2828
public:
2929
RenderContext(int w, int h, double orx, double ory, double mercW,
30-
double mercH, MapStyle style, ObjectStyle ostyle, size_t numThreads);
30+
double mercH, MapStyle style, ObjectStyle ostyle,
31+
size_t numThreads);
3132

3233
const std::vector<uint32_t>& getPoints(size_t i) { return _points[i]; }
34+
const std::vector<uint32_t>& getLinePoints(size_t i) {
35+
return _linePoints[i];
36+
}
3337
const std::vector<uint32_t>& getAreaFillPoints(size_t i) {
3438
return _areaFillPoints[i];
3539
}
@@ -38,10 +42,10 @@ class RenderContext {
3842
}
3943
std::vector<unsigned char>& getImage() { return _image; }
4044
void drawLinePoint(size_t tid, int px, int py, double weight, double rasterW,
41-
double rasterH);
45+
double rasterH, double rad);
46+
void drawLinePoint(size_t tid, int px, int py, double weight, double rasterW,
47+
double rasterH);
4248
void drawPoint(size_t tid, int px, int py, double weight, double rasterW,
43-
double rasterH, double r = 1);
44-
void drawPointObject(size_t tid, int px, int py, double weight, double rasterW,
4549
double rasterH);
4650
void drawFillPoint(size_t tid, int px, int py, double weight, int r = 0);
4751
void drawLineSegment(int x0, int y0, int x1, int y1, int w, int h);
@@ -68,8 +72,10 @@ class RenderContext {
6872

6973
std::vector<std::vector<uint32_t>> _points;
7074
std::vector<std::vector<uint32_t>> _areaFillPoints;
75+
std::vector<std::vector<uint32_t>> _linePoints;
7176
std::vector<std::vector<double>> _weights;
7277
std::vector<std::vector<double>> _areaFillWeights;
78+
std::vector<std::vector<double>> _lineWeights;
7379
std::vector<std::vector<std::pair<float, float>>> _rasterDims;
7480
std::vector<unsigned char> _image;
7581
MapStyle _style;

src/qlever-petrimaps/server/Server.cpp

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,8 @@ util::http::Answer Server::handleHeatMapReq(const Params& pars,
361361
auto px = RenderContext::mercToPx(cp, orx, ory, mercW, mercH, w, h);
362362
auto ppx = RenderContext::mercToPx(p, orx, ory, mercW, mercH, w, h);
363363

364-
rcontext.drawPoint(0, px.getX(), px.getY(), r->getVal(lid, oid), 0, 0,
365-
1);
364+
rcontext.drawPoint(0, px.getX(), px.getY(), r->getVal(lid, oid), 0,
365+
0);
366366
rcontext.drawLineSegment(px.getX(), px.getY(), ppx.getX(), ppx.getY(),
367367
w, h);
368368
} else {
@@ -377,10 +377,10 @@ util::http::Answer Server::handleHeatMapReq(const Params& pars,
377377
auto rasterMeta =
378378
r->getRasterMetas(lid, oid, {rasterWidth, rasterHeight});
379379
rcontext.drawPoint(0, px.getX(), px.getY(), r->getVal(lid, oid),
380-
rasterMeta.first, rasterMeta.second, 1);
380+
rasterMeta.first, rasterMeta.second);
381381
} else {
382382
rcontext.drawPoint(0, px.getX(), px.getY(), r->getVal(lid, oid), 0,
383-
0, 1);
383+
0);
384384
}
385385
}
386386
}
@@ -407,7 +407,7 @@ util::http::Answer Server::handleHeatMapReq(const Params& pars,
407407

408408
// TODO: just setting rasterWidth to 1x1 here is not correct
409409
rcontext.drawPoint(tid, px.getX(), px.getY(), grid.getCellSum(x, y),
410-
1, 1, 0.5);
410+
1, 1);
411411
} else {
412412
for (auto oid : *cell) {
413413
if (r->isCluster(lid, oid)) oid = r->getCluster(lid, oid).first;
@@ -421,10 +421,10 @@ util::http::Answer Server::handleHeatMapReq(const Params& pars,
421421
r->getRasterMetas(lid, oid, {rasterWidth, rasterHeight});
422422
rcontext.drawPoint(tid, px.getX(), px.getY(),
423423
r->getVal(lid, oid), rasterMeta.first,
424-
rasterMeta.second, 0.5);
424+
rasterMeta.second);
425425
} else {
426426
rcontext.drawPoint(tid, px.getX(), px.getY(),
427-
r->getVal(lid, oid), 0, 0, 0.5);
427+
r->getVal(lid, oid), 0, 0);
428428
}
429429
}
430430
}
@@ -552,49 +552,59 @@ util::http::Answer Server::handleHeatMapReq(const Params& pars,
552552
0, 0,
553553
0, 0,
554554
objColorR, objColorG,
555-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.06,
555+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.06,
556556
objColorR, objColorG,
557-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.12,
557+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.12,
558558
objColorR, objColorG,
559-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.25,
559+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.25,
560560
objColorR, objColorG,
561-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.5,
561+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.5,
562562
objColorR, objColorG,
563-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.65,
563+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.65,
564564
objColorR, objColorG,
565-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.8,
565+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.8,
566566
objColorR, objColorG,
567-
objColorB, 256 * lcfg.objectStyle.fillOpacity * 0.9,
567+
objColorB, 255 * lcfg.objectStyle.fillOpacity * 0.9,
568568
objColorR, objColorG,
569-
objColorB, 256 * lcfg.objectStyle.fillOpacity};
569+
objColorB, 255 * lcfg.objectStyle.fillOpacity};
570570
heatmap_colorscheme_t fillColorScheme = {
571571
fillColors, sizeof(fillColors) / sizeof(fillColors[0]) / 4};
572572

573573
unsigned char borderColors2[] = {
574-
0, 0, 0, 0,
575-
0, 0, 0, 0,
576-
objColorR, objColorG, objColorB, 0,
577-
objColorR, objColorG, objColorB, 0,
578-
objColorR, objColorG, objColorB, 0,
579-
objColorR, objColorG, objColorB, 0,
580-
objColorR, objColorG, objColorB, 0,
581-
objColorR, objColorG, objColorB, 0,
582-
objColorR, objColorG, objColorB, 0,
583-
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity};
574+
0, 0,
575+
0, 0,
576+
0, 0,
577+
0, 0,
578+
objColorR, objColorG,
579+
objColorB, 0,
580+
objColorR, objColorG,
581+
objColorB, 0,
582+
objColorR, objColorG,
583+
objColorB, 0,
584+
objColorR, objColorG,
585+
objColorB, 0,
586+
objColorR, objColorG,
587+
objColorB, 0,
588+
objColorR, objColorG,
589+
objColorB, 0,
590+
objColorR, objColorG,
591+
objColorB, 0,
592+
objColorR, objColorG,
593+
objColorB, std::max(1.0, 255 * lcfg.objectStyle.lineOpacity)};
584594
heatmap_colorscheme_t borderColor2Scheme = {
585595
borderColors2, sizeof(borderColors2) / sizeof(borderColors2[0]) / 4};
586596

587597
unsigned char borderColors[] = {
588598
0, 0, 0, 0,
589-
objColorR, objColorG, objColorB, 64 * lcfg.objectStyle.lineOpacity,
590-
objColorR, objColorG, objColorB, 64 * lcfg.objectStyle.lineOpacity,
591-
objColorR, objColorG, objColorB, 64 * lcfg.objectStyle.lineOpacity,
592-
objColorR, objColorG, objColorB, 64 * lcfg.objectStyle.lineOpacity,
593599
objColorR, objColorG, objColorB, 128 * lcfg.objectStyle.lineOpacity,
594-
objColorR, objColorG, objColorB, 160 * lcfg.objectStyle.lineOpacity,
600+
objColorR, objColorG, objColorB, 169 * lcfg.objectStyle.lineOpacity,
595601
objColorR, objColorG, objColorB, 192 * lcfg.objectStyle.lineOpacity,
596-
objColorR, objColorG, objColorB, 192 * lcfg.objectStyle.lineOpacity,
597-
objColorR, objColorG, objColorB, 192 * lcfg.objectStyle.lineOpacity};
602+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity,
603+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity,
604+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity,
605+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity,
606+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity,
607+
objColorR, objColorG, objColorB, 255 * lcfg.objectStyle.lineOpacity};
598608
heatmap_colorscheme_t borderColorScheme = {
599609
borderColors, sizeof(borderColors) / sizeof(borderColors[0]) / 4};
600610

@@ -1586,6 +1596,8 @@ RequestorConfig Server::getRequestorCfgFromJSON(
15861596
if (layer.value().contains("pointradius"))
15871597
curField.objectStyle.pointRadius =
15881598
layer.value()["pointradius"].get<double>();
1599+
if (layer.value().contains("group"))
1600+
curField.group = layer.value()["group"].get<std::string>();
15891601
if (curField.name.size() == 0) curField.name = curField.geomField;
15901602

15911603
// always assign an ID

0 commit comments

Comments
 (0)