Skip to content

Commit 71516ab

Browse files
[update]mapbox经纬网新增set方法 review by songym
1 parent be513a8 commit 71516ab

File tree

4 files changed

+181
-34
lines changed

4 files changed

+181
-34
lines changed

build/jsdocs/template/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@
327327
"name": "Three"
328328
},
329329
"GraticuleLayer": {
330-
"name": "GraticuleLayer"
330+
"name": "经纬网"
331331
}
332332
}
333333
},

src/common/util/MapCalculateUtil.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export var getMeterPerMapUnit = function(mapUnit) {
2020
return meterPerMapUnit;
2121
};
2222

23-
export function getWrapNum(x, range = [-180, 180], includeMax = true, includeMin) {
23+
export function getWrapNum(x, includeMax = true, includeMin = true, range = [-180, 180]) {
2424
var max = range[1],
2525
min = range[0],
2626
d = max - min;
@@ -38,10 +38,10 @@ export function getWrapNum(x, range = [-180, 180], includeMax = true, includeMin
3838
}
3939

4040
export function conversionDegree(degrees) {
41-
const degree = parseInt(degrees);
42-
let fraction = parseInt((degrees - degree) * 60);
43-
let second = parseInt(((degrees - degree) * 60 - fraction) * 60);
44-
fraction = parseInt(fraction / 10) === 0 ? `0${fraction}` : fraction;
45-
second = parseInt(second / 10) === 0 ? `0${second}` : second;
46-
return `${degree}°${fraction}'${second}`;
41+
const degree = parseInt(degrees);
42+
let fraction = parseInt((degrees - degree) * 60);
43+
let second = parseInt(((degrees - degree) * 60 - fraction) * 60);
44+
fraction = parseInt(fraction / 10) === 0 ? `0${fraction}` : fraction;
45+
second = parseInt(second / 10) === 0 ? `0${second}` : second;
46+
return `${degree}°${fraction}'${second}`;
4747
}

src/mapboxgl/overlay/GraticuleLayer.js

Lines changed: 132 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ import mapboxgl from 'mapbox-gl';
1515
* @class mapboxgl.supermap.GraticuleLayer
1616
* @category Visualization GraticuleLayer
1717
* @classdesc 经纬网。
18+
* @version 10.1.1
1819
* @param {mapboxgl.Map} map - mapboxgl 地图对象,将在下个版本弃用,请用 map.addLayer() 方法添加图层。
1920
* @param {Object} options -经纬网参数。
2021
* @param {boolean} [options.visible=true] - 是否显示经纬网。
2122
* @param {boolean} [options.showLabel=true] - 是否显示标签。
2223
* @param {number} [options.opacity=1] - 画布透明度。
2324
* @param {number|Function} [options.interval = 10] - 经纬度的间隔(以度为单位),可以是数字,也可以是函数,参数是map。
2425
* @param {mapboxgl.LngLatBounds} [options.extent] - 经纬网渲染的边界范围([minx, miny, maxx, maxy]),不传为整个地图范围。
25-
* @param {number} [options.minZoom] - 最小视图缩放级别(不包括此级别),在该级别之上,该层将可见
26+
* @param {number} [options.minZoom] - 最小视图缩放级别(不包括此级别),在该级别之上,该层将可见。
2627
* @param {number} [options.maxZoom] - 该图层可见的最大视图缩放级别(含)。
2728
* @param {Function} [options.lngLabelFormatter = null] - 经度标签转换函数。
2829
* @param {Function} [options.latLabelFormatter = null] - 纬度标签转换函数。
@@ -46,8 +47,8 @@ import mapboxgl from 'mapbox-gl';
4647
* @property {string} [lineColor = 'red'] - 线颜色。
4748
* @property {string} [lineCap = 'round'] - 线端点风格:butt, round, square。
4849
* @property {string} [lineJoin = round] - 线连接样式:bevel, round, miter。
49-
* @property {Array.<number>|Function} [lindDasharray = [0.5,4]] - 虚线样式。可以是数组,也可以是函数,参数是map
50-
* @property {number|Function} [lineWidth = 1] - 线宽:可以是数字,也可以是函数,参数是map
50+
* @property {Array.<number>} [lindDasharray = [0.5,4]] - 虚线样式。
51+
* @property {number} [lineWidth = 1] - 线宽。
5152
*/
5253

5354
const defaultTextStyle = {
@@ -115,6 +116,7 @@ export class GraticuleLayer {
115116
/**
116117
* @function mapboxgl.supermap.GraticuleLayer.prototype.setVisibility
117118
* @description 设置是否可见。
119+
* @param {boolean} visible - 是否可见。
118120
*/
119121
setVisibility(visible) {
120122
const zoom = this.map.getZoom();
@@ -129,6 +131,97 @@ export class GraticuleLayer {
129131
this._drawLabel();
130132
}
131133

134+
/**
135+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setMinZoom
136+
* @description 设置最小视图缩放级别。
137+
* @param {number} minZoom - 最小视图缩放级别(不包括此级别),在该级别之上,该层将可见。
138+
*/
139+
setMinZoom(minZoom) {
140+
this.options.minZoom = minZoom;
141+
this.setVisibility();
142+
}
143+
144+
/**
145+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setMaxZoom
146+
* @description 该图层可见的最大视图缩放级别。
147+
* @param {number} maxZoom - 该图层可见的最大视图缩放级别(含)。
148+
*/
149+
setMaxZoom(maxZoom) {
150+
this.options.maxZoom = maxZoom;
151+
this.setVisibility();
152+
}
153+
154+
/**
155+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setShowLabel
156+
* @description 设置显示标签。
157+
* @param {boolean} showLabel - 是否显示标签。
158+
*/
159+
setShowLabel(showLabel) {
160+
this.options.showLabel = showLabel;
161+
this._drawLabel();
162+
}
163+
164+
/**
165+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setExtent
166+
* @description 设置经纬网渲染的边界范围。
167+
* @param {mapboxgl.LngLatBounds} extent - 经纬网渲染的边界范围。
168+
*/
169+
setExtent(extent) {
170+
this.options.extent = this._getDefaultExtent(extent, this.map);
171+
this.features = this._getGraticuleFeatures();
172+
this._updateGraticuleLayer();
173+
this._drawLabel();
174+
}
175+
176+
/**
177+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setStrokeStyle
178+
* @description 设置经纬线样式。
179+
* @param {mapboxgl.supermap.GraticuleLayer.StrokeStyle} strokeStyle - 经纬线样式。
180+
*/
181+
setStrokeStyle(strokeStyle) {
182+
this.options.strokeStyle = strokeStyle;
183+
const { layout, paint } = this._transformStrokeStyle(strokeStyle);
184+
for (let key in layout) {
185+
this.map.setLayoutProperty(this.sourceId, key, layout[key]);
186+
}
187+
for (let key in paint) {
188+
this.map.setPaintProperty(this.sourceId, key, paint[key]);
189+
}
190+
}
191+
192+
/**
193+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setLngLabelStyle
194+
* @description 设置经度标签样式。
195+
* @param {mapboxgl.supermap.GraticuleLayer.LabelStyle} labelStyle - 标签样式。
196+
*/
197+
setLngLabelStyle(labelStyle) {
198+
this.options.lngLabelStyle = labelStyle;
199+
this._drawLabel();
200+
}
201+
202+
/**
203+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setLatLabelStyle
204+
* @description 设置纬度标签样式。
205+
* @param {mapboxgl.supermap.GraticuleLayer.LabelStyle} labelStyle - 标签样式。
206+
*/
207+
setLatLabelStyle(labelStyle) {
208+
this.options.latLabelStyle = labelStyle;
209+
this._drawLabel();
210+
}
211+
212+
/**
213+
* @function mapboxgl.supermap.GraticuleLayer.prototype.setIntervals
214+
* @description 设置经纬度的间隔(以度为单位)
215+
* @param {number|Function} interval - 经纬度的间隔(以度为单位),可以是数字,也可以是函数,参数是map。
216+
*/
217+
setIntervals(interval) {
218+
this.options.interval = interval;
219+
this._calcInterval();
220+
this.features = this._getGraticuleFeatures();
221+
this._updateGraticuleLayer();
222+
this._drawLabel();
223+
}
224+
132225
_bindEvent() {
133226
this.map.on('move', this.resetEvent);
134227
this.map.on('moveend', this.resetEvent);
@@ -241,10 +334,8 @@ export class GraticuleLayer {
241334
}
242335

243336
_updateRotate() {
244-
const canvas = this.canvas;
245-
const sw = this.map.unproject([0, canvas.height]);
246-
const ne = this.map.unproject([canvas.width, 0]);
247-
this.isRotate = sw.lng > ne.lng;
337+
const bearing = this.map.getBearing();
338+
this.isRotate = (bearing > -180 && bearing <= -90) || (bearing >= 90 && bearing < 180);
248339
}
249340

250341
_updateExtent() {
@@ -372,9 +463,7 @@ export class GraticuleLayer {
372463

373464
features.forEach(feature => {
374465
const lat = feature.geometry.coordinates[0][1];
375-
376-
const isLatFeature = feature.geometry.coordinates[1][1];
377-
466+
const isLatFeature = feature.geometry.coordinates[1][1] === lat;
378467
if (isLatFeature) {
379468
let lng = typeof lastLng === 'number' ? lastLng : lngRange[1];
380469
if (this.isRotate) {
@@ -402,7 +491,7 @@ export class GraticuleLayer {
402491

403492
features.forEach(feature => {
404493
let lng = feature.geometry.coordinates[0][0];
405-
const isLngFeature = feature.geometry.coordinates[1][0];
494+
const isLngFeature = feature.geometry.coordinates[1][0] === lng;
406495
if (isLngFeature) {
407496
points.push([lng, lat]);
408497
if (this.options.wrapX) {
@@ -420,20 +509,13 @@ export class GraticuleLayer {
420509
const lastLng = extent.length > 2 ? extent[2] : extent[1];
421510
while (lng >= _sw.lng) {
422511
const wrapNum = getWrapNum(lng, lastLng === 180, extent[0] === -180);
423-
// if (wrapNum === -180 && lastLng === 180 && extent[0] !== -180) {
424-
// wrapNum = 180;
425-
// }
426512
if (!extent || (wrapNum >= extent[0] && wrapNum <= lastLng)) {
427513
points.push([lng, lat]);
428514
}
429515
lng -= 360;
430516
}
431517
while (lng <= _ne.lng) {
432518
const wrapNum = getWrapNum(lng, lastLng === 180, extent[0] === -180);
433-
// let wrapNum = getWrapNum(lng);
434-
// if (wrapNum === 180 && lastLng !== 180 && extent[0] === -180) {
435-
// wrapNum = -180;
436-
// }
437519
if (!extent || (wrapNum >= extent[0] && wrapNum <= lastLng)) {
438520
points.push([lng, lat]);
439521
}
@@ -584,9 +666,21 @@ export class GraticuleLayer {
584666
return points;
585667
}
586668
var tmp = intersectPoints;
669+
const width = this.canvas.width;
670+
const height = this.canvas.height;
587671
for (var i in points) {
588-
if (!tmp.find(item => item[0] === points[i][index])) {
672+
const edgePoint = this.map.project(points[i]);
673+
const intersetIndex = tmp.findIndex(item => item[0] === points[i][index]);
674+
if (intersetIndex <= -1) {
589675
tmp.push(points[i]);
676+
} else if (
677+
edgePoint &&
678+
edgePoint.x >= 0 &&
679+
edgePoint.x <= width &&
680+
edgePoint.y >= 0 &&
681+
edgePoint.y <= height
682+
) {
683+
tmp[intersetIndex] = points[i];
590684
}
591685
}
592686
return tmp;
@@ -621,6 +715,17 @@ export class GraticuleLayer {
621715
}
622716
}
623717

718+
_updateGraticuleLayer(features = this.features) {
719+
if (this.map.getSource(this.sourceId)) {
720+
const geoJSONData = {
721+
type: 'FeatureCollection',
722+
features
723+
};
724+
this.map.getSource(this.sourceId).setData(geoJSONData);
725+
}
726+
this._addGraticuleLayer();
727+
}
728+
624729
_getGraticuleFeatures() {
625730
const _currLngInterval = this._currLngInterval || 10;
626731
const _currLatInterval = this._currLatInterval || 10;
@@ -665,22 +770,23 @@ export class GraticuleLayer {
665770
const realExtent = {};
666771
if (extent[1] % this._currLatInterval !== 0) {
667772
realExtent.firstLat = extent[1];
668-
let intNumber = parseInt(extent[1] / this._currLatInterval);
669-
intNumber = extent[1] > 0 ? intNumber + 1 : intNumber - 1;
773+
const intNumber = Math.ceil(extent[1] / this._currLatInterval);
670774
extent[1] = intNumber * this._currLatInterval;
671775
}
672776
if (extent[3] % this._currLatInterval !== 0) {
673777
realExtent.lastLat = extent[3];
674-
extent[3] = parseInt(extent[3] / this._currLatInterval) * this._currLatInterval;
778+
const intNumber = Math.floor(extent[3] / this._currLatInterval);
779+
extent[3] = intNumber * this._currLatInterval;
675780
}
676781
if (extent[0] % this._currLngInterval !== 0) {
677782
realExtent.firstLng = extent[0];
678-
let intNumbers = parseInt(extent[0] / this._currLngInterval);
679-
extent[0] = intNumbers * this._currLngInterval;
783+
const intNumber = Math.ceil(extent[0] / this._currLngInterval);
784+
extent[0] = intNumber * this._currLngInterval;
680785
}
681786
if (extent[2] % this._currLngInterval !== 0) {
682787
realExtent.lastLng = extent[2];
683-
extent[2] = parseInt(extent[2] / this._currLngInterval) * this._currLngInterval;
788+
const intNumber = Math.floor(extent[2] / this._currLngInterval);
789+
extent[2] = intNumber * this._currLngInterval;
684790
}
685791
return { latRange: [extent[1], extent[3]], lngRange: [extent[0], extent[2]], extent, ...realExtent };
686792
}
@@ -758,7 +864,7 @@ export class GraticuleLayer {
758864
ctx.fillStyle = labelStyle.textColor;
759865
}
760866
if (labelStyle.textSize) {
761-
ctx.font = labelStyle.textSize + ' ' + labelStyle.textFont.join(',');
867+
ctx.font = labelStyle.textSize + ' ' + (labelStyle.textFont || ['Calibri', 'sans-serif']).join(',');
762868
}
763869
if (labelStyle.textHaloColor) {
764870
ctx.strokeStyle = labelStyle.textHaloColor;

test/mapboxgl/overlay/GraticuleLayerSpec.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,47 @@ describe('mapboxgl_GraticuleLayer', () => {
8282
expect(visible).toBe('visible');
8383
});
8484

85+
it('setMinZoom', () => {
86+
graticuleLayer.setMinZoom(0);
87+
expect(graticuleLayer.options.minZoom).toEqual(0);
88+
});
89+
90+
it('setMaxZoom', () => {
91+
graticuleLayer.setMaxZoom(10);
92+
expect(graticuleLayer.options.maxZoom).toEqual(10);
93+
});
94+
95+
it('setShowLabel', () => {
96+
graticuleLayer.setShowLabel(false);
97+
expect(graticuleLayer.options.showLabel).toEqual(false);
98+
});
99+
100+
it('setExtent', () => {
101+
graticuleLayer.setExtent([[0, 0], [50, 50]]);
102+
expect(graticuleLayer.options.extent[0]).toEqual(0);
103+
expect(graticuleLayer.options.extent[3]).toEqual(50);
104+
});
105+
106+
it('setStrokeStyle', () => {
107+
graticuleLayer.setStrokeStyle({ lineWidth: 3 });
108+
expect(graticuleLayer.options.strokeStyle.lineWidth).toEqual(3);
109+
});
110+
111+
it('setLngLabelStyle', () => {
112+
graticuleLayer.setLngLabelStyle({ textSize: '12px' });
113+
expect(graticuleLayer.options.lngLabelStyle.textSize).toEqual('12px');
114+
});
115+
116+
it('setLatLabelStyle', () => {
117+
graticuleLayer.setLatLabelStyle({ textSize: '12px' });
118+
expect(graticuleLayer.options.latLabelStyle.textSize).toEqual('12px');
119+
});
120+
121+
it('setIntervals', () => {
122+
graticuleLayer.setIntervals(5);
123+
expect(graticuleLayer.options.interval).toEqual(5);
124+
});
125+
85126
it('_calcInterval', () => {
86127
const interval = map.getZoom();
87128
const calcInterval = map => {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy