Skip to content

Commit a1993b1

Browse files
authored
add symbol hash (#1319)
* add symbol hash * set default symbol hash to 1
1 parent 24dcf2b commit a1993b1

File tree

6 files changed

+51
-27
lines changed

6 files changed

+51
-27
lines changed

src/core/util/strings.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,18 @@ export function splitTextToRow(text, style) {
302302
'rawSize': size
303303
};
304304
}
305+
306+
export function hashCode(s) {
307+
let hash = 0;
308+
const strlen = s && s.length || 0;
309+
if (!strlen) {
310+
return hash;
311+
}
312+
let c;
313+
for (let i = 0; i < strlen; i++) {
314+
c = s.charCodeAt(i);
315+
hash = ((hash << 5) - hash) + c;
316+
hash = hash & hash; // Convert to 32bit integer
317+
}
318+
return hash;
319+
}

src/core/util/style.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { extend, isNil, isFunction, hasOwn, isString, isObject } from './common';
1+
import { extend, isNil, isString, isObject } from './common';
2+
import { hashCode } from './strings';
23
import { isFunctionDefinition } from '@maptalks/function-type';
34

45
/**
@@ -38,26 +39,24 @@ export function getGradientStamp(g) {
3839
* @return {String} symbol's stamp
3940
* @memberOf Util
4041
*/
41-
export function getSymbolStamp(symbol) {
42+
export function getSymbolHash(symbol) {
43+
if (!symbol) {
44+
return 1;
45+
}
4246
const keys = [];
4347
if (Array.isArray(symbol)) {
4448
for (let i = 0; i < symbol.length; i++) {
45-
keys.push(getSymbolStamp(symbol[i]));
46-
}
47-
return '[ ' + keys.join(' , ') + ' ]';
48-
}
49-
for (const p in symbol) {
50-
if (hasOwn(symbol, p)) {
51-
if (!isFunction(symbol[p])) {
52-
if (isGradient(symbol[p])) {
53-
keys.push(p + '=' + getGradientStamp(symbol[p]));
54-
} else {
55-
keys.push(p + '=' + symbol[p]);
56-
}
57-
}
49+
keys.push(getSymbolHash(symbol[i]));
5850
}
51+
return keys.sort().join(',');
5952
}
60-
return keys.join(';');
53+
const sortedKeys = Object.keys(symbol).sort();
54+
const sortedSymbol = sortedKeys.reduce((accumulator, curValue) => {
55+
accumulator[curValue] = symbol[curValue];
56+
return accumulator;
57+
}, {});
58+
const hash = hashCode(JSON.stringify(sortedSymbol));
59+
return hash;
6160
}
6261

6362
/**

src/geometry/Geometry.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
forEachCoord,
1313
flash
1414
} from '../core/util';
15-
import { extendSymbol } from '../core/util/style';
15+
import { extendSymbol, getSymbolHash } from '../core/util/style';
1616
import { convertResourceUrl, getExternalResources } from '../core/util/resource';
1717
import Coordinate from '../geo/Coordinate';
1818
import Extent from '../geo/Extent';
@@ -271,10 +271,18 @@ class Geometry extends JSONAble(Eventable(Handlerable(Class))) {
271271
setSymbol(symbol) {
272272
this._symbol = this._prepareSymbol(symbol);
273273
this.onSymbolChanged();
274-
this.__symbol = JSON.stringify(this._symbol);
274+
this._symbolHash = getSymbolHash(symbol);
275275
return this;
276276
}
277277

278+
/**
279+
* Get symbol's hash code
280+
* @return {String}
281+
*/
282+
getSymbolHash() {
283+
return this._symbolHash;
284+
}
285+
278286
/**
279287
* Update geometry's current symbol.
280288
*

src/renderer/geometry/symbolizers/VectorMarkerSymbolizer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isNil, isNumber, isArrayHasData, getValueOrDefault, sign } from '../../../core/util';
22
import { isGradient, getGradientStamp } from '../../../core/util/style';
3-
import { getAlignPoint } from '../../../core/util/strings';
3+
import { getAlignPoint, hashCode } from '../../../core/util/strings';
44
import { hasFunctionDefinition, isFunctionDefinition } from '../../../core/mapbox';
55
import Size from '../../../geo/Size';
66
import Point from '../../../geo/Point';
@@ -137,7 +137,7 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
137137

138138
_stampSymbol() {
139139
if (!this._stamp) {
140-
this._stamp = [
140+
this._stamp = hashCode([
141141
this.style['markerType'],
142142
isGradient(this.style['markerFill']) ? getGradientStamp(this.style['markerFill']) : this.style['markerFill'],
143143
this.style['markerFillOpacity'],
@@ -151,7 +151,7 @@ export default class VectorMarkerSymbolizer extends PointSymbolizer {
151151
this.style['markerHeight'],
152152
this.style['markerHorizontalAlignment'],
153153
this.style['markerVerticalAlignment']
154-
].join('_');
154+
].join('_'));
155155
}
156156
return this._stamp;
157157
}

src/renderer/layer/vectorlayer/VectorLayerCanvasRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ class VectorLayerRenderer extends OverlayLayerCanvasRenderer {
289289
geo._inCurrentView = (x >= xmin && y >= ymin && x <= xmax && y <= ymax);
290290
//不在视野内的,再用fixedExtent 精确判断下
291291
if (!geo._inCurrentView) {
292-
const symbolkey = geo.__symbol;
292+
const symbolkey = geo._symbolHash;
293293
let fixedExtent;
294294
if (symbolkey) {
295295
//相同的symbol 不要重复计算

test/core/UtilSpec.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Util', function () {
3333
expect(now2 >= now).to.be.ok();
3434
});
3535

36-
it('getSymbolStamp', function () {
36+
it('getSymbolHash', function () {
3737
var symbol = {
3838
'markerType' : 'ellipse',
3939
'markerFill' : {
@@ -46,8 +46,9 @@ describe('Util', function () {
4646
'markerWidth' : 10,
4747
'markerHeight' : 10
4848
};
49-
var expected = 'markerType=ellipse;markerFill=radial_0,rgba(17, 172, 263, 0),0.4,rgba(17, 172, 263, 1);markerWidth=10;markerHeight=10';
50-
expect(maptalks.Util.getSymbolStamp(symbol)).to.be.eql(expected);
49+
// var expected = 'markerType=ellipse;markerFill=radial_0,rgba(17, 172, 263, 0),0.4,rgba(17, 172, 263, 1);markerWidth=10;markerHeight=10';
50+
var expected = 1936604526;
51+
expect(maptalks.Util.getSymbolHash(symbol)).to.be.eql(expected);
5152

5253
symbol = [
5354
{
@@ -68,8 +69,9 @@ describe('Util', function () {
6869
'markerHeight' : 10
6970
}
7071
];
71-
expected = '[ markerFile=foo.png;markerWidth=5;markerHeight=5 , markerType=ellipse;markerFill=radial_0,rgba(17, 172, 263, 0),0.4,rgba(17, 172, 263, 1);markerWidth=10;markerHeight=10 ]';
72-
expect(maptalks.Util.getSymbolStamp(symbol)).to.be.eql(expected);
72+
// expected = '[ markerFile=foo.png;markerWidth=5;markerHeight=5 , markerType=ellipse;markerFill=radial_0,rgba(17, 172, 263, 0),0.4,rgba(17, 172, 263, 1);markerWidth=10;markerHeight=10 ]';
73+
expected = '1501174206,1936604526';
74+
expect(maptalks.Util.getSymbolHash(symbol)).to.be.eql(expected);
7375
});
7476

7577
describe('split content', function () {

0 commit comments

Comments
 (0)